omniJS crashing OG7 test 7.4 - check a leaf node for children

The excellent new OGOutlineNode interface seems to have a small teething problem with outline leaf nodes

Product: OmniGraffle-7.4.x
Tag:
Date: 2017-06-19 21:39:52 -0700
Builder: omnibuild
Host: tb1010f.private.omnigroup.com
Revision: 290241

(shapes which do have incoming connectors, but have no outgoing connectors, like the daughter node below)

If we ask omniJS for the .children property of the leaf node here, in lieu of the expected empty array, we are currently getting a full and instant app crash.

TEST

  1. Create a pair of shapes and link them, so that we have a parent and a child
  2. Ask omniJS (through the virtual root -> real parent -> leaf-child chain) for any .children of the child node by pasting the following into the Automation Console and hitting return.
(() => document.windows[0]
    .selection.canvas.outlineRoot  // virtual root (allowing for multiple trees)
    .children[0]                   // Parent
    .children[0]                   // Daughter
    .children)();                  // Expected empty Array, but triggered crash

PS given that in an empty document (where canvas.outlineRoot is itself a kind of leaf with no children) this works fine:

and given also that (for the moment at least) the API lists the type of OGOutlineNode.children as Array, I think the most useful behaviour would be for leaf shapes to return an empty Array ( [ ] rather than undefined or null) from OGOutlineNode.children

In the meanwhile, if anyone is in a hurry to traverse diagram structures with the OGOutlineNodes interface (which, unlike .graphic.outgoingLines, lets a script know sibling sequences as well as parent-child nesting) we can still reroute to bypass the crash by testing for leaf status with something like:

.graphic.outgoingLines.length < 1

For example:

(() => {
    // readTree :: OG () -> JSON String
    const readTree = () => {

        // show :: a -> String
        const show = (...x) =>
            JSON.stringify.apply(
                null, x.length > 1 ? [x[0], null, x[1]] : x
            );

        // textNest :: OGoutlineNodes -> Node {text: String, nest:[Node]}
        const textNest = xs =>
            xs.length ? (
                xs.map(x => {
                    const
                        g = x.graphic,
                        isLeaf = g.outgoingLines.length < 1;
                    return {
                        text: g.text,
                        nest: isLeaf ? [] : textNest(x.children)
                    }
                })
            ) : [];

        return show(textNest(
            document.windows[0].selection.canvas.outlineRoot.children
        ));
    };

    return readTree();
})();
1 Like

Thanks for the bug report! This is now fixed in revision 290263.

1 Like

That was quick !

Thank you - I appreciate that

It’s working flawlessly – the snippet above is now simpler to write:

(() => {
    // readTree :: OG () -> JSON String
    const readTree = () => {

        // show :: a -> String
        const show = (...x) =>
            JSON.stringify.apply(
                null, x.length > 1 ? [x[0], null, x[1]] : x
            );

        // textNest :: OGoutlineNodes -> Node {text: String, nest:[Node]}
        const textNest = xs =>
            xs.length ? xs.map(x => ({
                text: x.graphic.text,
                nest: x.children.length > 0 ? (
                    textNest(x.children)
                ) : []
            })) : [];

        return show(textNest(
            document.windows[0].selection.canvas.outlineRoot.children
        ));
    };

    return readTree();
})();