Commit 8100d719 authored by Richard's avatar Richard Committed by Vincent Bechu

[erp5_notebook][erp5_officejs][erp5_officejs_ui_test]: update iodide to run pyodide

parent 7ce8b5ed
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_jio_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_jio_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>jio_view</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Action Information</string> </value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>35.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>View</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/WebPage_viewAsJio</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -2859,6 +2859,7 @@ li.CodeMirror-hint-active {
color: #333;
background-color: #fff;
overflow: hidden;
position: relative;
}
div#page {
......@@ -2897,13 +2898,17 @@ div#cells.presentation {
height: inherit;
}
div#cells.pane-open {
width: calc(100% - 575px);
}
/************************************************/
/* cell output styles */
.rep-container {
overflow-x: auto;
}
.array-rep {
overflow-x: auto;
}
.data-set-info {
color: #888;
font-style: italic;
......@@ -2948,6 +2953,10 @@ div.promise-handler-value {
margin-top:6px;
}
.undefined-rep, .null-rep {
display: inline-block;
}
/************************************************/
/* header bar styles */
......@@ -2966,11 +2975,11 @@ div.promise-handler-value {
}
div.editor-mode-controls {
width: 260px;
width: 300px;
}
div.view-controls {
width: 300px;
width: 375px;
display:flex;
align-items:center;
}
......@@ -3123,7 +3132,7 @@ code {
border-radius: 3px;
}
.side-pane {
width:575px !important;
width:auto !important;
top: 50px !important;
border: none !important;
border-left: 2px solid lightgray !important;
......@@ -3134,6 +3143,7 @@ code {
top: 0;
z-index: 10;
background: #fff;
padding-top: 1px;
}
.pane-title {
......@@ -3163,18 +3173,28 @@ div.history-cells {
padding-right: 20px;
}
div.history-cell {
width: inherit
}
div.history-cells .CodeMirror {
height: auto;
}
div.history-cells div.cell-container {
padding-right:0px;
}
pre.history-item-code {
overflow:scroll;
overflow: scroll;
padding:3px;
}
div.history-content {
outline: 1px solid lightgray;
div.history-content {
outline: 1px solid #f1f1f1;
width: calc(100% - 1px)
}
div.history-date {
......@@ -3201,7 +3221,7 @@ div.side-pane {
border: 2px solid gray;
border-right: none;
width: 75%;
overflow: scroll;
overflow: auto;
height: 100%;
background-color: rgba(255, 255, 255);
}
......@@ -3210,8 +3230,36 @@ i.close-side-pane:hover {
outline: 1px solid lightgray;
}
div.frozen-variables {
display: grid;
grid-template-columns: minmax(100px, min-content) 100px;
grid-column-gap: 0px;
}
div.frozen-variable-name {
border: 1px solid #f1f1f1;
background: #f9f9f9;
font-family: monospace;
padding-left:5px;
padding-right:20px;
overflow-wrap: break-word;
max-width: calc(100% - 25px);
}
div.frozen-variable-value {
border: 1px solid #f1f1f1;
background: #f9f9f9;
font-family: monospace;
color:gray;
justify-self: end;
white-space: pre;
padding-left:5px;
padding-right:5px;
width: 100%;
}
div.declared-variables-list {
padding: 15px
padding: 15px;
}
div.declared-variable {
......@@ -3220,7 +3268,7 @@ div.declared-variable {
div.declared-variable-name {
font-size: 14px;
font-family: "monospace";
font-family: monospace;
background: #f9f9f9;
border: 1px solid #f1f1f1;
padding: 1px 10px;
......@@ -3236,6 +3284,12 @@ div.app-info-message {
padding-right: 10px;
padding-top: 20px;
}
div.app-message-when {
font-style:italic;
color:gray;
font-size:12px;
}
.medium-menu {
display: flex !important;
justify-content: space-between;
......@@ -3293,6 +3347,11 @@ div.app-info-message {
top: 10px;
z-index:100;
}
.user-avatar {
height: 24px;
border-radius: 50%;
}
/* cell and cell container styles*/
div.cell-container {
......@@ -3343,15 +3402,16 @@ div#cells.presentation div.cell-row.input {
}
.cell-menu-container {
width: 64px;
width: 76px;
font-size:12px;
flex-shrink: 0;
flex-grow: 0;
}
.cell-type-label {
text-align: right;
color: hsl(275, 12%, 75%);
cursor: pointer;
padding: 0px 6px 0px 0px;
height: 18px;
border: 1px solid rgba(0,0,0,0);
display: flex;
......@@ -3391,7 +3451,9 @@ div#cells.presentation div.cell-row.input {
div.cell-row-container {
width: calc(100% - 64px); /* 100% minus cell-menu-contatiner width*/
width: calc(100% - 76px); /* 100% minus cell-menu-contatiner width*/
flex-shrink: 0;
flex-grow: 0;
}
div.cell-row {
......@@ -3407,7 +3469,8 @@ div.collapse-button {
margin-right: 5px;
margin-left: 3px;
width: 18px;
height: 100%;
flex-shrink: 0;
flex-grow: 0;
}
div.collapse-button:hover {
......@@ -3422,15 +3485,18 @@ div.HIDDEN div.collapse-button-tooltip-wrapper {
}
div.HIDDEN div.collapse-button {
width: calc(100%);
width: calc(100% - 3px);
/* when collapsed, make the button visible*/
background: #fdfdfd;
outline: 1px solid #ddd;
cursor: pointer;
height: 20px;
}
div.main-component {
width: calc(100% - 24px); /* 100% minus .collapse-button width (including margins) */
width: calc(100% - 25px); /* 100% minus .collapse-button width (including margins) */
flex-shrink: 0;
flex-grow: 0;
}
div.input div.main-component {
......@@ -3491,6 +3557,7 @@ div.SCROLL.output .main-component {
}
/* FIX ME i think this style is never used, double check it*/
div.hidden-cell {
display: none;
......@@ -3551,6 +3618,17 @@ div#cells.presentation div.main-component {
width: 100%;
}
/* which side-effects are shown in the report view*/
div#cells.presentation .side-effect-target {
max-width:800px;
margin: auto;
}
div#cells.presentation div.side-effect-target div.hide-side-effect {
display: none;
}
/* div#cells.presentation {
padding-top:30px;
} */
......@@ -3571,8 +3649,7 @@ div#cells.presentation div.main-component {
/* establish block-level elements to be a certain width. This
lets us create full width divs using css if necessary, while still
retaining the narrower colum view for readability and flow.
retaining the narrower column view for readability and flow.
*/
.user-markdown p,
......
{"dependencies": {"matplotlib": ["cycler", "kiwisolver", "numpy", "pyparsing", "python-dateutil", "pytz"], "numpy": [], "pyparsing": [], "kiwisolver": [], "python-dateutil": [], "xlrd": [], "pandas": ["numpy", "python-dateutil", "pytz"], "cycler": [], "pytz": []}}
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>packages.json</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>application/json</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>pyodide.asm.data.js</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>application/javascript</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>pyodide.asm.html</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -12,7 +12,7 @@
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>application/octet-stream</string> </value>
<value> <string>application/wasm</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
......
/**
* The main bootstrap script for loading pyodide.
*/
var languagePluginLoader = new Promise((resolve, reject) => {
let baseURL = "";
// This is filled in by the Makefile to be either a local file or the
// deployed location. TODO: This should be done in a less hacky
// way.
const baseURL = '';
////////////////////////////////////////////////////////////
// Package loading
var packages = undefined;
let loadedPackages = new Set();
let loadPackage = (names) => {
// DFS to find all dependencies of the requested packages
let packages = window.pyodide.packages.dependencies;
let queue = new Array(names);
let toLoad = new Set();
while (queue.length) {
const package = queue.pop();
if (!loadedPackages.has(package)) {
toLoad.add(package);
if (packages.hasOwnProperty(package)) {
packages[package].forEach((subpackage) => {
if (!loadedPackages.has(subpackage) && !toLoad.has(subpackage)) {
queue.push(subpackage);
}
});
} else {
console.log(`Unknown package '${package}'`);
}
}
}
let promise = new Promise((resolve, reject) => {
if (toLoad.size === 0) {
resolve('No new packages to load');
}
pyodide.monitorRunDependencies = (n) => {
if (n === 0) {
toLoad.forEach((package) => loadedPackages.add(package));
delete pyodide.monitorRunDependencies;
const packageList = Array.from(toLoad.keys()).join(', ');
resolve(`Loaded ${packageList}`);
}
};
toLoad.forEach((package) => {
let script = document.createElement('script');
script.src = `${baseURL}${package}.js`;
script.onerror = (e) => { reject(e); };
document.body.appendChild(script);
});
// We have to invalidate Python's import caches, or it won't
// see the new files. This is done here so it happens in parallel
// with the fetching over the network.
window.pyodide.runPython('import importlib as _importlib\n' +
'_importlib.invalidate_caches()\n');
});
if (window.iodide !== undefined) {
window.iodide.evalQueue.await([ promise ]);
}
return promise;
};
function fixRecursionLimit(pyodide) {
// The Javascript/Wasm call stack may be too small to handle the default
// Python call stack limit of 1000 frames. This is generally the case on
// Chrom(ium), but not on Firefox. Here, we determine the Javascript call
// stack depth available, and then divide by 50 (determined heuristically)
// to set the maximum Python call stack depth.
let depth = 0;
function recurse() {
depth += 1;
recurse();
}
try {
recurse();
} catch (err) {
;
}
let recursionLimit = depth / 50;
if (recursionLimit > 1000) {
recursionLimit = 1000;
}
pyodide.runPython(
`import sys; sys.setrecursionlimit(int(${recursionLimit}))`);
};
////////////////////////////////////////////////////////////
// Loading Pyodide
let wasmURL = `${baseURL}pyodide.asm.wasm`;
let wasmXHR = new XMLHttpRequest();
wasmXHR.open('GET', wasmURL, true);
wasmXHR.responseType = 'arraybuffer';
wasmXHR.onload = function() {
let Module = {};
window.Module = Module;
if (wasmXHR.status === 200 || wasmXHR.status === 0) {
Module.wasmBinary = wasmXHR.response;
} else {
console.warn(
`Couldn't download the pyodide.asm.wasm binary. Response was ${wasmXHR.status}`);
reject();
Module.noImageDecoding = true;
Module.noAudioDecoding = true;
let isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
if (isFirefox) {
console.log("Skipping wasm decoding");
Module.noWasmDecoding = true;
}
Module.baseURL = baseURL;
let wasm_promise = WebAssembly.compileStreaming(fetch(wasmURL));
Module.instantiateWasm = (info, receiveInstance) => {
wasm_promise.then(module => WebAssembly.instantiate(module, info))
.then(instance => receiveInstance(instance));
return {};
};
Module.filePackagePrefixURL = baseURL;
var postRunPromise = new Promise((resolve, reject) => {
Module.postRun = () => {
delete window.Module;
fetch(`${baseURL}packages.json`)
.then((response) => response.json())
.then((json) => {
window.pyodide.packages = json;
fixRecursionLimit(pyodide);
resolve();
});
};
});
var dataLoadPromise = new Promise((resolve, reject) => {
Module.monitorRunDependencies =
(n) => {
if (n === 0) {
delete Module.monitorRunDependencies;
resolve();
}
}
});
Promise.all([ postRunPromise, dataLoadPromise ]).then(() => resolve());
let data_script = document.createElement('script');
data_script.src = `${baseURL}pyodide.asm.data.js`;
data_script.onload = (event) => {
let script = document.createElement('script');
script.src = `pyodide.asm.js`;
script.src = `${baseURL}pyodide.asm.js`;
script.onload = () => {
window.pyodide = pyodide(Module);
window.pyodide.loadPackage = loadPackage;
};
document.body.appendChild(script);
document.head.appendChild(script);
};
wasmXHR.send(null);
document.head.appendChild(data_script);
////////////////////////////////////////////////////////////
// Iodide-specific functionality, that doesn't make sense
// if not using with Iodide.
if (window.iodide !== undefined) {
// Load the custom CSS for Pyodide
let link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = `${baseURL}renderedhtml.css`;
document.getElementsByTagName('head')[0].appendChild(link);
// Add a custom output handler for Python objects
window.iodide.addOutputHandler({
shouldHandle : (val) => {
return (typeof val === 'function' && pyodide.PyProxy.isPyProxy(val));
},
render : (val) => {
let div = document.createElement('div');
div.className = 'rendered_html';
var element;
if (val._repr_html_ !== undefined) {
let result = val._repr_html_();
if (typeof result === 'string') {
div.appendChild(new DOMParser()
.parseFromString(result, 'text/html')
.body.firstChild);
element = div;
} else {
element = result;
}
} else {
let pre = document.createElement('pre');
pre.textContent = val.toString();
div.appendChild(pre);
element = div;
}
return element;
}
});
}
});
languagePluginLoader
\ No newline at end of file
.rendered_html {
overflow: auto;
max-height: 30em;
color: black;
/* any extras will just be numbers: */
}
.rendered_html em {
font-style: italic;
}
.rendered_html strong {
font-weight: bold;
}
.rendered_html u {
text-decoration: underline;
}
.rendered_html :link {
text-decoration: underline;
}
.rendered_html :visited {
text-decoration: underline;
}
.rendered_html h1 {
font-size: 185.7%;
margin: 1.08em 0 0 0;
font-weight: bold;
line-height: 1.0;
}
.rendered_html h2 {
font-size: 157.1%;
margin: 1.27em 0 0 0;
font-weight: bold;
line-height: 1.0;
}
.rendered_html h3 {
font-size: 128.6%;
margin: 1.55em 0 0 0;
font-weight: bold;
line-height: 1.0;
}
.rendered_html h4 {
font-size: 100%;
margin: 2em 0 0 0;
font-weight: bold;
line-height: 1.0;
}
.rendered_html h5 {
font-size: 100%;
margin: 2em 0 0 0;
font-weight: bold;
line-height: 1.0;
font-style: italic;
}
.rendered_html h6 {
font-size: 100%;
margin: 2em 0 0 0;
font-weight: bold;
line-height: 1.0;
font-style: italic;
}
.rendered_html h1:first-child {
margin-top: 0.538em;
}
.rendered_html h2:first-child {
margin-top: 0.636em;
}
.rendered_html h3:first-child {
margin-top: 0.777em;
}
.rendered_html h4:first-child {
margin-top: 1em;
}
.rendered_html h5:first-child {
margin-top: 1em;
}
.rendered_html h6:first-child {
margin-top: 1em;
}
.rendered_html ul:not(.list-inline),
.rendered_html ol:not(.list-inline) {
padding-left: 2em;
}
.rendered_html ul {
list-style: disc;
}
.rendered_html ul ul {
list-style: square;
margin-top: 0;
}
.rendered_html ul ul ul {
list-style: circle;
}
.rendered_html ol {
list-style: decimal;
}
.rendered_html ol ol {
list-style: upper-alpha;
margin-top: 0;
}
.rendered_html ol ol ol {
list-style: lower-alpha;
}
.rendered_html ol ol ol ol {
list-style: lower-roman;
}
.rendered_html ol ol ol ol ol {
list-style: decimal;
}
.rendered_html * + ul {
margin-top: 1em;
}
.rendered_html * + ol {
margin-top: 1em;
}
.rendered_html hr {
color: black;
background-color: black;
}
.rendered_html pre {
margin: 1em 2em;
padding: 0px;
background-color: white;
}
.rendered_html code {
background-color: #eff0f1;
}
.rendered_html p code {
padding: 1px 5px;
}
.rendered_html pre code {
background-color: white;
}
.rendered_html pre,
.rendered_html code {
border: 0;
color: black;
font-size: 100%;
}
.rendered_html blockquote {
margin: 1em 2em;
}
.rendered_html table {
margin-left: auto;
margin-right: auto;
border: none;
border-collapse: collapse;
border-spacing: 0;
color: black;
font-size: 12px;
table-layout: fixed;
}
.rendered_html thead {
border-bottom: 1px solid black;
vertical-align: bottom;
}
.rendered_html tr,
.rendered_html th,
.rendered_html td {
text-align: right;
vertical-align: middle;
padding: 0.5em 0.5em;
line-height: normal;
white-space: normal;
max-width: none;
border: none;
}
.rendered_html th {
font-weight: bold;
}
.rendered_html tbody tr:nth-child(odd) {
background: #f5f5f5;
}
.rendered_html tbody tr:hover {
background: rgba(66, 165, 245, 0.2);
}
.rendered_html * + table {
margin-top: 1em;
}
.rendered_html p {
text-align: left;
}
.rendered_html * + p {
margin-top: 1em;
}
.rendered_html img {
display: block;
margin-left: auto;
margin-right: auto;
}
.rendered_html * + img {
margin-top: 1em;
}
.rendered_html img,
.rendered_html svg {
max-width: 100%;
height: auto;
}
.rendered_html img.unconfined,
.rendered_html svg.unconfined {
max-width: none;
}
.rendered_html .alert {
margin-bottom: initial;
}
.rendered_html * + .alert {
margin-top: 1em;
}
[dir="rtl"] .rendered_html p {
text-align: right;
}
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>renderedhtml.css</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/css</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
Notebook Module | view
Notebook | jio_view
Notebook | view
\ No newline at end of file
......@@ -6,6 +6,61 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
......@@ -70,9 +125,12 @@ gadget_notebook.html\n
iodide_master.js\n
iodide_master.css\n
pyodide.js\n
pyodide.asm.data.js\n
pyodide.asm.js\n
pyodide.asm.wasm\n
pyodide.asm.data\n
packages.json\n
renderedhtml.css\n
\n
font-awesome/font-awesome.css\n
font-awesome/font-awesome-webfont.eot\n
......@@ -315,7 +373,7 @@ NETWORK:\n
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>969.41850.61151.55500</string> </value>
<value> <string>969.50674.1572.7867</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -333,7 +391,7 @@ NETWORK:\n
</tuple>
<state>
<tuple>
<float>1534492524.35</float>
<float>1535021998.08</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -24,10 +24,8 @@
<td></td>
</tr>
<tal:block tal:define="web_site_name python: 'officejs_notebook'">
<tal:block
metal:use-macro="here/Zuite_CommonTemplateForOfficejsUi/macros/install_offline_and_redirect"
/>
</tal:block>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForOfficejsUi/macros/install_offline_and_redirect" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[@data-i18n='Storages']</td>
......
......@@ -153,7 +153,7 @@ For that I'm using this undocumented triggerOnKeyDown() method -->
<!-- Laurent : in case the UI of iodide notebooks ever changes, you need to select the "run cell" button here -->
<tr>
<td>click</td>
<td>//*[@class="editor-mode-controls"]/div[5]/button</td>
<td>//*[@class="editor-mode-controls"]/button[5]</td>
<td></td>
</tr>
<tr>
......@@ -345,6 +345,7 @@ For that I'm using this undocumented triggerOnKeyDown() method -->
<td>description</td>
<td>${description}</td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/notebook_module/Zuite_waitForActivities</td>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment