Kanasan.JS #8 で Jetpack について発表した

9月6日(日)、Kanasan.JS #8 に参加した。
Kanasan.JS JavaScript第5版読書会#8& 懇親会

今回は開催地が京都だった。駅で修学旅行生とか観光っぽい人をいっぱい見かけて、京都パワーを補給しながら開催地に向かった。

読書会の内容

今回の内容は、主にキーイベントとフォームの制御(読んだところは p443 から p477)。比較的分かりやすくてスラスラ読めたと思う。

今回思ったのは、サイ本のサンプルコードは読みやすい。うれしい。

Jetpack の発表

で、僕は予告通り Jetpack について発表した。


いくつか feature(追加するスクリプトのこと) を作ったので、それを紹介した。作ったコード本体は全部 Github にあるよ。

hello-statusbar.js

まずは Hello World から。ステータスバーに "Hello" というラベルを追加して、そのラベルをクリックすると下からトースターみたいに通知が出てくる。

jetpack.statusBar.append({
  html: "Hello",
  width: 45,

  // widget 引数が追加されるラベル要素にあたる
  onReady: function(widget){
    $(widget).click(function() {
      jetpack.notifications.show("Hello Jetpack!");
    });
  }
});

7行目 $() ってのは jQuery$ 関数。

Jetpack にはデフォルトで jQuery が入っている。ちなみに、現在 Jetpack バージョン0.4の時点で、中に入ってる jQuery のバージョンは1.3.1。

あと、feature をインストールするにはちょっと注意が必要。Greasemonkey と違ってインストール用の(HTMLの)ページが別途必要になる。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <link rel="jetpack" href="hello-statusbar.js" name="Hello Jetpack in Statusbar" />
    <title>hello-statusbar.js install page</title>
  </head>

  <body>
    <h1>Hello Jetpack in Statusbar install page</h1>
  </body>
</html>

こんな感じで link 要素でインストールする js ファイルのパスを指定する。このページをブラウザで開けば、あとは適当にOKっぽいボタンを押せばインストールできる(Github の install.html とかを開いてもインストールできない)。

Github 上のコードは以下。
mollifier's hello-jetpack at master - GitHub

clHatenaHighlight.js

次に、はてなダイアリーで検索したときのハイライトを消す feature を紹介した。ステータスバーの "clearH" ラベルをクリックするとハイライトが消える。

jetpack.statusBar.append({
  html: "clearH",
  width: 60,
  onReady: function(widget) {
    $(widget).click(function() {
      $(jetpack.tabs.focused.contentDocument).
      find("span.highlight").removeClass("highlight");
    });
  }
});

単純に highlight ってクラスを削除してる。jQuery が使えるので for ループとかなしに一気に書ける。

Github 上のコードは以下。
mollifier's clHatenaHighlight at master - GitHub

ssbSlideBar.js

最後に、Stack Stock Booksブックマークレット代わりになる feature。Amazonの書籍ページなんかを開いた状態で左のスライドバーボタンを押すと、本を登録するボタンが出てくる。

jetpack.future.import("slideBar");

jetpack.slideBar.append({
  icon: "http://stack.nayutaya.jp/images/icon/nayutaya.gif",
  // スライドバーを開いたときのページ内容
  html: "<h1>stack stock books slideBar</h1>" +
        "<div>" +
          "<input type='button' value='unread' />" +
          "<input type='button' value='reading' />" +
          "<input type='button' value='read' />" +
          "<input type='button' value='wish' />" +
        "</div>",

  width: 320,

  // アイコンをクリックしてスライドバーを開いたときのコールバック関数
  onSelect: function(s) {
    s.slide(320, {persist: true}); // 開きっぱなしにする
  },

  // スライドバーの内容のロードが完了したときのコールバック関数
  // スライドバーを開かなくてもこの関数は呼び出される
  onReady: function(s) {
    var getAsin = function(uri) {
      var regex = new RegExp("(ASIN|asin|dp|product|book)/([0-9]{9}[0-9Xx])");
      var match = uri.match(regex);
      return (match === null ? null : match[2]);
    }

    var baseUri = "http://stack.nayutaya.jp/book/";
    var slidebarDoc = s.contentDocument;

    $(slidebarDoc).find("input").click(function() {
      var focusedWindow = jetpack.tabs.focused.contentWindow;
      var asin = getAsin(focusedWindow.location.href);
      if (asin !== null) {
        // 登録ページを読み込む
        focusedWindow.location.href =
          baseUri + asin + "?state=" + $(this).attr("value");
      }
    });

  }

});

Github 上のコードは以下。
mollifier's ssbSlideBar at master - GitHub

Jetpack feature を書くときのポイント

Window オブジェクトがいっぱいある

スライドにも書いたけど、普通の JavaScript コードを書くときと違ってタブごとに Window オブジェクトがある。Window, Document オブジェクトを取得する方法は以下。

jetpack.tabs.focused.contentWindow
今表示しているタブの Window オブジェクト
jetpack.tabs.focused.contentDocument
今表示しているタブの Document オブジェクト

なのでいきなり document.getElementById とかは書けないし、jQuery でよくやる $( CSSセレクタ ) とい書き方もうまく動かない。かなりわかりにくいので注意。

仕様が確定していない

Jetpack はまだまだ開発中のアドオンということで、仕様が固まってない。さらに、公式のAPIリファレンスマニュアルも最新の実装に追いついていない。

今回もスライドバーの使おうとしたんだけど、最初マニュアルをまねしてもうまく動かなかった。で、いろいろググってたらスライドバーに関する解説ページを見つけた(ありがたい)。どうやら仕様が変わってたみたいだ。

なので、開発するにはかなり情報を集めないといけないし、いろいろはまる可能性もある。

最後に

というわけで、Jetpack 入門の補足でした。

Jetpack のコンテストが行われてる。締め切りは 10月15日なので参加するつもりの人(僕)は急ごう。
Jetpack Lift-Off – Details