Firefox 4.0b10でGreasemonkey 0.9.1のユーザスクリプトのwindowを共通にする改造(開発者orVimper向け)
2010/02/09追記: Firefox 4.0b11でもおk
2010/03/01追記: Firefox 4.0b12でもおk。のようだけど、時々うまく動かない事も
2010/03/14追記: Firefox 4.0 RC1でもおk
2012/01/04追記: Greasemonkey 0.9.13で動かなくなってます。てかバグってグリモン動かなくなるのでこれを適用しないでください
LDRizeが使えないのは耐えられないので、Firefox 4.0b10でGreasemonkey 0.9.1のユーザスクリプトのwindowを共通にする改造をグリモンに施した。
LDRizeが使えないことについてはこの辺参照。
- ああ、やられた (greasemonkey 0.9 顛末記) - twwp http://d.hatena.ne.jp/taizooo/20110128/1296172869
- Greasemonkeyが0.9になってLDRizeやAutoPagerizeが動かなくなった http://anond.hatelabo.jp/20110128093703
- MinibufferとLDRize を Greasemonkey 0.9.1 で動かす - hogehoge @teramako http://d.hatena.ne.jp/teramako/20110202/p1
あとTombloo使ってる場合はこちらの方法がいいかも
Twitter / @utatane: GMのWindowをsharedにするTombloo ... http://twitter.com/#!/Constellation/statuses/31786122715594752
改造方法
グリモンのソースはここ https://github.com/greasemonkey/greasemonkey
改造パッチはこんな感じ
--- a/components/greasemonkey.js +++ b/components/greasemonkey.js @@ -255,6 +255,9 @@ GM_GreasemonkeyService.prototype = { var xmlhttpRequester; var resources; var unsafeContentWin = wrappedContentWin.wrappedJSObject; + var sharedWindow = {}; + sharedWindow.window = sharedWindow; + sharedWindow.__proto__ = new XPCNativeWrapper(unsafeContentWin); // detect and grab reference to firebug console and context, if it exists var firebugConsole = this.getFirebugConsole(unsafeContentWin, chromeWin); @@ -297,6 +300,7 @@ GM_GreasemonkeyService.prototype = { "registerMenuCommand", unsafeContentWin); + sandbox.window = sharedWindow; // Re-wrap the window before assigning it to the sandbox.__proto__ // This is a workaround for a bug in which the Security Manager // vetoes the use of eval.
サンドボックスから見えるwindowを、content Windowをプロトタイプにした普通のオブジェクトにしたて、これをユーザスクリプト間で使い回すわけです。
Firefox 4.0b10ではこれで動いてくれるけど、何故かFirefox 3.6.13では動かない
何故かsharedWindow.window.documentがundefined。多分3.6.13のXPCNativeWrapperあたりのバグだと思う。3.6.13ではGM 0.9.0使えばいいか。
まぁ、とりあえず、こんな方法でどうでしょう?
2010/02/01 追記
Vimperatorユーザなら簡単にLDRizeできるようになるよ
そういえばGMはXPCOMで上記の部分取り出していじれるから、グリモンのソースコードいじってxpiビルドする必要なかった。
Vimperならvimperatorrcに以下を追加するだけで上記パッチあてられる
" Greasemonkey 0.9.1でwindowを共通にする。(必要性は一時的?" js <<EOM autocommands.add('VimperatorEnter', '.*', function() { let gm = Components.classes['@greasemonkey.mozdev.org/greasemonkey-service;1']; if (gm) { gm = gm.getService().wrappedJSObject; if (gm.injectScripts.toSource().search('sharedWindow') == -1) { gm.injectScripts = liberator.eval( gm.injectScripts.toSource() .replace(/(?=var firebugConsole)/, 'var sharedWindow = {};' + 'sharedWindow.window = sharedWindow;' + 'sharedWindow.__proto__ = new XPCNativeWrapper(unsafeContentWin);') .replace(/(?=sandbox\.__proto__)/, ' sandbox.window = sharedWindow;'), gm.injectScripts); } } }); EOM
あとLDRize使うVimperならldrize_cooperation.js使ってると思うので、上記GMの改造にあわせて次のパッチが必要です
すでに以下のパッチは最新版に取り込まれました。最新のldrize_cooperation.jsを使えばおkです。swirhenさんありがとうございます
--- a/ldrize_cooperation.js +++ b/ldrize_cooperation.js @@ -184,18 +184,18 @@ } else { var [code,codebase,sandbox] = arguments; } - if(sandbox.LDRize != undefined && sandbox.Minibuffer != undefined){ + if(sandbox.window.LDRize != undefined && sandbox.window.Minibuffer != undefined){ sandbox.window.addEventListener("focus",function(){ - self.LDRize = liberator.eval("self",sandbox.LDRize.getSiteinfo); - self.Minibuffer = liberator.eval("command",sandbox.Minibuffer.addCommand); - if (typeof self.LDRize.getSiteinfo != 'function') self.LDRize = sandbox.LDRize; - if (typeof self.Minibuffer.addCommand != 'function') self.Minibuffer = sandbox.Minibuffer.command; + self.LDRize = liberator.eval("self",sandbox.window.LDRize.getSiteinfo); + self.Minibuffer = liberator.eval("command",sandbox.window.Minibuffer.addCommand); + if (typeof self.LDRize.getSiteinfo != 'function') self.LDRize = sandbox.window.LDRize; + if (typeof self.Minibuffer.addCommand != 'function') self.Minibuffer = sandbox.window.Minibuffer.command; },false); - if(window.content.wrappedJSObject == sandbox.unsafeWindow){ - self.LDRize = liberator.eval("self",sandbox.LDRize.getSiteinfo); - self.Minibuffer = liberator.eval("command",sandbox.Minibuffer.addCommand); - if (typeof self.LDRize.getSiteinfo != 'function') self.LDRize = sandbox.LDRize; - if (typeof self.Minibuffer.addCommand != 'function') self.Minibuffer = sandbox.Minibuffer.command; + if(window.content.wrappedJSObject == sandbox.window.unsafeWindow){ + self.LDRize = liberator.eval("self",sandbox.window.LDRize.getSiteinfo); + self.Minibuffer = liberator.eval("command",sandbox.window.Minibuffer.addCommand); + if (typeof self.LDRize.getSiteinfo != 'function') self.LDRize = sandbox.window.LDRize; + if (typeof self.Minibuffer.addCommand != 'function') self.Minibuffer = sandbox.window.Minibuffer.command; } } });
GMの改造にあわせて、sandboxのところをsandbox.windowにした。