...examples...
datatemplate elementBlock-level element and metadata element.
rule elements.
HTMLElement.
The datatemplate element
brings together the various rules that form a data template. The element
doesn't itself do anything exciting.
rule elementdatatemplate
element.
condition
mode
interface HTMLRuleElement : HTMLElement {
attribute DOMString condition;
attribute DOMString mode;
readonly attribute DOMTokenString modeList;
};
The rule element represents a template
of content that is to be used for elements when updating an element's generated content.
The condition attribute, if
specified, must contain a valid selector. It specifies which nodes in the
data tree will have the condition's template applied. [SELECTORS]
If the condition attribute is not specified, then
the condition applies to all elements, text nodes, CDATA nodes, and
processing instructions.
The mode attribute,
if specified, must have a value that is an unordered
set of space-separated tokens representing the various modes for which
the rule applies. When, and only when, the mode attribute is omitted, the rule applies if and
only if the mode is the empty string. A mode is invoked by the nest element; for the first node (the root node)
of the data tree, the mode is the empty string.
The contents of rule elements form a
template, and may be anything that, when the parent datatemplate is applied to some
conforming data, results in a conforming DOM tree.
The condition DOM attribute must
reflect the condition content attribute.
The mode and modeList DOM
attributes must reflect the mode content attribute.
nest elementrule element,
regardless of the parent element's content model.
filter
mode
interface HTMLNestElement : HTMLElement {
attribute DOMString filter;
attribute DOMString mode;
};
The nest element represents a point in
a template where the user agent should recurse and start inserting the
children of the data node that matches the rule in which the nest element finds itself.
The filter
attribute, if specified, must contain a valid selector. It specifies which
of the child nodes in the data tree will be examined for further
processing at this point. [SELECTORS]
If the filter
attribute is not specified, then all elements, text nodes, CDATA nodes,
and processing instructions are processed.
The mode
attribute, if specified, must have a value that is a word token consisting
of one or more characters, none of which are space characters. It gives the mode which will be in effect
when looking at the rules in the data template.
The filter DOM
attribute must reflect the filter content attribute.
The mode DOM
attribute must reflect the mode content attribute.
The template
attribute may be added to an element to indicate that the template
processing model is to be applied to that element.
The template
attribute, when specified, must be a URI to an XML or HTML document, or a
fragment identifier pointing at another part of the document. If there is
a fragment identifier present, then the element with that ID in the target
document must be a datatemplate
element, otherwise, the root element must be a datatemplate element.
The template DOM
attribute must reflect the template content attribute.
The ref attribute may be
specified on any element on which the template attribute is specified. If it is
specified, it must be a URI to an XML or HTML document, or a fragment
identifier pointing at another part of the document.
When an element has a template attribute but no ref attribute, the element may,
instead of its usual content model, have a single element of any kind.
That element is then used as the root node of the data for the template.
The ref DOM attribute must
reflect the ref content
attribute.
The registrationmark attribute
may be specified on any element that is a descendant of a rule element, except nest elements. Its value may be any string,
including the empty string (which is the value that is assumed if the
attribute is omitted). This attribute performs a role similar to
registration marks in printing presses: when the generated content is
regenerated, elements with the same registrationmark are lined up. This
allows the author to disambiguate how elements should be moved around when
generated content is regenerated in the face of changes to the data tree.
The registrationMark DOM
attribute must reflect the registrationmark content attribute.
originalContent DOM attributeThe originalContent is set to a
DocumentFragment to hold the original children of an element
that has been replaced by content generated for a data template.
Initially, it must be null. Its value is set when the template attribute is
set to a usable value, and is unset when the attribute is removed.
The originalContent DOM attribute can thus
be used as an indicator of whether a template is currently being applied,
just as the templateElement DOM attribute can.
template attributeSetting: When an
HTML element without a template attribute has its template attribute set,
the user agent must fetch the specified
file and parse it
(without a browsing context, and with
scripting disabled) to obtain a DOM. If
the URI is the same as the URI of the current document,
then the current document's DOM must be assumed to be that parsed DOM.
While this loading and parsing is in progress, the element is said to be
busy loading the template rules or data.
If the resource specified by the template attribute is not the current
document and does not have an XML MIME type, or if an XML
parse error is found while parsing the resource, then the resource cannot
be successfully parsed, and the user agent must jump to the failed to parse
steps below.
Once the DOM in question has been parsed, assuming that it indeed can be parsed and does so successfully, the user agent must wait for no scripts to be executing, and as soon as that opportunity arises, run the following algorithm:
If the template attribute's value has a fragment
identifier, and, in the DOM in question, it identifies a
datatemplate element, then set
the templateElement DOM attribute to that
element.
Otherwise, if the template attribute value does not have a
fragment identifier, and the root element of the DOM in question is a
datatemplate element, then set
the templateElement DOM attribute to that
element.
Otherwise, jump to the failed to parse steps below.
Create a new DocumentFragment and move all the nodes that
are children of the element to that DocumentFragment
object. Set the originalContent DOM attribute on the
element to this new DocumentFragment object.
Jump to the steps below for updating the generated content.
If the resource has failed to parse, the user agent
must fire a simple event with the name error at the element on
which the template attribute was found.
Unsetting:
When an HTML element with a template attribute has its template attribute
removed or dynamically changed from one value to another, the user agent
must run the following algorithm:
Set the templateElement DOM attribute to
null.
If the originalContent DOM attribute of the
element is not null, run these substeps:
Remove all the nodes that are children of the element.
Append the nodes in the originalContent
DocumentFragment to the element.
Set originalContent to null.
(If the originalContent DOM attribute of the
element is null, then either there was an error loading or parsing the
previous template, or the previous template never finished loading; in
either case, there is nothing to undo.)
If the template attribute was changed (as opposed
to simply removed), then act as if it was now set to its new
value (fetching the specified page, etc, as described above).
The templateElement DOM attribute
is updated by the above algorithm to point to the currently active
datatemplate element. Initially,
the attribute must have the value null.
ref attributeSetting: When an
HTML element without a ref attribute has its ref attribute set, the user agent must fetch the
specified file
and parse it (without a browsing context, and
with scripting disabled) to obtain a DOM. If
the URI is the same as the URI of the current document,
then the current document's DOM is assumed to be that parsed DOM. While
this loading and parsing is in progress, the element is said to be
busy loading the template rules or data.
If the resource specified by the ref attribute is not the current
document and does not have an XML MIME type, or if an XML
parse error is found while parsing the resource, then the resource cannot
be successfully parsed, and the user agent must jump to the failed to parse steps
below.
Once the DOM in question has been parsed, assuming that it indeed can be parsed and does so successfully, the user agent must wait for no scripts to be executing, and as soon as that opportunity arises, run the following algorithm:
If the ref attribute
value does not have a fragment identifier, then set the refNode DOM attribute to
the Document node of that DOM.
Otherwise, if the ref
attribute's value has a fragment identifier, and, in the DOM in
question, that fragment identifier identifies an element, then set the
refNode DOM
attribute to that element.
Otherwise, jump to the failed to parse steps below.
Jump to the steps below for updating the generated content.
If the resource has failed
to parse, the user agent must fire a simple
event with the name error at the element on which the ref attribute was found, and must
then jump to the steps below for updating the generated content (the contents
of the element will be used instead of the specified resource).
Unsetting: When an
HTML element with a ref attribute has its ref attribute removed or dynamically changed from
one value to another, the user agent must run the following algorithm:
Set the refNode
DOM attribute to null.
If the ref attribute
was changed (as opposed to simply removed), then act as if it was now set to its new value
(fetching the specified page, etc, as described above). Otherwise, jump
to the steps below for updating the generated content.
The refNode DOM
attribute is updated by the above algorithm to point to the current data
tree, if one is specified explicitly. If it is null, then the data tree is
given by the originalContent DOM attribute, unless
that is also null, in which case no template is currently being applied.
Initially, the attribute must have the value null.
NodeDataTemplate interfaceAll objects that implement the Node interface must also
implement the NodeDataTemplate interface, whose
members must be accessible using binding-specific casting mechanisms.
interface NodeDataTemplate {
readonly attribute Node dataNode;
};
The dataNode DOM
attribute returns the node for which this node was generated. It
must initially be null. It is set on the nodes that form the content
generated during the algorithm
for updating the generated content of elements that are using the data
template feature.
An element with a non-null templateElement is said to be a data tree user of the node identified by the element's
refNode attribute,
as well as all of that node's children, or, if that attribute is null, of
the node identified by the element's originalContent, as well as all
that node's children.
Nodes that have one or more data tree users associated with them (as per the previous paragraph) are themselves termed data tree component nodes.
Whenever a data tree component node changes its name or value, or has one of its attributes change name or value, or has an attribute added or removed, or has a child added or removed, the user agent must update the generated content of all of that node's data tree users.
An element with a non-null templateElement is also said to be a
template tree user of the node identified by the
element's templateElement attribute, as well as
all of that node's children.
Nodes that have one or more template tree users associated with them (as per the previous paragraph) are themselves termed template tree component nodes.
Whenever a template tree component node changes its name or value, or has one of its attributes change name or value, or has an attribute added or removed, or has a child added or removed, the user agent must update the generated content of all of that node's template tree users.
In other words, user agents update the content generated from a template whenever either the backing data changes or the template itself changes.
When the user agent is to update the generated content of an element that uses a template, the user agent must run the following steps:
Let destination be the element whose generated content is being updated.
If the destination element is busy loading the template rules or data, then abort these steps. Either the steps will be invoked again once the loading has completed, or the loading will fail and the generated content will be removed at that point.
Let template tree be the element given by destination's templateElement DOM attribute. If it
is null, then abort these steps. There are no rules to apply.
Let data tree be the node given by destination's refNode DOM attribute. If it is null, then
let data tree be the node given by the originalContent DOM node.
Let existing nodes be a set of ordered lists of nodes, each list being identified by a tuple consisting of a node, a node type and name, and a registration mark (a string).
For each node node that is a descendant of destination, if any, add node to the
list identified by the tuple given by: node's dataNode DOM
attribute; the node's node type and, if it's an
element, its qualified name (that is, its namespace and local name), or,
if it's a processing instruction, its target name,
and the value of the node's registrationmark attribute, if it
has one, or the empty string otherwise.
Remove all the child nodes of destination, so that its child node list is empty.
Run the Levenberg data node algorithm (described below) using destination as the destination node, data tree as the source node, template tree as the rule container, the empty string as the mode, and the existing nodes lists as the lists of existing nodes.
The Levenberg algorithm consists of two algorithms that invoke each other recursively, the Levenberg data node algorithm and the Levenberg template node algorithm. These algorithms use the data structures initialised by the set of steps described above.
The Levenberg data node algorithm is as follows. It is always invoked with three DOM nodes, one string, and a set of lists as arguments: the destination node, the source node, the rule container, the mode string, and the existing nodes lists respectively.
Let condition be the first rule element child of the rule
container element, or null if there aren't any.
If condition is null, follow these substeps:
If the source node is an element, then, for each child child node of the source node element, in tree order, invoke the Levenberg data node algorithm recursively, with destination node, child node, rule container, the empty string, and existing nodes lists as the five arguments respectively.
Abort the current instance of the Levenberg data node algorithm, returning to whatever algorithm invoked it.
Let matches be a boolean with the value true.
If the condition element has a mode attribute, but the
value of that attribute is not a mode match for the current
mode string, then let matches be false.
If the condition element has a condition
attribute, and the attribute's value, when evaluated as a selector, does not match the
current source node, then let matches be false.
If matches is true, then follow these substeps:
For each child child node of the condition element, in tree order, invoke the Levenberg template node algorithm recursively, with the five arguments being destination node, source node, rule container, child node, and existing nodes lists respectively.
Abort the current instance of the Levenberg data node algorithm, returning to whatever algorithm invoked it.
Let condition be the next rule element that is a child of the rule container element, after the condition element itself, or null if there are no more
rule elements.
Jump to step 2 in this set of steps.
The Levenberg template node algorithm is as follows. It is always invoked with four DOM nodes and a set of lists as arguments: the destination node, the source node, the rule container, the template node, and the existing nodes lists respectively.
If template node is a comment node, abort the current instance of the Levenberg template node algorithm, returning to whatever algorithm invoked it.
If template node is a nest element, then run these substeps:
If source node is not an element, then abort the current instance of the Levenberg template node algorithm, returning to whatever algorithm invoked it.
If the template node has a mode attribute, then
let mode be the value of that attribute;
otherwise, let mode be the empty string.
Let child node be the first child of the source node element, or null if source node has no children.
If child node is null, abort the current instance of the Levenberg template node algorithm, returning to whatever algorithm invoked it.
If the template node element has a filter attribute,
and the attribute's value, when evaluated as a
selector, matches child node, then invoke the
Levenberg data node algorithm recursively,
with destination node, child
node, rule container, mode, and existing nodes lists as
the five arguments respectively.
Let child node be child node's next sibling, or null if child node was the last node of source node.
Return to step 4 in this set of substeps.
If template node is an element, and that element
has a registrationmark attribute, then let
registration mark have the value of that attribute.
Otherwise, let registration mark be the empty
string.
If there is a list in the existing nodes lists corresponding to the tuple (source node, the node type and name of template node, registration mark), and that list is not empty, then run the following substeps. (For an element node, the name of the node is its qualified tag name, i.e. its namespace and local name. For a processing instruction, its name is the target. For other types of nodes, there is no name.)
Let new node be the first node in that list.
Remove new node from that list.
If new node is an element, remove all the child nodes of new node, so that its child node list is empty.
Otherwise, if there is no matching list, or there was, but it is now empty, then run these steps instead:
Let new node be a shallow clone of template node.
Let new node's dataNode DOM attribute be source node.
If new node is an element, run these substeps:
For each attribute on new node, if an attribute with the same qualified name is not present on template node, remove that attribute.
For each attribute attribute on template node, run these substeps:
Let expanded be the result of passing the value of attribute to the text expansion algorithm for templates along with source node.
If an attribute with the same qualified name as attribute is already present on new node, then: if its value is different from expanded, replace its value with expanded.
Otherwise, if there is no attribute with the same qualified name as attribute on new node, then add an attribute with the same namespace, prefix, and local name as attribute, with its value set to expanded's.
Otherwise, the new node is a text node, CDATA block, or PI. Run these substeps instead:
Let expanded be the result of passing the node value of template node (the content of the text node, CDATA block, or PI) to the text expansion algorithm for templates along with source node.
If the value of the new node is different from expanded, then set the value of new node to expanded.
Append new node to destination.
If template node is an element, then, for each child child node of the template node element, in tree order, invoke the Levenberg template node algorithm recursively, with the five arguments being new child, source node, rule container, child node, and existing nodes lists respectively.
Define: evaluated as a selector
Define: text expansion algorithm for templates