Photoshop extensionでjsxのデバッグログをうまいこと拾うパネルを作る


extension loggerの困りごと

photoshopのエクステンションを作成しているとき、jsのconsole.logは基本的にchromeのデバッガーで拾えるのだが、jsx側のlogに関しては少し工夫しないと拾えない。
個人的には簡単なコンソールログに関してはalertを発火させてしまうのだけれども、人に教えているときにalertは使いづらい!という意見があったのでうまいことできないかなーと試行錯誤してみた。

jsxのログ出力をjsに流してjs側でconsole.logする

一般的な方法。

logger.jsx
// ログ送信側のjsx
var externalObjectName = "PlugPlugExternalObject.framework"; 
var mylib = new ExternalObject( "lib:" + externalObjectName );

function logger(msg)
{
  try {
    var eventObj = new CSXSEvent();
    eventObj.type = "jsx_logger";
    eventObj.data = msg;
    eventObj.dispatch();  
  } catch(err){ alert(err); }
}
logger_interface.js
// ログ受信側のjs

(function () {
  var csInterface = new CSInterface();

  // 送信側で指定したtype名でイベントの待ち受けをする
  csInterface.addEventListener("jsx_logger", function (event) {
    console.log(event.data);
  });
}());

これでひとまずデバッグポートをchromeで開けばログが見れるようになる

困りごと2

及第点には達したが、あまり詳しいログをだす必要がないときにわざわざchromeからコンソールを見に行くのが面倒。もっと手軽にログを見れないことかと思い、デバッグログが流れるパネルを作成してみることにした。
(Generator pluginのPanelを作成するのは面倒だったので、慣れているextensionで作成してみることにした。)
要件は以下の通り

  • 同一のライブラリから発生しているログを全て一枚のパネルで眺めたい(切り替えとかが面倒)
    • ただし、どのextensionから発生しているログなのかは判別がつかなくてはいけない
  • ログの種別によって表示を切り替えたい(log,info,warn,error.....)
  • 設定とかは出来るだけ省いたシンプルなものが欲しい

調べてみたところ、CSInterfaceのEventListennerは別のextensionが発行しているメッセージも受け取れるらしく、実装自体は簡単そうだった。

DebugLogを集約して表示できるパネルを作成する

出来上がりはこんな感じ

指定されたtype名を常にLisstenして、受け取ったメッセージをパネルに流し込むという簡単な仕組み。
PSDebugLogと名付けました。

main.js
(function () {
  'use strict';
  var csInterface = new CSInterface();

  var logger = function(type,msg){
    $("#psdebug-log-interface").append(`<span class="${type}"> > ${msg}</span>`);
  }

  csInterface.addEventListener("psdebuglog.log", function (event) {
    logger("log",event.data);
  });
  csInterface.addEventListener("psdebuglog.info", function (event) {
    logger("info",event.data);
  });
  csInterface.addEventListener("psdebuglog.warning", function (event) {
    logger("warn",event.data);
  });
  csInterface.addEventListener("psdebuglog.error", function (event) {
    logger("error",event.data);
    });

}());

このパネルを使用したいextensionはPSDebugLog.jsxを読み込み、これを使ってログを流すだけ

PSDebugLog.jsx
function PSDebugLog(context) {
    this.context = context;
    if(context == undefined) this.context = "";
    var mylib = new ExternalObject( "lib:\PlugPlugExternalObject" );
}

PSDebugLog.prototype._execute = function(type,msg) {
    try {
        var eventObj = new CSXSEvent();
        eventObj.type = type;
        eventObj.data = "" + this.context + "" + msg;
        eventObj.dispatch();  
    } catch(err){ alert(err); }
}

PSDebugLog.prototype.log = function(msg) {
    this._execute("psdebuglog.log", msg);
}
PSDebugLog.prototype.info = function(msg) {
    this._execute("psdebuglog.info", msg);
}
PSDebugLog.prototype.warn = function(msg) {
    this._execute("psdebuglog.warning", msg);
}
PSDebugLog.prototype.error = function(msg) {
    this._execute("psdebuglog.error", msg);
}
sample.jsx
// 使用サンプル
#include 'jsx/PSDebugLog.jsx';

function log_test() { 
  var debug = new PSDebugLog("sample");
  debug.log( "debug : log" );  
  debug.info( "debug : info" );  
  debug.warn( "debug : warn" );  
  debug.error( "debug : error" );  
}

見た目は適当にhtmlとcssで調整していい感じに。
デバッグパネルにはもうちょっと機能つけて、そのうちもう少しまとめて公開したい。

参考
CEPガイド6:ツール・パネル間のイベント
CEP ExtensionsとInDesignをCallbackで仲良くしてもらう方法