[82] [DFN[[CODE(JS)@en[document.write]]]] は、
動作中の[[構文解析器]]の[[入力ストリーム]]に[[文字列]]を挿入する [[JavaScript]]
[[メソッド]]です。

[83] [[DOM0]] 時代には、 [CODE(JS)@en[document.write]] は[[文書]]の内容を任意に書き換える唯一の方法でした。
その後の [[DOM]] [[API]] の整備により、[[構文解析器]]の動作中に限らず[[文書]]の任意の部分を書き換えられるようになったため、
[CODE(JS)@en[document.write]] は徐々に使われなくなりました。

[84] [[構文解析器]]が[[構文解析]]の進行中に [CODE(HTMLe)@en[script]]
[[要素]]の[[スクリプト]]を実行し、そこから [CODE(JS)@en[document.write]]
によって[[入力ストリーム]]に[[スクリプト]]が介入できるため、
[[構文解析器]]の動作が複雑になる要因の1つとなっています。

;; [CODE(JS)@en[document.write]] によって新たに [CODE(HTMLe)@en[script]]
[[要素]]を注入することも可能です。

* 仕様書

[REFS[
- [10] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2015-05-06 10:42:35 +09:00]] 版) <https://html.spec.whatwg.org/#dom-document-write>
]REFS]

* 処理

[62] [CODE(DOMi)@en[[[Document]]]] [[インターフェイス]]の
[DFN[[CODE(DOMm)@en[write][document.write]]]] [[メソッド]]は、
次のようにしなければ[MUST[なりません]] [SRC[>>10]]。

[FIG(steps)[
= [64] [VAR[引数群]]を、指定されたすべての[[引数]]を [CODE(IDL)@en[[[DOMString]]]] として解釈した結果に設定します [SRC[>>10]]。
= [76] [VAR[入力]]を、[[空文字列]]に設定します。
= [100] [VAR[引数群]]の各[VAR[引数]]について、順に、
== [101] [VAR[入力]]の末尾に[VAR[引数]]を追加します。
= [97] [[文脈オブジェクト]]と[VAR[入力]]について、
[[document write steps]] を実行します。
[[例外]]が[[投げ]]られたら、[[再び投げ]]ます。
]FIG]

[73] [CODE(DOMi)@en[[[Document]]]] [[インターフェイス]]の
[DFN[[CODE(DOMm)@en[writeln]]]] [[メソッド]]は、
次のようにしなければ[MUST[なりません]] [SRC[>>10]]。

[FIG(steps)[
= [102] [VAR[引数群]]を、指定されたすべての[[引数]]を [CODE(IDL)@en[[[DOMString]]]] として解釈した結果に設定します [SRC[>>10]]。
= [103] [VAR[入力]]を、[[空文字列]]に設定します。
= [104] [VAR[引数群]]の各[VAR[引数]]について、順に、
== [105] [VAR[入力]]の末尾に[VAR[引数]]を追加します。
= [106] [VAR[入力]]の末尾に [CODE[U+000A]] を追加します。
= [107] [[文脈オブジェクト]]と[VAR[入力]]について、
[[document write steps]] を実行します。
[[例外]]が[[投げ]]られたら、[[再び投げ]]ます。
]FIG]

[96] [DFN[document write steps]] は、[VAR[文書]]と[VAR[入力]]を次のようにします。

[FIG(steps)[
= [65] 
[FIG(list)[
- [88] [VAR[文書]]の[F[型][文書の型]]が [[XML文書]]
- [89] [VAR[文書]]の [F[throw-on-dynamic-markup-insertion counter]] が[[正]]
]FIG]
... のいずれかの場合、
== [90] [CODE(DOMe)@en[InvalidStateError]] [[例外]]を投げ、ここで停止します [SRC[>>10]]。
= [113] 
[VAR[文書]]の[F[活性構文解析器がabortされた]]が[[真]]の場合、
== [114] 
ここで停止します。 [SRC[>>10]]
= [67] 
[FIG(list)[
- [92] [VAR[文書]]の[F[構文解析器]]が [CODE[null]]
- [93] [VAR[文書]]の[F[構文解析器]]の[F[挿入点]]が[[未定義]]
]FIG]
... のいずれかの場合、
== [68] [VAR[文書]]の [[ignore-opens-during-unload counter]] が[[正]]か、
[VAR[文書]]の [[ignore-destructive-writes counter]] が[[正]]の場合、
=== [99] ここで停止します [SRC[>>10]]。
== [69] [VAR[文書]]について、[[文書を開く手順群]]を実行した結果に設定します 
[SRC[>>10]]。
= [72] [VAR[文書]]の[F[構文解析器]]の[F[入力ストリーム]]に対し、
[VAR[文書]]の[F[構文解析器]]の[F[挿入点]]の直前に、
[VAR[入力]]を挿入します [SRC[>>10]]。
= [77] [VAR[文書]]に [[pending parsing-blocking script]] がない場合、
== [78] [VAR[文書]]の[F[構文解析器]]について、
[[字句化器]]が[F[挿入点]]に達するか、[[木構築段階]]が[[構文解析器]]を [[abort]]
するまで、[[構文解析器]]を動作させます。
([CODE(HTMLe)@en[[[script]]]] [[終了タグ]]があると、 [[abort]] することがあります。)
[SRC[>>10]]
]FIG]

