SET-TIMER::25min
GLOBAL-ALIGN::left
ALIGN::center
拡張機能開発
チュートリアル
----
HEADER::拡張機能開発チュートリアル
CHAPTER::概要
ALIGN::center
本日の
概要
----
[[EM:Part1]] XULとXPCOMを使ってみる
[[EM:Part2]] 拡張機能を作ってみる
----
SoftwareDesign
4月号の
焼き直し
----
すでに
試した人
----
拡張機能
作ったこと
がある人
----
向こうの
部屋へ
----
GO
----
CHAPTER::XULとXPCOMを使ってみる
HEADER::
ALIGN::center
[[EM:Part1]]
----
HEADER::XULとXPCOMを使ってみる
XULと
XPCOMを
使ってみる
----
準備
----
受講さ
れる方
----
PC
----
忘れ
た人
----
隣の人に
見せて貰い
ましょう
----
必要
な物
----
最低
限
----
3つ
----
1
----
Firefox
----
2.0.0.4
----
2
----
テキスト
エディタ
----
UTF-8を
扱える物
----
3
----
ZIP形式を
扱える
アーカイバ
----
7-Zip
オヌヌメ
----
ソースコードを
Webに置いてます
----
ALIGN::right
[[https://piro.sakura.ne.jp/xul/doc/|https://piro.sakura.ne.jp/xul/doc/fxdevcon2007summer/]]
[[fxdevcon2007summer/|https://piro.sakura.ne.jp/xul/doc/fxdevcon2007summer/]]
----
ダウンロード
しといて
ください
----
本編に
入る前に
----
自己紹介
----
発表者:
下田洋志 / "Piro"
自己紹介(略歴)
----
2001
Mozilla用拡張機能の
開発に手を出し始める
(中略)
2007
SoftwareDesign 4月号
特集記事の一部を担当
----
CHAPTER::XUL
FOOTER::XUL
それ
では
----
ALIGN::center
[[EM:XUL]]を
書いて
みよう
----
教科書
8ページ
----
C:\extensions\helloworld\
[[EM:sample.xul]] として保存
[[PRE:
]]
----
メッセージを
表示してみよう
----
[[EM:]] ラベル
[[PRE:
]]
----
sample.xulを
開いて確認
----
もうちょっと
複雑な例
----
[[RAW:
]]
----
[[EM:]] 垂直ボックス
[[EM:]] 水平ボックス
[[PRE:
]]
----
sample.xulを
開いて確認
----
別のファイルを
インクルード
してみよう
----
教科書
19ページ
----
[[EM:オーバーレイ]]
----
1. インクルードされるファイル
overlay.xulを作る
2. overlay.xulをインクルード
する指定をsample.xulに
加える
----
[[EM:overlay.xul]] として保存
[[PRE:
]]
----
このファイルを
インクルード
するための指定
----
XULオーバーレイ
処理命令
----
[[EM:]]
----
sample.xulに
XULオーバーレイ
処理命令を
書き加える
----
[[PRE:
(略)
]]
----
sample.xulを
開いて確認
----
CHAPTER::JavaScript
FOOTER::JavaScript
こん
どは
----
ALIGN::center
[[EM:JavaScript]]
を書いて
みよう
----
直接埋め込む場合
[[PRE:
]]
----
外部ファイルにする場合
[[PRE:
]]
----
メッセージ
を表示する
ボタンを
作ってみる
----
関数を
定義
----
[[PRE:
(略)
]]
----
イベント
ハンドラ
----
[[PRE:
]]
----
ここまで
のまとめ
----
[[PRE:
]]
----
sample.xulを
開いて確認
----
CHAPTER::XPCOM
FOOTER::XPCOM
こん
どは
----
ALIGN::center
[[EM:XPCOM]]
を使って
みよう
----
教科書
27ページ
----
テキスト
ファイルの
読み込み
----
1. 読み込みたいテキスト
ファイルを用意する
2. ファイルハンドラを作る
3. ストリームを用意する
4. ファイルの中身を読み込む
5. (゚д゚)ウマー
----
テキスト
ファイル
----
ファイル
ハンドラ
----
[[EM:nsILocalFile]] ローカルのファイル
[[PRE:
function showMessage() {
var file = Components
.classes['@mozilla.org/file/local;1']
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath('c:\\extensions\\helloworld\\sample.xul');
]]
----
ストリーム
----
[[EM:nsIFileInputStream]] ファイルからの入力用のストリーム
[[PRE:
var fileStream = Components
.classes['@mozilla.org/network/file-input-stream;1']
.createInstance(Components.interfaces.nsIFileInputStream);
fileStream.init(file, 1, 0, false);
]]
----
もう一つ
----
[[EM:nsIConverterInputStream]]
文字コード変換を行いながらデータを読み込むストリーム
[[PRE:
var converterStream = Components
.classes['@mozilla.org/intl/converter-input-stream;1']
.createInstance(Components.interfaces.nsIConverterInputStream);
converterStream.init(fileStream, 'UTF-8', 1024,
converterStream.DEFAULT_REPLACEMENT_CHARACTER);
]]
----
ファイル
の中身を
読み込む
----
[[PRE:
var out = {};
converterStream.readString(fileStream.available(), out);
converterStream.close();
fileStream.close();
alert(out.value);
}
]]
使い終わったストリームはクローズしておきましょう。
----
ここまで
のまとめ
----
[[PRE:
]]
----
sample.xulを
開いて確認
----
うごか
ない!
----
ALIGN::center
何故
?
----
[[EM:XPConnect特権]]
----
XPConnect?
----
↓これ
[[PRE:
var foo = Components.classes[■■■■]
.createInstance(■■■■);
]]
[[PRE:
var bar = Components.classes[■■■■]
.getService(■■■■);
]]
----
実行に
[[EM:特権]]
が必要
----
教科書
23ページ
----
[[PRE:
netscape.security.PrivilegeManager
.enablePrivilege('UniversalXPConnect');
]]
privilege:【名】特権/【他動】特権を与える
----
[[EM:XPConnectを使いたい]]
[[EM:実行コンテキスト]]
でこのコードを実行する
----
○
[[PRE:
function showMessage() {
netscape.security.PrivilegeManager
.enablePrivilege('UniversalXPConnect');
var file = Components
.classes['@mozilla.org/file/local;1']
.createInstance(Components.interfaces.nsILocalFile);
(略)
}
]]
----
○
[[PRE:
function showMessage() {
netscape.security.PrivilegeManager
.enablePrivilege('UniversalXPConnect');
alert(getContent());
}
function getContent() {
var file = Components
.classes['@mozilla.org/file/local;1']
.createInstance(Components.interfaces.nsILocalFile);
(略)
}
]]
----
×
[[PRE:
netscape.security.PrivilegeManager
.enablePrivilege('UniversalXPConnect');
function showMessage() {
var file = Components
.classes['@mozilla.org/file/local;1']
.createInstance(Components.interfaces.nsILocalFile);
(略)
}
]]
----
ここまで
のまとめ
----
[[PRE:
]]
----
では
もう一度
----
sample.xulを
開いて確認
----
次
----
発展1
----
CHAPTER::nsIFilePicker
FOOTER::nsIFilePicker
ファイル選択
ダイアログを
使ってみよう
----
関数の
冒頭部を
書き換え
----
前
[[PRE:
function showMessage() {
netscape.security.PrivilegeManager
.enablePrivilege('UniversalXPConnect');
var file = Components
.classes['@mozilla.org/file/local;1']
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath('c:\\extensions\\helloworld\\sample.xul');
(略)
}
]]
----
後
[[PRE:
function showMessage() {
netscape.security.PrivilegeManager
.enablePrivilege('UniversalXPConnect');
var file = chooseFile();
(略)
}
function chooseFile() {
// ここにファイル選択の処理を書く
}
]]
----
ファイル選択
用のXPCOM
コンポーネント
----
[[EM:nsIFilePicker]]
----
初期化
----
[[PRE:
const nsIFilePicker = Components.interfaces.nsIFilePicker;
const FP = Components.classes['@mozilla.org/filepicker;1']
.createInstance(nsIFilePicker);
FP.init(window, 'Choose a file.', nsIFilePicker.modeOpen);
]]
----
4つの
モード
----
nsIFilePicker.[[EM:modeOpen]]
→単一のファイルを開く
nsIFilePicker.[[EM:modeOpenMultiple]]
→複数のファイルを開く
nsIFilePicker.[[EM:modeSave]]
→ファイルを保存
nsIFilePicker.[[EM:modeGetFolder]]
→フォルダを選択
----
開けるファイル
の種類を限定
----
[[PRE:
FP.appendFilters(
nsIFilePicker.filterHTML + // HTML文書
nsIFilePicker.filterText + // テキスト
nsIFilePicker.filterXML + // XML文書
nsIFilePicker.filterXUL // XUL
);
]]
----
nsIFilePicker.[[EM:filterAll]]
→すべてのファイル
nsIFilePicker.[[EM:filterImages]]
→画像ファイル
(*.gif, *.jpg, *.jpeg, *.png )
nsIFilePicker.[[EM:filterApps]]
→実行ファイル
(*.exe, etc. )
----
ファイル選択
ダイアログ
を開く
----
[[PRE:
var result = FP.show();
]]
----
選択された
ファイルを
返す
----
[[PRE:
return FP.file;
]]
----
キャンセル
された時の
ための処理
----
[[PRE:
var result = FP.show();
switch (result)
{
case nsIFilePicker.returnOK:
return FP.file;
default:
return null;
}
]]
nsIFilePicker.show()の返り値で
どの操作だったのかが分かる
----
chooseFile関数のまとめ
[[PRE:
function chooseFile() {
const nsIFilePicker = Components.interfaces.nsIFilePicker;
const FP = Components.classes['@mozilla.org/filepicker;1']
.createInstance(nsIFilePicker);
FP.init(window, 'Choose a file.', nsIFilePicker.modeOpen);
FP.appendFilters(nsIFilePicker.filterHTML +
nsIFilePicker.filterText +
nsIFilePicker.filterXML +
nsIFilePicker.filterXUL);
var result = FP.show();
switch (result)
{
case nsIFilePicker.returnOK:
return FP.file;
default:
return null;
}
}
]]
----
全体の
まとめ
----
[[PRE:
]]
----
sample.xulを
開いて確認
----
次
----
発展2
----
CHAPTER::nsIClipboardHelper
FOOTER::nsIClipboardHelper
ファイルの内容を
クリップボードに
コピーしてみよう
----
関数の
末尾部を
書き換え
----
[[PRE:
alert(out.value);
// この後にコードを追加
]]
----
クリップボードへの
コピー用のXPCOM
コンポーネント
----
[[EM:nsIClipboardHelper]]
----
文字列を
クリップボードへ
コピー
----
[[PRE:
var CLIPBOARD = Components
.classes['@mozilla.org/widget/clipboardhelper;1']
.getService(Components.interfaces.nsIClipboardHelper);
CLIPBOARD.copyString(out.value);
]]
----
showMessage()
のまとめ
----
[[PRE:
function showMessage() {
netscape.security.PrivilegeManager
.enablePrivilege('UniversalXPConnect');
var file = chooseFile();
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, 'UTF-8', 1024,
converterStream.DEFAULT_REPLACEMENT_CHARACTER);
var out = {};
converterStream.readString(fileStream.available(), out);
converterStream.close();
fileStream.close();
alert(out.value);
var CLIPBOARD = Components
.classes['@mozilla.org/widget/clipboardhelper;1']
.getService(Components.interfaces.nsIClipboardHelper);
CLIPBOARD.copyString(out.value);
}
]]
----
全体の
まとめ
----
[[PRE:
]]
----
sample.xulを
開いて確認