Documentation
This commit is contained in:
parent
a6e920986f
commit
eca267f712
|
@ -1,98 +1,35 @@
|
|||
# Opening a JavaScript debugger within Oxygen [JS Operations](https://www.oxygenxml.com/doc/versions/23.1/ug-editor/topics/dg-default-author-operations.html#dg-default-author-operations__jsoperation)
|
||||
# Including scripts within Oxygen [JS Operations](https://www.oxygenxml.com/doc/versions/23.1/ug-editor/topics/dg-default-author-operations.html#dg-default-author-operations__jsoperation)
|
||||
|
||||
Even though its authors state that this operation "[can be used to execute small pieces of Javascript code](https://github.com/oxygenxml/javascript-sample-operations)",
|
||||
all the Oxygen and Java public APIs are exposed and this operation can be used for fairly complex tasks.
|
||||
Another limitation of the JS operation is that a single "globals.js" file is loaded before the execution of javascript operation.
|
||||
|
||||
The main limitation is then the lack of a debugger and relying on logs rapidly becomes very tedious to develop complex code.
|
||||
|
||||
The good news is that Oxygen uses Mozilla's [Rhino JavaScript engine](https://en.wikipedia.org/wiki/Rhino_(JavaScript_engine)) and that this engine comes with a
|
||||
[debugger](https://www-archive.mozilla.org/rhino/debugger.html).
|
||||
|
||||
This rambling proposes a way to launch the debugger from a JS Operation.
|
||||
This rambling proposes a way to include other scripts at runtime.
|
||||
|
||||
## Installation
|
||||
|
||||
To do so, add this function to your commons.js file:
|
||||
|
||||
```javascript
|
||||
startDebugger = function () {
|
||||
|
||||
var runnable = {
|
||||
run: function () {
|
||||
main.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var context = Packages.org.mozilla.javascript.Context.getCurrentContext(); // Within the current context...
|
||||
var contextFactory = context.getFactory();
|
||||
var scope = Packages.org.mozilla.javascript.tools.shell.Environment(runnable.__parent__); // and the scope of the runnable variable's parent ...
|
||||
var main = Packages.org.mozilla.javascript.tools. debugger.Main.mainEmbedded(contextFactory, scope, 'Debugger'); // start a debugging session ...
|
||||
main.setExitAction(java.lang.Runnable(runnable)); // , clean the resources at exit time...
|
||||
main.setVisible(true); // and make it visible/
|
||||
|
||||
include = function (filepath, isAbsolute) {
|
||||
if (isAbsolute === undefined || isAbsolute == false) {
|
||||
filepath = Packages.ro.sync.ecss.extensions.commons.operations.CommonsOperationsUtil.expandAndResolvePath(authorAccess, filepath);
|
||||
}
|
||||
var text = new java.lang.String(java.nio.file.Files.readAllBytes(java.nio.file.Paths. get (java.net.URI(filepath))));
|
||||
text = String(text);
|
||||
eval(text);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And use it in the script parameter of the JS operation:
|
||||
And use the include() function it in the script parameter of the JS operation:
|
||||
```javascript
|
||||
doOperation = startDebugger;
|
||||
```
|
||||
|
||||
To call the action which uses this operation, you can attach it to a menu or tool icon or just define a shortkey and you're done !
|
||||
|
||||
Call this action and you'll pop up a nice vintage debugger :
|
||||
![debugger.jpg](debugger.jpg)
|
||||
|
||||
Use the File menu to open or run the file to debug (such as [test.js]):
|
||||
![debugger2.jpg](debugger2.jpg)
|
||||
|
||||
There are a few things to know before using it, though...
|
||||
doOperation = function () {
|
||||
include('hello.js');
|
||||
hello();
|
||||
}```
|
||||
|
||||
## Limitations
|
||||
|
||||
### Scope
|
||||
|
||||
I haven't found a way to simply grab the current scope object in JavaScript and the closest method I have found is:
|
||||
```javascript
|
||||
Packages.org.mozilla.javascript.tools.shell.Environment(runnable.__parent__)
|
||||
```
|
||||
|
||||
This creates a scope with everything in the runnable's parent's scope augmented with the environment variables with may not be present in the current scope.
|
||||
|
||||
|
||||
All the other methods I have tried gave scopes which were, on the contrary, reduced compared to the current scope and lacking, for instance, the authorAcces object
|
||||
without which you can't interact with Oxygen.
|
||||
|
||||
### Functions seen as objects
|
||||
|
||||
Just try it by yourself in the "evaluate" window:
|
||||
```javascript
|
||||
function a() {}
|
||||
|
||||
b = function() {}
|
||||
```
|
||||
"a" is seen as an object and not as a function, meaning that you can't call it. "b" is, correctly, seen as a function.
|
||||
|
||||
### Strict behavior on instanciation.
|
||||
|
||||
The word "new" is mandatory when instanciating a "class" (which is not the case when a JS operation script is run out of the debugger):
|
||||
|
||||
```javascript
|
||||
aclass = function () {
|
||||
this.setFoo(1);
|
||||
return this;
|
||||
}
|
||||
|
||||
aclass.prototype.setFoo = function (v) {
|
||||
this.foo = v;
|
||||
}
|
||||
|
||||
anObject = new aclass() ; // works as expected
|
||||
|
||||
anobject = aclass(); // fails with a message saying that there is no setFoo function in the object
|
||||
|
||||
```
|
||||
The function needs an authorAccess variable in order to resolve relative URIs and this variable is only available in the scope of the doOperation function. This means that you can't use it
|
||||
outside of this function call, like, for instance, in the global scope of the common.js script.
|
||||
|
||||
# Framework
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 38 KiB |
|
@ -1,21 +0,0 @@
|
|||
startDebugger = function () {
|
||||
|
||||
var runnable = {
|
||||
run: function () {
|
||||
main.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var context = Packages.org.mozilla.javascript.Context.getCurrentContext();
|
||||
// Within the current context...
|
||||
var contextFactory = context.getFactory();
|
||||
var scope = Packages.org.mozilla.javascript.tools.shell.Environment(runnable.__parent__);
|
||||
// and the scope of the runnable variable's parent ...
|
||||
var main = Packages.org.mozilla.javascript.tools. debugger.Main.mainEmbedded(contextFactory, scope, 'Debugger');
|
||||
// start a debugging session ...
|
||||
main.setExitAction(java.lang.Runnable(runnable));
|
||||
// , clean the resources at exit time...
|
||||
main.setVisible(true);
|
||||
// and make it visible/
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 158 KiB |
|
@ -762,56 +762,6 @@
|
|||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
</action>
|
||||
<action>
|
||||
<field name="id">
|
||||
<String>debugger</String>
|
||||
</field>
|
||||
<field name="name">
|
||||
<String>debugger</String>
|
||||
</field>
|
||||
<field name="description">
|
||||
<String>Open a JS debugger</String>
|
||||
</field>
|
||||
<field name="largeIconPath">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="smallIconPath">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="accessKey">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="accelerator">
|
||||
<String>M1 M2 D</String>
|
||||
</field>
|
||||
<field name="actionModes">
|
||||
<actionMode-array>
|
||||
<actionMode>
|
||||
<field name="xpathCondition">
|
||||
<String></String>
|
||||
</field>
|
||||
<field name="argValues">
|
||||
<serializableOrderedMap>
|
||||
<entry>
|
||||
<String>script</String>
|
||||
<String>doOperation = function () {
|
||||
include('debugger.js');
|
||||
startDebugger();
|
||||
}
|
||||
</String>
|
||||
</entry>
|
||||
</serializableOrderedMap>
|
||||
</field>
|
||||
<field name="operationID">
|
||||
<String>ro.sync.ecss.extensions.commons.operations.JSOperation</String>
|
||||
</field>
|
||||
</actionMode>
|
||||
</actionMode-array>
|
||||
</field>
|
||||
<field name="enabledInReadOnlyContext">
|
||||
<Boolean>false</Boolean>
|
||||
</field>
|
||||
</action>
|
||||
<action>
|
||||
<field name="id">
|
||||
<String>hello</String>
|
||||
|
|
Loading…
Reference in New Issue