GLOBAL-ALIGN::left
ALIGN::center
Firefox/Thunderbird用
拡張機能の
開発ノウハウ紹介
----
HEADER::Firefox/Thunderbird用拡張機能の開発ノウハウ紹介
CHAPTER::自己紹介と概要
発表者:
下田洋志 aka "Piro"
自己紹介(略歴)
----
2001
Mozilla用拡張機能の開発に手を出し始める
"コンテキストメニュー拡張"
("ContextMenu Extensions")公開
2002
"タブブラウザ拡張"
("Tabbrowser Extensions")公開
2004
Mozilla.Party.JP 5.0
2005
株式会社グッデイ 入社
Mozilla.Party.JP 6.0
2006
書籍 "Firefoxを究める256のテクニック" 上梓
----
ALIGN::center
本日の
概要
----
Part1
Firefoxの構造と
それを支える技術を知る
Part2
拡張機能開発の
チュートリアル
質疑応答
----
CHAPTER::関連技術の解説
HEADER::
ALIGN::center
[[EM:Part1]]
Firefoxの構造と
それを支える
技術を知る
----
HEADER::Part1 Firefoxの構造とそれを支える技術を知る
[[image src="01.jpg" width="800" height="555"]]
----
いくつかのキーワード
・XUL
・CSS
・JavaScript
・XPCOM
----
FOOTER::XUL
ALIGN::center
XUL
----
[[EM:X]]ML-based
[[EM:U]]ser-interface
[[EM:L]]anguage
----
ALIGN::center
XMLベースの構造記述言語
[[PRE:
]]
----
・HTMLに似通っている
・HTMLのフォーム関連要素のような
GUI部品(widget)
・DHTMLでは作るのが大変だった
様々なGUI部品を標準で利用できる
(ドロップダウンメニューや
スクロールバー、切り替え式のタブなど)
----
Firefox内部だけでなく
Web上でも使える
[[サンプル|https://piro.sakura.ne.jp/latest/blosxom.cgi/mozilla/index.xul]]
このプレゼンツール
自体も……
----
言語仕様に関する情報
[[XUL Planet|http://www.xulplanet.com/]]
[[http://www.xulplanet.com/]]
----
FOOTER::CSS
ALIGN::center
CSS
----
[[EM:C]]ascading
[[EM:S]]tyle
[[EM:S]]heets
----
人間の理解しやすい形でXML文書の
表示を指定するスタイル言語
[[PRE:
#content {
font-size: 10pt;
border-width: 1pt;
border-color: red;
border-style: solid;
}
]]
----
[[EM:カスケーディング]]
衝突する指定は優先順位が一番高いものが
適用され、それ以外は無視される仕組み
[[PRE:
box#content {
height: 200px;
}
box {
height: 100px;
border: 2px solid white;
border-width: 3px;
}
]]
↓
[[PRE:
{
height: 200px;
border-style: solid;
border-color: white;
border-width: 3px;
}
]]
----
XULもCSSで整形
[[PRE:
button[type="menu-button"] {
-moz-box-align: center;
-moz-box-pack: center;
margin: 0;
border: none;
}
.button-menu-dropmarker,
.button-menubutton-dropmarker {
margin: 1px;
background-image: url("chrome://global/skin/arrow/arrow-dn.gif");
background-repeat: no-repeat;
background-position: center center;
min-width:11px;
min-height:11px;
}
]]
----
FOOTER::JavaScript
JavaScript
----
・[[ECMAScript(ECMA-262)|http://www.ecma-international.org/publications/standards/Ecma-262.htm]]
第3版に準拠した
プロトタイプベースの
オブジェクト指向言語
・自由度が非常に高い
・Javaとは無関係
----
FOOTER::XULとJavaScript
ALIGN::center
XUL
と
JavaScript
の
[[EM:DOM]]による
連携
----
[[EM:D]]ocument
[[EM:O]]bject
[[EM:M]]odel
JavaScriptの
オブジェクトとして
XML文書を操作
----
FOOTER::XPCOM
XPCOM
----
[[EM:Cross(X)]]
[[EM:P]]latform
[[EM:C]]omponent
[[EM:O]]bject
[[EM:M]]odel
----
・プラットフォームに依存しない
コンポーネントの開発のための
フレームワーク
・それに基づいて開発された
コンポーネント
・そのコンポーネントが
提供する機能
----
Firefoxにおいては
二つの役割を持つ
----
・プラットフォームごとの差異を吸収して
単一のAPIで複数プラットフォームに
対応
・JavaScriptでは実現できない
高度な処理を担当
----
XPCOMの例:
[[EM:nsIFile]]インターフェースの
[[EM:create]]メソッド
・ファイルを生成する働き
・二つの引数を取る
ファイルタイプ(File or Directory)
パーミッション(UNIX形式)
→第2引数は場合によっては無視される
----
FOOTER::JavaScriptとXPCOM
ALIGN::center
JavaScript
と
XPCOM
----
[[EM:XPConnect]]
JavaScriptから
XPCOMを利用する
仕組み
----
例:
XPConnectを利用して
JavaScriptからXPCOMを呼び出し
テンポラリフォルダを生成する
[[PRE:
const nsILocalFile = Components.interfaces.nsILocalFile;
var file = Components.classes['@mozilla.org/file/local;1']
.createInstance(nsILocalFile);
file.initWithPath('C:\\');
file.append('temporary-directory');
if (!file.exists()) {
file.create(nsILocalFile.DIRECTORY_TYPE, 0777);
}
]]
----
XPConnectを
利用するのに必要
[[EM:XPConnect特権]]
----
Firefoxのセキュリティ機構の一つ
・Firefox内部のスクリプトは特権を持つ
・拡張機能のスクリプトも特権を持つ
・Webページのスクリプトは特権を持たない
・ユーザが許可した場合は別
----
Firefoxや拡張機能にバグがあった場合
意図せずWebページのスクリプトが
XPConnect特権を取得できてしまう
ことも……
----
FOOTER::
ALIGN::center
まとめ
----
[[image src="02.jpg" width="780" height="555"]]
----
FOOTER::「拡張機能」というメカニズムを実現するもの
CHAPTER::拡張機能を実現する技術
拡張
機能
----
ALIGN::center
「拡張機能」は
一体どうやって
実現されているのか
----
ALIGN::center
窓の○は
[[EM:「プラグイン」]]
と呼んでいるが
「プラグイン」とは
どう違うのか
----
[[EM:プラグイン]]
・本体アプリケーションと
規約に則って通信を行い
処理の代行・機能の提供を行う
小さなアプリケーション部品
(一般的な意味)
・本体アプリケーションが
備えている機能のための
追加の定義ファイル
----
[[EM:Firefoxの拡張機能]]
本体に[[EM:動的に組み込まれるパッチ]]
的なもの
----
動的に
組み込まれる
----
Firefoxを構成
している技術は
どれも
[[EM:後からの変更]]
[[EM:機能の上書き・追加]]
をサポート
----
・CSS
・JavaScript
・XUL
・XPCOM
----
CSS
----
[[EM:カスケーディング]]
----
[[EM:カスケーディング]]
衝突する指定は優先順位が一番高いものが
適用され、それ以外は無視される仕組み
[[PRE:
box#content {
height: 200px;
}
box {
height: 100px;
border: 2px solid white;
border-width: 3px;
}
]]
↓
[[PRE:
{
height: 200px;
border-style: solid;
border-color: white;
border-width: 3px;
}
]]
----
Firefoxに内蔵されている
スタイルシート
↓
拡張機能が追加した
スタイルシート
↓
ユーザースタイルシート
という順に適用される
----
=拡張機能でFirefoxの
元々のスタイル定義を
上書きできる
----
ALIGN::center
スタイルシート
だけを含む
拡張機能
||
[[EM:テーマ]]
----
JavaScript
----
JavaScriptでは
文字列も数値も関数も
全てオブジェクト
としてアクセスする
----
オブジェクトへの
プロパティやメソッドの
結びつけは
Classを必要とせず
代入だけで実現できる
----
[[PRE:
var obj = new Object();
obj.objectProperty = new Object();
obj.objectProperty.newProperty = 'string'
obj.objectProperty.parent = obj;
obj.myself = obj;
]]
関数も代入できる(=メソッドになる)
[[PRE:
var obj = new Object();
obj.name = 'Firefox';
function sayName() {
alert(this.name);
}
obj.sayMyName = sayName;
obj.sayMyName(); // sais "Firefox"
]]
----
プロパティ同士での代入もできる
[[PRE:
obj.propertyA = 'foobar';
obj.propertyB = obj.propertyA;
alert(obj.propertyB); // sais "foobar"
]]
メソッド同士での代入もできる
[[PRE:
obj.name = 'Thunderbird';
obj.methodA = function() { alert(this.name); };
obj.methodB = obj.methodA;
obj.methodB(); // sais "Thunderbird"
]]
----
window.open()を乗っ取って
Googleのページを開こうとしたら
必ずブロックするようにしてみる
[[PRE:
window.__original__open = window.open;
widnow.open = function(aURI, aName, aFlag) {
if (aURI.indexOf('.google.') > -1)
return null;
return this.__original__open(aURI, aName, aFlag);
};
window.open('http://www.google.co.jp/'); // will be blocked
]]
----
拡張機能のスクリプトで
Firefox内部のオブジェクトに
新しい機能を加えることも
既存の機能を置き換えることも
できる
----
XUL
----
CSSの
カスケーディング
のような仕組み?
----
XUL独自の機能
[[EM:オーバーレイ]]
----
元のXUL文書
[[PRE:
]]
+
content.xul
[[PRE:
]]
↓
読み込みの段階でID名などをキーにして統合
[[PRE:
]]
----
JavaScriptとDOMを使って
XULを編集する方法も
----
XPCOM
----
XPCOMコンポーネントの
機能は編集できないが
新しいXPCOMコンポーネントを
組み込むことはできる
----
JavaScriptからXPCOMを
XPConnectで呼び出している部分を
拡張機能のスクリプトで
置き換えれば……
----
ALIGN::center
まとめ
----
XUL
→オーバーレイとDOM
JavaScript
→プロパティ・メソッドの
乗っ取り(など)
CSS
→カスケーディング
XPCOM
→新しく追加して置換
----
・インタープリタ型なので
拡張機能による変更が
動的に適用される
・コンパイルすることなしに
誰でも簡単に
変更を適用したり
元に戻したりできる
----
つまり
拡張機能は理論上は
何でもできる
(Firefoxを別物に
変えてしまうことすら)
----
CHAPTER::開発環境の整備
HEADER::
FOOTER::
ALIGN::center
[[EM:Part2]]
拡張機能
開発の
チュートリアル
----
HEADER::Part2 拡張機能開発のチュートリアル
FOOTER::開発環境に必要なもの
ALIGN::center
開発環境に
必要なもの
----
[[EM:絶対に必要]]
・テキストエディタ
(UTF-8を扱えるもの)
・アーカイバ
(ZIP形式を扱えるもの)
[[EM:あると便利]]
・JavaScriptデバッガ
----
テキストエディタの例
(Windows)
秀丸エディタ
[[http://hide.maruo.co.jp/]]
TeraPad
[[http://www5f.biglobe.ne.jp/~t-susumu/]]
----
アーカイバの例
(Windows)
7-Zip
[[http://www.7-zip.org/ja/]]
----
Venkman JavaScriptデバッガ
[[http://www.hacksrus.com/~ginda/venkman/]]
[[(日本語パック)|https://piro.sakura.ne.jp/latest/blosxom.cgi/mozilla/extension/2005-09-30_venkman-ja.htm]]
----
ALIGN::center
しておくと
便利な設定
----
コンソールへの出力を有効化
[[PRE:
user_pref("browser.dom.window.dump.enabled", true);
]]
dump("文字列") という機能が使えるようになる
渡した文字列がコンソールに表示される
※Windows環境ではFirefoxを
-consoleオプション付きで起動する
LinuxやMac OS XではFirefoxを
ターミナルから起動する
----
JavaScriptコンソールへの内部エラーの表示
[[PRE:
user_pref("javascript.options.showInConsole", true);
]]
※「ツール」→「JavaScriptコンソール」で
JavaScriptコンソールを起動
----
FOOTER::拡張機能を実際に作ってみる
ALIGN::center
拡張機能を
実際に
作ってみる
----
拡張機能のタイプ
・新機能を加えるもの
・既存機能の挙動を
変えるもの
----
CHAPTER::Close All Tabs
FOOTER::拡張機能を実際に作ってみる - Close All Tabs
ALIGN::center
[[EM:Close All Tabs]]
「すべてのタブを一度に閉じる」
ボタンをツールバーに加えてみる
----
目標(要求仕様)
・ツールバーに「すべてのタブを閉じる」
ボタンを加える。
・ボタンを押すと、空のタブを残して
すべてのタブを閉じる。
・「すべてのタブを閉じる」という項目を
「ファイル」メニューの中にも加える。
・キーボードショートカット「Ctrl-Q」でも
機能を利用できるようにする。
----
作業手順
1. IDを決める
2. どこをいじればいいか調べる
3. フォルダとファイルを用意する
4. XULで構造を定義する
5. JavaScriptで挙動を定義する
6. CSSで外観を定義する
7. パッケージングする
8. 配布
----
用意するもの:
ボタン用アイコン画像
大サイズ 24×24 [[image src="icon.png" width="72" height="72"]]
小サイズ 16×16 [[image src="icon-small.png" width="48" height="48"]]
----
ALIGN::center
IDを決める
----
使えるIDの形式
[[EM:UUID(GUID)]]:完全なID
{E0EACCD1-98F3-4936-A229-41C667E820B8}
[[EM:名前@ドメイン]]:簡易的なID
closealltabs@piro.sakura.ne.jp
----
ALIGN::center
どこをいじれば
いいか調べる
----
DOMインスペクタ
----
ソースコード全文検索
(LXR)
[[lxr.mozilla.org/mozilla/]]
----
ALIGN::center
フォルダと
ファイルを
用意する
----
[[image src="03.jpg" width="319" height="600"]]
----
ALIGN::center
XULで
構造を
定義する
----
closealltabs.xul
[[PRE:
]]
----
コマンドの定義
[[PRE:
]]
----
ツールバーボタンの定義
[[PRE:
]]
----
キーボードショートカットの定義
[[PRE:
]]
----
メニュー項目の定義
[[PRE:
]]
----
ALIGN::center
JavaScript
で挙動を
定義する
----
closealltabs.js
[[PRE:
function BrowserCloseAllTabs() {
var tab = gBrowser.addTab('about:blank');
gBrowser.removeAllTabsBut(tab);
}
]]
----
ALIGN::center
CSSで
外観を
定義する
----
closealltabs.css
[[PRE:
#closeAllTabs-button {
list-style-image: url(icon.png);
}
toolbar[iconsize="small"] #closeAllTabs-button {
list-style-image: url(icon-small.png);
}
#menuitem_closeAllTabs {
list-style-image: url(icon-small.png);
}
]]
----
ALIGN::center
インストール
定義を書く
----
install.rdf
[[PRE:
]]
----
アプリケーションのUUID
Firefox
{ec8030f7-c20a-464f-9b0e-13a3a9e97384}
Thunderbird
{3550f703-e582-4d05-9a08-453d09bdfdc6}
----
chrome.manifest
[[PRE:
content closealltabs chrome/content/closealltabs/
skin closealltabs classic/1.0 chrome/skin/classic/closealltabs/
overlay chrome://browser/content/browser.xul chrome://closealltabs/content/closealltabs.xul
overlay chrome://global/content/customizeToolbar.xul chrome://closealltabs/content/closealltabs.xul
]]
----
ALIGN::center
XPIパッケージを
作成する
----
ALIGN::center
配布する
----
Mozilla Update
[[https://addons.mozilla.org/]]
----
XPIパッケージのMIME Type
[[EM:application/x-xpinstall]]
ダウンロードさせたい場合
[[EM:application/octet-stream]]
----
ALIGN::center
注意点
----
他の拡張機能と
バッティングしないか?
----
質疑
応答