readonly attribute long sectionRowIndex;
readonly attribute HTMLCollection cells;
HTMLElement insertCell(in long index);
void deleteCell(in long index);
};
The tr
element represents a row of cells in a table.
The tr
element takes part in the table model.
The rowIndex
element must, if the element has a parent table
element, or a parent tbody
, thead
,
or tfoot
element and a
grandparent table
element,
return the index of the tr
element in that
table
element's rows
collection. If there
is no such table
element, then the
attribute must return 0.
The sectionRowIndex
DOM
attribute must, if the element has a parent table
, tbody
,
thead
, or tfoot
element, return the index of the tr
element in the parent element's rows
collection (for tables, that's the rows
collection; for table
sections, that's the rows
collection). If there is no such parent
element, then the attribute must return 0.
The cells
attribute
must return an HTMLCollection
rooted at the tr
element, whose filter
matches only td
and th
elements that are children of the tr
element.
The insertCell(index)
method must act as follows:
If index is less than -1 or greater than the number
of elements in the cells
collection, the method must raise an
INDEX_SIZE_ERR
exception.
If index is equal to -1 or equal to the number of
items in cells
collection, the method must create a td
element, append it to the tr
element, and
return the newly created td
element.
Otherwise, the method must create a td
element, insert it as a child of the tr
element, immediately before the indexth td
or th
element in
the cells
collection,
and finally must return the newly created td
element.
The deleteCell(index)
method must remove the indexth element in the cells
collection from its parent. If index is less than zero or greater than or equal to the
number of elements in the cells
collection, the method must instead raise
an INDEX_SIZE_ERR
exception.
td
elementtr
element.
colspan
rowspan
interface HTMLTableCellElement : HTMLElement { attribute long colSpan; attribute long rowSpan; readonly attribute long cellIndex; };
The td
element represents a data cell in a table.
The td
element may have a colspan
content attribute
specified, whose value must be a valid non-negative
integer greater than zero. Its default value, which must be used if parsing the
attribute as a non-negative integer returns either an error or zero,
is 1.
The td
element may also have a rowspan
content
attribute specified, whose value must be a valid
non-negative integer. Its default value, which must be used if parsing the
attribute as a non-negative integer returns an error, is also 1.
The td
element and its colspan
and rowspan
attributes
take part in the table model.
The colspan
DOM
attribute must reflect the content attribute of the
same name, with the exception that on setting, if the new value is 0, then
an INDEX_SIZE_ERR
exception must be raised.
The rowspan
DOM
attribute must reflect the content attribute of the
same name.
The cellIndex
DOM attribute must, if
the element has a parent tr
element, return
the index of the cell's element in the parent element's cells
collection. If there
is no such parent element, then the attribute must return 0.
There has been some suggestion that the headers
attribute from HTML4, or some other mechanism that
is more powerful than scope=""
, should be included.
This has not yet been considered.
th
elementtr
element.
colspan
rowspan
scope
interface HTMLTableHeaderCellElement : HTMLTableCellElement { attribute DOMString scope; };
The th
element represents a header cell in a table.
The th
element may have a colspan
content
attribute specified, whose value must be a valid
non-negative integer greater than zero. Its default value, which must
be used if parsing the attribute as a non-negative integer returns
either an error or zero, is 1.
The th
element may also have a rowspan
content
attribute specified, whose value must be a valid
non-negative integer. Its default value, which must be used if parsing the
attribute as a non-negative integer returns an error, is also 1.
The th
element may have a scope
content attribute specified.
The scope
attribute
is an enumerated attribute with five states,
four of which have explicit keywords:
row
keyword, which maps to the row state
col
keyword, which maps to the column state
rowgroup
keyword, which
maps to the row group state
colgroup
keyword, which
maps to the column group state
The scope
attribute's missing value default is the auto state.
The exact effect of these values is described in detail in the algorithm for assigning header cells to data cells, which user agents must apply to determine the relationships between data cells and header cells.
The th
element and its colspan
, rowspan
, and scope
attributes take
part in the table model.
The scope
DOM
attribute must reflect the content attribute of the
same name.
The HTMLTableHeaderCellElement
interface inherits from the HTMLTableCellElement
interface and
therefore also has the DOM attributes defined above in the td
section.
The various table elements and their content attributes together define the table model.
A table consists of cells
aligned on a two-dimensional grid of slots with coordinates (x,
y). The grid is finite, and is either empty or has one
or more slots. If the grid has one or more slots, then the x coordinates are always in the range
1 ≤ x ≤ xmax, and the y coordinates are always in the range
1 ≤ y ≤ ymax. If one or both of xmax and ymax are zero, then the table is empty (has no slots).
Tables correspond to table
elements.
A cell is a set of slots anchored
at a slot (cellx, celly), and with a particular width and height such that the cell
covers all the slots with coordinates (x, y) where cellx ≤ x < cellx+width and celly ≤ y < celly+height. Cell can either
be data cells or header cells. Data cells correspond to
td
elements, and have zero or more
associated header cells. Header cells correspond to th
elements.
A row is a complete set of slots
from x=1 to x=xmax, for
a particular value of y. Rows correspond to tr
elements.
A column is a complete set of
slots from y=1 to y=ymax, for
a particular value of x. Columns can correspond to
col
elements, but in the absense of
col
elements are implied.
A row group is a set of
rows anchored at a slot (1, groupy) with a particular height such that the row group covers all the slots with
coordinates (x, y) where
1 ≤ x < xmax and groupy ≤ y < groupy+height. Row groups
correspond to tbody
, thead
, and tfoot
elements. Not every row is necessarily in
a row group.
A column group is a set
of columns anchored at a slot
(groupx, 1) with a particular width such that the column group covers all the slots with
coordinates (x, y) where
groupx ≤ x < groupx+width and
1 ≤ y < ymax. Column groups correspond
to colgroup
elements. Not every
column is necessarily in a column group.
Row groups cannot overlap each other. Similarly, column groups cannot overlap each other.
A cell cannot cover slots that are from two or more row groups. It is, however, possible for a cell to be in multiple column groups. All the slots that form part of one cell are part of zero or one row groups and zero or more column groups.
In addition to cells, columns, rows, row groups, and column groups, tables can have a caption
element associated with them. This
gives the table a heading, or legend.
A table model error is an error with the data
represented by table
elements and their
descendants. Documents must not have table model errors.
To determine which elements correspond to which slots in a table associated with a table
element, to determine the dimensions of the
table (xmax and ymax), and to determine if there are
any table model errors,
user agents must use the following algorithm:
Let xmax be zero.
Let ymax be zero.
Let the table be the table represented by the table
element. The xmax and ymax variables give the table's
extent. The table is initially empty.
If the table
element has no table
children, then return the table (which will be
empty), and abort these steps.
Let the current element be the first element child
of the table
element.
If a step in this algorithm ever requires the current
element to be advanced to the next child of the table
when there is no such next child, then
the algorithm must be aborted at that point and the algorithm must
return the table.
While the current element is not one of the
following elements, advance the current element to
the next child of the table
:
If the current element is a caption
, then that is the caption
element associated with the table. Otherwise, it has no associated caption
element.
If the current element is a caption
, then while the current element is not one of the following elements,
advance the current element to the next child of the
table
:
(Otherwise, the current element will already be one of those elements.)
If the current element is a colgroup
, follow these substeps:
Column groups. Process the current element according to the appropriate one of the following two cases:
col
element children
Follow these steps:
Let xstart have the value xmax+1.
Let the current column be the first col
element child of the colgroup
element.
Columns. If the current column
col
element has a span
attribute,
then parse its value using the rules for parsing
non-negative integers.
If the result of parsing the value is not an error or zero, then let span be that value.
Otherwise, if the col
element
has no span
attribute, or if trying to parse the attribute's value resulted in
an error, then let span be 1.
Increase xmax by span.
Let the last span columns in the table
correspond to the current column col
element.
If current column is not the last col
element child of the colgroup
element, then let the current column be the next col
element child of the colgroup
element, and return to the
third step of this innermost group of steps (columns).
Let all the last columns in the table
from x=xstart
to x=xmax
form a new column
group, anchored at the slot (xstart, 1), with width xmax-xstart-1, corresponding to the colgroup
element.
col
element children
If the colgroup
element has
a span
attribute, then parse its value using the rules
for parsing non-negative integers.
If the result of parsing the value is not an error or zero, then let span be that value.
Otherwise, if the colgroup
element has no span
attribute, or if trying to parse the
attribute's value resulted in an error, then let span be 1.
Increase xmax by span.
Let the last span columns in the table
form a new column
group, anchored at the slot (xmax-span+1, 1), with
width span, corresponding to the colgroup
element.
Advance the current element to the next child of
the table
.
While the current element is not one of the
following elements, advance the current element to
the next child of the table
:
If the current element is a colgroup
element, jump to step 1 in these
substeps (column groups).
Let ycurrent be zero. When the algorithm is aborted, if ycurrent does not equal ymax, then that is a table model error.
Let the list of downward-growing cells be an empty list.
Rows. While the current element is not
one of the following elements, advance the current
element to the next child of the table
:
If the current element is a tr
, then run the algorithm
for processing rows (defined below), then return to the previous
step (rows).
Otherwise, run the algorithm for ending a row group.
Let ystart have the value ymax+1.
For each tr
element that is a child of
the current element, in tree order, run the algorithm for processing rows (defined below).
If ymax ≥ ystart, then let all the last rows in the table from y=ystart to y=ymax form a new row group, anchored at the slot with coordinate (1, ystart), with height ymax-ystart+1, corresponding to the current element.
Run the algorithm for ending a row group again.
Return to step 12 (rows).
The algorithm for ending a row group, which is invoked by the set of steps above when starting and ending a block of rows, is:
If ycurrent is less than ymax, then this is a table model error.
While ycurrent is less than ymax, follow these steps:
Increase ycurrent by 1.
Empty the list of downward-growing cells.
The algorithm for processing rows, which is
invoked by the set of steps above for processing tr
elements, is:
Increase ycurrent by 1.
Let xcurrent be 1.
If the tr
element being processed
contains no td
or th
elements, then abort this set of steps and
return to the algorithm above.
Let current cell be the first td
or th
element in
the tr
element being processed.
Cells. While xcurrent is less than or equal to xmax and the slot with coordinate (xcurrent, ycurrent) already has a cell assigned to it, increase xcurrent by 1.
If xcurrent is greater than xmax, increase xmax by 1 (which will make them equal).
If the current cell has a colspan
attribute, then parse that attribute's value, and
let colspan be the result.
If parsing that value failed, or returned zero, or if the attribute is absent, then let colspan be 1, instead.
If the current cell has a rowspan
attribute, then parse that attribute's value, and
let rowspan be the result.
If parsing that value failed or if the attribute is absent, then let rowspan be 1, instead.
If rowspan is zero, then let cell grows downward be true, and set rowspan to 1. Otherwise, let cell grows downward be false.
If xmax < xcurrent+colspan-1, then let xmax be xcurrent+colspan-1.
If ymax < ycurrent+rowspan-1, then let ymax be ycurrent+rowspan-1.
Let the slots with coordinates (x, y) such that xcurrent ≤ x < xcurrent+colspan and ycurrent ≤ y < ycurrent+rowspan be covered by a new cell c, anchored at (xcurrent, ycurrent), which has width colspan and height rowspan, corresponding to the current cell element.
If the current cell element is a th
element, let this new cell c be a header cell; otherwise, let it be a data cell. To
establish what header cells apply to a data cell, use the algorithm for assigning header cells to data
cells described in the next section.
If any of the slots involved already had a cell covering them, then this is a table model error. Those slots now have two cells overlapping.
If cell grows downward is true, then add the tuple {c, xcurrent, colspan} to the list of downward-growing cells.
Increase xcurrent by colspan.
If current cell is the last td
or th
element in
the tr
element being processed, then
abort this set of steps and return to the algorithm above.
Let current cell be the next td
or th
element in
the tr
element being processed.
Return to step 5 (cells).
The algorithm for growing downward-growing cells, used when adding a new row, is as follows:
If the list of downward-growing cells is empty, do nothing. Abort these steps; return to the step that invoked this algorithm.
Otherwise, if ymax is less than ycurrent, then increase ymax by 1 (this will make it equal to ycurrent).
For each {cell, cellx, width} tuple in the list of downward-growing cells, extend the cell cell so that it also covers the slots with coordinates (x, ycurrent), where cellx ≤ x < cellx+width-1.
If, after establishing which elements correspond to which slots, there exists a column in the table containing only slots that do not have a cell anchored to them, then this is a table model error.
Each data cell can be assigned zero or more header cells. The algorithm for assigning header cells to data cells is as follows.
For each header cell in the table, in tree order:
Let (headerx, headery) be the coordinate of the slot to which the header cell is anchored.
Examine the scope
attribute of the th
element corresponding to the header cell, and,
based on its state, apply the appropriate substep:
Assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where headerx < datax ≤ xmax and datay = headery.
Assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where datax = headerx and headery < datay ≤ ymax.
If the header cell is not in a row group, then don't assign the header cell to any data cells.
Otherwise, let (1, groupy) be the slot at which the row group is anchored, let height be the number of rows in the row group, and assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where headerx ≤ datax ≤ xmax and headery ≤ datay < groupy+height.
If the header cell is not in a column group, then don't assign the header cell to any data cells.
Otherwise, let (groupx, 1) be the slot at which the column group is anchored, let width be the number of columns in the column group, and assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where headerx ≤ datax < groupx+width and headery ≤ datay ≤ ymax.
If the header cell is not in the first row of the table, or not in the first cell of a row, then don't assign the header cell to any data cells.
Otherwise, if the header cell is in the first row of the table, assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where datax = headerx and headery < datay ≤ ymax.
Otherwise, the header cell is in the first column of the table; assign the header cell to any data cells anchored at slots with coordinates (datax, datay) where headerx < datax ≤ xmax and datay = headery.
This section will contain definitions of the
form
element and so forth.
This section will be a rewrite of the HTML4 Forms and Web Forms 2.0 specifications, with hopefully no normative changes.
form
elementfieldset
elementinput
elementbutton
elementlabel
elementselect
elementdatalist
elementoptgroup
elementoption
elementtextarea
elementoutput
elementSee WF2 for now
See WF2 for now
script
elementsrc
attribute, depends on the value of the type
attribute.
src
attribute, the element must be empty.
src
async
defer
type
interface HTMLScriptElement : HTMLElement { attribute DOMStringsrc
; attribute booleanasync
; attribute booleandefer
; attribute DOMStringtype
; attribute DOMStringtext
; };
The script
element allows authors to
include dynamic script in their documents.
When the src
attribute is set, the script
element
refers to an external file. The value of the attribute must be a URI (or
IRI).
If the src
attribute is not set, then the script is given by the contents of the
element.
The language of the script may be given by the type
attribute. If the attribute
is present, its value must be a valid MIME type, optionally with
parameters. [RFC2046]
The async
and
defer
attributes
are boolean attributes
that indicate how the script should be executed.
There are three possible modes that can be selected using these
attributes. If the async
attribute is present, then the script will
be executed asynchronously, as soon as it is available. If the async
attribute is not
present but the defer
attribute is present, then the script is
executed when the page has finished parsing. If neither attribute is
present, then the script is downloaded and executed immediately, before
the user agent continues parsing the page. The exact processing details
for these attributes is described below.
The defer
attribute may be specified even if the async
attribute is specified, to cause legacy Web
browsers that only support defer
(and not async
) to fall back to the defer
behavior instead
of the synchronous blocking behavior that is the default.
Changing the src
,
type
, async
, and defer
attributes
dynamically has no direct effect; these attribute are only used at
specific times described below (namely, when the element is inserted into
the document).
script
elements have three
associated pieces of metadata. The first is a flag indicating whether or
not the script block has been "already executed".
Initially, script
elements must have
this flag unset (script blocks, when created, are not "already executed").
When a script
element is cloned, the
"already executed" flag, if set, must be propagated to the clone when it
is created. The second is a flag indicating whether the element was "parser-inserted". This flag is set by the HTML parser and is used to handle document.write()
calls. The third
piece of metadata is the script's
type. It is determined when the script is run, based on the
attributes on the element at that time.
Running a script: when a script block is inserted into a document, the user agent must act as follows:
If the script
element has a type
attribute but
its value is the empty string, or if the script
element has no type
attribute but
it has a language
attribute, and
that attribute's value is the empty string, let the script's type for this script
element be "text/javascript
".
Otherwise, if the script
element
has a type
attribute, let the script's type
for this script
element be the value
of that attribute.
Otherwise, if the element has a language
attribute, let the script's type for this script
element be the concatenation of the
string "text/
" followed by the value of the language
attribute.
If scripting is disabled, or if the
Document
has designMode
enabled, or if the script
element was created by an XML
parser that itself was created as part of the processing of the
innerHTML
attribute's
setter,
or if the user agent does not support the scripting
language given by the script's
type for this script
element, or if the script
element
has its "already executed" flag set, then the
user agent must abort these steps at this point. The script is not
executed.
The user agent must set the element's "already executed" flag.
If the element has a src
attribute, then a load for the specified
content must be started.
Later, once the load has completed, the user agent will have to complete the steps described below.
For performance reasons, user agents may start loading the script as
soon as the attribute is set, instead, in the hope that the element will
be inserted into the document. Either way, once the element is inserted
into the document, the load must have started. If the UA performs such
prefetching, but the element is never inserted in the document, or the
src
attribute is
dynamically changed, then the user agent will not execute the script,
and the load will have been effectively wasted.
Then, the first of the following options that describes the situation must be followed:
defer
attribute,
and the element does not have an async
attribute
async
attribute and a src
attribute
async
attribute but no src
attribute, and the
list of scripts that will execute
asynchronously is not empty
src
attribute and has been flagged as "parser-inserted"
src
attribute
When a script completes loading: If a script whose element was added to one of the lists mentioned above completes loading while the document is still being parsed, then the parser handles it. Otherwise, when a script completes loading, the UA must run the following steps as soon as as any other scripts that may be executing have finished executing:
If the script's element is not the first element in the list, then do nothing yet. Stop going through these steps.
Otherwise, execute the script (that is, the script associated with the first element in the list).
Remove the script's element from the list (i.e. shift out the first entry in the list).
If there are any more entries in the list, and if the script associated with the element that is now the first in the list is already loaded, then jump back to step two to execute it.
If the script is not the first element in the list, then do nothing yet. Stop going through these steps.
Execute the script (the script associated with the first element in the list).
Remove the script's element from the list (i.e. shift out the first entry in the list).
If there are any more scripts in the list, and the element now at
the head of the list had no src
attribute when it was added to the list,
or had one, but its associated script has finished loading, then jump
back to step two to execute the script associated with this element.
Remove the script's element from the list.
The script will be handled when the parser resumes (amazingly enough).
The download of an external script must delay the
load
event.
Executing a script
block: If the load resulted in an error (for example a DNS error, or
an HTTP 404 error), then executing the script must just consist of firing an error
event at the element.
If the load was successful, then first the user agent must fire a load
event at the
element, and then, if scripting is enabled, and
the Document
does not have designMode
enabled, and the Document
is the active
document in its browsing context, the user
agent must execute the script:
If the script is from an external file, then that file must be used as the file to execute.
If the script is inline, then, for scripting languages that consist of
pure text, user agents must use the value of the DOM text
attribute (defined
below) as the script to execute, and for XML-based scripting languages,
user agents must use all the child nodes of the script
element as the script to execute.
In any case, the user agent must execute the script according to the semantics defined by the language associated with the script's type (see the scripting languages section below).
Scripts must be executed in the scope of the browsing context of the element's
Document
.
The element's attributes' values might have changed between
when the element was inserted into the document and when the script has
finished loading, as may its other attributes; similarly, the element
itself might have been taken back out of the DOM, or had other changes
made. These changes do not in any way affect the above steps; only the
values of the attributes at the time the script
element is first inserted into the
document matter.
The DOM attributes src
, type
, async
, and defer
, each must reflect the respective content attributes of the same
name.
The DOM attribute text
must return a concatenation
of the contents of all the text
nodes that are direct children of the script
element (ignoring any other nodes such
as comments or elements), in tree order. On setting, it must act the same
way as the textContent
DOM
attribute.
A user agent is said to support the scripting language if the script's type matches the MIME type of a scripting language that the user agent implements.
The following lists some MIME types and the languages to which they refer:
text/javascript
text/javascript;e4x=1
User agents may support other MIME types and other languages.
When examining types to determine if they support the language, user agents must not ignore unknown MIME parameters — types with unknown parameters must be assumed to be unsupported.
noscript
elementhead
element of an HTML document, if there are no
ancestor noscript
elements.
noscript
elements.
head
element: in any order, zero or more link
elements, zero or more style
elements, and zero or more meta
elements.
head
element: transparent, but there must be no noscript
element descendants.
HTMLElement
.
The noscript
element does not
represent anything. It is used to present different markup to user agents
that support scripting and those that don't support scripting, by
affecting how the document is parsed.
The noscript
element must not be
used in XML documents.
When used in HTML documents, the allowed content
model depends on whether scripting is enabled or not, and whether the
element is in a head
element or not.
In a head
element, if scripting is disabled, then the content model of a
noscript
element must contain only
link
, style
, and meta
elements. If scripting is enabled, then the
content model of a noscript
element
is text, except that invoking the HTML fragment parsing algorithm
with the noscript
element as the context and the text contents as the input must result in a list of nodes that consists only of
link
, style
, and meta
elements.
Outside of head
elements, if scripting is disabled, then the content model of a
noscript
element is transparent, with the additional restriction that
a noscript
element must not have a
noscript
element as an ancestor (that
is, noscript
can't be nested).
Outside of head
elements, if scripting is enabled, then the content model of a
noscript
element is text, except that
the text must be such that running the following algorithm results in a
conforming document with no noscript
elements and no script
elements, and
such that no step in the algorithm causes an HTML
parser to flag a parse error:
script
element from
the document.
noscript
element in the document. For every noscript
element in that list, perform the
following steps:
noscript
element.
noscript
element,
and call these elements the before children.
noscript
element, and call these elements the after
children.
noscript
element.
innerHTML
attribute of the parent element to the value of s.
(This, as a side-effect, causes the noscript
element to be removed from the
document.)
The noscript
element has no other
requirements. In particular, children of the noscript
element are not exempt from form
submission, scripting, and so forth, even when scripting is enabled.
All these contortions are required because, for historical
reasons, the noscript
element causes
the HTML parser to act differently based on whether
scripting is enabled or not. The element is not allowed in XML, because in
XML the parser is not affected by such state, and thus the element would
not have the desired effect.
event-source
elementsrc
interface HTMLEventSourceElement : HTMLElement { attribute DOMString src; };
The event-source
element
represents a target for events generated by a remote server.
The src
attribute, if specified, must give a URI (or IRI) pointing to a resource
that uses the application/x-dom-event-stream
format.
When the element is inserted into the document, if it has the src
attribute
specified, the user agent must act as if the addEventSource()
method on the event-source
element had been invoked with
the URI resulting from resolving the src
attribute's value to an absolute URI.
While the element is in a document, if its src
attribute is
mutated, the user agent must act as if first the removeEventSource()
method on the
event-source
element had been
invoked with the URI resulting from resolving the old value of the
attribute to an absolute URI, and then as if the addEventSource()
method on the element
had been invoked with the URI resulting from resolving the new
value of the src
attribute to an absolute URI.
When the element is removed from the document, if it has the src
attribute
specified, or, when the src
attribute is about to be removed, the user
agent must act as if the removeEventSource()
method on the
event-source
element had been
invoked with the URI resulting from resolving the src
attribute's
value to an absolute URI.
There can be more than one event-source
element per document, but
authors should take care to avoid opening multiple connections to the same
server as HTTP recommends a limit to the number of simultaneous
connections that a user agent can open per server.
The src
DOM
attribute must reflect the content attribute of the same name.
details
elementlegend
element followed by prose content.
open
interface HTMLDetailsElement : HTMLElement { attribute boolean open; };
The details
element represents
additional information or controls which the user can obtain on demand.
The first element child of a details
element, if it is a legend
element,
represents the summary of the details.
If the first element is not a legend
element, the UA should provide its own legend (e.g. "Details").
The open
content attribute is a boolean attribute. If
present, it indicates that the details should be shown to the user. If the
attribute is absent, the details should not be shown.
If the attribute is removed, then the details should be hidden. If the attribute is added, the details should be shown.
The user should be able to request that the details be shown or hidden.
The open
attribute must reflect the open
content
attribute.
Rendering will be described in the Rendering section in
due course. Basically CSS :open and :closed match the element, it's a
block-level element by default, and when it matches :closed it renders as
if it had an XBL binding attached to it whose template was just
<template>▶<content
includes="legend:first-child">Details</content></template>
,
and when it's :open it acts as if it had an XBL binding attached to it
whose template was just <template>▼<content
includes="legend:first-child">Details</content><content/></template>
or some such.
Clicking the legend would make it open/close (and would change the content attribute). Question: Do we want the content attribute to reflect the actual state like this? I think we do, the DOM not reflecting state has been a pain in the neck before. But is it semantically ok?
datagrid
elementtable
element.
table
element.
select
element.
datalist
element.
multiple
disabled
interface HTMLDataGridElement : HTMLElement { attribute DataGridDataProvider data; readonly attribute DataGridSelection selection; attribute boolean multiple; attribute boolean disabled; void updateEverything(); void updateRowsChanged(in RowSpecification row, in unsigned long count); void updateRowsInserted(in RowSpecification row, in unsigned long count); void updateRowsRemoved(in RowSpecification row, in unsigned long count); void updateRowChanged(in RowSpecification row); void updateColumnChanged(in unsigned long column); void updateCellChanged(in RowSpecification row, in unsigned long column); };
One possible thing to be added is a way to detect when a row/selection has been deleted, activated, etc, by the user (delete key, enter key, etc).
This element is defined as interactive, which means it can't contain other interactive elements, despite the fact that we expect it to work with other interactive elements e.g. checkboxes and input fields. It should be called something like a Leaf Interactive Element or something, which counts for ancestors looking in and not descendants looking out.
The datagrid
element represents an
interactive representation of tree, list, or tabular data.
The data being presented can come either from the content, as elements
given as children of the datagrid
element, or from a scripted data provider given by the data
DOM attribute.
The multiple
and disabled
attributes are boolean
attributes. Their effects are described in the processing model
sections below.
The multiple
and disabled
DOM
attributes must reflect the multiple
and
disabled
content attributes respectively.
datagrid
data modelThis section is non-normative.
In the datagrid
data model, data
is structured as a set of rows representing a tree, each row being split
into a number of columns. The columns are always present in the data
model, although individual columns may be hidden in the presentation.
Each row can have child rows. Child rows may be hidden or shown, by closing or opening (respectively) the parent row.
Rows are referred to by the path along the tree that one would take to reach the row, using zero-based indices. Thus, the first row of a list is row "0", the second row is row "1"; the first child row of the first row is row "0,0", the second child row of the first row is row "0,1"; the fourth child of the seventh child of the third child of the tenth row is "9,2,6,3", etc.
The columns can have captions. Those captions are not considered a row in their own right, they are obtained separately.
Selection of data in a datagrid
operates at the row level. If the multiple
attribute is present, multiple rows
can be selected at once, otherwise the user can only select one row at a
time.
The datagrid
element can be
disabled entirely by setting the disabled
attribute.
Columns, rows, and cells can each have specific flags, known as classes,
applied to them by the data provider. These classes affect the functionality of the datagrid
element, and are also passed to the style system. They are similar
in concept to the class
attribute, except that they are not specified on elements but are given by
scripted data providers.
The chains of numbers that give a row's path, or identifier, are represented by objects that implement the RowSpecification interface.
interface RowSpecification { // binding-specific interface };
In ECMAScript, two classes of objects are said to implement this
interface: Numbers representing non-negative integers, and homogeneous
arrays of Numbers representing non-negative integers. Thus,
[1,0,9]
is a RowSpecification, as is 1
on its
own. However, [1,0.2,9]
is not a RowSpecification object, since its second
value is not an integer.
User agents must always represent RowSpecification
s in ECMAScript by
using arrays, even if the path only has one number.
The root of the tree is represented by the empty path; in ECMAScript,
this is the empty array ([]
). Only the getRowCount()
and GetChildAtPosition()
methods ever
get called with the empty path.
The conformance criteria in this section apply to any implementation
of the DataGridDataProvider
, including
(and most commonly) the content author's implementation(s).
// To be implemented by Web authors as a JS object interface DataGridDataProvider { void initialize(in HTMLDataGridElement datagrid); unsigned long getRowCount(in RowSpecification row); unsigned long getChildAtPosition(in RowSpecification parentRow, in unsigned long position); unsigned long getColumnCount(); DOMString getCaptionText(in unsigned long column); void getCaptionClasses(in unsigned long column, in DOMTokenList classes); DOMString getRowImage(in RowSpecification row); HTMLMenuElement getRowMenu(in RowSpecification row); void getRowClasses(in RowSpecification row, in DOMTokenList classes); DOMString getCellData(in RowSpecification row, in unsigned long column); void getCellClasses(in RowSpecification row, in unsigned long column, in DOMTokenList classes); void toggleColumnSortState(in unsigned long column); void setCellCheckedState(in RowSpecification row, in unsigned long column, in long state); void cycleCell(in RowSpecification row, in unsigned long column); void editCell(in RowSpecification row, in unsigned long column, in DOMString data); };
The DataGridDataProvider
interface
represents the interface that objects must implement to be used as custom
data views for datagrid
elements.
Not all the methods are required. The minimum number of methods that
must be implemented in a useful view is two: the getRowCount()
and getCellData()
methods.
Once the object is written, it must be hooked up to the datagrid
using the data
DOM attribute.
The following methods may be usefully implemented:
initialize(datagrid)
datagrid
element
(the one given by the datagrid argument) after it has
first populated itself. This would typically be used to set the initial
selection of the datagrid
element
when it is first loaded. The data provider could also use this method
call to register a select
event handler on the datagrid
in order to monitor selection
changes.
getRowCount(row)
datagrid
must be called first.
Otherwise, this method must always return the same number. For a list (as
opposed to a tree), this method must return 0 whenever it is called with
a row identifier that is not empty.
getChildAtPosition(parentRow, position)
getRowCount(parentRow)
.
getColumnCount()
datagrid
's updateEverything()
method must be
called.
getCaptionText(column)
datagrid
's updateColumnChanged()
method must
be called with the appropriate column index.
getCaptionClasses(column, classes)
datagrid
's updateColumnChanged()
method must
be called with the appropriate column index. Some classes have predefined meanings.
getRowImage(row)
datagrid
's update methods must be called to
update the row in question.
getRowMenu(row)
HTMLMenuElement
object that is to be
used as a context menu for row row, or null if there
is no particular context menu. May be omitted if none of the rows have a
special context menu. As this method is called immediately before showing
the menu in question, no precautions need to be taken if the return value
of this method changes.
getRowClasses(row, classes)
datagrid
's update methods must be
called to update the row in question. Some classes have predefined meanings.
getCellData(row,
column)
datagrid
's update methods must be called to
update the rows that changed. If only one cell changed, the updateCellChanged()
method may be
used.
getCellClasses(row, column, classes)
datagrid
's update methods must be
called to update the rows or cells in question. Some classes have predefined meanings.
toggleColumnSortState(column)
datagrid
when the
user tries to sort the data using a particular column column. The data provider must update its state so that
the GetChildAtPosition()
method returns
the new order, and the classes of the columns returned by getCaptionClasses()
represent the
new sort status. There is no need to tell the datagrid
that it the data has changed, as
the datagrid
automatically assumes
that the entire data model will need updating.
setCellCheckedState(row, column, state)
datagrid
when the
user changes the state of a checkbox cell on row row,
column column. The checkbox should be toggled to the
state given by state, which is a positive integer (1)
if the checkbox is to be checked, zero (0) if it is to be unchecked, and
a negative number (-1) if it is to be set to the indeterminate state.
There is no need to tell the datagrid
that the cell has changed, as the
datagrid
automatically assumes that
the given cell will need updating.
cycleCell(row, column)
datagrid
when the
user changes the state of a cyclable cell on row row,
column column. The data provider should change the
state of the cell to the new state, as appropriate. There is no need to
tell the datagrid
that the cell has
changed, as the datagrid
automatically assumes that the given cell will need updating.
editCell(row, column, data)
datagrid
when the
user edits the cell on row row, column column. The new value of the cell is given by data. The data provider should update the cell
accordingly. There is no need to tell the datagrid
that the cell has changed, as the
datagrid
automatically assumes that
the given cell will need updating.The following classes (for rows, columns, and cells) may be usefully used in conjunction with this interface:
| Class name | Applies to | Description |
|---|---|---|
checked
| Cells | The cell has a checkbox and it is checked. (The cyclable and progress classes override this, though.)
|
cyclable
| Cells | The cell can be cycled through multiple values. (The progress class overrides this, though.)
|
editable
| Cells | The cell can be edited. (The cyclable , progress , checked , unchecked and indeterminate classes override this,
though.)
|
header
| Rows | The row is a heading, not a data row. |
indeterminate
| Cells | The cell has a checkbox, and it can be set to an indeterminate
state. If neither the checked nor unchecked classes are present, then the
checkbox is in that state, too. (The cyclable and progress classes override this, though.)
|
initially-hidden
| Columns | The column will not be shown when the datagrid is initially rendered. If this
class is not present on the column when the datagrid is initially rendered, the column
will be visible if space allows.
|
initially-closed
| Rows | The row will be closed when the datagrid is initially rendered. If neither
this class nor the initially-open class is present on
the row when the datagrid is
initially rendered, the initial state will depend on platform
conventions.
|
initially-open
| Rows | The row will be opened when the datagrid is initially rendered. If neither
this class nor the initially-closed class is present
on the row when the datagrid is
initially rendered, the initial state will depend on platform
conventions.
|
progress
| Cells | The cell is a progress bar. |
reversed
| Columns | If the cell is sorted, the sort direction is descending, instead of ascending. |
selectable-separator
| Rows | The row is a normal, selectable, data row, except that instead of
having data, it only has a separator. (The header
and separator classes override this, though.)
|
separator
| Rows | The row is a separator row, not a data row. (The header
class overrides this, though.)
|
sortable
| Columns | The data can be sorted by this column. |
sorted
| Columns | The data is sorted by this column. Unless the reversed class is also present, the sort
direction is ascending.
|
unchecked
| Cells | The cell has a checkbox and, unless the checked
class is present as well, it is unchecked. (The cyclable and progress classes override this, though.)
|
The user agent must supply a default data provider for the case where
the datagrid
's data
attribute is
null. It must act as described in this section.
The behaviour of the default data provider depends on the nature of the
first element child of the datagrid
.
table
element
getRowCount(row)
: The number of rows returned by
the default data provider for the root of the tree (when row is empty) must be the total number of tr
elements that are children of tbody
elements that are children of the
table
, if there are any such child
tbody
elements. If there are no such
tbody
elements then the number of rows
returned for the root must be the number of tr
elements that are children of the table
.
When row is not empty, the number of rows returned must be zero.
The table
-based default
data provider cannot represent a tree.
Rows in thead
elements
do not contribute to the number of rows returned, although they do
affect the columns and column captions. Rows in tfoot
elements are ignored completely by this algorithm.
getChildAtPosition(row,
i)
: The default data provider
must return the mapping appropriate to the current sort order.
getColumnCount()
: The number
of columns returned must be the number of td
element children in the first tr
element child of the first tbody
element child of the table
, if there are any such tbody
elements. If there are no such tbody
elements, then it must be the number of
td
element children in the first tr
element child of the table
, if any, or otherwise 1. If the number
that would be returned by these rules is 0, then 1 must be returned
instead.
getCaptionText(i)
: If the table
has no thead
element child, or if its first thead
element child has no tr
element child, the default data provider must
return the empty string for all captions. Otherwise, the value of the
textContent
attribute of the
ith th
element child
of the first tr
element child of the
first thead
element child of the
table
element must be returned. If
there is no such th
element, the empty
string must be returned.
getCaptionClasses(i, classes)
: If the table
has no thead
element child, or if its first thead
element child has no tr
element child, the default data provider must
not add any classes for any of the captions. Otherwise, each class in
the class
attribute
of the ith th
element
child of the first tr
element child of
the first thead
element child of the
table
element must be added to the
classes. If there is no such th
element, no classes must be added. The user
agent must then:
sorted
and reversed
classes.
table
element has a class
attribute that
includes the sortable
class, add the sortable
class.
sorted
class.
reversed
class as well.
The various row- and cell- related methods operate relative to a particular element, the element of the row or cell specified by their arguments.
For rows: Since the default data provider for a
table
always returns 0 as the number
of children for any row other than the root, the path to the row passed
to these methods will always consist of a single number. In the prose
below, this number is referred to as i.
If the table
has tbody
element children, the element for the
ith row is the ith tr
element that is a child of a tbody
element that is a child of the table
element. If the table
does not have tbody
element children, then the element for
the ith real row is the ith
tr
element that is a child of the
table
element.
For cells: Given a row and its element, the row's
ith cell's element is the ith
td
element child of the row element.
The colspan
and rowspan
attributes are ignored by this
algorithm.
getRowImage(i)
: If the row's first cell's element
has an img
element child, then the URI
of the row's image is the URI of the first img
element child of the row's first cell's
element. Otherwise, the URI of the row's image is the empty string.
getRowMenu(i)
: If the row's first cell's element
has a menu
element child, then the
row's menu is the first menu
element
child of the row's first cell's element. Otherwise, the row has no menu.
getRowClasses(i, classes)
: The default data provider
must never add a class to the row's classes.
toggleColumnSortState(i)
: If the data is already being
sorted on the given column, then the user agent must change the current
sort mapping to be the inverse of the current sort mapping; if the sort
order was ascending before, it is now descending, otherwise it is now
ascending. Otherwise, if the current sort column is another column, or
the data model is currently not sorted, the user agent must create a new
mapping, which maps rows in the data model to rows in the DOM so that
the rows in the data model are sorted by the specified column, in
ascending order. (Which sort comparison operator to use is left up to
the UA to decide.)
When the sort mapping is changed, the values returned by the getChildAtPosition()
method for
the default data provider will
change appropriately.
getCellData(i, j)
, getCellClasses(i, j, classes)
, getCellCheckedState(i,
j, state)
, cycleCell(i, j)
, and editCell(i, j, data)
: See the common definitions
below.
The data provider must call the datagrid
's update methods appropriately
whenever the descendants of the datagrid
mutate. For example, if a tr
is removed, then the updateRowsRemoved()
methods would
probably need to be invoked, and any change to a cell or its descendants
must cause the cell to be updated. If the table
element stops being the first child of
the datagrid
, then the data
provider must call the updateEverything()
method on the
datagrid
. Any change to a cell
that is in the column that the data provider is currently using as its
sort column must also cause the sort to be reperformed, with a call to
updateEverything()
if the change did
affect the sort order.
select
or
datalist
element
The default data provider must return 1 for the column count, the empty string for the column's caption, and must not add any classes to the column's classes.
For the rows, assume the existence of a node filter view of the
descendants of the first element child of the datagrid
element (the select
or datalist
element), that skips all nodes other than
optgroup
and option
elements, as well as any
descendents of any option
elements.
Given a path row, the corresponding element is the one obtained by drilling into the view, taking the child given by the path each time.
Given the following XML markup:
<datagrid> <select> <!-- the options and optgroups have had their labels and values removed to make the underlying structure clearer --> <optgroup> <option/> <option/> </optgroup> <optgroup> <option/> <optgroup id="a"> <option/> <option/> <bogus/> <option id="b"/> </optgroup> <option/> </optgroup> </select> </datagrid>
The path "1,1,2" would select the element with ID "b". In the filtered view, the text nodes, comment nodes, and bogus elements are ignored; so for instance, the element with ID "a" (path "1,1") has only 3 child nodes in the view.
getRowCount(row)
must
drill through the view to find the element corresponding to the method's
argument, and return the number of child nodes in the filtered view that
the corresponding element has. (If the row is empty,
the corresponding element is the select
element at the root
of the filtered view.)
getChildAtPosition(row,
position)
must return position. (The select
/datalist
default data provider does not support sorting the data grid.)
getRowImage(i)
must
return the empty string, getRowMenu(i)
must
return null.
getRowClasses(row, classes)
must add the classes from the
following list to classes when their condition is
met:
optgroup
element: header
class
attribute contains
the closed
class: initially-closed
class
attribute contains
the open
class: initially-open
The getCellData(row, cell)
method must return the value of the
label
attribute if the row's corresponding element is an optgroup
element, otherwise, if the row's corresponding
element is an option
element, its label
attribute if it has one, otherwise
the value of its textContent
DOM
attribute.
The getCellClasses(row, cell, classes)
method must
add no classes.
autoselect some rows when initialised, reflect the selection in the select, reflect the multiple attribute somehow.
The data provider must call the datagrid
's update methods appropriately
whenever the descendants of the datagrid
mutate.
The default data provider must return 1 for the column count, the empty string for the column's caption, and must not add any classes to the column's classes.
For the rows, assume the existence of a node filter view of the
descendants of the datagrid
that
skips all nodes other than li
, h1
-h6
, and hr
elements, and skips any descendants of menu
elements.
Given this view, each element in the view represents a row in the data model. The element corresponding to a path row is the one obtained by drilling into the view, taking the child given by the path each time. The element of the row of a particular method call is the element given by drilling into the view along the path given by the method's arguments.
getRowCount(row)
must
return the number of child elements in this view for the given row, or
the number of elements at the root of the view if the row is empty.
In the following example, the elements are identified by the paths given by their child text nodes:
<datagrid> <ol> <li> row 0 </li> <li> row 1 <ol> <li> row 1,0 </li> </ol> </li> <li> row 2 </li> </ol> </datagrid>
In this example, only the li
elements
actually appear in the data grid; the ol
element does not affect the data grid's processing model.
getChildAtPosition(row,
position)
must return position. (The generic default data provider does not
support sorting the data grid.)
getRowImage(i)
must
return the URI of the image given by the first img
element descendant (in the real DOM) of the
row's element, that is not also a descendant of another element in the
filtered view that is a descendant of the row's element.
In the following example, the row with path "1,0" returns "http://example.com/a" as its image URI, and the other rows (including the row with path "1") return the empty string:
<datagrid> <ol> <li> row 0 </li> <li> row 1 <ol> <li> row 1,0 <img src="http://example.com/a" alt=""> </li> </ol> </li> <li> row 2 </li> </ol> </datagrid>
getRowMenu(i)
must
return the first menu
element
descendant (in the real DOM) of the row's element, that is not also a
descendant of another element in the filtered view that is a decsendant
of the row's element. (This is analogous to the image case above.)
getRowClasses(i, classes)
must add the classes from the
following list to classes when their condition is
met:
class
attribute contains the closed
class: initially-closed
class
attribute contains the open
class: initially-open
h1
-h6
element:
header
hr
element: separator
The getCellData(i, j)
, getCellClasses(i, j, classes)
, getCellCheckedState(i,
j, state)
, cycleCell(i, j)
, and editCell(i, j, data)
methods must act as described in the common definitions
below, treating the row's element as being the cell's element.
selection handling?
The data provider must call the datagrid
's update methods appropriately
whenever the descendants of the datagrid
mutate.
The data provider must return 0 for the number of rows, 1 for the
number of columns, the empty string for the first column's caption, and
must add no classes when asked for that column's classes. If the
datagrid
's child list changes such
that there is a first element child, then the data provider must call
the updateEverything()
method on the
datagrid
.
These definitions are used for the cell-specific methods of the default
data providers (other than in the
select
/datalist
case). How they behave is based
on the contents of an element that represents the cell given by their
first two arguments. Which element that is is defined in the previous
section.
If the first element child of a cell's element is a
select
element that has a no multiple
attribute and has at least
one option
element descendent, then the cell acts as a
cyclable cell.
The "current" option
element is the selected
option
element, or the first option
element if
none is selected.
The getCellData()
method must return the
textContent
of the current
option
element (the label
attribute is ignored in this context as the optgroup
s
are not displayed).
The getCellClasses()
method must add the
cyclable
class and then all the classes of
the current option
element.
The cycleCell()
method must change the
selection of the select
element such that the next
option
element after the current option
element is the only one that is selected (in tree
order). If the current option
element is the last
option
element descendent of the select
, then
the first option
element descendent must be selected
instead.
The setCellCheckedState()
and editCell()
methods must do nothing.
If the first element child of a cell's element is a progress
element, then the cell acts as a
progress bar cell.
The getCellData()
method must return the
value returned by the progress
element's position
DOM attribute.
The getCellClasses()
method must add the
progress
class.
The setCellCheckedState()
, cycleCell()
, and editCell()
methods must do nothing.
If the first element child of a cell's element is an
input
element that has a type
attribute with the value checkbox
, then the cell acts as a check box cell.
The getCellData()
method must return the
textContent
of the cell element.
The getCellClasses()
method must add the
checked
class if the input
element is checked, and the unchecked
class otherwise.
The setCellCheckedState()
method must
set the input
element's checkbox state to checked if the method's third
argument is 1, and to unchecked otherwise.
The cycleCell()
and editCell()
methods must do nothing.
If the first element child of a cell's element is an
input
element that has a type
attribute with the value text
or that has no type
attribute at all, then the cell acts
as an editable cell.
The getCellData()
method must return the
value
of the input
element.
The getCellClasses()
method must add the
editable
class.
The editCell()
method must set the
input
element's value
DOM attribute to the value of the third argument to the method.
The setCellCheckedState()
and cycleCell()
methods must do nothing.
datagrid
elementA datagrid
must be disabled until
its end tag has been parsed (in the case of a datagrid
element in the original document
markup) or until it has been inserted into the document (in the case of a
dynamically created element). After that point, the element must fire a
single load
event at
itself, which doesn't bubble and cannot be canceled.
The end-tag parsing thing should be moved to the parsing section.
The datagrid
must then populate
itself using the data provided by the data provider assigned to the data
DOM attribute.
After the view is populated (using the methods described below), the
datagrid
must invoke the initialize()
method on the data provider
specified by the data
attribute, passing itself (the HTMLDataGridElement
object) as the
only argument.
When the data
attribute is null, the datagrid
must
use the default data provider described in the previous section.
To obtain data from the data provider, the element must invoke methods on the data provider object in the following ways:
getColumnCount()
method with no
arguments. The return value is the number of columns. If the return value
is zero or negative, not an integer, or simply not a numeric type, or if
the method is not defined, then 1 must be used instead.
getCaptionText()
method with the index
of the column in question. The index i must be in the
range 0 ≤ i < N, where N is the total number of columns. The return value is the
string to use when referring to that column. If the method returns null
or the empty string, the column has no caption. If the method is not
defined, then none of the columns have any captions.
getCaptionClasses()
method with the
index of the column in question, and an object implementing the DOMTokenList
interface, associated with
an anonymous empty string. The index i must be in the
range 0 ≤ i < N, where N is the total number of columns. The tokens contained in
the string underlying DOMTokenList
object when the method
returns represent the classes that apply to the given column. If the
method is not defined, no classes apply to the column.
initially-hidden
class applies to the
column. If it does, then the column should not be initially included; if
it does not, then the column should be initially included.
sortable
class applies to the column. If it
does, then the user should be able to ask the UA to display the data
sorted by that column; if it does not, then the user agent must not allow
the user to ask for the data to be sorted by that column.
sorted
class applies to the column. If it does, then that column is the sorted
column, otherwise it is not.
sorted
class applies to that column. The first
column that has that class, if any, is the sorted column. If none of the
columns have that class, there is no sorted column.
reversed
class applies to the column. If it
does, then the sort direction is descending (down; first rows have the
highest values), otherwise it is ascending (up; first rows have the
lowest values).
getRowCount()
method with a RowSpecification
object representing
the empty path as its only argument. The return value is the number of
rows at the top level of the data grid. If the return value of the method
is negative, not an integer, or simply not a numeric type, or if the
method is not defined, then zero must be used instead.
getRowCount()
method with a RowSpecification
object representing
the path to the row in question. The return value is the number of child
rows for the given row. If the return value of the method is negative,
not an integer, or simply not a numeric type, or if the method is not
defined, then zero must be used instead.
Invoke the getChildAtPosition()
method with a
RowSpecification
object
representing the path to the parent of the rows that are being rendered
as the first argument, and the position that is being rendered as the
second argument. The return value is the index of the row to render in
that position.
If the rows are:
...and the getChildAtPosition()
method is
implemented as follows:
function getChildAtPosition(parent, child) { // always return the reverse order return getRowCount(parent)-child-1; }
...then the rendering would actually be:
If the return value of the method is negative, larger than the number
of rows that the getRowCount()
method reported for that
parent, not an integer, or simply not a numeric type, then the entire
data grid should be disabled. Similarly, if the method returns the same
value for two or more different values for the second argument (with the
same first argument, and assuming that the data grid hasn't had relevant
update methods invoked in the meantime), then the data grid should be
disabled. Instead of disabling the data grid, the user agent may act as
if the getChildAtPosition()
method was
not defined on the data provider (thus disabling sorting for that data
grid, but still letting the user interact with the data). If the method
is not defined, then the return value must be assumed to be the same as
the second argument (an indentity transform; the data is rendered in its
natural order).
getRowClasses()
method with a RowSpecification
object representing
the row in question, and a DOMTokenList
associated with an empty
string. The tokens contained in the DOMTokenList
object's underlying string
when the method returns represent the classes that apply to the row in
question. If the method is not defined, no classes apply to the row.
header
class applies to the row, then it is not a data row, it is a subheading.
The data from the first cell of the row is the text of the subheading,
the rest of the cells must be ignored. Otherwise, if the separator
class applies to the row, then in
the place of the row, a separator should be shown. Otherwise, if the
selectable-separator
class
applies to the row, then the row should be a data row, but represented as
a separator. (The difference between a separator
and a selectable-separator
is that the
former is not an item that can be actually selected, whereas the second
can be selected and thus has a context menu that applies to it, and so
forth.) For both kinds of separator rows, the data of the rows' cells
must all be ignored. If none of those three classes apply then the row is
a simple data row.
initially-open
class applies to the
row, then it should be initially open. Otherwise, if the initially-closed
class applies to the
row, then it must be initially closed. Otherwise, if neither class
applies to the row, or if the row is not openable, then the initial state
of the row is entirely up to the UA.getRowImage()
method with a RowSpecification
object representing
the row in question. The return value is a string representing a URI (or
IRI) to an image. Relative URIs must be interpreted relative to the
datagrid
's base URI. If the method
returns the empty string, null, or if the method is not defined, then the
row has no associated image.
getRowMenu()
method with a RowSpecification
object representing
the row in question. The return value is a reference to an object
implementing the HTMLMenuElement
interface, i.e. a
menu
element DOM node. (This element
must then be interpreted as described in the section on context menus to
obtain the actual context menu to use.)
If the method returns something that is not an HTMLMenuElement
, or if the method is
not defined, then the row has no associated context menu. User agents may
provide their own default context menu, and may add items to the
author-provided context menu. For example, such a menu could allow the
user to change the presentation of the datagrid
element.
getCellData()
method with the first
argument being a RowSpecification
object representing
the row of the cell in question and the second argument being the index
of the cell's column. The second argument must be a non-negative integer
less than the total number of columns. The return value is the value of
the cell. If the return value is null or the empty string, or if the
method is not defined, then the cell has no data. (For progress bar
cells, the cell's value must be further interpreted, as described below.)
getCellClasses()
method with the first
argument being a RowSpecification
object representing
the row of the cell in question, the second argument being the index of
the cell's column, and the third being an object implementing the
DOMTokenList
interface,
associated with an empty string. The second argument must be a
non-negative integer less than the total number of columns. The tokens
contained in the DOMTokenList
object's underlying string when the method returns represent the classes
that apply to that cell. If the method is not defined, no classes apply
to the cell.
progress
class applies to the cell, it is a
progress bar. Otherwise, if the cyclable
class applies to the cell, it is a
cycling cell whose value can be cycled between multiple states.
Otherwise, none of these classes apply, and the cell is a simple text
cell.
checked
, unchecked
, or indeterminate
classes applies to the
cell. If any of these are present, then the cell has a checkbox,
otherwise none are present and the cell does not have a checkbox. If the
cell has no checkbox, check whether the editable
class applies to the cell. If it
does, then the cell value is editable, otherwise the cell value is
static.
checked
class applies to the cell. If it does,
the cell is checked. Otherwise, check whether the unchecked
class applies to the cell. If it
does, the cell is unchecked. Otherwise, the indeterminate
class appplies to the cell
and the cell's checkbox is in an indeterminate state. When the indeterminate
class appplies to the
cell, the checkbox is a tristate checkbox, and the user can set it to the
indeterminate state. Otherwise, only the checked
and/or unchecked
classes apply to the cell, and the
cell can only be toggled betwen those two states.
If the data provider ever raises an exception while the datagrid
is invoking one of its methods, the
datagrid
must act, for the purposes
of that particular method call, as if the relevant method had not been
defined.
A RowSpecification
object
p with n path components passed to
a method of the data provider must fulfill the constraint
0 ≤ pi < m-1
for all integer values of i in the range
0 ≤ i < n-1, where m is the value that
was last returned by the getRowCount()
method when it was passed the
RowSpecification
object q with i-1 items, where
pi = qi for all integer values of i in the range 0 ≤ i < n-1, with any
changes implied by the update methods taken into account.
The data model is considered stable: user
agents may assume that subsequent calls to the data provider methods will
return the same data, until one of the update methods is called on the
datagrid
element. If a user agent is
returned inconsistent data, for example if the number of rows returned by
getRowCount()
varies in ways that do not
match the calls made to the update methods, the user agent may disable the
datagrid
. User agents that do not
disable the datagrid
in inconsistent
cases must honour the most recently returned values.
User agents may cache returned values so that the data provider is never
asked for data that could contradict earlier data. User agents must not
cache the return value of the getRowMenu
method.
The exact algorithm used to populate the data grid is not defined here, since it will differ based on the presentation used. However, the behaviour of user agents must be consistent with the descriptions above. For example, it would be non-conformant for a user agent to make cells have both a checkbox and be editable, as the descriptions above state that cells that have a checkbox cannot be edited.
datagrid
Whenever the data
attribute is set to a new value, the
datagrid
must clear the current
selection, remove all the displayed rows, and plan to repopulate itself
using the information from the new data provider at the earliest
opportunity.
There are a number of update methods that can be invoked on the datagrid
element to cause it to refresh
itself in slightly less drastic ways:
When the updateEverything()
method is called, the user agent must repopulate the entire datagrid
. If the number of rows decreased,
the selection must be updated appropriately. If the number of rows
increased, the new rows should be left unselected.
When the updateRowsChanged(row, count)
method is
called, the user agent must refresh the rendering of the rows starting
from the row specified by row, and including the count next siblings of the row (or as many next siblings as
it has, if that is less than count), including all
descendant rows.
When the updateRowsInserted(row, count)
method is
called, the user agent must assume that count new rows
have been inserted, such that the first new row is indentified by row. The user agent must update its rendering and the
selection accordingly. The new rows should not be selected.
When the updateRowsRemoved(row, count)
method is
called, the user agent must assume that count rows
have been removed starting from the row that used to be identifier by row. The user agent must update its rendering and the
selection accordingly.
The updateRowChanged(row)
method must be exactly equivalent to
calling updateRowsChanged(row,
1)
.
When the updateColumnChanged(column)
method is called, the user agent must
refresh the rendering of the specified column column,
for all rows.
When the updateCellChanged(row, column)
method is
called, the user agent must refresh the rendering of the cell on row row, in column column.
Any effects the update methods have on the datagrid
's selection is not considered a
change to the selection, and must therefore not fire the select
event.
These update methods should only be called by the data provider, or code
acting on behalf of the data provider. In particular, calling the updateRowsInserted()
and updateRowsRemoved()
methods without
actually inserting or removing rows from the data provider is likely to result in inconsistent
renderings, and the user agent is likely to disable the data grid.
This section only applies to interactive user agents.
If the datagrid
element has a disabled
attribute, then the user agent must disable the datagrid
, preventing the user from
interacting with it. The datagrid
element should still continue to update itself when the data provider
signals changes to the data, though. Obviously, conformance requirements
stating that datagrid
elements must
react to users in particular ways do not apply when one is disabled.
If a row is openable, then the user should be able to toggle its open/closed state. When a row's open/closed state changes, the user agent must update the rendering to match the new state.
If a cell is a cell whose value can be cycled
between multiple states, then the user must be able to activate the
cell to cycle its value. When the user activates this "cycling" behaviour
of a cell, then the datagrid
must
invoke the data provider's cycleCell()
method, with a RowSpecification
object representing
the cell's row as the first argument and the cell's column index as the
second. The datagrid
must act as if
the datagrid
's updateCellChanged()
method had been
invoked with those same arguments immediately before the provider's method
was invoked.
When a cell has a checkbox, the user must be
able to set the checkbox's state. When the user changes the state of a
checkbox in such a cell, the datagrid
must invoke the data provider's
setCellCheckedState()
method, with
a RowSpecification
object
representing the cell's row as the first argument, the cell's column index
as the second, and the checkbox's new state as the third. The state should
be represented by the number 1 if the new state is checked, 0 if the new
state is unchecked, and -1 if the new state is indeterminate (which must
only be possible if the cell has the indeterminate
class set). The datagrid
must act as if the datagrid
's updateCellChanged()
method had been
invoked, specifying the same cell, immediately before the provider's
method was invoked.
If a cell is editable, the user must be able to
edit the data for that cell, and doing so must cause the user agent to
invoke the editCell()
method of the data provider with
three arguments: a RowSpecification
object representing
the cell's row, the cell's column's index, and the new text entered by the
user. The user agent must act as if the updateCellChanged()
method had been
invoked, with the same row and column specified, immediately before the
provider's method was invoked.
This section only applies to interactive user agents. For other user
agents, the selection
attribute must return null.
interface DataGridSelection { readonly attribute unsigned long length; RowSpecification item(in unsigned long index); boolean isSelected(in RowSpecification row); void setSelected(in RowSpecification row, in boolean selected); void selectAll(); void invert(); void clear(); };
Each datagrid
element must keep
track of which rows are currently selected. Initially no rows are
selected, but this can be changed via the methods described in this
section.
The selection of a datagrid
is
represented by its selection
DOM attribute,
which must be a DataGridSelection
object.
DataGridSelection
objects
represent the rows in the selection. In the selection the rows must be
ordered in the natural order of the data provider (and not, e.g., the
rendered order). Rows that are not rendered because one of their ancestors
is closed must share the same selection state as their nearest rendered
ancestor. Such rows are not considered part of the selection for the
purposes of iterating over the selection.
This selection API doesn't allow for hidden rows to be selected because it is trivial to create a data provider that has infinite depth, which would then require the selection to be infinite if every row, including every hidden row, was selected.
The length
attribute
must return the number of rows currently present in the selection. The
item(index)
method must return the indexth row in the selection. If the argument is out of
range (less than zero or greater than the number of selected rows minus
one), then it must raise an INDEX_SIZE_ERR
exception. [DOM3CORE]
The isSelected()
method must return the selected state of the row specified by its
argument. If the specified row exists and is selected, it must return
true, otherwise it must return false.
The setSelected()
method takes two arguments, row and selected. When invoked, it must set the selection state of
row row to selected if selected is
true, and unselected if it is false. If row is not a
row in the data grid, the method must raise an INDEX_SIZE_ERR
exception. If the specified row is not rendered because one of its
ancestors is closed, the method must do nothing.
The selectAll()
method must mark all the rows in the data grid as selected. After a call
to selectAll()
, the length
attribute will return the number of rows in the data grid, not counting
children of closed rows.
The invert()
method must
cause all the rows in the selection that were marked as selected to now be
marked as not selected, and vice versa.
The clear()
method must
mark all the rows in the data grid to be marked as not selected. After a
call to clear()
, the length
attribute will return zero.
If the datagrid
element has a multiple
attribute, then the user must be able to select any number of rows (zero
or more). If the attribute is not present, then the user must only be able
to select a single row at a time, and selecting another one must unselect
all the other rows.
This only applies to the user. Scripts can select multiple
rows even when the multiple
attribute is absent.
Whenever the selection of a datagrid
changes, whether due to the user
interacting with the element, or as a result of calls to methods of the
selection
object, a select
event that bubbles but is not cancelable must be fired on the datagrid
element. If changes are made to the
selection via calls to the object's methods during the execution of a
script, then the select
events must be
coalesced into one, which must then be fired when the
script execution has completed.
The DataGridSelection
interface has no
relation to the Selection
interface.
This section only applies to interactive user agents.
Each datagrid
element must keep
track of which columns are currently being rendered. User agents should
initially show all the columns except those with the initially-hidden
class, but may allow
users to hide or show columns. User agents should initially display the
columns in the order given by the data provider, but may allow this order
to be changed by the user.
If columns are not being used, as might be the case if the data grid is being presented in an icon view, or if an overview of data is being read in an aural context, then the text of the first column of each row should be used to represent the row.
If none of the columns have any captions (i.e. if the data provider does
not provide a getCaptionText()
method), then user
agents may avoid showing the column headers at all. This may prevent the
user from performing actions on the columns (such as reordering them,
changing the sort column, and so on).
Whatever the order used for rendering, and irrespective of
what columns are being shown or hidden, the "first column" as referred to
in this specification is always the column with index zero, and the "last
column" is always the column with the index one less than the value
returned by the getColumnCount()
method of the data
provider.
If a column is sortable, then the user must
be able to invoke it to sort the data. When the user does so, then the
datagrid
must invoke the data
provider's toggleColumnSortState()
method,
with the column's index as the only argument. The datagrid
must then act as if the
datagrid
's updateEverything()
method had been
invoked.
command
elementtype
label
icon
hidden
disabled
checked
radiogroup
default
title
attribute has special semantics on this
element.
interface HTMLCommandElement : HTMLElement { attribute DOMString type; attribute DOMString label; attribute DOMString icon; attribute boolean hidden; attribute boolean disabled; attribute boolean checked; attribute DOMString radiogroup; attribute boolean default; void click(); // shadowsHTMLElement
.click()
};
The Command
interface must also be implemented by this element.
The command
element represents a
command that the user can invoke.
The type
attribute indicates the kind of command: either a normal command with an
associated action, or a state or option that can be toggled, or a
selection of one item from a list of items.
The attribute's value must be either "command
",
"checkbox
", or "radio
",
denoting each of these three types of commands respectively. The attribute
may also be omitted if the element is to represent the first of these
types, a simple command.
The label
attribute gives the name of the command, as shown to the user.
The title
attribute gives a hint describing the command, which might be shown to the
user to help him.
The icon
attribute gives a picture that represents the command. If the attribute is
specified, the attribute's value must contain a URI (or IRI).
The hidden
attribute is a boolean attribute that, if present,
indicates that the command is not relevant and is to be hidden.
The disabled
attribute is a boolean attribute that, if present, indicates that
the command is not available in the current state.
The distinction between Disabled State and Hidden State is subtle. A command should be Disabled if, in the same context, it could be enabled if only certain aspects of the situation were changed. A command should be marked as Hidden if, in that situation, the command will never be enabled. For example, in the context menu for a water faucet, the command "open" might be Disabled if the faucet is already open, but the command "eat" would be marked Hidden since the faucet could never be eaten.
The checked
attribute is a boolean attribute that, if present, indicates that
the command is selected.
The radiogroup
attribute
gives the name of the group of commands that will be toggled when the
command itself is toggled, for commands whose type
attribute has
the value "radio
". The scope of the name is the
child list of the parent element.
If the command
element is used when
generating a context
menu, then the default
attribute indicates,
if present, that the command is the one that would have been invoked if
the user had directly activated the menu's subject instead of using its
context menu. The default
attribute is a boolean attribute.
Need an example that shows an element that, if
double-clicked, invokes an action, but that also has a context menu,
showing the various command
attributes off, and that has a default command.
The type
, label
, icon
, hidden
, disabled
, checked
, radiogroup
, and default
DOM
attributes must reflect their respective namesake
content attributes.
The click()
method's behaviour depends on the value of the type
attribute of the
element, as follows:
type
attribute has the value checkbox
If the element has a checked
attribute, the UA must remove that
attribute. Otherwise, the UA must add a checked
attribute, with the literal value checked
. The UA
must then fire a click
event
at the element.
type
attribute has the value radio
If the element has a parent, then the UA must walk the list of child
nodes of that parent element, and for each node that is a command
element, if that element has a radiogroup
attribute whose value exactly
matches the current element's (treating missing radiogroup
attributes as if they were the
empty string), and has a checked
attribute, must remove that
attribute and fire a click
event at the element.
Then, the element's checked
attribute attribute must be set to
the literal value checked
and a click
event must be fired at
the element.
The UA must fire a click
event at the element.
Firing a synthetic click
event
at the element does not cause any of the actions described above to
happen.
should change all the above so it actually is just trigged by a click event, then we could remove the shadowing click() method and rely on actual events.
Need to define the command="" attribute
command
elements are not
rendered unless they form part of a menu.
menu
elementmenu
element ancestor:
phrasing content.
menu
element ancestor:
where phrasing content is expected.
li
elements.
type
label
autosubmit
interface HTMLMenuElement : HTMLElement { attribute DOMString type; attribute DOMString label; attribute boolean autosubmit; };
The menu
element represents a list of
commands.
The type
attribute is an enumerated attribute indicating
the kind of menu being declared. The attribute has three states. The context
keyword maps to the context menu state, in which
the element is declaring a context menu. The toolbar
keyword maps to the tool bar state, in which the
element is declaraing a tool bar. The attribute may also be omitted. The
missing value default is the list state, which indicates that the element is merely a list
of commands that is neither declaring a context menu nor defining a tool
bar.
If a menu
element's type
attribute is in the
context menu state,
then the element represents the commands of a context menu, and the user
can only interact with the commands if that context menu is activated.
If a menu
element's type
attribute is in the
tool bar state, then the
element represents a list of active commands that the user can immediately
interact with.
If a menu
element's type
attribute is in the
list state, then the element either
represents an unordered list of items (each represented by an li
element), each of which represents a command that
the user may perform or activate, or, if the element has no li
element children, prose
content describing available commands.
The label
attribute gives the label of the menu. It is used by user agents to
display nested menus in the UI. For example, a context menu containing
another menu would use the nested menu's label
attribute for the submenu's menu label.
The autosubmit
attribute is a boolean attribute that, if present, indicates that
selections made to form controls in this menu are to result in the
control's form being immediately submitted.
If a change
event bubbles through a
menu
element, then, in addition to any
other default action that that event might have, the UA must act as if the
following was an additional default action for that event: if (when it
comes time to execute the default action) the menu
element has an autosubmit
attribute, and the target of the event is an input
element,
and that element has a type
attribute
whose value is either radio
or checkbox
, and the input
element in question
has a non-null form
DOM attribute, then
the UA must invoke the submit()
method
of the form
element indicated by that DOM attribute.
This section is non-normative.
...
A menu (or tool bar) consists of a list of zero or more of the following components:
The list corresponding to a particular menu
element is built by iterating over its child
nodes. For each child node in tree order, the
required behaviour depends on what the node is, as follows:
command
element with a default
attribute, mark the command as being a default command.
hr
element
option
element that has a value
attribute set to the empty string,
and has a disabled
attribute, and
whose textContent
consists of a
string of one or more hyphens (U+002D HYPHEN-MINUS)
li
element
li
element.
menu
element with no label
attribute
select
element
menu
or select
element,
then append another separator.
menu
element with a label
attribute
optgroup
element
label
attribute as the label of the menu. The submenu
must be constructed by taking the element and creating a new menu for it
using the complete process described in this section.
We should support label
in the algorithm above
-- just iterate through the contents like with li
, to support input
elements in
label
elements. Also, optgroup
elements without
labels should be ignored (maybe? or at least should say they have no label
so that they are dropped below), and select
elements inside
label
elements may need special processing.
Once all the nodes have been processed as described above, the user agent must the post-process the menu as follows:
The contextmenu
attribute gives the
element's context menu. The
value must be the ID of a menu
element in
the DOM. If the node that would be obtained by the invoking the
getElementById()
method using the attribute's value as the
only argument is null or not a menu
element, then the element has no assigned context menu. Otherwise, the
element's assigned context menu is the element so identified.
When an element's context menu is requested (e.g. by the user
right-clicking the element, or pressing a context menu key), the UA must
fire a contextmenu
event on
the element for which the menu was requested.
Typically, therefore, the firing of the contextmenu
event will be the default
action of a mouseup
or keyup
event. The exact sequence of events is
UA-dependent, as it will vary based on platform conventions.
The default action of the contextmenu
event depends on whether the
element has a context menu assigned (using the contextmenu
attribute) or not. If it does not, the default action must be for the user
agent to show its default context menu, if it has one.
If the element does have a context menu assigned, then the user
agent must fire a show
event
on the relevant menu
element.
The default action of this event is that the user agent must
show a context menu built from the menu
element.
The user agent may also provide access to its default context menu, if any, with the context menu shown. For example, it could merge the menu items from the two menus together, or provide the page's context menu as a submenu of the default menu.
If the user dismisses the menu without making a selection, nothing in particular happens.
If the user selects a menu item that represents a command, then the UA must invoke that command's Action.
Context menus must not, while being shown, reflect changes in the DOM;
they are constructed as the default action of the show
event and must remain like that until
dismissed.
User agents may provide means for bypassing the context menu processing
model, ensuring that the user can always access the UA's default context
menus. For example, the user agent could handle right-clicks that have the
Shift key depressed in such a way that it does not fire the contextmenu
event and instead always shows
the default context menu.
The contextMenu
attribute must reflect the contextmenu
content attribute.
Toolbars are a kind of menu that is always visible.
When a menu
element has a type
attribute with the
value toolbar
, then the user agent must build the menu
for that menu
element and render it in the document in
a position appropriate for that menu
element.
The user agent must reflect changes made to the menu
's DOM immediately in the UI.
A command is the abstraction behind menu items, buttons, and links. Once a command is defined, other parts of the interface can refer to the same command, allowing many access points to a single feature to share aspects such as the disabled state.
Commands are defined to have the following facets:
Commands are represented by elements in the DOM. Any element that can
define a command also implements the Command
interface:
interface Command {
readonly attribute DOMString commandType;
readonly attribute DOMString id;
readonly attribute DOMString label;
readonly attribute DOMString title;
readonly attribute DOMString icon;
readonly attribute boolean hidden;
readonly attribute boolean disabled;
readonly attribute boolean checked;
void click();
readonly attribute HTMLCollection triggers;
readonly attribute Command command;
};
The Command
interface is implemented by any element capable of defining a command. (If
an element can define a command, its definition will list this interface
explicitly.) All the attributes of the Command
interface are read-only. Elements
implementing this interface may implement other interfaces that have
attributes with identical names but that are mutable; in bindings that
simply flatten all supported interfaces on the object, the mutable
attributes must shadow the readonly attributes defined in the Command
interface.
The commandType
attribute
must return a string whose value is either "command
", "radio
", or "checked
", depending on whether the Type of the command defined by the element is
"command", "radio", or "checked" respectively. If the element does not
define a command, it must return null.
The id
attribute
must return the command's ID, or
null if the element does not define a command or defines an anonymous command. This attribute will be shadowed
by the id
DOM attribute on
the HTMLElement
interface.
The label
attribute must return the command's Label, or null if the element does not
define a command or does not specify a Label. This attribute will be shadowed by
the label
DOM attribute on option
and
command
elements.
The title
attribute must return the command's Hint, or null if the element does not define
a command or does not specify a Hint. This attribute will be shadowed by the
title
DOM attribute on
the HTMLElement
interface.
The icon
attribute must return an absolute URI to the command's Icon. If the element does not specify an
icon, or if the element does not define a command, then the attribute must
return null. This attribute will be shadowed by the icon
DOM attribute on
command
elements.
The hidden
attribute must
return true if the command's Hidden State is that the command is
hidden, and false if it is that the command is not hidden. If the element
does not define a command, the attribute must return false. This attribute
will be shadowed by the hidden
DOM attribute on command
elements.
The disabled
attribute must
return true if the command's Disabled State is that the command
is disabled, and false if the command is not disabled. This attribute is
not affected by the command's Hidden State. If the element does not
define a command, the attribute must return false. This attribute will be
shadowed by the disabled
attribute on
button
, input
, option
, and command
elements.
The checked
attribute must
return true if the command's Checked State is that the command is
checked, and false if it is that the command is not checked. If the
element does not define a command, the attribute must return false. This
attribute will be shadowed by the checked
attribute
on input
and command
elements.
The click()
method must trigger the Action for the command. If the element does
not define a command, this method must do nothing. This method will be
shadowed by the click()
method on HTML elements, and is included only
for completeness.
The triggers
attribute must
return a list containing the elements that can trigger the command (the
command's Triggers).
The list must be live. While the element does not
define a command, the list must be empty.
The commands
attribute of the
document's HTMLDocument
interface
must return an HTMLCollection
rooted at the Document
node, whose filter matches only
elements that define commands and have IDs.
The following elements can define commands: a
, button
, input
, option
, command
.
a
element to define a commandAn a
element with an href
attribute defines a command.
The Type of the command is "command".
The ID of the command is the
value of the id
attribute of
the element, if the attribute is present and not empty. Otherwise the
command is an anonymous command.
The Label of the command
is the string given by the element's textContent
DOM attribute.
The Hint of the command is
the value of the title
attribute of the a
element. If the attribute
is not present, the Hint is
the empty string.
The Icon of the command is
the absolute URI of the first image in the element. Specifically, in a
depth-first search of the children of the element, the first element that
is img
element with a
src
attribute
is the one that is used as the image.
The URI must be taken
from the element's src
attribute.
Relative URIs must be resolved relative to the base URI of the image
element.
If no image is found, then the Icon facet is left blank.
The Hidden State and Disabled State facets of the command are always false. (The command is always enabled.)
The Checked State of the command is always false. (The command is never checked.)
The Action of the
command is to fire a click
event at the element.
button
element to define a
commandA button
element always defines a command.
The Type, ID, Label, Hint, Icon, Hidden State, Checked State, and Action facets of the command are determined
as for a
elements (see
the previous section).
The Disabled
State of the command mirrors the disabled state of the button.
Typically this is given by the element's disabled
attribute, but certain button
types become disabled at other times too (for example, the
move-up
button type is disabled when it would have no
effect).
input
element to define a
commandAn input
element whose type
attribute is one of submit
,
reset
, button
, radio
,
checkbox
, move-up
, move-down
,
add
, and remove
defines a command.
The Type of the command
is "radio" if the type
attribute has
the value radio
, "checkbox" if the type
attribute has the value checkbox
, and "command" otherwise.
The ID of the command is the
value of the id
attribute of
the element, if the attribute is present and not empty. Otherwise the
command is an anonymous command.
The Label of the command depends on the Type of the command:
If the Type is "command",
then it is the string given by the value
attribute, if any, and a
UA-dependent value that the UA uses to label
the button itself if the attribute is absent.
Otherwise, the Type is
"radio" or "checkbox". If the element has a label
element
associated with it, the textContent
of the first such element is
the Label (in DOM terms,
this the string given by element.labels[0].textContent
). Otherwise, the value
of the value
attribute, if present, is the Label. Otherwise, the Label is the empty string.
The Hint of the command is
the value of the title
attribute of the input
element. If the attribute is not
present, the Hint is the
empty string.
There is no Icon for the command.
The Hidden State of the command is always false. (The command is never hidden.)
The Disabled
State of the command mirrors the disabled state of the control.
Typically this is given by the element's disabled
attribute, but certain input
types become disabled at other times too (for example, the
move-up
input type is disabled when it would have no effect).
The Checked
State of the command is true if the command is of Type "radio" or "checkbox" and the element
has a checked
attribute, and false
otherwise.
The Action of the
command is to fire a click
event at the element.
option
element to define a
commandAn option
element with an ancestor select
element and either no value
attribute
or a value
attribute that is not the
empty string defines a
command.
The Type of the command
is "radio" if the option
's nearest ancestor
select
element has no multiple
attribute, and "checkbox" if it
does.
The ID of the command is the
value of the id
attribute of
the element, if the attribute is present and not empty. Otherwise the
command is an anonymous command.
The Label of the command
is the value of the option
element's label
attribute, if there is one, or the
value of the option
element's textContent
DOM attribute if it doesn't.
The Hint of the command is
the string given by the element's title
attribute, if any, and the empty string if
the attribute is absent.
There is no Icon for the command.
The Hidden State of the command is always false. (The command is never hidden.)
The Disabled
State of the command is true (disabled) if the element has a disabled
attribute, and false otherwise.
The Checked
State of the command is true (checked) if the element's selected
DOM attribute is true, and false
otherwise.
The Action of the
command depends on its Type. If the command is of Type "radio" then this must set the selected
DOM attribute of the
option
element to true, otherwise it must toggle the state of
the selected
DOM attribute (set it
to true if it is false and vice versa). Then a change
event must be
fired on the option
element's nearest ancestor
select
element (if there is one), as if the selection had
been changed directly.
command
element to define a
commandA command
element defines a command.
The Type of the command
is "radio" if the command
's type
attribute is
"radio
", "checkbox" if the attribute's value is
"checkbox
", and "command" otherwise.
The ID of the command is the
value of the id
attribute of
the element, if the attribute is present and not empty. Otherwise the
command is an anonymous command.
The Label of the command
is the value of the element's label
attribute, if there is one, or the empty
string if it doesn't.
The Hint of the command is
the string given by the element's title
attribute, if any, and the empty string if
the attribute is absent.
The Icon for the command
is the absolute URI resulting from resolving the value of the element's
icon
attribute as
a URI relative to the element's base URI. If the element has no icon
attribute then the
command has no Icon.
The Hidden State
of the command is true (hidden) if the element has a hidden
attribute,
and false otherwise.
The Disabled
State of the command is true (disabled) if the element has either a
disabled
attribute or a hidden
attribute (or both), and false otherwise.
The Checked
State of the command is true (checked) if the element has a checked
attribute, and false otherwise.
The Action of the
command is to invoke the behaviour described in the definition of the
click()
method
of the HTMLCommandElement
interface.
...examples...
datatemplate
elementrule
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 unique 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 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
legend
elementfieldset
element.
details
element.
figure
element, if
there are no other legend
element
children of that element.
HTMLElement
.
The legend
element represents a title
or explanatory caption for the rest of the contents of the legend
element's parent element.
div
elementHTMLElement
.
The div
element represents nothing at
all. It can be used with the class
, lang
/xml:lang
, and title
attributes to mark up semantics common to a
group of consecutive elements.
Allowing div
elements to
contain phrasing content makes it easy for authors to abuse div
, using it with the class=""
attribute to the point of not having any other elements in the markup.
This is a disaster from an accessibility point of view, and it would be
nice if we could somehow make such pages non-compliant without preventing
people from using div
s as the extension
mechanism that they are, to handle things the spec can't otherwise do
(like making new widgets).
This section describes features that apply most directly to Web browsers. Having said that, unless specified elsewhere, the requirements defined in this section do apply to all user agents, whether they are Web browsers or not.
A browsing context is a collection of one or
more Document
objects, and one or more views.
At any one time, one of the Document
s in a browsing context is the active
document. The collection of Document
s is the browsing context's session
history.
A view is a user agent interface tied to a particular
media used for the presentation of Document
objects in some
media. A view may be interactive. Each view is represented by an
AbstractView
object. Each view belongs to a browsing context. [DOM2VIEWS]
The document
attribute of an
AbstractView
object representing a view
gives the Document
object of the view's browsing context's active
document. [DOM2VIEWS]
Events that use the UIEvent
interface are
related to a specific view (the view in which the
event happened); the AbstractView
of that view is given in
the event object's view
attribute. [DOM3EVENTS]
A typical Web browser has one obvious view per browsing context: the
browser's window (screen media). If a page is printed, however, a second
view becomes evident, that of the print media. The two views always share
the same underlying Document
, but they have a different
presentation of that document. A speech browser also establishes a
browsing context, one with a view in the speech media.
A Document
does not necessarily have a browsing context associated with it. In particular,
data mining tools are likely to never instantiate browsing contexts.
The main view through which a user primarily interacts with a user agent is the default view.
The default view of a
Document
is given by the defaultView
attribute on the Document
object's DocumentView
interface. [DOM3VIEWS]
When a browsing context is first created, it
must be created with a single Document
in its session
history, whose address is
about:blank
, which is marked as being an HTML documents. The Document
must
have a single child html
node, which
itself has a single child body
node. If
the browsing context is created specifically to
be immediately navigated, then that initial navigation will have replacement enabled.
Certain elements (for example, iframe
elements) can instantiate further browsing contexts. These are called nested browsing contexts. If a
browsing context P has an element in one of its
Document
s D that nests another browsing
context C inside it, then P is
said to be the parent browsing context of C, C is said to be a child browsing context of P, and C is said to be nested through D.
The browsing context with no parent browsing context is the top-level browsing context of all the browsing contexts nested within it (either directly or indirectly through other nested browsing contexts).
A Document
is said to be fully active
when it is the active document of its browsing context, and either its browsing context is
a top-level browsing context, or the
Document
through which that browsing context is nested is itself fully active.
Because they are nested through an element, child browsing contexts are always tied
to a specific Document
in their parent
browsing context. User agents must not allow the user to interact with
child browsing
contexts of elements that are in Document
s that are not
themselves fully active.
It is possible to create new browsing contexts that are related to a top level browsing context without being nested through an element. Such browsing contexts are called auxiliary browsing contexts. Auxiliary browsing contexts are always top-level browsing contexts.
An auxiliary browsing context has an opener browsing context, which is the browsing context from which the auxiliary browsing context was created, and it has a furthest ancestor browsing context, which is the top-level browsing context of the opener browsing context when the auxiliary browsing context was created.
The opener
DOM
attribute on the Window
object must
return the Window
object of the browsing context from which the current browsing
context was created (its opener browsing context),
if there is one and it is still available.
User agents may support secondary browsing contexts, which are browsing contexts that form part of the user agent's interface, apart from the main content area.
Each browsing context is defined as having a list of zero or more directly reachable browsing contexts. These are: