Home > Latest topics

Latest topics 近況報告

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

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

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

Page 22/248: « 18 19 20 21 22 23 24 25 26 »

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をリダイレクトするだけなんだよね。ショボっ!

プラットフォームのデフォルトの文字エンコーディングを取得する方法を調べようとして挫折したことのまとめ - Jun 06, 2009

ソース表示タブの障害として、「外部のテキストエディタを使う設定にしてる時に、Windowsのアカウント名が日本語だったりするとファイルを開けない」という報告を受けた。それを修正しようとして挫折した。以下はそのまとめ。

Webページのソースをテキストエディタで開く処理について

当該機能は実はソース表示タブ自身が提供しているわけではなく、Firefox 2以降くらいからFirefox自体に元々備わっている隠し設定のための設定UIを提供しているだけで、実際の処理はFirefox本体の物に丸投げしている。具体的にはviewSourceUtils.jsopenInExternalEditor()とかそこら辺。

ただ、Firefox本体のこのコードは国際化のことをきちんと考えられていないようで、テキストエディタの実行ファイルのパスに日本語の文字などが含まれているとダメという既知のバグがある(原因はgetExternalViewSourceEditor()の中でgetCharPref()で取得したパス文字列をUTF-8バイト列からUCS2のUnicode文字列に変換していないせい)。なのでソース表示タブではこの部分に動的にパッチを当てる形で問題を回避するようにして、もう少し実用に耐えるようにしようとしてみている。

今回の問題の原因は、エディタの実行ファイルではなく、開こうとしている対象のファイルのパスの扱いにある。

Firefoxは、ソースを表示しようとしている対象がローカルのファイルだとそれをそのまま、Web上のファイルであればそれをダウンロードしたテンポラリファイルを、エディタに渡そうとするんだけど、どうもその時にnsIProcessrun()メソッドで渡す引数がUCS2のままなのがいけないらしい。試しに自分の環境(Windows Vista日本語版)で試したところ、引数のeditor.run(false, [path], 1);とか書かれてる箇所で渡されてるパス文字列をnsIScriptableUnicodeConverterあたりでShift_JISに変換してやったらうまく動いた。IDL定義ではstringの配列としか書かれてないけど、ここはプラットフォームごとのデフォルトの文字エンコーディングにしておかないといけないようだ。

実験段階で明らかなように、nsIScriptableUnicodeConverterで適切なエンコーディングに変換してやれば問題は解決できる。残る問題は、じゃあ一体どのエンコーディングに変換すればいいのか、ということだ。

設定UI上にエンコーディング選択用のドロップダウンリストを付けるという手もあるけど、ユーザにそんな事を意識させるのはダサイ。なるべくなら自動で判別できるようにしておきたい。ということでその方法を模索してみた。

nsIFileのnativePathから辿ってみた

現在のFirefoxでは、ローカルファイルはnsIFileインターフェースで処理されている。このIDL定義を見ると、プラットフォームのデフォルトのエンコーディングでのパス文字列をそのまま保持しているとおぼしきnativePathプロパティの定義には[noscript]と書かれていて、JavaScriptからはアクセスできないようになっている。実際、試してみても無理だし。

ちなみに、昔おそらくnsIFileの代わりに使われていたと思われるnsIFileSpecだとnativePathには[noscript]が付いてない。なので、これを使ってやればいいか?と思ったけど、リンク先のソースの位置を見ると分かる通りこれは既に廃止されたモジュールで、今のFirefoxのバイナリには入ってないっぽい。インスタンスを作ろうとしてもエラーになる。

nsIFile/nsILocalFileを実装してるWindows用のコード(nsLocalFileWin.cpp)GetNativePath()の定義を見ればヒントを掴めるんじゃないか?と思ってみてみたら、CopyUnicodeToNativeという関数?が使われてた。コードが書かれてるnsNativeCharsetUtils.cppを見てみると……おおお、なんか答えっぽい物があるぞ。ifdefでプラットフォームごとに関数の中身の定義をそれぞれ変えてて、例えば頭の方を見てみると、Mac OS XとBeOSでは単純にUTF-8に変換してるという事が分かる。

