Home > Latest topics

Latest topics 近況報告

たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。

萌えるふぉくす子さんだば子本制作プロジェクトの動向はもえじら組ブログで。

宣伝1。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

宣伝2。Firefox Hacks Rebooted発売中。本書の1/3を使って、再起動不要なアドオンの作り方のテクニックや非同期処理の効率のいい書き方などを解説しています。既刊のFirefox 3 Hacks拡張機能開発チュートリアルと併せてどうぞ。

Firefox Hacks Rebooted ―Mozillaテクノロジ徹底活用テクニック
浅井 智也 池田 譲治 小山田 昌史 五味渕 大賀 下田 洋志 寺田 真 松澤 太郎
オライリージャパン

Page 12/239: « 8 9 10 11 12 13 14 15 16 »

en-USでは定義されてて他のロケールで定義されてないエンティティ参照の有無を調べるスクリプトを書いてみた - Jul 09, 2009

機能を追加した時にen-USに追加したエンティティを他のロケールに追加し忘れて「○○語の環境で設定画面が動かねえぞゴラァ!!!」という風なバグ報告を貰うことがあまりに多いので(そして自分で気づけないので)、そういうミスを事前に防ぐためのスクリプトを書いてみた。

find_missing_entries_from_locales.js

コンテキストメニュー拡張などの、任意のスクリプトをXPConnect特権付きで実行できるツールでこのスクリプトを実行すると、以下のように動作する。はず。

  1. フォルダ選択のダイアログが開かれる。
  2. localeフォルダ、またはその上位の任意のフォルダを選択する。
  3. その中にある*.dtdなファイルがすべて読み込まれる。
  4. en-USロケールでは定義されていて他のロケールで定義されていない、というエンティティの一覧が表示される。

バイナリをBase64エンコードする - Jul 07, 2009

var file = Cc['@mozilla.org/file/local;1']
            .createInstance(Ci.nsILocalFile);
file.initWithPath('C:\\temp\\target.jpg');

var fileStream = Cc['@mozilla.org/network/file-input-stream;1']
                  .createInstance(Ci.nsIFileInputStream);
fileStream.init(file, 1, 0, false);
var binaryStream = Cc['@mozilla.org/binaryinputstream;1']
                    .createInstance(Ci.nsIBinaryInputStream);
binaryStream.setInputStream(fileStream);
var bytes = binaryStream.readBytes(fileStream.available());
binaryStream.close();
fileStream.close();

var base64 = btoa(bytes);

Bug 364586 - nsXmlRpcCLient.js conversion to base64 is slowで「JavaScriptでBase64エンコードするの遅いから組み込みの関数使えやゴラァ」と提出されていたパッチを見て知った。バイナリファイルの内容をバイト列の配列として読んでゴニョゴニョしなくても、単純に、バイナリのインプットストリームからreadBytes()でバイト列を文字列として取得してbtoa()にかければOK、だそうだ。試してみたら確かにちゃんといけた。

Fennecの構造 - Jun 19, 2009

Fennecのどんなところがマズいわけ?という話の中で、canvasがどうしてそこででてくるのか、Fennecって実際どんな作りになってるんだ、というツッコミを受けた。なので簡単に解説してみる。

しばらくソースを見るとだんだん分かってくるんだけど、要約するとこんな風になってる。

<window>
  <html:canvas id="browser-canvas"/>
  <box id="browsers" hidden="true">
    <browser/>
    <browser/>
    ...
  </box>
</window>

