omniJS and GUI disagree over children when text cursor is in parent


#1

The omniJS-model and GUI-display relationship seems to break down over .children when the selected parent is being edited.

They agree when the parent is selected in non-edit state:

but diverge, despite successful script completion and apparently confident return value, when the parent item contains a text-editing cursor:

To test, try pasting and running the following code (reverses sequence of children of first selected node) in the Automation Console, and inspect both the GUI effect, and the omniJS Console log and return value.

In both cases, the script reports the order of the children as now newly reversed.

The GUI display, however, only actually updates if the nature of the selection is non-editing.

omniJS appears not to know that its effect has not propagated, and that its view of the model differs from what the user is seeing.

i.e. it seems to be misleading us, in the current build (5.2 test (v184 r294472)), on the real script outcome, and on the real state of the document.

Not sure what the design intention is here …

(Perhaps a workaround would be for the script to change the nature of the selection before proceeding ?)

// reversedChildren :: OO () -> OO IO String
(() => {
    // GENERIC FUNCTION --------------------------------------------------

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

        // REVERSAL ----------------------------------------------------------
        const
            selnItem = document.editors[0].selectedNodes[0].object,
            childItems = selnItem.children,
            lng = childItems.length,
            outline = document.outline,
            reversedTopics = (
                // The last shall be first (if they are different)
                lng > 1 && outline.moveItems(
                    [childItems[lng - 1]],
                    childItems[0].before
                ),

                // and others come after what once followed them.
                lng > 2 && (() => {
                    const
                        xs = selnItem.children, // (resampled)
                        [h, t] = [xs[0], xs.slice(1)];
                    return t.reduceRight( // reduceRight starts at end of list
                        (a, x) => (
                            outline.moveItems([x], a.after),
                            x
                        ), h, t
                    );
                })(),
                // Final resample before reporting
                selnItem.children.map(x => x.topic)
            );
        return (
            log(reversedTopics),
            reversedTopics
        );
    })()

#2

Further testing suggests that a simpler formulation of this might be that the user won’t see any scripted changes to descendants until they exit the text-editing mode of a parent text cell.

An architecturally inevitable limitation of modal text-editing widgets ?

If so, perhaps users might be helped by a warning that scripts need to force an exit from the text-editing state of parent cells before they can do anything visible with descendant cells ?

i.e. something like:

// Cache the selection
selnNodes = editor.selectedNodes

// Suspend the selection
editor.select([])

// Something scripted happens to selnNodes descendants here ...

// Restore the node selection (tho we lose any text-editing cursor in a cell)
editor.select(selnNodes)