拡張機能デバッグインターフェイス
拡張機能開発時によく使うログや表明 (assertion) などのためのインターフェイスのサンプルコードです
var myextension = {
// debug interface
debug: {
// https://developer.mozilla.org/en/NsIConsoleService
_consoleservice: Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService),
_Cc_scripterror: Components.classes["@mozilla.org/scripterror;1"],
_Ci_scripterror: Components.interfaces.nsIScriptError,
enabled: false, // set true to output
noFirebug: false, // don't show object in Firebug
prefix: "", // prefix string
createScripterror: function() this._Cc_scripterror.createInstance(this._Ci_scripterror),
// log for Firebug with existence check
logFirebug: function(x) this.enabled && !this.noFirebug && Firebug && Firebug.Console && Firebug.Console.log(x),
logFirebugOnlyObject: function(x) typeof x == "object" && x != null && this.logFirebug(x),
// log/warn/error in console
log: function(message) {
if (this.enabled) {
this._consoleservice.logStringMessage(this.prefix+message);
this.logFirebugOnlyObject(message);
}
},
warn: function(message) {
if (this.enabled) {
var stack = Components.stack.caller;
var error = this._Cc_scripterror.createInstance(this._Ci_scripterror);
error.init(this.prefix+message, stack.filename, null, stack.lineNumber, null, this._Ci_scripterror.warningFlag, null);
this._consoleservice.logMessage(error);
this.logFirebugOnlyObject(message);
}
},
error: function(message) {
if (this.enabled) {
var stack = Components.stack.caller;
var error = this._Cc_scripterror.createInstance(this._Ci_scripterror);
error.init(this.prefix+message, stack.filename, null, stack.lineNumber, null, this._Ci_scripterror.errorFlag, null);
this._consoleservice.logMessage(error);
this.logFirebugOnlyObject(message);
}
},
// debug with exception (error objects)
exception: function(error) {
if (this.enabled) {
Components.utils.reportError(error);
this.logFirebugOnlyObject(error);
}
},
stack: function(error) {
if (this.enabled) {
if (error instanceof Error) {
this._consoleservice.logStringMessage(this.prefix+error.stack);
}
else {
error = new Error();
var callerstack = error.stack.replace(/^.*\n.*\n/, "");
this._consoleservice.logStringMessage(this.prefix+callerstack);
}
this.logFirebugOnlyObject(error);
}
},
// alert and assert
alert: function(message) {
if (this.enabled) {
window.alert(this.prefix + message);
this.logFirebugOnlyObject(message);
}
},
assert: function(cond, message) {
var failed = this.enabled && !cond;
if (failed) {
var message = this.prefix+message;
var stack = Components.stack.caller;
var error = this._Cc_scripterror.createInstance(this._Ci_scripterror);
error.init(message, stack.filename, null, stack.lineNumber, null, this._Ci_scripterror.errorFlag, null);
this._consoleservice.logMessage(error);
window.alert(message);
this.logFirebugOnlyObject(message);
}
return !failed;
}
},
onLoad: function() {
this.debug.enabled = true;
this.debug.prefix = "myextension debug:\n";
this.debug.log("myextension inited!");
}
}
window.addEventListener("load", function() { myextension.onLoad() }, false);
debug オブジェクトを自分の拡張機能専用オブジェクトのプロパティとして定義し、debug.log() などのメソッドを使います。debug.prefix に文字列を設定しておけば、コンソールのメッセージすべての先頭にその文字列が表示されるので検索しやすくなります。引数がオブジェクトの場合、Firebug がインストールされていれば Firebug のコンソールにも出力します。
上記の例では直接 true を代入していますが、debug.enabled プロパティはユーザ設定から読み込むようにすれば、開発環境だけでログを出力するといった使い方もできます。
より詳しい解説の追加などはまた後日…