Firefox拡張機能のJavaScript内でXPathを使用する
Firefoxの拡張機能を作成する上でXPathを使いたくなった。少し調べたので、以下メモ。
参考にしたページ
サンプルコード
Wikipediaの日本語版から英語版に移動するサンプルコードは以下。英語版のURLを取ってくるのにXPathを使用している。
var switchWikipedia = function() { var targetHost = "ja.wikipedia.org"; var xpath = '//li[@class="interwiki-en"]/a'; // 現在のタブのnsIURI, documentオブジェクト (FUELを使用している) var currentUri = Application.activeWindow.activeTab.uri; var currentDocument = Application.activeWindow.activeTab.document; if (currentUri.host == targetHost) { // ここでXPathを使っている var nodes = currentDocument.evaluate( xpath, currentDocument, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var nextUri = nodes.snapshotItem(0).getAttribute("href"); if (nextUri) { // 新しいnsIURIオブジェクトを作成する var newNsIURI = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService) .newURI(nextUri, null, null); // 現在のタブに新しいページを読み込む Application.activeWindow.activeTab.load(newNsIURI); } } };
解説
まずポイントは、documentオブジェクトを取得するところ(7行目)。タブブラウザなので開いているページはたくさんあって、どのdocumentなのか指定しないとうまく動かない*1。
もう一つのポイントは、document.evaluateメソッドの戻り値だ(このコードで言うとnodes)。
この戻り値は、第4引数によってどんな型にするか指定できる。やたら種類があるが、とりあえずXPathResult.ORDERED_NODE_SNAPSHOT_TYPEを指定しておけば問題ないだろう。
これで戻り値としてXPathにマッチするノードが全部取得できる。この例の様にsnapshotItemメソッドで各ノードを参照できるし、snapshotLengthプロパティでノード数を取得できる。
この戻り値に関してはMDCのXPathResultページが参考になる、はずなのだが、今のところ各プロパティ、メソッドの説明はほとんどない(ので、あんまり役に立たない)。
ノードが取得できたら、後はやりたい放題だ。element - DOM | MDNに書いてあることはだいたいできる(と思う)ので、いろいろ試してみよう。
*1:2008/11/28 追記: FUELを使用しない場合、content.document
で現在開いているタブのdocumentオブジェクトを取得できる。こちらの方が簡単で良いだろう。