前回は、拡張機能に必要なファイルの説明とブラウザ拡張について記述しました。
今回は、ブラウザ拡張のイベントついて記述していきます。


イベント処理は、各コンポーネントのイベントハンドラ実装としてJavaScriptで記述します。
そこで、今回はイベントハンドリグとファイル操作の方法についてご紹介します。
( 2008/10/13 )

イベントハンドリング


イベントのハンドリングは、大きく分類すると、
  • メニューやツールバーなどユーザ操作がトリガ

  • ページ読み込みなどブラウザ動作がトリガ
となるものがあります。


それぞれの処理記述のコードサンプルをご紹介します。

■メニューやツールバーなどユーザ操作がトリガとなる

sampleOverlay.xul

<?xml version="1.0" encoding="UTF-8"?>
<overlay id="sampleextension-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- イベントハンドル時の実行コードを指定 -->
<script type="application/x-javascript" src="eventhandle.js"/>

<!-- 右クリックコンテキストメニュー -->
<popup id="contentAreaContextMenu">
<menuitem id="sample-item" label="Hello, sample extension" oncommand="menu_click()"/>
</popup>

</overlay>

eventhandle.js

function menu_click() {
alert('menu click');
}


■ページ読み込みなどブラウザ動作がトリガとなる

sampleOverlay.xul

<overlay id="sampleextension-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- ページ読込み時の実行コードを指定 -->
<script type="application/x-javascript" src="onpageload.js"/>
</overlay>

onpageload.js

window.addEventListener('load', MyContLoad.init, false);
var MyContLoad = {
init: function() {
window.removeEventListener("load", MyContLoad.init, false);
window.addEventListener("DOMContentLoaded", MyContLoad.onContentLoad, false);
},
onContentLoad: function() {
// ここにページ処理を記述
alert('page load');
}
};


この他にも、onStateChange関数や processNewURL関数を利用することで、”タブ切り替え”や”アドレスバーのURLの変更”のイベントをハンドリングすることも出来ます。


ファイル操作


拡張機能からファイル操作が必要となる場合があると思います。
ここではファイル操作の方法についてご紹介します。

ファイルシステムには、Mozilla XPCOM コンポーネント経由でアクセスできます。
※XPCOM(Cross Platform Component Object Model)は、ファイルやメモリ管理、スレッド、基本的なデータ構造などといった、一連のコアのコンポーネントやクラスを提供します。

■XPCOM によるファイル操作

ファイルの操作として、
  • 作成

  • 削除

  • 読込み

  • 書込み
のコードサンプルをご紹介します。

sampleOverlay.xul

<overlay id="sampleextension-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- 外部ファイル操作の実行コードを指定 -->
<script type="application/x-javascript" src="file.js"/>

<!-- メニューバー(新規) -->
<menubar id="main-menubar">
<menu id="sample-menu" label="外部ファイル操作">
<menupopup id="sample-popup">
<menuitem label="作成" oncommand="create()"/>
<menuitem label="削除" oncommand="remove()"/>
<menuitem label="読込み" oncommand="read()"/>
<menuitem label="書込み" oncommand="write()"/>
</menupopup>
</menu>
</menubar>

</overlay>

file.js

// ■ファイルの作成
function create() {
// オブジェクト生成
var file = Components.classes['@mozilla.org/file/local;1']
.createInstance(Components.interfaces.nsILocalFile);
// オブジェクト初期化
file.initWithPath('C:\\temp\\temp.txt');
// ファイル作成
// 第1引数には,生成するファイルの種類
// 第2引数は生成するファイルのアクセス権
file.create(file.NORMAL_FILE_TYPE, 0666);
}

// ■ファイルの削除
function remove() {
// オブジェクト生成
var file = Components.classes['@mozilla.org/file/local;1']
.createInstance(Components.interfaces.nsILocalFile);
// オブジェクト初期化
file.initWithPath('C:\\temp\\temp.txt');
// ファイルが存在するかどうか
if (file.exists()) {
// ファイル削除
// 引数にtrueを渡すとファイルやフォルダを再帰的に削除
// 今回はとりあえずfalse
file.remove(false);
}
}

// ■テキストファイルの読み込み
function read() {
// オブジェクト生成
var file = Components.classes['@mozilla.org/file/local;1']
.createInstance(Components.interfaces.nsILocalFile);
// オブジェクト初期化
file.initWithPath('C:\\temp\\temp.txt');
// 文字コード指定
var charset = 'Shift_JIS';
// ファイルストリーム生成
var fileStream = Components.classes['@mozilla.org/network/file-input-stream;1']
.createInstance(Components.interfaces.nsIFileInputStream);
// 読込み専用で初期化
fileStream.init(file, 1, 0, false);
// 文字列読込みストリーム生成
var converterStream = Components.classes['@mozilla.org/intl/converter-input-stream;1']
.createInstance(Components.interfaces.nsIConverterInputStream);
// 文字列読込みストリーム初期化
converterStream.init(fileStream, charset, fileStream.available(),
converterStream.DEFAULT_REPLACEMENT_CHARACTER);

// 文字列の読込み
var out = {};
converterStream.readString(fileStream.available(), out);
var fileContents = out.value;
// 文字列読込みストリームクローズ
converterStream.close();
// ファイルストリームクローズ
fileStream.close();
// 読込んだ文字列を表示
alert(fileContents);
}

// ■テキストファイルの書き込み
function write() {
// オブジェクト生成
var file = Components.classes['@mozilla.org/file/local;1']
.createInstance(Components.interfaces.nsILocalFile);
// オブジェクト初期化
file.initWithPath('C:\\temp\\temp.txt');
// ファイルが存在するかどうか
if (!file.exists()) {
// ファイル作成
file.create(file.NORMAL_FILE_TYPE, 0666);
}
// 文字コード指定
var charset = 'Shift_JIS';
// 書込む文字列
var string = 'write';
// ファイルストリーム生成
var fileStream = Components.classes['@mozilla.org/network/file-output-stream;1']
.createInstance(Components.interfaces.nsIFileOutputStream);
// 書込み専用で初期化
fileStream.init(file, 2, 0x200, false);
// 文字列書込みストリーム生成
var converterStream = Components.classes['@mozilla.org/intl/converter-output-stream;1']
.createInstance(Components.interfaces.nsIConverterOutputStream);
// 文字列書込みストリーム初期化
converterStream.init(fileStream, charset, string.length,
Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);

// 文字列書込み
converterStream.writeString(string);
// 文字列書込みストリームクローズ
converterStream.close();
// ファイルストリームクローズ
fileStream.close();
}



役に立つ拡張機能を作るために、今後も色々試した情報を公開していきます。