Documentation
This commit is contained in:
parent
124fd26a4a
commit
c478df3a34
|
@ -0,0 +1,101 @@
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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/
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And use 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...
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
# Framework
|
||||||
|
|
||||||
|
This directory includes the Oxygen sample framework on which ou can test the debugger but it should work on any framework.
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,11 @@ startDebugger = function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var context = Packages.org.mozilla.javascript.Context.getCurrentContext();
|
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__);
|
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');
|
var main = Packages.org.mozilla.javascript.tools. debugger.Main.mainEmbedded(contextFactory, scope, 'Debugger'); // start a debugging session ...
|
||||||
main.setExitAction(java.lang.Runnable(runnable));
|
main.setExitAction(java.lang.Runnable(runnable)); // , clean the resources at exit time...
|
||||||
main.setVisible(true);
|
main.setVisible(true); // and make it visible/
|
||||||
|
|
||||||
}
|
}
|
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
After Width: | Height: | Size: 158 KiB |
|
@ -1,14 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Unexpected things happen here...
|
||||||
|
*/
|
||||||
|
|
||||||
function a() {}
|
function a() {}
|
||||||
|
|
||||||
b = function() {}
|
b = function() {}
|
||||||
|
|
||||||
typeof a;
|
// Notice the weird behavior :
|
||||||
typeof b;
|
|
||||||
|
typeof a; // object
|
||||||
|
typeof b; // function
|
||||||
|
|
||||||
aclass = function () {
|
aclass = function () {
|
||||||
// this.foo = 1;
|
|
||||||
this.setFoo(1);
|
this.setFoo(1);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +28,7 @@ anObject.setFoo(2);
|
||||||
|
|
||||||
anObject.foo;
|
anObject.foo;
|
||||||
|
|
||||||
|
// Also worth mentionning, you ***must*** use new and this doesn't work :
|
||||||
|
//
|
||||||
// anobject = aclass();
|
// anobject = aclass();
|
||||||
|
|
||||||
// anobject.setFoo(3);
|
|
Loading…
Reference in New Issue