I’m not sure when the .evaluateJavascript()
method was added to macOS OG7, but it’s going to be very useful.
Unlike the more fiddly technique of invoking omnijs-run
urls, evaluateJavascript()
actually returns a value from omniJS code.
In current OG builds (as in current OO) builds, it already works well with simple JSON-representable return values, but will still crash the app if we try to return complex object values.
For example, I find that I can successfully obtain a list of shape texts in the front canvas by evaluating this code in Script Editor, with the JavaScript language tab selected in the top right corner:
(() => {
'use strict';
// OMNIJS CODE -----------------------------------------------------------
const shapeTexts = () => [].concat.apply([],
document.portfolio.canvases[0].graphics.map(
x => x.constructor.name === 'Shape' ? [x.text] : []
))
.join('\n');
// JXA CODE --------------------------------------------------------------
return Application('OmniGraffle')
.evaluateJavascript(
'(' + shapeTexts + ')()'
);
})();
For more complex values, it’s is sensible to wrap the return value in an application of JSON.stringify()
;
The serialized return value can then be restored and used in JXA with JSON.parse();
This makes sense even for JS Arrays, which .evaluateJavascript
is currently returning as dictionaries.
So, for example, to get a simple array of texts back to JXA from a diagram like:
We could run the following in Script Editor
Source:
(() => {
// OMNIJS CODE -------------------------------------------------
const shapeTextList = () => JSON.stringify(
[].concat.apply([],
document.portfolio.canvases[0].graphics.map(
x => x.constructor.name === 'Shape' ? [x.text] : []
).sort()
)
);
// JXA CODE ----------------------------------------------------
return JSON.parse(
Application('OmniGraffle')
.evaluateJavascript(
'(' + shapeTextList + ')()'
)
);
})();