Should we be able to pass a nested value between Omni apps using URL.tellScript(String).call(Function) ?
There is no comment on this in the current API docs, but the very useful omni-automation.com example passes a flat array of strings (top-level OO topics -> named OG canvases), and advises:
“It is important to note that the generated Omni Automation script URL should return some type [of?] data (like a string or an array) as its result” (my emphases)
Must the array contain only simple atomic values ? I have found that data transfer fails with an array of nested dictionaries, and I am not sure whether that is:
- An architectural constraint which could be usefully clarified in the docs (and perhaps on omni-automation.com) ?
- An unintended bug which might prove fixable ?
As an example, the following code does successfully import the full depth of an OmniOutliner outline as a nested tree diagram, but only by getting omniOutliner to return a JSON serialisation of the array of dictionaries (rather than the array itself), and using JSON.parse in OmniGraffle to deserialize the passed JSON string.
(If we try to pass a nested [Dict] array directly, rather than passing a JSON string, we seem to get an array of vanilla Objects stripped of further properties) (and no error message …)
Is this (known / inevitable / by design) or just a bug ?
(() => {
'use strict';
// Rob Trew 2017
// OMNIGRAFFLE 7.5 - OMNIJS CODE TO:
// 1. READ AN OMNIOUTLINER OUTLINE THRU URL.tellScript(s).call(f(v))
// 2. CREATE A NESTED TREE DIAGRAM FROM THE OUTLINE
// OMNI-OUTLINER OUTLINE-READING FUNCTION --------------------------------
// docTextNests :: OO () ->
// [TextNest :: {text :: String, nest :: TextNest}]
const docTextNests = () => {
const tn = x => ({
text: x.topic,
nest: x.children.map(tn)
});
// IT SEEMS THAT WE HAVE TO STRINGIFY HERE ...
// IF WE TRY TO PASS THE ARRAY ITSELF, OMNIGRAFFLE
// GETS ONLY AN ARRAY OF EMPTY OBJECTS ....
return JSON.stringify(document.outline.rootItem.children.map(tn));
};
// OMNIGRAFFLE DIAGRAM-BUILDING FUNCTION ---------------------------------
// Blank Canvas -> Dictionary with text and list of child dictionaries
// -> Root shape of new diagram
// nestedDiagram :: OG Canvas ->
// TextNest :: {text :: String, nest :: TextNest} -> OG Shape
const nestedDiagram = (cnv, dctNode) => {
const shp = cnv.newShape();
return (
// Effect
shp.geometry = new Rect(0, 0, 120, 120),
shp.text = dctNode.text || '',
dctNode.nest.map(x => {
const child = nestedDiagram(cnv, x);
return (cnv.connect(shp, child), child);
}),
// Value
shp
);
};
// EVALUATING OMNI-OUTLINER CODE (FROM INSIDE OMNIGRAFFLE) ---------------
// TO A (STRINGIFIED) NEST OF TEXTS
URL.tellScript('omnioutliner', '(' + docTextNests + ')()')
.call(strJSON => {
const cnv = addCanvas();
document.windows[0].selection.view.canvas = cnv;
cnv.layoutInfo.automaticLayout = true;
// TextNest de-serialized
JSON.parse(strJSON)
// Tree diagram built
.map(x => nestedDiagram(cnv, x));
});
})();