Now browsing the archives for 7月, 2010.
Jetpack SDK 0.5 の Tabs API
Jetpack SDK 0.5 で追加された Tabs API を使用すると、指定したURLを新しいタブやウィンドウで開いたり、各タブ内に表示されたページのDOMへアクセスしたり、タブの開閉やページの読み込みなどのイベントに対してコールバック処理を追加したりすることが可能です。
Tabs API を使用するには、はじめに require 関数でモジュールをインポートします。
var tabs = require("tabs");
タブを開く
Tabs API の open
メソッドで、指定したURLを新しいタブやウィンドウで開くことが可能です。似た機能を持ったAPIとして、 tab-browser API の addTab
メソッドもありますが、 Tabs API の open メソッドを使用することが推奨されています。
open
メソッドの引数に直接URLを指定した場合、新しいタブへ開くと同時にフォーカスします。
tabs.open("http://www.example.com/");
一方、引数を下記のようなオブジェクト形式とした場合、指定したURLを新しいバックグラウンドのタブで開きます。
tabs.open({
url: "http://www.example.com/",
inBackground: true
});
各タブの情報を取得する・タブ内のページのDOMへアクセスする
Tabs API の activeTab
プロパティによって現在のタブ(Tab オブジェクト)を取得したり、 Tabs API のオブジェクト自体を for ~ in ループで回すことで全ウィンドウ内の全タブ(Tab オブジェクト)を列挙したりすることが可能です。 Tab オブジェクトは、 title
プロパティでタブのタイトルやURLを取得したり、 contentDocument
プロパティでタブ内に表示されたページのDOMへアクセスしたりすることが可能です。
下記は、現在のタブのタイトルとURLを取得し、現在のタブ内に表示されたページのDOMの window.alert メソッドを使って表示させる例です。
var tab = tabs.activeTab;
tab.contentWindow.alert(tab.title + "
" + tab.location);
Tab オブジェクトの面白い機能として、 thumbnail
プロパティでタブ内に表示されたページのサムネイル画像を html:canvas 要素として取得することが可能です。下記は、全ウィンドウ内の全タブについてサムネイル画像を取得して data: URL へ変換し、それらを表示するHTMLを新しいウィンドウで開く例です。
var html = "";
for (var tab in tabs) {
html += '<img src="' + tab.thumbnail.toDataURL() + '"/>';
}
tabs.open({
url: "data:text/html,<html><body>" + html + "</body></html>";,
inNewWindow: true
});
タブを閉じる・移動する
Tab オブジェクトには、タブを閉じる close
、タブを同一ウィンドウ内の別の位置へ移動する move
、タブへフォーカスする activate
などのメソッドもあります。下記は、現在のタブを閉じる例です。
tabs.activeTab.close();
タブ関連イベントへのコールバック処理
onOpen(タブを開いたとき), onClose(タブを閉じたとき), onActivate(アクティブなタブが変化したとき), onReady(タブ内のページのDOMツリー構築時 = DOMContentLoaded イベント発生時), onPaint(タブ内のページで再描画発生時 = MozAfterPaint イベント発生時)などに対してコールバック処理を追加することができます。下記は、タブ内のページのDOMツリー構築完了時に、そのページのURLをコンソールへ表示する例です。
tabs.onReady = function(tab) {
console.log("onReady: " + tab.location.href);
};
Jetpack SDK 0.5 の Unload API
Jetpack SDK の Unload API を使用すると、以下の例のように Firefox の終了や拡張機能の無効化などのシグナルを検知してコールバック処理を実行することが可能となります。
require("unload").when(function(reason) {
switch (reason) {
case "disable":
// 拡張機能が無効化される直前に実行する処理
break;
case "uninstall":
// 拡張機能が削除される直前に実行する処理
break;
case "shutdown":
// アプリケーション終了直前に実行する処理
break;
}
});
Firefox 3.6 以下ではアドオンマネージャで該当する拡張機能の「無効化」または「削除」ボタンを押下して Firefox を終了または再起動する直前にコールバック処理が実行されるのに対して、 Firefox 4.0b2 以上では「無効化」または「削除」ボタンを押下した直後にコールバック処理が実行されます。
Jetpack SDK 0.5 の Selection API
Jetpack SDK 0.5 で追加された Selection API を使用すると、選択範囲の取得や変更などが可能となります。
Selection API を使用するためには、はじめに require 関数でモジュールをインポートします。
var selection = require("selection");
選択範囲の取得
Selection API の text
および html
プロパティで選択範囲の文字列あるいはHTMLソースを取得・変更することが可能です。また、Ctrlキーを押下しながら複数の範囲を選択した場合、 contigious
プロパティが false となります。この時、 Selection API のオブジェクト自体に対して for ~ in ループで個々のサブ選択範囲(Selection オブジェクト)を取得することが可能です。
以下は、選択範囲が複数ある場合を考慮し、全ての選択範囲のHTMLソースをコンソールへ出力する例です。
if (selection.contiguous) {
// 選択範囲がひとつだけの場合
console.log(selection.html);
}
else {
// 複数の選択範囲がある場合
for (var subsel in selection) {
console.log(subsel.html);
}
}
範囲を選択したときのコールバック処理
onSelect
プロパティによって、範囲を選択したときのコールバック処理を追加することが可能です。以下は、範囲を選択した時に、その選択範囲を <span> タグで囲み、蛍光ペンで着色したような表示にする例です。
selection.onSelect = function() {
selection.html = '<span style="background-color: yellow;">' + selection.html + '</span>';
};
Jetpack SDK 0.5 の Reuqest API
Jetpack SDK 0.5 で追加された Request API を使用すると、 XMLHttpRequest によってWebサーバとデータを送受信する処理をより簡単に実装できます。特に、レスポンスがJSONかXML形式であるようなWebサービスのAPIを利用する場合に重宝しそうです。
この記事では、 Request API を使い、Twitter でキーワード「Firefox 4」を含むツイートの検索結果をコンソールへ列挙する例を紹介します。
Twitter のAPI仕様
実装に入る前に、 Twitter の検索用APIの仕様を簡単に示しておきます。
リクエスト
キーワード xxx で検索する場合、以下のようなURLへGETメソッドで送信する。
http://search.twitter.com/search.json?q=xxx
レスポンス
キーワードにマッチしたツイートのデータが、下記のようなJSON形式で返る。
{ "results": [ { "text": "(1番目のツイートの内容)", "from_user": "(1番目のツイートの発言者)" ... }, { "text": "(2番目のツイートの内容)", "from_user": "(2番目のツイートの発言者)" ... }, { "text": "(3番目のツイートの内容)", "from_user": "(3番目のツイートの発言者)" ... }, ... ] }
実装
まず、 require 関数でモジュールをインポートします。
var requests = require("request");
次に、 Request APIの Request
コンストラクタを用いて、 Request オブジェクトのインスタンスを生成します。コンストラクタの引数には、以下のプロパティを有するオブジェクトを渡します。
プロパティ | 概要 |
---|---|
url |
データ送信先のURL |
onComplete |
データ受信時(XHRでいうところの readyState == 4)のコールバック処理 |
headers |
必要に応じてリクエストヘッダ(User-Agent や Referer)をオブジェクト形式でセットする。例:headers: { "User-Agent": "MyApp", Referer: "http://..." }, |
content |
必要に応じてリクエストのパラメータをオブジェクト形式でセットする。 |
contentType |
必要に応じてHTTPヘッダの Content-Type の値をセットする。 デフォルトでは application/x-www-form-urlencoded |
生成した Request インスタンスの get
メソッドを呼び出すと、GETメソッドでリクエストが送信されます。なお、 post
メソッドを呼び出すと、POSTメソッドでリクエストが送信されます。
// Request インスタンスの生成
var request = requests.Request({
url: "http://search.twitter.com/search.json",
content: { q: "Firefox 4" },
onComplete: function () {
// ToDo
}
});
// GETメソッドで送信
request.get();
Webサーバからのレスポンスが返って onComplete
メソッドがコールバックされると、 Request インスタンスの response
プロパティからレスポンス内容(Response オブジェクト)を取得することができるようになります。 Response オブジェクトは色々なプロパティを有し、 json
プロパティや xml
プロパティでレスポンスのボディ部をJSONあるいはXML形式でパースした結果を取得したり、 headers
プロパティでレスポンスのヘッダ部の各フィールド値を取得したりすることが可能です。
今回はレスポンスのボディ部をJSON形式でパースし、前述のAPI仕様にあるとおり "results" プロパティでツイートのデータの配列を取得し、配列の各要素に対して "from_user", "text" プロパティで発言者と発言内容を取得します。
onComplete: function () { var results = this.response.json.results; results.forEach(function(result) { console.log("user: " + result.from_user); console.log("text: " + result.text); }); }
Jetpack SDK 0.4 の Page Worker API
HTTP(S)によりWebサーバとデータを送受信するには、 xhr API で XMLHttpRequest のインスタンスを生成する方法や、 Jetpack SDK 0.5 で追加された Request API を使用する方法があります。しかし、これらのAPIではWebサーバからのレスポンスがHTMLデータだった場合、特定のノードにある文字列を抽出したりする処理がやや困難となります。
一方、 Jetpack SDK 0.4 で追加された Page Worker API を用いると、不可視のフレーム(iframe 要素)内に指定したURLのHTMLドキュメントをロードし、パースされた結果をDOM操作することが可能となります。この記事では、 Page Worker API を用いて Wikipedia の Internet に関するページを不可視のフレームに読み込んで見出し(H2 > SPAN
要素)を列挙する例を紹介します。
基本的な使い方
まず、 require 関数でモジュールをインポートします。
var pageWorker = require("page-worker");
Page Worker APIの Page
コンストラクタを用いて、 Page オブジェクトのインスタンスを生成します。コンストラクタの引数には、以下のプロパティを有するオブジェクトを渡します。
プロパティ | 概要 |
---|---|
content |
不可視のフレームにロードするURL、またはHTMLソース |
onReady |
ロード完了時のコールバック処理 |
allow |
不可視のフレーム内でのスクリプト実行を許可するかどうかなどを指定するためのオプション。allow: { script: false } でスクリプトの実行を不許可に設定することが可能。 |
生成した Page インスタンスを add
メソッドへ渡すと、不可視のフレーム内への読み込みが開始されます。
var page = pageWorker.Page({
content: "http://en.wikipedia.org/wiki/Internet",
onReady: function() {
// ToDo
}
});
pageWorker.add(page);
不可視のフレームへの読み込みが完了すると、 Page インスタンスの window
および document
プロパティ経由で不可視のフレーム内のDOMへアクセスすることができるようになります。以下の例では、不可視のフレームへの読み込み完了時、 HTMLのURLおよびタイトルを取得してコンソールへ表示し、さらにH2要素直下にあるSPAN要素の中身の文字列を列挙して表示します。
onReady: function() { var url = this.window.location.href; var title = this.document.title; console.log(url + " " + title); var elts = this.document.querySelectorAll("h2 > span"); Array.forEach(elts, function(elt) { console.log(elt.textContent); }); pageWorker.remove(this); }
なお、 onReady
の最後で Page オブジェクトのインスタンス自身を PageWorker の remove
メソッドへ渡すことで、 window
および document
プロパティが削除され、不可視のフレーム内でのページ読み込みに使用されたメモリが解放されます。
Jetpack SDK 0.4 の Simple Storage API
拡張機能の設定値のような少量のデータを保存する際には Preferences Service API を使用しますが、より多くのデータを永続的に(Firefox を終了しても保持されるように)保存するには、 Simple Storage API が便利です。
基本的な使い方
はじめに require 関数でライブラリをインポートします。
var simpleStorage = require("simple-storage");
もっとも単純な方法は、 storage
プロパティへ直接値をセットする方式です。以下は “test” という文字列を保存した後、値を取り出す例です。
simpleStorage.storage = "test";
console.log(simpleStorage.storage); // test
文字列だけでなく、数値、配列、オブジェクトなどをセットして保存可能です。
simpleStorage.storage = { "foo": 100, "bar": 200 };
console.log(simpleStorage.storage.foo); // 100
上記は以下のように書くことも可能です。
simpleStorage.storage.foo = 100;
simpleStorage.storage.bar = 200;
データの保存先
Simple Storage APIを使って保存したデータは、プロファイルフォルダ配下の jetpack{パッケージマニフェストのID}simple-storagestore.json へJSON形式で保存されます。また、ファイルへの出力タイミングは Jetpack SDK 0.5 時点では Firefox 終了時のみですが、将来的には Firefox 使用中も最大で5分に1回出力される仕様となるようです。
データ保存可能サイズ
ひとつの拡張機能が保存できるデータサイズは5MBまでとなっています。 Simple Storage API の quotaUsage
プロパティにて現在のデータ使用量(5MBを1.0とした割合)を調べたり、 onOverQuota
プロパティにてデータ使用量が最大値を超過したときのコールバック処理を追加したりすることも可能です。ただし、 Jetpack SDK 0.5 時点では正常に動作しないようです。
console.log(simpleStorage.quotaUsage);
simpleStorage.onOverQuota = function() {
// データ使用量が最大値を超過したときのコールバック処理
};