1. 8.4 動的マークアップの挿入
      1. 8.4.1 入力ストリームを開く
      2. 8.4.2 入力ストリームを閉じる
      3. 8.4.3 document.write()
      4. 8.4.4 document.writeln()

8.4 Dynamic markup insertion

APIs for dynamically inserting markup into the document interact with the parser, and thus their behavior varies depending on whether they are used with HTML documents (and the HTML parser) or XML documents (and the XML parser).

Document objects have a throw-on-dynamic-markup-insertion counter, which is used in conjunction with the create an element for the token algorithm to prevent custom element constructors from being able to use document.open(), document.close(), and document.write() when they are invoked by the parser. Initially, the counter must be set to zero.

8.4.1 入力ストリームを開く

open()メソッドは、異なる引数の数をもつ異形を提供する。

document = document . open( [ type [, replace ] ] )

前のオブジェクトを再利用する場合を除き、あたかもそれが新しいDocumentオブジェクトであるかのように、Documentに正しい場所で置換され、その後返される。

type引数が省略されるかは、"text/html"を持つ場合、結果として生じるDocumentは、document.write()を使って解析するデータを指定されうる、関連付けられたHTMLパーサを持つ。そうでなければ、document.write()に渡ったすべてのコンテンツは、プレーンテキストとして解析されるだろう。

replace引数が存在し、値"replace"を持つ場合、Documentオブジェクトのセッション履歴内の既存エントリは削除される。

Documentがまだ解析されている場合、メソッドは効果がない。

Throws an "InvalidStateError" DOMException if the Document is an XML document.

Throws an "InvalidStateError" DOMException if the parser is currently executing a custom element constructor.

window = document . open( url, name, features )

window.open()メソッドのように動作する。

Document objects have an ignore-opens-during-unload counter, which is used to prevent scripts from invoking the document.open() method (directly or indirectly) while the document is being unloaded. Initially, the counter must be set to zero.

