近江在住

2012-11-26 Firefox17公開による恒例行事

まだ下書きだよ 2012/11/26 1:26

肝心な部分だけ追記したよ 2012/11/28 2:45

リンクもだいたい整備したよ 2012/11/29 8:55

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

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を前提としてます。

ちなみに、LDRizeやAutoPagerizeまでsharedObjectにぶっこんでいるのは、こっちの手元ではLDRizeやAutoPagerizeを利用するスクリプトを導入してあるから。必要なければ、最低限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

解説、要る? 01:26

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に変更したいのだけれど、ちょっとその方法は思いつかないのでパスで。

トラックバック - http://d.hatena.ne.jp/t_f_m/20121126