URL: App-to-App Scripting

A fundamental principle of user-automation is:

No application is an island.

In other words, it is quite appropriate to expect scripts to be able to extract and share data between multiple applications. After all, that’s the way we work, why shouldn’t our automation tools do the same?

To facilitate the sharing of data between Omni applications, a “Call and Response” scenario is implemented in OmniJS scripts. With “Call and Response” a host application gathers data from another application, and then uses that data in performing actions with its own document and objects. For example, a script executed in OmniGraffle may use the topics from the current OmniOutliner document, to create named text objects in the current OmniGraffle document.

To extract or gather data from another application, the script run by the host application uses either the tellScript() or fromString() methods from the URL class, to generate a new OmniJS script URL. This script URL is then executed by the host script using the call() method of the URL class, which has as its direct parameter, a call-back function to process the results returned from the OmniJS URL script. It is important to note that the generated OmniJS script URL should return some type data (like a string or an array) as its result.

The following materials show how to implement either of the two available techniques for deploying “call and response” automation between applications from the Omni Group.

The Calling Script is OmniJS Code

The first technique for performing “Call and Response” uses the tellScript() method of the URL class to create a URL object by converting the quoted code of an OmniJS script into an OmniJS script URL (line 1 below). The tellScript() method takes two parameters:

var scriptURL = URL.tellScript("nameOfTargetApp",' // SCRIPT TO BE EXECUTED BY TARGET APP ') scriptURL.call(function(reply){ // CODE FOR DEALING WITH RESULTS OF SCRIPT })

To execute the created script URL, the call() method is applied to the script URL object (line 4 above). This method has a call-back function as its parameter. This call-back function includes the passed result of the script URL execution as its sole parameter. These results are then used by the code in the host script (line 5) when the call-back function gets called.

Using the tellScript() method to perform call and response offers the advantage of providing easy editing of both the calling and response scripts. With this approach, you can quickly alter either script as needed. Below is an example of call and response using the tellScript() method to create the calling script URL.

IMPORTANT: note the inclusion of both the trailing semi-colon AND backslash character (\) together at the end of each of the lines of calling script code. As the script code text is combined to a single-line, these characters ensure that the script code is read correctly as it is converted from text to code during the script execution.

var scriptURL = URL.tellScript("omnioutliner",'\ var titles = [];\ var items = rootItem.children;\ var i;\ for (i = 0; i < items.length; i++) {\ titles[i] = items[i].topic;\ };\ titles;\ ') scriptURL.call(function(reply){ var aCanvas = document.windows[0].selection.canvas var aCanvasSize = aCanvas.size var cW = aCanvasSize.width var cH = aCanvasSize.height var typeSize = Math.round(cH/cW*100) for (i = 0; i < reply.length; i++){ replyItem = reply[i] if(i != 0){ aCanvas = addCanvas() aCanvas.size = aCanvasSize } aCanvas.name = replyItem aShape = aCanvas.newShape() aShape.text = replyItem aShape.textSize = typeSize aShape.autosizing = TextAutosizing.Full aShape.textHorizontalAlignment = HorizontalTextAlignment.Center aShape.shadowColor = null aShape.strokeType = null aShape.strokeColor = null aShapeGeo = aShape.geometry aRect = new Rect(cW/2 - aShapeGeo.width/2, typeSize, aShapeGeo.width, aShapeGeo.height) aShape.geometry = aRect aShape.text = "<%Canvas%>" } })
omnigraffle:///omnijs-run?script=var%20scriptURL%20%3D%20URL%2EtellScript%28%22omnioutliner%22%2C%27%5C%0Avar%20titles%20%3D%20%5B%5D%3B%5C%0Avar%20items%20%3D%20rootItem%2Echildren%3B%5C%0Avar%20i%3B%5C%0Afor%20%28i%20%3D%200%3B%20i%20%3C%20items%2Elength%3B%20i%2B%2B%29%20%7B%5C%0A%09titles%5Bi%5D%20%3D%20items%5Bi%5D%2Etopic%3B%5C%0A%7D%3B%5C%0Atitles%3B%5C%0A%27%29%0AscriptURL%2Ecall%28function%28reply%29%7B%0A%09var%20aCanvas%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Ecanvas%0A%09var%20aCanvasSize%20%3D%20aCanvas%2Esize%0A%09var%20cW%20%3D%20aCanvasSize%2Ewidth%0A%09var%20cH%20%3D%20aCanvasSize%2Eheight%0A%09var%20typeSize%20%3D%20Math%2Eround%28cH%2FcW*100%29%0A%09for%20%28i%20%3D%200%3B%20i%20%3C%20reply%2Elength%3B%20i%2B%2B%29%7B%0A%09%09replyItem%20%3D%20reply%5Bi%5D%0A%09%09if%28i%20%21%3D%200%29%7B%0A%09%09%09aCanvas%20%3D%20addCanvas%28%29%0A%09%09%09aCanvas%2Esize%20%3D%20aCanvasSize%0A%09%09%7D%0A%09%09aCanvas%2Ename%20%3D%20replyItem%0A%09%09aShape%20%3D%20aCanvas%2EnewShape%28%29%0A%09%09aShape%2Etext%20%3D%20replyItem%0A%09%09aShape%2EtextSize%20%3D%20typeSize%0A%09%09aShape%2Eautosizing%20%3D%20TextAutosizing%2EFull%0A%09%09aShape%2EtextHorizontalAlignment%20%3D%20HorizontalTextAlignment%2ECenter%0A%09%09aShape%2EshadowColor%20%3D%20null%0A%09%09aShape%2EstrokeType%20%3D%20null%0A%09%09aShape%2EstrokeColor%20%3D%20null%0A%09%09aShapeGeo%20%3D%20aShape%2Egeometry%0A%09%09aRect%20%3D%20new%20Rect%28cW%2F2%20-%20aShapeGeo%2Ewidth%2F2%2C%20typeSize%2C%20aShapeGeo%2Ewidth%2C%20aShapeGeo%2Eheight%29%0A%09%09aShape%2Egeometry%20%3D%20aRect%0A%09%09aShape%2Etext%20%3D%20%22%3C%25Canvas%25%3E%22%0A%09%7D%0A%7D%29

When the script example (shown above) is executed, a new canvas will be created in OmniGraffle for each of the topics in the OmniOutliner document. In addition, the title of the topic will be displayed on the new canvas, centered horizontally at the top.

The Calling Script is an OmniJS URL String

The second technique for implementing “Call and Response” in an OmniJS script, it to use the fromString() method of the URL class to convert an encoded OmniJS script URL string into a URL object, and then execute the script URL object using the call() method of the URL class as in the previous example.

TIP: For detailed information about creating OmniJS links, vist this webpage.

var scriptURL = URL.fromString(' // ENCODED SCRIPT URL TO BE EXECUTED BY TARGET APP ') scriptURL.call(function(reply){ // CODE FOR DEALING WITH RESULTS OF SCRIPT })

In the script outline shown above, the percent-encoded script URL string is entered as the direct parameter of the fromString() method. This method creates a new URL object from the script URL string.

To execute the created script URL object, the call() method is applied to the script URL object (line 4 above). This method has a call-back function as its parameter. This call-back function includes the passed result of the script URL execution as its sole parameter. These results are then used by the code in the host script (line 5) when the call-back function gets called.

Below is an example of call and response using the fromString() method of the URL class to create the calling script URL object.

var scriptURL = URL.fromString('omnioutliner:///omnijs-run?script=var%20titles%20%3D%20%5B%5D%0Avar%20items%20%3D%20rootItem%2Echildren%0Avar%20i%0Afor%20%28i%20%3D%200%3B%20i%20%3C%20items%2Elength%3B%20i%2B%2B%29%20%7B%0A%09titles%5Bi%5D%20%3D%20items%5Bi%5D%2Etopic%0A%7D%0Atitles') scriptURL.call(function(reply){ var aCanvas = document.windows[0].selection.canvas var aCanvasSize = aCanvas.size var cW = aCanvasSize.width var cH = aCanvasSize.height var typeSize = Math.round(cH/cW*100) for (i = 0; i < reply.length; i++){ replyItem = reply[i] if(i != 0){ aCanvas = addCanvas() aCanvas.size = aCanvasSize } aCanvas.name = replyItem aShape = aCanvas.newShape() aShape.text = replyItem aShape.textSize = typeSize aShape.autosizing = TextAutosizing.Full aShape.textHorizontalAlignment = HorizontalTextAlignment.Center aShape.shadowColor = null aShape.strokeType = null aShape.strokeColor = null aShapeGeo = aShape.geometry aRect = new Rect(cW/2 - aShapeGeo.width/2, 72, aShapeGeo.width, aShapeGeo.height) aShape.geometry = aRect aShape.text = "<%Canvas%>" } })
omnigraffle:///omnijs-run?script=var%20scriptURL%20%3D%20URL%2EfromString%28%27omnioutliner%3A%2F%2F%2Fomnijs-run%3Fscript%3Dvar%2520titles%2520%253D%2520%255B%255D%250Avar%2520items%2520%253D%2520rootItem%252Echildren%250Avar%2520i%250Afor%2520%2528i%2520%253D%25200%253B%2520i%2520%253C%2520items%252Elength%253B%2520i%252B%252B%2529%2520%257B%250A%2509titles%255Bi%255D%2520%253D%2520items%255Bi%255D%252Etopic%250A%257D%250Atitles%27%29%0AscriptURL%2Ecall%28function%28reply%29%7B%0A%09var%20aCanvas%20%3D%20document%2Ewindows%5B0%5D%2Eselection%2Ecanvas%0A%09var%20aCanvasSize%20%3D%20aCanvas%2Esize%0A%09var%20cW%20%3D%20aCanvasSize%2Ewidth%0A%09var%20cH%20%3D%20aCanvasSize%2Eheight%0A%09var%20typeSize%20%3D%20Math%2Eround%28cH%2FcW*100%29%0A%09for%20%28i%20%3D%200%3B%20i%20%3C%20reply%2Elength%3B%20i%2B%2B%29%7B%0A%09%09replyItem%20%3D%20reply%5Bi%5D%0A%09%09if%28i%20%21%3D%200%29%7B%0A%09%09%09aCanvas%20%3D%20addCanvas%28%29%0A%09%09%09aCanvas%2Esize%20%3D%20aCanvasSize%0A%09%09%7D%0A%09%09aCanvas%2Ename%20%3D%20replyItem%0A%09%09aShape%20%3D%20aCanvas%2EnewShape%28%29%0A%09%09aShape%2Etext%20%3D%20replyItem%0A%09%09aShape%2EtextSize%20%3D%20typeSize%0A%09%09aShape%2Eautosizing%20%3D%20TextAutosizing%2EFull%0A%09%09aShape%2EtextHorizontalAlignment%20%3D%20HorizontalTextAlignment%2ECenter%0A%09%09aShape%2EshadowColor%20%3D%20null%0A%09%09aShape%2EstrokeType%20%3D%20null%0A%09%09aShape%2EstrokeColor%20%3D%20null%0A%09%09aShapeGeo%20%3D%20aShape%2Egeometry%0A%09%09aRect%20%3D%20new%20Rect%28cW%2F2%20-%20aShapeGeo%2Ewidth%2F2%2C%2072%2C%20aShapeGeo%2Ewidth%2C%20aShapeGeo%2Eheight%29%0A%09%09aShape%2Egeometry%20%3D%20aRect%0A%09%09aShape%2Etext%20%3D%20%22%3C%25Canvas%25%3E%22%0A%09%7D%0A%7D%29

Here’s a short video demonstrating App-to-App scripting between OmniGraffle and OmniOutliner (iOS). In the shown example, the topics from an OmniOutliner document are used to create “slides” in the current OmniGraffle document.

App Switcher Scripts

Here’s a simple but useful example of app-to-app scripting: creating an app-switcher script. Using the activate() method of the application class, and the call() method of the URL class, here are short scripts you can use to quickly switch between Omni applications. They make great Toolbar actions!

scriptURL = URL.fromString('omnioutliner://localhost/omnijs-run?script=app.activate()') scriptURL.call(function(reply){})
url = URL.fromString('omnigraffle://localhost/omnijs-run?script=app.activate()') url.call(function(reply){})
UNDER CONSTRUCTION

This webpage is in the process of being developed. Any content may change and may not be accurate or complete at this time.

DISCLAIMER