前回はXULのオーバーレイによってFirefoxの右クリックメニューへタグヘルパー拡張機能のメニュー項目を追加しました。今回はメニュー項目をクリックしたときの動作をJavaScriptで実装します。なお,第3回完成時点でのソースファイルは,下記URLから入手可能です。
ソースファイルのフォルダ構成
前回作成した「overlay.xul」では,クロムURLが「chrome://taghelper/content/overlay.js」で表されるJavaScriptファイルを,<script>タグを使って読み込んでいます。今回はこの「overlay.js」を作成します。「overlay.js」はcontentパッケージ内のソースファイルなので,当然「content」フォルダ内に配置します。したがって,第3回完成時点での各種ソースファイルのフォルダ構成は図1のようになります。また,第3回で新たに作成するソースファイルの概要を表1に示します。
表1 第3回で新たに作成するソースファイルの概要
| ファイル名 | 概要 |
|---|---|
| overlay.js | overlay.xul内で読み込まれるJavaScript。 |
機能のオブジェクト化
前回作成した「overlay.xul」では,オーバーレイで追加するmenuitem要素のoncommand属性に「TagHelper.generateTags();」と記述しました。これは,「TagHelper」オブジェクトの「generateTags」プロパティ(function型オブジェクト)を実行することを意味します。そこで,ひとまずは「overlay.js」へリスト1のような雛形の内容を記述します。
リスト1 「overlay.js」への記述内容1(雛形)
var TagHelper = {
generateTags: function() {
},
};
拡張機能がFirefoxのブラウザウィンドウへオーバーレイする際,オーバーレイするXUL(今回の場合は「overlay.xul」)から読み込まれるJavaScript(今回の場合は「overlay.js」)内で定義したグローバル変数や関数は,すべてFirefoxのブラウザウィンドウ「browser.xul」のwindowオブジェクトのプロパティとなることに注意してください。「browser.xul」のwindowオブジェクトのプロパティには,Firefox自体や他の拡張機能によって定義された変数や関数がいくつも混在しています。独立性を高めて拡張機能どうしの衝突を避けるためには,リスト1のように拡張機能で利用する変数や関数をすべてひとつのオブジェクトのプロパティとしてまとめてしまうのが効果的です。
選択範囲の取得
リスト1の段階では「generateTags」プロパティを実行しても,何の処理もしません。ここからは,現在表示しているWebページ上で選択されたすべての文字列を取得し,配列へ格納する処理を追加します。「overlay.js」にリスト2の内容を追加してください。
リスト2 「overlay.js」への記述内容2(選択範囲の取得処理を追加)
var TagHelper = {
generateTags: function() {
var keywords = [];
var sel = window.content.getSelection();
for (var i = 0; i < sel.rangeCount; i++) {
var keyword = sel.getRangeAt(i).toString();
keyword = keyword.replace(/^\s+|\s+$/g, "");
keywords.push(keyword);
}
sel.removeAllRanges();
},
};
リスト2で追加した内容を順を追って解説します。まず,「window.content」によってブラウザの表示エリア内のWebページに対応するDOM:windowオブジェクトを取得します。次に,windowオブジェクトのgetSelectionメソッドで,選択範囲に対応するDOM:selectionオブジェクトを取得します。Firefox 3ではCtrlキーを押下しながら複数の範囲を選択することが可能となりましたが,個々の選択範囲に対応するDOM:rangeオブジェクトは,selectionオブジェクトのgetRangeAtメソッドを使って取得します。rangeオブジェクトのtoStringメソッドは,選択範囲の文字列を返すので,これを正規表現によって先頭と末尾の空白を取り除いてから配列へ追加していきます。最後に,selectionオブジェクトのremoveAllRangesメソッドによって,すべての選択範囲を解除します。

