2006年 08月 12日

GreaseMonkey で MochiKit 使ってみる。すなわち外部ライブラリの読み込み。あるいははてなのグラフが綺麗じゃない

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 さんからの指摘により、エラーを握りつぶす処理を追加し、最大ロード試行数を加えました。

2006年 06月 22日

flickr 系 user.js for Opera

確認がとれたものと修正して動いたもの

ずばばっと表示させるやつはどうも挙動が怪しいです。動的にレンダリングするのを変えるのはやっぱちょっと苦手っぽい。

require 000.user.js

ignore-not-cc-photo.user.js を書き換えた。flickr が gamma になったときぐらいに HTML の構造を変えたらしく、もっと簡単に書けるようになっていた。ついでに $X 使うように修正した。

2006年 06月 21日

GreaseMonkey Script on Opera 9.00

9.0 がリリースされたのでいろいろ調べて書く。

XPath は割と普通に使えるっぽい。時々変な挙動な気もするけど。$X は書き換え無しに動く。と思いきや createNSResolver は動かない

innerHTML 使ってパースさせるやつ は Opera でもできるようだ。


Array#forEach や GM_xmlhttpRequest がないため、殆どの GreaseMonkey スクリプトは動かない (が、後述するスクリプトでほぼ解決)。ついでに Opera はハイパートリッキーなことをしないとドメインを超えられないようだ。

Opera 用のラッパは 000.user.js とか最初のほうに呼ばれそうなファイルに書いてあげればいいっぽい。000.user.js . インターフェイスのラッパだけです。ドメイン超えるのも 000.user.js に書けば普通にいけるかもしれない。

作ったスクリプトで確認がとれたやつを列挙する。


E4X とかクロスドメインとかでひっかかる。E4X を innerHTML + XPath にし、クロスドメインのハックをすれば動くと思われる。

それと、日本語は素でかけないようです。\u でエンコードする必要あり。スクリプトを直接編集する場合もです。(GreaseMonkey はインストールするときに化けるらしく、直接編集している限りは日本語は普通にかけます。)

2006年 06月 19日

ふぁっきん not well-formed, XMLHttpRequest とかで

GreaseMonkey では GM_xmlhttpRequest で他のページとってくるじゃないですか。で、onload して req.responseXML をとるなり req.responseText をとるなりするけど、どうにもこうにも not well-formed なページ (HTML とか) をとってきてノード検索するとき面倒くさいんですよ。responseXML はもちろん空だし、responseText はもちろんただのテキストだし。

で、なんとなく思いついたので以下のように解決するようにした。

GM_xmlhttpRequest({
method : "GET",
url : i.href,
onload : function (req) {
// てきとーなエレメント作って突っ込む (ブラウザにパースさせる)
var d = document.createElement("div");
d.innerHTML = req.responseText;
// d を最初のコンテキストノードにして文書を XPath 検索
$X(".//foobar", d);
},
onerror : function (req) {
alert(req.responseText);
}
});

なんてキモイ!

問題点は application/xhtml+xml なページから not well-formed なページをとってくるっていう場合は使えないこと。なぜなら innerHTML が使えないから。でも殆どの場合 (というか殆どのページは) text/html なので問題ない感じ。はてなとかはてなとかはてなとか。

Firefox 1.5 からは application/xhtml+xml なページでも innerHTML 使えるみたいです。by yoko さん

はてブオートページャー

hatena-bk-autopager.user.js

最速インターフェース研究会 :: GoogleAutoPagerというのを作りました のはてブ版。

自分のブックマーク一覧でしか動きません。

はてブでスクリーンショットとコメントをさっさと表示させる GM

はてぶでコメントと画像を表示させてる

hatena-bk-show-ss-and-comments.user.js

似たようなのがあるけどとりあえず公開する。こっちは自分のブックマークじゃなくてもいろんなところで動くと思う。

はてな使うのをやめるための GreaseMonkey スクリプト

sayonara-hatena-by-araiteru.user.js

気が付いたらはてなを使っている人向けのスクリプトです。そこそこ適切な代替サービスなどにリダイレクトします。

実装がダサかったので少しだけ変えました。コンセプトが既にダサいとかは知りません。

2006年 06月 18日

はてブ。見たくないユーザのコメントを消す GM

hatena-bk-neglect-comment-by-id.user.js

指定ユーザのコメントを消します。デフォルトでは「ブックマークしている」ことは薄く見えるようにしてあります。ERASE_FROM_THE_WORLDtrue にするとブックマークしている事実も消します (ブックマーク数は変えません)。

2006年 06月 11日

はてダ。フラグメントハイライト

hatena-highlight-fragment.user.js

ハッシュつきアクセスの場合該当セクションをハイライトさせる GreaseMonkey。日記モードでしか意味がないっぽい。フィードリーダーで読んでるからあんまり意味ないけど。#1149956303 とかついてる場合そのセクションをハイライトする。クリックで解除


もともとはどこでも使えるようなスクリプトの予定だったけど、ちゃんと構造化されて id をふっているサイトがあまりにもなかった (id をふってる要素以下だけハイライトさせると悲惨になることが多い) 。なんか意味がなかった (というか弊害のほうが大きかった) ので、割と解りにくいなぁと思うはてダに特化させた。

はてダの場合 id じゃなくて a @name だから、フラグメントとは言わないかな?

2006年 06月 07日

はてダの編集テキストボックスを自動スクロールさせる GM

hatena-textarea-scroll.user.js

はてなの編集画面を開くたびにいちいち下までスクロールするのが面倒くさいので作った。ついでに編集画面開いたらキャレット位置を最後にしてフォーカスさせるようにした。すぐ書ける。編集しやすい。

Ajax でインラインエディットできたらいいんだけど

過去のページでもいけるように @include を書き換えました。