The document open steps, given a document, type, and replaceInput, are as follows:

  1. If document is an XML document, then throw an "InvalidStateError" DOMException exception.

  2. If document's throw-on-dynamic-markup-insertion counter is greater than 0, then throw an "InvalidStateError" DOMException.

  3. If document is not an active document, then return document.

  4. If document's origin is not same origin to the origin of the responsible document specified by the entry settings object, then throw a "SecurityError" DOMException.

  5. If document has an active parser whose script nesting level is greater than 0, then return document.

    This basically causes document.open() to be ignored when it's called in an inline script found during parsing, while still letting it have an effect when called from a non-parser task such as a timer callback or event handler.

  6. Similarly, if document's ignore-opens-during-unload counter is greater than 0, then return document.

    This basically causes document.open() to be ignored when it's called from a beforeunload, pagehide, or unload event handler while the Document is being unloaded.

  7. Let replace be false.

  8. If replaceInput is an ASCII case-insensitive match for "replace", then set replace to true.

    Otherwise, if document's browsing context's session history contains only one Document object, and that was the about:blank Document created when document's browsing context was created, and that Document object has never had the unload a document algorithm invoked on it (e.g., by a previous call to document.open()), then set replace to true.

  9. Set document's salvageable state to false.

  10. Prompt to unload document. If the user refused to allow the document to be unloaded, then return document.

  11. Unload document, with the recycle parameter set to true.

  12. Abort document.

  13. Unregister all event listeners registered on document and its descendants.

  14. Remove any tasks associated with document in any task source.

  15. Remove all child nodes of document, without firing any mutation events.

  16. Call the JavaScript InitializeHostDefinedRealm() abstract operation with the following customizations:

    This is not universally implemented and can perhaps be removed; see issue #1698.

  17. Set up a window environment settings object with realm execution context.

  18. Set the active document of document's browsing context to document with window.

  19. Replace document's singleton objects with new instances of those objects, created in window's Realm. (This includes in particular the History, ApplicationCache, and Navigator, objects, the various BarProp objects, the two Storage objects, the various HTMLCollection objects, and objects defined by other specifications, like Selection. It also includes all the Web IDL prototypes in the JavaScript binding, including document's prototype.)

  20. Change document's character encoding to UTF-8.

  21. If document is ready for post-load tasks, then set document's reload override flag and set document's reload override buffer to the empty string.

  22. Set document's salvageable state back to true.

  23. Change document's URL to the URL of the responsible document specified by the entry settings object.

  24. If document's iframe load in progress flag is set, then set document's mute iframe load flag.

  25. Create a new HTML parser and associate it with document. This is a script-created parser (meaning that it can be closed by the document.open() and document.close() methods, and that the tokenizer will wait for an explicit call to document.close() before emitting an end-of-file token). The encoding confidence is irrelevant.

  26. Set the current document readiness of document to "loading".

  27. If type is an ASCII case-insensitive match for the string "replace", then, for historical reasons, set it to the string "text/html".

    Otherwise:

    If the type string contains a U+003B SEMICOLON character (;), remove the first such character and all characters from it up to the end of the string.

    Strip leading and trailing ASCII whitespace from type.

  28. If type is not now an ASCII case-insensitive match for the string "text/html", then act as if the tokenizer had emitted a start tag token with the tag name "pre" followed by a single U+000A LINE FEED (LF) character, then switch the HTML parser's tokenizer to the PLAINTEXT state.

  29. Remove any tasks queued by the history traversal task source that are associated with any Document objects in the top-level browsing context's document family.

  30. Remove all the entries in the browsing context's session history after the current entry. If the current entry is the last entry in the session history, then no entries are removed.

    This doesn't necessarily have to affect the user agent's user interface.

  31. Remove any earlier entries whose Document object is document.

  32. If replace is false, then add a new entry, just before the last entry, and associate with the new entry the text that was parsed by the previous parser associated with document, as well as the state of document at the start of these steps. This allows the user to step backwards in the session history to see the page before it was blown away by the document.open() call. This new entry does not have a Document object, so a new one will be created if the session history is traversed to that entry.

  33. Set document's fired unload flag to false. (It could have been set to true during the unload step above.)

  34. Finally, set the insertion point to point at just before the end of the input stream (which at this point will be empty).

  35. Return document.

When invoked with two arguments or fewer, the document.open(type, replace) method must return the result of running the document open steps with this Document object, type, and replace.

The document.open() method does not affect whether a Document is ready for post-load tasks or completely loaded.

When invoked with three arguments, the open(url, name, features) method must run these steps:

  1. If this Document object is not an active document, then throw an "InvalidStateError" DOMException exception.

  2. Return the result of running the window open steps with url, name, and features.

8.4.2 入力ストリームを閉じる

document . close()

document.open()メソッドによって開かれた入力ストリームを閉じる。

Throws an "InvalidStateError" DOMException if the Document is an XML document.

Throws an "InvalidStateError" DOMException if the parser is currently executing a custom element constructor.

The close() method must run the following steps:

  1. If the Document object is an XML document, then throw an "InvalidStateError" DOMException and abort these steps.

  2. If the Document object's throw-on-dynamic-markup-insertion counter is greater than zero, then throw an "InvalidStateError" DOMException and abort these steps.

  3. If there is no script-created parser associated with the document, then abort these steps.

  4. Insert an explicit "EOF" character at the end of the parser's input stream.

  5. If there is a pending parsing-blocking script, then abort these steps.

  6. Run the tokenizer, processing resulting tokens as they are emitted, and stopping when the tokenizer reaches the explicit "EOF" character or spins the event loop.

8.4.3 document.write()

document . write(text...)

一般に、与えられた文字列をDocumentの入力ストリームに加える。

このメソッドは非常に特異な振る舞いを持つ。一部の場合において、このメソッドは、パーサが実行されている間、HTMLパーサの状態に影響を与えることができる。その結果、文書のソースに対応しないDOMをもたらす(たとえば、記述された文字列が、文字列"<plaintext>"または"<!--"である場合)。他の例では、あたかもdocument.open()が呼び出されていたかのように、呼び出しが最初に現在のページをクリアできる。さらに多くの例では、メソッドは単に無視されるか、または例外を投げる。Users agents are explicitly allowed to avoid executing script elements inserted via this method. And to make matters even worse, the exact behavior of this method can in some cases be dependent on network latency, which can lead to failures that are very hard to debug. For all these reasons, use of this method is strongly discouraged.

Throws an "InvalidStateError" DOMException when invoked on XML documents.

Throws an "InvalidStateError" DOMException if the parser is currently executing a custom element constructor.

Document objects have an ignore-destructive-writes counter, which is used in conjunction with the processing of script elements to prevent external scripts from being able to use document.write() to blow away the document by implicitly calling document.open(). Initially, the counter must be set to zero.

The document write steps, given a Document object document and a string input, are as follows:

  1. If document is an XML document, then throw an "InvalidStateError" DOMException.

  2. If document's throw-on-dynamic-markup-insertion counter is greater than 0, then throw an "InvalidStateError" DOMException.

  3. If document is not an active document, then return.

  4. If the insertion point is undefined, then:

    1. If document's ignore-opens-during-unload counter is greater than 0 or document's ignore-destructive-writes counter is greater than 0, then return.

    2. Run the document open steps with document, "text/html", and the empty string. ユーザーが文書をアンロードできるようにすることを拒否した場合、これらの手順を中止する。Otherwise, the insertion point will point at just before the end of the (empty) input stream.

  5. Insert input into the input stream just before the insertion point.

  6. If document's reload override flag is set, then append input to document's reload override buffer.

  7. If there is no pending parsing-blocking script, have the HTML parser process input, one code point at a time, processing resulting tokens as they are emitted, and stopping when the tokenizer reaches the insertion point or when the processing of the tokenizer is aborted by the tree construction stage (this can happen if a script end tag token is emitted by the tokenizer).

    If the document.write() method was called from script executing inline (i.e. executing because the parser parsed a set of script tags), then this is a reentrant invocation of the parser. If the parser pause flag is set, the tokenizer will abort immediately and no HTML will be parsed, per the tokenizer's parser pause flag check.

The document.write(...) method, when invoked, must run the document write steps with this Document object and a string that is the concatanation of all arguments passed.

8.4.4 document.writeln()

document . writeln(text...)

改行文字の後に、与えられた文字列をDocumentの入力ストリームに加える。必要ならば、open()メソッドを暗黙のうちに最初に呼び出す。

Throws an "InvalidStateError" DOMException when invoked on XML documents.

Throws an "InvalidStateError" DOMException if the parser is currently executing a custom element constructor.

The document.writeln(...) method, when invoked, must run the document write steps with this Document object and a string that is the concatanation of all arguments passed and U+000A LINE FEED.