解説、要る?

Nightlyで今すぐGoogle Reader Full Feed Modを動かす方法 - Firefox更新情報Wikiブログのところが参考になった。greasemonkey内の機能であっても、共有のための機能として認識されていなければ、セキュリティのために共有を制限されるというところがミソ。
__exposedProps__とはなんぞや、という向きにはこちら(g:moz-addon:id:teramako:20120822:1345637649__exposedProps__ プロパティ - hogezilla - Mozilla 拡張機能勉強会)を。

参考例ではGM_xmlhttpRequestなのでread onlyで問題ないのだけれど、sharedObjectの場合は各種スクリプトの側から改変を加えることが前提なので、rwにする必要がある。可能なら、MinibufferなりLDRizeなりAutoPagerizeなりで改変を加えたあとでread onlyに変更したいのだけれど、ちょっとその方法は思いつかないのでパスで。

Firefox 17 環境でのLDRize復活への手引き(unsafeWindow不使用バージョン)

Firefox 17になって恒例行事のごとくLDRizeが動かなくなって、しばらくどうしようもない感じでしたが、Firefox 16のときにちらっと目にしたエラーを頼りに修正かけたらあっさり動くようになったので、備忘録的に記事にしてみます。

前提のひとつとして、Firefox17からE4Xはデフォルトでオフになり(javascript.options.xml.content でオンには出来る)、将来的には削除されます。そのため、E4Xで書かれているヒアドキュメント部分はすべて文字列に置き換える必要があります。

で、残る問題はグリモン間のオブジェクトの共有。Minibufferオブジェクトが共有されてくれないとどうにもならない。
unsafeWindowを使っても良いなら、id:serian:20121122:p1([Firefox] firefox17とminibufferとldrizeとUserScriptLoaderとtombloo - うぇぶとらばぁす)で書かれているような改変でまったく問題ないのですが、unsafeWindowということはサイトの側からもMinibuffferをいじれる状態ということ。せめてgreasemonkey内くらいに影響範囲をおさえて自衛可能にしておきたいです。

ということで、基本的な方針は例によって例のごとく、Greasemonkey0.9.12以降でMinibufferとLDRizeが動かない理由とか - tyoro.exeと同じ。sharedObjectを処方すること。
Firefox17、greasemonkey1.5を前提としてます。

ちなみに、LDRizeAutoPagerizeまでsharedObjectにぶっこんでいるのは、こっちの手元ではLDRizeAutoPagerizeを利用するスクリプトを導入してあるから。必要なければ、最低限MinibufferのところだけあればLDRizeは復活できます。

greasemonkeyを直接いじる場合
diff貼る

diff --git a/components/greasemonkey.js b/components/greasemonkey.js
index 89d1575..6491421 100644
--- a/components/greasemonkey.js
+++ b/components/greasemonkey.js
@@ -490,11 +490,22 @@ service.prototype.injectScripts = function(
     scripts, url, wrappedContentWin
 ) {
   var chromeWin = getChromeWinForContentWin(wrappedContentWin);
+  var sharedObject = {
+    Minibuffer : null,
+    LDRize : null,
+    AutoPagerize : null,
+    __exposedProps__ : {
+      Minibuffer : "rw",
+      LDRize : "rw",
+      AutoPagerize : "rw"
+    }
+  };
   var firebugConsole = getFirebugConsole(wrappedContentWin, chromeWin);

   for (var i = 0, script = null; script = scripts[i]; i++) {
     var sandbox = createSandbox(
         script, wrappedContentWin, chromeWin, firebugConsole, url);
+    sandbox.sharedObject = sharedObject;
     runScriptInSandbox(script, sandbox);
   }
 };

diffを読めない人のための完成形はこんな感じ
injectScriptsのとこ

これが

service.prototype.injectScripts = function(
    scripts, url, wrappedContentWin
) {
  var chromeWin = getChromeWinForContentWin(wrappedContentWin);
  var firebugConsole = getFirebugConsole(wrappedContentWin, chromeWin);

  for (var i = 0, script = null; script = scripts[i]; i++) {
    var sandbox = createSandbox(
        script, wrappedContentWin, chromeWin, firebugConsole, url);
    runScriptInSandbox(script, sandbox);
  }
};

こうなる。

service.prototype.injectScripts = function(
    scripts, url, wrappedContentWin
) {
  var chromeWin = getChromeWinForContentWin(wrappedContentWin);
  var sharedObject = {
    Minibuffer : null,
    LDRize : null,
    AutoPagerize : null,
    __exposedProps__ : {
      Minibuffer : "rw",
      LDRize : "rw",
      AutoPagerize : "rw"
    }
  };
  var firebugConsole = getFirebugConsole(wrappedContentWin, chromeWin);

  for (var i = 0, script = null; script = scripts[i]; i++) {
    var sandbox = createSandbox(
        script, wrappedContentWin, chromeWin, firebugConsole, url);
    sandbox.sharedObject = sharedObject;
    runScriptInSandbox(script, sandbox);
  }
};

そんでtombloo

addAround使えばいいんだろうけど肝心のaddAroundをどう使えばいいのかよくわかんなかったのでパス。

vimperator

js <<EOM
autocommands.add(
  'VimperatorEnter', '.*',
  function () {
    let Cc = Components.classes['@greasemonkey.mozdev.org/greasemonkey-service;1'];
    if (Cc) {
      Cc = Cc.getService().wrappedJSObject;
      if (Cc.injectScripts.toSource().search('sharedObject') == -1) {
        Cc.injectScripts = liberator.eval(
          Cc.injectScripts.toSource()
            .replace(/(?=(?:var|let) (?:firebugConsole))/,  'var sharedObject = {\n    Minibuffer:null,\n    LDRize:null,\n    AutoPagerize:null,\n    __exposedProps__:{\n      Minibuffer:"rw",\n      LDRize:"rw",\n      AutoPagerize:"rw"}};\n  ')
            .replace(/(?=runScriptInSandbox\()/, 'sandbox.sharedObject = sharedObject;\n    ')
            .replace(/(?:}\)$)/, '  return sharedObject;\n})'),
        Cc.injectScripts);
      };
    };
  });
EOM

本当に余談

ということで0時過ぎから書き始めたのにこんな時間……

余談

自分とこのメモ記事というか、その元であるMinibuffer Exploit - hogehoge @teramakoに詳しいんだけど、LDRizeの動作に必須のMinibufferの動作の隙を突かれる可能性は常に存在するので、そういう意味でもLDRizeを使い続けるのは自己責任で。

バグ報告とか

というか、ざっとBugzillaでmatchとかRegExpで検索してみてもそれっぽいトピックがひっかからないし、mozillaZineフォーラムやもじら組フォーラムはいわずもがな。Firefox 13 for developers - Mozilla | MDNFirefox 13 の後方互換性に関わる修正 | Mozilla Developer Street (modest)にすら、正規表現まわりには言及がない。こういうときってどうすりゃいいんだろう。やっぱり自分から報告しに行かなきゃダメかしらん。