The input to the tree construction stage is a sequence of tokens
from the tokenization stage. The tree construction
stage is associated with a DOM Document object when a
parser is created. The "output" of this stage consists of
dynamically modifying or extending that document's DOM tree.
This specification does not define when an interactive user agent
has to render the Document so that it is available to
the user, or when it has to begin accepting user input.
As each token is emitted from the tokeniser, the user agent must process the token according to the rules given in the section corresponding to the current insertion mode.
When the steps below require the UA to insert a
character into a node, if that node has a child immediately
before where the character is to be inserted, and that child is a
Text node, and that Text node was the last
node that the parser inserted into the document, then the character
must be appended to that Text node; otherwise, a new
Text node whose data is just that character must be
inserted in the appropriate place.
DOM mutation events must not fire
for changes caused by the UA parsing the document. (Conceptually,
the parser is not mutating the DOM, it is constructing it.) This
includes the parsing of any content inserted using document.write() and document.writeln() calls. [DOM3EVENTS]
Not all of the tag names mentioned below are conformant tag names in this specification; many are included to handle legacy content. They still form part of the algorithm that implementations are required to implement to claim conformance.
The algorithm described below places no limit on the depth of the DOM tree generated, or on the length of tag names, attribute names, attribute values, text nodes, etc. While implementors are encouraged to avoid arbitrary limits, it is recognized that practical concerns will likely force user agents to impose nesting depths.
When the steps below require the UA to create an element for a token in a
particular namespace, the UA must create a node implementing the
interface appropriate for the element type corresponding to the tag
name of the token in the given namespace (as given in the
specification that defines that element, e.g. for an a
element in the HTML namespace, this specification
defines it to be the HTMLAnchorElement interface), with
the tag name being the name of that element, with the node being in
the given namespace, and with the attributes on the node being those
given in the given token.
The interface appropriate for an element in the HTML
namespace that is not defined in this specification is
HTMLElement. The interface appropriate for an element
in another namespace that is not defined by that namespace's
specification is Element.
When a resettable element is created in this manner, its reset algorithm must be invoked once the attributes are set. (This initializes the element's value and checkedness based on the element's attributes.)
When the steps below require the UA to insert an HTML element for a token, the UA must first create an element for the token in the HTML namespace, and then append this node to the current node, and push it onto the stack of open elements so that it is the new current node.
The steps below may also require that the UA insert an HTML element in a particular place, in which case the UA must follow the same steps except that it must insert or append the new node in the location specified instead of appending it to the current node. (This happens in particular during the parsing of tables with invalid content.)
If an element created by the insert an HTML element
algorithm is a form-associated element, and the
form element pointer is not null,
and the newly created element doesn't have a form attribute, the user agent must
associate the newly
created element with the form element pointed to by the
form element pointer before
inserting it wherever it is to be inserted.
When the steps below require the UA to insert a foreign
element for a token, the UA must first create an element
for the token in the given namespace, and then append this
node to the current node, and push it onto the
stack of open elements so that it is the new
current node. If the newly created element has an xmlns attribute in the XMLNS namespace
whose value is not exactly the same as the element's namespace, that
is a parse error.
When the steps below require the user agent to adjust MathML
attributes for a token, then, if the token has an attribute
named definitionurl, change its name to definitionURL (note the case difference).
When the steps below require the user agent to adjust
foreign attributes for a token, then, if any of the attributes
on the token match the strings given in the first column of the
following table, let the attribute be a namespaced attribute, with
the prefix being the string given in the corresponding cell in the
second column, the local name being the string given in the
corresponding cell in the third column, and the namespace being the
namespace given in the corresponding cell in the fourth
column. (This fixes the use of namespaced attributes, in particular
xml:lang.)
| Attribute name | Prefix | Local name | Namespace |
|---|---|---|---|
xlink:actuate | xlink | actuate | XLink namespace |
xlink:arcrole | xlink | arcrole | XLink namespace |
xlink:href | xlink | href | XLink namespace |
xlink:role | xlink | role | XLink namespace |
xlink:show | xlink | show | XLink namespace |
xlink:title | xlink | title | XLink namespace |
xlink:type | xlink | type | XLink namespace |
xml:base | xml | base | XML namespace |
xml:lang | xml | lang | XML namespace |
xml:space | xml | space | XML namespace |
xmlns | (none) | xmlns | XMLNS namespace |
xmlns:xlink | xmlns | xlink | XMLNS namespace |
The generic CDATA element parsing algorithm and the generic RCDATA element parsing algorithm consist of the following steps. These algorithms are always invoked in response to a start tag token.
Insert an HTML element for the token.
If the algorithm that was invoked is the generic CDATA element parsing algorithm, switch the tokeniser's content model flag to the CDATA state; otherwise the algorithm invoked was the generic RCDATA element parsing algorithm, switch the tokeniser's content model flag to the RCDATA state.
Let the original insertion mode be the current insertion mode.
Then, switch the insertion mode to "in CDATA/RCDATA".
When the steps below require the UA to generate implied end
tags, then, while the current node is a
dd element, a dt element, an
li element, an option element, an
optgroup element, a p element, an
rp element, or an rt element, the UA must
pop the current node off the stack of open
elements.
If a step requires the UA to generate implied end tags but lists an element to exclude from the process, then the UA must perform the above steps as if that element was not in the above list.
Foster parenting happens when content is misnested in tables.
When a node node is to be foster parented, the node node must be inserted into the foster parent element, and the current table must be marked as tainted. (Once the current table has been tainted, whitespace characters are inserted into the foster parent element instead of the current node.)
The foster parent element is the parent element of the
last table element in the stack of open
elements, if there is a table element and it has
such a parent element. If there is no table element in
the stack of open elements (fragment
case), then the foster parent element is the first
element in the stack of open elements (the
html element). Otherwise, if there is a
table element in the stack of open
elements, but the last table element in the
stack of open elements has no parent, or its parent
node is not an element, then the foster parent element is
the element before the last table element in the
stack of open elements.
If the foster parent element is the parent element of the
last table element in the stack of open
elements, then node must be inserted
immediately before the last table element in
the stack of open elements in the foster parent
element; otherwise, node must be
appended to the foster parent element.
When the insertion mode is "initial", tokens must be handled as follows:
Ignore the token.
Append a Comment node to the Document
object with the data attribute set to the
data given in the comment token.
If the DOCTYPE token's name is not a
case-sensitive match for the string "html", or if the token's public identifier is
neither missing nor a case-sensitive match for the
string "XSLT-compat", or if the token's system
identifier is not missing, then there is a parse
error (this is the DOCTYPE parse
error). Conformance checkers may, instead of reporting this
error, switch to a conformance checking mode for another language
(e.g. based on the DOCTYPE token a conformance checker could
recognize that the document is an HTML4-era document, and defer to
an HTML4 conformance checker.)
Append a DocumentType node to the
Document node, with the name
attribute set to the name given in the DOCTYPE token; the publicId attribute set to the public identifier
given in the DOCTYPE token, or the empty string if the public
identifier was missing; the systemId
attribute set to the system identifier given in the DOCTYPE token,
or the empty string if the system identifier was missing; and the
other attributes specific to DocumentType objects set
to null and empty lists as appropriate. Associate the
DocumentType node with the Document
object so that it is returned as the value of the doctype attribute of the Document
object.
Then, if the DOCTYPE token matches one of the conditions in the following list, then set the document to quirks mode:
HTML". +//Silmaril//dtd html Pro v0r11 19970101//" -//AdvaSoft Ltd//DTD HTML 3.0 asWedit + extensions//" -//AS//DTD HTML 3.0 asWedit + extensions//" -//IETF//DTD HTML 2.0 Level 1//" -//IETF//DTD HTML 2.0 Level 2//" -//IETF//DTD HTML 2.0 Strict Level 1//" -//IETF//DTD HTML 2.0 Strict Level 2//" -//IETF//DTD HTML 2.0 Strict//" -//IETF//DTD HTML 2.0//" -//IETF//DTD HTML 2.1E//" -//IETF//DTD HTML 3.0//" -//IETF//DTD HTML 3.2 Final//" -//IETF//DTD HTML 3.2//" -//IETF//DTD HTML 3//" -//IETF//DTD HTML Level 0//" -//IETF//DTD HTML Level 1//" -//IETF//DTD HTML Level 2//" -//IETF//DTD HTML Level 3//" -//IETF//DTD HTML Strict Level 0//" -//IETF//DTD HTML Strict Level 1//" -//IETF//DTD HTML Strict Level 2//" -//IETF//DTD HTML Strict Level 3//" -//IETF//DTD HTML Strict//" -//IETF//DTD HTML//" -//Metrius//DTD Metrius Presentational//" -//Microsoft//DTD Internet Explorer 2.0 HTML Strict//" -//Microsoft//DTD Internet Explorer 2.0 HTML//" -//Microsoft//DTD Internet Explorer 2.0 Tables//" -//Microsoft//DTD Internet Explorer 3.0 HTML Strict//" -//Microsoft//DTD Internet Explorer 3.0 HTML//" -//Microsoft//DTD Internet Explorer 3.0 Tables//" -//Netscape Comm. Corp.//DTD HTML//" -//Netscape Comm. Corp.//DTD Strict HTML//" -//O'Reilly and Associates//DTD HTML 2.0//" -//O'Reilly and Associates//DTD HTML Extended 1.0//" -//O'Reilly and Associates//DTD HTML Extended Relaxed 1.0//" -//SoftQuad Software//DTD HoTMetaL PRO 6.0::19990601::extensions to HTML 4.0//" -//SoftQuad//DTD HoTMetaL PRO 4.0::19971010::extensions to HTML 4.0//" -//Spyglass//DTD HTML 2.0 Extended//" -//SQ//DTD HTML 2.0 HoTMetaL + extensions//" -//Sun Microsystems Corp.//DTD HotJava HTML//" -//Sun Microsystems Corp.//DTD HotJava Strict HTML//" -//W3C//DTD HTML 3 1995-03-24//" -//W3C//DTD HTML 3.2 Draft//" -//W3C//DTD HTML 3.2 Final//" -//W3C//DTD HTML 3.2//" -//W3C//DTD HTML 3.2S Draft//" -//W3C//DTD HTML 4.0 Frameset//" -//W3C//DTD HTML 4.0 Transitional//" -//W3C//DTD HTML Experimental 19960712//" -//W3C//DTD HTML Experimental 970421//" -//W3C//DTD W3 HTML//" -//W3O//DTD W3 HTML 3.0//" -//W3O//DTD W3 HTML Strict 3.0//EN//" -//WebTechs//DTD Mozilla HTML 2.0//" -//WebTechs//DTD Mozilla HTML//" -/W3C/DTD HTML 4.0 Transitional/EN" HTML" http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" -//W3C//DTD HTML 4.01 Frameset//" -//W3C//DTD HTML 4.01 Transitional//" Otherwise, if the DOCTYPE token matches one of the conditions in the following list, then set the document to limited quirks mode:
-//W3C//DTD XHTML 1.0 Frameset//" -//W3C//DTD XHTML 1.0 Transitional//" -//W3C//DTD HTML 4.01 Frameset//" -//W3C//DTD HTML 4.01 Transitional//" The name, system identifier, and public identifier strings must be compared to the values given in the lists above in an ASCII case-insensitive manner. A system identifier whose value is the empty string is not considered missing for the purposes of the conditions above.
Then, switch the insertion mode to "before html".
Set the document to quirks mode.
Switch the insertion mode to "before html", then reprocess the current token.
When the insertion mode is "before html", tokens must be handled as follows:
Parse error. Ignore the token.
Append a Comment node to the Document
object with the data attribute set to the
data given in the comment token.
Ignore the token.
Create an element for the token in the HTML
namespace. Append it to the Document
object. Put this element in the stack of open
elements.
If the token has an attribute "manifest", then resolve the value of that attribute to an absolute URL, and if that is successful, run the application cache selection algorithm with the resulting absolute URL. Otherwise, if there is no such attribute or resolving it fails, run the application cache selection algorithm with no manifest.
Switch the insertion mode to "before head".
Create an HTMLElement node with the tag name
html, in the HTML namespace. Append it
to the Document object. Put this element in the
stack of open elements.
Run the application cache selection algorithm with no manifest.
Switch the insertion mode to "before head", then reprocess the current token.
Should probably make end tags be ignored, so that "</head><!-- --><html>" puts the comment before the root node (or should we?)
The root element can end up being removed from the
Document object, e.g. by scripts; nothing in particular
happens in such cases, content continues being appended to the nodes
as described in the next section.
When the insertion mode is "before head", tokens must be handled as follows:
Ignore the token.
Append a Comment node to the current
node with the data attribute set to
the data given in the comment token.
Parse error. Ignore the token.
Process the token using the rules for the "in body" insertion mode.
Insert an HTML element for the token.
Set the head element pointer
to the newly created head element.
Switch the insertion mode to "in head".
Act as if a start tag token with the tag name "head" and no attributes had been seen, then reprocess the current token.
Parse error. Ignore the token.
Act as if a start tag token with the tag name "head" and no attributes had been seen, then reprocess the current token.
This will result in an empty head
element being generated, with the current token being
reprocessed in the "after head" insertion mode.
When the insertion mode is "in head", tokens must be handled as follows:
Insert the character into the current node.
Append a Comment node to the current
node with the data attribute set to
the data given in the comment token.
Parse error. Ignore the token.
Process the token using the rules for the "in body" insertion mode.
Insert an HTML element for the token. Immediately pop the current node off the stack of open elements.
Acknowledge the token's self-closing flag, if it is set.
Insert an HTML element for the token. Immediately pop the current node off the stack of open elements.
Acknowledge the token's self-closing flag, if it is set.
If the element has a charset attribute, and its
value is a supported encoding, and the confidence is
currently tentative, then change the
encoding to the encoding given by the value of the
charset attribute.
Otherwise, if the element has a content attribute, and
applying the algorithm for extracting an encoding from a
Content-Type to its value returns a supported encoding
encoding, and the confidence is
currently tentative, then change the
encoding to the encoding encoding.
Follow the generic RCDATA element parsing algorithm.
Follow the generic CDATA element parsing algorithm.
Insert an HTML element for the token.
Switch the insertion mode to "in head noscript".
Mark the element as being "parser-inserted".
This ensures that, if the script is external, any
document.write()
calls in the script will execute in-line, instead of blowing the
document away, as would happen in most other cases. It also
prevents the script from executing until the end tag is seen.
If the parser was originally created for the HTML
fragment parsing algorithm, then mark the
script element as "already
executed". (fragment case)
Append the new element to the current node.
Switch the tokeniser's content model flag to the CDATA state.
Let the original insertion mode be the current insertion mode.
Switch the insertion mode to "in CDATA/RCDATA".
Pop the current node (which will be the
head element) off the stack of open
elements.
Switch the insertion mode to "after head".
Act as described in the "anything else" entry below.
Parse error. Ignore the token.
Act as if an end tag token with the tag name "head" had been seen, and reprocess the current token.
In certain UAs, some elements don't trigger the "in body" mode straight away, but instead get put into the head. Do we want to copy that?
When the insertion mode is "in head noscript", tokens must be handled as follows:
Parse error. Ignore the token.
Process the token using the rules for the "in body" insertion mode.
Pop the current node (which will be a
noscript element) from the stack of open
elements; the new current node will be a
head element.
Switch the insertion mode to "in head".
Process the token using the rules for the "in head" insertion mode.
Act as described in the "anything else" entry below.
Parse error. Ignore the token.
Parse error. Act as if an end tag with the tag name "noscript" had been seen and reprocess the current token.
When the insertion mode is "after head", tokens must be handled as follows:
Insert the character into the current node.
Append a Comment node to the current
node with the data attribute set to
the data given in the comment token.
Parse error. Ignore the token.
Process the token using the rules for the "in body" insertion mode.
Insert an HTML element for the token.
Switch the insertion mode to "in body".
Insert an HTML element for the token.
Switch the insertion mode to "in frameset".
Push the node pointed to by the head element pointer onto the
stack of open elements.
Process the token using the rules for the "in head" insertion mode.
Remove the node pointed to by the head element pointer from the stack
of open elements.
Parse error. Ignore the token.
Act as if a start tag token with the tag name "body" and no attributes had been seen, and then reprocess the current token.
When the insertion mode is "in body", tokens must be handled as follows:
Reconstruct the active formatting elements, if any.
Insert the token's character into the current node.
Append a Comment node to the current
node with the data attribute set to
the data given in the comment token.
Parse error. Ignore the token.
Parse error. For each attribute on the token, check to see if the attribute is already present on the top element of the stack of open elements. If it is not, add the attribute and its corresponding value to that element.
Process the token using the rules for the "in head" insertion mode.
If the second element on the stack of open
elements is not a body element, or, if the
stack of open elements has only one node on it,
then ignore the token. (fragment case)
Otherwise, for each attribute on the token, check to see if
the attribute is already present on the body
element (the second element) on the stack of open
elements. If it is not, add the attribute and its
corresponding value to that element.
If there is a node in the stack of open elements
that is not either a dd element, a dt
element, an li element, a p element, a
tbody element, a td element, a
tfoot element, a th element, a
thead element, a tr element, the
body element, or the html element, then
this is a parse error.
If the stack of open elements does not have a body element
in scope, this is a parse error; ignore the
token.
Otherwise, if there is a node in the stack of open
elements that is not either a dd element, a
dt element, an li element, a
p element, a tbody element, a
td element, a tfoot element, a
th element, a thead element, a
tr element, the body element, or the
html element, then this is a parse
error.
Switch the insertion mode to "after body".
Act as if an end tag with tag name "body" had been seen, then, if that token wasn't ignored, reprocess the current token.
The fake end tag token here can only be ignored in the fragment case.
If the stack of open elements has a p element in
scope, then act as if an end tag with the tag name
"p" had been seen.
Insert an HTML element for the token.
If the stack of open elements has a p element in
scope, then act as if an end tag with the tag name
"p" had been seen.
If the current node is an element whose tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then this is a parse error; pop the current node off the stack of open elements.
Insert an HTML element for the token.
If the stack of open elements has a p element in
scope, then act as if an end tag with the tag name
"p" had been seen.
Insert an HTML element for the token.
If the next token is a U+000A LINE FEED (LF) character
token, then ignore that token and move on to the next
one. (Newlines at the start of pre blocks are
ignored as an authoring convenience.)
If the form element
pointer is not null, then this is a parse
error; ignore the token.
Otherwise:
If the stack of open elements has a p element in
scope, then act as if an end tag with the tag name
"p" had been seen.
Insert an HTML element for the token, and set the
form element pointer to
point to the element created.
Run the following algorithm:
Initialize node to be the current node (the bottommost node of the stack).
If node is an li element,
then act as if an end tag with the tag name "li" had
been seen, then jump to the last step.
If node is not in the
formatting category, and is not in the
phrasing category, and is not an
address, div, or p
element, then jump to the last step.
Otherwise, set node to the previous entry in the stack of open elements and return to step 2.
This is the last step.
If the stack of open elements has a p element in
scope, then act as if an end tag with the tag name
"p" had been seen.
Finally, insert an HTML element for the token.
Run the following algorithm:
Initialize node to be the current node (the bottommost node of the stack).
If node is a dd or
dt element, then act as if an end tag with the same
tag name as node had been seen, then jump to
the last step.
If node is not in the
formatting category, and is not in the
phrasing category, and is not an
address, div, or p
element, then jump to the last step.
Otherwise, set node to the previous entry in the stack of open elements and return to step 2.
This is the last step.
If the stack of open elements has a p element in
scope, then act as if an end tag with the tag name
"p" had been seen.
Finally, insert an HTML element for the token.
If the stack of open elements has a p element in
scope, then act as if an end tag with the tag name
"p" had been seen.
Insert an HTML element for the token.
Switch the content model flag to the PLAINTEXT state.
Once a start tag with the tag name "plaintext" has been seen, that will be the last token ever seen other than character tokens (and the end-of-file token), because there is no way to switch the content model flag out of the PLAINTEXT state.
If the stack of open elements does not have an element in scope with the same tag name as that of the token, then this is a parse error; ignore the token.
Otherwise, run these steps:
If the current node is not an element with the same tag name as that of the token, then this is a parse error.
Pop elements from the stack of open elements until an element with the same tag name as the token has been popped from the stack.
Let node be the element that the
form element pointer is set
to.
Set the form element pointer
to null.
If node is null or the stack of open elements does not have node in scope, then this is a parse error; ignore the token.
Otherwise, run these steps:
If the current node is not node, then this is a parse error.
Remove node from the stack of open elements.
If the stack of open elements does not have an element in scope
with the same tag name as that of the token, then this is a
parse error; act as if a start tag with the tag name
p had been seen, then reprocess the current
token.
Otherwise, run these steps:
Generate implied end tags, except for elements with the same tag name as the token.
If the current node is not an element with the same tag name as that of the token, then this is a parse error.
Pop elements from the stack of open elements until an element with the same tag name as the token has been popped from the stack.
If the stack of open elements does not have an element in scope with the same tag name as that of the token, then this is a parse error; ignore the token.
Otherwise, run these steps:
Generate implied end tags, except for elements with the same tag name as the token.
If the current node is not an element with the same tag name as that of the token, then this is a parse error.
Pop elements from the stack of open elements until an element with the same tag name as the token has been popped from the stack.
If the stack of open elements does not have an element in scope whose tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then this is a parse error; ignore the token.
Otherwise, run these steps:
If the current node is not an element with the same tag name as that of the token, then this is a parse error.
Pop elements from the stack of open elements until an element whose tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6" has been popped from the stack.
Take a deep breath, then act as described in the "any other end tag" entry below.
If the list of active formatting elements contains an element whose tag name is "a" between the end of the list and the last marker on the list (or the start of the list if there is no marker on the list), then this is a parse error; act as if an end tag with the tag name "a" had been seen, then remove that element from the list of active formatting elements and the stack of open elements if the end tag didn't already remove it (it might not have if the element is not in table scope).
In the non-conforming stream
<a href="a">a<table><a href="b">b</table>x,
the first a element would be closed upon seeing
the second one, and the "x" character would be inside a link
to "b", not to "a". This is despite the fact that the outer
a element is not in table scope (meaning that a
regular </a> end tag at the start of the table
wouldn't close the outer a element).
Reconstruct the active formatting elements, if any.
Insert an HTML element for the token. Add that element to the list of active formatting elements.
Reconstruct the active formatting elements, if any.
Insert an HTML element for the token. Add that element to the list of active formatting elements.
Reconstruct the active formatting elements, if any.
If the stack of open elements has a nobr element in scope,
then this is a parse error; act as if an end tag with
the tag name "nobr" had been seen, then once again
reconstruct the active formatting elements, if
any.
Insert an HTML element for the token. Add that element to the list of active formatting elements.
Follow these steps:
Let the formatting element be the last element in the list of active formatting elements that:
If there is no such node, or, if that node is also in the stack of open elements but the element is not in scope, then this is a parse error; ignore the token, and abort these steps.
Otherwise, if there is such a node, but that node is not in the stack of open elements, then this is a parse error; remove the element from the list, and abort these steps.
Otherwise, there is a formatting element and that element is in the stack and is in scope. If the element is not the current node, this is a parse error. In any case, proceed with the algorithm as written in the following steps.
Let the furthest block be the topmost node in the stack of open elements that is lower in the stack than the formatting element, and is not an element in the phrasing or formatting categories. There might not be one.
If there is no furthest block, then the UA must skip the subsequent steps and instead just pop all the nodes from the bottom of the stack of open elements, from the current node up to and including the formatting element, and remove the formatting element from the list of active formatting elements.
Let the common ancestor be the element immediately above the formatting element in the stack of open elements.
If the furthest block has a parent node, then remove the furthest block from its parent node.
Let a bookmark note the position of the formatting element in the list of active formatting elements relative to the elements on either side of it in the list.
Let node and last node be the furthest block. Follow these steps:
If the common ancestor node is a
table, tbody, tfoot,
thead, or tr element, then,
foster parent whatever last
node ended up being in the previous step.
Otherwise, append whatever last node ended up being in the previous step to the common ancestor node, first removing it from its previous parent node if any.
Perform a shallow clone of the formatting element.
Take all of the child nodes of the furthest block and append them to the clone created in the last step.
Append that clone to the furthest block.
Remove the formatting element from the list of active formatting elements, and insert the clone into the list of active formatting elements at the position of the aforementioned bookmark.
Remove the formatting element from the stack of open elements, and insert the clone into the stack of open elements immediately below the position of the furthest block in that stack.
Jump back to step 1 in this series of steps.
The way these steps are defined, only elements in the formatting category ever get cloned by this algorithm.
Because of the way this algorithm causes elements to change parents, it has been dubbed the "adoption agency algorithm" (in contrast with other possibly algorithms for dealing with misnested content, which included the "incest algorithm", the "secret affair algorithm", and the "Heisenberg algorithm").
If the stack of open elements has a button element in
scope, then this is a parse error;
act as if an end tag with the tag name "button" had been seen,
then reprocess the token.
Otherwise:
Reconstruct the active formatting elements, if any.
Insert an HTML element for the token.
Insert a marker at the end of the list of active formatting elements.
Reconstruct the active formatting elements, if any.
Insert an HTML element for the token.
Insert a marker at the end of the list of active formatting elements.
If the stack of open elements does not have an element in scope with the same tag name as that of the token, then this is a parse error; ignore the token.
Otherwise, run these steps:
If the current node is not an element with the same tag name as that of the token, then this is a parse error.
Pop elements from the stack of open elements until an element with the same tag name as the token has been popped from the stack.
Reconstruct the active formatting elements, if any.
Follow the generic CDATA element parsing algorithm.
If the stack of open elements has a p element in
scope, then act as if an end tag with the tag name
"p" had been seen.
Insert an HTML element for the token.
Switch the insertion mode to "in table".
Reconstruct the active formatting elements, if any.
Insert an HTML element for the token. Immediately pop the current node off the stack of open elements.
Acknowledge the token's self-closing flag, if it is set.
Insert an HTML element for the token. Immediately pop the current node off the stack of open elements.
Acknowledge the token's self-closing flag, if it is set.
If the stack of open elements has a p element in
scope, then act as if an end tag with the tag name
"p" had been seen.
Insert an HTML element for the token. Immediately pop the current node off the stack of open elements.
Acknowledge the token's self-closing flag, if it is set.
Parse error. Change the token's tag name to "img" and reprocess it. (Don't ask.)
If the form element
pointer is not null, then ignore the token.
Otherwise:
Acknowledge the token's self-closing flag, if it is set.
Act as if a start tag token with the tag name "form" had been seen.
If the token has an attribute called "action", set the
action attribute on the
resulting form element to the value of the
"action" attribute of the token.
Act as if a start tag token with the tag name "hr" had been seen.
Act as if a start tag token with the tag name "p" had been seen.
Act as if a start tag token with the tag name "label" had been seen.
Act as if a stream of character tokens had been seen (see below for what they should say).
Act as if a start tag token with the tag name "input" had been
seen, with all the attributes from the "isindex" token except
"name", "action", and "prompt". Set the name attribute of the resulting
input element to the value "isindex".
Act as if a stream of character tokens had been seen (see below for what they should say).
Act as if an end tag token with the tag name "label" had been seen.
Act as if an end tag token with the tag name "p" had been seen.
Act as if a start tag token with the tag name "hr" had been seen.
Act as if an end tag token with the tag name "form" had been seen.
If the token has an attribute with the name "prompt", then the
first stream of characters must be the same string as given in
that attribute, and the second stream of characters must be
empty. Otherwise, the two streams of character tokens together
should, together with the input element, express the
equivalent of "This is a searchable index. Insert your search
keywords here: (input field)" in the user's preferred
language.
Insert an HTML element for the token.
If the next token is a U+000A LINE FEED (LF) character
token, then ignore that token and move on to the next
one. (Newlines at the start of textarea elements are
ignored as an authoring convenience.)
Append the new element to the current node.
Switch the tokeniser's content model flag to the RCDATA state.
Let the original insertion mode be the current insertion mode.
Switch the insertion mode to "in CDATA/RCDATA".
Follow the generic CDATA element parsing algorithm.
Reconstruct the active formatting elements, if any.
Insert an HTML element for the token.
If the insertion mode is one of in table", "in caption", "in column group", "in table body", "in row", or "in cell", then switch the insertion mode to "in select in table". Otherwise, switch the insertion mode to "in select".
If the stack of open elements has an option element in
scope, then act as if an end tag with the tag name "option"
had been seen.
Reconstruct the active formatting elements, if any.
Insert an HTML element for the token.
If the stack of open elements has a ruby element in scope,
then generate implied end tags. If the current
node is not then a ruby element, this is a
parse error; pop all the nodes from the current
node up to the node immediately before the bottommost
ruby element on the stack of open
elements.
Insert an HTML element for the token.
Parse error. Act as if a start tag token with the tag name "br" had been seen. Ignore the end tag token.
Reconstruct the active formatting elements, if any.
Adjust MathML attributes for the token. (This fixes the case of MathML attributes that are not all lowercase.)
Adjust foreign attributes for the token. (This fixes the use of namespaced attributes, in particular XLink.)
Insert a foreign element for the token, in the MathML namespace.
If the token has its self-closing flag set, pop the current node off the stack of open elements and acknowledge the token's self-closing flag.
Otherwise, let the secondary insertion mode be the current insertion mode, and then switch the insertion mode to "in foreign content".
Parse error. Ignore the token.
Reconstruct the active formatting elements, if any.
Insert an HTML element for the token.
This element will be a phrasing element.
Run the following steps:
Initialize node to be the current node (the bottommost node of the stack).
If node has the same tag name as the end tag token, then:
If the tag name of the end tag token does not match the tag name of the current node, this is a parse error.
Pop all the nodes from the current node up to node, including node, then stop these steps.
Otherwise, if node is in neither the formatting category nor the phrasing category, then this is a parse error; ignore the token, and abort these steps.
Set node to the previous entry in the stack of open elements.
Return to step 2.
When the insertion mode is "in CDATA/RCDATA", tokens must be handled as follows:
Insert the token's character into the current node.
If the current node is a script
element, mark the script element as "already
executed".
Pop the current node off the stack of open elements.
Switch the insertion mode to the original insertion mode and reprocess the current token.
Let script be the current node
(which will be a script element).
Pop the current node off the stack of open elements.
Switch the insertion mode to the original insertion mode.
Let the old insertion point have the same value as the current insertion point. Let the insertion point be just before the next input character.
Increment the parser's script nesting level by one.
Run the script. This might cause some script to execute, which might cause new characters to be inserted into the tokeniser, and might cause the tokeniser to output more tokens, resulting in a reentrant invocation of the parser.
Decrement the parser's script nesting level by one. If the parser's script nesting level is zero, then set the parser pause flag to false.
Let the insertion point have the value of the old insertion point. (In other words, restore the insertion point to the value it had before the previous paragraph. This value might be the "undefined" value.)
At this stage, if there is a pending external script, then:
document.write():Set the parser pause flag to true, and abort the processing of any nested invocations of the tokeniser, yielding control back to the caller. (Tokenization will resume when the caller returns to the "outer" tree construction stage.)
Follow these steps:
Let the script be the pending external script. There is no longer a pending external script.
Pause until the script has completed loading.
Let the insertion point be just before the next input character.
Let the insertion point be undefined again.
If there is once again a pending external script, then repeat these steps from step 1.
Pop the current node off the stack of open elements.
Switch the insertion mode to the original insertion mode.
When the insertion mode is "in table", tokens must be handled as follows:
If the current table is tainted, then act as described in the "anything else" entry below.
Otherwise, insert the character into the current node.
Append a Comment node to the current
node with the data attribute set to
the data given in the comment token.
Parse error. Ignore the token.
Clear the stack back to a table context. (See below.)
Insert a marker at the end of the list of active formatting elements.
Insert an HTML element for the token, then switch the insertion mode to "in caption".
Clear the stack back to a table context. (See below.)
Insert an HTML element for the token, then switch the insertion mode to "in column group".
Act as if a start tag token with the tag name "colgroup" had been seen, then reprocess the current token.
Clear the stack back to a table context. (See below.)
Insert an HTML element for the token, then switch the insertion mode to "in table body".
Act as if a start tag token with the tag name "tbody" had been seen, then reprocess the current token.
Parse error. Act as if an end tag token with the tag name "table" had been seen, then, if that token wasn't ignored, reprocess the current token.
The fake end tag token here can only be ignored in the fragment case.
If the stack of open elements does not have an element in table scope with the same tag name as the token, this is a parse error. Ignore the token. (fragment case)
Otherwise:
Pop elements from this stack until a table
element has been popped from the stack.
Parse error. Ignore the token.
If the current table is tainted then act as described in the "anything else" entry below.
Otherwise, process the token using the rules for the "in head" insertion mode.
If the token does not have an attribute with the name "type",
or if it does, but that attribute's value is not an ASCII
case-insensitive match for the string "hidden", or, if the current table is
tainted, then: act as described in the "anything
else" entry below.
Otherwise:
Insert an HTML element for the token.
Pop that input element off the stack of
open elements.
If the current node is not the root
html element, then this is a parse
error.
It can only be the current node in the fragment case.
Parse error. Process the token using the
rules for the "in
body" insertion mode, except that if the
current node is a table,
tbody, tfoot, thead, or
tr element, then, whenever a node would be inserted
into the current node, it must instead be foster parented.
When the steps above require the UA to clear the stack
back to a table context, it means that the UA must, while
the current node is not a table
element or an html element, pop elements from the
stack of open elements.
The current node being an
html element after this process is a fragment
case.
When the insertion mode is "in caption", tokens must be handled as follows:
If the stack of open elements does not have an element in table scope with the same tag name as the token, this is a parse error. Ignore the token. (fragment case)
Otherwise:
Now, if the current node is not a
caption element, then this is a parse
error.
Pop elements from this stack until a caption
element has been popped from the stack.
Clear the list of active formatting elements up to the last marker.
Switch the insertion mode to "in table".
Parse error. Act as if an end tag with the tag name "caption" had been seen, then, if that token wasn't ignored, reprocess the current token.
The fake end tag token here can only be ignored in the fragment case.
Parse error. Ignore the token.
Process the token using the rules for the "in body" insertion mode.
When the insertion mode is "in column group", tokens must be handled as follows:
Insert the character into the current node.
Append a Comment node to the current
node with the data attribute set to
the data given in the comment token.
Parse error. Ignore the token.
Process the token using the rules for the "in body" insertion mode.
Insert an HTML element for the token. Immediately pop the current node off the stack of open elements.
Acknowledge the token's self-closing flag, if it is set.
If the current node is the root
html element, then this is a parse
error; ignore the token. (fragment
case)
Otherwise, pop the current node (which will be
a colgroup element) from the stack of open
elements. Switch the insertion mode to
"in table".
Parse error. Ignore the token.
If the current node is the root html
element, then stop parsing. (fragment
case)
Otherwise, act as described in the "anything else" entry below.
Act as if an end tag with the tag name "colgroup" had been seen, and then, if that token wasn't ignored, reprocess the current token.
The fake end tag token here can only be ignored in the fragment case.