Kanasan.JS Jetpackワークショップに向けたJetpack入門(その2)

前回に引き続いて、Kanasan.JS Jetpack ワークショップに向けた Jetpack 入門をやる。ちなみに、その勉強会は 12/06(日) 京都です。詳細は告知ページ参照。

今回は Greasemonkey っぽい簡単な feature (Jetpack スクリプト)を書いてみる。つまり、ページを開いたら自動的にそのページの内容を書き換える feature を作る。

ページを読み込んだらそのページの URL を表示する

とりあえずは URL を表示するだけの feature をつくってみる。

jetpack.tabs.onReady(function(targetDocument) {
  // frame, ifreme の場合は何もしない
  if (targetDocument.defaultView.frameElement) {
    return;
  }
 
  console.log(targetDocument.location.href);
});

(gist: 248274 - GitHub)
こんな感じで jetpack.tabs.onReady にコールバック関数を渡すと、ページが読み込まれるたびにそいつが実行される。

その次の if (targetDocument.defaultView.frameElement) ってとこは、frame/iframe の場合の処理。このコールバックは frame や iframe のときも呼び出されるんだけど、たいていの場合そうなってほしくない。こうやって書いておくと frame か iframe のときは何もしないようになる。

その後はコンソールにログ表示してる。コールバック関数の引数 (targetDocument) がそのページの document オブジェクトだ。

よく分からない理由で firebug のエラーコンソールに出てくれないので、普通のエラーコンソールで出力を確認した(「ツール」 -> 「エラーコンソール」)。

はてなダイアリーのキーワード リンクを無効化する

次は、はてなダイアリーのキーワード リンクを無効化して単なる文字列にする feature。

jetpack.tabs.onReady(function(targetDocument) {
  if (targetDocument.defaultView.frameElement) {
    return;
  }
 
  if (targetDocument.location.href.search(/^http:\/\/d.hatena.ne.jp\//) !== -1) {
    $(targetDocument).find("a.keyword").each(function() {
      $(this).replaceWith($(this).html());
    });
  }
});

(gist: 248261 - GitHub)
if 文で「URL がはてなダイアリーだったら」って条件分岐してる。

その後の置き換える処理は jQuery を使ってる。こんな風に Jetpack では jQuery が使えるので、「条件に合うやつを全部置き換える」とかいうのが簡単にできる。

$(targetDocument).find ... ってとこはちょっと注意が必要。普通の jQuery コードならここは $("a.keyword") ... って書くんだけど、それではうまくいかない。

Jetpack feature 内では普通の document オブジェクトは存在しない。その代わり、このコールバック関数内では targetDocument が document オブジェクトになっている。なので、一旦 $(targetDocument)jQuery オブジェクトに変換してる。その後は普通の jQuery コードと同じ。

別の書き方

次は、さっきの feature の別の書き方。

jetpack.future.import("pageMods");
 
var callback = function(targetDocument) {
  $(targetDocument).find("a.keyword").each(function() {
    $(this).replaceWith($(this).html());
  });
};
 
var options = {};
options.matches = ["http://d.hatena.ne.jp/*"];
 
jetpack.pageMods.add(callback, options);

(gist: 248334 - GitHub)
pageMods ってのを使用してる。

1行目の jetpack.future.import("pageMods"); ってのがポイント。Jetpack では「仕様が確定してないけど将来実装される予定の機能」を先取りして使うことが出来る。pageMods もその一種で、こうやって import して初めて使えるようになる。

この pageMods を使うと、特定の URL パターンにマッチするページだけ動作するようにできる。要するにグリモンみたいに動作させるための簡単な書き方。

pageMods については以下を参照。

ここでもさっきみたいに if (targetDocument.defaultView.frameElement) って書いて frame のときは除くようにしないといけないような気がする。でもよく分かんないのでこのままにしておく。

最後に

ちなみに、今回はローカルのJetpack FeatureファイルをインストールするFeatureをインストールして使ってみた。めちゃ便利。

使い方も「Install JetpackFeature」を選んで js ファイルを指定するだけ。今回みたいにちょこちょこ feature を作って試すのに便利。

まあ、これって Jetpack 本体が持ってなきゃいけないような気もするけど。