AppleScriptからJavaScriptを実行する方法がUS AppleのAppleScript Users MLで議論されていたので、いろいろとテストしたうえでまとめてみました。
なお、本AppleScriptは明示的にメインスレッドで実行させるために、Script Editor上で通常の「Command-R」ではなく、「Control-Command-R」で実行する必要があります(この操作を行わないと、サブスレッド上で実行されている旨のエラーが出ます)。ASObjCExplorer 4上で実行する場合には、ウィンドウ左下にある「Run in foreground」のチェックボックスにチェックを入れてから実行します。
(1)run script xxxxx in “OSA-Language Name”
こんな方法で実行できたとは、、、。正直言って驚きました。これまで、OSに複数のOSA言語がインストールされてリリースされたことが(ほとんど)なかったので、他のOSA言語を呼び出すという場面がなかったわけですが、こういう呼び出し方で呼び出せるんですね。リリースノートに書かれているんだかいないんだか。この呼び出し方でJXA(JavaScript for Automation)のScriptをAppleScript側から実行できます。同様に、JXA側からAppleScriptを実行することも可能と思われます。
(2)WebViewを動的に生成してJavaScriptを実行
WebViewを動的に生成して操作する場合には、JavaScriptのコマンドを実行することになります。つまり、Webブラウザ上と同様にJavaScriptを実行できるわけですが、これはJXAではありません。このため、Webブラウザ上で実行できるJavaScriptはこの方法で呼び出せますが、JXAで書かれたScriptを実行することはできません。
(3)JavaScript CoreでJavaScriptを実行
WebKitでJS実行するのと速度差はありません。同様に、ここで実行できるJavaScriptはJXAではありません。
JS処理系 | JXA(JavaScript for Automation) | JSX(with Adobe CC) | JavaScript on WebView | JavaScript Core |
GUIアプリケーション操作 | OK | Adobeアプリケーションのみ | NG | NG |
実行環境 | スクリプトエディタ、アプレット、スクリプトメニューなど | ExtendScript Toolkit | WebView | メモリ上でオブジェクトをロードして実行 |
備考 | macOS 10.10で標準装備されたOSA版のJS | Adobe CS/CCを操作するためのJS | Webブラウザ上で動作させるJS | WebkitのJavaScript実行エンジン |
▲OS X上で実行可能な(主な)JavaScript処理系
実際に、数値演算ライブラリをJavaScriptで書いて(JXA)AppleScriptから呼び出したときに、頻繁にクラッシュを経験しているため、JXAでライブラリを書くのはリスキーだと感じています。
結局、AppleScriptからJavaScript Coreを呼び出す方法に落ち着き、クラッシュも激減。スピードもJXA呼び出しより30倍ぐらい高速になりました。
AppleScript名:ASでJavaScriptを実行する |
use AppleScript version “2.4” use scripting additions use framework “Foundation” use framework “JavaScriptCore” use framework “WebKit” –実行するJavaScriptのテキスト set jsText to “ var app = Application.currentApplication() app.includeStandardAdditions = true app.displayDialog(’How are you?’) “ –run scriptでAppleScriptからJavaScriptを実行する(JXA:アプリケーション操作可能) set k to run script jsText in “Javascript” –AppleScriptから一番手軽なJXA呼び出し log {“1”} –WebKitでJavaScriptを実行する(高速だが、アプリケーション操作不可) set theWebView to current application’s WebView’s alloc()’s init() set x to (theWebView’s stringByEvaluatingJavaScriptFromString:jsText) as text log {“2”} –JavaScript CoreでJavaScriptを実行する(高速だが、アプリケーション操作不可) set theContext to current application’s JSContext’s alloc()’s init() set theJSValue to theContext’s evaluateScript:jsText log {“3”} |
また、「Safariのdo JavaScriptから結果をJSONで返してASの各種オブジェクトに変換」の記事において、AppleScriptからJavaScriptを呼び出して、さまざまな型のデータをJavaScript側から受け取る方法についても紹介しています。