ガジェカツ~在宅SEのガジェット活動ブログ~

在宅SEな筆者がガジェットネタやIT、プログラミングネタを書き連ねるブログ

userChrome.jsスクリプトの開発方法をまとめてみた。

Firefox拡張機能作りたい→作れないorz→userChrome.js?拡張機能を書けるぐりもん的な奴?→んでどうやって書くの?
ということでGreasemonkeyスクリプトの開発で役に立ったサイトや本 - h1mesuke’s hoge-logのまんまオマージュの始まりですが、userChrome.jsスクリプトの開発方法をまとめてみようと常々思っていたのでまとめてみました。

追記(2010/03/31)

無名関数とか言っていたのをクロージャに書き換え&修正。
あとサンプルコードが全てまともに動いていませんでしたので修正または変更を行いました。

id:Griever さんへ。
この記事のミスの多さに自分で一切気づいておらず、このままだとひどいコードを晒したままになっていました。ブクマコメでの突っ込みホントありがとうございます。

userChrome.js

userChrome.jsというのはGreasemonkeyFirefox内部を弄れる版といったところで本来拡張機能しか使えないChrome特権を操作したりブラウザ画面のカスタム果てはマウスジェスチャーも実装できたりとしてくれるuserChrome.cssJavascript版のようなもので一言で言えば、


JavaScriptを通して、Firefoxインターフェイスを簡単に改造するための拡張です。
ですね。もしこれで分からないという方にはここここらへんを見てみて下さい。
注意:この記事の内容はSub-Script/Overlay Loaderでの利用を前提としたスクリプトの作成方法をまとめています。

基本的なuserChrome.jsスクリプトの開発方法

正直言うとそういうのをまとめているページは自分では見つけられなかった。なので最低限のことだけは自分で書こうと思う。

大前提

「Sub-Script/Overlay Loader」を利用するもしなくても何よりも実行するJavascriptクロージャを利用する(下記の一段目のサンプル)などの方法でbrowser.xul内でのグローバル変数化を避ける。
ここらへんは少し前のGreasemonkeyと同じ。というか開発はGreasemonkeyとほぼ同じ。ただFirefox内部のオブジェクト(つかXULだね)やChrome特権などを知らないと作成できないだけ。
また文字コードUTF-8がよいと思われる。

(function(){
/* この中に実行コードを書く */
})();


/* 下は自分の書き方。連想配列として宣言してinitという初期化用変数を最後に呼び出してる。ただ配列内の変数や関数を呼び出すためにthisをつけるのがめんどくさかったり。*/
var objectName = {
	panelId: "objectName_panel"
	init: function()
	{
		var statusbarpanel = document.createElement("statusbarpanel");
		statusbarpanel.setAttribute('id', this.panelId);
		statusbarpanel.addEventListener("click" ,this.objectName_Click ,false);
		document.getElementById("status-bar").appendChild(statusbarpanel);
	},
	objectName_Click: function(event)
	{
		alert(event);
	}
}
objectName.init();

二つ目はGreasemonkeyみたいなヘッダを書くこと。
以下のように書けばよし。また下段の例のようにもし「Sub-Script/Overlay Loader」を利用している場合は「@include」を利用することで別のウィンドウに読み込ませることが出来る(この場合だとアドオンウィンドウに読み込ませれる。)
さらにrebuild_userChrome.uc.xulを利用している場合はdescriptionの内容がポップアップ表示(文字コードUTF-8にしないと化ける)される。

// ==UserScript==
// @name         Mouse Action
// @description  軽量かつ多機能でカスタマイズしやすいマウスアクションスクリプト(マウスジェスチャー)。
// @namespace    http://zuzu-service.net/
// @include      main
// @author       zuzu
// @version      1.0.20100340
// @homepage     http://zuzu-service.net/
// ==/UserScript==

// ==UserScript==
// @name           Open Add-on Folder
// @namespace      http://www.xuldev.org/
// @description    Adds 'Open Folder' menu to Add-on Manager.
// @include        chrome://mozapps/content/extensions/extensions.xul
// @compatibility  Firefox 3.0, 3.5, 3.6b4
// @author         Gomita
// @version        1.1.20091203
// @homepage       http://www.xuldev.org/misc/ucjs.php
// ==/UserScript==

こういう感じであとはGreasemonkey開発みたいにイベント追加したり(addEventListener)、エレメントを作成してそれを追加したり(createElement→appendChild)していけば作れます。

Firefox内部のオブジェクトなどの調べ方

DOM Inspector(DOM Inspector - MDC)を使えばおk。
使い方は以下の通り(自分用メモだけど分かりやすいのでそのまま載せる)

1. メニューの「Search」 → Find Nodes → Attr をチェック
2. Attrに「label」、Valueに見つけたいメニューの表示名(「すべて選択」など)を入力
3. 検索。
4. 見つかったオブジェクトのツリーアイテムの右クリックメニューなどからIDやxpathをコピー。

他にも地道にネットで調べるとか人のサンプルコードを見るとか。

エレメントの追加方法

やり方は主に二種類。
document.createElementしてからのappendChildするようなDOMを使うかE4Xというものを使って追加するかです。

DOM

DOMこそがJavascriptの真髄じゃないですけど、それほど有名ですよね。動的にJavacriptによってDOM操作してページ遷移なしにページのデザインや表示を変えるっていうね。
サンプルコードはこんな感じ。

var statusbarpanel = document.createElement("statusbarpanel");
statusbarpanel.setAttribute('label', 'HelloWorld!');
document.getElementById("status-bar").appendChild(statusbarpanel);

これをuserChrome.jsスクリプトとして実行するとステータスバーの右端に「HelloWorld!」と表示します。

E4X

確かJavascriptコード上に直接XMLコードを書けるとかいう仕様だったはず……正確には下のようなもの。


ECMAScript for XMLE4X)は、ECMAScriptActionScript、DMDScript、JavaScriptJScript を含む)にネイティブのXMLサポートを追加するプログラミング言語拡張である。
これを使うとFirefox拡張機能で使える「XUL overlay file」みたいな感じに記述できます。

var overlay =
             <overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
             <statusbar id="status-bar">
                 <statusbarpanel label="HelloWorld!" />
             </statusbar>
             </overlay>;
overlay = "data:application/vnd.mozilla.xul+xml;charset=utf-8,"
+ encodeURI(overlay.toXMLString());
document.loadOverlay(overlay, null);

これもuserChrome.jsスクリプトとして実行するとステータスバーの右端に「HelloWorld!」と表示します。

最後に

うーん……やはり具体的に開発方法に関することを書いているのはuserChrome.js(.pdf)しかなかった。
まあuserChrome.jsなんでニッチな拡張機能ですもんね。便利なのに……Javascriptを書ける人にとっては凄く便利なのに!
何よりも他人の作ったスクリプトをちょいちょいと改造できるのが最高。拡張機能とかでこのショートカットキー使いにくいな変えられないかなーとかもすぐにDOM Inspectorでそのショートカットキーが書いてあるXULオブジェクト探してオーバーレイしちゃえばいいもんね。
具体的に言うとはてなブックマーク拡張のパネル表示用の関数を探して、それを「B」キーに設定したりとか。
ちなみに「hBookmark.StatusBar.showPanelToggle(true);」がその表示用関数。
それはともかく、こんなにも便利なのにニッチなのが悲しいので今日こんなまとめ記事を即興で二時間かけて書いてみました。
そんな即興記事が誰かの助けになれば幸いです。
それでは。