;; [63] [VAR[文書]]が[[構文解析]]中なら、ここで[[構文解析器]]が再帰的に動作させられることがあります。

[9] [[文書]]は [DFN[[[ignore-destructive-writes counter]]]] を持ちます。
その初期値は0です。 [SRC[>>10]]

;; [79] 実際の [[Webブラウザー]]は、 [[script nesting level]] が[[正]]なら
([[スクリプト]]内からの [CODE(JS)@en[[[document.write]]]] 呼び出しなら)
[[reload override buffer]] に追記しないようです。
(そうしないと[[再読込]]後に [CODE(JS)@en[[[document.write]]]] された部分が二重になってしまいます。)
[TIME[2015-05-07T03:21:43.200Z]]

* 文書の適合性への影響

[112] [[文書の適合性]]を参照。

* 歴史

** HTML 4

[1] 仕様書:
- [[HTML 4]]
-- [CITE[18.2.4 Dynamic modification of documents]]
<IW:HTML4:"interact/scripts.html#idx-document">
-- [CITE[18.2.3 Intrinsic events]]
<IW:HTML4:"interact/scripts.html#idx-control">

[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]] が再評価されます。

[118] 
このモデルは、 [[SGML構文解析器]]で HTML 文書から木構造を抽出し、
それを HTML 仕様書の規定する意味と表現によってレンダリングするという
SGML 的に本来あるべき UA の処理方法ではなく、 HTML
文書を適当に読込みながら適当に解析しつつ適当にレンダリングし続けるという
WWW ブラウザの伝統的な処理方法に依拠しているように思えます。

[18]
HTML 4 仕様書に示された例によれば、
[PRE(HTML example code)[
 <TITLE>Test Document</TITLE>
 <SCRIPT type="text/javascript">
     document.write("<p><b>Hello World!<\/b>")
 </SCRIPT>
]PRE]

は
[PRE(HTML example code)[
 <TITLE>Test Document</TITLE>
 <P><B>Hello World!</B>
]PRE]

という HTML マークと同じ効果を持ちます。[Q[効果]]という曖昧な言葉を使っているため、
何を指しているのか (レンダリング結果? 出来上がる構造?) はっきりとはしませんが、
ともかくある意味においてこの2例は HTML 的に等価です。

ところが、 SGML 的には、前者は
[PRE(HTML invalid example code)[
<HTML><HEAD> <TITLE>Test Document</TITLE>
 <SCRIPT type="text/javascript">
     document.write("<p><b>Hello World!<\/b>")
 </SCRIPT>
</HEAD></HTML>
]PRE]

と等価 (完全に交換可能) であり、

;; 注: これだけでは [CODE(HTMLe)@en[[[body]]]] [[要素]]がないので、
[[非妥当]]です。

後者は
[PRE(HTML example code)[
<HTML><HEAD> <TITLE>Test Document</TITLE>
 </HEAD><BODY><P><B>Hello World!</B>
</BODY></HTML>
]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)[
 <TITLE>Test Document</TITLE>
 <SCRIPT type="text/javascript">
     document.write("<p><b>Hello World!<\/b>")
 </SCRIPT>
]PRE]

が >>2 の SGML 的解釈のように
[PRE(HTML invalid example code)[
<HTML><HEAD> <TITLE>Test Document</TITLE>
 <p><b>Hello World!</b>
</HEAD></HTML>
]PRE]

となるなら、 ([CODE(HTMLe)@en[[[body]]]] [[要素]]がないことには目をつぶっても)
[CODE(HTMLe)@en[[[head]]]] [[要素]]内に [CODE(HTMLe)@en[[[p]]]]
[[要素]]を入れることはできないので、[[非妥当]]です。しかし、
一旦
[PRE(HTML example code)[
 <TITLE>Test Document</TITLE>
 <p><b>Hello World!</b>
]PRE]

となり、更に
[PRE(HTML example code)[
<HTML><HEAD> <TITLE>Test Document</TITLE>
 </HEAD><BODY><p><b>Hello World!</b>
</BODY></HTML>
]PRE]

と解釈されるなら、この文書片は[[妥当]]です。

また、
[PRE(HTML)[
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
[INS[...]]
<script type="text/javascript">
  document.write ('<p>');
</script>
A paragraph.
[INS[...]]
]PRE]

は、果たして
[PRE(HTML)[
<p>
A paragraph?
</p>
]PRE]

でしょうか、
[PRE(HTML)[
<p></p>
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]]


[117] [[CEA-2014-B]]

** XHTML1 との関係

