Using Omnigraffle.evaluateJavascript()

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:

ALPHA

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 + ')()'
        )
    );
})();
1 Like