travil@1:  travil@1: travil@1: travil@1: travil@1: DOM Parsing and Serialization travil@1: travil@8: travil@1: travil@1: travil@1: travil@1: travil@1:
travil@1:

This specification defines various APIs for programmatic access to travil@1: HTML and generic XML parsers by web applications for use in parsing travil@24: and serializing DOM nodes.

travil@1:
travil@1: travil@24:
travil@24:

This specification is based on the original work of the travil@31: DOM Parsing and Serialization Living Specification, though it has diverged in terms of travil@24: supported features, normative requirements, and algorithm specificity. As appropriate, travil@31: relevant fixes from the living specification are incorporated into this document. travil@24:

travil@1: travil@1: travil@3:
travil@1:

Issues

travil@1: travil@13:

Open issues that appear throughout the remainder of this travil@13: document will be highlighted like this.

travil@1:
travil@1: travil@1:
travil@1:

Requirements phrased in the imperative as part of algorithms travil@1: (such as "strip any leading space characters" or "return false and travil@1: terminate these steps") are to be interpreted with the meaning of the travil@1: key word ("must", "should", "may", etc) used in introducing the travil@1: algorithm.

travil@1: travil@1:

Conformance requirements phrased as algorithms or specific steps travil@1: may be implemented in any manner, so long as the end result is travil@1: equivalent. (In particular, the algorithms defined in this travil@1: specification are intended to be easy to follow, and not intended to travil@1: be performant.)

travil@1: travil@1:

User agents may impose travil@1: implementation-specific limits on otherwise unconstrained inputs, travil@1: e.g. to prevent denial of service attacks, to guard against running travil@1: out of memory, or to work around platform-specific limitations.

travil@1: travil@1:

When a method or an attribute is said to call another method or travil@1: attribute, the user agent must invoke its internal API for that travil@1: attribute or method so that e.g. the author can't change the behavior travil@1: by overriding attributes or methods with custom properties or functions travil@1: in ECMAScript.

travil@1: travil@1:

Unless otherwise stated, string comparisons are done in a travil@1: case-sensitive manner.

travil@1: travil@1:

If an algorithm calls into another algorithm, any exception that is travil@1: thrown by the latter (unless it is explicitly caught), must cause the travil@1: former to terminate, and the exception to be propagated up to travil@1: its caller.

travil@1: travil@1:
travil@1:

Dependencies

travil@1: travil@1:

The IDL fragments in this specification must be interpreted as travil@1: required for conforming IDL fragments, as described in the Web IDL travil@1: specification. [[!WEBIDL]]

travil@1: travil@1:

Some of the terms used in this specification are defined in travil@1: [[DOM4]], [[HTML5]], and [[XML10]]. travil@1:

travil@1: travil@1:
travil@1:

Extensibility

travil@1: travil@1:

Vendor-specific proprietary extensions to this specification are travil@1: strongly discouraged. Authors must not use such extensions, as travil@1: doing so reduces interoperability and fragments the user base, travil@1: allowing only users of specific user agents to access the content in travil@1: question.

travil@1: travil@1:

If vendor-specific extensions are needed, the members should be travil@1: prefixed by vendor-specific strings to prevent clashes with future travil@1: versions of this specification. Extensions must be defined so that travil@1: the use of extensions neither contradicts nor causes the travil@1: non-conformance of functionality defined in the specification.

travil@1: travil@1:

When vendor-neutral extensions to this specification are needed, travil@1: either this specification can be updated accordingly, or an travil@1: extension specification can be written that overrides the travil@1: requirements in this specification. When someone applying this travil@1: specification to their activities decides that they will recognise travil@1: the requirements of such an extension specification, it becomes an travil@1: applicable travil@1: specification for the purposes of conformance requirements in travil@1: this specification.

travil@1: travil@1:
travil@1:
travil@1: travil@1:
travil@1:

Terminology

travil@1: travil@1:

The term context object means the object on which the method or travil@1: attribute being discussed was called. travil@1:

travil@1: travil@38:
travil@38:

Namespaces

travil@38: travil@38:

The HTML namespace is http://www.w3.org/1999/xhtml. travil@38:

The XML namespace is http://www.w3.org/XML/1998/namespace. travil@38:

The XMLNS namespace is http://www.w3.org/2000/xmlns/. travil@38:

travil@1: travil@1:
travil@1:

Parsing and serializing Nodes

travil@1: travil@1:
travil@1:

Parsing

travil@1: travil@1:

The following steps form the travil@1: fragment parsing algorithm, whose travil@1: arguments are a markup string and a travil@1: context element. travil@1: travil@1:

    travil@1:
  1. travil@1:

    If the context element's travil@1: node document travil@1: is an HTML document: let travil@1: algorithm be the travil@1: HTML travil@1: fragment parsing algorithm.

    travil@1: travil@1:

    If the context element's travil@1: node document travil@1: is an XML document: let travil@1: algorithm be the travil@1: XML travil@1: fragment parsing algorithm.

    travil@1:
  2. travil@1: travil@1:
  3. Invoke algorithm with markup as travil@1: the input, and context element as the travil@1: context travil@1: element.
  4. travil@1: travil@1:
  5. Let new children be the nodes returned.
  6. travil@1: travil@1:
  7. Let fragment be a new travil@1: DocumentFragment whose travil@1: node document travil@1: is context element's travil@1: node document. travil@1: travil@1:
  8. Append travil@1: each node in travil@1: new children to fragment (in order). travil@1: travil@1:

    This ensures the travil@1: node document tleithea@34: for the new nodes is correct. travil@1: travil@1:

  9. Return fragment. travil@1:
travil@1:
travil@1: travil@1:
travil@1:

Serializing

travil@49:

The following steps form the travil@49: fragment serializing algorithm, travil@55: whose arguments are a Node travil@50: node and a flag require well-formed. travil@1: travil@1:

    travil@49:
  1. Let context document be node's travil@18: node document. travil@49:
  2. If context document is an travil@18: HTML document, tleithea@34: return an HTML serialization of node. travil@49:
  3. Otherwise, context document is an travil@49: XML document; travil@49: return an XML serialization of node travil@50: passing the flag require well-formed. travil@49:

    The XML serialization defined in this document travil@49: conforms to the requirements of the XML fragment serialization algorithm defined in [[HTML5]].

    travil@49:
travil@49: travil@49:

To produce an HTML serialization of a travil@55: Node node, the user agent travil@49: must run the travil@49: HTML travil@49: fragment serialization algorithm [[!HTML5]] on node and return the string produced. travil@49: travil@49:

To produce an XML serialization of a travil@55: Node node given a travil@50: flag require well-formed, run the following steps: travil@49:

    travil@38:
  1. Let context namespace be null. travil@41: The context namespace is changed when a travil@49: node serializes a different default namespace definition from its parent. The travil@49: algorithm assumes no namespace to start. travil@38:
  2. Let namespace prefix map be a new map travil@38: for associating namespaceURI and namespace prefix pairs, where travil@38: namespaceURI values are the map's keys, and prefix values are travil@38: the map's key values. The namespace prefix map travil@39: will be populated by previously seen namespaceURIs and their most recent prefix associations travil@39: for a subtree. Note: the travil@38: namespace prefix map only associates a single travil@39: prefix value with a given namespaceURI. During serialization, if different namespace prefixes travil@39: are found that map to the same namespaceURI, the last one encountered "wins" by replacing the travil@38: existing key value in the map with the new prefix value. travil@39:
  3. Initialize the namespace prefix map with the travil@39: XML namespace key and string "xml" as the key value. travil@38:
  4. Let generated namespace prefix index be an integer travil@38: with a value of 1. The generated namespace travil@39: prefix index is used to generate a new unique prefix value when no suitable existing travil@39: namespace prefix is available to serialize a node's namespaceURI (or the namespaceURI travil@39: of one of node's attributes). See the travil@39: generate a prefix algorithm. travil@49:
  5. Return the result of running the XML serialization travil@49: algorithm on node passing the context travil@49: namespace, namespace prefix map, travil@49: generated namespace prefix index reference, and the travil@50: flag require well-formed. If an exception travil@49: occurs during the execution of the algorithm, then catch that exception and throw a travil@49: DOMException with travil@49: name InvalidStateError. travil@1:
travil@49: travil@38:

An XML serialization differs from an travil@38: HTML serialization in the following ways: tleithea@35:

travil@38: travil@39:

Otherwise, the algorithm for producing an XML serialization travil@39: is designed to produce a serialization that is compatible with the travil@39: HTML parser. For example, travil@39: elements in the HTML namespace that contain no child nodes are serialized travil@39: with an explicit begin and end tag rather than using the self-closing tag syntax [[XML10]]. travil@38: travil@55:

Per [[DOM4]], Attr travil@55: objects do not inherit from Node, and thus cannot travil@52: be serialized by the XML serialization algorithm. travil@55: An attempt to serialize an Attr travil@55: object will result in a TypeError exception [[WEBIDL]]. travil@52: travil@49:

To run the XML serialization algorithm on travil@49: a node given a context namespace travil@49: namespace, a namespace prefix map travil@49: prefix map, a generated namespace prefix index travil@50: prefix index, and a flag require well-formed, the user agent must run the travil@49: appropriate steps, depending on node's interface:

travil@49: travil@1:
travil@51:
Element travil@1:
travil@18:

Run the following algorithm: travil@1:

    travil@41: travil@42: travil@41: travil@50: travil@50:
  1. If the require well-formed flag is set (its value is travil@50: true), and this node's travil@50: localName travil@50: attribute contains the character ":" (U+003A COLON) or does not match the travil@50: XML Name production [[XML10]], then throw an travil@50: exception; the serialization of this node would not be a well-formed element. travil@41:
  2. Let markup be the string "<" (U+003C LESS-THAN SIGN). travil@36:
  3. Let qualified name be an empty string. travil@41:
  4. Let a skip end tag flag have the value false. travil@41:
  5. Let an ignore namespace definition attribute flag have the value false. travil@42:
  6. Let map be a copy of the prefix map namespace prefix map. travil@38:
  7. Let element prefixes list be an empty list. This list is travil@38: local to each element. Its purpose is to ensure that there are no conflicting prefixes travil@38: should a new namespace prefix attribute need to be generated. travil@42:
  8. Let duplicate prefix definition be null. travil@41:
  9. Let local default namespace be the result of travil@41: recording the namespace information for travil@41: node given map, element prefixes list, and travil@42: duplicate prefix definition. travil@38:

    This above step will update the map with any found namespace prefix travil@41: definitions, add the found prefix definitions to the element prefixes list, optionally travil@42: set the duplicate prefix definition value, and return a local default namespace travil@41: value defined by a default namespace attribute if one exists. Otherwise it returns travil@41: null.

    travil@41:
  10. Let inherited ns be a copy of namespace. travil@18:
  11. Let ns be the value of node's tleithea@34: namespaceURI travil@18: attribute. travil@41:
  12. If inherited ns is equal to ns, then: travil@39:
      travil@41:
    1. If local default namespace is not null, then set ignore travil@41: namespace definition attribute to true. travil@39:
    2. If ns is the XML namespace, then let qualified name travil@39: be the concatenation of the string "xml:" and the value of node's travil@55: localName. travil@41:
    3. Otherwise, let qualified name be the value of node's travil@55: localName. travil@42: The node's prefix is always dropped. travil@41:
    4. Append the value of qualified name to markup. travil@39:
    travil@41:
  13. Otherwise, inherited ns is not equal to ns (the node's travil@41: own namespace is different from the context namespace of its parent). Run these sub-steps: travil@41: travil@38:
      travil@41:
    1. Let prefix be the value of node's travil@41: prefix travil@41: attribute. travil@38:
    2. Let candidate prefix be a value from map where there exists a key in travil@39: map that matches the value of ns or if there is no such key, then let travil@39: candidate prefix be null. travil@39: travil@42:
    3. If candidate prefix is not null (a suitable namespace prefix is defined travil@42: which maps to ns), then: travil@18:
        travil@41:
      1. Let qualified name be the concatenation of candidate prefix, travil@42: ":" (U+003A COLON), and localName. travil@42: There exists on this node or the node's ancestry a travil@42: namespace prefix definition that defines the node's namespace. travil@42:
      2. If local default namespace is not null (there exists a locally-defined travil@42: default namespace declaration attribute), then let inherited ns get the value of travil@42: ns. travil@41:
      3. Append the value of qualified name to markup. travil@38:
      travil@41: travil@41:
    4. Otherwise, if prefix is not null and local default namespace is travil@41: null, then: travil@39:
        travil@41:
      1. If the element prefixes list contains the value of prefix, then travil@41: let prefix be the result of travil@38: generating a prefix providing as input the travil@38: namespace prefix map map, travil@38: node's ns string, and the prefix index integer. travil@41:
      2. Otherwise, append to map a new key ns whose key value is travil@41: prefix. travil@41: travil@41:
      3. Let qualified name be the concatenation travil@41: of prefix, ":" (U+003A COLON), and travil@41: localName. travil@41:
      4. Append the value of qualified name to markup. travil@42:
      5. Append the following to markup, in order: The following travil@42: serializes the new namespace/prefix association just added to the map. travil@18:
          travil@41:
        1. " " (U+0020 SPACE); travil@38:
        2. the string "xmlns:"; travil@41:
        3. the value of prefix; travil@18:
        4. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); travil@41:
        5. The result of serializing an attribute value travil@50: given ns and the require well-formed flag travil@50: as input; travil@18:
        6. """ (U+0022 QUOTATION MARK); travil@18:
        travil@18:
      travil@41: travil@41:
    5. Otherwise, if local default namespace is null, or local default travil@41: namespace is not null and its value is not equal to ns, then: travil@41:
        travil@41:
      1. Set the ignore namespace definition attribute flag to true. travil@41:
      2. Let qualified name be the node's localName. travil@42:
      3. Let the value of inherited ns be ns. The new travil@42: default namespace will be used in the serialization to define this node's travil@42: namespace and act as the context namespace for its children. travil@41:
      4. Append the value of qualified name to markup. travil@42:
      5. Append the following to markup, in order: The following travil@42: serializes the new (or replacement) default namespace definition. travil@41:
          travil@41:
        1. " " (U+0020 SPACE); travil@41:
        2. the string "xmlns"; travil@41:
        3. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); travil@41:
        4. The result of serializing an attribute value travil@50: given ns and the require well-formed flag travil@50: as input; travil@41:
        5. """ (U+0022 QUOTATION MARK); travil@41:
        travil@41:
      travil@41: travil@42:
    6. Otherwise, the node has a local default namespace that matches travil@42: ns. Let qualified name be the node's travil@42: localName, travil@42: let the value of inherited ns be ns, and append the value of travil@42: qualified name to markup. travil@38:
    travil@41:
  14. Append to markup the result of the travil@38: XML serialization of node's travil@39: attributes given the travil@41: namespace prefix map map, travil@41: the generated prefix index prefix index, the travil@42: flag ignore namespace definition attribute and the value of duplicate travil@42: prefix definition. travil@38:
  15. If ns is the HTML namespace, travil@18: and the node's list of travil@18: children travil@18: is empty, and the node's travil@38: localName travil@20: matches any one of the following travil@20: void elements: travil@20: "area", travil@20: "base", travil@46: "basefont", travil@46: "bgsound", travil@20: "br", travil@20: "col", travil@20: "embed", travil@46: "frame", travil@20: "hr", travil@20: "img", travil@20: "input", travil@20: "keygen", travil@20: "link", travil@20: "menuitem", travil@20: "meta", travil@20: "param", travil@20: "source", travil@20: "track", travil@20: "wbr"; travil@18: then append the following to markup, in order: travil@18:
      travil@18:
    1. " " (U+0020 SPACE); travil@18:
    2. "/" (U+002F SOLIDUS); travil@18:
    travil@18: and set the skip end tag flag to true. travil@38:
  16. If ns is not the HTML namespace, travil@18: and the node's list of travil@18: children travil@18: is empty, then append "/" (U+002F SOLIDUS) to markup travil@18: and set the skip end tag flag to true. travil@18:
  17. Append ">" (U+003E GREATER-THAN SIGN) to markup. travil@18:
  18. If the value of skip end tag is true, then return travil@18: the value of markup and skip the remaining steps. The travil@18: node is a leaf-node. travil@53:
  19. If ns is the HTML namespace, and the node's travil@53: localName travil@53: matches the string "template", then this is a travil@55: template element. travil@53: Append to markup the result of running the travil@53: XML serialization algorithm on the travil@53: template element's travil@53: template contents travil@55: (a DocumentFragment), travil@53: providing the value of inherited ns for the travil@53: context namespace, travil@53: map for the namespace prefix map, travil@53: prefix index for the travil@53: generated namespace prefix index, and the value travil@53: of the require well-formed flag. This allows travil@53: template content to travil@53: round-trip , given the rules for travil@53: parsing XHTML documents travil@53: [[HTML5]]. travil@53:
  20. Otherwise, append to markup the result of running the travil@49: XML serialization algorithm on each travil@49: of node's travil@18: children, travil@49: in order, providing the value of inherited ns for the travil@49: context namespace, travil@38: map for the namespace prefix map, travil@49: prefix index for the travil@49: generated namespace prefix index, and the value travil@50: of the require well-formed flag. travil@36:
  21. Append the following to markup, in order: travil@18:
      travil@37:
    1. "</" (U+003C LESS-THAN SIGN, U+002F SOLIDUS); travil@37:
    2. The value of qualified name; travil@37:
    3. ">" (U+003E GREATER-THAN SIGN). travil@18:
    travil@18:
  22. Return the value of markup. travil@1:
travil@1: travil@51:
Document travil@1:
travil@50:

If the require well-formed flag is set (its value is travil@50: true), and this node has no travil@55: documentElement travil@55: (the documentElement travil@50: attribute's value is null), then throw an travil@50: exception; the serialization of this node would not be a well-formed document. travil@50:

Otherwise, run the following steps: travil@21:

    travil@50:
  1. Let serialized document be an empty string. travil@50:
  2. Append to serialized document the string produced by running the steps to tleithea@34: produce a DocumentType serialization travil@21: of node's travil@55: doctype travil@50: attribute provided the require well-formed flag if node's travil@55: doctype travil@50: attribute is not null. travil@50:
  3. For each travil@50: child of travil@50: node, in order, run the travil@50: XML serialization algorithm travil@50: on the child given a context namespace travil@50: namespace, a namespace prefix map travil@50: prefix map, a reference to a generated travil@50: namespace prefix index prefix index, flag require well-formed, and travil@50: append the result to serialized document. travil@50:
  4. Return the value of serialized document. travil@21:
travil@1: travil@51:
Comment travil@32:
travil@50:

If the require well-formed flag is set (its value is travil@50: true), and node's travil@50: data travil@50: contains characters that are not matched by the XML Char production [[XML10]] or travil@50: contains "--" (two adjacent U+002D HYPHEN-MINUS characters) or that ends with travil@50: a "-" (U+002D HYPHEN-MINUS) character, then travil@50: throw an exception; the serialization of this travil@50: node's travil@50: data travil@50: would not be well-formed. travil@32:

Return the concatenation of "<!--", node's travil@1: data, and travil@1: "-->". travil@1: travil@47: travil@47: travil@51:

Text travil@15:
    travil@50:
  1. If the require well-formed flag is set (its value is travil@50: true), and node's travil@50: data travil@50: contains characters that are not matched by the XML Char production [[XML10]], travil@50: then throw an exception; the serialization of this travil@50: node's travil@50: data travil@50: would not be well-formed. travil@15:
  2. Let markup be node's travil@1: data. travil@50: travil@15:
  3. Replace any occurrences of "&" in markup by travil@15: "&amp;". travil@14: travil@15:
  4. Replace any occurrences of "<" in markup by travil@15: "&lt;". travil@15: travil@15:
  5. Replace any occurrences of ">" in markup by travil@15: "&gt;". travil@15: travil@15:
  6. Return data. travil@15:
travil@51:
DocumentFragment travil@15:
    travil@15:
  1. Let markup the empty string. travil@1: travil@15:
  2. For each travil@43: child of node, travil@49: in order, run the XML serialization algorithm travil@49: on the child given travil@43: a context namespace namespace, a travil@49: namespace prefix map prefix map, travil@43: a reference to a generated namespace prefix index travil@50: prefix index, and flag require well-formed. Concatenate the result travil@49: to markup. travil@15:
  3. Return markup. travil@15:
travil@51: travil@51:
DocumentType tleithea@34:
Run the steps to produce a DocumentType travil@50: serialization of node given the require well-formed travil@50: flag, and return the string this produced. travil@15: travil@51:
ProcessingInstruction travil@15:
    travil@50:
  1. If the require well-formed flag is set (its value is travil@50: true), and node's travil@50: target travil@50: contains a ":" (U+003A COLON) character or is an travil@50: ASCII case-insensitive travil@50: match for the string "xml", then throw an travil@50: exception; the serialization of this node's travil@50: target travil@50: would not be well-formed. travil@50:
  2. If the require well-formed flag is set (its value is travil@50: true), and node's travil@50: data travil@50: contains characters that are not matched by the XML Char production [[XML10]] or travil@50: contains the string "?>" (U+003F QUESTION MARK, U+003E GREATER-THAN SIGN), travil@50: then throw an exception; the serialization of this travil@50: node's travil@50: data travil@50: would not be well-formed. travil@39:
  3. Let markup be the concatenation of the following, in order: travil@39:
      travil@39:
    1. "<?" (U+003C LESS-THAN SIGN, U+003F QUESTION MARK); travil@50:
    2. The value of node's target; travil@39:
    3. " " (U+0020 SPACE); travil@39:
    4. The value of node's data; travil@39:
    5. "?>" (U+003F QUESTION MARK, U+003E GREATER-THAN SIGN). travil@39:
    travil@15:
  4. Return markup. travil@15:
travil@51: travil@1:
travil@1: tleithea@34:

To produce a DocumentType serialization of a travil@55: Node node, given a travil@50: require well-formed flag, the user agent must return travil@50: the result of the following algorithm:

travil@16: travil@16:
    travil@50:
  1. If the require well-formed flag is true travil@50: and the node's travil@50: publicId travil@50: attribute contains characters that are not matched by the XML PubidChar production travil@50: [[XML10]], then throw an exception; the serialization travil@50: of this node would not be a well-formed document type declaration. travil@50:
  2. If the require well-formed flag is true travil@50: and the node's travil@50: systemId travil@50: attribute contains characters that are not matched by the XML Char production travil@50: [[XML10]] or that contains both a """ (U+0022 QUOTATION MARK) and a "'" travil@50: (U+0027 APOSTROPHE), then throw an exception; the travil@50: serialization of this node would not be a well-formed document type declaration. travil@16:
  3. Let markup be an empty string. travil@16:
  4. Append the string "<!DOCTYPE" to markup. travil@16:
  5. Append " " (U+0020 SPACE) to markup. travil@16:
  6. Append the value of the node's travil@16: name travil@16: attribute to markup. For a node belonging to an travil@16: HTML document, travil@16: the value will be all lowercase. travil@16:
  7. If the node's travil@16: publicId travil@16: is not the empty string then append the following, in order, to markup: travil@16:
      travil@16:
    1. " " (U+0020 SPACE); travil@16:
    2. The string "PUBLIC"; travil@16:
    3. " " (U+0020 SPACE); travil@16:
    4. """ (U+0022 QUOTATION MARK); travil@16:
    5. The value of the node's travil@16: publicId travil@16: attribute; travil@16:
    6. """ (U+0022 QUOTATION MARK); travil@16:
    travil@16:
  8. travil@16:
  9. If the node's travil@16: systemId travil@16: is not the empty string and the node's travil@16: publicId travil@16: is set to the empty string, then append the following, in order, to markup: travil@16:
      travil@16:
    1. " " (U+0020 SPACE); travil@16:
    2. The string "SYSTEM"; travil@16:
    travil@16:
  10. travil@16:
  11. If the node's travil@16: systemId travil@16: is not the empty string then append the following, in order, to markup: travil@16:
      travil@16:
    1. " " (U+0020 SPACE); travil@16:
    2. """ (U+0022 QUOTATION MARK); travil@16:
    3. The value of the node's travil@16: systemId travil@16: attribute; travil@16:
    4. """ (U+0022 QUOTATION MARK); travil@16:
    travil@16:
  12. travil@47: travil@16:
  13. Append ">" (U+003E GREATER-THAN SIGN) to markup. travil@16:
travil@16: travil@39:

To record the namespace information for an travil@55: Element element, given a travil@41: namespace prefix map map, an travil@42: element prefixes list (initially empty), and a duplicate prefix travil@42: definition reference, the user agent must run the following steps: travil@38:

    travil@42:
  1. Let default namespace attr value be null. travil@38:
  2. For each attribute travil@38: attr in element's travil@55: attributes, travil@38: in order: travil@38:
      travil@39:

      The following conditional steps add namespace prefixes travil@38: into the element prefixes list and add or replace them in the map. travil@38: Only attributes in the XMLNS namespace are travil@39: considered (e.g., attributes made to look like namespace declarations via travil@39: setAttribute("xmlns:pretend-prefix", travil@39: "pretend-namespace") are not included).

      travil@38:
    1. Let attribute namespace be the attr's travil@55: namespaceURI travil@38: value. travil@38:
    2. Let attribute prefix be the value of attr's travil@55: prefix. travil@39:
    3. If the attribute namespace is the XMLNS namespace, then: travil@38:
        travil@39:
      1. If attribute prefix is null, then attr is a travil@42: default namespace declaration. Set the default namespace attr value to travil@55: attr's value and stop running these steps, returning to the travil@39: top of the loop to visit the next attribute. travil@39:
      2. Otherwise, the attribute prefix is not null and attr travil@39: is a namespace prefix definition. Run the following steps: travil@39:
          travil@39:
        1. Let prefix definition be the value of attr's travil@55: localName. travil@39:
        2. Let namespace definition be the value of attr's travil@55: value. travil@39:
        3. If a key matching the value of namespace definition already exists in travil@41: map, and the key's value matches prefix definition, then travil@42: this is a duplicate namespace prefix definition. Set the value of duplicate travil@42: prefix definition to prefix definition. travil@41:
        4. Otherwise, if the key matching the value of namespace definition already travil@41: exists in map, but the key's value does not match prefix definition, travil@41: then update the key's value to be prefix definition. travil@39:
        5. Otherwise, no key matching the value of namespace definition exists; travil@39: append to map a new key namespace definition travil@39: whose key value is the prefix definition. travil@39:
        6. Append the value of prefix definition to element prefixes list. travil@39:
        travil@38:
      travil@38:
    travil@42:
  3. Return the value of default namespace attr value. travil@38:
travil@38: travil@38:

To generate a prefix given a travil@38: namespace prefix map map, a travil@42: string new namespace, and a reference to a travil@38: generated namespace prefix index prefix travil@38: index, the user agent must run the following steps: travil@38:

    travil@38:
  1. Let generated prefix be the concatenation of the string "ns" and travil@38: the current numerical value of prefix index. travil@38:
  2. Let the value of prefix index be incremented by one. travil@38:
  3. Append to map a new key new namespace whose key value is the travil@38: generated prefix. travil@38:
  4. Return the value of generated prefix. travil@38:
travil@16: tleithea@34:

The XML serialization of the attributes travil@55: of an Element travil@39: element together with a namespace prefix travil@41: map map, a generated prefix index travil@50: prefix index reference, a flag ignore namespace definition attribute, a travil@50: duplicate prefix definition value, and a flag require well-formed, travil@50: is the result of the following algorithm: travil@1:

    travil@18:
  1. Let result be the empty string. travil@50:
  2. Let localname set be a new empty travil@50: namespace localname set. This localname travil@55: set will contain tuples of unique attribute travil@55: namespaceURI travil@55: and localName travil@50: pairs, and is populated as each attr is processed. travil@50: This set is used to [optionally] enforce the well-formed constraint that an travil@55: element cannot have two attributes with the same travil@55: namespaceURI travil@55: and localName. travil@50: This can occur when two otherwise identical attributes on the same element differ only by their travil@50: prefix values. travil@39:
  3. For each attribute travil@18: attr in element's travil@55: attributes, travil@18: in order: travil@39:
      travil@50:
    1. If the require well-formed flag is set (its value is travil@50: true), and the localname set contains a tuple whose values match those travil@50: of a new tuple consisting of attr's travil@50: namespaceURI travil@50: attribute and localName travil@50: attribute, then throw an exception; the serialization of this travil@50: attr would fail to produce a well-formed element serialization. travil@50:
    2. Create a new tuple consisting of attr's travil@50: namespaceURI travil@50: attribute and localName travil@50: attribute, and add it to the localname set. travil@39:
    3. Let attribute namespace be the attr's travil@55: namespaceURI travil@39: value. travil@39: travil@42:
    4. Let candidate prefix be null. travil@41:
    5. If attribute namespace is not null, then run these sub-steps: travil@18:
        travil@42:
      1. If the value of attribute namespace is the travil@41: XMLNS namespace and either the attr's travil@55: prefix travil@42: is null and the ignore namespace definition travil@41: attribute flag is true or the attr's travil@55: prefix travil@42: is not null and the attr's travil@55: localName travil@42: matches the value of duplicate prefix definition, then stop running travil@42: these steps and return to the loop to visit the next attribute. travil@42:
      2. Otherwise, if there exists a key in map that matches the value of attribute travil@42: namespace, then let candidate prefix be that key's value from the travil@42: map. travil@41:
      3. Otherwise, there is no key matching attribute namespace in map and travil@41: the attribute namespace is not the XMLNS namespace. travil@41: Run these steps: travil@39:
          travil@42:
        1. Let candidate prefix be the result of travil@41: generating a prefix providing map, travil@41: attribute namespace, and prefix index as input. travil@41:
        2. Append the following to result: travil@41:
            travil@41:
          1. " " (U+0020 SPACE); travil@41:
          2. The string "xmlns:"; travil@42:
          3. The value of candidate prefix; travil@41:
          4. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); travil@41:
          5. The result of serializing an attribute value travil@50: given attribute namespace and the travil@50: require well-formed flag as input; travil@41:
          6. """ (U+0022 QUOTATION MARK). travil@41:
          travil@39:
        travil@18:
      travil@41: travil@39:
    6. Append a " " (U+0020 SPACE) to result. travil@42:
    7. If candidate prefix is not null, then append to result travil@42: the concatenation of candidate prefix with ":" (U+003A COLON). travil@50: travil@50:
    8. If the require well-formed flag is set (its value is travil@50: true), and this attr's travil@50: localName travil@50: attribute contains the character ":" (U+003A COLON) or does not match the XML travil@50: Name production [[XML10]] or equals "xmlns" and attribute travil@50: namespace is null, then throw an travil@50: exception; the serialization of this attr would not be a well-formed attribute. travil@41: travil@39:
    9. Append the following strings to result: travil@39:
        travil@39:
      1. The value of attr's travil@55: localName; travil@39:
      2. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK); travil@41:
      3. The result of serializing an attribute value travil@41: given attr's travil@50: value travil@50: attribute and the require well-formed flag as input; travil@39:
      4. """ (U+0022 QUOTATION MARK). travil@39:
      travil@39:
    travil@18:
  4. Return result. travil@1:
travil@41: travil@41:

To serialize an attribute value given an travil@50: attribute value and require well-formed flag, travil@50: the user agent must run the following steps: travil@41:

    travil@50:
  1. If the require well-formed flag is set (its value is travil@50: true), and attribute value contains characters that are not matched travil@50: by the XML Char production [[XML10]], then travil@50: throw an exception; the serialization of this travil@50: attribute value would fail to produce a well-formed element serialization. travil@42:
  2. If attribute value is null, then return the empty string. travil@41:
  3. Otherwise, attribute value is a string. Return attribute value, travil@41: first replacing any occurrences of the following: travil@41:
      travil@41:
    1. """ with "&quot;" travil@41:
    2. "&" with "&amp;" travil@41:
    3. "<" with "&lt;" travil@41:
    4. ">" with "&gt;" travil@41:
    travil@41:

    This matches behavior present in browsers, and goes above travil@41: and beyond the grammar requirement in the XML specification's AttValue travil@41: production [[XML10]] by also replacing ">" characters.

    travil@41:
travil@1:
travil@1:
travil@1: travil@1:
travil@1:

The DOMParser interface

travil@1: travil@1:
enum SupportedType {
travil@1:     "text/html",
travil@1:     "text/xml",
travil@1:     "application/xml",
travil@1:     "application/xhtml+xml",
travil@1:     "image/svg+xml"
travil@1: };
travil@1: tleithea@34:

The DOMParser() constructor travil@1: must return a new DOMParser object. travil@1: travil@1:

travil@1:
Document parseFromString(DOMString str, SupportedType type)
travil@1:
travil@1:

The tleithea@34: parseFromString(str, type) travil@1: method must run these steps, depending on type: travil@1: travil@1:

travil@1:
"text/html" travil@1:
travil@1:

Parse str with an travil@1: HTML parser, and return the newly tleithea@34: created document. travil@1: travil@1:

The scripting flag must be set to travil@1: "disabled". travil@1: travil@1:

meta elements are not travil@1: taken into account for the encoding used, as a Unicode stream is passed into travil@1: the parser. travil@1: travil@1:

script elements get marked travil@1: unexecutable and the contents of noscript travil@1: get parsed as markup. travil@1: travil@1:

"text/xml" travil@1:
"application/xml" travil@1:
"application/xhtml+xml" travil@1:
"image/svg+xml" travil@1:
travil@1:
    travil@1:
  1. Parse str with a namespace-enabled travil@1: XML parser. travil@1: travil@1:
  2. If the previous step didn't return an error, return the newly tleithea@34: created document travil@1: and terminate these steps. travil@1: travil@23:
  3. Otherwise, throw a travil@55: DOMException travil@23: with name SyntaxError. travil@23: travil@23:

    Some UAs do not throw an exception, but rather return a minimal travil@23: well-formed XML document that describes the error. In these cases, the error travil@23: document's root element will be named parsererror and its namespace travil@23: will be set to "http://www.mozilla.org/newlayout/xml/parsererror.xml". travil@23: travil@23: travil@1:

travil@1:
travil@1: travil@1:

In any case, the returned tleithea@34: document's tleithea@34: content type travil@23: must be the type argument. Additionally, the tleithea@34: document must have a tleithea@34: URL value equal to travil@23: the URL of the tleithea@34: active document, a tleithea@34: location value of null. travil@1: travil@1:

The returned tleithea@34: document's tleithea@34: encoding is travil@1: the default, UTF-8. travil@1:

travil@1:
travil@1:
travil@1: travil@1:
travil@1:

The XMLSerializer interface

travil@1: tleithea@34:

The XMLSerializer() travil@1: constructor must return a new XMLSerializer object. travil@1: travil@1:

travil@1:
DOMString serializeToString(Node root)
travil@0: travil@17:
The serializeToString(root) travil@49: method must produce an XML serialization of root passing travil@50: a value of false for the require well-formed parameter, and return the result.
travil@1:
travil@1:
travil@1: travil@1:
travil@1:

Extensions to the Element interface

travil@1: travil@1:
travil@11:
[TreatNullAs=EmptyString] attribute DOMString innerHTML
travil@1:
tleithea@34:

The innerHTML IDL travil@1: attribute represents the markup of the travil@1: Element's contents. travil@1: travil@1:

travil@1: travil@1: tleithea@34:
element . innerHTML [ = value ] travil@1:
travil@1:

Returns a fragment of HTML or XML that represents the element's travil@1: contents. travil@1: travil@1:

Can be set, to replace the contents of the element with nodes travil@1: parsed from the given string. travil@1: travil@1:

In the case of an XML document, travil@1: will throw a tleithea@34: DOMException with name InvalidStateError travil@1: if the Element cannot be serialized travil@1: to XML, and a tleithea@34: DOMException with name SyntaxError travil@1: if the given string is not well-formed. travil@1:

travil@1: travil@49:

On getting, return the result of invoking the travil@49: fragment serializing algorithm on the travil@49: context object providing true for the travil@50: require well-formed flag (this might throw an exception travil@49: instead of returning a string). travil@1: travil@1:

On setting, these steps must be run: travil@1:

    travil@1:
  1. Let fragment be the result of invoking the travil@1: fragment parsing algorithm with travil@1: the new value as markup, and the travil@1: context object as the context element. travil@1: tleithea@34:
  2. Replace all travil@1: with fragment within the context object. travil@1:
travil@1:
travil@0: travil@1: travil@11:
[TreatNullAs=EmptyString] attribute DOMString outerHTML
travil@1:
tleithea@34:

The outerHTML IDL travil@1: attribute represents the markup of the travil@1: Element and its contents. travil@1: travil@1:

tleithea@34:
element . outerHTML [ = value ] travil@1:
travil@1:

Returns a fragment of HTML or XML that represents the element and its travil@1: contents. travil@1: travil@1:

Can be set, to replace the element with nodes parsed from the given travil@1: string. travil@1: travil@1:

In the case of an XML document, travil@1: will throw a tleithea@34: DOMException with name InvalidStateError travil@1: if the element cannot be serialized to XML, and a tleithea@34: DOMException with name SyntaxError travil@1: if the given string is not well-formed. travil@1: travil@1:

Throws a tleithea@34: DOMException with name NoModificationAllowedError travil@1: if the parent of the element is the travil@1: Document node. travil@1:

travil@1: travil@49:

On getting, return the result of invoking the travil@49: fragment serializing algorithm on a travil@49: fictional node whose only child is the context object travil@49: context object providing true for the travil@50: require well-formed flag (this might throw an exception travil@49: instead of returning a string). travil@1: travil@1:

On setting, the following steps must be run: travil@1: travil@1:

    travil@1:
  1. Let parent be the context object's tleithea@34: parent. travil@1: travil@1:
  2. If parent is null, terminate these steps. There would be no travil@1: way to obtain a reference to the nodes created even if the remaining steps travil@1: were run. travil@1: travil@1:
  3. If parent is a travil@1: Document, throw a tleithea@34: DOMException with name NoModificationAllowedError travil@1: exception and terminate these steps. travil@1: travil@1:
  4. If parent is a travil@1: DocumentFragment, let travil@1: parent be a new travil@1: Element with travil@1: travil@1: travil@1: travil@1:
  5. Let fragment be the result of invoking the travil@1: fragment parsing algorithm with travil@1: the new value as markup, and parent as travil@1: the context element. travil@1: tleithea@34:
  6. Replace travil@1: the context object with fragment within travil@1: the context object's tleithea@34: parent. travil@1:
travil@1:
travil@0: travil@1: travil@9:
void insertAdjacentHTML(DOMString position, DOMString text)
travil@1:
travil@1:
tleithea@34:
element . insertAdjacentHTML(position, text) travil@1: travil@1:
travil@1:

Parses the given string text as HTML or XML and inserts travil@1: the resulting nodes into the tree in the position given by the travil@1: position argument, as follows: travil@1: travil@1:

travil@1:
"beforebegin" travil@1:
Before the element itself. travil@1: travil@1:
"afterbegin" travil@1:
Just inside the element, before its first child. travil@1: travil@1:
"beforeend" travil@1:
Just inside the element, after its last child. travil@1: travil@1:
"afterend" travil@1:
After the element itself. travil@1:
travil@1: travil@9:

Throws a SyntaxError exception if the arguments have invalid values (e.g., in the case of an tleithea@34: XML document, if the given string is travil@9: not well-formed). travil@1: travil@1:

Throws a tleithea@34: DOMException with name NoModificationAllowedError travil@1: if the given position isn't possible (e.g. inserting elements travil@1: after the root element of a Document). travil@1:

travil@1: travil@1:

The tleithea@34: insertAdjacentHTML(position, text) travil@1: method must run these steps: travil@1: travil@1:

    travil@1:
  1. Use the first matching item from this list: travil@1: travil@1:
    travil@1:
    If position is an travil@1: ASCII case-insensitive match for travil@1: the string "beforebegin" travil@1: travil@1:
    If position is an travil@1: ASCII case-insensitive match for travil@1: the string "afterend" travil@1: travil@1:
    travil@1:

    Let context be the context object's tleithea@34: parent. travil@1: travil@1:

    If context is null or a travil@1: document, throw travil@1: a tleithea@34: DOMException with name NoModificationAllowedError travil@1: and terminate these steps. travil@1: travil@1:

    If position is an travil@1: ASCII case-insensitive match for travil@1: the string "afterbegin" travil@1: travil@1:
    If position is an travil@1: ASCII case-insensitive match for travil@1: the string "beforeend" travil@1: travil@1:
    Let context be the context object. travil@9: travil@9:
    Otherwise travil@9:
    travil@9:

    Throw a SyntaxError exception. travil@1:

    travil@1: travil@1:
  2. If context is not an travil@1: Element or the following are all true: travil@1: travil@1: travil@1: travil@1:

    let context be a new travil@1: Element with travil@1: travil@1:

    travil@1: travil@1:
  3. Let fragment be the result of invoking the travil@1: fragment parsing algorithm with text as travil@1: markup, and parent as the context element. travil@1: travil@1:
  4. Use the first matching item from this list: travil@1: travil@1:
    travil@1:
    If position is an travil@1: ASCII case-insensitive match for travil@1: the string "beforebegin" travil@1: tleithea@34:
    Insert travil@1: fragment into the context object's tleithea@34: parent travil@1: before the context object. travil@1: travil@1:
    If position is an travil@1: ASCII case-insensitive match for travil@1: the string "afterbegin" travil@1: tleithea@34:
    Insert travil@1: fragment into the context object travil@1: before its tleithea@34: first child. travil@1: travil@1:
    If position is an travil@1: ASCII case-insensitive match for travil@1: the string "beforeend" travil@1: travil@1:
    Append travil@1: fragment to the context object. travil@1: travil@1:
    If position is an travil@1: ASCII case-insensitive match for travil@1: the string "afterend" travil@1: tleithea@34:
    Insert travil@1: fragment into the context object's tleithea@34: parent travil@1: before the context object's tleithea@34: next sibling. travil@1:
    travil@1:
travil@1:
travil@0: travil@1:
travil@1:
travil@1: travil@14: travil@1: travil@1:
travil@1:

Extensions to the Range interface

travil@1: travil@1:
travil@1:
DocumentFragment createContextualFragment(DOMString fragment)
travil@1:
travil@1:
tleithea@34:
fragment = range . createContextualFragment(fragment) travil@1:
Returns a DocumentFragment, created travil@1: from the markup string given. travil@1:
travil@1: travil@1:

The tleithea@34: createContextualFragment(fragment) travil@1: method must run these steps: travil@1: travil@1:

    travil@1:
  1. Let node the context object's tleithea@34: start node. travil@1: travil@1:

    Let element be as follows, depending on node's interface: travil@1: travil@1:

    travil@1:
    Document travil@1:
    DocumentFragment travil@1:
    null travil@1: travil@1:
    Element travil@1:
    node travil@1: travil@1:
    Text travil@1:
    Comment travil@1:
    node's travil@1: parent element travil@1: travil@1:
    DocumentType travil@1:
    ProcessingInstruction travil@1:
    [[DOM4]] prevents this case. travil@1:
    travil@1: travil@1:
  2. If either element is null or the following are all true: travil@1: travil@1: travil@1: travil@1:

    let element be a new tleithea@34: element with travil@1: travil@1:

    travil@1: travil@1:
  3. Let fragment node be the result of invoking the travil@1: fragment parsing algorithm with fragment as travil@1: markup, and element as the context element. travil@1: travil@1:
  4. Unmark all scripts in fragment node as "already started". travil@1: travil@1:
  5. Return fragment node. travil@1:
travil@1:
travil@1:
travil@1:
travil@1: travil@1:
travil@1:

Acknowledgements

travil@24:

Thanks to Ms2ger [Mozilla] for maintaining the initial travil@24: drafts of this specification and for its continued improvement in the travil@31: Living Specification. travil@1: travil@11:

Thanks to Anne van Kesteren, Aryeh Gregor, Boris Zbarsky, Henri Sivonen, Simon Pieters and timeless travil@1: for their useful comments. travil@1: travil@1:

Special thanks to Ian Hickson for defining the tleithea@34: innerHTML and tleithea@34: outerHTML attributes, and the tleithea@34: insertAdjacentHTML() method in travil@1: [[HTML5]] and his useful comments. travil@1:

travil@1: travil@54: travil@1: travil@1: