details elementlegend element followed by flow content.openinterface HTMLDetailsElement : HTMLElement {
attribute boolean open;
};
The details element represents additional
information or controls which the user can obtain on demand.
The details element is not appropriate
for footnotes. Please see the section on
footnotes for details on how to mark up footnotes.
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 agent should allow the user to request that the details
be shown or hidden. To honor a request for the details to be shown,
the user agent must set the open attribute on the element to
the value open. To honour a request for the
details to be hidden, the user agent must remove the open attribute from the
element.
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.
datagrid elementtable, select, or datalist element.table element.select element.datalist element.multipledisabledinterface 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).
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.
[NoInterfaceObject] 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 RowSpecifications
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
[NoInterfaceObject] 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 behavior of the default data provider depends on the nature
of the first element child of the datagrid.
table elementgetRowCount(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): The URL of the
row's image is the absolute URL obtained by resolving the value of the src attribute of the first
img element child of the row's first cell's element,
if there is one and resolving its attribute is
successful. Otherwise, the URL 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 elementThe 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: headerclass attribute
contains the closed class: initially-closedclass attribute
contains the open class: initially-openThe 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
optionelement, 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 initialized, 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 absolute URL
obtained from resolving the
value of the src attribute of
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, if such an element exists and resolving its attribute is
successful. Otherwise, it must return the empty string.
In the following example, the row with path "1,0" returns "http://example.com/a" as its image URL, 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 descendant 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-closedclass
attribute contains the open class: initially-openh1–h6
element: headerhr element: separatorThe 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
optgroups 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's checkedness is true, and the
unchecked class
otherwise.
The setCellCheckedState()
method must set the input element's checkbox checkedness to true if the
method's third argument is 1, and to false 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 agent should offer
the user the option to have the data displayed 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
identity 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 should be
based on platform conventions.getRowImage() method with a
RowSpecification object representing the row in
question. The return value is a URL. Immediately resolve that URL as if it came from an
attribute of the datagrid element to obtain an
absolute URL identifying the image that represents the
row. 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 applies to the cell and the cell's checkbox is in an
indeterminate state. When the indeterminate
class applies 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 between
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 honor
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 behavior 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.
datagridWhenever 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
identified 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 be called only 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 agent should offer to the user the option of toggling the row's 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 agent should allow
the user to activate the cell to cycle its value. When the user
activates this "cycling" behavior 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 then act as if the
datagrid's updateCellChanged()
method had been invoked with those same arguments.
When a cell has a checkbox, the user
agent should allow the user 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 be possible only if the cell has the indeterminate class
set). The datagrid must then act as if the
datagrid's updateCellChanged()
method had been invoked, specifying the same cell.
If a cell is editable, the user agent
should allow the user 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 then act as if
the updateCellChanged()
method had been invoked, with the same row and column specified.
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;
[IndexGetter] 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 agent should allow the user to select any
number of rows (zero or more). If the attribute is not present, then
the user agent must not allow the user to select more than 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
agent should allow the user to request that the data be sorted using
that column. 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 elementtypelabelicondisabledcheckedradiogroupdefaulttitle attribute has special semantics on this element.interface HTMLCommandElement : HTMLElement {
attribute DOMString type;
attribute DOMString label;
attribute DOMString icon;
attribute boolean disabled;
attribute boolean checked;
attribute DOMString radiogroup;
attribute boolean default;
void click(); // shadows HTMLElement.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 is an enumerated attribute with three
keywords and states. The keyword "command"
maps to the Command state, the
checkbox"
maps to the Checkbox, and the
"radio"
keyword maps to the Radio state. The
missing value default is the Command state.
The element represents a normal command with an associated action.
The element represents a state or option that can be toggled.
The element represents a selection of one item from a list of items.
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
valid URL.
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 and hidden 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 attribute must be
omitted unless the type
attribute is in either the Checkbox state or
the Radio
state.
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. The attribute must be omitted unless the type attribute is in the Radio state.
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. The attribute must be omitted
unless the type attribute is
in the Command
state.
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, disabled, checked, radiogroup, and
default DOM
attributes must reflect the respective content
attributes of the same name.
The click()
method's behavior depends on the value of the type attribute of the element, as
follows:
type attribute is
in the Checkbox stateIf 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 is
in the Radio stateIf 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