宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能!
XBLはアドオン同士の衝突の原因になりやすい。だからXBLはあまり使わないように僕はしてる。
XBLを使うと、DOMノードにgetterやsetterになってるプロパティを定義したり、独自のメソッドを追加したりできる。でも、それらはJavaScriptのテクニックで代用できないこともない。JavaScriptのレベルで目的を達成するやり方として、僕は最近よく、こんな設計をしてる。
function MyController(aNode) {
this._node = aNode;
this.init();
}
MyController.prototype = {
get property() {
...
},
set property(aVaule) {
...
},
method : function() {
...
},
init : function() {
this._node.addEventListener('...', this, false);
...
},
destroy : function() {
this._node.removeEventListener('...', this, false);
...
},
handleEvent : function(aEvent) {
...
}
};
var node = document.createElement('box');
node.controller = new MyController(node);
かなりの部分はこういったやり方で目的を達成できると思う。ツリー型タブなんかもこれに近い実装になってる。
ただ、オートコンプリートのテキストボックスの挙動を変えるだとかの、本体で定義されている物を置き換える場面では、たまにこの方法だけでは不十分なことがある。例えば<textbox type="autocomplete" />
な要素のmaxDropMarkerRows
や<panel type="autocomplete" />
な要素のoverrideValue
やなんかはreadonlyなプロパティとしてXBLで定義されてしまっているので、これらが返す値を変えたいと思うと結構厄介な事になる。
XBLを使わないでサクッと済ませようとすると、__defineGetter__()
を使う方法がまずは思い浮かぶ。Firefox 3.0以降ではDOMノードに対して__defineGetter__()
を使えるので、上記の例のコードのinit()
あたりでそれを使ってやるという感じだ。実際、XUL/MigemoではoverrideValue
で任意の値を返すためにそうしてる。
でも、この方法はできれば使わない方がいいのかもなと思ってる。そう思ったきっかけは、同じようなことをやるコードの自動テストを書いていた時。setUpとtearDownで毎回ウィンドウを開いたり閉じたりとやってると時間がかかってしょうがないからUxU組み込みのフレームにページを読み込ませて……という風にしてみたら、セキュリティの制限に引っかかってしまった。object.__defineGetter__(name, getter)
のobjectとgetterの属してる名前空間が違うと、Illegal valueとか言われてエラーになってしまった。それでTrunkでの__defineGetter__()
の実装を見てみたら、この両者のコンパートメントが違う場合はゲッタの登録を拒否するような設計になってた。こういうセキュリティの制限を回避してreadonlyなプロパティの働きを置き換えようと思ったら、どうもやはり、XBLを使うしかないようだ。
そもそもなんでoverrideValue
がreadonlyなんだよ、なんで書き換え可能なただのフィールドになってないんだよ、って思って来歴を調べてみたら、nsIAutoCompletePopupインターフェースのoverrideValue
は昔のオートコンプリートの実装におけるgetOverrideValue()
メソッドがその祖先で、当時のコードには「こいつの働きを変えたかったらXBLでオーバーライドしろ」ってコメントが書いてあった。今のFirefoxのオートコンプリートの実装にはこのコメントがなかったので、なんでreadonlyになってるんだよという不満しか抱きようがなかった。getXXXとなってたメソッドをプロパティの形に置き換えるなら、確かにそれはreadonlyになるだろう。
でもどうせプロパティに変えたんだったらwritableにしたってよかったはず。ほんとに、何でこんな設計にするんだろう……
の末尾に2020年11月30日時点の日本の首相のファミリーネーム(ローマ字で回答)を繋げて下さい。例えば「noda」なら、「2010-10-22_xbl.trackbacknoda」です。これは機械的なトラックバックスパムを防止するための措置です。
writeback message: Ready to post a comment.