拡張機能やユーザスクリプトでは、 設定値の取得やファイル操作は COM (XPCOM) でバイナリを呼び出して実装することができる。 しかし、この呼び出し文が長い。 ドキュメントのサンプルコードでも通常2行に分けて書いてある位である。 そのような長い文がコードの中ほどに現れてきて読みずらい。というか格好悪い。
さて、今回は、ScrapBookのコードの一部分(Gomita, 2006)を例題としてみようと思う。これは、一般的な、読みやすいコーディングで書かれているものである。
......
function SB_pasteClipboardURL()
{
try {
var myClip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard);
var myTrans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
myTrans.addDataFlavor("text/unicode");
myClip.getData(myTrans, myClip.kGlobalClipboard);
// データを取得
var str = new Object();
var len = new Object();
myTrans.getTransferData("text/unicode", str, len);
// 文字列へ変換
if ( str ) {
str = str.value.QueryInterface(Components.interfaces.nsISupportsString);
if ( str.toString().match(/^(http|https|file):\/\//) ) SBURL.value = str + "\n";
}
} catch(ex) { // quiet warning
}
}
......2行の意味は、
createInstanceに、適当な別名をつけて、ソースの先頭に置けばよい。
関数xpiClassを書くと、次のようになる。
var xpcomClass = function(name, itf){
var obj = function() {
return Components.classes[this.name].createInstance(this.theInterface);};
obj.name = name;
obj.theInterface = Components.interfaces[itf] || Components.interfaces.nsISupports;
return obj;
};
//imports
var Clipboard = xpcomClass("@mozilla.org/widget/clipboard;1", "nsIClipboard");
var Transferable = xpcomClass("@mozilla.org/widget/transferable;1", "nsITransferable");
......
function SB_pasteClipboardURL()
{
try {
var myClip = Clipboard();
var myTrans = Transferable();
myTrans.addDataFlavor("text/unicode");
myClip.getData(myTrans, myClip.kGlobalClipboard);
.
.
.
.
......