[CEP] JSXファイルの動的読み込み
CEPエクステンションのデバッグにはCEF Clientを利用すると便利だという話は以前書きました。(https://forums.adobe.com/community/international_forums/japanese/automation/blog/2018/01/25/cefclientによるエクステンションのリモートデバッグ)
このクライアントを利用すればCEP側のJavaScriptは実際にアプリケーション上で動作させ、適宜修正を加えながら再読込し動作を確認することが出来ます。しかし、この再読込出来るのはCEP側だけです。ExtendScript側は再読込することが出来ません。
日頃「アプリケーション側のロジックはエクステンションに組み込む前にESTK等を利用して完全にデバッグを済ませておく」という趣旨の事は口を酸っぱくして言い続けているわけで、わたしのブログをご覧になっている方々はきっと何度も目にしていることだと思います。しかしながら、ExtendScript側もデバッグ時に「あの部分をちょっとだけ変えてみたい…」といった事が少なからず起こってきます。そういった場合においても、いちいちアプリケーションから立ち上げ直すと言った作業を強いられながらデバッグを進めるというのも精神衛生上如何なものかとも思います。
今回はそういったケースでもExtendScript側のロジックを再読込出来る手法を解説します。
まずサンプルエクステンションプロジェクトは以下のURLから入手可能ですのでダウンロードしましょう。
ダウンロードしましたでしょうか???
では、今回のエクステンションの特徴的な部分を見ていきます。まずCEP側のJavaScriptを見てみましょう。
//#main.js
(function(){
'use strict';
var CSLibrary = new CSInterface();
themeSynchronizer.init();
var mainJSX = CSLibrary.getSystemPath(SystemPath.EXTENSION)
+ '/jsx/hostscript.jsx';
var script = '$.evalFile("' + mainJSX + '");';
CSLibrary.evalScript(script);
$("#aply").click(function () {
var str = $("input#str").val();
CSLibrary.evalScript('testcall("' + str + '")',
function(re){
alert("alert from CEP side : " + re);
});
});
})();
基本的にはExtendScriptのコードをCEP側から$オブジェクトにあるevalFileメソッドを利用する事によりExtendScriptのコードを動的に展開させる処理になります。
ここでの肝になる部分がホスト用のスクリプトの絶対パスをどう取得するかというところです。こちらはCSInterfaceクラスに用意されたgetSystemPathメソッドにてExtension Rootを捉えて利用します。
var mainJSX = CSLibrary.getSystemPath(SystemPath.EXTENSION)
+ '/jsx/hostscript.jsx';
var script = '$.evalFile("' + mainJSX + '");';
CSLibrary.evalScript(script);
この様にSystemPath.EXTENSIONを引数にわたします。実際にExtendScriptに渡されるのは2行目で組み立てられた$.evalFileの部分です。引数には前行にて組み立てたjsxファイルへのパスが用意されます。この組立てたスクリプトをevalScriptでExtendScript側で実行する事によりExtendScriptエンジン側にコードを展開させます。
実際にExtendScriptの関数を呼び出す部分は
CSLibrary.evalScript('testcall("' + str + '")',
この様に通常のevalScriptと変わりありません。
一方、ExtendScript側でも各関数は下記のtestmain()関数のように通常の記述と何ら変わりありません。
//#hostscript.jsx
var extensionPath = $.fileName.split('/')
.slice(0, -1).join('/') + '/';
$.evalFile(extensionPath + 'sub.jsx');
function testmain(){
alert("alert from main.jsx");
}
外部ファイルの読み込みについても
var extensionPath = $.fileName.split('/')
.slice(0, -1).join('/') + '/';
$.evalFile(extensionPath + 'sub.jsx');
この様にメインのjsxファイルのファイルパスを得て、そこを基準にサブファイルを読み込む形になります。CEP側、ExtendScript側それぞれでファイルパスの取得しますが、その際の処理の違いにご注意ください。
//#sub.jsx
function testcall(str) {
alert("Alert from sub.jsx");
return "Test string from sub file.";
}
それではテストしてみましょう。エクステンションを開きボタンをクリックします。
このようなアラートが帰ってきました。
cefclientを起動してエクステンションにアクセスします。sub.jsxファイルのメッセージ部分を書き換えた後Audit>>Reloadを実行し再度エクステンションパネルのボタンをクリックします。
このようにsub.jsxのtestcall関数が返すメッセージが変わっています。
ここで紹介したテクニックは開発時以外には殆ど必要とはならないテクニックです。繰り返しになるのですが、ExtendScript側はエクステンションに組み込む前にデバッグを終了させておいたほうが得策なのは言うまでもありません。cefclientではESTKの様にDOMの参照や実行制御も出来ません。そういったメリット・デメリットをしっかり理解した上でご利用ください。