[2] HTML 4 の 18.2.4 は文書読込み時に実行される[[スクリプト]]による文書内容の動的な編集について触れています。
そこでは [CODE(JS)[[[document]].write]]
はその実現手段の一例として挙げられていますが、
実用的なレベルで存在したもので該当するのは他になかったでしょうし、
[[DOM]] が整理される以前の規定ですから、
[CODE(JS)[document.write]] と HTML 文書・UA の関係に関する規定と捉えてよいでしょう。
また、一般の DOM による操作等は想定範囲外でしょうから、
拡大して解釈することには慎重であるべきと考えられます。
さて、 18.2.4 によれば、文書の動的な編集は次の通りモデル化できるそうです。
= すべての [CODE(HTMLe)[[[script]]]] が、
文書の読込まれる順序で評価されます。
= [[SGML]] [CODE(SGML)[[[CDATA]]]] を生成する [CODE(HTMLe)[[[script]]]]
要素中のスクリプト構造がすべて評価されます。
その生成文を結合したものが文書中の [CODE(HTMLe)[[[script]]]]
要素の場所に挿入されます。
= 生成された [CODE(SGML)[CDATA]] が再評価されます。
このモデルは、 SGML 構文解析器で HTML 文書から木構造を抽出し、
それを HTML 仕様書の規定する意味と表現によってレンダリングするという
SGML 的に本来あるべき UA の処理方法ではなく、 HTML
文書を適当に読込みながら適当に解析しつつ適当にレンダリングし続けるという
WWW ブラウザの伝統的な処理方法に依拠しているように思えます。
[18]
HTML 4 仕様書に示された例によれば、
[PRE(HTML example code)[
Test Document
]PRE]
は
[PRE(HTML example code)[
Test Document
Hello World!
]PRE]
という HTML マークと同じ効果を持ちます。[Q[効果]]という曖昧な言葉を使っているため、
何を指しているのか (レンダリング結果? 出来上がる構造?) はっきりとはしませんが、
ともかくある意味においてこの2例は HTML 的に等価です。
ところが、 SGML 的には、前者は
[PRE(HTML invalid example code)[
Test Document
]PRE]
と等価 (完全に交換可能) であり、
;; 注: これだけでは [CODE(HTMLe)@en[[[body]]]] [[要素]]がないので、
[[非妥当]]です。
後者は
[PRE(HTML example code)[
Test Document
Hello World!
]PRE]
と等価ですから、両者は異なる構造を持っています。そして、
[CODE(JS)[document.write]] の結果は常に [CODE(HTMLe)[[[body]]]]
内に書込まれるとか (これは先のモデルと矛盾します。)、
[CODE(HTMLe)[[[head]]]] 内にも [CODE(HTMLe)[[[p]]]] 要素が含められるとか
(これは HTML DTD と矛盾します。) の仮定を置かない限り、
適切な結果が得られません。
[3] HTML 4 は、次のようにも述べています。
> HTML 文書は、 [CODE(HTMLe)[script]] 要素の処理の前後いずれにおいても
HTML DTD に適合するよう制約されます。
[CODE(HTMLe)[script]] の出力であるからといって
[CODE(HTMLe)[[[ul]]]] 要素の子供に [CODE(HTMLe)[[[td]]]]
要素があっても困りますから、これは当然の規定といえましょう。
しかし、ここで、 >>2 とも関係しますが、
処理後の適合性は何について判断するのかという疑問が生じます。
[PRE(HTML)[
Test Document
]PRE]
が >>2 の SGML 的解釈のように
[PRE(HTML invalid example code)[
Test Document
Hello World!
]PRE]
となるなら、 ([CODE(HTMLe)@en[[[body]]]] [[要素]]がないことには目をつぶっても)
[CODE(HTMLe)@en[[[head]]]] [[要素]]内に [CODE(HTMLe)@en[[[p]]]]
[[要素]]を入れることはできないので、[[非妥当]]です。しかし、
一旦
[PRE(HTML example code)[
Test Document
Hello World!
]PRE]
となり、更に
[PRE(HTML example code)[
Test Document
Hello World!
]PRE]
と解釈されるなら、この文書片は[[妥当]]です。
また、
[PRE(HTML)[
[INS[...]]
A paragraph.
[INS[...]]
]PRE]
は、果たして
[PRE(HTML)[
A paragraph?
]PRE]
でしょうか、
[PRE(HTML)[
A paragraph?
]PRE]
でしょうか。 (この例はどちらの解釈でも結果は[[妥当]]です。)
[4] '''スクリプト実行結果の静的妥当性検証''':
>>2-3 のような仕様の解釈に関する問題があるとはいえ、
ある解釈を選べば、ある文書がスクリプト実行後に DTD
妥当であるか否かはスクリプトを実際に実行してみれば容易に判断できます。
一方で、スクリプトを実行せずとも出力が妥当であるかどうかを検証できれば、
([CODE(JS)[document.write]] はもう使われなくなっていますが、
[[CGIスクリプト]]などにも応用できますから) 便利かもしれません。
実際にその方法を研究していた人もいたようですが、
良い方法は見つかっていません。
[5] '''スクリプト実行後の文書構造''':
現代の UA などは文書をその構造によって保持しています。 HTML
文書は読込まれると構文解析されて [[DOM]]
などのモデルによる木として記憶上で持っているか、
持っているかのように操作できるようになっています。
そうすると、 >>2 の規定を忠実に解釈すると、結果の文書木に
[CODE(HTMLe)[script]] 要素は含まれないことになってしまいます。
?? WinIE や Gecko はどうしている ??
また、 [CODE(JS)[document]] 物体は DOM の [CODE(DOMi)[[[Document]]]]
界面の物体 ([[文書要素]]に対応する物体) として再定義されてしまったので、
文書木が完成する前には存在しない虞があります (解析しながら木を作っているなら、
あるかもしれません)。
[6] [[内在事象取扱器]]で [CODE(JS)[document.write]] すると、
新しい文書が作られてそこに書かれるそうです [SRC[18.2.3 Note]]。
それもまたおかしな話です。
** DOM2 HTML
@@ TBW
[[#comment]]
** XHTML1 との関係
[8]
[CITE@ja[空繰再繰 - application/xhtml+xmlなページでdocument.writeを動作させる #2]] ([CODE[2007-05-01 11:21:43 +09:00]] 版)
([[名無しさん]] [WEAK[2007-05-01 02:24:18 +00:00]])
[[#comment]]
** メモ
[7]
[CITE[d:id:quaa]] ([CODE[2006-11-28 10:39:05 +09:00]] 版)
([[名無しさん]] [WEAK[2006-12-28 01:52:17 +00:00]])
[11]
[[Firefox]] 2 も [[WinIE]] 7 も PASS。
[12]
[[Firefox]] 2 も [[WinIE]] 7 も PASS。
[13]
[[WinIE 7]] は DOM view はただしいが、なぜか Rendered view
には何もレンダリングされない。
[[Firefox]] 2 は FAIL ([CODE(HTMLa)@en[[[defer]]]] 未対応)。
[14]
>>13 の [[WinIE 7]] で[[レンダリング]]されないのは
[CODE(HTMLe)@en[[[script]]]] が2つあるかららしく、
なら[[レンダリング]]される。
[15]
「CODE(JS)@円「「「document]].[[write]]]] というより
[CODE(HTMLa)@en[[[defer]]]] のテスト。
[[WinIE 7]] は PASS。
後の [CODE(HTMLe)@en[[[script]]]] 内に 「CODE(DOMm)@en[[[alert]]()]] を入れれば、
ちゃんと後の [CODE(HTMLe)@en[[[script]]]] も実行されていることが確認できる。
[16]
[[Firefox]] 2 でも [[WinIE 7]] でも、 [CODE(HTMLe)@en[[[script]]]]
内の [CODE(HTMLe)@en[[[script]]]] が実行され、[Q[aa]] と[[レンダリング」」されます。]]
[[HTML 5]] の[[構文解析算法]]でも、ややこしいですがおそらく、
[Q[aa]] と「「レンダリング]]されるのが正しい動作です。
(1つ目の [CODE(JS)@en[[[[document]].[[write]]]]
によって行われる[[構文解析]]で、与えられた「「引数]]の末尾に到達したところで、
[[挿入点]]に到着したということで[[字句化器]]が停止します。
[[木構築段階]]は [CODE(HTMLe)@en[[[script]]]]
[[開始タグ]]が現れると[[文字字句]]を集め続けますが、
それは[[字句化器]]が停止したところで一旦終わるので、
[CODE(HTMLe)@en[[[script]]]] [[終了タグ」」の直前までいきます。ここで、 [CODE(JS)@en[[[document]].[[write]]]] は[[返る]]のですが、]]
それによって外側の[[構文解析]]が再開されます。そして、
次の[[字句]]が [CODE(HTMLe)@en[[[script]]]] の[[終了タグ]]になるので、
[[木構築段階]]の [CODE(HTMLe)@en[[[script]]]] [[開始タグ]]の処理の続きで、[[スクリプト]]が実行されます。)
[17]
[[WinIE 7]] でも [[Firefox]] 2 でも、緑の[Q[xxxx]]が[[レンダリング]]されます。
[[#comment]]
* メモ