Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Sebastian
erp5
Commits
8954ad1f
Commit
8954ad1f
authored
Mar 08, 2017
by
Sebastian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5_data_notebook: Add script for renderjs-extension
parent
cec2bbfb
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
198 additions
and
0 deletions
+198
-0
bt5/erp5_data_notebook/SkinTemplateItem/portal_skins/erp5_data_notebook/Base_loadRenderJSExtension.py
...al_skins/erp5_data_notebook/Base_loadRenderJSExtension.py
+136
-0
bt5/erp5_data_notebook/SkinTemplateItem/portal_skins/erp5_data_notebook/Base_loadRenderJSExtension.xml
...l_skins/erp5_data_notebook/Base_loadRenderJSExtension.xml
+62
-0
No files found.
bt5/erp5_data_notebook/SkinTemplateItem/portal_skins/erp5_data_notebook/Base_loadRenderJSExtension.py
0 → 100644
View file @
8954ad1f
import
json
# This script provides the backend-functionality of the Juypter Notebook RenderJS Extension.
# Due to the internal protocol of the ERP5Kernel and the ERP5-Jupyter-Backend messages between
# Javascript in the client and the ERP5Kernel are exchange via objections containing
# Javascript code as _repr_html_.
# Here a schematic overview of the messaging:
# 1. Extension-Function is called in the notebook (e.g. loadGadget("gadget", "https://someurl.com/gadget"))
# 2. Code is processed by the ERP5Kernel (client)
# 3. Code is sent to the ERP5-Backend
# 4. The required logic is handled by this script in the backend
# 5. This script returns an object with _repr_html_ containing the JS-response for the client
# 6. The ERP5-Backend sends a response to the ERP5Kernel (client)
# 7. The ERP5Kernel interprets the object with _repr_html_ as text/html message and injects it into the notebook
# 8. Now the Javascript code is executed as part of the (client) extension (e.g. a renderJS-gadget is loaded into the page)
class
RJSExtension
:
def
__init__
(
self
):
pass
# Create the original load_gadget with modified rsvp, renderjs
# Because jupyter notebook has already loaded when this can be called
# a manual initialization of the whole renderJS setup is required
#
# First the libs rsvp, renderjs-gadget-global and renderjs (patched)
# are injected into the page. The patch on renderjs itself is to enable
# the following manual bootstrap
# After the scripts are present, a div is appended containing the
# loading_gadget.
# After everything is inplace, rJS.manualBootstrap initializes the
# loading_gadget in exactly the same way as when rJS is normally initialized
# (on-load)
def
initRenderJS
(
self
):
script
=
'''
<script>
var loadingDiv = document.querySelector(".loading_gadget");
if(loadingDiv == null) {
console.log("~~ Initializing RenderJS!");
$.getScript("/nbextensions/renderjs_nbextension/rsvp-2.0.4.js", function() {
console.log("~~ loading_gadget: rsvp.js loaded");
$.getScript("/nbextensions/renderjs_nbextension/rjs_gadget_global_js.js", function() {
console.log("~~ loading_gadget: renderjs-gadget-global.js loaded");
$.getScript("/nbextensions/renderjs_nbextension/renderjs-latest.js", function() {
console.log("~~ loading_gadget: renderjs.js loaded");
$("#notebook-container").append('<div data-gadget-url="/nbextensions/renderjs_nbextension/loading_gadget.html" data-gadget-scope="public"></div>');
rJS.manualBootstrap();
});
});
});
} else {
console.log("~~ Renderjs seems to be initialized already!");
}
</script>'''
return
RJSHtmlMessage
(
script
)
# Load a gadget given a unique ref and URL to the HTML file of the gadget
# -> Fires an event which loading_gadget listens on and passes on the URL
def
loadGadget
(
self
,
ref
,
gadgetUrl
):
script
=
'''
<script>
var load_event = new CustomEvent("load_gadget",
{ "detail": { "url": "'''
+
gadgetUrl
+
'", "gadgetId": "'
+
ref
+
'''" }});
var loadingDiv = document.querySelector(".loading_gadget");
if(loadingDiv != null) {
loadingDiv.dispatchEvent(load_event);
} else {
console.log("~~ load: RenderJS init required first!");
}
</script>
'''
return
RJSHtmlMessage
(
script
)
# Fires an event with
# * the ref of the gadget
# * the name of the declared_method
# * the arguments to be passed to the declared_method
# The arguments are packed into a json string and passed to js as such
def
callDeclaredMethod
(
self
,
ref
,
method_name
,
*
args
):
j_str
=
json
.
dumps
(
args
)
script
=
'''
<script>
var call_event = new CustomEvent("call_gadget",
{ "detail": {
"gadgetId": "'''
+
ref
+
'''",
"methodName": "'''
+
method_name
+
'''",
"methodArgs": '''
+
"'"
+
j_str
+
"'"
+
'''
}});
var loadingDiv = document.querySelector(".loading_gadget");
if(loadingDiv != null) {
loadingDiv.dispatchEvent(call_event);
} else {
console.log("~~ call: RenderJS init required first!");
}
</script>
'''
return
RJSHtmlMessage
(
script
)
# Fires an event to the destroy this gadget
# Only thing passed is the ref of the gadget
def
destroyGadget
(
self
,
ref
):
script
=
'''
<script>
var destroy_event = new CustomEvent("destroy_gadget",
{ "detail": { "gadgetId": "'''
+
ref
+
'''" }});
var loadingDiv = document.querySelector(".loading_gadget");
if(loadingDiv != null) {
loadingDiv.dispatchEvent(destroy_event);
} else {
console.log("~~ destroy: RenderJS init required first!");
}
</script>
'''
return
RJSHtmlMessage
(
script
)
class
RJSHtmlMessage
:
'''
Represents a HTML-injection into the frontend. Returning such an object from the ERP5
backend is sufficient, as the _repr_html_ will be called internally.
'''
def
__init__
(
self
,
html
):
self
.
html
=
html
def
_repr_html_
(
self
):
return
self
.
html
obj
=
RJSExtension
()
return
obj
bt5/erp5_data_notebook/SkinTemplateItem/portal_skins/erp5_data_notebook/Base_loadRenderJSExtension.xml
0 → 100644
View file @
8954ad1f
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"PythonScript"
module=
"Products.PythonScripts.PythonScript"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
Script_magic
</string>
</key>
<value>
<int>
3
</int>
</value>
</item>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_container
</string>
</key>
<value>
<string>
container
</string>
</value>
</item>
<item>
<key>
<string>
name_context
</string>
</key>
<value>
<string>
context
</string>
</value>
</item>
<item>
<key>
<string>
name_m_self
</string>
</key>
<value>
<string>
script
</string>
</value>
</item>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
_params
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
Base_loadRenderJSExtension
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment