Jetpackチュートリアル
このページは、Mozilla Labsの Jetpack Tutorial およびJetpackインストール後の”about:jetpack”を元にしたものです。
最初は普通に翻訳としようかとも思ったのですが、やはり原文に縛られるとニュアンス的に難しくなるので(これは多分に私の語学力によるものですが)、いつも通りあくまで「私の視点での、原文を読みながらの要約と補足」という位置づけで記述しますので、ご了承ください。
Jetpackチュートリアルへ、ようこそ!このチュートリアルを最後まで読めば、閲覧中のページもしくは全てのページからFlashなどのembedを自動的に削除するJetpack Featureを作ることができるようになります。コードはいずれも両手で数えられる程度の短いステップだけです。
Chapter 0: はじめに
Jetpackの最も重要な目的のひとつは、開発をワクワクさせることです。緊密なフィードバックの繰り返しや、優れたデバッガなどによって活発にJetpack Featureを作っていけば、それが文字通りWebページを活性化させることに繫がります。だからこそ、Jetpackでは全てのエラーを行番号付きでレポートしています。
さあ、開発をはじめましょう。このチュートリアルはWeb上にあるものをベースにしていますが、Jetpackをインストールすると使えるようになる “about:jetpack” のページを見るのが最良の方法です。なぜなら、そちらのページにはインタラクティブなサンプルコードがついているからです。
コードだけを読んでもピンとこないことは多いですが、そんな時に実際に実行してみれば理解が深まります。このページを参考にする場合も、まずは Jetpack をインストールして about:jetpack ページを開き、あわせて読み進めることをお勧めします。
この about:jetpack にあるインタラクティブコードについて説明しておきます。いずれかのコードブロックをクリックすると、自動的にJetpack Featureとしてインストールされ、コードは編集可能な状態になります。その場で実行結果を確認することが出来ますし、更にコードを編集して “try out this code” をクリックすれば、その実行結果をリアルタイムに確認できます。コードの変更や重ねた実行を繰り返してよくわからない状態になってしまった場合などは、ページをリロードすれば元に戻ることを覚えておきましょう。
Chapter 1: ショットガン
“Boom Stick”はショットガンのことでいいのかな?とにかく、ページ上のものを”Boom!”できる機能をつけましょうということ。
まずはステータスバーに「Boom!」というメッセージを表示するウィジェットを追加しましょう。
jetpack.statusBar.append({ html: "Boom!" });
前述の通り、about:jetpackのページから実行してみましょう。ステータスバーに”Boom!”という文字が現れたかと思います。リスターと無しに表示されたことに注目してください。
見ての通り、ここで使っている statusBar.append関数はオプションにオブジェクトを受け取ります。htmlキーに表示内容を渡していますが、このキーをurlにして表示内容のhtmlファイルを指定することもできます。その場合、相対パス指定もできます。
現時点で、ウィジェットは恐らく広すぎると思います。これはまだJetpackに自動サイズ調整機能が無いためです。とりあえず、widthを明示的に指定しておきましょう。
jetpack.statusBar.append({ html: "Boom!", width: 45 });
それは良いとして、しかし「Boom!」とステータスバーに出るだけでは面白くありません。何か実行するようにしましょう。
jetpack.statusBar.append({ html: "Boom!", width: 45, onReady: function(widget){ $(widget).click(function(){ console.log( jetpack.tabs ); }); } });
これで、ウィジェットをクリックすればいつでも、jetpack.tabsオブジェクトの内容がFirebugコンソールに出力されるようになりました。JetpackはFeatureのデバッグに新たなツールを作るのではなく、既に評価の高いFirebugをそのためのツールとしています。開発時は是非ともインストールしておきましょう。
Firebugがあれば、オブジェクトの中身を調べたりすることも簡単です。例えば、現在アクティブになっているjetpackタブにアクセスするための jetpack.tabs.focused オブジェクトなどを、すぐに見つけられると思います。
そして、jQueryが自動的に包含されていることにも気づくと思います。もしそれがピンと来ないようであれば、Javascript標準には無い$関数に注目して下さい。これについては、jQueryのドキュメントと、拙作jQuery日本語リファレンスなどを参照してもらえればと思います。将来的にはDojoなど他のライブラリも取り込まれいくようです。
さて、もう少し Boom! を面白くしてみましょう。
jetpack.statusBar.append({ html: "Boom!", width: 45, onReady: function(widget){ $(widget).click(function(){ jetpack.notifications.show( "Booming!" ); $(jetpack.tabs.focused.contentDocument) .find("body") .css({backgroundColor: "blue"}) .animate({opacity: .5}); }); } });
試してみましょう。どのタブオブジェクトにも、イベントリスナーやプロパティが豊富に用意されていますので、FirebugやAPIリファレンスで確認してください。たとえばiframeなどと同様に、contentDocumentという指定したタブのドキュメントオブジェクトにアクセスするプロパティがあります。また、.alert()関数などの親となるWindowオブジェクトにアクセスできる contentWindow プロパティなどもあります。
ユーザに軽く何か情報を伝えたい場合は、jetpack.notifications.show()関数を使うと良いでしょう。これはWindowsやLinuxでは”Toast“、Macでは”Growl“として実装されているメッセージ通知方式です。
では次に、ページを青くするのはやめて、代わりにページ上からembed要素を削除する機能をつけましょう。これはjQueryを使えば1行で書けてしまいます。
jetpack.statusBar.append({ html: "Boom!", width: 45, onReady: function(widget){ $(widget).click(function(){ var doc = jetpack.tabs.focused.contentDocument; $(doc).find("embed").remove(); }); } });
どうでしょう?10行以下のコードで、embed除去ボタンが出来てしまいました。
Chapter 2: 自動 Boom!
前章でembedを取り除けるようにしましたが、ページごとに必ず “Boom!” ボタンを押さなければなりませんでした。これを、全てのサイトに対する設定として enable/disable を設定しておける機能にしてみるのはどうでしょう?それには、jetpack.tabs.onReady 関数の魔法を用います。ここには、新しいページがロードされて、しかしiframeや画像、スクリプトなどが読み込まれる前に毎回呼び出されるコードを記述できます。全てのロードが終わるのを待ちたいのであれば、その場合は jetpack.tabs.onLoad を使います。Jetpackは複数のウィンドウを開いたり、新しいタブを作ったりといった複雑なケースでの動作を引き受けてくれますし、Jetpack Featureがリロードされた場合に以前のイベントハンドラを削除するようなこともしてくれます。そのため、開発中にエラーが起きたりした場合もFirefoxを再起動するような必要はありません。
function removeEmbeds(doc){ $(doc).find("embed").remove(); } jetpack.statusBar.append({ html: 'Boom?', width: 70, onReady: function(widget){ $("input", widget).click(function(){ if( this.checked ){ jetpack.tabs.onReady( removeEmbeds ); removeEmbeds(jetpack.tabs.focused.contentDocument); } else jetpack.tabs.onReady.unbind( removeEmbeds ); }); } });
unbind関数で、イベントハンドラを取り除きます。これはJetpack開発チームの工夫のようで、例えば unbind( ‘onReady’ )のように文字列でイベントを渡すのではなく、イベント関数のunbindを呼び、そこに削除したいリスナー関数を渡すようになっています。
Chapter 3: ライブラリ
すばらしいAPIは、再利用性を大切にします。だからこそJetpackでは「標準ライブラリ」として一般的なWebAPIを取り込むようにしています。今現在は Twitter のライブラリが取り込まれているだけですが、将来的にはより多くのものが使えるようになるでしょう。また、その際にはJetpackに取り込むのではなく、ライブラリを外部からインポートする機能も実装されると思います。
ここでは、Twitterライブラリを用いた簡単なJetpack Featureを作ります。指定したユーザの最後の呟きを通知するツールです。
var twitter = jetpack.lib.twitter var oldTweet = null; function getTweet(){ twitter.getTwitLatestStatus( "osunick", function(tweet){ var newTweet = tweet.text; if( oldTweet != newTweet ){ jetpack.notifications.show( newTweet ); oldTweet = newTweet; } }); } getTweet(); setInterval( getTweet, 1000*60 );
例えば自分であれば “osunick” を “nao58″ に変えれば、早速自分の呟きで試すことが出来ます。
変更した際も、Jetpackは自動的にsetIntervalやsetTimeoutをクリアしてくれるので、以前のリスナーが生きていて混乱してしまうようなことはありません。
このTwitterライブラリのドキュメントを入手したい場合、最も簡単なのは現時点ではコードのコメントを読むことだそうです。コードは自身の端末内にインストールされているので、ご自分の “about:jetpack” ページからリンクを辿ってください。
Chapter 4: Email通知
ここまでを通じて一緒に試してきたことで、次のサンプルコードを読んで理解できるようになっていると思います。これは、Gmailの受信箱にある未読メール件数を表示するJetpack Featureです。ここまでに出てきていないAPIは、jetpack.tabs.open(url)とtab.focus()だけなので、だいたいの想像でコードは読めるのではないでしょうか。
function GmailNotifier(doc){ $(doc).click( this.goToInbox ); this.update( doc ); setInterval( function(){ this.update(doc); }, 60*1000 ); } GmailNotifier.prototype = { goToInbox: function(){ jetpack.tabs.open("http://mail.google.com"); jetpack.tabs[ Jetpack.tabs.length-1 ].focus(); }, update: function(doc){ var url = "http://mail.google.com/mail/feed/atom"; doc = $(doc); $.get( url, function(xml){ var el = $(xml).find("fullcount"); // Unread message count if( el ){ var count = el.get(0).textContent; doc.find("#count").text( count ); } else{ doc.find("#count").text( "Login" ); } }); } } jetpack.statusBar.append({ html: '', onReady: function(doc){ var gmail = new GmailNotifier(doc); $("#count", doc).css({ position: "absolute", left: 4, top: 8, fontSize: "10px", cursor: "pointer", backgroundColor: "rgba(255,255,255,.8)" }); }, width: 20 });
Chapter 5: 将来
今後もJetpackでは沢山の機能が追加されていく予定です。当面はAPIリファレンスを参考に、色々と試してみてください。