2007/01/10

hackin' firefox a go go!

2007年になってからやけにテクニカルな話題がおおいのは、冬だからです。冬はhackな季節なのです。

さて、今日のfirefox hackはというとー、なんかたいぷちゃんがapplication/jsonをブラウザで開くようにしたいとかいってるので、それをうねうねと調べてみた。

まぁ、FirefoxのDeepなサイドに触れたことのある人(Profileディレクトリの中を見たことがある人)は、mimeTypes.rdfっていうファイルにMIMEタイプごとのハンドラをRDFで記述しているのは知っての通り。よし、これでやってみることにします。

このmimeTypes.rdfはおおざっぱにいうと論理構造的には3段の木構造になってて、urn:mimetypes:rootからurn:mimetypes:[MIME-TYPE]への参照を持ち、各MIME-TYPEのDescriptionからhandlerを参照して、外部アプリをつかうならhandlerからexternalApplicationを参照するという形になってます。…全然意味わかんないとおもうので、ちらっと図を載せておくのでコレ見てなんとか理解してください(流し読みの人は眺めるだけでいいです)。

mimeTypes.rdfの参照構造
各RDF:Descriptionが同じ高さに並んでるんです

RDFのスキーマの都合上、たぶんRDF:Descriptionの入れ子はできないんだとおもうので、こういう構造になってるんじゃないかなー。

さてそれはさておき、これを踏まえてapplication/jsonのハンドラを書いてみると、まずRDF:Seqのurn:mimetypes:rootのところに<RDF:li RDF:resource="urn:mimetype:application/json"/>を含むようにして、あとは

<RDF:Description RDF:about="urn:mimetype:application/json"
        NC:value="application/json"
        NC:editable="true"
        NC:description="JSONファイル">
    <NC:fileExtensions>json</NC:fileExtensions>
    <NC:handlerProp RDF:resource="urn:mimetype:handler:application/json"/>
</RDF:Description>
<RDF:Description RDF:about="urn:mimetype:handler:application/json"
        NC:alwaysAsk="false"
        NC:useSystemDefault="false"
        NC:saveToDisk="false"
        NC:handleInternal="true">
</RDF:Description>

というのを追加してみました。上半分はまぁJSONファイルの情報を適当に書いて、handlerに処理させるような指定をしています。下半分が今回のキモになっていて、NC:handleInternal="true"という指定によりFirefoxの内部のコンポーネントを使って処理する指定になっています。他のプロパティは読んだまんまですが、どう処理するか尋ねるのをオフ、システムデフォルトを使うのをオフ、ディスクにセーブするのをオフにしています。こいつらどれか一つでもtrueになってると勝手にセーブしたり勝手にシステム標準のハンドラで開いたりします。

で、コレを指定して再起動してapplication/jsonのファイルを開くと…。うわっ、大失敗。なんか何も尋ねないで勝手にダウンロードしてしまいました…。なんでだろうと思いつつ、しかたないのでFirefoxのソースを読んでみると、ソース中でFirefox内部で処理するMIME-Typeがハードコーディングされてて、それ以外のMIME-TypeのやつはFirefoxでは処理できないからダウンロードしてるような雰囲気。

じゃあどうすればいいかというと、ソースを書き換えればよい。書き換えるべきところはどこかというとー、手元のFirefox2.0.0.1のソースをベースにして話をしていくと…

  1. まず /mozilla/layout/build/nsContentDLF.cpp の gHTMLTypes っていう配列に"application/json"を追加
  2. そして、そこのコメントに書いてあるとおり、 /mozilla/parser/htmlparser/public/nsIParser.h の一番下あたりに#define kJSONApplicationContentType "application/json"を追加
  3. 最後に、このdefineされたシンボルを利用する /mozilla/parser/htmlparser/src/nsParser.cpp のDetermineParseMode関数でelse if部分の条件文にさっき定義したやつを使う|| aMimeType.EqualsLiteral(kJSONApplicationContentType)を追加してプレーンテキストとして処理するように変更

という変更を加えてコンパイルすればFirefoxでapplication/jsonをテキスト表示できるようになるんじゃないかなーと(コンパイル面倒なのでためしてません)。

と、ソース読める人間の特権のごとく直接Firefoxのソースに手を入れればいいじゃん的な解決法しかみつけれなかったんですが、プロキシソフトで"application/json"を"application/javascript"に書き換えるとか、それっぽいのをエクステンションでやるとか、そういう感じしか解決法がないんじゃないかなーと。

うされもん @acidlemonについて

|'-')/ acidlemonです。鎌倉市在住で、鎌倉で働く普通のITエンジニアです。

30年弱住んだ北海道を離れ、鎌倉でまったりぽわぽわしています。

外部サイト情報

  • twitter
  • github
  • facebook
  • instagram
  • work on kayac