Firefoxのtabbrowser要素に相当する物は主にJavaScriptで実装されている。canvasは現在フォーカスされているタブに対応するbrowser要素の内容を描画するための物で、1つだけしか存在しない。パンスクロールやズームは全てこのcanvasの再描画でまかなわれてる。ユーザの目に見えているのはこのcanvas要素で、実際のページの内容は画面外の非表示のbrowser要素の中に置かれている。

  • ページの読み込みが完了した時→browser要素の内容をdrawWindow()でcanvasに描画する。
  • パンスクロールする時→canvasを制御するコントローラにあたるJavaScriptオブジェクトが保持している座標情報を変更して、canvasに描画する範囲を変更する。
  • ズームする時→canvasに描画する内容のズーム率を変える。
  • ユーザがリンクをクリックした時→canvas上の座標、パンスクロールの位置、ズーム率の3つから、browser要素内の実際のページにおけるクリック位置を算出して、nsIDOMWindowUtilsの機能でマウスイベントを実際のページに送出する。
  • アニメーション等で再描画が発生した時→browser要素の中にあるページ上で、再描画された箇所の座標情報を持ったMozAfterPaintイベントが発行される。それをFennecのイベントハンドラが検知して、パンスクロールの位置とズーム率を元に「再描画された箇所に対応するcanvas上の座標」を計算し、必要最低限の領域だけ再描画を行う。

何故こうなっているかというと、ズームとスクロールのパフォーマンスの問題かららしい。具体的には、Firefox 3以降のフルズームを使った場合、ズーム率を変えるごとにreflow(ボックスの位置等の計算)が発生してしまうなどのせいでパフォーマンスが落ちてしまうため、使い物にならない。そこで、高速な再描画ができるcanvasが使われることになったということのようだ。

だから現状では、FirefoxでcanvasとdrawWindow()を使った時に起こる問題が全部未解決のまま積み上がってる。例えばFlashなどのプラグインによって描画される箇所はスッポリ抜けるし、select要素のように独自の「ウィンドウ」を形成する物は見当違いの場所にポップアップが出る。そういった問題は当然解決されるべきだ(そして実際、Gecko 1.9.2以降で修正することを目指しているらしい)けれども、それって却って遠回りなんじゃないの? というのが、自分の率直な感想。

DOM周りの根っこの所に変更が入ったみたい - Jun 10, 2009

The Burning Edge見てたら、こんなバグがFIXEDになっていた。

text/htmlなHTMLドキュメントをXMLとして扱うにあたって、HTML5の仕様に合わせる形になるという事のようだ。namespaceURInullから"http://www.w3.org/1999/xhtml"へ、localNameがすべて大文字からすべて小文字へ、それぞれ変わる、と。

以前の挙動は以前の挙動で古い仕様には合致していたはずなので、時代の移り変わりをしみじみと感じる。

nsIHttpProtocolHandlerに対するプロキシとなるXPCOMコンポーネントを実装してみた - Jun 08, 2009

ローカルプロキシっぽいことをローカルプロキシを立てずにやろうとして挫折したことのまとめを書いたら、thorikawaさんが別のアプローチを提示してくださったので、その方向で頑張ってみた。

結論から言うと、URIの置き換え(特定のURIにアクセスしようとした時に、別のURIのリソースの内容を返す)についてはできるようになった。成果はUxU 0.6.0組み込んである。ただし、他のアドオンとの競合の可能性があるので、初期状態では機能を無効にしてある。

実装がどうなっているかはGlobalService.jsの中のProtocolHandlerProxyHttpProtocolHandlerProxyHttpsProtocolHandlerProxyの各クラスを参照のこと。thorikawaさんのエントリに挙げられている課題は、一応解決されているはず。

thorikawaさんによるコードからの違いは以下の点だ。

変更点1:元のコンポーネントが実装しているインターフェースは全部備えることにした

一つは QueryInterfaceの部分で、QueryInterfaceの部分を置換前のXPCOMに丸投げしてしまっているので、その後の個別の処理も全て置換前XPCOMで行われてもよいはずです。だけど実際にはnewURI,newChannelといったメソッドは置換後のXPCOMのものが呼び出されます。

QueryInterface()は、実はメソッドの返り値を見るまでもなく、メソッドを実行した時点でそのラッパーオブジェクト自体が変更される。なので、そのせいじゃないかと思う。例えば

var pref = Cc['@mozilla.org/preferences;1']
            .getService(Ci.nsIPrefBranch);
var value = pref.getBoolPref(...);

このコードは

var pref = Cc['@mozilla.org/preferences;1']
            .getService();
pref.QueryInterface(Ci.nsIPrefBranch);
var value = pref.getBoolPref(...);

と書いてもちゃんと動く。後者のような使い方をされている限りは、QueryInterface()で何を返していようと関係ない、ということではないのかなあ。

C++で書かれたコンポーネントの中ではdo_QueryInterface()という関数?がよく使われているようで、こいつが中で何をやってるのかまでは僕にはよく分かってないけど、上記の例の前者ではなく後者に相当するものなんだったら、引用部のような現象が起こるのではないかと思う。

ということでそういう場合に備えて、ProtocolHandlerProxyクラスは、コンポーネント「{4f47e42e-4d23-4dd3-bfda-eb29255e9ea3}」が備えているすべてのインターフェースを実装しておくようにした。具体的には、nsIHttpProtocolHandler、nsIProtocolHandler、nsIProxiedProtocolHandler、nsIObserver、nsISupports、nsISupportsWeakReferenceの各インターフェース。といっても、やってることとしてはやっぱり単に元のコンポーネントに処理を丸投げしてるだけなんだけど。

変更点2:プロパティとしてアクセスされる情報を、prototypeの方に定義するようにした

またもう一つは、このサンプルでも正常に動作しないサイトがいくつかあること。AJAXを多用しているサイトでも基本的には問題なく動くのですが、たとえばGMailにアクセスするとなぜか簡易版HTMLが表示されてしまいます。もしかすると上記の問題と関連しているのかも知れません。

これは推測だけれども、HTTP_USER_AGENT等が正常に送られなくなっていたせいではないかと思われる。

ちゃんと調べたわけではないんだけど、Webページ内のスクリプトのnavigator.userAgentの値や、HTTPの通信の際に送られるユーザエージェント名の文字列は、コントラクトIDが@mozilla.org/network/protocol;1?name=httpであるコンポーネントがnsIHttpProtocolHandlerインターフェースを通じて返す値を元に生成されているらしい。

然るに、thorikawaさんによるサンプルコードのコンポーネントにはnewChannel()などのメソッドは定義されているけれども、nsIHttpProtocolHandlerが持つはずのuserAgent等のプロパティは定義されていない。XPConnect経由でこのコンポーネントにアクセスすると、undefinedが文字列にキャストされて空文字として返ることになる。その結果、サーバに送られるUA文字列も空っぽになってしまう。つまりサーバから見たら未知のUAとなってしまう。GMailにアクセスするとなぜか簡易版HTMLが表示されてしまうのは、未知のUAに対しては簡易版HTMLを返すようにGMailが作られているからではないかと僕は推測している。

変更点1で書いた話を実施するにあたって、当初はこれらのプロパティもgetterとして定義してみてたんだけど、実際に動かしてみると、期待通りには動かなかった。具体的には、Webページ内のスクリプトからnavigator.userAgent等にアクセスしようとすると、セキュリティの制限により前述のgetter関数を実行できない、というエラーが出る。

なので、getter関数を使うことは諦めて、ProtocolHandlerProxyクラスのプロトタイプに、単純な文字列や数値の定数プロパティとしてそれらを設定しておくようにした。general.useragent.* 系の設定の変更を動的に反映しないといけないので(ここでgetterを使えないのが痛い)、とりあえず今のところは、それらの設定の変更を常時監視して、変更があればその都度ProtocolHandlerProxyクラスのプロトタイプの定数プロパティの値を更新するようにしている。

変更点3:https:なURIに対しても働かせるようにした

この実装では、ProtocolHandlerProxyをスーパークラスとして、HttpProtocolHandlerProxyHttpsProtocolHandlerProxyという2つのサブクラスを定義することにした。これらの違いは単にコントラクトIDだけ。(まあ、モジュールを登録する時にしか使わない情報なので、サブクラスにするまでもなかったんだろうとは思うけど……)

