MinibufferとLDRize を Greasemonkey 0.9.1 で動かす

「諦めたらそれまでだ。でも、君なら運命を変えられる」

邪道なやり方である。Use at your own risk !!!

因みに「邪道」だと書いたのはGreasemonkey, Scriptish側に変更を入れる方法だからで、危険があるわけではない(と思う) Issue登録もしておいた

Greasemonkeyが0.9になってLDRizeやAutoPagerizeが動かなくなったの件
昨日あたり、Twitter上で談義していたが、解決方法が出てこないので、Greasemonkey側を弄ることにしたw

Minefieldでテストしたら動かなかったので後で書きなおす

for Greasemonkey

diff --git a/components/greasemonkey.js b/components/greasemonkey.js
index 0deb036..0307104 100644
--- a/components/greasemonkey.js
+++ b/components/greasemonkey.js
@@ -255,6 +255,7 @@ GM_GreasemonkeyService.prototype = {
     var xmlhttpRequester;
     var resources;
     var unsafeContentWin = wrappedContentWin.wrappedJSObject;
+    var sharedObject = {};

     // detect and grab reference to firebug console and context, if it exists
     var firebugConsole = this.getFirebugConsole(unsafeContentWin, chromeWin);
@@ -273,6 +274,7 @@ GM_GreasemonkeyService.prototype = {
       resources = new GM_Resources(script);

       sandbox.unsafeWindow = unsafeContentWin;
+      sandbox.sharedObject = sharedObject;

       // hack XPathResult since that is so commonly used
       sandbox.XPathResult = Ci.nsIDOMXPathResult;

for Scriptish

diff --git a/extension/components/scriptish.js b/extension/components/scriptish.js
index ceac80c..9a8302b 100644
--- a/extension/components/scriptish.js
+++ b/extension/components/scriptish.js
@@ -273,10 +273,13 @@ ScriptishService.prototype = {

     // detect and grab reference to firebug console and context, if it exists
     let fbConsole = Scriptish_getFirebugConsole(wrappedContentWin, chromeWin);
+    let sharedObject = {};

     for (var i = 0; script = scripts[i++];) {
       sandbox = new Cu.Sandbox(wrappedContentWin);

+      sandbox.sharedObject = sharedObject;
+
       let GM_API = new tools.GM_API(
           script, url, wrappedContentWin, unsafeContentWin, chromeWin);

1行追加するだけ。
これでUserScript間でオブジェクトを共有できる。

// ==UserScript==
// ....
// ==/UserScript==
sharedWindow.Hoge = { foo: "bar" };
// ==UserScript==
// ....
// ==/UserScript==
console.log(sharedWindow.Hoge.foo);

これで、

find . -name "*.user.js" -exec sed -i 's/window\.Minibuffer/sharedWindow.Minibuffer/g' {} +

しておけばOK

間違いです

どうやらGreasemonkey 0.8ではMinibufferでのwindowとLDRizeでのwindowが同一のXPCNativeWrapperオブジェクトだったけど0.9では別のオブジェクトになったようだ。だからLDRizeでのwindow.MinibufferもundefinedになるしGM_MinibufferLoadedのイベントリスナーを設定してもwindowが違うから発行されないということみたい

Greasemonkeyが0.9になってLDRizeやAutoPagerizeが動かなくなった

前半は合っているけど、後半のイベントは間違い。イベントは発行できるし、取ることはできる。ただし、この後書くけど、ネイティブに生成されたイベントオブジェクトのプロパティを変更してdispatchしてもそれを渡すことは不可。

XPCNativeWrapperに関してはXPCNativeWrapper - MDC Doc Centerを参照。簡単にはスクリプト側で変更されたり追加されたプロパティは参照できなくなるというもの。
例えばページ側のスクリプトwindow.alert = function () "ぷぎゃー";とした場合でも、UserScript側からは正しく元のalert関数を呼べる。んで、件の変更で、今までは共通のこのラッパーオブジェクトだったのがUserScript毎にnew XPCNativeWrapperされるから参照できなくなっちゃったんだね。