AutoPagerizeのスクリプト実行順序制約をなくせるようになりました

Tumblrが新しくなって、よく見ていた/show/quotes/by/everyoneがちゃんとページングされなくなって悲しいと思っていたらcxxさんがFix Tumblr Dashboard Pagination for Greasemonkeyというスクリプトを書いてくれていました。

しかし21世紀はじめの10年最後の2009年ももう終わろうとしているにも関わらず、未だにTumblr dashboard reblog 4点セットのAutoPagerizeLDRizeMiniBufferreblogCommandの実行される順序をちゃんと覚えておかないといけないなんてローテクすぎる!という怒りにまかせて、順番に関係なく入れておけば動くように細工をしました。

それぞれ上記以降のバージョンであれば、Greasemonkeyで実行される時の順番を気にせず、とにかくインストールしておけばよくなりました。

しくみ

AutoPagerizeが実行されたときに

	var ev = document.createEvent('Events')
	ev.initEvent('GM_AutoPagerizeLoaded', false, true)
	window.dispatchEvent(ev)

というコードが実行されてGM_AutoPagerizeLoadedという名前のイベントが送られてくるようにしました。LDRizeのようにAutoPagerizeに依存してなにかを実行したときに、もしwindow.AutoPagerizeが存在しなかったらGM_AutoPagerizeLoadedイベントが送られてくるまで待ってから実行するようなコードを書けば、スクリプトが実行される順序に関係なく動作させることができるようになります。

以下はAutoPagerizeでページが継ぎ足されたときに、継ぎ足された部分をLDRizeが正しく認識するためのコードです。実行したいコードをaddFilterHandlerという名前の関数にしておいて、window.AutoPagerizeが存在していればそのまま実行、存在していない時はAutoPagerizeからGM_AutoPagerizeLoadedイベントが送られてくるのを待ってから実行することで、AutoPagerizeに依存するスクリプトを順序に関係なく正しく動作させることができます。

      var addFilterHandler = function(){
          window.AutoPagerize.addFilter(
              function(pages){
                  self.removeSpace();
                  setTimeout(function(){
                      self.initParagraph(pages);
                  }, 0);
              });
      }
      if(window.AutoPagerize){
        addFilterHandler();
      }else{
        window.addEventListener('GM_AutoPagerizeLoaded', addFilterHandler, false);
      }

AutoPagerizeと連動するスクリプトを書く人へのおねがい

AutoPagerizeに依存する部分を

      var f = function () {
        // やりたいこと
      }
      if(window.AutoPagerize){
        f();
      }else{
        window.addEventListener('GM_AutoPagerizeLoaded', f, false);
      }

と書くとスクリプトが実行される順序を気にしなくてよくなって、使ってくれる人の手間も省けるのでぜひご採用ください。

Webサイト側でのAutoPagerize検出

うれしい副作用として、ユーザスクリプトと同じようにHTMLドキュメント側でもGM_AutoPagerizeLoadedをlistenしておくことでAutoPagerizeが存在するかどうかを検出することができます。

  var isAutoPagerizePresent = false;
  window.addEventListener( 'load', function () {
    alert(isAutoPagerizePresent);
  }, false );
  window.addEventListener( 'GM_AutoPagerizeLoaded', function () {
    isAutoPagerizePresent = true;
  }, false );

Firefox3.1beta2+OSXの場合、GM_AutoPagerizeLoadedイベントが発生するタイミングはjQueryのreadyメソッドよりも後、loadイベントよりも前でした。

オチ

もとのcxxさんがFix Tumblr Dashboard Pagination for Greasemonkeyの説明をよく読むと

AutoPagerizeと併用する場合は、「ユーザスクリプトの管理」でAutoPagerizeよりもに置いておく必要があります。

と書かれていたのでした… にしないといけない制約しか考慮していなかったのでにしないといけない場合は、今後も順番を気にし続けるか、AutoPagerizeにそういう細工をして取り込んでくれるようにとswdyhにpull requestを送ってください。


About this entry