GreaseMonkey で外部ライブラリが使いたいな。みたいな。似たようなのでは CMS researcher - Greasemonkeyでprototype.jsやscript.aculo.usを使う方法 があるのですが、どうもうまくいかなかったので自力実装。
function dll(loadLibs, afterLoadedFunction) { if (afterLoadedFunction._retry) afterLoadedFunction._retry = 0; else afterLoadedFunction._retry++; if (afterLoadedFunction._retry > 10) throw("Library is not loaded because of some reason."); loadLibs.forEach(function (lib) { GM_xmlhttpRequest({ method : "GET", url : lib[0], onload : function (req) { try { (function (r) { eval(r.responseText) }).call(window, req); } catch (e) { // nigiri tubushi } }, onerror : function (req) { alert(req.responseText); } }); }); var loaded = true; loadLibs.forEach(function (lib) { try { loaded = loaded && typeof eval(lib[1]) != "undefined"; } catch(e) { loaded = false; } }); if (loaded) { try { afterLoadedFunction(); } catch (e) { unsafeWindow.console ? unsafeWindow.console.log(e) : window.dump(e); } } else { var f = arguments.callee; setTimeout(function () { f.apply(this, [loadLibs, afterLoadedFunction])}, 500); } }
で、以下のように使う。
// 第一要素にロードする js への URL // 第二要素にロード確認用のオブジェクトの名前 // を入れた配列の配列 dll([["http://example.com/mochi/Base.js", "MochiKit"]], function () { // ロードされたら実行される })
ポイントは eval を使うところ? eval を使うので unsafeWindow を極力使わなくてすむ。あとは DOM 系の処理でおかしいこと (ここには append できないぜ系エラー) になりにくい気がする。
ロードするスクリプトの依存関係上、何度かリクエストが発射されることがある。めんどいのでブラウザのキャッシュ機能にまかせてこっちではキャッシュしていないけど、ホントはちゃんとキャッシュしたほうがいいはず。
でもって、はてなアンケートの円グラフを PlotKit で描画しなおす GreaseMonkey スクリプトを書いてみた。hatena-q-make-graphs-with-plotkit.user.js
結果をソートするようにした。あと Global じゃなくて window 使うようにした。
id:secondlife さんからの指摘により、エラーを握りつぶす処理を追加し、最大ロード試行数を加えました。