もともとSGMLのDTDの話を書こうと思ったのは、HTMLでシステム識別子が省略可能かという話からであった(4月18日の投稿)。そのときにも書いたのだが、HTML/XHTMLには、SGML/XMLのインスタンスという側面と、Webに特化した(SGMLでもXMLでもない)データ記述フォーマットとしての側面とがあり、単純にSGML/XMLのルールをあてはめればいい、とは言い切れない。後者の側面を規定するのは、実際のアプリケーションの振舞いということになるだろう。非常に現実に沿った話である。
というわけで、実際にWebブラウザのソースコードを眺めて振舞いを調べたほうがいいだろうと思ったわけである。現状でブラウザのソースコードとして入手可能なのは、Mozilla(Firefox, Caminoなど)とWebkit(Safari, Google Chromeなど)である。この2つのソースコードをざっと眺めてみた。とはいえ、どちらのソースコードも巨大で、一朝一夕に全貌を理解できるような代物では到底ない。眺めたのはパーサ周りのごく一部に過ぎない。
まず、Mozilla, Webkitともに、HTML/XHTML専用パーサを使用している(Firefox, Safari 4 public beta)。汎用のSGMLパーサは内包されておらず、汎用XMLパーサもHTML/XHTMLのパースの時には用いられていないようだ。また、汎用SGMLパーサではないから、SGML Catalogのような仕組みも利用していない。ブラウザという目的を特化したソフトウェアだから、こういう構成なのは予想していたところである。
そして、Mozilla, Webkitともに、公開識別子に関するパーサの振舞いを規定するデータ構造PubIDInfoを内包していた。構造体の宣言も同じで、記述されている公開識別子も似たような感じになっている。いずれもオープンソースのプロジェクトだから、この辺は相互にソースコードを流用しているのかもしれない。
PubIDInfoにおけるパーサの振舞いには、FullStandards, AlmostStandards, Quirks, Quirks3の4種類がある。公開識別子と照らし合わせてみると、QuirksはHTML 4互換モード、Quirks3はHTML 3互換モードとされているようである。
PubIDInfoにはもう一つ面白い点がある。定義を一部転記してみよう。
eMode mode_if_no_sysid;eMode mode_if_sysid;
システム識別子がある場合とない場合とで、パーサのモードが変えられるようになっているのである。
では、どのような場合にどのモードでパーサが実行されるのか。Mozillaの場合はnsParser.cpp、Webkitの場合はHTMLDocument.cppの中にコードが含まれている。コードの外見はかなり違うが、どうやら、モード決定のロジックはどちらも同じようだ。
簡単なのは MIME Type が application/xhtml+xmlなど、なんらかのXMLデータだと解釈される場合で、このときは FullStandards モードになる。
MIME Type が text/html の場合は、いろいろなパターンに分かれる。
- 文書型宣言があり、公開識別子がない場合:FullStandards モード、文書型は HTML Strict。HTML 5の <!doctype html>などがこれに該当すると思われる。
- 文書型宣言があり、内部サブセットがある場合:FullStandards モード、文書型は HTML Strict。
- 公開識別子が上記 PubIDInfo のテーブルにない場合:FullStandards モード、文書型は HTML Strict。HTML 4.01 Strict や XHTML 1.1 などがこれに該当すると思われる。
- HTML 4.01 Transitional, HTML 4.01 Framesetでシステム識別子がある場合:AlmostStandards モード、文書型は HTML Strict。
- XHTML 1.0 Strict, XHTML 1.0 Frameset, XHTML 1.0 Transitional:システム識別子の有無にかかわらず AlmostStandards モード、文書型は HTML Strict。
これ以外は Quirks3 もしくは Quirks モードになる。例えば、文書型宣言がなければ Quirks モード、HTML 4.01 Transitional でシステム識別子がなければ Quirks3 モードになる。
もちろん、上に書いたのはパーサのモードについてのみ解析した結果であり、パーサの出力であるDOMや、レンダリング結果については、モードが異なれば結果が異なる可能性がある、としか言えない。それにしても、HTML 4.0以前とHTML 4.01とでモードが異なる、StrictとTransitional/Framesetでモードが異なる、MIME Typeでモードが異なる、などの結果は、私にとってはかなり新鮮であった。
ところで、こうやってソースを眺めてみると、当初の目的以外にいろいろなことに気づくことがある。まず、Webkitのほうが断然ソースコードが読みやすい。というか、Mozillaのコードはめちゃ汚い…AppleやGoogleがWebkitを採用したのも分かる気がする。
それから、謎の公開識別子がいくつも目につく。例えばこんなの:
こういうのに対するパーサのモードが全部定義してあるのである。Webデザイナがブラウザのバグに悩まされているのと同じように、ブラウザのプログラマもHTML文書のバグに悩まされてるんだなあ、ということがよく分かる。-/w3c/dtd html 4.0 transitional/en-//microsoft//dtd internet explorer 3.0 html//en-//w3c//dtd html experimental 19960712//en
0 comments:
コメントを投稿