変更点4:このコンポーネントを使うかどうかをユーザが設定できるようにした

コントラクトIDが@mozilla.org/network/protocol;1?name=httpであるコンポーネントを入れ替える事を考えた時に、一番問題になるのはおそらく、同じ事をしようとするアドオンが2つ以上あった時のことだと思う。テストケース内でリクエストされるURIをリダイレクトするためだけに、いつもコンポーネントを入れ替えた状態にしておくというのは、無駄にリスクを高めるだけのような気がする。なので、必要な時にだけ機能を有効化できるようにしてみた。

当初は、NSGetModule()が返すモジュールのregisterSelf()メソッドの中でregisterFactoryLocation()している箇所を、設定値を見て必要に応じスキップするようにすればいいだろうか、くらいに考えていた。でも2つの理由でこれはうまくいかなかった。

  1. コンポーネントを登録する処理が走る段階では、プロファイルが初期化されていないので、ユーザが設定を有効にしているのか無効にしているのかが分からない。
  2. コンポーネントの登録はUxUをインストールまたはアップデートした後に1回行われるのみなので、ユーザが設定を変更しても即座には反映されない。

1の問題をもう少し具体的に書くと、例えばこのコンポーネントの有効無効をextensions.uxu.protocolHandlerProxy.enabledといった名前の設定で切り替えるようにしようと思っても、NSGetModule()が返すモジュールのregisterSelf()メソッドが実行される段階ではまだユーザプロファイル内に保存された設定値が読み込まれていないため、その段階でextensions.uxu.protocolHandlerProxy.enabledの値を取得しても常にデフォルト値(=false)となってしまう、ということ。

これを回避するためにUxUでは、設定値ではなくファイルを使うことにした。プロファイル内に「.uxu-protocol-handler-proxy-enabled」という名前のファイルがあればコンポーネントを有効に、ファイルがなければコンポーネントを無効に、という風に、ファイルの有無を真偽値型の設定代わりに使うようにしている。泥臭いというか非効率的というかすごく馬鹿っぽいというかそんな気がするけど、これ以上にいい方法を僕は思いつけなかった。

2の問題は、1を解決できたとしても発生する。Firefoxは利用可能なXPCOMコンポーネントのデータベースをプロファイル内にcompreg.datとxpti.datとして保存しているようで、これらのファイルを生成する時にNSGetModule()が呼ばれるんだけれども、毎回起動時にこのデータベースを作り直していたら無駄が大きすぎる。ということで、アドオンが追加・削除された時などの「コンポーネントの一覧に変更があった可能性がある」場合にだけ、有効なコンポーネントの一覧のデータベースが作り直されるらしい。UxU的には、プロトコルハンドラの乗っ取りのON/OFFを切り替えた後に必ずこのデータベース再作成の処理を走らせないといけない、でもそれができてない、ということだ。

で、これも似たような方法でアッサリ解決した。Firefoxはユーザプロファイル内に「.autoreg」という名前のファイルがあると(ファイルの有無しか見ないので、内容は何でもいい。空ファイルでよい。)、必ずcompreg.datとxpti.datを再作成する。なので、ユーザが設定を変更したらそのタイミングで「.autoreg」を作成してやり、次に起動した時には設定の変更が確実に適用される(コンポーネントが有効かあるいは無効化される)ようにした。

んで

これだけごちゃごちゃと妙なことをやっておいて、できることといったら単にURIをリダイレクトするだけなんだよね。ショボっ!

高橋メソッドドリブン開発 - May 28, 2009

Mozilla Partyの発表用資料を準備してる最中、自分で作っておきながら画像の埋め込みの仕様がクソ過ぎることにブチギレて、高橋メソッド in XULを久しぶりに改良してた。

  • 画像を全部確実にプレロードするようにした。
  • 画像の埋め込み指定に幅と高さの指定が無い時は、プレロードした画像それ自体の大きさで表示するようにした。
    • 幅か高さのどちらかが省略されていた場合、指定されている方の大きさに合わせてアスペクト比を保って拡大・縮小表示するようにした。
    • 幅や高さにパーセント値を指定した場合は、ウィンドウサイズに対する割合として計算するようにした。
  • ウィンドウの大きさが変わった時にちゃんと再描画するようにした。

公開ページはまだ更新してない。改良されたバージョンはリポジトリに置いてある

ローカルプロキシっぽいことをローカルプロキシを立てずにやろうとして挫折したことのまとめ - May 28, 2009

FireMobileSimulatorでのローカルプロキシ実装の試みを見て、UxUデバッグ用ローカルプロキシみたいな事をできるようにしてみたい、と思った。

ただ、HTTPのことはこれっぽっちも分からない。ソケット通信も、一応独自プロトコルっぽいものを使って別プロファイルで動作中のFirefoxからテスト結果を受け取るということはできるようになったけど、それ以上の事は分かってないまま。なので、まじめにローカルプロキシを立てる以外の方法で、「特定のURIにアクセスしようとした時だけ、あらかじめ定義しておいたルールに従って別のリソースを返す」ということをできるようにしてみようと考えた。

僕が現在把握している方法としては、以下の物がある。

  1. ローカルプロキシを実装して、その中でリダイレクトするやり方。
  2. http-on-modify-requestイベントのタイミングでリダイレクトするやり方。
  3. nsIContentPoilcyのshouldLoad()の中でリダイレクトするやり方。

1はthorikawaさんが頑張っておいでなので、それに期待している(ソースがGPL互換ならUxUにそのまま入れられるので)。他人のフンドシ。他力本願。ここでは後の2つについての挫折の経緯だけ書き留めておく。

結論を先に言っておくと、2も3も実装上の制限により全滅っぽい。やはり、ローカルプロキシをちゃんと実装するしか完全な解決策はないようだ。thorikawaさん期待age。

http-on-modify-requestイベントを使うやり方

これは、現在FireMobileSimulator等ですでに使われている。nsHttpChannelはリクエストを送信する前にnsIObserverServiceを通じてhttp-on-modify-requestイベントを、レスポンスが返ってきた後にhttp-on-examine-responseとかhttp-on-examine-merged-responseとかhttp-on-examine-cached-responseとかのイベントを通知する(SubjectはnsHttpChannel自身)ので、このタイミングでリダイレクトをしようという話。

リクエストし直す場合

FireMobileSimulatorの場合、nsHttpChannelの現在の通信をキャンセルした上で、nsHttpChannelからnsIWebNavigationを引っ張ってきてloadURI()で新しく通信を始めてる。

