読者です 読者をやめる 読者になる 読者になる

FirefoxとOpera対応のUser Scriptを書くときのunsafeWindow

Greasemonkey Userjs

煤 - Note : 各ユーザスクリプトツールの window、unsafeWindowの件。
今までは、

var w = typeof unsafeWindow != "undefined" ? unsafeWindow : window;

こう書いてた。typeofや"undefined"が嫌な感じ。


でも、

var w = this.unsafeWindow || window;

これでいけるみたい。
もちろん、thisが変わっている場合は使えない。
無名関数を使って、

(function(unsafeWindow){
// alert(unsafeWindow)
})(this.unsafeWindow || window);

こうするとスマートかも。

SafariやIE(fub)は確認してない。(が、問題ないと思う)

[追記]
miya2000さんのブクマコメより、

window.wrappedJSObject || window

でもいけるようだ。(window.wrappedJSObject == unsafeWindow)
ただ、こちらはfubで動かないと思われる。

ちなみに、getElementsした要素もwrappedJSObjectで元のまま扱えるのだが、逆に言えば要素にチェックをつけて未処理のものだけ処理するようなScriptをFirefox対応(クロスブラウザ)にするには、

var elements = document.getElementsByName('foo');
for (var i = 0,len=elements.length;i < len; i++){
    var element = elements[i].wrappedJSObject || elements[i];
    if (!element.__checked) {
        /* hogehogeする */
        element.__checked = true;
    }
}

こんな感じに書く必要がある。
a、こういう感じのほうがいーのかな。

var elements = document.getElementsByName('foo');
forEach(elements,function(element) {
    if (!(element.wrappedJSObject||element).__checked) {
        /* hogehogeする */
        (element.wrappedJSObject||element).__checked = true;
    }
});
function forEach(a,f,o){for (var i=0,l=a.length;i<l;++i) f.call(o,a[i],i,a);}

Opera9.5、Safari3以降なら、wrappedJSObjectをgetter、setterで定義してあげればもう少しスマートに書ける。
アレ、クロスブラウザを意識しないですむのがGreasemonkeyのメリットだったような。気のせいか。
[/追記]


余談だけど、unsafeWindowはunsafeなので使うべきではない。