Extend Firefox 3.5 Runners-Up 賞品

先日 Extend Firefox 3.5 の賞品が届いた。

またメッセンジャーバッグかよ、と思っていたが、中身はEeePC 1005HA (Seashell)。
なんでも、当初予定されていたメッセンジャーバッグが在庫切れだったらしい。

箱を開けると、真っ黒のEeePCが。

しかし、キーボードは英語配列!

まだ電源は入れていないが、当然OSも英語版Windows XPなんだろうな。
Ubuntuでもインストールして遊ぶか。

TOP

userChrome.js スクリプト集のページ

Firefox 2 の時代に作った userChrome.js スクリプト集のページ に掲載したスクリプトの一部が最近の Firefox 3.0 や 3.5 で動作しなかったため、修正しました。

変更点:

  • 「Paste And Go」が Firefox 3.5 以降で動作しないバグを修正。
  • 「Open Add-on Folder」でプラグインなどの項目を右クリックしたときに「Open Folder」メニュー項目を表示しないように改善。
  • 「Restart Firefox」のショートカットキーの変更と再起動処理の改善。
  • 「Colorful Tabs」が Firefox 3.0 以降で動作しないバグを修正。
  • すべてのスクリプト中に @compatibility で Firefox の対応バージョンを明記。
  • すべてのスクリーンショットを Firefox 3.5 のものに差し替え。

TOP

Webページの拡大率を取得する

拡張機能などから、ブラウザのコンテンツエリアに表示された Web ページの拡大率(画像も含めたズームイン・ズームアウトによる拡大率)を調べる。
以下、 browser.xul へオーバーレイした状態を想定。

Firefox 3.5 以前

nsIMarkupDocumentViewer::fullZoom で取得可能。

var zoomFactor = gBrowser.mCurrentBrowser.markupDocumentViewer.fullZoom;

Firefox 3.6 以降

nsIDOMWindowUtils::screenPixelsPerCSSPixel でも取得可能。

var win = window.content;
var winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
var zoomFactor = winUtils.screenPixelsPerCSSPixel;

両者の値の違い

Firefox 3.6 以降の screenPixelsPerCSSPixel で取得できる値は、厳密にはズームイン・ズームアウト機能の拡大率ではなく、 CSS での1ピクセルがスクリーン上で何ピクセルとして表示されるかを示した値である。そして、両者の値はなぜか微妙に異なる。 Firefox 3.5 で Firefox 3.6 とほぼ同等の値を取得するにはどうすれば良いか? All-in-One Gestures が面白いやり方で実践していた。

var doc = window.content.document;
var div = doc.createElementNS("http://www.w3.org/1999/xhtml", "DIV");
div.style.position = "absolute";
div.style.top = "100000px";
doc.body.appendChild(div);
var zoomFactor = (doc.getBoxObjectFor(div).screenY - doc.getBoxObjectFor(doc.body).screenY) / div.offsetTop;
doc.body.removeChild(div);

ダミーの DIV 要素を、 Web ページの document.body を基点とした上から100000px(CSS上のピクセル)の絶対位置に配置し、 body と DIV 要素のスクリーン上のY座標の値を getBoxObjectFor で取得し、両者の差を100000で割ることで算出している。 getBoxObjectFor を使用しているので、もちろん Firefox 3.5 以下限定である。

関連記事

SCRAPBLOG : Firefox 3 のフルページズーム使用時はスクリーン上でのピクセル量とCSS上でのピクセル量は一致しない

TOP

Firefox 3.6 にて HTMLElement.classList が実装

Firefox 3.5 以前

HTML中のある要素のクラス名を取得するには、 HTMLElement.className プロパティを使用する。
クラス名はスペース区切りで複数の値を指定可能であるので、クラス名にある値が含まれるかどうかを判定するには、

var elt = document.getElementById("test");
elt.className.indexOf("foo") >= 0;

のようにしてやればよいが、これでは foobar のような値が含まれている場合も true と判定されてしまう。

Firefox 3.6 以降

Firefox 3.6 にて導入された HTML 5 の仕様の一部である HTMLElement.classList プロパティにより、複数の値が指定されたクラス名の扱いが簡単になる。
HTMLElement.classList プロパティは、 DOMTokenList 型オブジェクトであり、 contains メソッドによってリスト中にある値が含まれるかどうかを正確に調べることができる。

var elt = document.getElementById("test");
elt.classList.contains("foo");

add メソッドや remove メソッドによってクラスに値を追加・削除したり、 toggle メソッドで値の有無を切り替えたりすることも可能。
クラスの個々の値を取得するには以下のようにする。