var redirected = 'http://www.example.com/';
var observer = {
  observe : function(aSubject, aTopic, aData) {
    if (aTopic == 'http-on-modify-request') {
    var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel)
                              .QueryInterface(Ci.nsIRequest);
    // ここでキャンセル
    httpChannel.cancel(Components.results.NS_ERROR_FAILURE);
    // リクエストし直し
    httpChannel.notificationCallbacks
      .getInterface(Ci.nsIWebNavigation)
      .loadURI(redirected, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
  }
};
Cc['@mozilla.org/observer-service;1']
  .getService(Ci.nsIObserverService)
  .addObserver(observer, 'http-on-modify-request', false);

通常のbrowserやiframeの場合はこれでいいんだけど、img要素やXMLHttpRequestからの通信では失敗する。具体的にはhttpChannel.notificationCallbacks.getInterface(Ci.nsIWebNavigation)の時点でエラーになる。例えばXMLHttpRequestによる通信なら、httpChannel.notificationCallbacks.getInterface(Ci.nsIXMLHttpRequest)とすれば元のリクエストを取得できるので、こんな感じで場合に応じて再リクエストの方法を振り分けてやる必要がある。(XMLHttpRequestの場合については、どうやれば再リクエストできるのかまではたどり着けてない。もしかしたら無理なのかも。)

nsIURIのspecを書き換える場合

nsIChannelのURIプロパティはnsIURIインターフェースの読み取り専用プロパティなので、通信先のURIを書き換えることはできない……ように見える。でも実はnsIURIのspecプロパティの方は書き換え可能なので、ここに新しいURIを代入することででもリダイレクトできてしまう。

observe : function(aSubject, aTopic, aData) {
  if (aTopic == 'http-on-modify-request') {
  var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
  httpChannel.URI.spec = redirected;
}

とはいえこの方法は全くお勧めできない。動く場合もあるけど、動かない場合もある、という感じで実に不安定だ。nsHttpChannelの実装を見れば分かるけど、http-on-modify-requestが通知された段階ですでにその時のリクエスト先URIに基づいた初期化処理がいくつか終わってしまっているので、それと矛盾するURIを設定する(例えば、HTTPのリクエストだった物をFile URLにリダイレクトするとか)と、この後の内部処理でエラーが起こるっぽい。

レスポンスヘッダを書き換える

http-on-examine-responseの方ではnsIHttpChannelのsetResponseHeader()を利用できるので、LocationヘッダにURIを設定してみたんだけど、ダメだった。残念ながらヘッダを解釈してくれなかった。

nsHttpChannelの実装を見たら、HTTPのステータスコードが301とか302とかの時だけLocationヘッダを見るようになってた。ステータスコードを保持しているプロパティは読み取り専用なので、強制的にLocationヘッダを読ませるということはできそうにない。

nsIContentPoilcyのshouldLoad()を使うやり方

これはURNサポートなどで実際に使っている。詳しい方法は2007年当時のエントリに書いてあるけど、要約するとこういうことだ。

  1. nsIContentPolicyインターフェースを備えたXPCOMコンポーネントを作成して、
  2. カテゴリマネージャに登録しておき、
  3. 処理したいURIが渡ってきたら、元の通信の読み込みを中止させて、代わりに別のURIで通信を始める。

やってみると、一見上手く動いてくれてるように見えるんだけど、XPConnect特権がある実行コンテキストで作成したImageやnsIXMLHttpRequestのインスタンスからの通信が捕捉されなくて、UxUの用途では使えない感じだった。まあ仮に捕捉できたところで、元の通信を止めて別のURIで通信するようにさせる方法は分かってない(もしかしたら無いかもしれない)んだけど。

あと、shouldLoad()の第2引数はnsIURIインターフェースなのでこれのspecプロパティを書き換えたらどうだろう?と思ってやってみたけど、これもうまくいかなかった。browser要素等での読み込みの場合だと、nsDocShellのInternalLoad()でエラーが発生する。実装を見た感じでは、nsIContentPolicyに処理が渡ってくるより前に元のURIに基づいてセキュリティ関係の機能が初期化されてるので、その後でURIを書き換えたのがいけなかったんじゃないかと思う。

まとめ

とにかく、nsHttpChannelのインスタンスが作成された後からどうこうしようと思うのがそもそも手遅れくさい。それより前のステップでアクセス先のURIを書き換えようと思ったら、ローカルプロキシを立てる以外に手は無いようだ。

いいかげん諦めてMozilla Partyの発表資料作ることにします……

Trunkでデフォルトのテーマから削除されたThrobberの画像の代替 - May 25, 2009

くでんさんが報じておられる通り、Bug 418003 - Firefox is packaging unneeded images and iconsによって、過去に使われていたもののもう使われていない画像がデフォルトのテーマからまとめて削除された。Trunkでは既にそのようになってるけど、Firefox 3.5もそうなるんだろうか。だとしたら例によって「何でこんなギリギリになってからやるわけ?」と愚痴りたくなるわけですが。

削除されたファイルの一覧はMercurialのコミットログを見ると分かる。行の頭に「-」が付いている物が、削除されたファイルという事になる。

自分がアドオンの中で流用していて影響を受けるのは、「読み込み中」の状況を示すためのアイコンとして使っていたThrobber-small.gifだ。Throbber.png、Throbber.gif、Throbber-small.pngも一緒に削除されたので、これらを流用してる人は代わりのアイコンを参照するようにしないといけない。

これらのThrobber画像は、半透明のアニメーション画像に差し替える関係でFirefox 3.0の時点から既に使われなくなっていた。また、これらの新しいThrobber画像は16×16サイズのものしか用意されていないので、大きいサイズの画像が必要な場合は自作するか古いバージョンからぶっこ抜くしかない。

16×16については、以下のChrome URLで参照できる。

  • chrome://global/skin/icons/notloading_16.png(アニメーション無し)
  • chrome://global/skin/icons/loading_16.png(アニメーションあり)

少なくとも今の時点では、Windows用、Linux用、Mac OS X用のいずれも同じパスで参照できるようだ。

ユーザが別のテーマを選択している場合もこの画像を参照したければ、以下のようにjarファイルの中のパスを直接指定する必要がある。

  • jar:resource:///chrome/classic.jar!/skin/classic/global/icons/notloading_16.png
  • jar:resource:///chrome/classic.jar!/skin/classic/global/icons/loading_16.png

FUEL使ったんだ…… - May 16, 2009

FUEL の Window/Tab 周りのハンドラは Firefox 3 では使うな - 8時40分が超えられない - subtech

書籍の中で詳しく解説しといてナンですが、アレをほんとに使う人がいたのか!ということにむしろ驚いてますよってなもんです。

まあ言う人に言わせれば、NSPRやらNeckoやらのよくわからない物が何層も積み重なった上にあるFirefoxを使うということ自体が「しんじらんねー」な感じなんでしょうけども。

他のアドオンと連携しやすくするためのライブラリを作ってみた - May 13, 2009

マルチプルタブハンドラについてRockridge氏ほかから「メニューをカスタマイズできるようにしてくれ」という要望が挙がっていたのだけれども、Menu Editorという素晴らしいアドオンがあるのに自前で同じような機能を再実装するのは徒労感しか無いなあと思ったので、開き直って、マルチプルタブハンドラの設定ダイアログを以下のようにしてみた。

  • Menu Editorがインストールされていなければ「Menu Editorをダウンロードする」リンクを表示する。
  • Menu Editorがインストールされていれば「Menu Editorの設定を開く」ボタンを表示する。

Menu EditorのAPIをよく分かってないので(ていうかそもそも公開APIなのかどうかも知らない)、タブ選択時のメニューをカスタマイズできるようにするためにちょっと強引な方法を使ってる。

で、同じようなこと(他のアドオンの有無を調べた上で設定を開く)を何度も書きたくなかったので、設定ダイアログに加えた変更の要点を他のアドオンと連携しやすくするためのライブラリとして分離してみた。

if (window['piro.sakura.ne.jp'].extensions.isInstalled('my.extension.id@example.com') &&
    window['piro.sakura.ne.jp'].extensions.isEnabled('my.extension.id@example.com'))
    window['piro.sakura.ne.jp'].extensions.goToOptions('my.extension.id@example.com');

アドオンがインストールされているかどうか・有効か無効かを調べるだけならFUELで事足りるので、あまり使い出がないといえば使い出がない。まあThunderbird 2あたりでだったらニーズがあるかもだけど。

ちなみにFUELで書く場合、アドオンがインストールされているかどうかはApplication.extensions.has('my.extension.id@example.com')、有効か無効かはApplication.extensions.get('my.extension.id@example.com').enabledで分かる。設定ダイアログのChrome URLを調べるAPIはなくて、それでこのライブラリを作ることにした次第です。

Page 12/239: « 8 9 10 11 12 13 14 15 16 »

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のつぶやき

オススメ

Mozilla Firefox ブラウザ無料ダウンロード