ただ、下の方に書いてあるWindows用とUnix/Linux用の処理は、見ても訳が分からんかった……単純にこのエンコーディングに決め打ち、という訳にはいかないみたいで、ここからさらに色んな所のコードを見に行かなきゃいけないようだったので、この時点で挫折した。

nsIScriptableUnicodeConverter関係から辿ってみた

nsIScriptableUnicodeConverterはエンコーディング名を指定してUCS2との間で相互変換するものだけど、その時に「プラットフォームのデフォルトのエンコーディング」を指すようなキーワードがあったりしないしないか?と思って、そっち関係のコードも見てみた。

nsICharsetConverterManager.idlとかnsUConvModule.cpp見てて、どこをどう辿ったのか忘れたけど、GetDefaultCharsetForLocale()というメソッドがnsIPlatformCharset.hで定義されているという所まで辿り着いた。

メソッド名から見て、ロケールを指定しないといけないようだけど、それさえなんとかなればこれでいけるか? と思ってこれにJavaScriptからアクセスできないか試してみたけど、ダメだった。Components.classes['@mozilla.org/intl/platformcharset;1']にはアクセスできるんだけど、QueryInterface(Components.interfaces.nsIPlatformCharset)してみたら「そんなインターフェースねえよ」と怒られてしまった。検索してみても、どうもC言語用のコードしか無いみたい。

結論

無理でした。以上。

C(C++?)を書けるようになって、上で辿り着いたメソッドの実行結果を返すだけのコンポーネントでも書けば、サクッと解決できるのだろうか。もう勉強するしかないのか?

おまけ:文字コード選択のUI

コンテキストメニュー拡張で使ってるけど、文字コードを選択するドロップダウンリストは以下のようにすれば作れる。

<menulist id="charset"
  label="(choose an charset)"
  datasources="rdf:charset-menu"
  ref="NC:DecodersRoot">
  <template>
    <menupopup>
      <menuitem uri="..."
        label="rdf:http://home.netscape.com/NC-rdf#Name"
        value="..."/>
    </menupopup>
  </template>
</menulist>

ただし、XULにこれを書いただけだと空のリストになってしまう。onloadとかそこらへんでCc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService).notifyObservers(null, 'charsetmenu-selected', 'other');とすればポップアップの中身が生成される。設定ダイアログで使う時なら、その後でpreference要素のvalueを見るなどして、前回の選択状態を復元してやる必要がある。

Mozilla Party JP 10.0 - Jun 01, 2009

Mozilla Party JP 10.0のライトニングトークでの発表資料「UxUを使った自動テストで安心アドオン開発」を公開しました。何度か練習してなんとか5分以内に収まるように直前まで削ってましたが、結局早口でまくし立てるばかりの通訳泣かせな発表になってしまいました。

  • 台湾のコミュニティの話が興味深かった。頻繁に集まってるとか、Mozillaに限らずクリエイティブコモンズとかそういう方面からの関心でも人を集めているとか。あと兵役で抜けなきゃいけない人が多いのがマジ辛いと言ってたのも覚えている。
  • gyuqueさんの発表が大変面白かった。
  • 瀧田さんと吉岡さんの対談で「電子レンジがネットに繋がっても嬉しくない」という風な話が出ていたけれども、今日野菜炒めを作ってて思ったけどレシピの掲示場所としては実に適しているという気がした。扉を開け閉めする都合上、電子レンジの前は必ず空いてるから、ディスプレイが見えなくなるということは絶対にないし。
  • 担当通訳の人が滝川クリステル似の美人で、話してる時の相槌が「あーはぁ?(英語な人がよくやるあれ)」で、しかし名乗った苗字は日本人だった。
  • hknさんのドラ娘が眼福だった。

宴会で、おそらくAir Mozillaあたりで使うであろうメッセージビデオの撮影に呼び出された。当たり障りのない無難なことを喋った(自粛してそうしたわけではなくそれくらいしか言うことがなかった)ので採用されない可能性は高いと思う。

  • 慶応の一色教授(W3Cの中の人)と話した時に、「どんなアドオン作ってるの?」という話からXHTMLルビサポートのことを話して、CSSの縦書きとかルビとかの話になった。
    • 曰く、あの辺の仕様は印刷業界のプロの人達が本気で議論して作ってる感じで、InDesignとかそういう特定のツールに依存しないで印刷品質の物を作れるようにということを真面目に考えてるそうだ。
    • 「でも実際できるようになっても使う人どれくらいいるんだろう?」と言われたので、Geckoを縦書きに対応させようとしてるryoqun氏とチャットで少し話した時にも言った「同人小説の界隈だと需要あると思いますよ、竜破斬でドラグスレイブとか」(例が古い)という話をしたらウケたようだった。

