Now browsing the archives for 8月, 2009.

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