omniJS - iOS code vs macOS code (narrowing the two-version gap)

The need to maintain different versions of omniJS plugins and scripts for iOS and macOS, will probably be hard to eliminate entirely (builds on both sides will rarely be at identical development stages),

but, given the appealing ‘write-once’ goal of narrowing that gap where possible, perhaps worth collecting notes on where the differences are showing up ?

(See following posts)

iOS: Console.log() from URL-launched scripts.

Problem / difference:

With URL-launched scripts, the current iOS build (179.8.0.291436) seems to lose/discard the console.log output. This makes it a little impractical to develop, experiment or debug using iOS with URL-launching at the moment.

(The macOS version shows console.log strings from Plugins and URL scripts, but the iOS version only from Plugins):

Builds:

macOS: OmniGraffle 7.4 test (v179.5 r291208
iOS: OG 3 179.8.0.291436

Test:

Running the following code from the Web Console in Safari (or through any other URL-opening channel), lets us see the console.log output in macOS, but not in IOS.

    var cnv = document.windows[0].selection.canvas;
    cnv.layout();
    console.log("message from url evaluation")

The console.log message is seen in the macOS console

but not in the iOS console:

iOS vs macOS: Updating the selection object reference passed to Plugin menu and plugin toolbar button handlers after a scripted change of selected canvas:

Problem / difference:

If a URL-launched (or console-executed) script

  1. Creates a new canvas, and
  2. selects it with a line like:
    document.windows[0].selection.view.canvas = newCanvas;

On macOS the selection object passed to Plugin menu and toolbar - button handlers is immediately and correctly updated, so that functions invoked with plugin widgets get the expected reference to the newly selected canvas.

On iOS the selection object is not immediately updated, and still refers to the canvas that had the selection before the script ran, so that Plugin menu items and plugin toolbar button functions either fail, or attempt to produce effects in the wrong canvas.

(The selection object passed to plugin events is not updated until the user manually unselects and then reselects the new (script created and script-selected) canvas in the GUI.

Builds:

macOS: OmniGraffle 7.4 test (v179.5 r291208
iOS: OG 3 179.8.0.291436

Test:

First, script:

  1. The creation of a new canvas and a couple of shapes
  2. The setting of the front window selection to this new canvas

Then, try to use a plugin menu or a plugin button on the toolbar.

This will work on macOS, but fail on iOS. On iOS the plugin will be passed a reference to the previously selected (pre-script run) canvas.

On iOS, plugins won’t work in these circumstances until you manually take focus away from the new canvas, and then manually return it (though GUI interactions).

Test script:

(function () {
    'use strict';

    // 1. NEW CANVAS WITH 2 LINKED SHAPES
    // 2  MAKE IT THE CANVAS SELECTED IN THE FRONT WINDOW
    var
        newCanvas = addCanvas(),
        dctShapeStyle = {
            shape: "Circle",
            cornerRadius: 5,
            shadowColor: null,
            strokeColor: Color.RGB(
                0.647058844566345, 0.647058844566345, 0.647058844566345
            ),
            magnets: [new Point(0.00, 1.00), new Point(0.00, -1.00)],
        },
        shpA = Object.assign(
            newCanvas.newShape(),
            dctShapeStyle, {
                geometry: new Rect(100, 100, 50, 50),
            }
        ),
        shpB = Object.assign(
            newCanvas.newShape(),
            dctShapeStyle, {
                geometry: new Rect(200, 200, 50, 50)
            }
        );

    Object.assign(
        newCanvas.newLine(), {
            strokeThickness: 2,
            tail: shpA,
            lineType: LineType.Curved,
            head: shpB,
            shadowColor: null,
            strokeColor: Color.RGB(1.0, 0.149131417274475, 0.0)
        }
    );

    // SCRIPTED CHANGE OF SELECTED CANVAS
    document.windows[0].selection.view.canvas = newCanvas;

    // Now try to use a plugin menu or toolbar item.

    // On iOS, the plugin widgets will still get the wrong selected canvas,
    // until you manually toggle the selection in the GUI.

    // On macOS, the plugin widgets are immediately getting a reference
    // to the newly selected canvas.
})();

See also: Divergent selection API on macOS and iOS ?

Just to keep track of differing effects of the same script on the two platforms, this bug is seen on macOS but not on iOS:

Fonts are a simple but real obstacle to the ‘write-once’ goal for omniJS code.

If I open a .graffle file from macOS on iOS, I may be greeted by an alert which offers to substitute a font like ‘Monaco’ for example, with some other font that is on the iOS system.

At the moment, however, if I use Edit > Copy As > JavaScript on macOS, and then try to run the generated code on iOS, the code will simply fail with a .fontName error if any of the fonts in the macOS diagram are not to be found on iOS.

Perhaps worth thinking about something like:

  1. An alert and font substitution scheme - like that used when documents are opened ?
  2. An option or default to bypass alerts and simply using some other font that iOS does have ?
  3. A .fontFamily key for fall-back when .fontName finds no local match ?