GLOBAL-ALIGN::left
ALIGN::center
拡張機能
開発の
基礎知識
[[EM:Part2]]
----
CHAPTER::拡張機能って何?
[[EM:拡張機能]]って何?
どうやって作るの?
----
HEADER::拡張機能って何? どうやって作るの?
FOOTER::「拡張機能」というメカニズムを実現するもの
拡張
機能
----
ALIGN::center
「拡張機能」は
一体どうやって
実現されているのか
----
ALIGN::center
[プラグイン]
とはどう違うのか
----
[[EM:プラグイン]]
本体アプリケーションと
定型的な通信を行って
処理を代行する、小さな
アプリケーション部品
----
Firefoxの拡張機能は
[[EM:動的に組み込まれる
パッチ]]のようなもの
----
パッチ?
----
[[PRE:
Index: layout/xul/base/src/nsNativeScrollbarFrame.cpp
===================================================================
RCS file: /cvsroot/mozilla/layout/xul/base/src/nsNativeScrollbarFrame.cpp,v
retrieving revision 1.22
diff -u -6 -p -r1.22 nsNativeScrollbarFrame.cpp
--- layout/xul/base/src/nsNativeScrollbarFrame.cpp 31 Dec 2004 01:13:26 -0000 1.22
+++ layout/xul/base/src/nsNativeScrollbarFrame.cpp 28 Jul 2005 22:06:05 -0000
@@ -342,6 +342,68 @@ nsNativeScrollbarFrame::Hookup()
if (!curpos || error)
return;
scrollbar->SetPosition(curpos);
}
+NS_IMETHODIMP
+nsNativeScrollbarFrame::Paint(nsPresContext* aPresContext,
+ nsIRenderingContext& aRenderingContext,
+ const nsRect& aDirtyRect,
+ nsFramePaintLayer aWhichLayer,
+ PRUint32 aFlags)
+{
+ if (NS_FRAME_IS_UNFLOWABLE & mState) {
+ return NS_OK;
+ }
+
+ if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
+ PaintSelf(aPresContext, aRenderingContext, aDirtyRect);
+ }
+
+ return nsBoxFrame::Paint(aPresContext, aRenderingContext, aDirtyRect,
+ aWhichLayer);
+}
]]
----
動的に
組み込まれる?
----
実は
----
Firefoxを
構成している
主な技術
----
CSS
JavaScript
XUL
XPCOM
----
どれも
・[[EM:後からの変更]]
・[[EM:機能の上書き・追加]]
ができる
----
順番に見ていきましょう
----
CHAPTER::CSSの上書き
CSS
----
[[EM:カスケーディング]]
----
衝突する指定は、優先順位が
一番高いものが適用され
それ以外は無視される
(指定が上書きされる)
----
ALIGN::center
[[PRE:
box {
height: 100px;
border: 2px solid white;
}
box#content {
height: 200px;
border-width: 3px;
}
]]
↓
[[PRE:
{
height: 200px; /* 後から上書きされた値 */
border-style: solid; /* 元からある値 */
border-color: white; /* 元からある値 */
border-width: 3px; /* 後から上書きされた値 */
}
]]
----
ALIGN::center
Firefox内蔵のスタイルシート
↓
拡張機能のスタイルシート
↓
ユーザースタイルシート
という順に読み込まれ
上書きされていく
----
つまり
----
拡張機能でFirefoxの
元々のスタイル定義を
上書きできる
----
ちなみに
----
スタイルシート
だけを含む
拡張機能
=[[EM:テーマ]]
----
次
----
CHAPTER::XULの上書き
XUL
----
XMLの一種
----
XMLで一般的に使える
CSSのカスケーディング
のような仕組みはまだ無い
----
そこで
XUL独自の機能
----
[[EM:オーバーレイ]]
----
複数のXUL
ドキュメントを
1つにまとめて
合成する機能
----
元のXULドキュメント
[[PRE:
]]
+
オーバーレイ用のXULドキュメント
[[PRE:
]]
----
2つのXUL
ドキュメントを
ID名などを
キーにして合成
----
合成後のXULドキュメント
[[PRE:
]]
----
HIDDEN::true
オーバーレイの
3つの方法
----
HIDDEN::true
[[EM:1]]
ファイルの中での
オーバーレイ指定
----
HIDDEN::true
[[PRE:
]]
----
HIDDEN::true
CやPHPのinclude
Perlのrequire
みたいな
----
HIDDEN::true
ライブラリの
読み込み的な
使い方
----
HIDDEN::true
XULドキュメント
読み込み時に
オーバーレイ先も
常に読み込む
----
HIDDEN::true
[[EM:2]]
スクリプトによる
動的オーバーレイ
----
HIDDEN::true
[[PRE:
var observer = {
observe :
function(aS, aT, aD) {
...
}
};
document.loadOverlay(
'somefile.xul',
observer
);
]]
----
HIDDEN::true
任意のタイミング
でオーバーレイ先
ドキュメントを
読み込める
----
HIDDEN::true
必要に応じて実行すれば
最初の方法に比べて
XULドキュメント
読み込みの体感速度が
向上
----
HIDDEN::true
[[EM:3]]
chrome.manifestの
記述に基づく
オーバーレイ
----
HIDDEN::true
詳しくは
後で話します
----
オーバーレイ
以外の方法
----
スクリプト
の利用
----
JavaScriptと
DOMでXULを
編集する
----
ALIGN::center
||柔軟性|メンテナンス性
|オーバーレイ|低|~高
|JavaScript+DOM|~高|低
----
場合に応じて
使い分けよう
----
次
----
CHAPTER::JavaScriptの上書き
JavaScript
----
2つの
特徴
----
[[EM:1]]
文字列も数値も関数も
全てオブジェクトまたは
オブジェクトのプロパティ
としてアクセスする
----
[[EM:2]]
オブジェクトへの
プロパティの結びつけは
代入だけで実現できる
(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"
]]
----
HIDDEN::true
プロパティ同士
での代入もできる
----
HIDDEN::true
[[PRE:
obj.propertyA = 'foobar';
obj.propertyB = obj.propertyA;
alert(obj.propertyB); // sais "foobar"
]]
----
HIDDEN::true
メソッド同士
での代入もできる
----
HIDDEN::true
[[PRE:
obj.name = 'Thunderbird';
obj.methodA = function() { alert(this.name); };
obj.methodB = obj.methodA;
obj.methodB(); // sais "Thunderbird"
]]
----
これらを
踏まえて
----
[[EM:改造]]
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
]]
----
拡張機能のJavaScriptで
新しいメソッドを定義する
→[[EM:機能の追加]]
----
拡張機能のJavaScriptで
既存のメソッドを置き換える
→[[EM:挙動の変更]]
----
次
----
CHAPTER::XPCOMの上書き
XPCOM
----
XPCOM
コンポーネントの
機能は編集できない
(バイナリなので)
----
が
----
新しいXPCOM
コンポーネントの
[追加]はできる
----
+
----
XPCOM
コンポーネントは
[JavaScript]
から呼び出される
----
=
----
[XPCOMを呼び出している]
[XPConnect]の部分の
JavaScriptのメソッドや
関数を置き換えればよい
----
CHAPTER::拡張機能はプラグインと言うよりもパッチ
まとめ
----
ALIGN::center
|XUL |オーバーレイ+DOM
|JavaScript|プロパティやメソッドの
上書き
|CSS |カスケーディング
|XPCOM |コンポーネントを
追加して置換
----
プラグインとは
原理が違う
----
ALIGN::center
| |はたらき |実態
|プラグイン|Firefoxに頼まれて
データを処理する |外部の
ソフトウェア
|~拡張機能 |~Firefoxの
内部コードを
直接変更する|~パッチ
----
でも、ただの
パッチでもない
----
パッチとの
最大の違い
----
[[EM:後から
適用できる]]
----
XULも
JavaScriptも
CSSも
[コンパイル]不要
----
ビルドやインストールの後から
いくらでもFirefoxを
改変したり元に戻したりできる
----
[[EM:=拡張機能の
特徴]]
----
ALIGN::center
| |導入/削除|できること
|プラグイン |簡単 |限られている
|ソースへの
パッチ|難しい |何でもできる
|~拡張機能 |~簡単 |~何でもできる
----
CHAPTER::締め
HEADER::
FOOTER::
つまり
言いたいのは
----
拡張機能は
プラグインよりも
パッチよりも強力な
カスタマイズ手段
----
一緒にしちゃ
イヤン
----
OK
----
それは
分かった
----
実際に
やってる
所を見せれ
----
そこで
----
[[EM:Part3]]
につづく