[8]
[CITE@ja[空繰再繰 - application/xhtml+xmlなページでdocument.writeを動作させる #2]] ([CODE[2007-05-01 11:21:43 +09:00]] 版) <http://nyarla.net/blog/javascript-tips6>
([[名無しさん]] [WEAK[2007-05-01 02:24:18 +00:00]])

[50] [CITE@ja[document.writeを完全にDOM仕様にする - 空繰再繰]] ([TIME[2009-01-10 14:15:20 +09:00]] 版) <http://blog.nyarla.net/2007/11/17/1>


** メモ

[7]
[CITE[d:id:quaa]] ([CODE[2006-11-28 10:39:05 +09:00]] 版) <http://d.hatena.ne.jp/quaa/20061227#p1>
([[名無しさん]] [WEAK[2006-12-28 01:52:17 +00:00]])

[11]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0Adocument.write%20('%3Cstyle%3E%20p%20%7Bcolor%3A%20green%20%7D%20%3C%2Fst')%3B%0A%3C%2Fscript%3Eyle%3E%0A%3Cp%3EPASS%20iff%20green%3C%2Fp%3E>

[[Firefox]] 2 も [[WinIE]] 7 も PASS。

[12]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0Adocument.write%20('%3Cstyle%3E%20p%20%7Bcolor%3A%20gr')%3B%0A%3C%2Fscript%3Eeen%20%7D%20%3C%2Fstyle%3E%0A%3Cp%3EPASS%20iff%20green%3C%2Fp%3E>

[[Firefox]] 2 も [[WinIE]] 7 も PASS。

[13]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cp%3EFAIL%3C%2Fp%3E%0A%3Cscript%20defer%3E%0A%20%20document.write%20('%3Cstyle%3Ep%20%7Bcolor%3A%20green%7D%3C%2Fstyle%3E')%3B%0A%3C%2Fscript%3E%0A%3Cscript%20defer%3E%0A%20%20document.write%20('%3Cp%3EPASS%20iff%20green%3C%2Fp%3E')%3B%0A%3C%2Fscript%3E%20%0A%3Cstyle%3E%0Ap%20%7B%20color%3A%20red%20%7D%0A%3C%2Fstyle%3E>

[[WinIE 7]] は DOM view はただしいが、なぜか Rendered view
には何もレンダリングされない。

[[Firefox]] 2 は FAIL ([CODE(HTMLa)@en[[[defer]]]] 未対応)。

[14]
>>13 の [[WinIE 7]] で[[レンダリング]]されないのは
[CODE(HTMLe)@en[[[script]]]] が2つあるかららしく、
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cp%3EFAIL%3C%2Fp%3E%0D%0A%3Cscript%20defer%3E%0D%0A%20%20document.write%20('%3Cstyle%3Ep%20%7Bcolor%3A%20green%7D%3C%2Fstyle%3E')%3B%0D%0A%20%20document.write%20('%3Cp%3EPASS%20iff%20green%3C%2Fp%3E')%3B%0D%0A%3C%2Fscript%3E%20%0D%0A%3Cstyle%3E%0D%0Ap%20%7B%20color%3A%20red%20%7D%0D%0A%3C%2Fstyle%3E>
なら[[レンダリング]]される。

[15]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cp%3EFAIL%3C%2Fp%3E%0D%0A%3Cscript%20defer%3E%0D%0A%20%20document.write%20('%3Cstyle%3Ep%20%7Bcolor%3A%20green%7D%3C%2Fstyle%3E')%3B%0D%0A%20%20document.write%20('%3Cp%3EPASS%20iff%20green%3C%2Fp%3E')%3B%0D%0A%3C%2Fscript%3E%20%0D%0A%3Cscript%3E%0D%0A%20%20document.write%20('%3Cstyle%3Ep%20%7B%20color%3A%20red%20%7D%3C%2Fstyle%3E')%3B%0D%0A%20%20document.write%20('%3Cp%3EFAIL%3C%2Fp%3E')%3B%0D%0A%3C%2Fscript%3E>

[CODE(JS)@en[document.write]] というより
[CODE(HTMLa)@en[[[defer]]]] のテスト。
[[WinIE 7]] は PASS。

後の [CODE(HTMLe)@en[[[script]]]] 内に [CODE(DOMm)@en[[[alert]]()]] を入れれば、
ちゃんと後の [CODE(HTMLe)@en[[[script]]]] も実行されていることが確認できる。

[16]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cscript%3E%20document.write%20(%22aa%22)%3B%20%3C%2Fsc')%3B%0A%20%20document.write%20('ript%3E')%3B%0A%3C%2Fscript%3E>

[[Firefox]] 2 でも [[WinIE 7]] でも、 [CODE(HTMLe)@en[[[script]]]]
内の [CODE(HTMLe)@en[[[script]]]] が実行され、[Q[aa]] と[[レンダリング&#65379;&#65379;されます。]]
[[HTML 5]] の[[構文解析算法]]でも、ややこしいですがおそらく、
[Q[aa]] と&#65378;&#65378;レンダリング]]されるのが正しい動作です。
(1つ目の [CODE(JS)@en[[[[document]].[[write]]]]
によって行われる[[構文解析]]で、与えられた&#65378;&#65378;引数]]の末尾に到達したところで、
[[挿入点]]に到着したということで[[字句化器]]が停止します。
[[木構築段階]]は [CODE(HTMLe)@en[[[script]]]] 
[[開始タグ]]が現れると[[文字字句]]を集め続けますが、
それは[[字句化器]]が停止したところで一旦終わるので、
[CODE(HTMLe)@en[</[[script]]]] [[終了タグ&#65379;&#65379;の直前までいきます。ここで、 [CODE(JS)@en[[[document]].[[write]]]] は[[返る]]のですが、]]
それによって外側の[[構文解析]]が再開されます。そして、
次の[[字句]]が [CODE(HTMLe)@en[[[script]]]] の[[終了タグ]]になるので、
[[木構築段階]]の [CODE(HTMLe)@en[[[script]]]] [[開始タグ]]の処理の続きで、[[スクリプト]]が実行されます。)

[17]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cstyle%3E%20p%20%7B')%3B%0Aw(document.documentElement.innerHTML)%3B%0A%20%20document.write%20('color%3A%20gree')%3B%0Aw(document.documentElement.innerHTML)%3B%20%0A%20%20document.write%20('n%20%7D')%3B%0A%3C%2Fscript%3E%3C%2Fstyle%3E%3Cp%3Exxxx>

[[WinIE 7]] でも [[Firefox]] 2 でも、緑の[Q[xxxx]]が[[レンダリング]]されます。

[19]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cstyle%3E')%3B%0Aw%20(document.documentElement.innerHTML)%3B%0A%20%20document.write%20('color%3A%20gree')%3B%0Aw%20(document.documentElement.innerHTML)%3B%20%0A%20%20document.write%20('n%20%7D')%3B%0A%3C%2Fscript%3E%3C%2Fstyle%3E%3Cp%3Exxxx%0A%3Cscript%3E%0Aw%20(document.documentElement.innerHTML)%3B%20%0A%3C%2Fscript%3E%0A%3Cpre%3E%0Axxxx>

[CODE(JS)@en[[[document]].[[write]]]] による追加分が [[DOM]] [[木]]に反映されるのはいつか?
(ここでは [CODE(DOMa)@en[[[innerHTML]]]] を使用。)

- 通常の[[要素]]なら、直前の [CODE(JS)@en[[[document]].[[write]]]]
で与えられたものすべてが既に反映済み
- [CODE(HTMLe)@en[[[style]]]] [[要素]]の場合、
-- [[WinIE 7]] では [CODE(HTMLe)@en[[[style]]]] [[要素]]自体は追加されるが、
その[[内容]]は[[終了タグ]]を処理するまで[[空]]のまま
-- [[Firefox]] 2 では[[終了タグ]]が処理されるまで
[CODE(HTMLe)@en[[[style]]]] [[要素]]自体が追加されない

([[名無しさん]])

[20]
>>19 [[WinIE 7]] で [CODE(HTMLe)@en[[[style]]]]
[[要素]]の [CODE(DOMa)@en[[[sheet]]]]
[[属性]]は [CODE(DOM)@en[[[null]]]] になっているようです。
([[名無しさん]])

[21]
>>20 訂正: [CODE(DOMa)@en[[[styleSheet]]]] [[属性]]。
([[名無しさん]])

[22]
>>19 [[Opera]] 9.27、[[Safari]] 3.1.1 では、
[[WinIE 7]] 同様、[[終了タグ]]を処理するまでは空のままのようです。
[CODE(DOMa)@en[[[sheet]]]] [[属性]]は空の[[スタイル・シート]]になっているようです。
([[名無しさん]])

[23]
>>22 [CODE(DOMa)@en[[[sheet]]]] [[属性]]の指す[[スタイル・シート]]は[[終了タグ]]が処理されるまでずっと空のままのようです。

;; <http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0D%0A%20%20document.write%20('%3Cstyle%3E')%3B%0D%0A%20%20document.write%20('p%20%7B%20color%3A%20green%20%7D')%3B%0D%0A%20%20w%20(document.getElementsByTagName%20('style')%5B0%5D.sheet.cssRules.length)%3B%0D%0A%3C%2Fscript%3E%3C%2Fstyle%3E>

([[名無しさん]])

[24]
[CODE(JS)@en[[[document]].[[write]] ('<pre>\na</pre>')]]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0D%0A%20%20document.write%20('%3Cpre%3E%5Cna%3C%2Fpre%3E')%3B%0D%0A%3C%2Fscript%3E>

[[WinIE 7]], [[Firefox]] 2, [[Opera]] 9.27, [[Safari]] 3.1.1 のいずれも、
[[開始タグ]]直後の[[改行]]を無視。
([[名無しさん]])

[25]
[CODE(JS)@en[[[document]].[[write]] ('<pre>'); [[document]].[[write]] ('\na</pre>')]]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cpre%3E')%3B%0A%20%20document.write%20('%5Cna%3C%2Fpre%3E')%3B%0A%3C%2Fscript%3E>

>>24 の4ブラウザ中、[[Firefox]] 2 だけは[[改行]]を無視''せず''。
([[名無しさん]])

[26]
[CODE(JS)@en[[[document]].[[write]] ('<pre>', '\na</pre>');]]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cpre%3E'%2C%20'%5Cna%3C%2Fpre%3E')%3B%0A%3C%2Fscript%3E>

これなら [[Firefox]] 2 も[[改行]]を無視する。
([[名無しさん]])

[27]
[CODE(JS)@en[[[document]].[[writeln]] ('<pre>'); [[document]].[[write]] ('a</pre>');]]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.writeln%20('%3Cpre%3E')%3B%0A%20%20document.write%20('a%3C%2Fpre%3E')%3B%0A%3C%2Fscript%3E>

だけどこっちは [[Firefox]] 2 が[[改行]]を[[無視]]しない。
([[名無しさん]])

[28]
[[Opera]] 9.27 と [[Safari]] 3.1.1 の結果

>>11、>>12 PASS

>>13、>>15 FAIL ([CODE(HTMLa)@en[[[defer]]]] 未対応)

>>16 同じ (実行される)

([[名無しさん]])

[29]
>>19 みたいなことを [CODE(HTMLe)@en[[[script]]]]
[[要素]]を書き出す場合でやってみた
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0Aw%20(document.documentElement.innerHTML)%3B%0A%20%20document.write%20('%3Cscript%3E%20document.')%3B%0Aw%20(document.documentElement.innerHTML)%3B%0A%20%20document.write%20('write%20(%22a%22)%3B%20%3C%2F'%20%2B%20'script%3E')%3B%0Aw%20(document.documentElement.innerHTML)%3B%0A%3C%2Fscript%3E>

4ブラウザとも、 [CODE(HTMLe)@en[[[script]]]] [[要素]]が
[CODE(DOMa)@en[[[innerHTML]]]] に現れるのは[[終了タグ]]が処理されたあとのようです。

この例だと [[Safari]] だけは3番目の [CODE[w]] で生成された
[CODE(HTMLe)@en[[[script]]]] [[要素]]によって書き込まれた
[CODE[a]] が反映されていないのですが、
これはその [CODE(HTMLe)@en[[[script]]]] [[要素]]が実行されていないわけではなく、
[[文字データ]]を書いても次の[[タグ]]などが現れるまで
[[DOM]] に追加されないという ([[Safari]] だけの) 動作のためのようです。
([[名無しさん]])

[30]
>>29 

書き出される [CODE(HTMLe)@en[[[script]]]] [[要素]]が実行される時点での
[CODE(DOMa)@en[[[innerHTML]]]] は?
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0D%0A%20%20document.write%20('%3Cscript%3E%20w%20(document.documentElement.innerHTML)%3B%20document.')%3B%0D%0A%20%20document.write%20('write%20(%22a%22)%3B%20%3C%2F'%20%2B%20'script%3E')%3B%0D%0A%3C%2Fscript%3E>

書き出された [CODE(HTMLe)@en[[[script]]]] [[要素]]が [[DOM]]
に追加された状態の [CODE(DOMa)@en[[[innerHTML]]]] が出てくるようです。
([[名無しさん]])

[31]
>>30 は4ブラウザとも。
([[名無しさん]])

[32]
[CODE(HTMLe)@en[[[script]]]] の途中からが外側の
[CODE(HTMLe)@en[[[script]]]] [[要素]]の後にいっていてもよいのか?
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cscript%3E%20w%20(document.documentElement.innerHTML)%3B%20document.')%3B%0A%20%20document.write%20('write%20(%22a')%3B%0A%3C%2Fscript%3E%22)%3B%20%3C%2Fscript%3E>

4ブラウザともおk ([CODE(HTMLe)@en[[[script]]]] 
[[要素]]の続きとみなす) のようです。
([[名無しさん]])

[33]
わけがわからないくらい複雑な例 with [CODE(HTMLe)@en[[[script]]]] [CODE(HTMLa)@en[[[src]]]]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%20src%3D%22javascript%3A'%20document.write%20(%26quot%3Baaaaa%26quot%3B)%3B%20'%22%3E%3C%2Fscript%3E%0A%3Cscript%3E%0A%20%20document.write%20(%22%3Cscript%3Edocument.write%20('%3Cscript%20src%3Djavascript%3A%26apos%3Bdocument.write(%26quot%3Baaaaa%26quot%3B)%3B%26apos%3B%3E%3C%2F'%2C%20'script%3E%3Cscript%3E%20document.wri')%3B%3C%2F%22%2C%20%22script%3E%22)%3B%0A%3C%2Fscript%3Ete%20('ccc')%3B%20%3C%2Fscript%3E>

[[Firefox]] 2 では、最初の
[CODE(HTMLe)@en[[[script]]]] [[要素]]があるかないか
([CODE(URI)@en[[[javascript]]:]] [[URI]] を使っていることに起因している模様)、
[[Live DOM Viewer]] 内で見るかどうか、
[[Live DOM Viewer]] でも直接入力か permalink 使用かによって結果が変わってくる
(2つ目の [CODE(HTMLe)@en[[[script]]]] による書き込みが反映されたりされなかったりする、というか [CODE(HTMLe)@en[[[script]]]] が [[DOM]]
に現れなかったり、 [CODE(HTMLe)@en[[[body]]]] が2つでてきたり、よくわからん。) ようです。

;; [[Live DOM Viewer]] かどうかで結果が変わるのは、
[[Live DOM Viewer]] 自体が [CODE(JS)@en[[[document]].[[write]]]] を使っているせいでしょう。

([[名無しさん]])

[34]
>>33 他の3ブラウザはいずれも [Q[ccc]] とだけでてきます。
[[Safari]] と [[WinIE]] は、
[CODE(HTMLa)@en[[[src]]]] 内の [CODE(URI)@en[[[javascript]]:]]
[[URI]] を実行していないようです。 [[Opera]] は外部スクリプト内の
[CODE(JS)@en[[[document]].[[write]]]] を実行していないようです。
([[名無しさん]])

[35]
>>34 [[Opera]] は [CODE(JS)@en[[[document]].[[write]]]] を実行しないのではなく、
[CODE(HTMLa)@en[[[javascript]]:]] [[URI]] を実行はするのですが、
最後に得られた[[文字列]]を外部スクリプトとみなすのではないようで、
[[エラーコンソール]]に
[Q[リンク先のスクリプトを読み込むことができません]]とでてきます。
([[名無しさん]])

[36]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%20src%3D%22javascript%3A%20document.write%20('x')%3B%20%22%3E%3C%2Fscript%3E%20%20%20>

[[Opera]] では [Q[x]] が [CODE(HTMLe)@en[[[body]]]] [[要素]]中にでてきます。

[[Firefox]] の [CODE(HTMLa)@en[[[src]]]] 内の [CODE(URI)@en[[[javascripot]]:]]
[[URI]] の実行される文脈では文書本体の [CODE(JS)@en[[[Global]]]]
[[物体]]とは違うものを使っているようで、
[CODE(JS)@en[[[window]]]] にも [CODE(JS)@en[[[document]]]]
にもその他[[大域変数]]にもアクセスできません
([CODE(JS)@en[[[ReferenceError]]]] になります)。
([[名無しさん]])

[37]
[CITE@en[Hixie's Natural Log: Tag Soup: Blocks-in-inlines]] ([CODE[2008-04-25 22:46:42 +09:00]] 版) <http://ln.hixie.ch/?start=1138169545&count=1>
([[名無しさん]])

[38]
[CITE@en[Hixie's Natural Log: Why document.write() doesn't work in XML]] ([CODE[2008-04-25 22:48:57 +09:00]] 版) <http://ln.hixie.ch/?start=1091626816&count=1>
([[名無しさん]])

[39]
[CITE@en[Hixie's Natural Log: Tag Soup: appendChild() of a script that calls document.write()]] ([CODE[2008-04-25 22:49:24 +09:00]] 版) <http://ln.hixie.ch/?start=1155195074&count=1>
([[名無しさん]])

[40]
[CITE[Index of /tests/adhoc/dom/level0/write]] ([CODE[2008-04-25 23:07:32 +09:00]] 版) <http://hixie.ch/tests/adhoc/dom/level0/write/>
([[名無しさん]])

[41]
んー、カオス。
([[名無しさん]])

[42]
[CODE(JS)@en[[[document]].[[write]]]] で始まった
[CODE@en[[[CDATA]]]] [[内容モデル旗]]とその[[スクリプト]]の[[終了タグ]]の関係は?
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20(%22%3Cstyle%3E%20p%20%7B%22)%3B%0A%20%20w%20(document.documentElement.innerHTML)%3B%0A%3C%2Fscript%3E%20color%3A%20green%3B%0A%3Cscript%3E%0A%20%20document.write%20('%7D%20%3C%2Fstyle%3E')%3B%0A%3C%2Fscript%3E%3Cp%3Exxxx%0A>

4ブラウザとも、[CODE(HTML)@en[</[[script]]>]] 以後も[[内容モデル旗]]は
[CODE@en[[[CDATA]]]] にしたまま処理を続行するようで、
次の [CODE(HTML)@en[<[[script]]>]] [[開始タグ]]は[[開始タグ]]ではなく、
[[文字データ]]として処理します。

([[名無しさん]])

[43]
[CITE@en[Live Scripting HTML Parser]] ([CODE[2008-04-27 20:27:04 +09:00]] 版) <http://suika.fam.cx/www/markup/html/scripting-parser/parser>
([[名無しさん]])

[44]
[CITE[Bug 95487 &#8211; JavaScript-generated table never completes]] ([CODE[2008-06-18 09:05:55 +09:00]] 版) <https://bugzilla.mozilla.org/show_bug.cgi?id=95487>
([[名無しさん]])

[45]
[CITE@ja[document.write()の実行タイミングをずらす方法]] ([CODE[2008-06-22 15:16:43 +09:00]] 版) <http://p2b.jp/index.php?UID=1153728573>
([[名無しさん]])

[46]
[CITE[最速インターフェース研究会 :: ページレンダリングを妨げないdocument.writeの実装]] ([CODE[2008-06-22 15:21:04 +09:00]] 版) <http://la.ma.la/blog/diary_200612061928.htm>
([[名無しさん]])

[47]
[CITE[Fenrir's BLog: Ajaxでdocument.writeするJavaScriptへの対策]] ([CODE[2008-06-02 14:24:53 +09:00]] 版) <http://fenrir.naruoka.org/archives/000555.html>
([[名無しさん]])

[48]
[CITE@ja-JP[野ログはノロキュアMaxHeart - document.writeをバッファリングするJavaScript]] ([[nog]] 著, [CODE[2008-04-18 09:41:41 +09:00]] 版) <http://cureblack.com/20080418.html#p01>
([[名無しさん]])


[49]
[CITE[Javascriptの外部ファイル内でdocument.writeしたら文字化け(Mac IE 4.5編)]] ([TIME[2007-02-19 06:57:31 +09:00]] 版) <http://www.shtml.jp/mojibake/macie45.html>

[51] [CITE@en[Web Applications 1.0 r5616     Change how document.write() is ignored.Fixing http://www.w3.org/Bugs/Public/show_bug.cgi?id=9767]]
( ([TIME[2010-10-13 06:20:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=5615&to=5616>

[52] [CITE[IRC logs: freenode / #whatwg / 20101013]]
( ([TIME[2010-10-23 23:42:03 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20101013>

[53] [CITE@en[Web Applications 1.0 r6924 More tweaks to the text (including a comment that describes one of the situations in question).Fixing https://www.w3.org/Bugs/Public/show_bug.cgi?id=14275]]
( ([TIME[2012-01-27 09:30:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=6923&to=6924>

[54] [CITE[''''''[''''''whatwg'''''']'''''' HTMLLinkElement.disabled and HTMLLinkElement.sheet behavior]]
( ([TIME[2012-08-28 04:46:43 +09:00]] 版))
<http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-August/037001.html>

[55] [CITE@en[Web Applications 1.0 r7290     Change how <script> is handled in re-entrant parser situations when there's a blocking style sheet.]]
( ([TIME[2012-08-28 13:48:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=7289&to=7290>

[56] [CITE@en[Web Applications 1.0 r7757     Try to define when document.open() doesn't work more precisely.]]
( ([TIME[2013-03-16 07:41:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=7756&to=7757>

[57] [CITE@en[Web Applications 1.0 r7869     Make document.write() a no-op on non-active documents.]]
( ([TIME[2013-05-29 05:47:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=7868&to=7869>

[FIG[
[FIGCAPTION[
[58] 
[CITE[新暦と旧暦の変換計算(長期)]] ([TIME[2006-05-28 08:57:13 +09:00]] 版) <http://koyomi8.com/9reki/9rekicgi.htm>

;; [59] [CODE(HTMLa)@en[[[action]]]] を可変にするために [CODE(JS)@en[[[document.write]]]]
が使われています。なお[[終了タグ]]は直接 [[HTML]] として記述されています。
]FIGCAPTION]

[PRE(HTML code)[
<SCRIPT Language="JavaScript">
<!--
document.writeln('<form NAME="9reki" method="POST" action="' + CGISERVER + 'cgi/9reki_f.cgi">');
// -->
</SCRIPT>
]PRE]
]FIG]


[60] [CITE@en[bug 5562 – 無限にdocument.write()を繰り返してメモリを食いつぶしていくと再パース処理でクラッシュする]]
( ([TIME[2014-12-19 18:15:57 +09:00]] 版))
<http://bugzilla.mozilla.gr.jp/show_bug.cgi?id=5562>

[61] [CITE@en[430574 – Infinite document.write() loop hangs, fills memory, and crashes]]
( ([TIME[2014-12-19 18:16:32 +09:00]] 版))
<https://bugzilla.mozilla.org/show_bug.cgi?id=430574>

[80] [CITE[IRC logs: freenode / #whatwg / 20150528]]
([TIME[2015-05-29 16:21:13 +09:00]] 版)
<http://krijnhoetmer.nl/irc-logs/whatwg/20150528>

[81] [CITE@en[Formalize custom element reactions · whatwg/html@27aa7bc]]
([TIME[2016-04-26 18:51:55 +09:00]] 版)
<https://github.com/whatwg/html/commit/27aa7bc4fa6f168654a8c858f0773e611f679b39>

[FIG(amazon)[
JavaScript
]FIG]

[85] [CITE@en[Clarify the note about reentrant parsing in document.write()]]
([[domenic]]著, [TIME[2016-08-15 17:30:21 +09:00]])
<https://github.com/whatwg/html/commit/d6630fe808e48898108dc671025c0bcad5048cc3>

[86] [CITE@en[Make document.write etc. throw during parsing custom elements]]
([[domenic]]著, [TIME[2016-08-17 15:44:39 +09:00]])
<https://github.com/whatwg/html/commit/00c6fa07bdb9f0d08a28f6c6e1ababca7d08618c>

[87] [CITE@en[Make document.write etc. throw during parsing custom elements]]
([[domenic]]著, [TIME[2016-08-17 15:44:39 +09:00]])
<https://github.com/whatwg/html/commit/00c6fa07bdb9f0d08a28f6c6e1ababca7d08618c>

[94] [CITE@en[For users on very slow connections, block document.written scripts · Issue #17 · WICG/interventions]]
([TIME[2016-10-25 13:13:39 +09:00]])
<https://github.com/WICG/interventions/issues/17>

[95] [CITE@en[Editorial: refactor document.open()/write()/writeln()]]
([[annevk]]著, [TIME[2017-05-16 14:12:59 +09:00]])
<https://github.com/whatwg/html/commit/d43b7050b4fe83ebce7724ea005e4707f06a86f7>

[108] [CITE@en[Allow not executing scripts inserted by document.write()]]
([[domenic]]著, [TIME[2017-07-14 05:37:38 +09:00]])
<https://github.com/whatwg/html/commit/15b258dc74ffe1ba321b81a1c876f129681a97c2>

[109] [CITE@en[For users on very slow connections, block document.written scripts · Issue #17 · WICG/interventions]]
([TIME[2017-07-15 23:45:02 +09:00]])
<https://github.com/WICG/interventions/issues/17>

[110] [CITE@en[Allow not executing scripts inserted by document.write() by domenic · Pull Request #1400 · whatwg/html]]
([TIME[2017-07-16 00:03:04 +09:00]])
<https://github.com/whatwg/html/pull/1400>

[111] [CITE@en[Intervening against document.write()  |  Web  |  Google Developers]]
([TIME[2017-05-17 04:19:52 +09:00]])
<https://developers.google.com/web/updates/2016/08/removing-document-write>



[70] [CITE@en[document.open() simplifications, part 2]]
([[TimothyGu]]著, [TIME[2018-08-21 03:57:31 +09:00]])
<https://github.com/whatwg/html/commit/ae7cf0cc1936c6c309d7279c822dffc3af147851>

[71] [CITE@en[Remove overridden reload concept]]
([[TimothyGu]]著, [TIME[2018-08-18 05:31:49 +09:00]])
<https://github.com/whatwg/html/commit/6440ccae7340ea41d3eb5bf8ff0b3b27363eda85>

[74] [CITE@en[document.open() simplifications, part 2 by TimothyGu · Pull Request #3946 · whatwg/html]]
([TIME[2018-09-05 23:39:21 +09:00]])
<https://github.com/whatwg/html/pull/3946>

[75] [CITE@en[Allow document.open()/write() to be called on non-active documents]]
([[TimothyGu]]著, [TIME[2018-09-05 05:19:06 +09:00]])
<https://github.com/whatwg/html/commit/ad541d6a5e74f56dccedc56d50750adb65184505>

[66] [CITE@en[Extend document.open/write to non-active documents · Issue #2827 · whatwg/html]]
([TIME[2018-09-29 18:51:34 +09:00]])
<https://github.com/whatwg/html/issues/2827>

[91] [CITE@en[Allow document.open() to be called on non-active documents by TimothyGu · Pull Request #3977 · whatwg/html]]
([TIME[2018-09-29 18:54:54 +09:00]])
<https://github.com/whatwg/html/pull/3977>

[98] [CITE@en[Ignore document.open/write after the active parser has been aborted]]
([[foolip]]著, [TIME[2019-10-16 17:25:18 +09:00]])
<https://github.com/whatwg/html/commit/ead4aa8ec576d7d330a04f7ec8508e336b895fdb>

[115] [CITE@en[Consider adding an "ignore document.open/write" flag on document · Issue #4723 · whatwg/html · GitHub]]
([TIME[2020-08-31 17:27:01 +09:00]])
<https://github.com/whatwg/html/issues/4723>

[116] [CITE@en[Ignore document.open/write after the active parser has been aborted by foolip · Pull Request #4907 · whatwg/html · GitHub]]
([TIME[2020-08-31 17:30:18 +09:00]])
<https://github.com/whatwg/html/pull/4907>