More documentation

This commit is contained in:
Eric van der Vlist 2021-04-25 14:37:47 +02:00
parent 0cd619bf73
commit d03f8e1f65
8 changed files with 103 additions and 92 deletions

View File

@ -1,19 +1,23 @@
# 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) # Alltogether: 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) through inclusion
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)", This rambling shows how a [debugger](../js-debugger) can be launched using an [inclusion](../js-include).
all the Oxygen and Java public APIs are exposed and this operation can be used for fairly complex tasks.
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.
## Installation ## Installation
To do so, add this function to your commons.js file: To do so:
### 1) add the include() function to your commons.js file:
```javascript
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);
}
```
### 2) create a debugger.js file:
```javascript ```javascript
startDebugger = function () { startDebugger = function () {
@ -24,78 +28,32 @@ startDebugger = function () {
} }
var context = Packages.org.mozilla.javascript.Context.getCurrentContext(); // Within the current context... var context = Packages.org.mozilla.javascript.Context.getCurrentContext();
// Within the current context...
var contextFactory = context.getFactory(); 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 scope = Packages.org.mozilla.javascript.tools.shell.Environment(runnable.__parent__);
var main = Packages.org.mozilla.javascript.tools. debugger.Main.mainEmbedded(contextFactory, scope, 'Debugger'); // start a debugging session ... // and the scope of the runnable variable's parent ...
main.setExitAction(java.lang.Runnable(runnable)); // , clean the resources at exit time... var main = Packages.org.mozilla.javascript.tools. debugger.Main.mainEmbedded(contextFactory, scope, 'Debugger');
main.setVisible(true); // and make it visible/ // start a debugging session ...
main.setExitAction(java.lang.Runnable(runnable));
// , clean the resources at exit time...
main.setVisible(true);
// and make it visible/
} }
``` ```
### 3) Use these functions in your doOperation() method:
And use it in the script parameter of the JS operation:
```javascript ```javascript
doOperation = startDebugger; doOperation = function () {
``` include('debugger.js');
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...
## 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
``` ```
## See also
More details on these hacks:
* [debugger](../js-debugger)
* [inclusion](../js-include)
# Framework # Framework
This directory includes the Oxygen sample framework on which ou can test the debugger but it should work on any framework. This directory includes the Oxygen sample framework on which ou can test these techniques but they should work on any framework.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

View File

@ -2,9 +2,25 @@
<project version="21.1"> <project version="21.1">
<meta> <meta>
<filters directoryPatterns="" filePatterns="\Qjs-debugger.xpr\E" positiveFilePatterns="" showHiddenFiles="false"/> <filters directoryPatterns="" filePatterns="\Qjs-debugger.xpr\E" positiveFilePatterns="" showHiddenFiles="false"/>
<options/> <options>
<serialized version="21.1" xml:space="preserve">
<serializableOrderedMap>
<entry>
<String>additional.frameworks.directories</String>
<String-array>
<String>/home/vdv/projects/pro/Remix/oxygen/frameworks/http___oxygen.remix.rece.hachette_livre.fr_oxygenUpdate.xml</String>
<String>/home/vdv/projects/tea/dyomedea/ramblings/oxygen/js-debugger-include</String>
</String-array>
</entry>
<entry>
<String>key.editor.document.type.custom.locations.option.pane</String>
<Boolean>true</Boolean>
</entry>
</serializableOrderedMap>
</serialized>
</options>
</meta> </meta>
<projectTree name="js-debugger.xpr"> <projectTree name="js-debugger-include.xpr">
<folder path="."/> <folder path="."/>
</projectTree> </projectTree>
</project> </project>

View File

@ -93,6 +93,9 @@ anObject = new aclass() ; // works as expected
anobject = aclass(); // fails with a message saying that there is no setFoo function in the object anobject = aclass(); // fails with a message saying that there is no setFoo function in the object
``` ```
## See also
* [inclusion](../js-include)
* [debugger + inclusion](../js-debugger-include)
# Framework # Framework

View File

@ -2,7 +2,23 @@
<project version="21.1"> <project version="21.1">
<meta> <meta>
<filters directoryPatterns="" filePatterns="\Qjs-debugger.xpr\E" positiveFilePatterns="" showHiddenFiles="false"/> <filters directoryPatterns="" filePatterns="\Qjs-debugger.xpr\E" positiveFilePatterns="" showHiddenFiles="false"/>
<options/> <options>
<serialized version="21.1" xml:space="preserve">
<serializableOrderedMap>
<entry>
<String>additional.frameworks.directories</String>
<String-array>
<String>/home/vdv/projects/pro/Remix/oxygen/frameworks/http___oxygen.remix.rece.hachette_livre.fr_oxygenUpdate.xml</String>
<String>/home/vdv/projects/tea/dyomedea/ramblings/oxygen/js-debugger</String>
</String-array>
</entry>
<entry>
<String>key.editor.document.type.custom.locations.option.pane</String>
<Boolean>true</Boolean>
</entry>
</serializableOrderedMap>
</serialized>
</options>
</meta> </meta>
<projectTree name="js-debugger.xpr"> <projectTree name="js-debugger.xpr">
<folder path="."/> <folder path="."/>

View File

@ -31,9 +31,11 @@ doOperation = function () {
## Limitations ## Limitations
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 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. outside of this function call, like, for instance, in the global scope of the common.js script.
## See also
* [debugger](../js-debugger)
* [debugger + inclusion](../js-debugger-include)
# Framework # Framework
This directory includes the Oxygen sample framework on which ou can test the debugger but it should work on any framework. This directory includes the Oxygen sample framework on which ou can test this techniwue but it should work on any framework.

View File

@ -2,9 +2,25 @@
<project version="21.1"> <project version="21.1">
<meta> <meta>
<filters directoryPatterns="" filePatterns="\Qjs-debugger.xpr\E" positiveFilePatterns="" showHiddenFiles="false"/> <filters directoryPatterns="" filePatterns="\Qjs-debugger.xpr\E" positiveFilePatterns="" showHiddenFiles="false"/>
<options/> <options>
<serialized version="21.1" xml:space="preserve">
<serializableOrderedMap>
<entry>
<String>additional.frameworks.directories</String>
<String-array>
<String>/home/vdv/projects/pro/Remix/oxygen/frameworks/http___oxygen.remix.rece.hachette_livre.fr_oxygenUpdate.xml</String>
<String>/home/vdv/projects/tea/dyomedea/ramblings/oxygen/js-include</String>
</String-array>
</entry>
<entry>
<String>key.editor.document.type.custom.locations.option.pane</String>
<Boolean>true</Boolean>
</entry>
</serializableOrderedMap>
</serialized>
</options>
</meta> </meta>
<projectTree name="js-debugger.xpr"> <projectTree name="js-include.xpr">
<folder path="."/> <folder path="."/>
</projectTree> </projectTree>
</project> </project>