for (var i = 0; i < elt.classList.length; i++) {
    elt.classList.item(i);
}

TOP

Babelzilla の WTS で全ローカライズの進捗が100%と誤認識される問題

事象

Bazelzilla の Web Translation System (WTS) では、通常各ローカライズの DTD ファイルおよび propertiesファイル中の未翻訳部分は、その行自体が無い状態でXPIにパッケージングしてアップロードする必要がある。しかし、誤って全ローカライズの未翻訳部分を英語に置き換えた内容の XPI ファイルをアップロードしたところ、全ローカライズの翻訳進捗率が100%と誤認識されてしまった。もう一度正しい XPI ファイルをアップロードしなおしてもサーバー側のデータベースに以前翻訳された内容が保持されているようで、翻訳進捗率は100%のまま。こうなってしまうと、翻訳者はどのファイルのどの部分が未翻訳であるかを把握できなくなってしまう。

復旧方法

XPI ファイルからすべてのローカライズ( jar ファイル中の locale フォルダと chrome.manifest の locale 宣言)を取り除いた偽バージョンを作成し、アップロードする。その後、改めて正しい XPI ファイルをアップロードする。この手順で翻訳進捗率の表示が正しい値に戻った。

TOP

Firefox を再起動する

Firefox 3 以前

Firefox を再起動するとき、 Firefox 3 までは以下のようなコードを書く必要があった。

var appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
appStartup.quit(appStartup.eRestart | appStartup.eAttemptQuit);

ただし、上記コードでは Firefox 終了直前に「開いているタブを保存して次回起動時に復元しますか?」の確認ダイアログを表示する設定になっていた場合などに、ダイアログを表示せずに強制的に終了してしまう欠点がある。そのような場合でもちゃんとダイアログを表示させるようにするためには、 chrome://mozapps/content/extensions/extensions.js の restartApp 関数のように少々長いコードを書く必要があった。

Firefox 3.5 以降

FUELextIApplication インタフェースに追加された restart メソッドで実現可能となった。

Application.restart();

Application 定数が未定義の JS XPCOM 内では、以下のようにする。

var fuelApp = Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication);
fuelApp.restart();

また、 restart メソッドの戻り値で、実際に再起動の処理を開始するか、あるいはユーザによってキャンセルされたかを判別可能。

var ret = Application.restart();
alert(ret ? "再起動します。" : "再起動はユーザによってキャンセルされました。");

なお、 Firefox を終了する処理についても、 FUEL で実現可能となった。

Application.quit();

TOP

Windows Vista のバックアップと復元センター

Windows Vista のバックアップと復元センターをあらためて試し、バックアップ前と復元後の全ファイルを比較したところ、下記の拡張子を持ったファイルなどがバックアップ対象外となっていたようだ。

asp bak bat cgi chm dll exe ini jar js jsp manifest php pl vbs wsf

ちゃんとしたバックアップツールが無いかと探したところ BunBackup が良さそうなので乗り換えた。

TOP

拡張機能開発の一時休止のお知らせ

PCリカバリに伴い Windows Vista のバックアップと復元機能を使用したところ、「js」を含む特定の拡張子のファイルがごっそり消えたため、拡張機能開発をしばらくの間休止します。

TOP

openDialog の引数で指定したウィンドウ名を nsIWindowMediator で使用する

ルート要素に windowtype 属性がセットされていないウィンドウを、以下のように "test_window" という名前付きで開く。

window.openDialog("chrome://...", "test_window", "chrome,all");

引き続き nsIWindowMediator を使ってそのウィンドウの名前からウィンドウを取得しようとしても、できない。

var winMediator = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var win = winMediator.getMostRecentWindow("test_window");
// |win| is null

そこで、以下のようにウィンドウを開いた直後に window.name から取得したウィンドウ名を windowtype 属性へセットしてやる必要がある。

var win = window.openDialog("chrome://...", "test_window", "chrome,all");
win.document.documentElement.setAttribute("windowtype", win.name);

ただしモーダルダイアログを開く場合、ウィンドウを開く側ではなく、開かれたウィンドウ側で上記処理を行う必要がある。

TOP

Software Design 2009年1月号 : Firefox徹底カスタマイズ術

Software Design 2009年1月号

Software Design 2009年1月号|gihyo.jp … 技術評論社
第2特集
~Greasemonkey+α,Ubiquity,Vimperator,Firemacs,FireGestures~ Firefox徹底カスタマイズ術

TOP