Scraping a return value from the omniJS Console

A couple of obstacles to testing OmniGraffle 7.3 scripting:

  1. The window.selection method fails in AppleScript and JXA, which makes it harder to test other things in a useful way – we can’t read the selection array and apply scripts to the graphics it contains.
    UPDATE: Now fixed in 7.3.1 test (v177.5 r285572)
  2. Selection works in omniJS, but it can’t (I think ?) return a value like a shape ID in a way that JXA can use.

This seems like a fairly important general gap at the moment (getting a return value from an omniJS script), and here for example, in testing some things in JXA, I would delegate the reading of the current selection to omniJS if I could.

One shameless hack that we can perform, however, is to scrape a return value (in stringified form) from the omniJS Scripting Console.

Here, for example, is a JXA script for OmniGraffle 7.3 which returns an array of text lines from the omniJS console:

(() => {
    // ver 0.4
    'use strict';

    // concat :: [[a]] -> [a] | [String] -> String
    const concat = xs =>
        xs.length > 0 ? (() => {
            const unit = typeof xs[0] === 'string' ? '' : [];
            return unit.concat.apply(unit, xs);
        })() : [];

    // init :: [a] -> [a]
    const init = xs => xs.length > 0 ? xs.slice(0, -1) : [];

    // show :: a -> String
    const show = x => JSON.stringify(x, null, 2);

    // log :: a -> IO ()
    const log = (...args) =>
        console.log(
            args
            .map(show)
            .join(' -> ')
        );

    // omniJSConsoleStrings :: () -> [String]
    function omniJSConsoleStrings() {
        const
            se = Application("System Events"),
            procs = se.applicationProcesses.where({
                name: {
                    _contains: 'OmniGraffle'
                }
            }),
            pOG = procs.length > 0 ? [procs.at(0)] : [];

        return (pOG.length > 0) ? (() => {
            const
                ws = pOG[0].windows.where({
                    name: {
                        _beginsWith: 'Scripting Console'
                    }
                }),
                groups = ws.length > 0 ? ws.at(0)
                .scrollAreas.at(0)
                .uiElements.at(0)
                .groups.at(0)
                .groups() : [];

            return init(concat(groups.map(g =>
                g.subrole() !== "AXPreformattedStyleGroup" ? [] : (
                    g.staticTexts.value()
                    .join('')
                ))));
        })() : [];
    }

    return show(
        omniJSConsoleStrings()
    );
})();