その後残りのメンバーの一部とカラオケに行き、終電の時間で仕切り直して徹夜カラオケして、帰ってきて寝て起きたら19時だった。親に電話した(荷物が届いたことを連絡しようと思った)ら「声がおかしいぞ」と言われた。

高橋メソッドドリブン開発 - 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の発表資料作ることにします……

「英語(辞書アシスト検索)」モードは、英和辞書で検索する機能ではない - May 28, 2009

ローマ字入力で日本語ページ内の検索を可能にする「XUL/Migemo」拡張 - SourceForge.JP Magazine

さて、もう一つの検索方法である「英語(辞書アシスト検索)」であるが、これは英単語を入力するとその対訳となる日本語の単語が検索されるというモードだ。なぜか筆者の環境ではうまく機能しなかったのだが、一応使い方を説明しておく。

そんな機能実装した覚えないんですけど……

英語モードは、僕が正式にXUL/Migemoを引き継いだ後に行った大改造において、将来的に日本語だけでなく中国語や韓国語などのIMが必要な他の言語に対応できるよう、言語依存の主要モジュールを差し替え可能にした時に、日本語特有の処理(ローマ字入力を平仮名に変換するなどの処理)を含まないプレーンなモジュールの実装例として用意した物だ。

Firefox自身の通常の検索機能と比較して、このモードで具体的に起こる変化としては、「ext」まで入力した時点で「extension」「extend」等の英単語が強調表示されるようになる、という感じなんだけれども……これってぶっちゃけ無意味なんだよね。

  • 日本語では、入力した文字列(ローマ字)とページ内のヒット箇所(仮名漢字交じり)の文字列とが一致しない。「kanj」と入力した段階で登録済み単語の「漢字」にヒットしてくれれば、総キータイプ数が少なくなる。→メリットがある!
  • 英語では、入力した文字列とページ内のヒット箇所とが原則として一致する。なので、補完が無くても元々キータイプ数は最小で済む。→メリットが無い!

あとは、発音記号付きのアルファベット等を区別せずに検索できるようになるけど、それとて日本語用のエンジンに既に包含されている機能だし。

強いて言えば、日本語とかローマ字とか全然興味がないし必要も無いという英語圏のユーザの人が、Safari風の強調表示だけ利用する時に、ほとんど何も余計なことをしないから邪魔にならない……ということくらいだろうか。英語モードのメリットは。とにかく、「これこれこういう凄いことができるようになる」といった類の意義は皆無だ。そのモードを作った本人が言うんだから、間違いないよ。

Firefox 3.5の新アイコン、第7案はなかなか良いと思う - May 25, 2009

ノベルティやらパートナー企業の作るチラシやらが全部作り直しになるやんけ、という点を除けば、新しいドラフトはイイ感じに仕上がってきてると思う。

正直、初期のドラフトは端的に言って「え、これにリニューアル? ははは、またまたご冗談を」という印象しかなかった。「変えなきゃ、とにかく新しくしなきゃ」という意図が強く働いていなかったのか、何もかもを台無しにぶち壊していたように思う。それに比べたら最新のドラフトは、旧アイコンの解像度を上げた物として正当な進歩を遂げた形に落ち着いてると思った。カトキハジメの言うところの「マッハの戦い」とは、こういうことなんじゃないかと思う。

ここからまた変な方向に行ってしまわないかが心配だ。

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

Fennec合宿 - May 24, 2009

Mozilla Japan ブログ - Mobile Firefox 開発合宿を開催します

Fennecに力を注いでいるクリアコードとしては参加しないわけにはいきませんねという話なんですが、もっと低層の部分で四苦八苦してるらしい現状で、JavaScriptしか書けない僕に出番はあるのでしょうか。

Page 22/248: « 18 19 20 21 22 23 24 25 26 »

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のコメント

最近のつぶやき