Subscribed unsubscribe Subscribe Subscribe

枕を欹てて聴く

香炉峰の雪は簾を撥げて看る

unsafeExec on JSDeferred

JavaScript Greasemonkey

SmartLDR更新 - 素人がプログラミングを勉強していたブログ
のを見て, 関数に押し込むのもいいなあと思った.
けど, このままでは返り値が利用できない + Fxのlocation.hrefは非同期らしい
JSDeferred を高速化する (試し中) - 冬通りに消え行く制服ガールは✖夢物語にリアルを求めない。 - subtech
ので, その後でなにか処理となると面倒な書き方をしないといけない.
そこで非同期処理の定番, JSDeferredのuserscript版をrequireして

with(D()){
  function unsafeExec(func){
    var d = Deferred();
    // Global確保 => 呼び出し用
    // var Global = (function(){ return this})();
    var Global = unsafeWindow;
    // callbackの確保
    var cbname = null;
    if (!cbname) do {
      cbname = "callback" + String(Math.random()).slice(2);
    } while (typeof(Global[cbname]) != "undefined");

    // callback
    Global[cbname] = function(res){
      delete Global[cbname];
      d.call(res);
    }
    location.href = "javascript:void " + cbname + "((" + func + ")())";
    return d;
  }
  Deferred.unsafeExec = unsafeExec;
}

ってunsafeExecを登録すると,

//LDRとかで.
with(D()){
  // unsafeExecに渡す関数はunsafeWindowの枠組みで実行される.
  // => newとかできる, いろいろできる.
  unsafeExec(function(){
    // 返り値は次の関数の引数になる.
    return new HotKey();
  })
  // 続くnextに渡す関数はwindow(GM)の枠組みで実行される.
  // => GM_xmlhttpRequestとか使える.
  .next(function(res){
    //res は new HotKey
    console.info(res);
    console.info(GM_xmlhttpRequest);
  });
}

見たいに使える.