Bug: Default object query syntax fails in JXA with OG obj.class() property

When the canvas contains graphics of different classes (shapes, lines, and a group for example) we can write:

// Canvas of first document window
Application("OmniGraffle").windows.whose({
	_not: [{ document: null }]
}).windows.at(0).canvas

// Array of class strings for graphics on this canvas
.graphics.class()

If, however, we use the default JavaScript for Automation .whose() or .where() object query syntax to find only graphics of a particular class, the query, which works well with all other properties, fails with the ‘class’ key.

The interpreter reduces:

// Canvas of first document window
Application("OmniGraffle").windows.whose({
	_not: [{ document: null }]
}).windows.at(0).canvas

// reference to subset of graphics
.graphics.whose({
	"class": "line"
})

to the corresponding ObjectSpecifier() notation

Application("OmniGraffle").windows.whose({_not: [{_match: [ObjectSpecifier().document, null]}]}).windows.at(0).canvas.graphics.whose({_match: [ObjectSpecifier().class, "line"]})

which is correct, but anomalously finds no matches when automatically derived in this way from the {key: value} condition notation.

// Canvas of first document window
Application("OmniGraffle").windows.whose({
	_not: [{ document: null }]
}).windows.at(0).canvas

// reference to subset of graphics
.graphics.whose({
	"class": "line"
}).class()

returns []

whereas

Application("OmniGraffle").windows.whose({_not: [{_match: [ObjectSpecifier().document, null]}]}).windows.at(0).canvas.graphics.whose({_match: [ObjectSpecifier().class, "line"]}).class()

if directly entered as source script, succeeds, returning ["line", "line", "line"]

WORKAROUND

To avoid this bug, which affects only the “class” property key, we have to directly use the more circuitous ObjectSpecifier() syntax directly, and avoid, for the "class" key alone, the default {key: value} syntax.

Possibly a hangover from the reserved keyword role of class in AppleScript ?

1 Like

Summary code for testing

  • Two forms that succeed with other properties, but fail with class
  • Two more circuitous forms that do succeed
(function () {
    'use strict';

    var og = Application('OmniGraffle'),
        ws = og.windows.whose({
            _not: [{
                document: null
            }]
        }),
        w = ws.length ? ws.at(0) : undefined,
        cnv = w ? w.canvas : undefined,
        gs = cnv ? cnv.graphics : undefined,
        slns = w ? w.selection() : [],
        lng = slns.length,
        lines;

    // 1. FAILS TO FIND THE MATCHES
    lines = gs.whose({
        "class": "line"
    });

    //  2. ALSO FAILS TO FIND THE MATCHES
    lines = gs.whose({
        "class": {
            _equals: "line"
        }
    });

    //  3. SUCCEEDS
    lines = gs.whose({
        _match: [ObjectSpecifier().class, "line"]
    });

    //  4. ALSO SUCCEEDS (bracket notation in lieu of dot notation
    //     for the property accessor)
    lines = gs.whose({
        _match: [ObjectSpecifier()['class'], "line"]
    });

    return lines.class();
})();