[html5] r2962 - [] (0) <datagrid> mark II, first draft

whatwg at whatwg.org whatwg at whatwg.org
Fri Apr 17 18:16:53 PDT 2009


Author: ianh
Date: 2009-04-17 18:16:51 -0700 (Fri, 17 Apr 2009)
New Revision: 2962

Modified:
   index
   source
Log:
[] (0) <datagrid> mark II, first draft

Modified: index
===================================================================
--- index	2009-04-08 06:11:13 UTC (rev 2961)
+++ index	2009-04-18 01:16:51 UTC (rev 2962)
@@ -39,7 +39,7 @@
   <div class=head>
    <p><a class=logo href=http://www.whatwg.org/ rel=home><img alt=WHATWG src=/images/logo></a></p>
    <h1>HTML 5</h1>
-   <h2 class="no-num no-toc" id=draft-recommendation-—-date:-01-jan-1901>Draft Recommendation — 8 April 2009</h2>
+   <h2 class="no-num no-toc" id=draft-recommendation-—-date:-01-jan-1901>Draft Recommendation — 18 April 2009</h2>
    <p>You can take part in this work. <a href=http://www.whatwg.org/mailing-list>Join the working group's discussion list.</a></p>
    <p><strong>Web designers!</strong> We have a <a href=http://blog.whatwg.org/faq/>FAQ</a>, a <a href=http://forums.whatwg.org/>forum</a>, and a <a href=http://www.whatwg.org/mailing-list#help>help mailing list</a> for you!</p>
    <dl><dt>Multiple-page version:</dt>
@@ -615,18 +615,18 @@
      <li><a href=#the-details-element><span class=secno>4.11.1 </span>The <code>details</code> element</a></li>
      <li><a href=#datagrid><span class=secno>4.11.2 </span>The <code>datagrid</code> element</a>
       <ol>
-       <li><a href=#the-datagrid-data-model><span class=secno>4.11.2.1 </span>The <code>datagrid</code> data model</a></li>
-       <li><a href=#how-rows-are-identified><span class=secno>4.11.2.2 </span>How rows are identified</a></li>
-       <li><a href=#the-data-provider-interface><span class=secno>4.11.2.3 </span>The data provider interface</a></li>
-       <li><a href=#the-default-data-provider><span class=secno>4.11.2.4 </span>The default data provider</a>
+       <li><a href=#introduction-1><span class=secno>4.11.2.1 </span>Introduction</a>
         <ol>
-         <li><a href=#commonDefaultDataGridMethodDefinitions><span class=secno>4.11.2.4.1 </span>Common default data
-  provider method definitions for cells</a></ol></li>
-       <li><a href=#populating-the-datagrid-element><span class=secno>4.11.2.5 </span>Populating the <code>datagrid</code> element</a></li>
-       <li><a href=#updating-the-datagrid><span class=secno>4.11.2.6 </span>Updating the <code>datagrid</code></a></li>
-       <li><a href=#requirements-for-interactive-user-agents><span class=secno>4.11.2.7 </span>Requirements for interactive user agents</a></li>
-       <li><a href=#the-selection><span class=secno>4.11.2.8 </span>The selection</a></li>
-       <li><a href=#columns-and-captions><span class=secno>4.11.2.9 </span>Columns and captions</a></ol></li>
+         <li><a href=#example:-a-datagrid-backed-by-a-static-table-element><span class=secno>4.11.2.1.1 </span>Example: a <code>datagrid</code> backed by a static <code>table</code> element</a></li>
+         <li><a href=#example:-a-datagrid-backed-by-nested-ol-elements><span class=secno>4.11.2.1.2 </span>Example: a <code>datagrid</code> backed by nested <code>ol</code> elements</a></li>
+         <li><a href=#example:-a-datagrid-backed-by-a-server><span class=secno>4.11.2.1.3 </span>Example: a <code>datagrid</code> backed by a server</a></ol></li>
+       <li><a href=#populating-the-datagrid><span class=secno>4.11.2.2 </span>Populating the <code>datagrid</code></a>
+        <ol>
+         <li><a href=#the-listener><span class=secno>4.11.2.2.1 </span>The listener</a></li>
+         <li><a href=#the-columns><span class=secno>4.11.2.2.2 </span>The columns</a></li>
+         <li><a href=#the-rows><span class=secno>4.11.2.2.3 </span>The rows</a></li>
+         <li><a href=#the-cells><span class=secno>4.11.2.2.4 </span>The cells</a></ol></li>
+       <li><a href=#listening-to-notifications-from-the-datagrid><span class=secno>4.11.2.3 </span>Listening to notifications from the <code>datagrid</code></a></ol></li>
      <li><a href=#the-command><span class=secno>4.11.3 </span>The <code>command</code> element</a></li>
      <li><a href=#the-bb-element><span class=secno>4.11.4 </span>The <code>bb</code> element</a>
       <ol>
@@ -681,7 +681,7 @@
      <li><a href=#relaxing-the-same-origin-restriction><span class=secno>5.4.1 </span>Relaxing the same-origin restriction</a></ol></li>
    <li><a href=#scripting><span class=secno>5.5 </span>Scripting</a>
     <ol>
-     <li><a href=#introduction-1><span class=secno>5.5.1 </span>Introduction</a></li>
+     <li><a href=#introduction-2><span class=secno>5.5.1 </span>Introduction</a></li>
      <li><a href=#enabling-and-disabling-scripting><span class=secno>5.5.2 </span>Enabling and disabling scripting</a></li>
      <li><a href=#processing-model-1><span class=secno>5.5.3 </span>Processing model</a>
       <ol>
@@ -717,7 +717,7 @@
      <li><a href=#manually-releasing-the-storage-mutex><span class=secno>5.7.3 </span>Manually releasing the storage mutex</a></ol></li>
    <li><a href=#offline><span class=secno>5.8 </span>Offline Web applications</a>
     <ol>
-     <li><a href=#introduction-2><span class=secno>5.8.1 </span>Introduction</a></li>
+     <li><a href=#introduction-3><span class=secno>5.8.1 </span>Introduction</a></li>
      <li><a href=#appcache><span class=secno>5.8.2 </span>Application caches</a></li>
      <li><a href=#manifests><span class=secno>5.8.3 </span>The cache manifest syntax</a>
       <ol>
@@ -812,7 +812,7 @@
    <li><a href=#spelling-and-grammar-checking><span class=secno>6.8 </span>Spelling and grammar checking</a></li>
    <li><a href=#dnd><span class=secno>6.9 </span>Drag and drop</a>
     <ol>
-     <li><a href=#introduction-3><span class=secno>6.9.1 </span>Introduction</a></li>
+     <li><a href=#introduction-4><span class=secno>6.9.1 </span>Introduction</a></li>
      <li><a href=#the-dragevent-and-datatransfer-interfaces><span class=secno>6.9.2 </span>The <code>DragEvent</code> and <code>DataTransfer</code> interfaces</a></li>
      <li><a href=#events-fired-during-a-drag-and-drop-action><span class=secno>6.9.3 </span>Events fired during a drag-and-drop action</a></li>
      <li><a href=#drag-and-drop-processing-model><span class=secno>6.9.4 </span>Drag-and-drop processing model</a>
@@ -831,7 +831,7 @@
      <li><a href=#security-risks-in-the-drag-and-drop-model><span class=secno>6.9.7 </span>Security risks in the drag-and-drop model</a></ol></li>
    <li><a href=#undo><span class=secno>6.10 </span>Undo history</a>
     <ol>
-     <li><a href=#introduction-4><span class=secno>6.10.1 </span>Introduction</a></li>
+     <li><a href=#introduction-5><span class=secno>6.10.1 </span>Introduction</a></li>
      <li><a href=#definitions-2><span class=secno>6.10.2 </span>Definitions</a></li>
      <li><a href=#the-undomanager-interface><span class=secno>6.10.3 </span>The <code>UndoManager</code> interface</a></li>
      <li><a href=#undo:-moving-back-in-the-undo-transaction-history><span class=secno>6.10.4 </span>Undo: moving back in the undo transaction history</a></li>
@@ -844,7 +844,7 @@
    <li><a href=#event-definitions><span class=secno>7.1 </span>Event definitions</a></li>
    <li><a href=#crossDocumentMessages><span class=secno>7.2 </span>Cross-document messaging</a>
     <ol>
-     <li><a href=#introduction-5><span class=secno>7.2.1 </span>Introduction</a></li>
+     <li><a href=#introduction-6><span class=secno>7.2.1 </span>Introduction</a></li>
      <li><a href=#security-4><span class=secno>7.2.2 </span>Security</a>
       <ol>
        <li><a href=#authors><span class=secno>7.2.2.1 </span>Authors</a></li>
@@ -853,7 +853,7 @@
      <li><a href=#posting-messages-with-message-ports><span class=secno>7.2.4 </span>Posting messages with message ports</a></ol></li>
    <li><a href=#channel-messaging><span class=secno>7.3 </span>Channel messaging</a>
     <ol>
-     <li><a href=#introduction-6><span class=secno>7.3.1 </span>Introduction</a></li>
+     <li><a href=#introduction-7><span class=secno>7.3.1 </span>Introduction</a></li>
      <li><a href=#message-channels><span class=secno>7.3.2 </span>Message channels</a></li>
      <li><a href=#message-ports><span class=secno>7.3.3 </span>Message ports</a>
       <ol>
@@ -972,10 +972,10 @@
    <li><a href=#parsing-xhtml-fragments><span class=secno>9.4 </span>Parsing XHTML fragments</a></ol></li>
  <li><a href=#rendering><span class=secno>10 </span>Rendering</a>
   <ol>
-   <li><a href=#introduction-7><span class=secno>10.1 </span>Introduction</a></li>
+   <li><a href=#introduction-8><span class=secno>10.1 </span>Introduction</a></li>
    <li><a href=#the-css-user-agent-style-sheet-and-presentational-hints><span class=secno>10.2 </span>The CSS user agent style sheet and presentational hints</a>
     <ol>
-     <li><a href=#introduction-8><span class=secno>10.2.1 </span>Introduction</a></li>
+     <li><a href=#introduction-9><span class=secno>10.2.1 </span>Introduction</a></li>
      <li><a href=#display-types><span class=secno>10.2.2 </span>Display types</a></li>
      <li><a href=#margins-and-padding><span class=secno>10.2.3 </span>Margins and padding</a></li>
      <li><a href=#alignment><span class=secno>10.2.4 </span>Alignment</a></li>
@@ -993,7 +993,7 @@
      <li><a href=#tool-bars-0><span class=secno>10.3.5 </span>Tool bars</a></ol></li>
    <li><a href=#bindings><span class=secno>10.4 </span>Bindings</a>
     <ol>
-     <li><a href=#introduction-9><span class=secno>10.4.1 </span>Introduction</a></li>
+     <li><a href=#introduction-10><span class=secno>10.4.1 </span>Introduction</a></li>
      <li><a href=#the-bb-element-0><span class=secno>10.4.2 </span>The <code>bb</code> element</a></li>
      <li><a href=#the-button-element-0><span class=secno>10.4.3 </span>The <code>button</code> element</a></li>
      <li><a href=#the-datagrid-element><span class=secno>10.4.4 </span>The <code>datagrid</code> element</a></li>
@@ -6253,13 +6253,6 @@
   to an underlying string that consists of an <a href=#unordered-set-of-unique-space-separated-tokens>unordered set of
   unique space-separated tokens</a>.</p>
 
-  <p>Which string underlies a particular <code><a href=#domtokenlist-0>DOMTokenList</a></code>
-  object is defined when the object is created. It might be a content
-  attribute (e.g. the string that underlies the <code title=dom-classList><a href=#dom-classlist>classList</a></code> object is the <code title=attr-class><a href=#classes>class</a></code> attribute), or it might be an
-  anonymous string (e.g. when a <code><a href=#domtokenlist-0>DOMTokenList</a></code> object is
-  passed to an author-implemented callback in the
-  <code><a href=#datagrid>datagrid</a></code> APIs).</p>
-
   <pre class=idl>[<a href=#dom-tokenlist-tostring title=dom-tokenlist-toString>Stringifies</a>] interface <dfn id=domtokenlist-0>DOMTokenList</dfn> {
   readonly attribute unsigned long <a href=#dom-tokenlist-length title=dom-tokenlist-length>length</a>;
   [IndexGetter] DOMString <a href=#dom-tokenlist-item title=dom-tokenlist-item>item</a>(in unsigned long index);
@@ -6669,7 +6662,7 @@
    <li value=20><dfn id=abort_err><code>ABORT_ERR</code></dfn></li> <!-- actually in XHR for now -->
    <li value=21><dfn id=url_mismatch_err><code>URL_MISMATCH_ERR</code></dfn></li> <!-- actually in workers for now -->
    <li value=22><dfn id=quota_exceeded_err><code>QUOTA_EXCEEDED_ERR</code></dfn></li> <!-- actually defined right here for now -->
-   <li value=23><dfn id=unavailable_script_err><code>UNAVAILABLE_SCRIPT_ERR</code></dfn></li> <!-- actually defined right here for now -->
+   <li value=23><dfn id=datagrid_model_err><code>DATAGRID_MODEL_ERR</code></dfn></li> <!-- actually defined right here for now -->
    <li value=81><dfn id=parse_err><code>PARSE_ERR</code></dfn></li> <!-- actually defined in dom3ls -->
    <li value=82><dfn id=serialise_err><code>SERIALISE_ERR</code></dfn></li> <!-- actually defined in dom3ls -->
   </ol><div class=impl>
@@ -15342,7 +15335,7 @@
   <ul class=brief><li>minimum value ≤ actual value ≤ maximum value</li>
    <li>minimum value ≤ low boundary ≤ high boundary ≤ maximum value</li>
    <li>minimum value ≤ optimum point ≤ maximum value</li>
-  </ul><p><strong>UA requirements for regions of the gauge</strong>: If the
+  </ul><!-- next two paragraphs are duplicated in the <datagrid> section --><p><strong>UA requirements for regions of the gauge</strong>: If the
   optimum point is equal to the low boundary or the high boundary, or
   anywhere in between them, then the region between the low and high
   boundaries of the gauge must be treated as the optimum region, and
@@ -16624,7 +16617,7 @@
 
   <p>The <code><a href=#the-img-element>img</a></code> must not be used as a layout tool. In
   particular, <code><a href=#the-img-element>img</a></code> elements should not be used to display
-  fully transparent images, as they rarely convey meaning and rarely
+   transparent images, as they rarely convey meaning and rarely
   add anything useful to the document.</p>
 
   <div class=impl>
@@ -26191,15 +26184,15 @@
   have explicit keywords:</p>
 
   <dl><dt>The <dfn id=attr-th-scope-row title=attr-th-scope-row><code>row</code></dfn>
-   keyword, which maps to the <i>row</i> state</dt>
+   keyword, which maps to the <i><a href=#row>row</a></i> state</dt>
 
-   <dd>The <i>row</i> state means the header cell applies to some of
+   <dd>The <i><a href=#row>row</a></i> state means the header cell applies to some of
    the subsequent cells in the same row(s).</dd>
 
    <dt>The <dfn id=attr-th-scope-col title=attr-th-scope-col><code>col</code></dfn>
-   keyword, which maps to the <i>column</i> state</dt>
+   keyword, which maps to the <i><a href=#column>column</a></i> state</dt>
 
-   <dd>The <i>column</i> state means the header cell applies to some
+   <dd>The <i><a href=#column>column</a></i> state means the header cell applies to some
    of the subsequent cells in the same column(s).</dd>
 
    <dt>The <dfn id=attr-th-scope-rowgroup title=attr-th-scope-rowgroup><code>rowgroup</code></dfn> keyword,
@@ -31816,25 +31809,22 @@
   <code><a href=#the-datalist-element>datalist</a></code> element, then there is no <a href=#concept-input-list title=concept-input-list>suggestions source element</a>.</p>
 
   <p>If there is a <a href=#concept-input-list title=concept-input-list>suggestions source
-  element</a>, then each <code><a href=#the-option-element>option</a></code> element that is a
-  descendant of the <a href=#concept-input-list title=concept-input-list>suggestions
-  source element</a>, that is not <a href=#concept-option-disabled title=concept-option-disabled>disabled</a>, and whose <a href=#concept-option-value title=concept-option-value>value</a> is a string that isn't the
-  empty string and that the user would be allowed to enter as the
-  <code><a href=#the-input-element>input</a></code> element's <a href=#concept-fe-value title=concept-fe-value>value</a>, represents a suggestion. Each
-  suggestion has a <a href=#concept-option-value title=concept-option-value>value</a> and
-  a <a href=#concept-option-label title=concept-option-label>label</a>.</p>
-
-  <p>When the user agent is allowing the user to edit the
-  <code><a href=#the-input-element>input</a></code> element's <a href=#concept-fe-value title=concept-fe-value>value</a>, the user agent should offer
-  the suggestions to the user in a manner suitable for the type of
-  control used. The user agent may use the suggestion's <a href=#concept-option-label title=concept-option-label>label</a> to identify the suggestion
+  element</a>, then, when the user agent is allowing the user to
+  edit the <code><a href=#the-input-element>input</a></code> element's <a href=#concept-fe-value title=concept-fe-value>value</a>, the user agent should offer
+  the suggestions represented by the <a href=#concept-input-list title=concept-input-list>suggestions source element</a> to the
+  user in a manner suitable for the type of control used. The user
+  agent may use the suggestion's <a href=#concept-option-label title=concept-option-label>label</a> to identify the suggestion
   if appropriate. If the user selects a suggestion, then the
   <code><a href=#the-input-element>input</a></code> element's <a href=#concept-fe-value title=concept-fe-value>value</a> must be set to the selected
   suggestion's <a href=#concept-option-value title=concept-option-value>value</a>, as if
   the user had written that value himself.</p>
 
-  <p>User agents should filter the suggestions to hide suggestions
-  that would cause the element to not <a href=#concept-fv-valid title=concept-fv-valid>satisfy its constraints</a>.</p>
+  <p>User agents must filter the suggestions to hide suggestiosn that
+  the user would not be allowed to enter as the <code><a href=#the-input-element>input</a></code>
+  element's <a href=#concept-fe-value title=concept-fe-value>value</a>, and should
+  filter the suggestions to hide suggestions that would cause the
+  element to not <a href=#concept-fv-valid title=concept-fv-valid>satisfy its
+  constraints</a>.</p>
 
   <hr><p>If the <code title=attr-input-list><a href=#attr-input-list>list</a></code> attribute does
   not apply, there is no <a href=#concept-input-list title=concept-input-list>suggestions
@@ -33001,8 +32991,14 @@
 
   <p>The <code><a href=#the-datalist-element>datalist</a></code> element is hooked up to an
   <code><a href=#the-input-element>input</a></code> element using the <code title=attr-input-list><a href=#attr-input-list>list</a></code> attribute on the
-  <code><a href=#the-input-element>input</a></code> element.</p>
+  <code><a href=#the-input-element>input</a></code> element. The <code><a href=#the-datalist-element>datalist</a></code> element can
+  also be used with a <code><a href=#datagrid>datagrid</a></code> element, as the source of
+  autocompletion hints for <code title=datagrid-type-editable><a href=#datagrid-type-editable>editable</a></code> cells.</p>
 
+  <p>Each <code><a href=#the-option-element>option</a></code> element that is a descendant of the
+  <code><a href=#the-datalist-element>datalist</a></code> element, that is not <a href=#concept-option-disabled title=concept-option-disabled>disabled</a>, and whose <a href=#concept-option-value title=concept-option-value>value</a> is a string that isn't the
+  empty string, represents a suggestion. Each suggestion has a <a href=#concept-option-value title=concept-option-value>value</a> and a <a href=#concept-option-label title=concept-option-label>label</a>.
+
   <dl class=domintro><dt><var title="">datalist</var> . <code title=dom-datalist-options><a href=#dom-datalist-options>options</a></code></dt>
 
    <dd>
@@ -35617,11 +35613,8 @@
 
 
 
-<div class=bad>
   <h4 id=datagrid><span class=secno>4.11.2 </span>The <dfn><code>datagrid</code></dfn> element</h4>
 
-<p class=XXX>The API here needs rewriting. Don't implement this right now.</p>
-
   <dl class=element><dt>Categories</dt>
    <dd><a href=#flow-content-0>Flow content</a>.</dd>
    <dd><a href=#interactive-content-0>Interactive content</a>.</dd>
@@ -35636,55 +35629,102 @@
    <dd>Or: A single <code><a href=#the-datalist-element>datalist</a></code> element.</dd>
    <dt>Content attributes:</dt>
    <dd><a href=#global-attributes>Global attributes</a></dd>
-   <dd><code title=attr-datagrid-multiple><a href=#attr-datagrid-multiple>multiple</a></code></dd>
+<!--v2DGS:
+   <dd><code title="attr-datagrid-multiple">multiple</code></dd>
+-->
    <dd><code title=attr-datagrid-disabled><a href=#attr-datagrid-disabled>disabled</a></code></dd>
    <dt>DOM interface:</dt>
    <dd>
 <pre class=idl>interface <dfn id=htmldatagridelement>HTMLDataGridElement</dfn> : <a href=#htmlelement>HTMLElement</a> {
-           attribute <a href=#datagriddataprovider>DataGridDataProvider</a> <a href=#dom-datagrid-data title=dom-datagrid-data>data</a>;
-  readonly attribute <a href=#datagridselection>DataGridSelection</a> <a href=#dom-datagrid-selection title=dom-datagrid-selection>selection</a>;
            attribute boolean <a href=#dom-datagrid-multiple title=dom-datagrid-multiple>multiple</a>;
            attribute boolean <a href=#dom-datagrid-disabled title=dom-datagrid-disabled>disabled</a>;
-  void <a href=#dom-datagrid-updateeverything title=dom-datagrid-updateEverything>updateEverything</a>();
-  void <a href=#dom-datagrid-updaterowschanged title=dom-datagrid-updateRowsChanged>updateRowsChanged</a>(in <a href=#rowspecification>RowSpecification</a> row, in unsigned long count);
-  void <a href=#dom-datagrid-updaterowsinserted title=dom-datagrid-updateRowsInserted>updateRowsInserted</a>(in <a href=#rowspecification>RowSpecification</a> row, in unsigned long count);
-  void <a href=#dom-datagrid-updaterowsremoved title=dom-datagrid-updateRowsRemoved>updateRowsRemoved</a>(in <a href=#rowspecification>RowSpecification</a> row, in unsigned long count);
-  void <a href=#dom-datagrid-updaterowchanged title=dom-datagrid-updateRowChanged>updateRowChanged</a>(in <a href=#rowspecification>RowSpecification</a> row);
-  void <a href=#dom-datagrid-updatecolumnchanged title=dom-datagrid-updateColumnChanged>updateColumnChanged</a>(in unsigned long column);
-  void <a href=#dom-datagrid-updatecellchanged title=dom-datagrid-updateCellChanged>updateCellChanged</a>(in <a href=#rowspecification>RowSpecification</a> row, in unsigned long column);
+           attribute <a href=#datagridlistener>DataGridListener</a> <a href=#dom-datagrid-listener title=dom-datagrid-listener>listener</a>;
+<!-- v2DGS:
+  readonly attribute <span>DataGridSelection</span> <span title="dom-datagrid-selection">selection</span>;
+-->
+  // columns
+  void <a href=#dom-datagrid-addcolumn title=dom-datagrid-addColumn>addColumn</a>(in <a href=#column>Column</a> id, in DOMString label, in DOMString type, [Optional] in HTMLImageElement icon, [Optional] in boolean sortable, [Optional] in boolean visible);
+           attribute DOMString <a href=#dom-datagrid-sortcolumn title=dom-datagrid-sortColumn>sortColumn</a>;
+           attribute boolean <a href=#dom-datagrid-sortascending title=dom-datagrid-sortAscending>sortAscending</a>;
+  void <a href=#dom-datagrid-clearcolumns title=dom-datagrid-clearColumns>clearColumns</a>();
+
+  // rows
+  void <a href=#dom-datagrid-renotify title=dom-datagrid-renotify>renotify</a>();
+  void <a href=#dom-datagrid-setrowcount title=dom-datagrid-setRowCount>setRowCount</a>(in long childCount, in long rowCount);
+  void <a href=#dom-datagrid-setrows title=dom-datagrid-setRows>setRows</a>(in <a href=#rowlist>RowList</a> rows);
+  void <a href=#dom-datagrid-insertrows title=dom-datagrid-insertRows>insertRows</a>(in <a href=#rowlist>RowList</a> rows);
+  void <a href=#dom-datagrid-deleterows title=dom-datagrid-deleteRows>deleteRows</a>(in <a href=#rowidlist>RowIDList</a> rows);
+  void <a href=#dom-datagrid-repaint title=dom-datagrid-repaint>repaint</a>(in <a href=#rowid>RowID</a> row, in DOMString column);
+  void <a href=#dom-datagrid-clearrows title=dom-datagrid-clearRows>clearRows</a>();
+<!--
+ v2: opening and closing a row
+     moving a row's actual ID
+      - imagine new mail moving a thread up; you just want to add the new mail to the thread and move the thread's first mail to the top
+      - though actually that should probably just be done using display sorting
+-->
+};
+
+typedef DOMString <dfn id=column>Column</dfn>;
+typedef sequence<<a href=#column>Column</a>> <dfn id=columnlist>ColumnList</dfn>;
+typedef sequence<any> <dfn id=cell>Cell</dfn>; // <a href=#column>Column</a>, [Variadic] any (exact types expected depend on the column type)
+typedef sequence<<a href=#cell>Cell</a>> <dfn id=celllist>CellList</dfn>;
+typedef sequence<any> <dfn id=row>Row</dfn>; // <a href=#rowid>RowID</a>, long, long, <a href=#celllist>CellList</a>, [Optional] boolean, [Optional] long
+typedef sequence<<a href=#row>Row</a>> <dfn id=rowlist>RowList</dfn>;
+typedef sequence<unsigned long> <dfn id=rowid>RowID</dfn>;
+typedef sequence<<a href=#rowid>RowID</a>> <dfn id=rowidlist>RowIDList</dfn>;
+
+[Callback=FunctionOnly, NoInterfaceObject]
+interface <dfn id=renderingcontext2dcallback>RenderingContext2DCallback</dfn> {
+  DOMString <span title=dom-Rendering2DContextCallback-handleEvent>handleEvent</span>(in <a href=#canvasrenderingcontext2d>CanvasRenderingContext2D</a> context, in unsigned long width, in unsigned long height);
 };</pre>
    </dd>
-  </dl><p class=XXX>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).</p> <!-- XXXPA -->
+  </dl><p>The <code><a href=#datagrid>datagrid</a></code> element <a href=#represents>represents</a> an
+  interactive representation of tree, list, or tabular data.</p>
 
-  <p>The <code><a href=#datagrid>datagrid</a></code> element <a href=#represents>represents</a> an interactive
-  representation of tree, list, or tabular data.</p>
+  <p>The data being presented is provided by script using the methods
+  described in the following sections.</p>
 
-  <p>The data being presented can come either from the content, as
-  elements given as children of the <code><a href=#datagrid>datagrid</a></code> element, or
-  from a scripted data provider given by the <code title=dom-datagrid-data><a href=#dom-datagrid-data>data</a></code> DOM attribute.</p>
+<!--v2DGS:
+  <p>The <dfn
+  title="attr-datagrid-multiple"><code>multiple</code></dfn> attribute
+  is a <span>boolean attribute</span>. When set, it indicates that the
+  user can select more than one row at a time.</p>
+-->
 
-  <p>The <code title=attr-datagrid-multiple><a href=#attr-datagrid-multiple>multiple</a></code> and
-  <code title=attr-datagrid-disabled><a href=#attr-datagrid-disabled>disabled</a></code> attributes are
-  <a href=#boolean-attribute title="boolean attribute">boolean attributes</a>. Their
-  effects are described in the processing model sections below.</p>
+  <p>The <dfn id=attr-datagrid-disabled title=attr-datagrid-disabled><code>disabled</code></dfn> attribute
+  is a <a href=#boolean-attribute>boolean attribute</a> used to disable the
+  control. <span class=impl>When the attribute is set, the user
+  agent must disable the <code><a href=#datagrid>datagrid</a></code>, preventing the user
+  from interacting with it. The <code><a href=#datagrid>datagrid</a></code> element should
+  still continue to update itself when the underlying data changes,
+  though, as described in the next few sections. However, conformance
+  requirements stating that <code><a href=#datagrid>datagrid</a></code> elements must react
+  to users in particular ways do not apply when one is
+  disabled.</span></p>
 
+  <div class=impl>
+
   <p>The <dfn id=dom-datagrid-multiple title=dom-datagrid-multiple><code>multiple</code></dfn> and <dfn id=dom-datagrid-disabled title=dom-datagrid-disabled><code>disabled</code></dfn> DOM
-  attributes must <a href=#reflect>reflect</a> the <code title=attr-datagrid-multiple><a href=#attr-datagrid-multiple>multiple</a></code> and <code title=attr-datagrid-disabled><a href=#attr-datagrid-disabled>disabled</a></code> content attributes
+  attributes must <a href=#reflect>reflect</a> the <code title=attr-datagrid-multiple>multiple</code> and <code title=attr-datagrid-disabled><a href=#attr-datagrid-disabled>disabled</a></code> content attributes
   respectively.</p>
 
+  </div>
 
-  <h5 id=the-datagrid-data-model><span class=secno>4.11.2.1 </span>The <code><a href=#datagrid>datagrid</a></code> data model</h5>
+  <!-- v2DGPA: 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). (v2DGPA = <datagrid> Perform Action) -->
 
+
+  <h5 id=introduction-1><span class=secno>4.11.2.1 </span>Introduction</h5>
+
   <p><em>This section is non-normative.</em></p>
 
   <p>In the <code><a href=#datagrid>datagrid</a></code> 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.</p>
+  although individual columns might be hidden in the presentation.</p>
 
-  <p>Each row can have child rows. Child rows may be hidden or
+  <hr><p>Each row can have child rows. Child rows may be hidden or
   shown, by closing or opening (respectively) the parent row.</p>
 
   <p>Rows are referred to by the path along the tree that one would
@@ -35694,1540 +35734,2177 @@
   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.</p>
 
-  <p>The columns can have captions. Those captions are not considered
-  a row in their own right, they are obtained separately.</p>
+  <p>The chains of numbers that give a row's path, or identifier, are
+  represented by arrays of positions, represented in IDL by the
+  <a href=#rowid>RowID</a> interface.</p>
 
-  <p>Selection of data in a <code><a href=#datagrid>datagrid</a></code> operates at the row
-  level. If the <code title=attr-datagrid-multiple><a href=#attr-datagrid-multiple>multiple</a></code>
+  <p>The root of the tree is represented by an empty array.</p>
+
+  <hr><p>Each column has a string that is used to identify it in the API,
+  a label that is shown to users interacting with the column, a type,
+  and optionally an icon.</p>
+
+  <p>The possible types are as follows:</p>
+
+  <table><thead><tr><td>Keyword
+     <td>Description
+   <tbody><tr><td><code title=datagrid-type-text><a href=#datagrid-type-text>text</a></code>
+     <td>Simple text.
+    <tr><td><code title=datagrid-type-editable><a href=#datagrid-type-editable>editable</a></code>
+     <td>Editable text.
+    <tr><td><code title=datagrid-type-checkable><a href=#datagrid-type-checkable>checkable</a></code>
+     <td>Text with a check box.
+    <tr><td><code title=datagrid-type-list><a href=#datagrid-type-list>list</a></code>
+     <td>A list of values that the user can switch between.
+    <tr><td><code title=datagrid-type-progress><a href=#datagrid-type-progress>progress</a></code>
+     <td>A progress bar.
+    <tr><td><code title=datagrid-type-meter><a href=#datagrid-type-meter>meter</a></code>
+     <td>A gauge.
+    <tr><td><code title=datagrid-type-custom><a href=#datagrid-type-custom>custom</a></code>
+     <td>A canvas onto which arbitrary content can be drawn.
+  </table><p>Each column can be flagged as sortable, in which case the user
+  will be able to sort the view using that column.</p>
+
+  <p>Columns are not necessarily visible. A column can be created
+  invisible by default. The user can select which columns are to be
+  shown.</p>
+
+  <p>When no columns have been added to the <code><a href=#datagrid>datagrid</a></code>, a
+  column with no name, whose identifier is the empty string, whose
+  type is <code title=datagrid-type-text><a href=#datagrid-type-text>text</a></code>, and which is
+  not sortable, is implied. This column is removed if any explicit
+  columns are declared.</p>
+
+  <p>Each cell uses the type given for its column, so all cells in a
+  column present the same type of information.</p>
+
+<!--v2DGS:
+  <p>Selection of data in a <code>datagrid</code> operates at the row
+  level. If the <code title="attr-datagrid-multiple">multiple</code>
   attribute is present, multiple rows can be selected at once,
   otherwise the user can only select one row at a time.</p>
-
-  <p>The <code><a href=#datagrid>datagrid</a></code> element can be disabled entirely by
-  setting the <code title=attr-datagrid-disabled><a href=#attr-datagrid-disabled>disabled</a></code>
-  attribute.</p>
-<!--XXXDND
-  <p class="XXX">selection draggable [normative definitions are
-  in the interactive part below]</p>
 -->
 
-  <p>Columns, rows, and cells can each have specific flags, known as
-  classes, applied to them by the data provider. These classes <a href=#datagridClassSummary>affect the functionality</a> of the
-  <code><a href=#datagrid>datagrid</a></code> element, and are also <a href=#datagridPseudos>passed to the style system</a>. They are
-  similar in concept to the <code title=attr-class><a href=#classes>class</a></code>
-  attribute, except that they are not specified on elements but are
-  given by scripted data providers.</p> <!-- XXX check xrefs -->
+  <!-- v2DGDND: selection should draggable to and from datagrids -->
 
 
-  <h5 id=how-rows-are-identified><span class=secno>4.11.2.2 </span>How rows are identified</h5>
+  <h6 id=example:-a-datagrid-backed-by-a-static-table-element><span class=secno>4.11.2.1.1 </span>Example: a <code><a href=#datagrid>datagrid</a></code> backed by a static <code><a href=#the-table-element>table</a></code> element</h6>
 
-  <p>The chains of numbers that give a row's path, or identifier, are
-  represented by objects that implement the
-  <a href=#rowspecification>RowSpecification</a> interface.</p>
+  <p class=XXX>...</p>
 
-  <pre class=idl>[NoInterfaceObject] interface <dfn id=rowspecification>RowSpecification</dfn> {
-  // binding-specific interface
-};</pre>
 
-  <p>In JavaScript, 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, <code>[1,0,9]</code> is a
-  <a href=#rowspecification>RowSpecification</a>, as is <code>1</code> on its
-  own. However, <code>[1,0.2,9]</code> is not a
-  <a href=#rowspecification>RowSpecification</a> object, since its second value is not
-  an integer.</p>
+  <h6 id=example:-a-datagrid-backed-by-nested-ol-elements><span class=secno>4.11.2.1.2 </span>Example: a <code><a href=#datagrid>datagrid</a></code> backed by nested <code><a href=#the-ol-element>ol</a></code> elements</h6>
 
-  <p>User agents must always represent <code><a href=#rowspecification>RowSpecification</a></code>s
-  in JavaScript by using arrays, even if the path only has one
-  number.</p>
+  <p class=XXX>...</p>
 
-  <p>The root of the tree is represented by the empty path; in
-  JavaScript, this is the empty array (<code>[]</code>). Only the
-  <code title=dom-provider-getRowCount><a href=#dom-provider-getrowcount>getRowCount()</a></code> and
-  <code title=dom-provider-getChildAtPosition><a href=#dom-provider-getchildatposition>GetChildAtPosition()</a></code>
-  methods ever get called with the empty path.</p>
 
+  <h6 id=example:-a-datagrid-backed-by-a-server><span class=secno>4.11.2.1.3 </span>Example: a <code><a href=#datagrid>datagrid</a></code> backed by a server</h6>
 
-  <h5 id=the-data-provider-interface><span class=secno>4.11.2.3 </span>The data provider interface</h5>
+  <p class=XXX>...</p>
 
-  <p><em>The conformance criteria in this section apply to any
-  implementation of the <code><a href=#datagriddataprovider>DataGridDataProvider</a></code>, including
-  (and most commonly) the content author's implementation(s).</em></p>
 
-<p class=XXX>The API here needs rewriting. Don't implement this right now.</p>
+  <h5 id=populating-the-datagrid><span class=secno>4.11.2.2 </span>Populating the <code><a href=#datagrid>datagrid</a></code></h5>
 
-  <pre class=idl>// To be implemented by Web authors as a JS object
-[NoInterfaceObject] interface <dfn id=datagriddataprovider>DataGridDataProvider</dfn> {
-  void <a href=#dom-provider-initialize title=dom-provider-initialize>initialize</a>(in <a href=#htmldatagridelement>HTMLDataGridElement</a> datagrid);
-  unsigned long <a href=#dom-provider-getrowcount title=dom-provider-getRowCount>getRowCount</a>(in <a href=#rowspecification>RowSpecification</a> row);
-  unsigned long <a href=#dom-provider-getchildatposition title=dom-provider-getChildAtPosition>getChildAtPosition</a>(in <a href=#rowspecification>RowSpecification</a> parentRow, in unsigned long position);
-  unsigned long <a href=#dom-provider-getcolumncount title=dom-provider-getColumnCount>getColumnCount</a>();
-  DOMString <a href=#dom-provider-getcaptiontext title=dom-provider-getCaptionText>getCaptionText</a>(in unsigned long column);
-  void <a href=#dom-provider-getcaptionclasses title=dom-provider-getCaptionClasses>getCaptionClasses</a>(in unsigned long column, in DOMTokenList classes);
-  DOMString <a href=#dom-provider-getrowimage title=dom-provider-getRowImage>getRowImage</a>(in <a href=#rowspecification>RowSpecification</a> row);
-  <a href=#htmlmenuelement>HTMLMenuElement</a> <a href=#dom-provider-getrowmenu title=dom-provider-getRowMenu>getRowMenu</a>(in <a href=#rowspecification>RowSpecification</a> row);
-  void <a href=#dom-provider-getrowclasses title=dom-provider-getRowClasses>getRowClasses</a>(in <a href=#rowspecification>RowSpecification</a> row, in DOMTokenList classes);
-  DOMString <a href=#dom-provider-getcelldata title=dom-provider-getCellData>getCellData</a>(in <a href=#rowspecification>RowSpecification</a> row, in unsigned long column);
-  void <a href=#dom-provider-getcellclasses title=dom-provider-getCellClasses>getCellClasses</a>(in <a href=#rowspecification>RowSpecification</a> row, in unsigned long column, in DOMTokenList classes);
-<!--XXXDND
-  boolean <span title="dom-provider-canDrop">canDrop</span>(in <span>RowSpecification</span> row, in <span>RowSpecification</span> position, data);
-  boolean <span title="dom-provider-dropped">dropped</span>(in <span>RowSpecification</span> row, in <span>RowSpecification</span> position, data);
--->  void <a href=#dom-provider-togglecolumnsortstate title=dom-provider-toggleColumnSortState>toggleColumnSortState</a>(in unsigned long column);
-  void <a href=#dom-provider-setcellcheckedstate title=dom-provider-setCellCheckedState>setCellCheckedState</a>(in <a href=#rowspecification>RowSpecification</a> row, in unsigned long column, in long state);
-  void <a href=#dom-provider-cyclecell title=dom-provider-cycleCell>cycleCell</a>(in <a href=#rowspecification>RowSpecification</a> row, in unsigned long column);
-  void <a href=#dom-provider-editcell title=dom-provider-editCell>editCell</a>(in <a href=#rowspecification>RowSpecification</a> row, in unsigned long column, in DOMString data);
-<!--XXXPA
-  void <span title="dom-provider-performAction">performAction</span>(in DOMString action); // required if .performAction() is ever invoked on the datagrid
-  void <span title="dom-provider-performActionOnRow">performActionOnRow</span>(in <span>RowSpecification</span> row, in DOMString action); // required if getRowClasses ever includes 'deletable' or if <span title="dom-provider-.performActionOnRow">.performActionOnRow</span>() is ever invoked on the datagrid
-  void <span title="dom-provider-performActionOnCell">performActionOnCell</span>(in <span>RowSpecification</span> row, in unsigned long column, in DOMString action); // required if .performActionOnCell() is ever invoked on the datagrid
--->};</pre>
-<!-- based on http://lxr.mozilla.org/seamonkey/source/layout/xul/base/src/tree/public/nsITreeView.idl -->
+  <dl class=domintro><dt><var title="">datagrid</var> . <code title=dom-datagrid-listener><a href=#dom-datagrid-listener>listener</a></code> [ = <var title="">value</var> ]</dt>
+   <dd>
 
-  <p>The <code><a href=#datagriddataprovider>DataGridDataProvider</a></code> interface represents the
-  interface that objects must implement to be used as custom data
-  views for <code><a href=#datagrid>datagrid</a></code> elements.</p>
+    <p>Return the current object that is configured as the
+    <code><a href=#datagrid>datagrid</a></code> listener, if any. Returns null if there is
+    none.</p>
 
-  <p>Not all the methods are required. The minimum number of methods
-  that must be implemented in a useful view is two: the <code title=dom-provider-getRowCount><a href=#dom-provider-getrowcount>getRowCount()</a></code> and <code title=dom-provider-getCellData><a href=#dom-provider-getcelldata>getCellData()</a></code> methods.</p>
+    <p>The listener is an object provided by the script author that
+    receives notifications when the <code><a href=#datagrid>datagrid</a></code> needs row
+    data to render itself, when the user opens and closes rows with
+    children, when the user edits a cell, and when the user invokes a
+    row's context menu. (The <code><a href=#datagridlistener>DataGridListener</a></code> interface
+    used for this purpose is described in the next section.)</p>
 
-  <p>Once the object is written, it must be hooked up to the
-  <code><a href=#datagrid>datagrid</a></code> using the <dfn id=dom-datagrid-data title=dom-datagrid-data><code>data</code></dfn> DOM attribute.</p>
+    <p>Can be set, to change the current listener.</p>
 
-  <p>The following methods may be usefully implemented:</p>
+   </dd>
 
-  <dl><dt><dfn id=dom-provider-initialize title=dom-provider-initialize><code>initialize(<var title="">datagrid</var>)</code></dfn></dt>
 
-   <dd>Called by the <code><a href=#datagrid>datagrid</a></code> element (the one given by
-   the <var title="">datagrid</var> argument) after it has first
-   populated itself. This would typically be used to set the initial
-   selection of the <code><a href=#datagrid>datagrid</a></code> element when it is first
-   loaded. The data provider could also use this method call to
-   register a <code title=event-select><a href=#event-select>select</a></code> event handler
-   on the <code><a href=#datagrid>datagrid</a></code> in order to monitor selection
-   changes.</dd>
+   <dt><var title="">datagrid</var> . <code title=dom-datagrid-renotify><a href=#dom-datagrid-renotify>renotify</a></code>()</dt>
+   <dd>
 
-   <dt><dfn id=dom-provider-getrowcount title=dom-provider-getRowCount><code>getRowCount(<var title="">row</var>)</code></dfn></dt>
+    <p>Causes the <code><a href=#datagrid>datagrid</a></code> to resend notifications to the
+    listener (if any) for any rows or cells that the
+    <code><a href=#datagrid>datagrid</a></code> does not yet have information for.</p>
 
-   <dd>Must return the number of rows that are children of the
-   specified <var title="">row</var>, including rows that are
-   off-screen. If <var title="">row</var> is empty, then the number of
-   rows at the top level must be returned. If the value that this
-   method would return for a given <var title="">row</var> changes,
-   the relevant update methods on the <code><a href=#datagrid>datagrid</a></code> 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 <var title="">row</var> identifier
-   that is not empty.</dd>
+    <!-- useful, e.g., if there is a server error and the script loses
+    track of what rows it's supposed to be reporting. -->
 
-   <dt><dfn id=dom-provider-getchildatposition title=dom-provider-getChildAtPosition><code>getChildAtPosition(<var title="">parentRow</var>, <var title="">position</var>)</code></dfn></dt>
+   </dd>
 
-   <dd>Must return the index of the row that is a child of <var title="">parentRow</var> and that is to be positioned as the <var title="">position</var>th row under <var title="">parentRow</var>
-   when rendering the children of <var title="">parentRow</var>. If
-   <var title="">parentRow</var> is empty, then <var title="">position</var> refers to the <var title="">position</var>th row at the top level of the data
-   grid. May be omitted if the rows are always to be sorted in the
-   natural order. (The natural order is the one where the method
-   always returns <var title="">position</var>.) For a given <var title="">parentRow</var>, this method must never return the same
-   value for different values of <var title="">position</var>. The
-   returned value <var title="">x</var> must be in the range
-   0 ≤ <var title="">x</var> < <var title="">n</var>, where <var title="">n</var> is the value returned
-   by <code title=dom-provider-getRowCount><a href=#dom-provider-getrowcount>getRowCount(<var title="">parentRow</var>)</a></code>.</dd>
 
-   <dt><dfn id=dom-provider-getcolumncount title=dom-provider-getColumnCount><code>getColumnCount()</code></dfn></dt>
+   <dt><var title="">datagrid</var> . <code title=dom-datagrid-addColumn><a href=#dom-datagrid-addcolumn>addColumn</a></code>(<var title="">id</var>, <var title="">label</var>, <var title="">type</var> [, <var title="">icon</var> [, <var title="">sortable</var> [, <var title="">visible</var> ] ] ] )</dt>
+   <dd>
 
-   <dd>Must return the number of columns currently in the data model
-   (including columns that might be hidden). May be omitted if there
-   is only one column. If the value that this method would return
-   changes, the <code><a href=#datagrid>datagrid</a></code>'s <code title=dom-datagrid-updateEverything><a href=#dom-datagrid-updateeverything>updateEverything()</a></code>
-   method must be called.</dd>
+    <p>Adds a column to the <code><a href=#datagrid>datagrid</a></code>.</p>
 
-   <dt><dfn id=dom-provider-getcaptiontext title=dom-provider-getCaptionText><code>getCaptionText(<var title="">column</var>)</code></dfn></dt>
+    <p>If a column with the given identifier has already been added,
+    it just replaces the information for that column.</p>
 
-   <dd>Must return the caption, or label, for column <var title="">column</var>. May be omitted if the columns have no
-   captions. If the value that this method would return changes, the
-   <code><a href=#datagrid>datagrid</a></code>'s <code title=dom-datagrid-updateColumnChanged><a href=#dom-datagrid-updatecolumnchanged>updateColumnChanged()</a></code>
-   method must be called with the appropriate column index.</dd>
+    <p>The possible types are enumerated in the previous section.</p>
 
-   <dt><dfn id=dom-provider-getcaptionclasses title=dom-provider-getCaptionClasses><code>getCaptionClasses(<var title="">column</var>, <var title="">classes</var>)</code></dfn></dt>
+   </dd>
 
-   <dd>Must add the classes that apply to column <var title="">column</var> to the <var title="">classes</var> object.
-   May be omitted if the columns have no special classes. If the
-   classes that this method would add changes, the
-   <code><a href=#datagrid>datagrid</a></code>'s <code title=dom-datagrid-updateColumnChanged><a href=#dom-datagrid-updatecolumnchanged>updateColumnChanged()</a></code>
-   method must be called with the appropriate column index. Some
-   classes have <a href=#datagridClassSummary>predefined
-   meanings</a>.</dd>
 
-   <dt><dfn id=dom-provider-getrowimage title=dom-provider-getRowImage><code>getRowImage(<var title="">row</var>)</code></dfn></dt>
+   <dt><var title="">datagrid</var> . <code title=dom-datagrid-sortColumn><a href=#dom-datagrid-sortcolumn>sortColumn</a></code> [ = <var title="">value</var> ]</dt>
+   <dd>
 
-   <dd>Must return a <a href=#url>URL</a> giving the address of an image
-   that represents row <var title="">row</var>, or the empty string if
-   there is no applicable image. May be omitted if no rows have
-   associated images. If the value that this method would return
-   changes, the <code><a href=#datagrid>datagrid</a></code>'s update methods must be called
-   to update the row in question.</dd>
+    <p>Returns the identifier of the column by which the data is to be
+    sorted.</p>
 
-   <dt><dfn id=dom-provider-getrowmenu title=dom-provider-getRowMenu><code>getRowMenu(<var title="">row</var>)</code></dfn></dt>
+    <p>Can be set, to indicate that the sort order has changed. This
+    will cause the <code><a href=#datagrid>datagrid</a></code> to clear its position
+    information for rows, so <code title=dom-datagrid-setRows><a href=#dom-datagrid-setrows>setRows()</a></code> will have to be
+    called again with the new sort order.</p>
 
-   <dd>Must return an <code><a href=#htmlmenuelement>HTMLMenuElement</a></code> object that is to
-   be used as a context menu for row <var title="">row</var>, 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.</dd>
+    <p>The columns are not actually sorted by the
+    <code><a href=#datagrid>datagrid</a></code>; the data has to be sorted by the script
+    that adds the rows to the <code><a href=#datagrid>datagrid</a></code>.</p>
 
-   <dt><dfn id=dom-provider-getrowclasses title=dom-provider-getRowClasses><code>getRowClasses(<var title="">row</var>, <var title="">classes</var>)</code></dfn></dt>
+   </dd>
 
-   <dd>Must add the classes that apply to row <var title="">row</var>
-   to the <var title="">classes</var> object. May be omitted if the
-   rows have no special classes. If the classes that this method would
-   add changes, the <code><a href=#datagrid>datagrid</a></code>'s update methods must be
-   called to update the row in question. Some classes have <a href=#datagridClassSummary>predefined meanings</a>.</dd>
 
-   <dt><dfn id=dom-provider-getcelldata title=dom-provider-getCellData><code>getCellData(<var title="">row</var>, <var title="">column</var>)</code></dfn></dt>
+   <dt><var title="">datagrid</var> . <code title=dom-datagrid-sortAscending><a href=#dom-datagrid-sortascending>sortAscending</a></code> [ = <var title="">value</var> ]</dt>
+   <dd>
 
-   <dd>Must return the value of the cell on row <var title="">row</var> in column <var title="">column</var>. For text
-   cells, this must be the text to show for that cell. For <a href=#datagrid-cell-class-progress title=datagrid-cell-class-progress>progress bar cells</a>,
-   this must be either a floating point number in the range 0.0 to 1.0
-   (converted to a string representation<!-- XXX this isn't
-   technically enough to define what the author must be doing here,
-   but let's let that slide until someone notices -->), indicating the
-   fraction of the progress bar to show as full (1.0 meaning
-   complete), or the empty string, indicating an indeterminate
-   progress bar. If the value that this method would return changes,
-   the <code><a href=#datagrid>datagrid</a></code>'s update methods must be called to update
-   the rows that changed. If only one cell changed, the <code title=dom-datagrid-updateCellChanged><a href=#dom-datagrid-updatecellchanged>updateCellChanged()</a></code>
-   method may be used.</dd>
+    <p>Returns true if the data is to be sorted with small values
+    first; otherwise, returns false, indicating that bigger values are
+    to be put first.</p>
 
-   <dt><dfn id=dom-provider-getcellclasses title=dom-provider-getCellClasses><code>getCellClasses(<var title="">row</var>, <var title="">column</var>, <var title="">classes</var>)</code></dfn></dt>
+    <p>Can be set, to indicate that the order is about to change.</p>
 
-   <dd>Must add the classes that apply to the cell on row <var title="">row</var> in column <var title="">column</var> to the <var title="">classes</var> object. May be omitted if the cells have no
-   special classes. If the classes that this method would add changes,
-   the <code><a href=#datagrid>datagrid</a></code>'s update methods must be called to update
-   the rows or cells in question. Some classes have <a href=#datagridClassSummary>predefined meanings</a>.</dd>
+   </dd>
 
-   <dt><dfn id=dom-provider-togglecolumnsortstate title=dom-provider-toggleColumnSortState><code>toggleColumnSortState(<var title="">column</var>)</code></dfn></dt>
 
-   <dd>Called by the <code><a href=#datagrid>datagrid</a></code> when the user tries to sort
-   the data using a particular column <var title="">column</var>. The
-   data provider must update its state so that the <code title=dom-provider-getChildAtPosition><a href=#dom-provider-getchildatposition>GetChildAtPosition()</a></code>
-   method returns the new order, and the classes of the columns
-   returned by <code title=dom-provider-getCaptionClasses><a href=#dom-provider-getcaptionclasses>getCaptionClasses()</a></code>
-   represent the new sort status. There is no need to tell the
-   <code><a href=#datagrid>datagrid</a></code> that it the data has changed, as the
-   <code><a href=#datagrid>datagrid</a></code> automatically assumes that the entire data
-   model will need updating.</dd>
+   <dt><var title="">datagrid</var> . <code title=dom-datagrid-clearColumns><a href=#dom-datagrid-clearcolumns>clearColumns</a></code>()</dt>
+   <dd>
 
-   <dt><dfn id=dom-provider-setcellcheckedstate title=dom-provider-setCellCheckedState><code>setCellCheckedState(<var title="">row</var>, <var title="">column</var>, <var title="">state</var>)</code></dfn></dt>
+    <p>Removes all the columns in the <code><a href=#datagrid>datagrid</a></code>,
+    reinstating the implied column.</p>
 
-   <dd>Called by the <code><a href=#datagrid>datagrid</a></code> when the user changes the
-   state of a checkbox cell on row <var title="">row</var>, column
-   <var title="">column</var>. The checkbox should be toggled to the
-   state given by <var title="">state</var>, 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
-   <code><a href=#datagrid>datagrid</a></code> that the cell has changed, as the
-   <code><a href=#datagrid>datagrid</a></code> automatically assumes that the given cell
-   will need updating.</dd>
+   </dd>
 
-   <dt><dfn id=dom-provider-cyclecell title=dom-provider-cycleCell><code>cycleCell(<var title="">row</var>, <var title="">column</var>)</code></dfn></dt>
 
-   <dd>Called by the <code><a href=#datagrid>datagrid</a></code> when the user changes the
-   state of a cyclable cell on row <var title="">row</var>, column
-   <var title="">column</var>. The data provider should change the
-   state of the cell to the new state, as appropriate. There is no
-   need to tell the <code><a href=#datagrid>datagrid</a></code> that the cell has
-   changed, as the <code><a href=#datagrid>datagrid</a></code> automatically assumes that
-   the given cell will need updating.</dd>
+   <dt><var title="">datagrid</var> . <code title=dom-datagrid-setRowCount><a href=#dom-datagrid-setrowcount>setRowCount</a></code>(<var title="">childCount</var>, <var title="">rowCount</var>)</dt>
+   <dd>
 
-   <dt><dfn id=dom-provider-editcell title=dom-provider-editCell><code>editCell(<var title="">row</var>, <var title="">column</var>, <var title="">data</var>)</code></dfn></dt>
+    <p>Sets the numbers of rows in the <code><a href=#datagrid>datagrid</a></code>,
+    excluding rows that are descendants of rows that are closed.</p>
 
-   <dd>Called by the <code><a href=#datagrid>datagrid</a></code> when the user edits the
-   cell on row <var title="">row</var>, column <var title="">column</var>. The new value of the cell is given by <var title="">data</var>. The data provider should update the cell
-   accordingly. There is no need to tell the <code><a href=#datagrid>datagrid</a></code>
-   that the cell has changed, as the <code><a href=#datagrid>datagrid</a></code>
-   automatically assumes that the given cell will need updating.</dd>
+    <p>Throws a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception if the
+    arguments contradict each other or previously declared information
+    (e.g. declaring that the <code><a href=#datagrid>datagrid</a></code> has three rows when
+    the 12th row has been declared).</p>
 
-<!--XXXPA
-  void performAction(in DOMString action); // required if .performAction() is ever invoked on the datagrid
-  void performActionOnRow(in <span>RowSpecification</span> row, in DOMString action); // required if getRowClasses ever includes 'deletable' or if .performActionOnRow() is ever invoked on the datagrid
-  void performActionOnCell(in <span>RowSpecification</span> row, in unsigned long column, in DOMString action); // required if .performActionOnCell() is ever invoked on the datagrid
--->
+   </dd>
 
-  </dl><p>The following classes (for rows, columns, and cells) may be
-  usefully used in conjunction with this interface:</p>
 
-  <table id=datagridClassSummary><tr><th>Class name</th>
-    <th>Applies to</th>
-    <th>Description</th>
-   <tr><td><!--checked--><dfn id=datagrid-cell-class-checked title=datagrid-cell-class-checked><code>checked</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell has a checkbox and it is checked. (The <code title=datagrid-cell-class-cyclable><a href=#datagrid-cell-class-cyclable>cyclable</a></code> and <code title=datagrid-cell-class-progress><a href=#datagrid-cell-class-progress>progress</a></code> classes
-    override this, though.)</td>
-   <tr><td><!--cyclable--><dfn id=datagrid-cell-class-cyclable title=datagrid-cell-class-cyclable><code>cyclable</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell can be cycled through multiple values. (The <code title=datagrid-cell-class-progress><a href=#datagrid-cell-class-progress>progress</a></code> class
-    overrides this, though.)</td>
-   <tr><td><!--editable--><dfn id=datagrid-cell-class-editable title=datagrid-cell-class-editable><code>editable</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell can be edited. (The <code title=datagrid-cell-class-cyclable><a href=#datagrid-cell-class-cyclable>cyclable</a></code>, <code title=datagrid-cell-class-progress><a href=#datagrid-cell-class-progress>progress</a></code>, <code title=datagrid-cell-class-checked><a href=#datagrid-cell-class-checked>checked</a></code>, <code title=datagrid-cell-class-checked><a href=#datagrid-cell-class-checked>unchecked</a></code> and <code title=datagrid-cell-class-checked><a href=#datagrid-cell-class-checked>indeterminate</a></code> classes
-    override this, though.)</td>
-   <tr><td><!--header--><dfn id=datagrid-row-class-header title=datagrid-row-class-header><code>header</code></dfn></td>
-    <td>Rows</td>
-    <td>The row is a heading, not a data row.</td>
-   <tr><td><!--indeterminate--><dfn id=datagrid-cell-class-indeterminate title=datagrid-cell-class-indeterminate><code>indeterminate</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell has a checkbox, and it can be set to an indeterminate
-    state. If neither the <code title=datagrid-cell-class-checked><a href=#datagrid-cell-class-checked>checked</a></code> nor <code title=datagrid-cell-class-checked><a href=#datagrid-cell-class-checked>unchecked</a></code> classes are
-    present, then the checkbox is in that state, too. (The <code title=datagrid-cell-class-cyclable><a href=#datagrid-cell-class-cyclable>cyclable</a></code> and <code title=datagrid-cell-class-progress><a href=#datagrid-cell-class-progress>progress</a></code> classes
-    override this, though.)</td>
-   <tr><td><!--initially-hidden--><dfn id=datagrid-column-class-initially-hidden title=datagrid-column-class-initially-hidden><code>initially-hidden</code></dfn></td>
-    <td>Columns</td>
-    <td>The column will not be shown when the <code><a href=#datagrid>datagrid</a></code> is
-    initially rendered. If this class is not present on the column
-    when the <code><a href=#datagrid>datagrid</a></code> is initially rendered, the column
-    will be visible if space allows.</td>
-   <tr><td><!--initially-closed--><dfn id=datagrid-row-class-initially-closed title=datagrid-row-class-initially-closed><code>initially-closed</code></dfn></td>
-    <td>Rows</td>
-    <td>The row will be closed when the <code><a href=#datagrid>datagrid</a></code> is
-    initially rendered. If neither this class nor the <code title=datagrid-row-class-initially-open><a href=#datagrid-row-class-initially-open>initially-open</a></code>
-    class is present on the row when the <code><a href=#datagrid>datagrid</a></code> is
-    initially rendered, the initial state will depend on platform
-    conventions.</td>
-   <tr><td><!--initially-open--><dfn id=datagrid-row-class-initially-open title=datagrid-row-class-initially-open><code>initially-open</code></dfn></td>
-    <td>Rows</td>
-    <td>The row will be opened when the <code><a href=#datagrid>datagrid</a></code> is
-    initially rendered. If neither this class nor the <code title=datagrid-row-class-initially-closed><a href=#datagrid-row-class-initially-closed>initially-closed</a></code>
-    class is present on the row when the <code><a href=#datagrid>datagrid</a></code> is
-    initially rendered, the initial state will depend on platform
-    conventions.</td>
-   <tr><td><!--progress--><dfn id=datagrid-cell-class-progress title=datagrid-cell-class-progress><code>progress</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell is a progress bar.</td>
-   <tr><td><!--reversed--><dfn id=datagrid-column-class-reversed title=datagrid-column-class-reversed><code>reversed</code></dfn></td>
-    <td>Columns</td>
-    <td>If the cell is sorted, the sort direction is descending,
-    instead of ascending.</td>
-   <tr><td><!--selectable-separator--><dfn id=datagrid-row-class-selectable-separator title=datagrid-row-class-selectable-separator><code>selectable-separator</code></dfn></td>
-    <td>Rows</td>
-    <td>The row is a normal, selectable, data row, except that instead
-    of having data, it only has a separator. (The <code title=datagrid-row-class-header><a href=#datagrid-row-class-header>header</a></code> and <code title=datagrid-row-class-separator><a href=#datagrid-row-class-separator>separator</a></code> classes
-    override this, though.)</td>
-   <tr><td><!--separator--><dfn id=datagrid-row-class-separator title=datagrid-row-class-separator><code>separator</code></dfn></td>
-    <td>Rows</td>
-    <td>The row is a separator row, not a data row. (The <code title=datagrid-row-class-header><a href=#datagrid-row-class-header>header</a></code> class
-    overrides this, though.)</td>
-   <tr><td><!--sortable--><dfn id=datagrid-column-class-sortable title=datagrid-column-class-sortable><code>sortable</code></dfn></td>
-    <td>Columns</td>
-    <td>The data can be sorted by this column.</td>
-   <tr><td><!--sorted--><dfn id=datagrid-column-class-sorted title=datagrid-column-class-sorted><code>sorted</code></dfn></td>
-    <td>Columns</td>
-    <td>The data is sorted by this column. Unless the <code title=datagrid-column-class-reversed><a href=#datagrid-column-class-reversed>reversed</a></code> class is
-    also present, the sort direction is ascending.</td>
-   <tr><td><!--unchecked--><dfn id=datagrid-cell-class-unchecked title=datagrid-cell-class-unchecked><code>unchecked</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell has a checkbox and, unless the <code title=datagrid-cell-class-checked><a href=#datagrid-cell-class-checked>checked</a></code> class is
-    present as well, it is unchecked. (The <code title=datagrid-cell-class-cyclable><a href=#datagrid-cell-class-cyclable>cyclable</a></code> and <code title=datagrid-cell-class-progress><a href=#datagrid-cell-class-progress>progress</a></code> classes
-    override this, though.)</td>
-   </tr><!--XXXPA
-   <tr>
-    <td><!- -deletable- -><dfn title="datagrid-row-class-deletable"><code>deletable</code></dfn></td>
-    <td>Rows</td>
-    <td></td>
-   </tr>
---></table><h5 id=the-default-data-provider><span class=secno>4.11.2.4 </span>The default data provider</h5>
+   <dt><var title="">datagrid</var> . <code title=dom-datagrid-setRows><a href=#dom-datagrid-setrows>setRows</a></code>(<var title="">rows</var>)</dt>
+   <dd>
 
-  <p>The user agent must supply a default data provider for the case
-  where the <code><a href=#datagrid>datagrid</a></code>'s <code title=dom-datagrid-data><a href=#dom-datagrid-data>data</a></code> attribute is null. It must act
-  as described in this section.</p>
+    <p>Updates data for rows in the <code><a href=#datagrid>datagrid</a></code>, or fills in
+    data for rows previously implied by a call to <code title=dom-datagrid-setRowCount><a href=#dom-datagrid-setrowcount>setRowCount()</a></code> but not
+    previously declared.</p>
 
-  <p>The behavior of the default data provider depends on the nature
-  of the first element child of the <code><a href=#datagrid>datagrid</a></code>.</p>
+    <p>The <var title="">rows</var> argument is an array of rows, each
+    represented by a further array consisting of:</p>
 
-  <dl class=switch><!-- XXX some of these entries say "the method must return" and
-   other say "the characteristic must be"; this should be rationalized
-   --><dt>While the first element child is a <code><a href=#the-table-element>table</a></code> element</dt>
+    <ol class=brief><li>A <code><a href=#rowid>RowID</a></code> object identifying the row.</li>
 
-   <dd>
+     <li>An integer giving the position of the row in its parent,
+     given the current sort order, or −1 to set other row data
+     without setting a position or changing a previously declared
+     position.</li>
 
-    <p><strong><code title=dom-provider-getRowCount><a href=#dom-provider-getrowcount>getRowCount(<var title="">row</var>)</a></code></strong>:
-    The number of rows returned by the default data provider for the
-    root of the tree (when <var title="">row</var> is empty) must be the total number of <code><a href=#the-tr-element>tr</a></code> elements
-    that are children of <code><a href=#the-tbody-element>tbody</a></code> elements that are children
-    of the <code><a href=#the-table-element>table</a></code>, if there are any such child
-    <code><a href=#the-tbody-element>tbody</a></code> elements. If there are no such
-    <code><a href=#the-tbody-element>tbody</a></code> elements then the number of rows returned for
-    the root must be the number of <code><a href=#the-tr-element>tr</a></code> elements that are
-    children of the <code><a href=#the-table-element>table</a></code>.</p>
+     <li>An integer giving the number of children of the row, or 0 if
+     the row has no children, or −1 if the row has children but
+     the count is currently unknown. If the number of children has
+     already been set to 0 or a positive integer, then passing
+     −1 leaves the previous count unchanged.</li>
 
-    <p>When <var title="">row</var> is not empty, the number of rows
-    returned must be zero.</p>
+     <li>An array giving the data for zero or more cells in the row,
+     as described below.</li>
 
-    <p class=note>The <code><a href=#the-table-element>table</a></code>-based default data provider
-    cannot represent a tree.</p>
+     <li>A boolean declaring whether the row is open or not. This
+     entry, if omitted, is assumed to be false (closed), unless the
+     row has already been declared as open.</li>
 
-    <p class=note>Rows in <code><a href=#the-thead-element>thead</a></code> elements do not
-    contribute to the number of rows returned, although they do affect
-    the columns and column captions. Rows in <code><a href=#the-tfoot-element>tfoot</a></code>
-    elements are <a href=#ignore title=ignore>ignored</a> completely by
-    this algorithm.</p>
+     <li>An integer giving the number of rows that are descendants of
+     this row, excluding those that are descendants of descendants of
+     this row that are closed. This entry can be omitted if the row is
+     closed or if it has already been declared.</li>
 
-    <p id=defaultDataProviderTableMapper><strong><code title=dom-provider-getChildAtPosition><a href=#dom-provider-getchildatposition>getChildAtPosition(<var title="">row</var>, <var title="">i</var>)</a></code></strong>: The
-    default data provider must return the mapping appropriate to the
-    <a href=#defaultDataProviderTableSort>current sort
-    order</a>.</p>
+    </ol><p>The array giving the data for the cells in the row consists of
+    a further set of arrays, one per cell. The first item of each of
+    these arrays is the column's identifier; the subsequent values
+    vary based on the type of the column, as follows:</p>
 
-    <p><strong><code title=dom-provider-getColumnCount><a href=#dom-provider-getcolumncount>getColumnCount()</a></code></strong>:
-    The number of columns returned must be the number of
-    <code><a href=#the-td-element>td</a></code> element children in the first <code><a href=#the-tr-element>tr</a></code>
-    element child of the first <code><a href=#the-tbody-element>tbody</a></code> element child of the
-    <code><a href=#the-table-element>table</a></code>, if there are any such <code><a href=#the-tbody-element>tbody</a></code>
-    elements. If there are no such <code><a href=#the-tbody-element>tbody</a></code> elements, then
-    it must be the number of <code><a href=#the-td-element>td</a></code> element children in the
-    first <code><a href=#the-tr-element>tr</a></code> element child of the <code><a href=#the-table-element>table</a></code>, if
-    any, or otherwise 1. If the number that would be returned by these
-    rules is 0, then 1 must be returned instead.</p>
+    <dl><dt><code title=datagrid-type-text><a href=#datagrid-type-text>text</a></code></dt>
+     <dd>
+      <ol class=brief><li>A string giving the cell's value.
+       <li>Optionally, an <code><a href=#the-img-element>img</a></code> element giving an icon for the cell.
+      </ol></dd>
 
-    <p><strong><code title=dom-provider-getCaptionText><a href=#dom-provider-getcaptiontext>getCaptionText(<var title="">i</var>)</a></code></strong>: If the <code><a href=#the-table-element>table</a></code> has
-    no <code><a href=#the-thead-element>thead</a></code> element child, or if its first
-    <code><a href=#the-thead-element>thead</a></code> element child has no <code><a href=#the-tr-element>tr</a></code> element
-    child, the default data provider must return the empty string for
-    all captions. Otherwise, the value of the <code><a href=#textcontent>textContent</a></code>
-    attribute of the <var title="">i</var>th <code><a href=#the-th-element>th</a></code> element
-    child of the first <code><a href=#the-tr-element>tr</a></code> element child of the first
-    <code><a href=#the-thead-element>thead</a></code> element child of the <code><a href=#the-table-element>table</a></code> element
-    must be returned. If there is no such <code><a href=#the-th-element>th</a></code> element, the
-    empty string must be returned.</p>
+     <dt><code title=datagrid-type-editable><a href=#datagrid-type-editable>editable</a></code></dt>
+     <dd>
+      <ol class=brief><li>A string giving the cell's value.
+       <li>Optionally, a <code><a href=#the-datalist-element>datalist</a></code> element giving a set of predefined options.
+       <li>Optionally, an <code><a href=#the-img-element>img</a></code> element giving an icon for the cell.
+      </ol></dd>
 
-    <p><strong><code title=dom-provider-getCaptionClasses><a href=#dom-provider-getcaptionclasses>getCaptionClasses(<var title="">i</var>, <var title="">classes</var>)</a></code></strong>: If
-    the <code><a href=#the-table-element>table</a></code> has no <code><a href=#the-thead-element>thead</a></code> element child, or
-    if its first <code><a href=#the-thead-element>thead</a></code> element child has no
-    <code><a href=#the-tr-element>tr</a></code> element child, the default data provider must not
-    add any classes for any of the captions. Otherwise, each class
-    in the <code title=attr-class><a href=#classes>class</a></code> attribute of the <var title="">i</var>th <code><a href=#the-th-element>th</a></code> element child of the first
-    <code><a href=#the-tr-element>tr</a></code> element child of the first <code><a href=#the-thead-element>thead</a></code>
-    element child of the <code><a href=#the-table-element>table</a></code> element must be added to
-    the <var title="">classes</var>. If there is no such
-    <code><a href=#the-th-element>th</a></code> element, no classes must be added. The user agent
-    must then:</p>
+     <dt><code title=datagrid-type-checkable><a href=#datagrid-type-checkable>checkable</a></code></dt>
+     <dd>
+      <ol class=brief><li>A string giving the cell's value.
+       <li>A boolean, indicating whether the cell is checked (true) or not (false).
+       <li>Optionally, a boolean indicating whether the value of the cell is obscured as indeterminate (true), or not (false).
+       <li>Optionally, an <code><a href=#the-img-element>img</a></code> element giving an icon for the cell.
+      </ol></dd>
 
-    <ol><li>Remove the <code title=datagrid-column-class-sorted><a href=#datagrid-column-class-sorted>sorted</a></code> and <code title=datagrid-column-class-reversed><a href=#datagrid-column-class-reversed>reversed</a></code>
-     classes.</li>
+     <dt><code title=datagrid-type-list><a href=#datagrid-type-list>list</a></code></dt>
+     <dd>
+      <ol class=brief><li>A string giving the cell's current value.
+       <li>A <code><a href=#the-select-element>select</a></code> element giving the <a href=#concept-select-option-list title=concept-select-option-list>list of options</a>.
+       <li>Optionally, an <code><a href=#the-img-element>img</a></code> element giving an icon for the cell.
+      </ol></dd>
 
-     <li>If the <code><a href=#the-table-element>table</a></code> element has a <code title=attr-class><a href=#classes>class</a></code> attribute that includes the <code title="">sortable</code> class, add the <code title=datagrid-column-class-sortable><a href=#datagrid-column-class-sortable>sortable</a></code>
-     class.</li>
+     <dt><code title=datagrid-type-progress><a href=#datagrid-type-progress>progress</a></code></dt>
+     <dd>
+      <ol class=brief><li>A value in the range 0.0 (no progress) to 1.0 (task complete).
+      </ol></dd>
 
-     <li>If the column is the one currently being used to
-     sort the data, add the <code title=datagrid-column-class-sorted><a href=#datagrid-column-class-sorted>sorted</a></code> class.</li>
+     <dt><code title=datagrid-type-meter><a href=#datagrid-type-meter>meter</a></code></dt>
+     <dd>
+      <ol class=brief><li>A number giving the cell's value.
+       <li>Optionally, a number giving the maximum value, if it's not 1.
+       <li>Optionally, a number giving the minimum value, if it's not 0.
+       <li>Optionally, a number giving the highest value that is considered "low".
+       <li>Optionally, a number giving the lowest value that is considered "high".
+       <li>Optionally, a number giving the value that is considered optimal.
+      </ol></dd>
 
-     <li>If the column is the one currently being used to sort the
-     data, and it is sorted in descending order, add the <code title=datagrid-column-class-reversed><a href=#datagrid-column-class-reversed>reversed</a></code> class as
-     well.</li>
+     <dt><code title=datagrid-type-custom><a href=#datagrid-type-custom>custom</a></code></dt>
+     <dd>
+      <ol class=brief><li>A number giving the minimum width of the cell, in CSS pixels, that is desired.
+       <li>A number giving the minimum height of the cell, in CSS pixels, that is desired.
+       <li>A function that is passed a <code><a href=#canvasrenderingcontext2d>CanvasRenderingContext2D</a></code> object, along with the width and height (in CSS pixels) of the cell that the context will draw on.
+      </ol></dd>
 
-    </ol><p>The various row- and cell- related methods operate relative to
-    a particular element, the element of the row or cell specified by
-    their arguments.</p>
+    </dl><p>While the rows in a single call to the <code title=dom-datagrid-setRows><a href=#dom-datagrid-setrows>setRows()</a></code> method can be in any
+    order, for each row, it is important that all its ancestor rows
+    and all its open previous siblings are also declared, either in
+    the same call or in an earlier one.</p>
 
-    <p><strong>For rows</strong>: Since the default data provider for
-    a <code><a href=#the-table-element>table</a></code> 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 <var title="">i</var>.</p>
+    <p>Throws a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception if the
+    arguments contradict each other or previously declared information
+    (e.g. saying that a row's position is 5 when the parent row only
+    has 3 children, or naming a column that doesn't exist, or
+    declaring a row without declaring its parent, or changing the
+    number of children that a row has while that row and its ancestors
+    are all open).</p>
 
-    <p>If the <code><a href=#the-table-element>table</a></code> has <code><a href=#the-tbody-element>tbody</a></code> element
-    children, the element for the <var title="">i</var>th row is the
-    <var title="">i</var>th <code><a href=#the-tr-element>tr</a></code> element that is a child of
-    a <code><a href=#the-tbody-element>tbody</a></code> element that is a child of the
-    <code><a href=#the-table-element>table</a></code> element. If the <code><a href=#the-table-element>table</a></code> does not
-    have <code><a href=#the-tbody-element>tbody</a></code> element children, then the element for the
-    <var title="">i</var>th real row is the <var title="">i</var>th
-    <code><a href=#the-tr-element>tr</a></code> element that is a child of the <code><a href=#the-table-element>table</a></code>
-    element.</p>
+   </dd>
 
-    <p><strong>For cells</strong>: Given a row and its element, the
-    row's <var title="">i</var>th cell's element is the <var title="">i</var>th <code><a href=#the-td-element>td</a></code> element child of the row
-    element.</p>
 
-    <p class=note>The <code>colspan</code> and <code>rowspan</code>
-    attributes are <a href=#ignore title=ignore>ignored</a> by this
-    algorithm.</p>
+   <dt><var title="">datagrid</var> . <code title=dom-datagrid-insertRows><a href=#dom-datagrid-insertrows>insertRows</a></code>(<var title="">rows</var>)</dt>
+   <dd>
 
-    <p><strong><code title=dom-provider-getRowImage><a href=#dom-provider-getrowimage>getRowImage(<var title="">i</var>)</a></code></strong>: The <a href=#url>URL</a> of the
-    row's image is the <a href=#absolute-url>absolute URL</a> obtained by <a href=#resolve-a-url title="resolve a url">resolving</a> the value of the <code title=attr-img-src><a href=#attr-img-src>src</a></code> attribute of the first
-    <code><a href=#the-img-element>img</a></code> element child of the row's first cell's element,
-    relative to that element, if there is one and resolving its
-    attribute is successful. Otherwise, the <a href=#url>URL</a> of the
-    row's image is the empty string.</p> <!-- note that if the base
-    URL has changed, this URL can be different than the one that the
-    <img> element fetched when it was created -->
+    <p>Inserts the given rows into the <code><a href=#datagrid>datagrid</a></code>,
+    increasing the numbers of rows that the <code><a href=#datagrid>datagrid</a></code>
+    assumes are present.</p>
 
-    <p><strong><code title=dom-provider-getRowMenu><a href=#dom-provider-getrowmenu>getRowMenu(<var title="">i</var>)</a></code></strong>: If the row's first cell's
-    element has a <code><a href=#menus>menu</a></code> element child, then the row's menu
-    is the first <code><a href=#menus>menu</a></code> element child of the row's first
-    cell's element. Otherwise, the row has no menu.</p>
+    <p>The <var title="">rows</var> argument is an array of rows in
+    the same structure as the argument to the <code title=dom-datagrid-setRows><a href=#dom-datagrid-setrows>setRows()</a></code> method described
+    above, with the same expectations of consistency (a given row's
+    ancestors and earlier open siblings being listed either earlier or
+    in the same call as a given row). However, unlike with the <code title=dom-datagrid-setRows><a href=#dom-datagrid-setrows>setRows()</a></code> method, if a row is
+    inserted along with its child, the child is not included in the
+    child and row counts of the parent row; every row in the <var title="">rows</var> argument will increase its parent's counts
+    automatically.</p>
 
-    <p><strong><code title=dom-provider-getRowClasses><a href=#dom-provider-getrowclasses>getRowClasses(<var title="">i</var>, <var title="">classes</var>)</a></code></strong>:
-    The default data provider must never add a class to the row's
-    classes.</p>
+    <p>Throws a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception if the
+    arguments contradict each other or previously declared
+    information.</p>
 
-    <p id=defaultDataProviderTableSort><strong><code title=dom-provider-toggleColumnSortState><a href=#dom-provider-togglecolumnsortstate>toggleColumnSortState(<var title="">i</var>)</a></code></strong>: 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.)</p>
+   </dd>
 
-    <p>When the sort mapping is changed, the values returned by the
-    <code title=dom-provider-getChildAtPosition><a href=#dom-provider-getchildatposition>getChildAtPosition()</a></code>
-    method for the default data provider <a href=#defaultDataProviderTableMapper>will change
-    appropriately</a>.</p>
 
-    <p><strong><code title=dom-provider-getCellData><a href=#dom-provider-getcelldata>getCellData(<var title="">i</var>, <var title="">j</var>)</a></code>, <code title=dom-provider-getCellClasses><a href=#dom-provider-getcellclasses>getCellClasses(<var title="">i</var>, <var title="">j</var>, <var title="">classes</var>)</a></code>, <code title=dom-provider-setCellCheckedState><a href=#dom-provider-setcellcheckedstate>getCellCheckedState(<var title="">i</var>, <var title="">j</var>, <var title="">state</var>)</a></code>, <code title=dom-provider-cycleCell><a href=#dom-provider-cyclecell>cycleCell(<var title="">i</var>,
-    <var title="">j</var>)</a></code>, and <code title=dom-provider-editCell><a href=#dom-provider-editcell>editCell(<var title="">i</var>,
-    <var title="">j</var>, <var title="">data</var>)</a></code></strong>:
-    See <a href=#commonDefaultDataGridMethodDefinitions>the common
-    definitions below</a>.</p>
+   <dt><var title="">datagrid</var> . <code title=dom-datagrid-deleteRows><a href=#dom-datagrid-deleterows>deleteRows</a></code>(<var title="">rows</var>)</dt>
+   <dd>
 
-    <p>The data provider must call the <code><a href=#datagrid>datagrid</a></code>'s update
-    methods appropriately whenever the descendants of the
-    <code><a href=#datagrid>datagrid</a></code> mutate. For example, if a <code><a href=#the-tr-element>tr</a></code> is
-    removed, then the <code title=dom-datagrid-updateRowsRemoved><a href=#dom-datagrid-updaterowsremoved>updateRowsRemoved()</a></code>
-    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
-    <code><a href=#the-table-element>table</a></code> element stops being the first child of the
-    <code><a href=#datagrid>datagrid</a></code>, then the data provider must call the <code title=dom-datagrid-updateEverything><a href=#dom-datagrid-updateeverything>updateEverything()</a></code>
-    method on the <code><a href=#datagrid>datagrid</a></code>. 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 <code title=dom-datagrid-updateEverything><a href=#dom-datagrid-updateeverything>updateEverything()</a></code> if
-    the change did affect the sort order.</p>
+    <p>Removes the given rows from the <code><a href=#datagrid>datagrid</a></code>, and
+    updates the number of rows known to be in the
+    <code><a href=#datagrid>datagrid</a></code> accordingly. The argument is an array of
+    <code><a href=#rowid>RowID</a></code> objects identifying the rows to remove.</p>
 
+    <p>Throws a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception if the argument
+    includes a row the <code><a href=#datagrid>datagrid</a></code> doesn't know about.</p>
+    <!-- since otherwise behaviour might depend on where the user
+    scrolled! -->
+
    </dd>
 
 
-   <dt>While the first element child is a <code><a href=#the-select-element>select</a></code> or <code><a href=#the-datalist-element>datalist</a></code> element</dt>
+   <dt><var title="">datagrid</var> . <code title=dom-datagrid-repaint><a href=#dom-datagrid-repaint>repaint</a></code>(<var title="">row</var>, <var title="">column</var>)</dt>
+   <dd>
 
+    <p>If the given column's type is <code title=datagrid-type-custom><a href=#datagrid-type-custom>custom</a></code>, then causes the
+    <code><a href=#datagrid>datagrid</a></code> to reinvoke the function that obtains the
+    desired rendering.</p>
+
+   </dd>
+
+
+   <dt><var title="">datagrid</var> . <code title=dom-datagrid-clearRows><a href=#dom-datagrid-clearrows>clearRows</a></code>()</dt>
    <dd>
 
-    <p>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.</p>
+    <p>Clears the <code><a href=#datagrid>datagrid</a></code> of all row data, resetting it
+    to empty<!-- v2DGS:, and clears the selection-->.</p>
 
-    <p>For the rows, assume the existence of a node filter view of the
-    descendants of the first element child of the
-    <code><a href=#datagrid>datagrid</a></code> element (the <code><a href=#the-select-element>select</a></code> or
-    <code><a href=#the-datalist-element>datalist</a></code> element), that skips all nodes other than
-    <code><a href=#the-optgroup-element>optgroup</a></code> and <code><a href=#the-option-element>option</a></code> elements, as well as
-    any descendants of any <code><a href=#the-option-element>option</a></code> elements.</p>
+   </dd>
 
-    <p>Given a path <var title="">row</var>, the corresponding element
-    is the one obtained by drilling into the view, taking the child
-    given by the path each time.</p>
+  </dl><div class=impl>
 
-    <div class=example>
+  <h6 id=the-listener><span class=secno>4.11.2.2.1 </span>The listener</h6>
 
-     <p>Given the following XML markup:</p>
+  <p>The <dfn id=dom-datagrid-listener title=dom-datagrid-listener><code>listener</code></dfn> DOM
+  attribute allows authors to specify an object that will receive all
+  the notifications from the <code><a href=#datagrid>datagrid</a></code>. Initially, its
+  value must be null. On getting, it must return its value. On
+  setting, its value must be set to the new value, and then the user
+  agent must <a href=#queue-a-task>queue a task</a> to call the <code title=dom-listener-initialize><a href=#dom-listener-initialize>initalize()</a></code> method with the
+  <code><a href=#datagrid>datagrid</a></code> element as its only argument.</p>
 
-     <pre><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></pre>
 
-     <p>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.</p>
+  <h6 id=the-columns><span class=secno>4.11.2.2.2 </span>The columns</h6>
 
-    </div>
+  <p>The columns are represented by the <dfn id=column-list>column list</dfn>, an
+  ordered list of entries for columns, each of which consists of:</p>
 
-    <p><code title=dom-provider-getRowCount><a href=#dom-provider-getrowcount>getRowCount(<var title="">row</var>)</a></code> 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 <var title="">row</var> is empty, the
-    corresponding element is the <code><a href=#the-select-element>select</a></code> element at the
-    root of the filtered view.)</p>
+  <dl><dt>An identifier</dt>
 
-    <p><code title=dom-provider-getChildAtPosition><a href=#dom-provider-getchildatposition>getChildAtPosition(<var title="">row</var>, <var title="">position</var>)</a></code> must
-    return <var title="">position</var>. (The
-    <code><a href=#the-select-element>select</a></code>/<code><a href=#the-datalist-element>datalist</a></code> default data provider
-    does not support sorting the data grid.)</p>
+   <dd>A string used to identify the column in the API.</dd>
 
-    <p><code title=dom-provider-getRowImage><a href=#dom-provider-getrowimage>getRowImage(<var title="">i</var>)</a></code> must return the empty string, <code title=dom-provider-getRowMenu><a href=#dom-provider-getrowmenu>getRowMenu(<var title="">i</var>)</a></code> must return null.</p>
+   <dt>A label</dt>
 
-    <p><code title=dom-provider-getRowClasses><a href=#dom-provider-getrowclasses>getRowClasses(<var title="">row</var>, <var title="">classes</var>)</a></code> must add the
-    classes from the following list to <var title="">classes</var>
-    when their condition is met:</p>
+   <dd>A string used in the user interface.</dd>
 
-    <ul><li>If the <var title="">row</var>'s corresponding element is an
-     <code><a href=#the-optgroup-element>optgroup</a></code> element: <code title=datagrid-row-class-header><a href=#datagrid-row-class-header>header</a></code></li>
+   <dt>A type</dt>
 
-     <li>If the <var title="">row</var>'s corresponding element
-     contains other elements that are also in the view, and the
-     element's <code title=attr-class><a href=#classes>class</a></code> attribute
-     contains the <code title="">closed</code> class: <code title=datagrid-row-class-initially-closed><a href=#datagrid-row-class-initially-closed>initially-closed</a></code></li>
+   <dd>One of the types described below.</dd>
 
-     <li>If the <var title="">row</var>'s corresponding element
-     contains other elements that are also in the view, and the
-     element's <code title=attr-class><a href=#classes>class</a></code> attribute
-     contains the <code title="">open</code> class: <code title=datagrid-row-class-initially-open><a href=#datagrid-row-class-initially-open>initially-open</a></code></li>
+   <dt>An icon</dt>
 
-    </ul><p>The <code title=dom-provider-getCellData><a href=#dom-provider-getcelldata>getCellData(<var title="">row</var>, <var title="">cell</var>)</a></code> method must
-    return the value of the <code title=attr-optgroup-label><a href=#attr-optgroup-label>label</a></code> attribute if the <var title="">row</var>'s corresponding element is an
-    <code><a href=#the-optgroup-element>optgroup</a></code> element, otherwise, if the <var title="">row</var>'s corresponding element is an
-    <code><a href=#the-option-element>option</a></code>element, its <code title=attr-option-label><a href=#attr-option-label>label</a></code> attribute if it has one,
-    otherwise the value of its <code><a href=#textcontent>textContent</a></code> DOM
-    attribute.</p>
+   <dd>An image, copied from an <code><a href=#the-img-element>img</a></code> element when the
+   column was declared.</dd>
 
-    <p>The <code title=dom-provider-getCellClasses><a href=#dom-provider-getcellclasses>getCellClasses(<var title="">row</var>, <var title="">cell</var>, <var title="">classes</var>)</a></code> method must add no classes.</p>
+   <dt>Whether the column is sortable</dt>
 
-    <p class=XXX><!-- select-provider-selection
-    XXX-->autoselect some rows when initialized, reflect the selection
-    in the select, reflect the multiple attribute somehow.</p>
+   <dd>A boolean indicating whether the user can request that the data
+   be sorted by this column (true), or not (false).</dd>
 
-    <p>The data provider must call the <code><a href=#datagrid>datagrid</a></code>'s update
-    methods appropriately whenever the descendants of the
-    <code><a href=#datagrid>datagrid</a></code> mutate.</p>
+   <dt>Whether the column is visible</dt>
 
-   </dd>
+   <dd>A boolean indicating whether the column is part of the
+   <code><a href=#datagrid>datagrid</a></code>'s rendering.</dd>
 
+  </dl><p>Initially, the <a href=#column-list>column list</a> must have a single
+  column, the <dfn id=default-column>default column</dfn>, whose identifier is the empty
+  string, whose label is the empty string, whose type is <code title=datagrid-type-text><a href=#datagrid-type-text>text</a></code>, with no icon, which is not
+  sortable, and which <em>is</em> visible.</p>
 
-   <dt>While the first element child is another element</dt>
+  <hr><p>The <dfn id=dom-datagrid-addcolumn title=dom-datagrid-addColumn><code>addColumn(<var title="">id</var>, <var title="">label</var>, <var title="">type</var>, <var title="">icon</var>, <var title="">sortable</var>, <var title="">visible</var>)</code></dfn>
+  method must run the following steps:</p>
 
-   <dd>
+  <ol><li><p>If there is already an entry in <a href=#column-list>column list</a>,
+   other than the <a href=#default-column>default column</a>, whose identifier is
+   <var title="">id</var>, throw a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code>
+   exception and abort these steps.</li>
 
-    <p>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.</p>
+   <li>
 
-    <p>For the rows, assume the existence of a node filter view of the
-    descendants of the <code><a href=#datagrid>datagrid</a></code> that skips all nodes
-    other than <code><a href=#the-li-element>li</a></code>, <code><a href=#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements>h1</a></code>–<code><a href=#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements>h6</a></code>, and
-    <code><a href=#the-hr-element>hr</a></code> elements, and skips any descendants of
-    <code><a href=#menus>menu</a></code> elements.</p>
+    <p>If <var title="">type</var> is not a string equal to one of the
+    <a href=#allowed-datagrid-column-types>allowed <code>datagrid</code> column types</a>, then
+    throw a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception and abort these
+    steps.</p>
 
-    <p>Given this view, each element in the view represents a row in
-    the data model. The element corresponding to a path <var title="">row</var> 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.</p>
+   </li>
 
-    <p><code title=dom-provider-getRowCount><a href=#dom-provider-getrowcount>getRowCount(<var title="">row</var>)</a></code> 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 <var title="">row</var> is
-    empty.</p>
+   <li><p>If the <var title="">icon</var> argument is present and not
+   null, and the given <code><a href=#the-img-element>img</a></code> element's <code title=dom-img-complete><a href=#dom-img-complete>complete</a></code> attribute is false, then
+   throw an <code><a href=#invalid_state_err>INVALID_STATE_ERR</a></code> exception and abort these
+   steps.</li>
 
-    <div class=example>
+   <li><p>If the <var title="">icon</var> argument is present and not
+   null, then copy the image data from that <code><a href=#the-img-element>img</a></code> element,
+   and let <var title="">image</var> be the copy of that image
+   data. Otherwise, let <var title="">image</var> be nothing.</li>
 
-     <p>In the following example, the elements are identified by the
-     paths given by their child text nodes:</p>
+   <li><p>Append a new entry to the <a href=#column-list>column list</a>, with
+   <var title="">id</var> as its identifier, <var title="">label</var>
+   as its label, <var title="">type</var> as its type, and <var title="">image</var> as its icon. Let the column be sortable if the
+   <var title="">sortable</var> argument is present and true, and make
+   it visible if the <var title="">visible</var> argument is absent or
+   true.</li>
 
-     <pre><datagrid>
- <ol>
-  <li> row 0 </li>
-  <li> row 1
-   <ol>
-    <li> row 1,0 </li>
-   </ol>
-  </li>
-  <li> row 2 </li>
- </ol>
-</datagrid></pre>
+   <li><p>If the <a href=#column-list>column list</a> contains the <a href=#default-column>default
+   column</a>, then remove the <a href=#default-column>default column</a> from the
+   <a href=#column-list>column list</a>, discard any data for cells in that column
+   in any rows in the <code><a href=#datagrid>datagrid</a></code>, set <code title=dom-datagrid-sortColumn><a href=#dom-datagrid-sortcolumn>sortColumn</a></code> to <var title="">id</var>, set <code title=dom-datagrid-sortAscending><a href=#dom-datagrid-sortascending>sortAscending</a></code> to true,
+   and run the <a href=#datagrid-resort-steps><code>datagrid</code> resort
+   steps</a>.</li>
 
-     <p>In this example, only the <code><a href=#the-li-element>li</a></code> elements actually
-     appear in the data grid; the <code><a href=#the-ol-element>ol</a></code> element does not
-     affect the data grid's processing model.</p>
+  </ol><hr><p>The <dfn id=dom-datagrid-sortcolumn title=dom-datagrid-sortColumn><code>sortColumn</code></dfn> DOM
+  attribute gives the current column used for sorting.  Initially, its
+  value must be the empty string. On getting, it must return its
+  current value. On setting, if the new value doesn't match the
+  identifier of one of the columns in the <a href=#column-list>column list</a>,
+  then the user agent must throw a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code>
+  exception. Otherwise, if the new value is not the same as its
+  current value, then the user agent must set the attribute to the new
+  value, and then run the <a href=#datagrid-resort-steps><code>datagrid</code> resort
+  steps</a>.</p>
 
-    </div>
+  <p>The <dfn id=dom-datagrid-sortascending title=dom-datagrid-sortAscending><code>sortAscending</code></dfn>
+  DOM attribute specifies the direction that the tree is sorted in,
+  ascending (true) or descending (false). Initially, its value must be
+  true (ascending). On getting, it must return its current value. On
+  setting, if the new value is not the same as its current value, then
+  the user agent must set the attribute to the new value, and then run
+  the <a href=#datagrid-resort-steps><code>datagrid</code> resort steps</a>.</p>
 
-    <p><code title=dom-provider-getChildAtPosition><a href=#dom-provider-getchildatposition>getChildAtPosition(<var title="">row</var>, <var title="">position</var>)</a></code> must
-    return <var title="">position</var>. (The generic default data
-    provider does not support sorting the data grid.)</p>
+  <p>When a column is marked as being sortable, the user agent should
+  allow the user to select that column to be the column used for
+  sorting, and should allow the user to chose whether the sort order
+  is ascending or descending.</p>
 
-    <p><code title=dom-provider-getRowImage><a href=#dom-provider-getrowimage>getRowImage(<var title="">i</var>)</a></code> must return the <a href=#absolute-url>absolute URL</a>
-    obtained from <a href=#resolve-a-url title="resolve a url">resolving</a> the
-    value of the <code title=attr-img-src><a href=#attr-img-src>src</a></code> attribute of
-    the first <code><a href=#the-img-element>img</a></code> 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
-    relative to the element itself, is successful. Otherwise, it must
-    return the empty string.</p> <!-- note that if the base URL has
-    changed, this URL can be different than the one that the <img>
-    element fetched when it was created -->
+  <p>When the user changes the sort order in this manner, the user
+  agent must update the <code title=dom-datagrid-sortColumn><a href=#dom-datagrid-sortcolumn>sortColumn</a></code> and <code title=dom-datagrid-sortAscending><a href=#dom-datagrid-sortascending>sortAscending</a></code> attributes
+  appropriately, and then run the <a href=#datagrid-resort-steps><code>datagrid</code> resort
+  steps</a>.</p>
 
-    <div class=example>
+  <p class=note>The <a href=#datagrid-resort-steps><code>datagrid</code> resort steps</a>
+  are described in the next section.</p>
 
-     <p>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:</p>
+  <hr><p>The <dfn id=dom-datagrid-clearcolumns title=dom-datagrid-clearColumns><code>clearColumns()</code></dfn>
+  method, if the <a href=#column-list>column list</a> doesn't contain the
+  <a href=#default-column>default column</a>, must empty the <a href=#column-list>column
+  list</a>, append the <a href=#default-column>default column</a> to the now empty
+  <a href=#column-list>column list</a>, discard any data for cells in all rows in
+  the <code><a href=#datagrid>datagrid</a></code>, set <code title=dom-datagrid-sortColumn><a href=#dom-datagrid-sortcolumn>sortColumn</a></code> to the empty
+  string, set <code title=dom-datagrid-sortAscending><a href=#dom-datagrid-sortascending>sortAscending</a></code> to true, and
+  run the <a href=#datagrid-resort-steps><code>datagrid</code> resort steps</a>. (If the
+  <a href=#column-list>column list</a> is already just the <a href=#default-column>default
+  column</a>, then the method does nothing.)</p>
 
-     <pre><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></pre>
 
-    </div>
+  <h6 id=the-rows><span class=secno>4.11.2.2.3 </span>The rows</h6>
 
-    <p><code title=dom-provider-getRowMenu><a href=#dom-provider-getrowmenu>getRowMenu(<var title="">i</var>)</a></code> must return the first <code><a href=#menus>menu</a></code>
-    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.)</p>
+  <p>A <code><a href=#datagrid>datagrid</a></code> element is intended to show a
+  representation of a tree, where typically the user only sees a
+  small part of the tree at a time.</p>
 
-    <p><code title=dom-provider-getRowClasses><a href=#dom-provider-getrowclasses>getRowClasses(<var title="">i</var>, <var title="">classes</var>)</a></code> must add the
-    classes from the following list to <var title="">classes</var>
-    when their condition is met:</p>
+  <p>To make this efficent, the <code><a href=#datagrid>datagrid</a></code> element
+  <em>actually</em> shows a small part of a <em>sparse</em> tree, so
+  that only relevant parts of the data structure need be loaded at any
+  time. Specifically, the model requires only that all the ancestor
+  rows of the displayed rows be loaded, as well as any open earlier
+  siblings (in the displayed sort order) of the displayed rows.</p>
 
-    <ul><li>If the row's element contains other elements that are also in
-     the view, and the element's <code title=attr-class><a href=#classes>class</a></code>
-     attribute contains the <code title="">closed</code> class: <code title=datagrid-row-class-initially-closed><a href=#datagrid-row-class-initially-closed>initially-closed</a></code></li>
+  <p>Conceptually, therefore, a <code><a href=#datagrid>datagrid</a></code> has a number of
+  related sparse data structures backing it.</p>
 
-     <li>If the row's element contains other elements that are also in
-     the view, and the element's <code title=attr-class><a href=#classes>class</a></code>
-     attribute contains the <code title="">open</code> class: <code title=datagrid-row-class-initially-open><a href=#datagrid-row-class-initially-open>initially-open</a></code></li>
+  <p>The first is the <dfn id=natural-order-sparse-data-tree>natural order sparse data tree</dfn>. This
+  is the structure in which rows are entered as they are declared, in
+  their natural order. This can differ from the order actually
+  displayed to the user. It consists of nested sparse lists of
+  rows. In the <a href=#natural-order-sparse-data-tree>natural order sparse data tree</a>, a row will
+  always have all its parents already declared. Once a row is added to
+  this structure, it can only be removed by the <code title=dom-datagrid-deleteRows><a href=#dom-datagrid-deleterows>deleteRows()</a></code> and <code title=dom-datagrid-clearRows><a href=#dom-datagrid-clearrows>clearRows()</a></code> methods. The order of
+  nodes in this tree never changes; to move a node in this tree, it
+  has to be removed and then another row (with the same data)
+  reinserted elsewhere.</p>
 
-     <li>If the row's element is an <code><a href=#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements>h1</a></code>–<code><a href=#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements>h6</a></code>
-     element: <code title=datagrid-row-class-header><a href=#datagrid-row-class-header>header</a></code></li>
+  <p>The second structure is the <dfn id=display-order-sparse-data-tree>display order sparse data
+  tree</dfn>. This is a similar structure that contains a subset of
+  the rows in the <a href=#natural-order-sparse-data-tree>natural order sparse data tree</a>, ordered
+  in the order given by the <code title=dom-datagrid-sortAscending><a href=#dom-datagrid-sortascending>sortAscending</a></code> and <code title=dom-datagrid-sortColumn><a href=#dom-datagrid-sortcolumn>sortColumn</a></code> attributes, and
+  excluding rows with one or more ancestors that are closed. This tree
+  is cleared whenever the <code title=dom-datagrid-sortAscending><a href=#dom-datagrid-sortascending>sortAscending</a></code> and <code title=dom-datagrid-sortColumn><a href=#dom-datagrid-sortcolumn>sortColumn</a></code> attributes
+  change.</p>
 
-     <li>If the row's element is an <code><a href=#the-hr-element>hr</a></code> element: <code title=datagrid-row-class-separator><a href=#datagrid-row-class-separator>separator</a></code></li> <!--
-     XXX no way to get selectable-separator -->
+  <p>The third structure is the <dfn id=display-order-sparse-data-list>display order sparse data
+  list</dfn>. This structure is a flattened representation of the
+  <a href=#display-order-sparse-data-tree>display order sparse data tree</a>.</p>
 
-    </ul><p>The <code title=dom-provider-getCellData><a href=#dom-provider-getcelldata>getCellData(<var title="">i</var>, <var title="">j</var>)</a></code>, <code title=dom-provider-getCellClasses><a href=#dom-provider-getcellclasses>getCellClasses(<var title="">i</var>, <var title="">j</var>, <var title="">classes</var>)</a></code>, <code title=dom-provider-setCellCheckedState><a href=#dom-provider-setcellcheckedstate>getCellCheckedState(<var title="">i</var>, <var title="">j</var>, <var title="">state</var>)</a></code>, <code title=dom-provider-cycleCell><a href=#dom-provider-cyclecell>cycleCell(<var title="">i</var>,
-    <var title="">j</var>)</a></code>, and <code title=dom-provider-editCell><a href=#dom-provider-editcell>editCell(<var title="">i</var>, <var title="">j</var>, <var title="">data</var>)</a></code> methods must
-    act as described in <a href=#commonDefaultDataGridMethodDefinitions>the common
-    definitions below</a>, treating the row's element as being the
-    cell's element.</p>
+  <p>At any time, a number of consecutive rows in the <a href=#display-order-sparse-data-list>display
+  order sparse data list</a> are physically visible to the
+  user. The <code><a href=#datagrid>datagrid</a></code> fires notifications to a <a href=#dom-datagrid-listener title=dom-datagrid-listener>listener</a> (provided by script),
+  and the listener, or other some script, is expected to feed the
+  <code><a href=#datagrid>datagrid</a></code> with the information needed to render the
+  control.</p>
 
-    <p class=XXX id=generic-provider-selection>selection
-    handling?</p>
+  <p>A <code><a href=#datagrid>datagrid</a></code> has a <dfn id=pending-datagrid-rows-list>pending <code>datagrid</code>
+  rows list</dfn>, which is a list of rows in the <a href=#display-order-sparse-data-list>display order
+  sparse data list</a> for which the <code><a href=#datagrid>datagrid</a></code> has sent
+  notifications requesting information but not yet received
+  information about.</p>
 
-    <p>The data provider must call the <code><a href=#datagrid>datagrid</a></code>'s update
-    methods appropriately whenever the descendants of the
-    <code><a href=#datagrid>datagrid</a></code> mutate.</p>
+  <p>A <code><a href=#datagrid>datagrid</a></code> also has a <dfn id=pending-datagrid-cells-list>pending
+  <code>datagrid</code> <em>cells</em> list</dfn>, which is a list of
+  row/column pairs (cells) for which the <code><a href=#datagrid>datagrid</a></code> has
+  sent notifications requesting information but not yet received
+  information about.</p>
 
-   </dd>
+  <p>User agents may discard information about rows that are not
+  displayed and that are not ancestors or open earlier siblings of
+  rows or ancestors of rows that are displayed.</p>
 
+  <hr><p>These structures are different views of the collection of rows
+  that form the <code><a href=#datagrid>datagrid</a></code>. Each row has the following
+  information associated with it:</p>
 
-   <dt>Otherwise, while there is no element child</dt>
+  <dl><dt>A parent</dt>
 
+   <dd><p>Either another row, or the <code><a href=#datagrid>datagrid</a></code> itself. This
+   is the parent of the row in the <a href=#natural-order-sparse-data-tree>natural order sparse data
+   tree</a> and the <a href=#display-order-sparse-data-tree>display order sparse data tree</a>
+   for the <code><a href=#datagrid>datagrid</a></code>.</dd>
+
+   <dt>A natural order position relative to the other rows with the
+   same parent</dt>
+
    <dd>
 
-    <p>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 <code><a href=#datagrid>datagrid</a></code>'s child list changes such
-    that there is a first element child, then the data provider must
-    call the <code title=dom-datagrid-updateEverything><a href=#dom-datagrid-updateeverything>updateEverything()</a></code>
-    method on the <code><a href=#datagrid>datagrid</a></code>.</p>
+    <p>This is the number of rows that precede this row under the same
+    parent in the <a href=#natural-order-sparse-data-tree>natural order sparse data tree</a>. This
+    number can't be changed relative to other rows in the same parent;
+    to change the relative natural order of data in the
+    <code><a href=#datagrid>datagrid</a></code>, the original rows have to be removed and
+    new rows (with the same data but different natural positions)
+    inserted in their place. (The exact number of a row can change, as
+    new rows can be inserted above it.)</p>
 
+    <p>A row can be identified by a <code><a href=#rowid>RowID</a></code> object. This is
+    an array of numbers, consisting of the natural order positions of
+    each ancestor row and the row itself, starting from the furthest
+    ancestor. Thus, for instance, the fourth child row of the first
+    child row of the second row in a <code><a href=#datagrid>datagrid</a></code> would be
+    identified by a <code><a href=#rowid>RowID</a></code> object whose value is <code title="">[1, 0, 3]</code>. A row's identifier changes if rows are
+    <a href=#dom-datagrid-insertrows title=dom-datagrid-insertRows>inserted before it</a> in
+    the <code><a href=#datagrid>datagrid</a></code>.</p>
+
    </dd>
 
-  </dl><h6 id=commonDefaultDataGridMethodDefinitions><span class=secno>4.11.2.4.1 </span>Common default data
-  provider method definitions for cells</h6>
+   <dt>A display order position relative to the other rows with
+   the same parent</dt>
 
-  <p>These definitions are used for the cell-specific methods of the
-  default data providers (other than in the
-  <code><a href=#the-select-element>select</a></code>/<code><a href=#the-datalist-element>datalist</a></code> 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.</p>
+   <dd><p>This is the number of rows that precede this row under the
+   same parent in the <a href=#display-order-sparse-data-tree>display order sparse data
+   tree</a>. This number can be unknown. If the sort order
+   changes, then this information is lost (as the <a href=#display-order-sparse-data-tree>display order
+   sparse data tree</a> is cleared).</dd>
 
-  <dl><dt>Cyclable cells</dt>
+   <dt>A child count</dt>
 
+   <dd><p>The number of rows that have this row as a parent. If this is
+   zero, the row cannot be opened. If this is −1, then the
+   child count is unknown but the row can be opened. This value can be
+   changed by the <code title=dom-datagrid-setRows><a href=#dom-datagrid-setrows>setRows()</a></code>
+   method only if the current value is −1 or if the row or one
+   of its ancestors is closed. Otherwise, it can only be changed
+   indirectly using the <code title=dom-datagrid-insertRows><a href=#dom-datagrid-insertrows>insertRows()</a></code> and <code title=dom-datagrid-deleteRows><a href=#dom-datagrid-deleterows>deleteRows()</a></code> methods.</dd>
+
+   <dt>An open flag</dt>
+
+   <dd><p>A boolean indicating whether the row is open (true) or
+   closed (false). Once set, can only be changed by the user or if one
+   of the row's ancestors is itself closed. A row can also be in a
+   third state, "opening", which is treated as closed for all purposes
+   except that the user agent may indicate that the row is in this
+   special state, and except that when the row is updated to have a
+   row count, the row will switch to being open.</dd>
+
+   <dt>A row count</dt>
+
+   <dd><p>The number of rows that have this row as a parent or
+   ancestor, and that do not have an ancestor that is a descendant of
+   this row that is itself closed. If this is −1, then the row
+   count is unknown. This value can be changed by the <code title=dom-datagrid-setRows><a href=#dom-datagrid-setrows>setRows()</a></code> method only if the
+   row or one of its ancestors is closed (or opening, but not
+   open). Otherwise, it can only be changed indirectly using the <code title=dom-datagrid-insertRows><a href=#dom-datagrid-insertrows>insertRows()</a></code> and <code title=dom-datagrid-deleteRows><a href=#dom-datagrid-deleterows>deleteRows()</a></code>
+   methods.</dd>
+
+   <dt>Cells</dt>
+
+   <dd><p>The data that applies to this row. Cell data is discussed in
+   more detail below.</dd>
+
+  </dl><p>The <code><a href=#datagrid>datagrid</a></code> itself also has a <dfn id=datagrid-child-count title="datagrid
+  child count">child count</dfn> and a <dfn id=datagrid-row-count title="datagrid row
+  count">row count</dfn>, which are analogous to the child counts and
+  row counts for rows. Initially these must be zero.</p>
+
+  <hr><p>The <dfn id=datagrid-resort-steps><code>datagrid</code> resort steps</dfn>, which are
+  invoked when the sort order changes as described in the previous
+  section, are as follows:</p>
+
+  <ol><li>
+
+    <p>Clear the <a href=#display-order-sparse-data-tree>display order sparse data tree</a>
+    (i.e. mark the display order position of all the rows in the
+    <code><a href=#datagrid>datagrid</a></code> as unknown).</p>
+
+    <p>User agents may cache the position information of rows for
+    various values of <code title=dom-datagrid-sortColumn><a href=#dom-datagrid-sortcolumn>sortColumn</a></code> and <code title=dom-datagrid-sortAscending><a href=#dom-datagrid-sortascending>sortAscending</a></code>, instead
+    of discarding the information altogether. If the user agent caches
+    this information, and has information that applies to the current
+    values of <code title=dom-datagrid-sortColumn><a href=#dom-datagrid-sortcolumn>sortColumn</a></code>
+    and <code title=dom-datagrid-sortAscending><a href=#dom-datagrid-sortascending>sortAscending</a></code>,
+    then the user agent may repopulate the <a href=#display-order-sparse-data-tree>display order sparse
+    data tree</a> from this information.</p>
+
+   </li>
+
+   <li>
+
+    <p>Clear the <a href=#pending-datagrid-rows-list>pending <code>datagrid</code> rows list</a>
+    and the <a href=#pending-datagrid-cells-list>pending <code>datagrid</code> cells list</a>.</p>
+
+   </li>
+
+   <li>
+
+    <p>Invoke the <a href=#datagrid-update-display-algorithm><code>datagrid</code> update display
+    algorithm</a>.</p>
+
+   </li>
+
+   <!-- v2: queue a task to fire an event, or tell the listener the
+   sort order changed, or something -->
+
+  </ol><hr><p>The <dfn id=dom-datagrid-renotify title=dom-datagrid-renotify><code>renotify()</code></dfn> method
+  must empty the <a href=#pending-datagrid-rows-list>pending <code>datagrid</code> rows list</a>
+  and the <a href=#pending-datagrid-cells-list>pending <code>datagrid</code> cells list</a>, and
+  invoke the <a href=#datagrid-update-display-algorithm><code>datagrid</code> update display
+  algorithm</a>.</p>
+
+  <hr><p>The <dfn id=dom-datagrid-setrowcount title=dom-datagrid-setRowCount><code>setRowCount(<var title="">childCount</var>, <var title="">rowCount</var>)</code></dfn> method must run the following
+  steps:</p>
+
+  <ol><li>
+
+    <p>Set the <a href=#datagrid-child-count><code>datagrid</code> child count</a> to <var title="">childCount</var>, the <a href=#datagrid-row-count><code>datagrid</code> row
+    count</a> to <var title="">rowCount</var>.</p>
+
+   </li>
+
+   <li>
+
+    <p><a href=#audit-the-datagrid>Audit the <code>datagrid</code></a>. If this fails,
+    then revert the changes made in the previous step, throw a
+    <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception, and abort these
+    steps.</p>
+
+   </li>
+
+   <li>
+
+    <p>Invoke the <a href=#datagrid-update-display-algorithm><code>datagrid</code> update display
+    algorithm</a>.</p>
+
+   </li>
+
+  </ol><hr><p>The <dfn id=dom-datagrid-setrows title=dom-datagrid-setRows><code>setRows(<var title="">rows</var>)</code></dfn> method must run the following
+  steps:</p>
+
+  <ol><li>
+
+    <p><a href=#type-check-a-rowlist-object title="type-check a RowList object">Type-check the <var title="">rows</var> argument</a>. If this fails, throw a
+    <code>TypeError</code> exception, and abort these steps.</p>
+
+   </li>
+
+   <li>
+
+    <p><a href=#partially-sort-a-rowlist-object title="partially sort a RowList object">Partially sort
+    the <var title="">rows</var> argument</a>.</p>
+
+   </li>
+
+   <li>
+
+    <p>For each <code><a href=#row>Row</a></code> object in the <var title="">rows</var> argument, in order, perform the appropriate
+    steps from the list below.</p>
+
+    <p class=note>The changes made to the <code><a href=#datagrid>datagrid</a></code>'s
+    data structures in this step get reverted (as required below) if
+    any consistency errors are detected either in this step or the
+    next.</p>
+
+    <dl><dt>If there already exists a row in the <code><a href=#datagrid>datagrid</a></code>'s
+     <a href=#natural-order-sparse-data-tree>natural order sparse data tree</a> with the same
+     identifier as given by the <code><a href=#row>Row</a></code> object's
+     <code><a href=#rowid>RowID</a></code> object, and that row and all its ancestors are
+     open</dt>
+
+     <dd>
+
+      <p>If one of the following conditions is true, then revert all
+      the changes done in this step, throw a
+      <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception, and abort these
+      steps:</p>
+
+      <ul><li>The value of the <code><a href=#row>Row</a></code> object's second entry is
+       neither −1 nor equal to the child count of the
+       preexisting row.</li>
+
+       <li>The <code><a href=#row>Row</a></code> object has fewer than five entries, or
+       its fifth entry is false.</li>
+
+       <li>The <code><a href=#row>Row</a></code> object has fewer than six entries, or
+       its sixth entry is not equal to the row count of the
+       preexisting row.</li>
+
+      </ul></dd>
+
+     <dt>If there already exists a row in the <code><a href=#datagrid>datagrid</a></code>'s
+     <a href=#natural-order-sparse-data-tree>natural order sparse data tree</a> with the same
+     identifier as given by the <code><a href=#row>Row</a></code> object's
+     <code><a href=#rowid>RowID</a></code> object, but either that row or one of its
+     ancestors is closed</dt>
+
+     <dd>
+
+      <p>Set the preexisting row's child count to the value of the
+      <code><a href=#row>Row</a></code> object's second entry.</p>
+
+      <p>If the <code><a href=#row>Row</a></code> object has five or more entries, and
+      either its fifth entry is true and the preexisting row is closed
+      but not opening, or its fifth entry is false and the preexisting
+      row is open, then: if the preexisting row has no ancestor row
+      that is closed, then revert all the changes done in this step,
+      throw a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception, and abort
+      these steps; otherwise, if the fifth entry is false, then close
+      the row; otherwise, open the row.</p>
+
+      <p>If the <code><a href=#row>Row</a></code> object has six entries, set the
+      preexisting row's row count to the value of the <code><a href=#row>Row</a></code>
+      object's sixth entry.</p>
+
+      <p>If the preexisting row is opening, then: increase the
+      <a href=#datagrid-row-count><code>datagrid</code> row count</a> and the row counts
+      of any ancestor rows by the number of rows that the preexisting
+      row now has in its row count, then open the row.</p> <!-- we
+      should also "update the <span>pending <code>datagrid</code> rows
+      list</span> and the <span>pending <code>datagrid</code> cells
+      list</span> accordingly" -->
+
+
+     </dd>
+
+     <dt>There does not exist a row in the <code><a href=#datagrid>datagrid</a></code>'s
+     <a href=#natural-order-sparse-data-tree>natural order sparse data tree</a> with the same
+     identifier as given by the <code><a href=#row>Row</a></code> object's
+     <code><a href=#rowid>RowID</a></code> object</dt>
+
+     <dd>
+
+      <p>If the <code><a href=#rowid>RowID</a></code> object has a length greater than 1,
+      then verify that there is a row identified by the
+      <code><a href=#rowid>RowID</a></code> consisting of all but the last number in the
+      <code><a href=#row>Row</a></code> object's <code><a href=#rowid>RowID</a></code>. If there is no
+      such row present in the <a href=#natural-order-sparse-data-tree>natural order sparse data
+      tree</a>, then revert all the changes done in this step,
+      throw a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception, and abort
+      these steps.</p>
+
+      <p>Create a row and insert it into the <a href=#natural-order-sparse-data-tree>natural order
+      sparse data tree</a>, such that its parent is the row
+      identified by the <code><a href=#rowid>RowID</a></code> consisting of all but the
+      last number in the <code><a href=#row>Row</a></code> object's <code><a href=#rowid>RowID</a></code>,
+      or the <code><a href=#datagrid>datagrid</a></code> if the lenght of the
+      <code><a href=#row>Row</a></code> object's <code><a href=#rowid>RowID</a></code> is 1; with its
+      natural order position being the last number of the
+      <code><a href=#row>Row</a></code> object's <code><a href=#rowid>RowID</a></code>; with the child
+      count being the value of the third entry of the <code><a href=#row>Row</a></code>
+      object; with the row being marked closed unless the
+      <code><a href=#row>Row</a></code> object has five or more entries and its fifth
+      entry is true, in which case the row is open; and with its row
+      count being −1 unless the <code><a href=#row>Row</a></code> object has six
+      entries, in which case the row count is equal to the value of
+      the <code><a href=#row>Row</a></code> object's sixth entry.</p>
+
+     </dd>
+
+    </dl></li>
+
+   <li>
+
+    <p><a href=#audit-the-datagrid>Audit the <code>datagrid</code></a>. If this fails,
+    then revert the changes made in the previous step, throw a
+    <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception, and abort these
+    steps.</p>
+
+   </li>
+
+   <li>
+
+    <p>For each <code><a href=#row>Row</a></code> object in the <var title="">rows</var> argument, in order, <a href=#apply-a-row-object title="apply a Row
+    object">apply the <code>Row</code> object</a>.</p>
+
+   </li>
+
+   <li>
+
+    <p>Invoke the <a href=#datagrid-update-display-algorithm><code>datagrid</code> update display
+    algorithm</a>.</p>
+
+   </li>
+
+  </ol><hr><p>The <dfn id=dom-datagrid-insertrows title=dom-datagrid-insertRows><code>insertRows(<var title="">rows</var>)</code></dfn> method must run the following
+  steps:</p>
+
+  <ol><li>
+
+    <p><a href=#type-check-a-rowlist-object title="type-check a RowList object">Type-check the <var title="">rows</var> argument</a>. If this fails, throw a
+    <code>TypeError</code> exception, and abort these steps.</p>
+
+   </li>
+
+   <li>
+
+    <p><a href=#partially-sort-a-rowlist-object title="partially sort a RowList object">Partially sort
+    the <var title="">rows</var> argument</a>.</p>
+
+   </li>
+
+   <li>
+
+    <p>For each <code><a href=#row>Row</a></code> object in the <var title="">rows</var> argument, in order, run the following
+    steps:</p>
+
+    <p class=note>The changes made to the <code><a href=#datagrid>datagrid</a></code>'s
+    data structures in this step get reverted (as required below) if
+    any consistency errors are detected either in this step or the
+    next.</p>
+
+    <ol><li>
+
+      <p>Let <var title="">parent</var> be the row identified by the
+      <code><a href=#rowid>RowID</a></code> consisting of all but the last number in the
+      <code><a href=#row>Row</a></code> object's <code><a href=#rowid>RowID</a></code>, or the
+      <code><a href=#datagrid>datagrid</a></code> itself it the <code><a href=#row>Row</a></code> object's
+      <code><a href=#rowid>RowID</a></code> has length 0.</p>
+
+      <p>If there is no such row present in the <a href=#natural-order-sparse-data-tree>natural order
+      sparse data tree</a>, then revert all the changes done in
+      this algorithm, throw a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code>
+      exception, and abort these steps.</p>
+
+     </li>
+
+     <li>
+
+      <p>Increment by one the natural order position of all rows whose
+      parent is <var title="">parent</var> and whose natural order
+      position is equal to or greater than the last number of the
+      <code><a href=#row>Row</a></code> object's <code><a href=#rowid>RowID</a></code>.</p>
+
+     </li>
+
+     <li>
+
+      <p>If the value of the <code><a href=#row>Row</a></code> object's second entry is
+      not −1, then increment by one the display order position
+      of all rows whose parent is <var title="">parent</var> and whose
+      display order position is equal to or greater than the value of
+      the <code><a href=#row>Row</a></code> object's second entry.</p>
+
+     <!--(Not sure how to really say this.)
+      <p>Update the <span>pending <code>datagrid</code> rows
+      list</span> and the <span>pending <code>datagrid</code> cells
+      list</span> accordingly.</p>
+     -->
+
+     </li>
+ 
+     <li>
+
+      <p>Create a row and insert it into the <a href=#natural-order-sparse-data-tree>natural order
+      sparse data tree</a>, such that its parent is <var title="">parent</var>; with its natural order position being the
+      last number of the <code><a href=#row>Row</a></code> object's <code><a href=#rowid>RowID</a></code>;
+      with the child count being the value of the third entry of the
+      <code><a href=#row>Row</a></code> object; with the row being marked closed unless
+      the <code><a href=#row>Row</a></code> object has five or more entries and its
+      fifth entry is true, in which case the row is open; and with its
+      row count being −1 unless the <code><a href=#row>Row</a></code> object has
+      six entries, in which case the row count is equal to the value
+      of the <code><a href=#row>Row</a></code> object's sixth entry.</p>
+
+     </li>
+
+    </ol></li>
+
+   <li>
+
+    <p>For each <code><a href=#row>Row</a></code> object in the <var title="">rows</var> argument, in order, <a href=#apply-a-row-object title="apply a Row
+    object">apply the <code>Row</code> object</a>.</p>
+
+   </li>
+
+   <li>
+
+    <p>Invoke the <a href=#datagrid-update-display-algorithm><code>datagrid</code> update display
+    algorithm</a>.</p>
+
+   </li>
+
+  </ol><hr><p>When an algorithm requires the user agent to <dfn id=type-check-a-rowlist-object>type-check a
+  <code>RowList</code> object</dfn> (an array), each entry in the
+  object must be checked against the following requirements. If any
+  are false, then the type-check fails, otherwise it passes.</p>
+
+  <ul><li><p>The entry is a <code><a href=#row>Row</a></code> object (an
+   array).</li>
+
+   <li><p>The first value in the <code><a href=#row>Row</a></code> is a
+   <code><a href=#rowid>RowID</a></code> object (also an array), whose length is at least
+   1, and whose values are all integers greater than or equal to
+   zero.</li>
+
+   <li><p>The numbers in the <code><a href=#rowid>RowID</a></code> object do not exactly
+   match any of the other entries in the <code><a href=#rowlist>RowList</a></code> object
+   (i.e. no two <code><a href=#row>Row</a></code> objects have the same
+   identifier).</li>
+
+   <li><p>The second value in the <code><a href=#row>Row</a></code> is an integer that
+   is either −1, zero, or a positive integer.</li>
+
+   <li><p>The third value in the <code><a href=#row>Row</a></code> is an integer that
+   is either −1, zero, or a positive integer.</li>
+
+   <li><p>The fourth value in the <code><a href=#row>Row</a></code> is a
+   <code><a href=#celllist>CellList</a></code> object (yet another array).</li>
+
+   <li><p>Each entry in the <a href=#celllist>CellList</a> object is a
+   <code><a href=#cell>Cell</a></code> object (again, an array).</li>
+
+   <li><p>Each <code><a href=#cell>Cell</a></code> object in the <a href=#celllist>CellList</a>
+   object has as its first value a <code><a href=#column>Column</a></code> object (a
+   string), and its value is the identifier of one of the columns in
+   the <a href=#column-list>column list</a>.</li>
+
+   <li>
+
+    <p>Each <code><a href=#cell>Cell</a></code> object in the <a href=#celllist>CellList</a>
+    object has as its second and subsequent entries values that match
+    the following requirements, as determined by the type of the
+    column identified by the first entry:</p>
+
+    <dl><dt>If the column's type is <code title=datagrid-type-text><a href=#datagrid-type-text>text</a></code></dt>
+     <dd>
+
+      <p>The second entry's value is a string, and either there are
+      only two entries, or there are three, and the third entry is
+      an <code><a href=#the-img-element>img</a></code> element.</p>
+
+      <p>If there is an <code><a href=#the-img-element>img</a></code> element specified, its <code title=dom-img-complete><a href=#dom-img-complete>complete</a></code> attribute is true.</p>
+
+     </dd>
+
+     <dt>If the column's type is <code title=datagrid-type-editable><a href=#datagrid-type-editable>editable</a></code></dt>
+     <dd>
+
+      <p>The second entry's value is a string, and either there are
+      only two entries, or the third entry is a
+      <code><a href=#the-datalist-element>datalist</a></code> element, and either there are only three
+      entries, or there are four, and the fourth entry is an
+      <code><a href=#the-img-element>img</a></code> element.</p>
+
+      <p>If there is an <code><a href=#the-img-element>img</a></code> element specified, its <code title=dom-img-complete><a href=#dom-img-complete>complete</a></code> attribute is true.</p>
+
+     </dd>
+
+     <dt>If the column's type is <code title=datagrid-type-checkable><a href=#datagrid-type-checkable>checkable</a></code></dt>
+     <dd>
+
+      <p>The second entry's value is a string, the third entry is a
+      boolean, and either there are only three entries, or the
+      fourth entry is also a boolean, and either there are only four
+      entries, or there are five, and the fifth entry is an
+      <code><a href=#the-img-element>img</a></code> element.</p>
+
+      <p>If there is an <code><a href=#the-img-element>img</a></code> element specified, its <code title=dom-img-complete><a href=#dom-img-complete>complete</a></code> attribute is true.</p>
+
+     </dd>
+
+     <dt>If the column's type is <code title=datagrid-type-list><a href=#datagrid-type-list>list</a></code></dt>
+     <dd>
+
+      <p>The second entry's value is a string, the third entry is a
+      <code><a href=#the-select-element>select</a></code> element, and either there are only three
+      entries, or there are four, and the fourth entry is an
+      <code><a href=#the-img-element>img</a></code> element.</p>
+
+      <p>If there is an <code><a href=#the-img-element>img</a></code> element specified, its <code title=dom-img-complete><a href=#dom-img-complete>complete</a></code> attribute is true.</p>
+
+     </dd>
+
+     <dt>If the column's type is <code title=datagrid-type-progress><a href=#datagrid-type-progress>progress</a></code></dt>
+     <dd>
+
+      <p>There are only two entries, the second entry's value is a
+      number, and the number's value is between 0.0 and 1.0
+      inclusive.</p>
+
+     </dd>
+
+     <dt>If the column's type is <code title=datagrid-type-meter><a href=#datagrid-type-meter>meter</a></code></dt>
+     <dd>
+
+      <p>There are at least two, but possibly up to seven, entries,
+      all entries but the first one are numbers, and the following
+      relationships hold:</p>
+
+      <ul class=brief><li>The second entry is less than the third, or less than 1.0
+       if the third is absent.</li>
+
+       <li>The second entry is greater than the fourth, or greater
+       than 0.0 if the fourth is absent.</li>
+
+       <li>If there are at least three entries, the third entry is
+       greater than the fourth, or greater than zero if the fourth
+       is absent.</li>
+
+       <li>If there are at least five entries, the fifth is not
+       greater than the third and not less than the fourth.</li>
+
+       <li>If there are at least six entries, the sixth is not
+       greater than the third and not less than the fifth.</li>
+
+       <li>If there are at least seven entries, the fifth is not
+       greater than the third and not less than the fourth.</li>
+
+      </ul></dd>
+
+     <dt>If the column's type is <code title=datagrid-type-custom><a href=#datagrid-type-custom>custom</a></code></dt>
+     <dd>
+
+      <p>There are four entries, the second and third are numbers
+      that are integers greater than zero, and the fourth is a
+      <code>Rendering2DContextCallback</code> object (a
+      function).</p>
+
+     </dd>
+
+    </dl></li>
+
+   <li><p>Either there are only four values in the <code><a href=#row>Row</a></code>,
+   or the fifth value in the <code><a href=#row>Row</a></code> is a boolean.</li>
+
+   <li><p>Either there are only four or five values in the
+   <code><a href=#row>Row</a></code>, or there are six, and the sixth value in the
+   <code><a href=#row>Row</a></code> an integer that is greater than or equal to
+   zero.</li>
+
+  </ul><p>Where the above requirements say that a value is to be a string,
+  the user agent must apply the ToString() conversion operator to the
+  value, assume that the value was indeed a string, and use the result
+  in the rest of the algorithm as if it had that had been the value
+  passed to the method. <a href=#refsECMA262>[ECMA262]</a></p>
+
+  <p>Where the above requirements say that a value is to be a number,
+  the user agent must first apply the ToNumber() conversion operator
+  to the value, and then verify that the result is neither the
+  not-a-number NaN value nor an infinite value. If this result is
+  indeed acceptable (i.e. finite), the user agent must use the result
+  in the rest of the algorithm as if it had that had been the value
+  passed to the method. <a href=#refsECMA262>[ECMA262]</a></p>
+
+  <p>Where the above requirements say that a value is to be an
+  integer, the user agent must first apply the ToNumber() conversion
+  operator to the value, and then verify that the result is a finite
+  integer. If so, the user agent must use the result in the rest of
+  the algorithm as if it had that had been the value passed to the
+  method. <a href=#refsECMA262>[ECMA262]</a></p>
+
+  <p>Where the above requirements say that a value is to be a boolean,
+  the user agent must apply the ToBoolean() conversion operator to the
+  value, assume that the value was indeed a boolean, and use the
+  result in the rest of the algorithm as if it had that had been the
+  value passed to the method. <a href=#refsECMA262>[ECMA262]</a></p>
+
+  <hr><p>When an algorithm requires the user agent to <dfn id=audit-the-datagrid>audit the
+  <code>datagrid</code></dfn>, the <code><a href=#datagrid>datagrid</a></code> must be
+  checked against the following requirements. If any are false, then
+  the audit fails, otherwise it passes.</p>
+
+  <ul><li>There is no row whose natural order position is greater than or
+   equal to the child count of its parent row in the <a href=#natural-order-sparse-data-tree>natural
+   order sparse data tree</a>.</li>
+
+   <li>There is no row whose display order position is greater than or
+   equal to the child count of its parent row in the <a href=#display-order-sparse-data-tree>display
+   order sparse data tree</a>.</li>
+
+   <li>There is no row such that the sum of that row's child count and
+   the row counts all the open rows that are direct children of that
+   row in the <a href=#natural-order-sparse-data-tree>natural order sparse data tree</a> is less than
+   that row's row count.</li>
+
+   <li>Of the rows whose child count is equal to the number of rows
+   that are direct children of that row in the <a href=#natural-order-sparse-data-tree>natural order
+   sparse data tree</a>, there is none such that the sum of that
+   row's child count and the row counts of all the open rows that are
+   direct children of that row in the <a href=#natural-order-sparse-data-tree>natural order sparse data
+   tree</a> is greater than that row's row count.</li>
+
+  </ul><p>For the purposes of this audit, the <code><a href=#datagrid>datagrid</a></code> must be
+  treated as the parent row of all the rows that are direct children
+  of the <code><a href=#datagrid>datagrid</a></code> in the <a href=#natural-order-sparse-data-tree>natural order sparse data
+  tree</a> and the <a href=#display-order-sparse-data-tree>display order sparse data tree</a>. The
+  child count of this implied row is the <a href=#datagrid-child-count><code>datagrid</code>
+  child count</a>, and the row count of this implied row is the
+  <a href=#datagrid-row-count><code>datagrid</code> row count</a>.</p>
+
+  <hr><p>When an algorithm requires the user agent to <dfn id=partially-sort-a-rowlist-object>partially sort
+  a <code>RowList</code> object</dfn> (an array), the entries in the
+  object must be resorted such that <code><a href=#row>Row</a></code> objects are
+  listed after any of their ancestors and after any of their earlier
+  siblings. In other words, for any two <code><a href=#row>Row</a></code> objects <var title="">a</var> and <var title="">b</var> in the
+  <code><a href=#rowlist>RowList</a></code>, where <var title="">a</var> is before <var title="">b</var> after the sort, the following conditions must
+  hold:</p>
+
+  <ul><li><p>If their <code><a href=#rowid>RowID</a></code> objects are the same length and
+   have values that are equal except for the last value, then the last
+   value of <var title="">a</var>'s <code><a href=#rowid>RowID</a></code>'s last value
+   must be less than <var title="">b</var>'s <code><a href=#rowid>RowID</a></code>'s last
+   value (i.e. earlier siblings must come before their later
+   siblings).</li>
+
+   <li><p>If their <code><a href=#rowid>RowID</a></code> objects are not the same length,
+   but the values in the shorter of the two are the same as the first
+   few values in the longer one, then <var title="">a</var>'s
+   <code><a href=#rowid>RowID</a></code> must be the shorter one (i.e. ancestors must
+   come before their descendants).</li>
+
+  </ul><hr><p>The <dfn id=dom-datagrid-deleterows title=dom-datagrid-deleteRows><code>deleteRows(<var title="">rows</var>)</code></dfn> method must run the following
+  steps:</p>
+
+  <ol><li>
+
+    <p>If any of the entries in <var title="">rows</var> are not
+    <code><a href=#rowid>RowID</a></code> objects consisting of one or more entries whose
+    values are all integers that are greater than or equal to zero,
+    then throw a <code>TypeError</code> exception and abort these
+    steps.</p>
+
+    <p>To check if a value is an integer, the user agent must first
+    apply the ToNumber() conversion operator to the value, and then
+    verify that the result is a finite integer. If so, the user agent
+    must use the result in the rest of the algorithm as if it had that
+    had been the value passed to the method. <a href=#refsECMA262>[ECMA262]</a></p>
+
+   </li>
+
+   <li>
+
+    <p>If any of the <code><a href=#rowid>RowID</a></code> objects in the <var title="">rows</var> argument identify a row that isn't present in
+    the <a href=#natural-order-sparse-data-tree>natural order sparse data tree</a>, then throw a
+    <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception and abort these
+    steps.</p>
+
+   </li>
+
+   <li>
+
+    <p>If any row is listed twice in the <var title="">rows</var>
+    argument, then throw a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception
+    and abort these steps.</p>
+
+   </li>
+
+   <li>
+
+    <p>Sort the <var title="">rows</var> argument such that the
+    entries are given in the same order as the rows they identify
+    would be visited in a pre-order, depth first traversal of the
+    <a href=#natural-order-sparse-data-tree>natural order sparse data tree</a>.</p>
+
+   </li>
+
+   <li>
+
+    <p>For each row identified by entries in <var title="">rows</var>,
+    <em>in reverse order</em>, run the following steps:</p>
+
+    <ol><li>
+
+      <p>Decrement the child count of the row's parent row, if that
+      child count is greater than zero. If the row has no parent,
+      decrement the <a href=#datagrid-child-count><code>datagrid</code> child
+      count</a>.</p>
+
+      <p>If the row has a parent row, and its child count is now zero,
+      then close that row.</p>
+
+     </li>
+
+     <li>
+
+      <p>Let <var title="">delta</var> be one more than the row's row
+      count if the row is open and its row count is greater than zero;
+      otherwise, let <var title="">delta</var> be one.</p>
+
+     </li>
+
+     <li>
+
+      <p>Let <var title="">ancestor</var> be the row.</p>
+
+     </li>
+
+     <li>
+
+      <p><i>Row count loop:</i> Let <var title="">ancestor</var> be
+      <var title="">ancestor</var>'s parent row, if any, or null if it
+      has none.</p>
+
+     </li>
+
+     <li>
+
+      <p>If <var title="">ancestor</var> is null, then decrement the
+      <a href=#datagrid-row-count><code>datagrid</code> row count</a> by <var title="">delta</var>. Otherwise, if <var title="">ancestor</var>
+      is open, then decrement its row count by <var title="">delta</var>.</p>
+
+     </li>
+
+     <li>
+
+      <p>If <var title="">ancestor</var> is not null, then jump back
+      to the step labeled <i>row count loop</i> above.</p>
+
+     </li>
+
+     <li>
+
+      <p>Let <var title="">parent</var> be the row's parent, or the
+      <code><a href=#datagrid>datagrid</a></code> if the row has no parent.</p>
+
+     </li>
+
+     <li>
+
+      <p>Decrement by one the natural order position of all rows whose
+      parent is <var title="">parent</var> and whose natural order
+      position is equal to or greater than the row's own natural order
+      position.</p>
+
+     </li>
+
+     <li>
+
+      <p>If the row is in the <a href=#display-order-sparse-data-tree>display order sparse data
+      tree</a>, then decrement by one the display order position of
+      all rows whose parent is <var title="">parent</var> and whose
+      display order position is equal to or greater than the row's own
+      display order position.</p>
+
+     </li>
+
+     <li>
+
+      <p>Clear the row and its descendants from the
+      <code><a href=#datagrid>Datagrid</a></code>.</p>
+
+     </li>
+
+    </ol></li>
+
+   <li>
+
+    <p>Invoke the <a href=#datagrid-update-display-algorithm><code>datagrid</code> update display
+    algorithm</a>.</p>
+
+   </li>
+
+  </ol><hr><p>The <dfn id=dom-datagrid-clearrows title=dom-datagrid-clearRows><code>clearRows()</code></dfn> method
+  must empty the <a href=#natural-order-sparse-data-tree>natural order sparse data tree</a>, reset
+  both the <a href=#datagrid-child-count><code>datagrid</code> child count</a> and the
+  <a href=#datagrid-row-count><code>datagrid</code> row count</a> to zero, and invoke the
+  <a href=#datagrid-update-display-algorithm><code>datagrid</code> update display algorithm</a>.</p>
+
+  <hr><p>The <dfn id=dom-datagrid-repaint title=dom-datagrid-repaint><code>repaint(<var title="">row</var>, <var title="">column</var>)</code></dfn> method
+  must cause the user agent to clear its cache for the cell specified
+  by the identifier <var title="">row</var> and the column <var title="">column</var>, if that column's type is <code title=datagrid-type-custom><a href=#datagrid-type-custom>custom</a></code>. If the given column has
+  not been declared, or its type is not <code title=datagrid-type-custom><a href=#datagrid-type-custom>custom</a></code>, then the user agent must
+  throw a <code><a href=#datagrid_model_err>DATAGRID_MODEL_ERR</a></code> exception. If the given row
+  is not known, then the method must do nothing. If the cell is indeed
+  cleared, the user agent must reinvoke the previously registered
+  <code><a href=#renderingcontext2dcallback>RenderingContext2DCallback</a></code> callback when it needs to
+  repaint that row.</p>
+
+  <hr><p>If a row has a child count that isn't zero, then the user agent
+  should offer to the user the option of opening and closing the
+  row.</p>
+
+  <p>When a row is opened, if the row's row count is greater than
+  zero, then the user agent must increase the
+  <a href=#datagrid-row-count><code>datagrid</code> row count</a> and the row counts of
+  any ancestor rows by the number of rows that the newly opened row
+  has in its row count<!-- we should also "update the <span>pending
+  <code>datagrid</code> rows list</span> and the <span>pending
+  <code>datagrid</code> cells list</span> accordingly" -->, then must
+  mark the row as open, then may fill in the <a href=#display-order-sparse-data-tree>display order
+  sparse data tree</a> with any information that the user agent has
+  cached about the display order positions of descendants of the newly
+  opened row, and then must invoke the <code title=dom-listener-rowOpened><a href=#dom-listener-rowopened>rowOpened()</a></code> method on the
+  current <code title=dom-datagrid-listener><a href=#dom-datagrid-listener>listener</a></code> with as
+  its first argument a <code><a href=#rowid>RowID</a></code> object identifying the row
+  that was opened and as its second argument the boolean false, and
+  then must invoke the <a href=#datagrid-update-display-algorithm><code>datagrid</code> update display
+  algorithm</a>.</p>
+
+  <p>On the other hand, when a row is opened and the row's row count
+  is −1, then the user agent must mark the row as opening, and
+  then must invoke the <code title=dom-listener-rowOpened><a href=#dom-listener-rowopened>rowOpened()</a></code> method on the
+  current <code title=dom-datagrid-listener><a href=#dom-datagrid-listener>listener</a></code> with as
+  its first argument a <code><a href=#rowid>RowID</a></code> object identifying the row
+  that was opened and as its second argument the boolean true.</p>
+
+  <p>When a row is closed, the user agent must decrease the
+  <a href=#datagrid-row-count><code>datagrid</code> row count</a> and the row counts of
+  any ancestor rows by the number of rows that the newly closed row
+  has in its row count, and then must invoke the <code title=dom-listener-rowOpened><a href=#dom-listener-rowopened>rowOpened()</a></code> method on the
+  current <code title=dom-datagrid-listener><a href=#dom-datagrid-listener>listener</a></code> with as
+  its first and only argument a <code><a href=#rowid>RowID</a></code> object identifying
+  the row that was opened.</p>
+
+
+
+  <h6 id=the-cells><span class=secno>4.11.2.2.4 </span>The cells</h6>
+
+  <p>Each row has one cell per column. Each cell has the same type as
+  its column. The <dfn id=allowed-datagrid-column-types>allowed <code>datagrid</code> column
+  types</dfn>, what they represent, and the requirements for when the
+  user interacts with them, are as follows:</p>
+
+  <dl><dt><dfn id=datagrid-type-text title=datagrid-type-text><code>text</code></dfn></dt>
    <dd>
 
-    <p>If the first element child of a cell's element is a
-    <code><a href=#the-select-element>select</a></code> element that has a no <code title=attr-select-multiple><a href=#attr-select-multiple>multiple</a></code> attribute and has at
-    least one <code><a href=#the-option-element>option</a></code> element descendant, then the cell
-    acts as a cyclable cell.</p>
+    <p>The cell represents some text and an optional image.</p>
 
-    <p>The "current" <code><a href=#the-option-element>option</a></code> element is the selected
-    <code><a href=#the-option-element>option</a></code> element, or the first <code><a href=#the-option-element>option</a></code>
-    element if none is selected.</p>
+   </dd>
 
-    <p>The <code title=dom-provider-getCellData><a href=#dom-provider-getcelldata>getCellData()</a></code>
-    method must return the <code><a href=#textcontent>textContent</a></code> of the current
-    <code><a href=#the-option-element>option</a></code> element (the <code title=attr-option-label><a href=#attr-option-label>label</a></code> attribute is <a href=#ignore title=ignore>ignored</a> in this context as the
-    <code><a href=#the-optgroup-element>optgroup</a></code>s are not displayed).</p>
+   <dt><dfn id=datagrid-type-editable title=datagrid-type-editable><code>editable</code></dfn></dt>
+   <dd>
 
-    <p>The <code title=dom-provider-getCellClasses><a href=#dom-provider-getcellclasses>getCellClasses()</a></code> method
-    must add the <code title=datagrid-cell-class-cyclable><a href=#datagrid-cell-class-cyclable>cyclable</a></code> class and
-    then all the classes of the current <code><a href=#the-option-element>option</a></code>
-    element.</p>
+    <p>The cells represents some editable text, an optional
+    <code><a href=#the-datalist-element>datalist</a></code> giving autocompletion hints, and an
+    optional image.</p>
 
-    <p>The <code title=dom-provider-cycleCell><a href=#dom-provider-cyclecell>cycleCell()</a></code>
-    method must change the selection of the <code><a href=#the-select-element>select</a></code>
-    element such that the next <code><a href=#the-option-element>option</a></code> element after the
-    current <code><a href=#the-option-element>option</a></code> element is the only one that is
-    selected (in <a href=#tree-order>tree order</a>). If the current <code><a href=#the-option-element>option</a></code>
-    element is the last <code><a href=#the-option-element>option</a></code> element descendant of the
-    <code><a href=#the-select-element>select</a></code>, then the first <code><a href=#the-option-element>option</a></code> element
-    descendant must be selected instead.</p>
+    <p>If there is a <code><a href=#the-datalist-element>datalist</a></code> element, the user agent
+    should offer the suggestions represented by that element to the
+    user. The user agent may use the suggestion's <a href=#concept-option-label title=concept-option-label>label</a> to identify the
+    suggestion. If the user selects a suggestion, then the editable
+    text must be set to the selected suggestion's <a href=#concept-option-value title=concept-option-value>value</a>, as if the user had
+    written that value himself.</p>
 
-    <p>The <code title=dom-provider-setCellCheckedState><a href=#dom-provider-setcellcheckedstate>setCellCheckedState()</a></code>
-    and <code title=dom-provider-editCell><a href=#dom-provider-editcell>editCell()</a></code> methods
-    must do nothing.</p>
+    <p>When the user edits the value, either directly or using the
+    <code><a href=#the-datalist-element>datalist</a></code>, the user agent must invoke the <code title=dom-listener-cellChanged><a href=#dom-listener-cellchanged>cellChanged()</a></code> method on
+    the current <code title=dom-datagrid-listener><a href=#dom-datagrid-listener>listener</a></code>
+    with as its first argument a <code><a href=#rowid>RowID</a></code> identifying the
+    cell's row, as its second argument the identifier of the cell's
+    column, as its third argument the new value, and as its fourth
+    argument the previous value.</p>
 
    </dd>
 
-   <dt>Progress bar cells</dt>
+   <dt><dfn id=datagrid-type-checkable title=datagrid-type-checkable><code>checkable</code></dfn></dt>
+   <dd>
 
+    <p>The cell represents some text, a check box that optionally has
+    its value obscured as indeterminate, and an optional image.</p>
+
+    <p>When the user checks or unchecks the check box, the user agent
+    must change the check box's state appropriately and stop obscuring
+    the check box as indeterminate (if it is obscuring it), and then
+    must invoke the <code title=dom-listener-cellChanged><a href=#dom-listener-cellchanged>cellChanged()</a></code> method on
+    the current <code title=dom-datagrid-listener><a href=#dom-datagrid-listener>listener</a></code>
+    with as its first argument a <code><a href=#rowid>RowID</a></code> identifying the
+    cell's row, as its second argument the identifier of the cell's
+    column, as its third argument true if the check box is now checked
+    and false otherwise, and as its fourth argument true if the check
+    box was previously checked and false otherwise.</p>
+
+   </dd>
+
+   <dt><dfn id=datagrid-type-list title=datagrid-type-list><code>list</code></dfn></dt>
    <dd>
 
-    <p>If the first element child of a cell's element is a
-    <code><a href=#the-progress-element>progress</a></code> element, then the cell acts as a progress
-    bar cell.</p>
+    <p>The cell represents some text giving the current value selected
+    from a dropdown list of options, a <code><a href=#the-select-element>select</a></code> element
+    giving the list of options, and an optional image.</p>
 
-    <p>The <code title=dom-provider-getCellData><a href=#dom-provider-getcelldata>getCellData()</a></code>
-    method must return the value returned by the <code><a href=#the-progress-element>progress</a></code>
-    element's <code title=dom-progress-position><a href=#dom-progress-position>position</a></code> DOM
-    attribute.</p>
+    <p>The user agent should allow the user to change the value of the
+    cell from its current value to one of the <a href=#concept-option-value title=concept-option-value>values</a> given by
+    <code><a href=#the-option-element>option</a></code> elements in the <a href=#concept-select-option-list title=concept-select-option-list>list of options</a> (if
+    any). The user agent may use the <code><a href=#the-option-element>option</a></code> elements'
+    <a href=#concept-option-label title=concept-option-label>labels</a> to annotate each
+    option.</p>
 
-    <p>The <code title=dom-provider-getCellClasses><a href=#dom-provider-getcellclasses>getCellClasses()</a></code> method
-    must add the <code title=datagrid-cell-class-progress><a href=#datagrid-cell-class-progress>progress</a></code> class.</p>
+    <p>When the user selects a new value from the <code><a href=#the-select-element>select</a></code>
+    element's <a href=#concept-select-option-list title=concept-select-option-list>list of
+    options</a>, the user agent must invoke the <code title=dom-listener-cellChanged><a href=#dom-listener-cellchanged>cellChanged()</a></code> method on
+    the current <code title=dom-datagrid-listener><a href=#dom-datagrid-listener>listener</a></code>
+    with as its first argument a <code><a href=#rowid>RowID</a></code> identifying the
+    cell's row, as its second argument the identifier of the cell's
+    column, as its third argument the new value, and as its fourth
+    argument the previous value.</p>
 
-    <p>The <code title=dom-provider-setCellCheckedState><a href=#dom-provider-setcellcheckedstate>setCellCheckedState()</a></code>,
-    <code title=dom-provider-cycleCell><a href=#dom-provider-cyclecell>cycleCell()</a></code>, and
-    <code title=dom-provider-editCell><a href=#dom-provider-editcell>editCell()</a></code> methods must
-    do nothing.</p>
+   </dd>
 
+   <dt><dfn id=datagrid-type-progress title=datagrid-type-progress><code>progress</code></dfn></dt>
+   <dd>
+
+    <p>The cell represents a (determinate) progress bar whose value is
+    between 0.0, indicating no progress, and 1.0, indicating the task
+    is complete.</p>
+
    </dd>
 
-   <dt>Checkbox cells</dt>
-
+   <dt><dfn id=datagrid-type-meter title=datagrid-type-meter><code>meter</code></dfn></dt>
    <dd>
 
-    <p>If the first element child of a cell's element is an
-    <code><a href=#the-input-element>input</a></code> element that has a <code title=attr-input-type><a href=#attr-input-type>type</a></code> attribute with the value <code title="">checkbox</code>, then the cell acts as a check box
-    cell.</p>
+    <p>The cell represents a gauge, described by one to six
+    numbers.</p>
 
-    <p>The <code title=dom-provider-getCellData><a href=#dom-provider-getcelldata>getCellData()</a></code>
-    method must return the <code><a href=#textcontent>textContent</a></code> of the cell
-    element.</p>
+    <p>The gauge's actual value is given by the first number.</p>
 
-    <p>The <code title=dom-provider-getCellClasses><a href=#dom-provider-getcellclasses>getCellClasses()</a></code> method
-    must add the <code title=datagrid-cell-class-checked><a href=#datagrid-cell-class-checked>checked</a></code> class if the
-    <code><a href=#the-input-element>input</a></code> element's <a href=#concept-fe-checked title=concept-fe-checked>checkedness</a> is true, and the
-    <code title=datagrid-cell-class-unchecked><a href=#datagrid-cell-class-unchecked>unchecked</a></code> class
-    otherwise.</p>
+    <p>If there is a second number, then that number is the maximum
+    value. Otherwise, the maximum value is 1.0.</p>
 
-    <p>The <code title=dom-provider-setCellCheckedState><a href=#dom-provider-setcellcheckedstate>setCellCheckedState()</a></code>
-    method must set the <code><a href=#the-input-element>input</a></code> element's checkbox <a href=#concept-fe-checked title=concept-fe-checked>checkedness</a> to true if the
-    method's third argument is 1, and to false otherwise.</p>
+    <p>If there is a third number, then that number is the minimum
+    value. Otherwise, the minimum value is 1.0.</p>
 
-    <p>The <code title=dom-provider-cycleCell><a href=#dom-provider-cyclecell>cycleCell()</a></code> and
-    <code title=dom-provider-editCell><a href=#dom-provider-editcell>editCell()</a></code> methods must
-    do nothing.</p>
+    <p>If there is a fourth number, then that number is the low
+    boundary. Otherwise, the low boundary is the minimum value.</p>
 
+    <p>If there is a fifth number, then that number is the high
+    boundary. Otherwise, the high boundary is the maximum value.</p>
+
+    <p>If there is a sixth number, then the optimal point is the sixth
+    number. Otherwise, the optimum point is the midpoint between the
+    minimum value and the maximum value.</p>
+
+    <!-- next two paragraphs copied from <meter>: -->
+
+    <p>If the optimum point is equal to the low boundary or the high
+    boundary, or anywhere in between them, then the region between the
+    low and high boundaries of the gauge must be treated as the
+    optimum region, and the low and high parts, if any, must be
+    treated as suboptimal. Otherwise, if the optimum point is less
+    than the low boundary, then the region between the minimum value
+    and the low boundary must be treated as the optimum region, the
+    region between the low boundary and the high boundary must be
+    treated as a suboptimal region, and the region between the high
+    boundary and the maximum value must be treated as an even less
+    good region. Finally, if the optimum point is higher than the high
+    boundary, then the situation is reversed; the region between the
+    high boundary and the maximum value must be treated as the optimum
+    region, the region between the high boundary and the low boundary
+    must be treated as a suboptimal region, and the remaining region
+    between the low boundary and the minimum value must be treated as
+    an even less good region.</p>
+
+    <p>User agents should indicate the relative position of the actual
+    actual to the minimum and maximum values, and the relationship
+    between the actual value and the three regions of the gauge.</p>
+
    </dd>
 
-   <dt>Editable cells</dt>
-
+   <dt><dfn id=datagrid-type-custom title=datagrid-type-custom><code>custom</code></dfn></dt>
    <dd>
 
-    <p>If the first element child of a cell's element is an
-    <code><a href=#the-input-element>input</a></code> element that has a <code title=attr-input-type><a href=#attr-input-type>type</a></code> attribute with the value <code title="">text</code> or that has no <code title=attr-input-type><a href=#attr-input-type>type</a></code> attribute at all, then the
-    cell acts as an editable cell.</p>
+    <p>The cell represents a dynamically generated graphical image.</p>
 
-    <p>The <code title=dom-provider-getCellData><a href=#dom-provider-getcelldata>getCellData()</a></code>
-    method must return the <code title=dom-input-value><a href=#dom-input-value>value</a></code>
-    of the <code><a href=#the-input-element>input</a></code> element.</p>
+    <p>The cell will have minimum dimensions (specified in CSS
+    pixels), and a callback (in the form of a
+    <code><a href=#renderingcontext2dcallback>RenderingContext2DCallback</a></code> object) to get a rendering
+    for the cell.</p>
 
-    <p>The <code title=dom-provider-getCellClasses><a href=#dom-provider-getcellclasses>getCellClasses()</a></code> method
-    must add the <code title=datagrid-cell-class-editable><a href=#datagrid-cell-class-editable>editable</a></code> class.</p>
+    <p>The user agent should not allow the cell to be rendered with
+    dimensions less than the given minimum width and height.</p>
 
-    <p>The <code title=dom-provider-editCell><a href=#dom-provider-editcell>editCell()</a></code>
-    method must set the <code><a href=#the-input-element>input</a></code> element's <code title=dom-input-value><a href=#dom-input-value>value</a></code> DOM attribute to the value of
-    the third argument to the method.</p>
+    <p>When the user agent needs to render the cell, the user agent
+    must <a href=#queue-a-task>queue a task</a> to invoke the
+    <a href=#renderingcontext2dcallback>RenderingContext2DCallback</a> callback, passing it a
+    newly created <code><a href=#canvasrenderingcontext2d>CanvasRenderingContext2D</a></code> object whose
+    <code title=dom-context-2d-canvas><a href=#dom-context-2d-canvas>canvas</a></code> DOM attribute is
+    null as the first argument, the actual cell width in CSS pixels as
+    the second argument, and the actual cell height in CSS pixels as
+    the third argument.</p>
 
-    <p>The <code title=dom-provider-setCellCheckedState><a href=#dom-provider-setcellcheckedstate>setCellCheckedState()</a></code>
-    and <code title=dom-provider-cycleCell><a href=#dom-provider-cyclecell>cycleCell()</a></code>
-    methods must do nothing.</p>
+    <p>If the user agent is able to render graphics, then it must
+    render the graphics commands that the callback executed on the
+    provided <code><a href=#canvasrenderingcontext2d>CanvasRenderingContext2D</a></code> object onto the
+    cell once the callback returns. The image must be clipped to the
+    dimensions of the cell. The coordinate space of the cell must be
+    aligned with that used by the 2D context such that the top left
+    corner of the cell is the 0,0 origin, with the coordinate space
+    increasing its <var title="">x</var> dimension towards the right
+    of the cell and its <var title="">y</var> axis towards the bottom
+    of the cell, and with the image not scaled (so that one CSS pixel
+    on the final rendering matches one CSS pixel in the coordinate
+    space usd by the 2D context).</p>
 
+    <p>The user agent must then decouple the
+    <code><a href=#canvasrenderingcontext2d>CanvasRenderingContext2D</a></code> object and any objects that
+    it created (such as <code><a href=#canvaspattern>CanvasPattern</a></code> objects or
+    <code><a href=#imagedata>ImageData</a></code> objects) from any real drawing surface.</p>
+
+    <p>If the user agent is unable to render graphics, then it must
+    render the text string returned by the callback instead.</p>
+
    </dd>
 
-  </dl><!-- XXX Calculated cells, like in spreadsheets? --><h5 id=populating-the-datagrid-element><span class=secno>4.11.2.5 </span>Populating the <code><a href=#datagrid>datagrid</a></code> element</h5>
+  </dl><hr><p>When an algorithm requires the user agent to <dfn id=apply-a-row-object>apply a
+  <code>Row</code> object</dfn>, the user agent must run the following
+  steps:</p>
 
-  <p>A <code><a href=#datagrid>datagrid</a></code> must be disabled until its end tag has
-  been parsed<!-- XXX do we define that? what if the end tag is never
-  seen, but the element is popped off the stack?--> (in the case of a
-  <code><a href=#datagrid>datagrid</a></code> element in the original document markup) or
-  until it has been <a href=#insert-an-element-into-a-document title="insert an element into a
-  document">inserted into the document</a> (in the case of a
-  dynamically created element). After that point, the element must
-  fire a single <code title=event-load><a href=#event-load>load</a></code> event at itself,
-  which doesn't bubble and cannot be canceled.</p>
+  <ol><li>
 
-  <p class=XXX>The end-tag parsing thing should be moved to
-  the parsing section.</p>
+    <p>If the value of the <code><a href=#row>Row</a></code> object's second entry is
+    not −1, then run these substeps:</p>
 
-  <p>The <code><a href=#datagrid>datagrid</a></code> must then populate itself using the
-  data provided by the data provider assigned to the <code title=dom-datagrid-data><a href=#dom-datagrid-data>data</a></code> DOM attribute. After the view
-  is populated (using the methods described below), the
-  <code><a href=#datagrid>datagrid</a></code> must invoke the <code title=dom-provider-initialize><a href=#dom-provider-initialize>initialize()</a></code> method on the
-  data provider specified by the <code title=dom-datagrid-data><a href=#dom-datagrid-data>data</a></code> attribute, passing itself (the
-  <code><a href=#htmldatagridelement>HTMLDataGridElement</a></code> object) as the only argument.</p>
+    <ol><li><p>If there is a row with the same parent as the row
+     specified by the <code><a href=#row>Row</a></code> object's <code><a href=#rowid>RowID</a></code>
+     object, whose display order position is currently the same as the
+     value of the <code><a href=#row>Row</a></code> object's second entry, then remove
+     that row from the <a href=#display-order-sparse-data-tree>display order sparse data
+     tree</a>.</li>
 
-  <p>When the <code title=dom-datagrid-data><a href=#dom-datagrid-data>data</a></code> attribute is
-  null, the <code><a href=#datagrid>datagrid</a></code> must use the default data provider
-  described in the previous section.</p>
+     <li><p>Set the display order position of the row specified by the
+     <code><a href=#row>Row</a></code> object's <code><a href=#rowid>RowID</a></code> to the value of the
+     <code><a href=#row>Row</a></code> object's second entry, updating its position in
+     the <a href=#display-order-sparse-data-tree>display order sparse data tree</a>
+     accordingly.</li>
 
-  <p>To obtain data from the data provider, the element must invoke
-  methods on the data provider object in the following ways:</p>
+     <li><p>If the row is in the the <a href=#pending-datagrid-rows-list>pending
+     <code>datagrid</code> rows list</a>, remove it.</li>
 
-  <dl><dt>To determine the total number of columns</dt>
+    </ol></li>
 
-   <dd>Invoke the <code title=dom-provider-getColumnCount><a href=#dom-provider-getcolumncount>getColumnCount()</a></code> 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.</dd>
+   <li>
 
-   <dt>To get the captions to use for the columns</dt>
+    <p>If the fourth entry in the <code><a href=#row>Row</a></code> object (a
+    <code><a href=#celllist>CellList</a></code> object, an array) is not empty, then for
+    each <code><a href=#cell>Cell</a></code> object in that array update the cell that
+    corresponds to the column identified by the value of the first
+    entry of the <code><a href=#cell>Cell</a></code> object, by using the appropriate
+    set of steps given below as determined by the type of the
+    column. Then, if the cell is in the the <a href=#pending-datagrid-cells-list>pending
+    <code>datagrid</code> cells list</a>, remove it.</p>
 
-   <dd>Invoke the <code title=dom-provider-getCaptionText><a href=#dom-provider-getcaptiontext>getCaptionText()</a></code> method
-   with the index of the column in question. The index <var title="">i</var> must be in the range 0 ≤ <var title="">i</var>
-   < <var title="">N</var>, where <var title="">N</var> 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.</dd>
+    <dl><dt>If the column's type is <code title=datagrid-type-text><a href=#datagrid-type-text>text</a></code></dt>
+     <dd>
 
-   <dt>To establish what classes apply to a column</dt>
+      <p>Update the cell's text to the value given in the
+      <code><a href=#cell>Cell</a></code> object's second entry.</p>
 
-   <dd>Invoke the <code title=dom-provider-getCaptionClasses><a href=#dom-provider-getcaptionclasses>getCaptionClasses()</a></code>
-   method with the index of the column in question, and an object
-   implementing the <code><a href=#domtokenlist-0>DOMTokenList</a></code> interface, associated
-   with an anonymous empty string. The index <var title="">i</var>
-   must be in the range 0 ≤ <var title="">i</var> < <var title="">N</var>, where <var title="">N</var> is the total number
-   of columns. The tokens contained in the string underlying
-   <code><a href=#domtokenlist-0>DOMTokenList</a></code> 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.</dd>
+      <p>If the <code><a href=#cell>Cell</a></code> object has three entries, then copy
+      the image data from the <code><a href=#the-img-element>img</a></code> element given in the
+      third entry, and let the cell's image be given by that image
+      data. Otherwise, update the cell to have no image.</p>
 
-   <dt>To establish whether a column should be initially included in
-   the visible columns</dt>
+     </dd>
 
-   <dd>Check whether the <code title=datagrid-column-class-initially-hidden><a href=#datagrid-column-class-initially-hidden>initially-hidden</a></code>
-   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.</dd>
+     <dt>If the column's type is <code title=datagrid-type-editable><a href=#datagrid-type-editable>editable</a></code></dt>
+     <dd>
 
-   <dt id=columnType2>To establish whether the data can be sorted
-   relative to a particular column</dt>
+      <p>Update the cell's text to the value given in the
+      <code><a href=#cell>Cell</a></code> object's second entry.</p>
 
-   <dd>Check whether the <code title=datagrid-column-class-sortable><a href=#datagrid-column-class-sortable>sortable</a></code> 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.</dd>
+      <p>If the <code><a href=#cell>Cell</a></code> object has three entries, then let
+      the <code><a href=#the-datalist-element>datalist</a></code> element given in the third entry be
+      the <code><a href=#the-datalist-element>datalist</a></code> element giving autocompletion
+      hints. Otherwise, update the cell to have no
+      <code><a href=#the-datalist-element>datalist</a></code> element.</p>
 
-   <dt>To establish if a column is a sorted column</dt>
+      <p>If the <code><a href=#cell>Cell</a></code> object has four entries, then copy
+      the image data from the <code><a href=#the-img-element>img</a></code> element given in the
+      fourth entry, and let the cell's image be given by that image
+      data. Otherwise, update the cell to have no image.</p>
 
-   <dd>If the user agent can handle multiple columns being marked as
-   sorted simultaneously: Check whether the <code title=datagrid-column-class-sorted><a href=#datagrid-column-class-sorted>sorted</a></code> class applies to
-   the column. If it does, then that column is the sorted column,
-   otherwise it is not.</dd>
+     </dd>
 
-   <dd>If the user agent can only handle one column being marked as
-   sorted at a time: Check each column in turn, starting with the
-   first one, to see whether the <code title=datagrid-column-class-sorted><a href=#datagrid-column-class-sorted>sorted</a></code> 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.</dd>
+     <dt>If the column's type is <code title=datagrid-type-checkable><a href=#datagrid-type-checkable>checkable</a></code></dt>
+     <dd>
 
-   <dt>To establish the sort direction of a sorted column</dt>
+      <p>Update the cell's text to the value given in the
+      <code><a href=#cell>Cell</a></code> object's second entry.</p>
 
-   <dd>Check whether the <code title=datagrid-column-class-reversed><a href=#datagrid-column-class-reversed>reversed</a></code> 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).</dd>
+      <p>Update the cell's checked state to match the value of the
+      third entry: checked if true, unchecked otherwise.</p>
 
-   <dt>To determine the total number of rows</dt>
+      <p>If the <code><a href=#cell>Cell</a></code> object has four entries and the
+      fourth entry is true, then update the cell to be obscured as
+      indeterminate. Otherwise, the cell's state is not obscured.</p>
 
-   <dd>Determine the number of rows for the root of the data grid, and
-   determine the number of child rows for each open row. The total
-   number of rows is the sum of all these numbers.</dd>
+      <p>If the <code><a href=#cell>Cell</a></code> object has five entries, then copy
+      the image data from the <code><a href=#the-img-element>img</a></code> element given in the
+      fifth entry, and let the cell's image be given by that image
+      data. Otherwise, update the cell to have no image.</p>
 
-   <dt>To determine the number of rows for the root of the data grid</dt>
+     </dd>
 
-   <dd>Invoke the <code title=dom-provider-getRowCount><a href=#dom-provider-getrowcount>getRowCount()</a></code> method with a
-   <code><a href=#rowspecification>RowSpecification</a></code> 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.</dd>
+     <dt>If the column's type is <code title=datagrid-type-list><a href=#datagrid-type-list>list</a></code></dt>
+     <dd>
 
-   <dt>To determine the number of child rows for a row</dt>
+      <p>Update the cell's text to the value given in the
+      <code><a href=#cell>Cell</a></code> object's second entry, and the
+      <code><a href=#the-select-element>select</a></code> element to be the one given in the
+      <code><a href=#cell>Cell</a></code> object's third entry</p>
 
-   <dd>Invoke the <code title=dom-provider-getRowCount><a href=#dom-provider-getrowcount>getRowCount()</a></code> method with a
-   <code><a href=#rowspecification>RowSpecification</a></code> 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.</dd>
+      <p>If the <code><a href=#cell>Cell</a></code> object has four entries, then copy
+      the image data from the <code><a href=#the-img-element>img</a></code> element given in the
+      fourth entry, and let the cell's image be given by that image
+      data. Otherwise, update the cell to have no image.</p>
 
-   <dt>To determine what order to render rows in</dt>
+     </dd>
 
-   <dd>
+     <dt>If the column's type is <code title=datagrid-type-progress><a href=#datagrid-type-progress>progress</a></code></dt>
+     <dd>
 
-    <p>Invoke the <code title=dom-provider-getChildAtPosition><a href=#dom-provider-getchildatposition>getChildAtPosition()</a></code>
-    method with a <code><a href=#rowspecification>RowSpecification</a></code> 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.</p>
+      <p>Update the cell to be a progress bar whose progress, on the
+      scale of 0.0 (no progress) to 1.0 (task complete) is given by
+      the value in the <code><a href=#cell>Cell</a></code> object's second entry.</p>
 
-    <div class=example>
+     </dd>
 
-     <p>If the rows are:</p>
+     <dt>If the column's type is <code title=datagrid-type-meter><a href=#datagrid-type-meter>meter</a></code></dt>
+     <dd>
 
-     <ol><li> Row "0"
-       <ol><li> Row "0,0"
-        <li> Row "0,1"
-       </ol></li>
-      <li> Row "1"
-       <ol><li> Row "1,0"
-        <li> Row "1,1"
-       </ol></li>
-     </ol><p>...and the <code title=dom-provider-getChildAtPosition><a href=#dom-provider-getchildatposition>getChildAtPosition()</a></code>
-    method is implemented as follows:</p>
+      <p>Update the cell to be a gauge configured with the numbers
+      given by the second and subsequent entries of the
+      <code><a href=#cell>Cell</a></code> object.</p>
 
-    <pre>function getChildAtPosition(parent, child) {
-  // always return the reverse order
-  return getRowCount(parent)-child-1;
-}</pre>
+     </dd>
 
-     <p>...then the rendering would actually be:</p>
+     <dt>If the column's type is <code title=datagrid-type-custom><a href=#datagrid-type-custom>custom</a></code></dt>
+     <dd>
 
-     <ol><li> Row "1"
-       <ol><li> Row "1,1"
-        <li> Row "1,0"
-       </ol></li>
-      <li> Row "0"
-       <ol><li> Row "0,1"
-        <li> Row "0,0"
-       </ol></li>
-     </ol></div>
+      <p>Update the cell's minimum width to be the length in CSS
+      pixels given by the <code><a href=#cell>Cell</a></code> object's second entry.</p>
 
-    <p>If the return value of the method is negative, larger than the
-    number of rows that the <code title=dom-provider-getRowCount><a href=#dom-provider-getrowcount>getRowCount()</a></code> 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 <code title=dom-provider-getChildAtPosition><a href=#dom-provider-getchildatposition>getChildAtPosition()</a></code>
-    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).</p>
+      <p>Update the cell's minimum height to be the length in CSS
+      pixels given by the <code><a href=#cell>Cell</a></code> object's third entry.</p>
 
-   </dd>
+      <p>Update the cell's callback to be the
+      <code><a href=#renderingcontext2dcallback>RenderingContext2DCallback</a></code> object given by the
+      <code><a href=#cell>Cell</a></code> object's fourth entry.</p>
 
-   <dt>To establish what classes apply to a row</dt>
+     </dd>
 
-   <dd>Invoke the <code title=dom-provider-getRowClasses><a href=#dom-provider-getrowclasses>getRowClasses()</a></code> method
-   with a <code><a href=#rowspecification>RowSpecification</a></code> object representing the row in
-   question, and a <code><a href=#domtokenlist-0>DOMTokenList</a></code> associated with an empty
-   string. The tokens contained in the <code><a href=#domtokenlist-0>DOMTokenList</a></code>
-   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.</dd>
+    </dl></li>
 
-   <dt>To establish whether a row is a data row or a special row</dt>
+  </ol><hr><p>When the user agent is to run the <dfn id=datagrid-update-display-algorithm><code>datagrid</code>
+  update display algorithm</dfn>, the user agent must invoke the <code title=dom-listener-getRows><a href=#dom-listener-getrows>getRows()</a></code> and <code title=dom-listener-getCells><a href=#dom-listener-getcells>getCells()</a></code> methods on the
+  current <code title=dom-datagrid-listener><a href=#dom-datagrid-listener>listener</a></code> such
+  that all the current visible rows in the <a href=#display-order-sparse-data-list>display order sparse
+  data list</a>, and all the cells in the currently visible columns
+  on all the currently visible rows, have been covered.</p>
 
-   <dd>Examine the classes that apply to the row. If the <code title=datagrid-row-class-header><a href=#datagrid-row-class-header>header</a></code> 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 <code title=datagrid-row-class-separator><a href=#datagrid-row-class-separator>separator</a></code> class applies
-   to the row, then in the place of the row, a separator should be
-   shown. Otherwise, if the <code title=datagrid-row-class-selectable-separator><a href=#datagrid-row-class-selectable-separator>selectable-separator</a></code>
-   class applies to the row, then the row should be a data row, but
-   represented as a separator. (The difference between a <code title=datagrid-row-class-separator><a href=#datagrid-row-class-separator>separator</a></code> and a <code title=datagrid-row-class-selectable-separator><a href=#datagrid-row-class-selectable-separator>selectable-separator</a></code>
-   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.</dd>
+  <p>A row is considered covered if it is present in the <a href=#pending-datagrid-rows-list>pending
+  <code>datagrid</code> rows list</a>, or if the <code title=dom-listener-getRows><a href=#dom-listener-getrows>getRows()</a></code> method is invoked with
+  a range that includes the row in question.</p>
 
-   <dt id=rowType1>To establish whether a row is openable</dt>
+  <p>A cell is considered covered if it is present in the
+  <a href=#pending-datagrid-cells-list>pending <code>datagrid</code> cells list</a>, or if the
+  <code title=dom-listener-getRows><a href=#dom-listener-getrows>getRows()</a></code> method is
+  invoked with a range that includes the row in question and a list of
+  columns that includes the cell's column, or if the <code title=dom-listener-getCells><a href=#dom-listener-getcells>getCells()</a></code> method is invoked
+  with a list of rows and columns that intersects the cell in
+  question. However, the <code title=dom-listener-getCells><a href=#dom-listener-getcells>getCells()</a></code> method can only be
+  used if the row is already present in the <a href=#display-order-sparse-data-list>display order sparse
+  data list</a>.</p>
 
-   <dd>Determine the number of child rows for that row. If there are
-   one or more child rows, then the row is openable.</dd>
+  <p>The <code title=dom-listener-getRows><a href=#dom-listener-getrows>getRows()</a></code> method,
+  if used, must be invoked with five arguments. The first argument
+  must be the index in the <a href=#display-order-sparse-data-list>display order sparse data list</a>
+  to the first row that the the user agent is requesting, known as the
+  <i>anchor row</i>. The second argument must be the number of
+  consecutive cells for which the user agent is requesting
+  information. The third argument must be the <code><a href=#rowid>RowID</a></code> of
+  the row that is the nearest ancestor in the <a href=#display-order-sparse-data-tree>display order
+  sparse data <em>tree</em></a> of the anchor row. If this is the
+  <code><a href=#datagrid>datagrid</a></code>, then the <code><a href=#rowid>RowID</a></code> object must be an
+  empty array. The fourth argument must be the display order position
+  of the anchor row in the <a href=#display-order-sparse-data-tree>display order sparse data
+  tree</a>, assuming that the row identified in the third argument
+  is indeed the anchor row's parent row. The fifth and final argument
+  must be an array of the identifiers of the columns for which the
+  user agent is requesting information, in the order they were added
+  to the <code><a href=#datagrid>datagrid</a></code>.</p>
 
-   <dt>To establish whether a row should be initially open or closed</dt>
+  <p>As the <code title=dom-listener-getRows><a href=#dom-listener-getrows>getRows()</a></code> method
+  is invoked, the <a href=#pending-datagrid-rows-list>pending <code>datagrid</code> rows list</a>
+  must be updated to include the rows for which information has been
+  requested, excluding rows for which information is already
+  available; and the <a href=#pending-datagrid-cells-list>pending <code>datagrid</code> cells
+  list</a> must be updated to include the cells for which
+  information has been requested on those rows.</p>
 
-   <dd>If <a href=#rowType1>the row is openable</a>, examine the
-   classes that apply to the row. If the <code title=datagrid-row-class-initially-open><a href=#datagrid-row-class-initially-open>initially-open</a></code>
-   class applies to the row, then it should be initially
-   open. Otherwise, if the <code title=datagrid-row-class-initially-closed><a href=#datagrid-row-class-initially-closed>initially-closed</a></code>
-   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.</dd>
+  <p>The <code title=dom-listener-getCells><a href=#dom-listener-getcells>getCells()</a></code> method,
+  if used, must be invoked with two arguments. The first argument must
+  be an array of <code><a href=#rowid>RowID</a></code> objects identifying the rows for
+  which information is being requested. The second argument must be an
+  array of the identifiers of the columns for which the user agent is
+  requesting information, in the order they were added to the
+  <code><a href=#datagrid>datagrid</a></code>.</p>
 
-<!-- XXXPA
-   <dt>To establish whether a row is deletable</dt>
+  <p>As the <code title=dom-listener-getCells><a href=#dom-listener-getcells>getCells()</a></code>
+  method is invoked, the <a href=#pending-datagrid-cells-list>pending <code>datagrid</code> cells
+  list</a> must be updated to include the cells for which
+  information has been requested.</p>
 
-   <dd>Check whether the <code
-   title="datagrid-row-class-deletable">deletable</code> class applies
-   to the row. If it does, the row is deletable, and interactive user
-   agents should provide a way for the user to request that the row be
-   deleted. (See the <code
-   title="dom-provider-performActionOnRow">performActionOnRow()</code>
-   method for more details.) Otherwise, the user agent should not
-   provide the user with a method for requesting that the row be
-   deleted.</dd>
--->
+  <p>Calls to these methods should be batched so that the rows and
+  cells to be covered are handled by the fewest number of calls to
+  these methods as possible. To this end, user agents may invoke the
+  <code title=dom-listener-getRows><a href=#dom-listener-getrows>getRows()</a></code> method for a set
+  of rows that includes some rows that are already in the
+  <a href=#display-order-sparse-data-list>display order sparse data list</a>, and similarly may
+  invoke the <code title=dom-listener-getCells><a href=#dom-listener-getcells>getCells()</a></code>
+  method with row/column combinations that cover some cells for which
+  data is already known. Generally, however, user agents should avoid
+  invoking these methods with arguments that cause information to be
+  requested when it has already been requested or is already
+  known.</p>
 
-   <dt>To obtain a <a href=#url>URL</a> identifying an image representing a row</dt>
+  <div class=example>
 
-   <dd>Invoke the <code title=dom-provider-getRowImage><a href=#dom-provider-getrowimage>getRowImage()</a></code> method with a
-   <code><a href=#rowspecification>RowSpecification</a></code> object representing the row in
-   question. The return value is a <a href=#url>URL</a>. Immediately <a href=#resolve-a-url title="resolve a url">resolve</a> that URL, relative to the
-   <code><a href=#datagrid>datagrid</a></code> element, to obtain an <a href=#absolute-url>absolute
-   URL</a> 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.</dd> <!-- changing
-   the base URL doesn't change the image used later -->
+   <p>For example, consider a case represented by the following table,
+   where the cells marked "Yes" indicate that the data has already
+   been obtained, the cells marked "Pending" indicate that the data
+   has been previously requested but not yet obtained, and the cells
+   with just a dash indicate that no information has ever been
+   obtained, or any information that had been obtained has now been
+   discarded.</p>
 
-   <dt>To obtain a context menu appropriate for a particular row</dt>
+   <table><tr><td>        <th> Row   <th> Column A  <th> Column B
+    <tr><th> Row 1  <td> -     <td> -         <td> -
+    <tr><th> Row 2  <td> Yes   <td> Yes       <td> Yes
+    <tr><th> Row 3  <td> Yes   <td> Yes       <td> Yes
+    <tr><th> Row 4  <td> Yes   <td> Yes       <td> Yes
+    <tr><th> Row 5  <td> -     <td> -         <td> -
+    <tr><th> Row 6  <td> -     <td> -         <td> -
+    <tr><th> Row 7  <td> Yes   <td> Pending   <td> -
+    <tr><th> Row 8  <td> Yes   <td> Pending   <td> Pending
+   </table><p>Thus, rows 2, 3, 4, 7, and 8 are already covered, as are the
+   cells from those rows except for the cell in column B of row 7.</p>
 
-   <dd>Invoke the <code title=dom-provider-getRowMenu><a href=#dom-provider-getrowmenu>getRowMenu()</a></code> method with a
-   <code><a href=#rowspecification>RowSpecification</a></code> object representing the row in
-   question. The return value is a reference to an object implementing
-   the <code><a href=#htmlmenuelement>HTMLMenuElement</a></code> interface, i.e. a
-   <code><a href=#menus>menu</a></code> 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.<!-- XXX update once menu section
-   works; with xrefs -->) If the method returns something that is not
-   an <code><a href=#htmlmenuelement>HTMLMenuElement</a></code>, 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 <code><a href=#datagrid>datagrid</a></code>
-   element.</dd>
+   <p>Now consider what happens if all of these rows become visible at
+   once. The user agent has several choices, including (but not
+   limited to) the following:</p>
 
-   <dt>To establish the value of a particular cell</dt>
+   <ul><li>Fire the <code title=dom-listener-getRows><a href=#dom-listener-getrows>getRows()</a></code>
+    method for rows 1 through 8 and columns A and B all at once.</li>
 
-   <dd>Invoke the <code title=dom-provider-getCellData><a href=#dom-provider-getcelldata>getCellData()</a></code> method with
-   the first argument being a <code><a href=#rowspecification>RowSpecification</a></code> 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.)</dd>
+    <li>Fire the <code title=dom-listener-getRows><a href=#dom-listener-getrows>getRows()</a></code>
+    method for row 1, then fire it again for rows 5 through 7.</li>
 
-   <dt>To establish what classes apply to a cell</dt>
+    <li>Fire the <code title=dom-listener-getRows><a href=#dom-listener-getrows>getRows()</a></code>
+    method for row 1, then fire it again for rows 5 and 6, and then
+    fire the <code title=dom-listener-getCells><a href=#dom-listener-getcells>getCells()</a></code>
+    method for row 7 column B.</li>
 
-   <dd>Invoke the <code title=dom-provider-getCellClasses><a href=#dom-provider-getcellclasses>getCellClasses()</a></code> method
-   with the first argument being a <code><a href=#rowspecification>RowSpecification</a></code>
-   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 <code><a href=#domtokenlist-0>DOMTokenList</a></code> 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 <code><a href=#domtokenlist-0>DOMTokenList</a></code> 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.</dd>
+   </ul><p>All three options are allowed, but the latter two are preferable
+   to the former, as they minimise the amount of redundant information
+   requested.</p>
 
-   <dt id=cellType1>To establish the type of a cell</dt>
+   <p>In any case, the data model now looks like this:</p>
 
-   <dd>Examine the classes that apply to the cell. If the <code title=datagrid-cell-class-progress><a href=#datagrid-cell-class-progress>progress</a></code> class applies
-   to the cell, it is a progress bar. Otherwise, if the <code title=datagrid-cell-class-cyclable><a href=#datagrid-cell-class-cyclable>cyclable</a></code> 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.</dd>
+   <table><tr><td>        <th> Row     <th> Column A  <th> Column B  <th> Column C
+    <tr><th> Row 1  <td> Pending <td> Pending   <td> Pending   <td> -
+    <tr><th> Row 2  <td> Yes     <td> Yes       <td> Yes       <td> -
+    <tr><th> Row 3  <td> Yes     <td> Yes       <td> Yes       <td> -
+    <tr><th> Row 4  <td> Yes     <td> Yes       <td> Yes       <td> -
+    <tr><th> Row 5  <td> Pending <td> Pending   <td> Pending   <td> -
+    <tr><th> Row 6  <td> Pending <td> Pending   <td> Pending   <td> -
+    <tr><th> Row 7  <td> Yes     <td> Pending   <td> Pending   <td> -
+    <tr><th> Row 8  <td> Yes     <td> Pending   <td> Pending   <td> -
+   </table><p>Now consider the case where a third column, column C, is added
+   to the data model. The user agent once again has several choices,
+   including (but not limited to) the following:</p>
 
-   <dt>To establish the value of a progress bar cell</dt>
+   <ul><li>Fire the <code title=dom-listener-getRows><a href=#dom-listener-getrows>getRows()</a></code>
+    method for rows 1 through 8 again, this time listing just column
+    C.</li>
 
-   <dd>If the value <var title="">x</var> of the cell is a string that
-   can be <a href=#rules-for-parsing-floating-point-number-values title="rules for parsing floating point number
-   values">converted to a floating-point number</a> in the range
-   0.0 ≤ <var title="">x</var> ≤ 1.0, then
-   the progress bar has that value (0.0 means no progress, 1.0 means
-   complete). Otherwise, the progress bar is an indeterminate progress
-   bar.</dd>
+    <li>Fire the <code title=dom-listener-getRows><a href=#dom-listener-getrows>getRows()</a></code>
+    method for row 1, then fire it again for rows 5 and 6, and then
+    fire the <code title=dom-listener-getCells><a href=#dom-listener-getcells>getCells()</a></code>
+    method for the other rows (in all three cases, listing just column
+    C).</li>
 
-   <dt id=cellType2>To establish how a simple text cell should be presented</dt>
+   </ul><p>The two options here are as bad as each other; the former
+   involves a lot of overlap, but the latter involves a lot of method
+   calls. Unfortunately the user agent can't do the obvious thing,
+   namely just to invoke the <code title=dom-listener-getCells><a href=#dom-listener-getcells>getCells()</a></code> method for all the
+   rows listing just column C, because it doesn't have the row
+   information for all the rows yet (rows 1, 5 and 6 are still
+   pending).</p>
 
-   <dd>Check whether one of the <code title=datagrid-cell-class-checked><a href=#datagrid-cell-class-checked>checked</a></code>, <code title=datagrid-cell-class-unchecked><a href=#datagrid-cell-class-unchecked>unchecked</a></code>, or <code title=datagrid-cell-class-indeterminate><a href=#datagrid-cell-class-indeterminate>indeterminate</a></code>
-   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
-   <code title=datagrid-cell-class-editable><a href=#datagrid-cell-class-editable>editable</a></code> class
-   applies to the cell. If it does, then the cell value is editable,
-   otherwise the cell value is static.</dd>
+   <p>In any case, the data model now looks like this:</p>
 
-   <dt>To establish the state of a cell's checkbox, if it has one</dt>
+   <table><tr><td>        <th> Row     <th> Column A  <th> Column B  <th> Column C
+    <tr><th> Row 1  <td> Pending <td> Pending   <td> Pending   <td> Pending
+    <tr><th> Row 2  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr><th> Row 3  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr><th> Row 4  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr><th> Row 5  <td> Pending <td> Pending   <td> Pending   <td> Pending
+    <tr><th> Row 6  <td> Pending <td> Pending   <td> Pending   <td> Pending
+    <tr><th> Row 7  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+    <tr><th> Row 8  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+   </table><p>If at this point the user scrolls around anywhere within this
+   <code><a href=#datagrid>datagrid</a></code>, the user agent won't fire the <code title=dom-listener-getRos>getRos()</code> and <code title=dom-listener-getCells><a href=#dom-listener-getcells>getCells()</a></code> methods, because
+   all of the rows and cells are covered.</p>
 
-   <dd>Check whether the <code title=datagrid-cell-class-checked><a href=#datagrid-cell-class-checked>checked</a></code> class applies to
-   the cell. If it does, the cell is checked. Otherwise, check whether
-   the <code title=datagrid-cell-class-unchecked><a href=#datagrid-cell-class-unchecked>unchecked</a></code>
-   class applies to the cell. If it does, the cell is unchecked.
-   Otherwise, the <code title=datagrid-cell-class-indeterminate><a href=#datagrid-cell-class-indeterminate>indeterminate</a></code>
-   class applies to the cell and the cell's checkbox is in an
-   indeterminate state. When the <code title=datagrid-cell-class-indeterminate><a href=#datagrid-cell-class-indeterminate>indeterminate</a></code>
-   class applies to the cell, the checkbox is a tristate checkbox,
-   and the user can set it to the indeterminate state. Otherwise, only
-   the <code title=datagrid-cell-class-checked><a href=#datagrid-cell-class-checked>checked</a></code> and/or
-   <code title=datagrid-cell-class-unchecked><a href=#datagrid-cell-class-unchecked>unchecked</a></code>
-   classes apply to the cell, and the cell can only be toggled between
-   those two states.</dd>
+   <p>Now consider the case where the user agent receives row
+   information, but no cell information, for rows 1, 5, and 6:</p>
 
-  </dl><p>If the data provider ever raises an exception while the
-  <code><a href=#datagrid>datagrid</a></code> is invoking one of its methods, the
-  <code><a href=#datagrid>datagrid</a></code> must act, for the purposes of that particular
-  method call, as if the relevant method had not been defined.</p>
+   <table><tr><td>        <th> Row     <th> Column A  <th> Column B  <th> Column C
+    <tr><th> Row 1  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+    <tr><th> Row 2  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr><th> Row 3  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr><th> Row 4  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr><th> Row 5  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+    <tr><th> Row 6  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+    <tr><th> Row 7  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+    <tr><th> Row 8  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+   </table><p>The user agent still won't fire any methods when the user
+   scrolls, because the data is still covered. But if the script then
+   calls the <code title=dom-datagrid-renotify><a href=#dom-datagrid-renotify>renotify()</a></code>
+   method, the "Pending" flags would get reset, and the model would
+   now look like this:</p>
 
-  <p>A <code><a href=#rowspecification>RowSpecification</a></code> object <var title="">p</var> with
-  <var title="">n</var> path components passed to a method of the data
-  provider must fulfill the constraint <span>0 ≤ <var title="">p<sub title=""><var title="">i</var></sub></var> < <var title="">m</var>-1</span> for all integer values of <var title="">i</var> in the range <span>0 ≤ <var title="">i</var> < <var title="">n</var>-1</span>,
-  where <var title="">m</var> is the value that was last returned by
-  the <code title=dom-provider-getRowCount><a href=#dom-provider-getrowcount>getRowCount()</a></code>
-  method when it was passed the <code><a href=#rowspecification>RowSpecification</a></code> object
-  <var title="">q</var> with <span title=""><var title="">i</var>-1</span>
-  items, where <span title=""><var title="">p<sub title=""><var title="">i</var></sub></var> = <var title="">q<sub title=""><var title="">i</var></sub></var></span> for all integer
-  values of <var title="">i</var> in the range
-  <span>0 ≤ <var title="">i</var> < <var title="">n</var>-1</span>, with any changes implied by the update
-  methods taken into account.</p>
+   <table><tr><td>        <th> Row     <th> Column A  <th> Column B  <th> Column C
+    <tr><th> Row 1  <td> Yes     <td> -         <td> -         <td> -      
+    <tr><th> Row 2  <td> Yes     <td> Yes       <td> Yes       <td> -      
+    <tr><th> Row 3  <td> Yes     <td> Yes       <td> Yes       <td> -      
+    <tr><th> Row 4  <td> Yes     <td> Yes       <td> Yes       <td> -      
+    <tr><th> Row 5  <td> Yes     <td> -         <td> -         <td> -      
+    <tr><th> Row 6  <td> Yes     <td> -         <td> -         <td> -      
+    <tr><th> Row 7  <td> Yes     <td> -         <td> -         <td> -      
+    <tr><th> Row 8  <td> Yes     <td> -         <td> -         <td> -      
+   </table><p>Now, assuming that all eight rows and all three columns are
+   still visible, the user agent has the following choices (amongst
+   others):</p>
 
-  <p id=inconsistentDataProvider>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 <code><a href=#datagrid>datagrid</a></code> element. If a user
-  agent is returned inconsistent data, for example if the number of
-  rows returned by <code title=dom-provider-getRowCount><a href=#dom-provider-getrowcount>getRowCount()</a></code> varies in ways
-  that do not match the calls made to the update methods, the user
-  agent may disable the <code><a href=#datagrid>datagrid</a></code>. User agents that do not
-  disable the <code><a href=#datagrid>datagrid</a></code> in inconsistent cases must honor
-  the most recently returned values.</p>
+   <ul><li>Fire the <code title=dom-listener-getRows><a href=#dom-listener-getrows>getCells()</a></code>
+    method for rows 1 through 8, listing all three columns.</li>
 
-  <p>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 <code title=dom-provider-getRowMenu><a href=#dom-provider-getrowmenu>getRowMenu</a></code> method.</p>
+    <li>Fire the <code title=dom-listener-getRows><a href=#dom-listener-getrows>getCells()</a></code>
+    method for rows 1 and 5 through 8, listing all three columns, and
+    then fire the method for rows 2 through 4, listing just column
+    C.</li>
 
-  <p>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.</p> <!-- XXX speaking of which, do we actually want that
-  limitation? -->
+    <li>Fire the <code title=dom-listener-getRows><a href=#dom-listener-getrows>getCells()</a></code>
+    method for rows 1 and 5 through 8, listing just columns A abd B,
+    and then fire the method for rows 1 through 8, listing just column
+    C.</li>
 
+   </ul><p>Here the latter two are preferable because they result in less
+   overlap than the first.</p>
 
-  <h5 id=updating-the-datagrid><span class=secno>4.11.2.6 </span>Updating the <code><a href=#datagrid>datagrid</a></code></h5>
+  </div>
 
-  <p>Whenever the <code title=dom-datagrid-data><a href=#dom-datagrid-data>data</a></code>
-  attribute is set to a new value, the <code><a href=#datagrid>datagrid</a></code> 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.</p>
+  <hr><p>The <a href=#task-source>task source</a> for tasks queued on behalf of a
+  <code><a href=#datagrid>datagrid</a></code> is the <a href=#dom-manipulation-task-source>DOM manipulation task
+  source</a>.</p>
 
-  <p>There are a number of update methods that can be invoked on the
-  <code><a href=#datagrid>datagrid</a></code> element to cause it to refresh itself in
-  slightly less drastic ways:</p>
+  </div>
 
-  <p>When the <dfn id=dom-datagrid-updateeverything title=dom-datagrid-updateEverything><code>updateEverything()</code></dfn>
-  method is called, the user agent must repopulate the entire
-  <code><a href=#datagrid>datagrid</a></code>. 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.</p>
 
-  <p>When the <dfn id=dom-datagrid-updaterowschanged title=dom-datagrid-updateRowsChanged><code>updateRowsChanged(<var title="">row</var>, <var title="">count</var>)</code></dfn> method
-  is called, the user agent must refresh the rendering of the rows
-  starting from the row specified by <var title="">row</var>, and
-  including the <var title="">count</var> next siblings of the row (or
-  as many next siblings as it has, if that is less than <var title="">count</var>), including all descendant rows.</p>
+  <h5 id=listening-to-notifications-from-the-datagrid><span class=secno>4.11.2.3 </span>Listening to notifications from the <code><a href=#datagrid>datagrid</a></code></h5>
 
-  <p>When the <dfn id=dom-datagrid-updaterowsinserted title=dom-datagrid-updateRowsInserted><code>updateRowsInserted(<var title="">row</var>, <var title="">count</var>)</code></dfn> method
-  is called, the user agent must assume that <var title="">count</var>
-  new rows have been inserted, such that the first new row is
-  identified by <var title="">row</var>. The user agent must update
-  its rendering and the selection accordingly. The new rows should not
-  be selected.</p>
+  <p><em>The conformance criteria in this section apply to any
+  implementation of the <code><a href=#datagridlistener>DataGridListener</a></code> interface,
+  including (and most commonly) the content author's
+  implementation(s).</em></p>
 
-  <p>When the <dfn id=dom-datagrid-updaterowsremoved title=dom-datagrid-updateRowsRemoved><code>updateRowsRemoved(<var title="">row</var>, <var title="">count</var>)</code></dfn> method
-  is called, the user agent must assume that <var title="">count</var>
-  rows have been removed starting from the row that used to be
-  identifier by <var title="">row</var>.  The user agent must update
-  its rendering and the selection accordingly.</p>
+  <pre class=idl>// To be implemented by Web authors as a JS object
+[NoInterfaceObject] interface <dfn id=datagridlistener>DataGridListener</dfn> {
+  void <a href=#dom-listener-initialize title=dom-listener-initialize>initialize</a>(in <a href=#htmldatagridelement>HTMLDataGridElement</a> datagrid);
 
-  <p>The <dfn id=dom-datagrid-updaterowchanged title=dom-datagrid-updateRowChanged><code>updateRowChanged(<var title="">row</var>)</code></dfn> method must be exactly equivalent
-  to calling <code title=dom-datagrid-updateRowsChanged><a href=#dom-datagrid-updaterowschanged>updateRowsChanged(<var title="">row</var>, 1)</a></code>.</p>
+  void <a href=#dom-listener-getrows title=dom-listener-getRows>getRows</a>(in unsigned long rowIndex, in unsigned long rowCount, in <a href=#rowid>RowID</a> parentRow, in unsigned long position, in <a href=#columnlist>ColumnList</a> columns);
+  void <a href=#dom-listener-getcells title=dom-listener-getCells>getCells</a>(in <a href=#rowidlist>RowIDList</a> rows, in <a href=#columnlist>ColumnList</a> columns);
+  void <a href=#dom-listener-rowopened title=dom-listener-rowOpened>rowOpened</a>(in <a href=#rowid>RowID</a> row, in boolean rowCountNeeded);
+  void <a href=#dom-listener-rowclosed title=dom-listener-rowClosed>rowClosed</a>(in <a href=#rowid>RowID</a> row);
 
-  <p>When the <dfn id=dom-datagrid-updatecolumnchanged title=dom-datagrid-updateColumnChanged><code>updateColumnChanged(<var title="">column</var>)</code></dfn> method is called, the user agent
-  must refresh the rendering of the specified column <var title="">column</var>, for all rows.</p>
+  void <a href=#dom-listener-cellchanged title=dom-listener-cellChanged>cellChanged</a>(in <a href=#rowid>RowID</a> row, in <a href=#column>Column</a> column, in any newValue, in any prevValue);
+  <a href=#htmlmenuelement>HTMLMenuElement</a> <a href=#dom-listener-getrowmenu title=dom-listener-getRowMenu>getRowMenu</a>(in <a href=#rowid>RowID</a> row);
+<!--vsDGDND
+  boolean <span title="dom-listener-canDrop">canDrop</span>(in <span>RowID</span> row, in <span>RowID</span> position, data);
+  boolean <span title="dom-listener-dropped">dropped</span>(in <span>RowID</span> row, in <span>RowID</span> position, data);
+--><!--v2DGPA
+  void <span title="dom-listener-performAction">performAction</span>(in <span>RowID</span> row, in DOMString action);
+-->};</pre>
 
-  <p>When the <dfn id=dom-datagrid-updatecellchanged title=dom-datagrid-updateCellChanged><code>updateCellChanged(<var title="">row</var>, <var title="">column</var>)</code></dfn> method
-  is called, the user agent must refresh the rendering of the cell on
-  row <var title="">row</var>, in column <var title="">column</var>.</p>
+  <p>The <code>DataGridDataProvider</code> interface, once implemented
+  by an object in a script and hooked up to a <code><a href=#datagrid>datagrid</a></code>
+  using the <dfn id=dom-datagrid-data title=dom-datagrid-data><code>data</code></dfn> DOM
+  attribute, receives notifications when the <code><a href=#datagrid>datagrid</a></code>
+  needs information (such as which rows exist) for display.</p>
 
-  <p>Any effects the update methods have on the
-  <code><a href=#datagrid>datagrid</a></code>'s selection is not considered a change to the
-  selection, and must therefore not fire the <code title=event-select><a href=#event-select>select</a></code> event.</p>
+  <p>The following methods may be usefully implemented:</p>
 
-  <p>These update methods should be called only by the data provider,
-  or code acting on behalf of the data provider. In particular,
-  calling the <code title=dom-datagrid-updateRowsInserted><a href=#dom-datagrid-updaterowsinserted>updateRowsInserted()</a></code>
-  and <code title=dom-datagrid-updateRowsRemoved><a href=#dom-datagrid-updaterowsremoved>updateRowsRemoved()</a></code>
-  methods without actually inserting or removing rows from the data
-  provider is <a href=#inconsistentDataProvider>likely to result in
-  inconsistent renderings</a>, and the user agent is likely to disable
-  the data grid.</p>
+  <dl><dt><dfn id=dom-listener-initialize title=dom-listener-initialize><code>initialize(<var title="">datagrid</var>)</code></dfn></dt>
 
+   <dd>
 
-  <h5 id=requirements-for-interactive-user-agents><span class=secno>4.11.2.7 </span>Requirements for interactive user agents</h5>
+    <p>Called by the <code><a href=#datagrid>datagrid</a></code> element (the one given by
+    the <var title="">datagrid</var> argument) when the <code title=dom-datagrid-listener><a href=#dom-datagrid-listener>listener</a></code> attribute is
+    set.</p>
 
-  <p><em>This section only applies to interactive user agents.</em></p>
+   </dd>
 
-  <p>If the <code><a href=#datagrid>datagrid</a></code> element has a <dfn id=attr-datagrid-disabled title=attr-datagrid-disabled><code>disabled</code></dfn>
-  attribute, then the user agent must disable the
-  <code><a href=#datagrid>datagrid</a></code>, preventing the user from interacting with it.
-  The <code><a href=#datagrid>datagrid</a></code> element should still continue to update
-  itself when the data provider signals changes to the data, though.
-  Obviously, conformance requirements stating that
-  <code><a href=#datagrid>datagrid</a></code> elements must react to users in particular
-  ways do not apply when one is disabled.</p>
+   <dt><dfn id=dom-listener-getrows title=dom-listener-getRows><code>getRows(<var title="">rowIndex</var>, <var title="">rowCount</var>, <var title="">parentRow</var>, <var title="">position</var>, <var title="">columns</var>)</code></dfn></dt>
 
-  <p>If <a href=#rowType1>a row is openable</a>, 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.</p>
+   <dd>
 
-  <p>If a cell is a cell whose value <a href=#cellType1>can be
-  cycled between multiple states</a>, 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
-  <code><a href=#datagrid>datagrid</a></code> must invoke the data provider's <code title=dom-provider-cycleCell><a href=#dom-provider-cyclecell>cycleCell()</a></code> method, with a
-  <code><a href=#rowspecification>RowSpecification</a></code> object representing the cell's row as
-  the first argument and the cell's column index as the second. The
-  <code><a href=#datagrid>datagrid</a></code> must then act as if the
-  <code><a href=#datagrid>datagrid</a></code>'s <code title=dom-datagrid-updateCellChanged><a href=#dom-datagrid-updatecellchanged>updateCellChanged()</a></code>
-  method had been invoked with those same arguments.</p>
+    <p>Called by the <code><a href=#datagrid>datagrid</a></code> element when the user agent
+    finds itself needing to render rows for which it is lacking
+    information.</p>
 
-  <p>When a cell <a href=#cellType2>has a checkbox</a>, 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
-  <code><a href=#datagrid>datagrid</a></code> must invoke the data provider's <code title=dom-provider-setCellCheckedState><a href=#dom-provider-setcellcheckedstate>setCellCheckedState()</a></code>
-  method, with a <code><a href=#rowspecification>RowSpecification</a></code> 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 <code title=datagrid-cell-class-indeterminate><a href=#datagrid-cell-class-indeterminate>indeterminate</a></code> class
-  set). The <code><a href=#datagrid>datagrid</a></code> must then act as if the
-  <code><a href=#datagrid>datagrid</a></code>'s <code title=dom-datagrid-updateCellChanged><a href=#dom-datagrid-updatecellchanged>updateCellChanged()</a></code>
-  method had been invoked, specifying the same cell.</p>
+    <p>The <var title="">rowIndex</var> argument gives the flattened
+    index of the first row for which it needs information, ignoring
+    the tree structure of the <code><a href=#datagrid>datagrid</a></code> model, where zero
+    is the first row of the entire tree.</p>
 
-  <p>If a cell <a href=#cellType2>is editable</a>, 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 <code title=dom-provider-editCell><a href=#dom-provider-editcell>editCell()</a></code> method of the data
-  provider with three arguments: a <code><a href=#rowspecification>RowSpecification</a></code>
-  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 <code title=dom-datagrid-updateCellChanged><a href=#dom-datagrid-updatecellchanged>updateCellChanged()</a></code>
-  method had been invoked, with the same row and column specified.</p>
+    <p>The <var title="">rowCount</var> argument gives the number of
+    rows for which the user agent would like information.</p>
 
-  <!-- XXXPA <p class="XXX">define actions (performAction(), etc)</p> -->
+    <p>The <var title="">parentRow</var> argument gives the
+    <code><a href=#rowid>RowID</a></code> object identifying the nearest ancestor of the
+    first row that the user agent is aware of. After the sort order
+    has changed, this will typically be the root of the tree
+    (identified by a <code><a href=#rowid>RowID</a></code> object consisting of an empty
+    array).
 
-  <h5 id=the-selection><span class=secno>4.11.2.8 </span>The selection</h5>
+    <p>The <var title="">columns</var> argument gives the columns for
+    which the user agent is lacking information, as an array of column
+    identifiers (as passed to <code title=dom-datagrid-addColumn><a href=#dom-datagrid-addcolumn>addColumn()</a></code>).</p>
 
-  <p><em>This section only applies to interactive user agents. For
-  other user agents, the <code title=dom-datagrid-selection><a href=#dom-datagrid-selection>selection</a></code> attribute must
-  return null.</em></p>
+   </dd>
 
-  <pre class=idl>interface <dfn id=datagridselection>DataGridSelection</dfn> {
-  readonly attribute unsigned long <span title=dom-DataGridSelection-count>length</span>;
-  [IndexGetter] <a href=#rowspecification>RowSpecification</a> <a href=#dom-datagridselection-item title=dom-DataGridSelection-item>item</a>(in unsigned long index);
-  boolean <a href=#dom-datagridselection-isselected title=dom-DataGridSelection-isSelected>isSelected</a>(in <a href=#rowspecification>RowSpecification</a> row);
-  void <a href=#dom-datagridselection-setselected title=dom-DataGridSelection-setSelected>setSelected</a>(in <a href=#rowspecification>RowSpecification</a> row, in boolean selected);
-<!--  void <span title="dom-DataGridSelection-addRange">addRange</span>(in <span>RowSpecification</span> first, in <span>RowSpecification</span> last);
-  void <span title="dom-DataGridSelection-removeRange">removeRange</span>(in <span>RowSpecification</span> first, in <span>RowSpecification</span> last);
-XXX selection ranges -->
-  void <a href=#dom-datagridselection-selectall title=dom-DataGridSelection-selectAll>selectAll</a>();
-  void <a href=#dom-datagridselection-invert title=dom-DataGridSelection-invert>invert</a>();
-  void <a href=#dom-datagridselection-clear title=dom-DataGridSelection-clear>clear</a>();
+   <dt><dfn id=dom-listener-getcells title=dom-listener-getCells><code>getCells(<var title="">rows</var>, <var title="">columns</var>)</code></dfn></dt>
+
+   <dd>
+
+    <p>Called by the <code><a href=#datagrid>datagrid</a></code> element when the user agent
+    finds itself needing to render cells for which it is lacking
+    information in rows that it does know about.</p>
+
+    <p>The <var title="">rows</var> argument gives an array of
+    <code><a href=#rowid>RowID</a></code> objects identifying the various rows for which
+    the user agent is lacking information.</p>
+
+    <p>The <var title="">columns</var> argument gives the columns for
+    which the user agent is lacking information, as an array of column
+    identifiers (as passed to <code title=dom-datagrid-addColumn><a href=#dom-datagrid-addcolumn>addColumn()</a></code>).</p>
+
+   </dd>
+
+   <dt><dfn id=dom-listener-rowopened title=dom-listener-rowOpened><code>rowOpened(<var title="">row</var>, <var title="">rowCountNeeded</var>)</code></dfn></dt>
+
+   <dd>
+
+    <p>Called by the <code><a href=#datagrid>datagrid</a></code> element when the user has
+    opened a row.</p>
+
+    <p>The <var title="">row</var> argument gives an
+    <code><a href=#rowid>RowID</a></code> object identifying the row that was opened.</p>
+
+    <p>If the user agent also knows how many children that row has,
+    then the <var title="">rowCountNeeded</var> argument will be
+    false. Otherwise, the argument will be true, and the row will
+    remain closed until the <code title=dom-datagrid-setRows><a href=#dom-datagrid-setrows>setRows()</a></code> method is called
+    with an accurate row count.</p>
+
+   </dd>
+
+   <dt><dfn id=dom-listener-rowclosed title=dom-listener-rowClosed><code>rowClosed(<var title="">row</var>)</code></dfn></dt>
+
+   <dd>
+
+    <p>Called by the <code><a href=#datagrid>datagrid</a></code> element when the user has
+    opened a row.</p>
+
+    <p>The <var title="">row</var> argument gives an
+    <code><a href=#rowid>RowID</a></code> object identifying the row that was closed.</p>
+
+   </dd>
+
+   <dt><dfn id=dom-listener-cellchanged title=dom-listener-cellChanged><code>cellChanged(<var title="">row</var>, <var title="">column</var>, <var title="">newValue</var>, <var title="">prevValue</var>)</code></dfn></dt>
+
+   <dd>
+
+    <p>Called by the <code><a href=#datagrid>datagrid</a></code> element when the user has
+    edited a cell or checked a check box in a cell.</p>
+
+    <p>The <var title="">row</var> argument gives an
+    <code><a href=#rowid>RowID</a></code> object identifying the row of the cell, and the
+    <var title="">column</var> argument gives the identifier of the
+    cell's column.</p>
+
+    <p>The <var title="">newValue</var> argument gives the new value,
+    and the <var title="">prevValue</var> argument gives the previous
+    value.</p>
+
+   </dd>
+
+   <dt><dfn id=dom-listener-getrowmenu title=dom-listener-getRowMenu><code>getRowMenu(<var title="">row</var>)</code></dfn></dt>
+
+   <dd>Must return an <code><a href=#htmlmenuelement>HTMLMenuElement</a></code> object that is to
+   be used as a context menu for row <var title="">row</var>, 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.</dd>
+
+   <!--v2DGDND, v2DFPA-->
+
+  </dl><div class=impl>
+
+  <p>Objects that implement the <code><a href=#datagridlistener>DataGridListener</a></code>
+  interface may omit any or all of the methods. When a method is
+  omitted, a user agent intending to call that method must instead
+  skip the method call, and must assume that the method's return value
+  is null.</p>
+
+  </div>
+
+
+
+<!-- v2DGS: <datagrid> selection (search for the bits marked "..." to see what needs filling in, at a minimum)
+
+  <h5>The selection</h5>
+
+  <pre class="idl">interface <dfn>DataGridSelection</dfn> {
+  readonly attribute unsigned long <span title="dom-DataGridSelection-length">length</span>;
+  [IndexGetter] <span>RowID</span> <span title="dom-DataGridSelection-item">item</span>(in unsigned long index);
+  boolean <span title="dom-DataGridSelection-isSelected">isSelected</span>(in <span>RowID</span> row);
+  void <span title="dom-DataGridSelection-setSelected">setSelected</span>(in <span>RowID</span> row, in boolean selected);
+  void <span title="dom-DataGridSelection-selectAll">selectAll</span>();
+  void <span title="dom-DataGridSelection-clear">clear</span>();
 };</pre>
 
-  <p>Each <code><a href=#datagrid>datagrid</a></code> element must keep track of which rows
+  <dl class="domintro">
+
+   ...
+
+  </dl>
+
+  <div class="impl">
+
+  <p>Each <code>datagrid</code> 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. <!--XXX
-  select-provider-selection The default data provider, for instance,
-  changes which rows are selected when it is first initialized.--></p>
+  be changed via the methods described in this section.</p>
 
-  <p>The selection of a <code><a href=#datagrid>datagrid</a></code> is represented by its
-  <dfn id=dom-datagrid-selection title=dom-datagrid-selection><code>selection</code></dfn> DOM
-  attribute, which must be a <code><a href=#datagridselection>DataGridSelection</a></code> object.</p>
+  <p>The selection of a <code>datagrid</code> is represented by its
+  <dfn title="dom-datagrid-selection"><code>selection</code></dfn> DOM
+  attribute, which must be a <code>DataGridSelection</code> object.</p>
 
-  <p><code><a href=#datagridselection>DataGridSelection</a></code> 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.</p>
+  <p><code>DataGridSelection</code> objects represent the rows in the
+  selection. In the selection the rows must be ordered in their
+  natural order (and not, e.g., the display order). A row with an
+  ancestor that is closed cannot be selected.</p>
 
-  <p class=note>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.</p>
-
-  <p>The <dfn id=dom-datagridselection-length title=dom-DataGridSelection-length><code>length</code></dfn>
+  <p>The <dfn
+  title="dom-DataGridSelection-length"><code>length</code></dfn>
   attribute must return the number of rows currently present in the
-  selection. This is the <var title=dom-DataGridSelection-length><a href=#dom-datagridselection-length>length</a></var>.</p>
+  selection. This is the <var
+  title="dom-DataGridSelection-length">length</var>.</p>
 
   <p>The object's <span>indices of the supported indexed
-  properties</span> are the numbers in the range zero to <span title=""><var title=dom-DataGridSelection-length><a href=#dom-datagridselection-length>length</a></var>-1</span>, unless
-  the <var title=dom-DataGridSelection-length><a href=#dom-datagridselection-length>length</a></var> is zero,
+  properties</span> are the numbers in the range zero to <span title=""><var
+  title="dom-DataGridSelection-length">length</var>-1</span>, unless
+  the <var title="dom-DataGridSelection-length">length</var> is zero,
   in which case there are no <span>supported indexed
   properties</span>.</p>
 
-  <p>The <dfn id=dom-datagridselection-item title=dom-DataGridSelection-item><code>item(<var title="">index</var>)</code></dfn> method must return the <var title="">index</var>th row in the selection. If the argument is out
+  <p>The <dfn title="dom-DataGridSelection-item"><code>item(<var
+  title="">index</var>)</code></dfn> method must return a
+  <code>RowID</code> object identifying the <var
+  title="">index</var>th 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 <code><a href=#index_size_err>INDEX_SIZE_ERR</a></code>
-  exception. <a href=#refsDOM3CORE>[DOM3CORE]</a></p>
+  minus one), then it must raise an <code>INDEX_SIZE_ERR</code>
+  exception. <a href="#refsDOM3CORE">[DOM3CORE]</a></p>
 
-  <p>The <dfn id=dom-datagridselection-isselected title=dom-DataGridSelection-isSelected><code>isSelected()</code></dfn>
+  <p>The <dfn
+  title="dom-DataGridSelection-isSelected"><code>isSelected()</code></dfn>
   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.</p>
+  argument. If the specified row is in the <span>natural order sparse
+  data tree</span> and is selected, the method must return true,
+  otherwise it must return false.</p>
 
-  <p>The <dfn id=dom-datagridselection-setselected title=dom-DataGridSelection-setSelected><code>setSelected()</code></dfn>
-  method takes two arguments, <var title="">row</var> and <var title="">selected</var>. When invoked, it must set the selection
-  state of row <var title="">row</var> to selected if <var title="">selected</var> is true, and unselected if it is false. If
-  <var title="">row</var> is not a row in the data grid, the method
-  must raise an <code><a href=#index_size_err>INDEX_SIZE_ERR</a></code> exception. If the
-  specified row is not rendered because one of its ancestors is
-  closed, the method must do nothing.</p>
+  <p>The <dfn
+  title="dom-DataGridSelection-setSelected"><code>setSelected()</code></dfn>
+  method takes two arguments, <var title="">row</var> and <var
+  title="">selected</var>. When invoked, it must set the selection
+  state of row <var title="">row</var> to selected if <var
+  title="">selected</var> is true, and unselected if it is false. If
+  <var title="">row</var> does not specify a row in the <span>natural
+  order sparse data tree</span> ...
 
-  <p>The <dfn id=dom-datagridselection-selectall title=dom-DataGridSelection-selectAll><code>selectAll()</code></dfn>
-  method must mark all the rows in the data grid as selected. After a
-  call to <code title=dom-DataGridSelection-selectAll><a href=#dom-datagridselection-selectall>selectAll()</a></code>, the
-  <code title=dom-DataGridSelection-length><a href=#dom-datagridselection-length>length</a></code> attribute
-  will return the number of rows in the data grid, not counting
-  children of closed rows.</p>
+  <p>The <dfn
+  title="dom-DataGridSelection-selectAll"><code>selectAll()</code></dfn>
+  method must ...
 
-  <p>The <dfn id=dom-datagridselection-invert title=dom-DataGridSelection-invert><code>invert()</code></dfn>
-  method must cause all the rows in the selection that were marked as
-  selected to now be marked as not selected, and vice versa.</p>
-
-  <p>The <dfn id=dom-datagridselection-clear title=dom-DataGridSelection-clear><code>clear()</code></dfn>
-  method must mark all the rows in the data grid to be marked as not
-  selected.  After a call to <code title=dom-DataGridSelection-clear><a href=#dom-datagridselection-clear>clear()</a></code>, the <code title=dom-DataGridSelection-length><a href=#dom-datagridselection-length>length</a></code> attribute will
+  <p>The <dfn
+  title="dom-DataGridSelection-clear"><code>clear()</code></dfn>
+  method must mark all the rows in the <code>datagrid</code> as not
+  selected. After a call to <code
+  title="dom-DataGridSelection-clear">clear()</code>, the <code
+  title="dom-DataGridSelection-length">length</code> attribute will
   return zero.</p>
 
-  <p>If the <code><a href=#datagrid>datagrid</a></code> element has a <dfn id=attr-datagrid-multiple title=attr-datagrid-multiple><code>multiple</code></dfn>
-  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.</p>
+  <p>If the <code>datagrid</code> element has a <code
+  title="attr-datagrid-multiple">multiple</code> 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
+  should allow the user to select a row, and must not allow the user
+  to select more than a single row at a time; selecting another one
+  must unselect all the other rows.</p>
 
-  <p class=note>This only applies to the user. Scripts can select
-  multiple rows even when the <code title=attr-datagrid-multiple><a href=#attr-datagrid-multiple>multiple</a></code> attribute is
+  <p class="note">This only applies to the user. Scripts can select
+  multiple rows even when the <code
+  title="attr-datagrid-multiple">multiple</code> attribute is
   absent.</p>
 
-  <p>Whenever the selection of a <code><a href=#datagrid>datagrid</a></code> changes,
-  whether due to the user interacting with the element, or as a result
-  of calls to methods of the <code title=dom-datagrid-selection><a href=#dom-datagrid-selection>selection</a></code> object, a <dfn id=event-select title=event-select><code>select</code></dfn><!-- XXX check if we
-  really should be DFNing this here. It's a DOM3 Core event. What's
-  our story going to be regarding events and defining them? --> event
-  that bubbles but is not cancelable must be fired on the
-  <code><a href=#datagrid>datagrid</a></code> element. If changes are made to the selection
-  via calls to the object's methods during the execution of a
-  script<!-- XXX should xref to a better explanation -->, then the
-  <code title=event-select><a href=#event-select>select</a></code> events must be coalesced
-  into one, which must then be fired<!--XXX xref again--> when the
-  script execution has completed<!-- XXX xref -->.</p>
+  ...event on selection change?...
 
-  <p class=note>The <code><a href=#datagridselection>DataGridSelection</a></code> interface has no
-  relation to the <code><a href=#selection-0>Selection</a></code> interface.</p>
+  </div>
 
+  <p class="note">The <code>DataGridSelection</code> interface has no
+  relation to the <code>Selection</code> interface.</p>
 
-  <h5 id=columns-and-captions><span class=secno>4.11.2.9 </span>Columns and captions</h5>
+-->
 
-  <p><em>This section only applies to interactive user agents.</em></p>
 
-  <p>Each <code><a href=#datagrid>datagrid</a></code> element must keep track of which
-  columns are currently being rendered. User agents should initially
-  show all the columns except those with the <code title=datagrid-column-class-initially-hidden><a href=#datagrid-column-class-initially-hidden>initially-hidden</a></code>
-  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.</p>
-
-  <p>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.</p>
-
-  <p>If none of the columns have any captions (i.e. if the data
-  provider does not provide a <code title=dom-provider-getCaptionText><a href=#dom-provider-getcaptiontext>getCaptionText()</a></code> 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).</p>
-
-  <p class=note>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 <code title=dom-provider-getcolumnCount><a href=#dom-provider-getcolumncount>getColumnCount()</a></code> method
-  of the data provider.</p>
-
-  <p>If <a href=#columnType2>a column is sortable</a>, 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 <code><a href=#datagrid>datagrid</a></code>
-  must invoke the data provider's <code title=dom-provider-toggleColumnSortState><a href=#dom-provider-togglecolumnsortstate>toggleColumnSortState()</a></code>
-  method, with the column's index as the only argument. The
-  <code><a href=#datagrid>datagrid</a></code> must <em>then</em> act as if the
-  <code><a href=#datagrid>datagrid</a></code>'s <code title=dom-datagrid-updateEverything><a href=#dom-datagrid-updateeverything>updateEverything()</a></code>
-  method had been invoked.</p>
-
-<!--XXXDND
+<!--vsDGDND
   <h5>Drag and drop in <code>datagrid</code>s</h5>
 
   <p><em>This section only applies to interactive user agents.</em></p>
 
-  <p class="XXX">define drag and drop in datagrids; selectiondraggable, etc.</p>
+  ...define drag and drop in datagrids; selectiondraggable...
 -->
-</div>
 
 
   <h4 id=the-command><span class=secno>4.11.3 </span>The <dfn><code>command</code></dfn> element</h4>
@@ -40410,7 +41087,7 @@
 
   <h3 id=scripting><span class=secno>5.5 </span>Scripting</h3>
 
-  <h4 id=introduction-1><span class=secno>5.5.1 </span>Introduction</h4>
+  <h4 id=introduction-2><span class=secno>5.5.1 </span>Introduction</h4>
 
   <p>Various mechanisms can cause author-provided executable code to
   run in the context of a document. These mechanisms include, but are
@@ -41269,7 +41946,7 @@
     <tr><td><dfn id=handler-onmousewheel title=handler-onmousewheel><code>onmousewheel</code></dfn> <td> <code title=event-mousewheel>mousewheel</code> <!-- widely used -->
 <!--<tr><td><dfn title="handler-onpaste"><code>onpaste</code></dfn> <td> <code title="event-paste">paste</code>--> <!-- widely used -->
     <tr><td><dfn id=handler-onscroll title=handler-onscroll><code>onscroll</code></dfn> <td> <code title=event-scroll>scroll</code> <!-- widely used --> <!-- XXX should define when it fires -->
-    <tr><td><dfn id=handler-onselect title=handler-onselect><code>onselect</code></dfn> <td> <code title=event-select><a href=#event-select>select</a></code> <!-- widely used --> <!-- XXX should define when it fires -->
+    <tr><td><dfn id=handler-onselect title=handler-onselect><code>onselect</code></dfn> <td> <code title=event-select>select</code> <!-- widely used --> <!-- XXX should define when it fires -->
 <!--<tr><td><dfn title="handler-onselectstart"><code>onselectstart</code></dfn> <td> <code title="event-selectstart">selectstart</code>--> <!-- widely used --> <!-- XXX should define when it fires -->
     <tr><td><dfn id=handler-onsubmit title=handler-onsubmit><code>onsubmit</code></dfn> <td> <code title=event-submit>submit</code> <!-- widely used -->
   </table><hr><p>The following are the <a href=#event-handler-attributes-0>event handler attributes</a> (and their corresponding <a href=#event-handler-event-type title="event handler event type">event handler event types</a>)
@@ -42359,7 +43036,7 @@
 
   <h3 id=offline><span class=secno>5.8 </span>Offline Web applications</h3>
 
-  <h4 id=introduction-2><span class=secno>5.8.1 </span>Introduction</h4>
+  <h4 id=introduction-3><span class=secno>5.8.1 </span>Introduction</h4>
 
   <p><em>This section is non-normative.</em></p>
 
@@ -47197,7 +47874,7 @@
 
   <h3 id=selection><span class=secno>6.6 </span>The text selection APIs</h3>
 
-  <p>Every <a href=#browsing-context>browsing context</a> has <dfn id=the-selection-0 title="the
+  <p>Every <a href=#browsing-context>browsing context</a> has <dfn id=the-selection title="the
   selection">a selection</dfn>. The selection can be empty, and the
   selection can have more than one range (a disjointed selection). The
   user agent should allow the user to change the selection. User
@@ -47232,7 +47909,7 @@
   </div>
 
   <p>Mostly for historical reasons, in addition to the <a href=#browsing-context>browsing
-  context</a>'s <a href=#the-selection-0 title="the selection">selection</a>, each
+  context</a>'s <a href=#the-selection title="the selection">selection</a>, each
   <code><a href=#the-textarea-element>textarea</a></code> and <code><a href=#the-input-element>input</a></code> element has an
   independent selection. These are the <dfn id=text-field-selection title="text field
   selection">text field selections</dfn>.</p>
@@ -47279,7 +47956,7 @@
 
   <p>The <dfn id=dom-getselection title=dom-getSelection><code>getSelection()</code></dfn> method on
   the <code><a href=#window>Window</a></code> interface must return the
-  <code><a href=#selection-0>Selection</a></code> object representing <a href=#the-selection-0>the
+  <code><a href=#selection-0>Selection</a></code> object representing <a href=#the-selection>the
   selection</a> of that <code><a href=#window>Window</a></code> object's
   <a href=#browsing-context>browsing context</a>.
 
@@ -47578,7 +48255,7 @@
   </div>
 
   <p class=note>The <code><a href=#selection-0>Selection</a></code> interface has no relation
-  to the <code><a href=#datagridselection>DataGridSelection</a></code> interface.</p>
+  to the <code>DataGridSelection</code> interface.</p>
 
 
   <h4 id=textFieldSelection><span class=secno>6.6.2 </span>APIs for the text field selections</h4>
@@ -47797,7 +48474,7 @@
 
   <p>When an editing host has focus, it must have a <dfn id=caret-position>caret
   position</dfn> that specifies where the current editing position
-  is. It may also have a <a href=#the-selection-0 title="the
+  is. It may also have a <a href=#the-selection title="the
   selection">selection</a>.</p> <!-- XXX xref to later section -->
 
   <p class=note>How the caret and selection are represented depends
@@ -47832,7 +48509,7 @@
 
    <dt>Change the selection</dt>
 
-   <dd><p>User agents must allow users to change <a href=#the-selection-0>the
+   <dd><p>User agents must allow users to change <a href=#the-selection>the
    selection</a> within an editing host, even into nested editable
    elements. User agents may prevent selections from being made in
    ways that cross from editable elements into non-editable elements
@@ -47918,7 +48595,7 @@
    element, backspacing when the caret is immediately after an
    element, forward-deleting at the end of an element,
    forward-deleting when the caret is immediately before an element,
-   and deleting a <a href=#the-selection-0 title="the selection">selection</a> whose
+   and deleting a <a href=#the-selection title="the selection">selection</a> whose
    start and end points do not share a common parent node.</p>
 
    <p>In any case, the exact behavior is UA-dependent, but user
@@ -47989,7 +48666,7 @@
   </dl><!-- XXX each action performed should be added to the undo history --><p>User agents may perform several commands per user request; for
   example if the user selects a block of text and hits
   <kbd><kbd>Enter</kbd></kbd>, the UA might interpret that as a
-  request to delete the content of <a href=#the-selection-0>the selection</a> followed
+  request to delete the content of <a href=#the-selection>the selection</a> followed
   by a request to break the paragraph at that position.</p>
 
   <p>All of the actions defined above, whether triggered by the user
@@ -48276,7 +48953,7 @@
 
   <p>However it is implemented, drag-and-drop operations must have a
   starting point (e.g. where the mouse was clicked, or the start of
-  <a href=#the-selection-0>the selection</a> or element that was selected for the
+  <a href=#the-selection>the selection</a> or element that was selected for the
   drag), may have any number of intermediate steps (elements that the
   mouse moves over during a drag, or elements that the user picks as
   possible drop points as he cycles through possibilities), and must
@@ -48290,7 +48967,7 @@
   </div>
 
 
-  <h4 id=introduction-3><span class=secno>6.9.1 </span>Introduction</h4>
+  <h4 id=introduction-4><span class=secno>6.9.1 </span>Introduction</h4>
 
   <p><em>This section is non-normative.</em></p>
 
@@ -49221,7 +49898,7 @@
   <p class=XXX>There has got to be a better way of doing this, surely.</p>
 
 
-  <h4 id=introduction-4><span class=secno>6.10.1 </span>Introduction</h4>
+  <h4 id=introduction-5><span class=secno>6.10.1 </span>Introduction</h4>
 
   <p class=XXX>...</p>
 
@@ -49665,7 +50342,7 @@
 
   <p>The <dfn id=execCommand title=dom-document-execCommand><code>execCommand(<var title="">commandId</var>, <var title="">showUI</var>, <var title="">value</var>)</code></dfn> method on the
   <code><a href=#htmldocument>HTMLDocument</a></code> interface allows scripts to perform
-  actions on the <a href=#the-selection-0 title="the selection">current selection</a>
+  actions on the <a href=#the-selection title="the selection">current selection</a>
   or at the current caret position. Generally, these commands would be
   used to implement editor UI, for example having a "delete" button on
   a toolbar.</p>
@@ -50199,7 +50876,7 @@
   </div>
 
 
-  <h4 id=introduction-5><span class=secno>7.2.1 </span>Introduction</h4>
+  <h4 id=introduction-6><span class=secno>7.2.1 </span>Introduction</h4>
 
   <p><em>This section is non-normative.</em></p>
 
@@ -50500,7 +51177,7 @@
 
   <h3 id=channel-messaging><span class=secno>7.3 </span><dfn>Channel messaging</dfn></h3>
 
-  <h4 id=introduction-6><span class=secno>7.3.1 </span>Introduction</h4>
+  <h4 id=introduction-7><span class=secno>7.3.1 </span>Introduction</h4>
 
   <p><em>This section is non-normative.</em></p>
 
@@ -60436,7 +61113,7 @@
   lead to this experience.</em></p>
 
 
-  <h3 id=introduction-7><span class=secno>10.1 </span>Introduction</h3>
+  <h3 id=introduction-8><span class=secno>10.1 </span>Introduction</h3>
 
   <p>In general, user agents are expected to support CSS, and many of
   the suggestions in this section are expressed in CSS terms. User
@@ -60458,7 +61135,7 @@
 
   <h3 id=the-css-user-agent-style-sheet-and-presentational-hints><span class=secno>10.2 </span>The CSS user agent style sheet and presentational hints</h3>
 
-  <h4 id=introduction-8><span class=secno>10.2.1 </span>Introduction</h4>
+  <h4 id=introduction-9><span class=secno>10.2.1 </span>Introduction</h4>
 
   <p>The CSS rules given in these subsections are, unless otherwise
   specified, expected to be used as part of the user-agent level style
@@ -61626,7 +62303,7 @@
 
   <h3 id=bindings><span class=secno>10.4 </span>Bindings</h3>
 
-  <h4 id=introduction-9><span class=secno>10.4.1 </span>Introduction</h4>
+  <h4 id=introduction-10><span class=secno>10.4.1 </span>Introduction</h4>
 
   <p>A number of elements have their rendering defined in terms of the
   'binding' property. <a href=#refsBECSS>[BECSS]</a></p>
@@ -63535,6 +64212,7 @@
  XXX * should check all cases of 'active document' and change the
        relevant ones to 'fully active document'.
  XXX * use <code>Document</code> consistently instead of 'document'.
+ XXX * s/raise/throw/g
 -->
 
  

Modified: source
===================================================================
--- source	2009-04-08 06:11:13 UTC (rev 2961)
+++ source	2009-04-18 01:16:51 UTC (rev 2962)
@@ -6256,15 +6256,6 @@
   to an underlying string that consists of an <span>unordered set of
   unique space-separated tokens</span>.</p>
 
-  <p>Which string underlies a particular <code>DOMTokenList</code>
-  object is defined when the object is created. It might be a content
-  attribute (e.g. the string that underlies the <code
-  title="dom-classList">classList</code> object is the <code
-  title="attr-class">class</code> attribute), or it might be an
-  anonymous string (e.g. when a <code>DOMTokenList</code> object is
-  passed to an author-implemented callback in the
-  <code>datagrid</code> APIs).</p>
-
   <pre class="idl">[<span title="dom-tokenlist-toString">Stringifies</span>] interface <dfn>DOMTokenList</dfn> {
   readonly attribute unsigned long <span title="dom-tokenlist-length">length</span>;
   [IndexGetter] DOMString <span title="dom-tokenlist-item">item</span>(in unsigned long index);
@@ -6737,7 +6728,7 @@
    <li value="20"><dfn><code>ABORT_ERR</code></dfn></li> <!-- actually in XHR for now -->
    <li value="21"><dfn><code>URL_MISMATCH_ERR</code></dfn></li> <!-- actually in workers for now -->
    <li value="22"><dfn><code>QUOTA_EXCEEDED_ERR</code></dfn></li> <!-- actually defined right here for now -->
-   <li value="23"><dfn><code>UNAVAILABLE_SCRIPT_ERR</code></dfn></li> <!-- actually defined right here for now -->
+   <li value="23"><dfn><code>DATAGRID_MODEL_ERR</code></dfn></li> <!-- actually defined right here for now -->
    <li value="81"><dfn><code>PARSE_ERR</code></dfn></li> <!-- actually defined in dom3ls -->
    <li value="82"><dfn><code>SERIALISE_ERR</code></dfn></li> <!-- actually defined in dom3ls -->
   </ol>
@@ -16471,6 +16462,8 @@
    <li>minimum value ≤ optimum point ≤ maximum value</li>
   </ul>
 
+  <!-- next two paragraphs are duplicated in the <datagrid> section -->
+
   <p><strong>UA requirements for regions of the gauge</strong>: If the
   optimum point is equal to the low boundary or the high boundary, or
   anywhere in between them, then the region between the low and high
@@ -17834,7 +17827,7 @@
 
   <p>The <code>img</code> must not be used as a layout tool. In
   particular, <code>img</code> elements should not be used to display
-  fully transparent images, as they rarely convey meaning and rarely
+   transparent images, as they rarely convey meaning and rarely
   add anything useful to the document.</p>
 
   <div class="impl">
@@ -35508,22 +35501,13 @@
   title="concept-input-list">suggestions source element</span>.</p>
 
   <p>If there is a <span title="concept-input-list">suggestions source
-  element</span>, then each <code>option</code> element that is a
-  descendant of the <span title="concept-input-list">suggestions
-  source element</span>, that is not <span
-  title="concept-option-disabled">disabled</span>, and whose <span
-  title="concept-option-value">value</span> is a string that isn't the
-  empty string and that the user would be allowed to enter as the
-  <code>input</code> element's <span
-  title="concept-fe-value">value</span>, represents a suggestion. Each
-  suggestion has a <span title="concept-option-value">value</span> and
-  a <span title="concept-option-label">label</span>.</p>
-
-  <p>When the user agent is allowing the user to edit the
-  <code>input</code> element's <span
+  element</span>, then, when the user agent is allowing the user to
+  edit the <code>input</code> element's <span
   title="concept-fe-value">value</span>, the user agent should offer
-  the suggestions to the user in a manner suitable for the type of
-  control used. The user agent may use the suggestion's <span
+  the suggestions represented by the <span
+  title="concept-input-list">suggestions source element</span> to the
+  user in a manner suitable for the type of control used. The user
+  agent may use the suggestion's <span
   title="concept-option-label">label</span> to identify the suggestion
   if appropriate. If the user selects a suggestion, then the
   <code>input</code> element's <span
@@ -35531,9 +35515,12 @@
   suggestion's <span title="concept-option-value">value</span>, as if
   the user had written that value himself.</p>
 
-  <p>User agents should filter the suggestions to hide suggestions
-  that would cause the element to not <span
-  title="concept-fv-valid">satisfy its constraints</span>.</p>
+  <p>User agents must filter the suggestions to hide suggestiosn that
+  the user would not be allowed to enter as the <code>input</code>
+  element's <span title="concept-fe-value">value</span>, and should
+  filter the suggestions to hide suggestions that would cause the
+  element to not <span title="concept-fv-valid">satisfy its
+  constraints</span>.</p>
 
   <hr>
 
@@ -36974,8 +36961,19 @@
   <p>The <code>datalist</code> element is hooked up to an
   <code>input</code> element using the <code
   title="attr-input-list">list</code> attribute on the
-  <code>input</code> element.</p>
+  <code>input</code> element. The <code>datalist</code> element can
+  also be used with a <code>datagrid</code> element, as the source of
+  autocompletion hints for <code
+  title="datagrid-type-editable">editable</code> cells.</p>
 
+  <p>Each <code>option</code> element that is a descendant of the
+  <code>datalist</code> element, that is not <span
+  title="concept-option-disabled">disabled</span>, and whose <span
+  title="concept-option-value">value</span> is a string that isn't the
+  empty string, represents a suggestion. Each suggestion has a <span
+  title="concept-option-value">value</span> and a <span
+  title="concept-option-label">label</span>.
+
   <dl class="domintro">
 
    <dt><var title="">datalist</var> . <code title="dom-datalist-options">options</code></dt>
@@ -40147,11 +40145,8 @@
 
 
 
-<div class="bad">
   <h4 id="datagrid">The <dfn><code>datagrid</code></dfn> element</h4>
 
-<p class="XXX">The API here needs rewriting. Don't implement this right now.</p>
-
   <dl class="element">
    <dt>Categories</dt>
    <dd><span>Flow content</span>.</dd>
@@ -40167,43 +40162,84 @@
    <dd>Or: A single <code>datalist</code> element.</dd>
    <dt>Content attributes:</dt>
    <dd><span>Global attributes</span></dd>
+<!--v2DGS:
    <dd><code title="attr-datagrid-multiple">multiple</code></dd>
+-->
    <dd><code title="attr-datagrid-disabled">disabled</code></dd>
    <dt>DOM interface:</dt>
    <dd>
 <pre class="idl">interface <dfn>HTMLDataGridElement</dfn> : <span>HTMLElement</span> {
-           attribute <span>DataGridDataProvider</span> <span title="dom-datagrid-data">data</span>;
-  readonly attribute <span>DataGridSelection</span> <span title="dom-datagrid-selection">selection</span>;
            attribute boolean <span title="dom-datagrid-multiple">multiple</span>;
            attribute boolean <span title="dom-datagrid-disabled">disabled</span>;
-  void <span title="dom-datagrid-updateEverything">updateEverything</span>();
-  void <span title="dom-datagrid-updateRowsChanged">updateRowsChanged</span>(in <span>RowSpecification</span> row, in unsigned long count);
-  void <span title="dom-datagrid-updateRowsInserted">updateRowsInserted</span>(in <span>RowSpecification</span> row, in unsigned long count);
-  void <span title="dom-datagrid-updateRowsRemoved">updateRowsRemoved</span>(in <span>RowSpecification</span> row, in unsigned long count);
-  void <span title="dom-datagrid-updateRowChanged">updateRowChanged</span>(in <span>RowSpecification</span> row);
-  void <span title="dom-datagrid-updateColumnChanged">updateColumnChanged</span>(in unsigned long column);
-  void <span title="dom-datagrid-updateCellChanged">updateCellChanged</span>(in <span>RowSpecification</span> row, in unsigned long column);
+           attribute <span>DataGridListener</span> <span title="dom-datagrid-listener">listener</span>;
+<!-- v2DGS:
+  readonly attribute <span>DataGridSelection</span> <span title="dom-datagrid-selection">selection</span>;
+-->
+  // columns
+  void <span title="dom-datagrid-addColumn">addColumn</span>(in <span>Column</span> id, in DOMString label, in DOMString type, [Optional] in HTMLImageElement icon, [Optional] in boolean sortable, [Optional] in boolean visible);
+           attribute DOMString <span title="dom-datagrid-sortColumn">sortColumn</span>;
+           attribute boolean <span title="dom-datagrid-sortAscending">sortAscending</span>;
+  void <span title="dom-datagrid-clearColumns">clearColumns</span>();
+
+  // rows
+  void <span title="dom-datagrid-renotify">renotify</span>();
+  void <span title="dom-datagrid-setRowCount">setRowCount</span>(in long childCount, in long rowCount);
+  void <span title="dom-datagrid-setRows">setRows</span>(in <span>RowList</span> rows);
+  void <span title="dom-datagrid-insertRows">insertRows</span>(in <span>RowList</span> rows);
+  void <span title="dom-datagrid-deleteRows">deleteRows</span>(in <span>RowIDList</span> rows);
+  void <span title="dom-datagrid-repaint">repaint</span>(in <span>RowID</span> row, in DOMString column);
+  void <span title="dom-datagrid-clearRows">clearRows</span>();
+<!--
+ v2: opening and closing a row
+     moving a row's actual ID
+      - imagine new mail moving a thread up; you just want to add the new mail to the thread and move the thread's first mail to the top
+      - though actually that should probably just be done using display sorting
+-->
+};
+
+typedef DOMString <dfn>Column</dfn>;
+typedef sequence<<span>Column</span>> <dfn>ColumnList</dfn>;
+typedef sequence<any> <dfn>Cell</dfn>; // <span>Column</span>, [Variadic] any (exact types expected depend on the column type)
+typedef sequence<<span>Cell</span>> <dfn>CellList</dfn>;
+typedef sequence<any> <dfn>Row</dfn>; // <span>RowID</span>, long, long, <span>CellList</span>, [Optional] boolean, [Optional] long
+typedef sequence<<span>Row</span>> <dfn>RowList</dfn>;
+typedef sequence<unsigned long> <dfn>RowID</dfn>;
+typedef sequence<<span>RowID</span>> <dfn>RowIDList</dfn>;
+
+[Callback=FunctionOnly, NoInterfaceObject]
+interface <dfn>RenderingContext2DCallback</dfn> {
+  DOMString <span title="dom-Rendering2DContextCallback-handleEvent">handleEvent</span>(in <span>CanvasRenderingContext2D</span> context, in unsigned long width, in unsigned long height);
 };</pre>
    </dd>
   </dl>
 
-  <p class="XXX">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).</p> <!-- XXXPA -->
+  <p>The <code>datagrid</code> element <span>represents</span> an
+  interactive representation of tree, list, or tabular data.</p>
 
-  <p>The <code>datagrid</code> element <span>represents</span> an interactive
-  representation of tree, list, or tabular data.</p>
+  <p>The data being presented is provided by script using the methods
+  described in the following sections.</p>
 
-  <p>The data being presented can come either from the content, as
-  elements given as children of the <code>datagrid</code> element, or
-  from a scripted data provider given by the <code
-  title="dom-datagrid-data">data</code> DOM attribute.</p>
+<!--v2DGS:
+  <p>The <dfn
+  title="attr-datagrid-multiple"><code>multiple</code></dfn> attribute
+  is a <span>boolean attribute</span>. When set, it indicates that the
+  user can select more than one row at a time.</p>
+-->
 
-  <p>The <code title="attr-datagrid-multiple">multiple</code> and
-  <code title="attr-datagrid-disabled">disabled</code> attributes are
-  <span title="boolean attribute">boolean attributes</span>. Their
-  effects are described in the processing model sections below.</p>
+  <p>The <dfn
+  title="attr-datagrid-disabled"><code>disabled</code></dfn> attribute
+  is a <span>boolean attribute</span> used to disable the
+  control. <span class="impl">When the attribute is set, the user
+  agent must disable the <code>datagrid</code>, preventing the user
+  from interacting with it. The <code>datagrid</code> element should
+  still continue to update itself when the underlying data changes,
+  though, as described in the next few sections. However, conformance
+  requirements stating that <code>datagrid</code> elements must react
+  to users in particular ways do not apply when one is
+  disabled.</span></p>
 
+  <div class="impl">
+
   <p>The <dfn
   title="dom-datagrid-multiple"><code>multiple</code></dfn> and <dfn
   title="dom-datagrid-disabled"><code>disabled</code></dfn> DOM
@@ -40212,16 +40248,24 @@
   title="attr-datagrid-disabled">disabled</code> content attributes
   respectively.</p>
 
+  </div>
 
-  <h5>The <code>datagrid</code> data model</h5>
+  <!-- v2DGPA: 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). (v2DGPA = <datagrid> Perform Action) -->
 
+
+  <h5>Introduction</h5>
+
   <p><em>This section is non-normative.</em></p>
 
   <p>In the <code>datagrid</code> 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.</p>
+  although individual columns might be hidden in the presentation.</p>
 
+  <hr>
+
   <p>Each row can have child rows. Child rows may be hidden or
   shown, by closing or opening (respectively) the parent row.</p>
 
@@ -40232,1757 +40276,2384 @@
   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.</p>
 
-  <p>The columns can have captions. Those captions are not considered
-  a row in their own right, they are obtained separately.</p>
+  <p>The chains of numbers that give a row's path, or identifier, are
+  represented by arrays of positions, represented in IDL by the
+  <span>RowID</span> interface.</p>
 
+  <p>The root of the tree is represented by an empty array.</p>
+
+  <hr>
+
+  <p>Each column has a string that is used to identify it in the API,
+  a label that is shown to users interacting with the column, a type,
+  and optionally an icon.</p>
+
+  <p>The possible types are as follows:</p>
+
+  <table>
+   <thead>
+    <tr>
+     <td>Keyword
+     <td>Description
+   <tbody>
+    <tr>
+     <td><code title="datagrid-type-text">text</code>
+     <td>Simple text.
+    <tr>
+     <td><code title="datagrid-type-editable">editable</code>
+     <td>Editable text.
+    <tr>
+     <td><code title="datagrid-type-checkable">checkable</code>
+     <td>Text with a check box.
+    <tr>
+     <td><code title="datagrid-type-list">list</code>
+     <td>A list of values that the user can switch between.
+    <tr>
+     <td><code title="datagrid-type-progress">progress</code>
+     <td>A progress bar.
+    <tr>
+     <td><code title="datagrid-type-meter">meter</code>
+     <td>A gauge.
+    <tr>
+     <td><code title="datagrid-type-custom">custom</code>
+     <td>A canvas onto which arbitrary content can be drawn.
+  </table>
+
+  <p>Each column can be flagged as sortable, in which case the user
+  will be able to sort the view using that column.</p>
+
+  <p>Columns are not necessarily visible. A column can be created
+  invisible by default. The user can select which columns are to be
+  shown.</p>
+
+  <p>When no columns have been added to the <code>datagrid</code>, a
+  column with no name, whose identifier is the empty string, whose
+  type is <code title="datagrid-type-text">text</code>, and which is
+  not sortable, is implied. This column is removed if any explicit
+  columns are declared.</p>
+
+  <p>Each cell uses the type given for its column, so all cells in a
+  column present the same type of information.</p>
+
+<!--v2DGS:
   <p>Selection of data in a <code>datagrid</code> operates at the row
   level. If the <code title="attr-datagrid-multiple">multiple</code>
   attribute is present, multiple rows can be selected at once,
   otherwise the user can only select one row at a time.</p>
-
-  <p>The <code>datagrid</code> element can be disabled entirely by
-  setting the <code title="attr-datagrid-disabled">disabled</code>
-  attribute.</p>
-<!--XXXDND
-  <p class="XXX">selection draggable [normative definitions are
-  in the interactive part below]</p>
 -->
 
-  <p>Columns, rows, and cells can each have specific flags, known as
-  classes, applied to them by the data provider. These classes <a
-  href="#datagridClassSummary">affect the functionality</a> of the
-  <code>datagrid</code> element, and are also <a
-  href="#datagridPseudos">passed to the style system</a>. They are
-  similar in concept to the <code title="attr-class">class</code>
-  attribute, except that they are not specified on elements but are
-  given by scripted data providers.</p> <!-- XXX check xrefs -->
+  <!-- v2DGDND: selection should draggable to and from datagrids -->
 
 
-  <h5>How rows are identified</h5>
+  <h6>Example: a <code>datagrid</code> backed by a static <code>table</code> element</h6>
 
-  <p>The chains of numbers that give a row's path, or identifier, are
-  represented by objects that implement the
-  <span>RowSpecification</span> interface.</p>
+  <p class="XXX">...</p>
 
-  <pre class="idl">[NoInterfaceObject] interface <dfn>RowSpecification</dfn> {
-  // binding-specific interface
-};</pre>
 
-  <p>In JavaScript, 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, <code>[1,0,9]</code> is a
-  <span>RowSpecification</span>, as is <code>1</code> on its
-  own. However, <code>[1,0.2,9]</code> is not a
-  <span>RowSpecification</span> object, since its second value is not
-  an integer.</p>
+  <h6>Example: a <code>datagrid</code> backed by nested <code>ol</code> elements</h6>
 
-  <p>User agents must always represent <code>RowSpecification</code>s
-  in JavaScript by using arrays, even if the path only has one
-  number.</p>
+  <p class="XXX">...</p>
 
-  <p>The root of the tree is represented by the empty path; in
-  JavaScript, this is the empty array (<code>[]</code>). Only the
-  <code title="dom-provider-getRowCount">getRowCount()</code> and
-  <code
-  title="dom-provider-getChildAtPosition">GetChildAtPosition()</code>
-  methods ever get called with the empty path.</p>
 
+  <h6>Example: a <code>datagrid</code> backed by a server</h6>
 
-  <h5>The data provider interface</h5>
+  <p class="XXX">...</p>
 
-  <p><em>The conformance criteria in this section apply to any
-  implementation of the <code>DataGridDataProvider</code>, including
-  (and most commonly) the content author's implementation(s).</em></p>
 
-<p class="XXX">The API here needs rewriting. Don't implement this right now.</p>
+  <h5>Populating the <code>datagrid</code></h5>
 
-  <pre class="idl">// To be implemented by Web authors as a JS object
-[NoInterfaceObject] interface <dfn>DataGridDataProvider</dfn> {
-  void <span title="dom-provider-initialize">initialize</span>(in <span>HTMLDataGridElement</span> datagrid);
-  unsigned long <span title="dom-provider-getRowCount">getRowCount</span>(in <span>RowSpecification</span> row);
-  unsigned long <span title="dom-provider-getChildAtPosition">getChildAtPosition</span>(in <span>RowSpecification</span> parentRow, in unsigned long position);
-  unsigned long <span title="dom-provider-getColumnCount">getColumnCount</span>();
-  DOMString <span title="dom-provider-getCaptionText">getCaptionText</span>(in unsigned long column);
-  void <span title="dom-provider-getCaptionClasses">getCaptionClasses</span>(in unsigned long column, in DOMTokenList classes);
-  DOMString <span title="dom-provider-getRowImage">getRowImage</span>(in <span>RowSpecification</span> row);
-  <span>HTMLMenuElement</span> <span title="dom-provider-getRowMenu">getRowMenu</span>(in <span>RowSpecification</span> row);
-  void <span title="dom-provider-getRowClasses">getRowClasses</span>(in <span>RowSpecification</span> row, in DOMTokenList classes);
-  DOMString <span title="dom-provider-getCellData">getCellData</span>(in <span>RowSpecification</span> row, in unsigned long column);
-  void <span title="dom-provider-getCellClasses">getCellClasses</span>(in <span>RowSpecification</span> row, in unsigned long column, in DOMTokenList classes);
-<!--XXXDND
-  boolean <span title="dom-provider-canDrop">canDrop</span>(in <span>RowSpecification</span> row, in <span>RowSpecification</span> position, data);
-  boolean <span title="dom-provider-dropped">dropped</span>(in <span>RowSpecification</span> row, in <span>RowSpecification</span> position, data);
--->  void <span title="dom-provider-toggleColumnSortState">toggleColumnSortState</span>(in unsigned long column);
-  void <span title="dom-provider-setCellCheckedState">setCellCheckedState</span>(in <span>RowSpecification</span> row, in unsigned long column, in long state);
-  void <span title="dom-provider-cycleCell">cycleCell</span>(in <span>RowSpecification</span> row, in unsigned long column);
-  void <span title="dom-provider-editCell">editCell</span>(in <span>RowSpecification</span> row, in unsigned long column, in DOMString data);
-<!--XXXPA
-  void <span title="dom-provider-performAction">performAction</span>(in DOMString action); // required if .performAction() is ever invoked on the datagrid
-  void <span title="dom-provider-performActionOnRow">performActionOnRow</span>(in <span>RowSpecification</span> row, in DOMString action); // required if getRowClasses ever includes 'deletable' or if <span title="dom-provider-.performActionOnRow">.performActionOnRow</span>() is ever invoked on the datagrid
-  void <span title="dom-provider-performActionOnCell">performActionOnCell</span>(in <span>RowSpecification</span> row, in unsigned long column, in DOMString action); // required if .performActionOnCell() is ever invoked on the datagrid
--->};</pre>
-<!-- based on http://lxr.mozilla.org/seamonkey/source/layout/xul/base/src/tree/public/nsITreeView.idl -->
+  <dl class="domintro">
 
-  <p>The <code>DataGridDataProvider</code> interface represents the
-  interface that objects must implement to be used as custom data
-  views for <code>datagrid</code> elements.</p>
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-listener">listener</code> [ = <var title="">value</var> ]</dt>
+   <dd>
 
-  <p>Not all the methods are required. The minimum number of methods
-  that must be implemented in a useful view is two: the <code
-  title="dom-provider-getRowCount">getRowCount()</code> and <code
-  title="dom-provider-getCellData">getCellData()</code> methods.</p>
+    <p>Return the current object that is configured as the
+    <code>datagrid</code> listener, if any. Returns null if there is
+    none.</p>
 
-  <p>Once the object is written, it must be hooked up to the
-  <code>datagrid</code> using the <dfn
-  title="dom-datagrid-data"><code>data</code></dfn> DOM attribute.</p>
+    <p>The listener is an object provided by the script author that
+    receives notifications when the <code>datagrid</code> needs row
+    data to render itself, when the user opens and closes rows with
+    children, when the user edits a cell, and when the user invokes a
+    row's context menu. (The <code>DataGridListener</code> interface
+    used for this purpose is described in the next section.)</p>
 
-  <p>The following methods may be usefully implemented:</p>
+    <p>Can be set, to change the current listener.</p>
 
-  <dl>
+   </dd>
 
-   <dt><dfn title="dom-provider-initialize"><code>initialize(<var title="">datagrid</var>)</code></dfn></dt>
 
-   <dd>Called by the <code>datagrid</code> element (the one given by
-   the <var title="">datagrid</var> argument) after it has first
-   populated itself. This would typically be used to set the initial
-   selection of the <code>datagrid</code> element when it is first
-   loaded. The data provider could also use this method call to
-   register a <code title="event-select">select</code> event handler
-   on the <code>datagrid</code> in order to monitor selection
-   changes.</dd>
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-renotify">renotify</code>()</dt>
+   <dd>
 
-   <dt><dfn title="dom-provider-getRowCount"><code>getRowCount(<var title="">row</var>)</code></dfn></dt>
+    <p>Causes the <code>datagrid</code> to resend notifications to the
+    listener (if any) for any rows or cells that the
+    <code>datagrid</code> does not yet have information for.</p>
 
-   <dd>Must return the number of rows that are children of the
-   specified <var title="">row</var>, including rows that are
-   off-screen. If <var title="">row</var> is empty, then the number of
-   rows at the top level must be returned. If the value that this
-   method would return for a given <var title="">row</var> changes,
-   the relevant update methods on the <code>datagrid</code> 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 <var title="">row</var> identifier
-   that is not empty.</dd>
+    <!-- useful, e.g., if there is a server error and the script loses
+    track of what rows it's supposed to be reporting. -->
 
-   <dt><dfn title="dom-provider-getChildAtPosition"><code>getChildAtPosition(<var title="">parentRow</var>, <var title="">position</var>)</code></dfn></dt>
+   </dd>
 
-   <dd>Must return the index of the row that is a child of <var
-   title="">parentRow</var> and that is to be positioned as the <var
-   title="">position</var>th row under <var title="">parentRow</var>
-   when rendering the children of <var title="">parentRow</var>. If
-   <var title="">parentRow</var> is empty, then <var
-   title="">position</var> refers to the <var
-   title="">position</var>th row at the top level of the data
-   grid. May be omitted if the rows are always to be sorted in the
-   natural order. (The natural order is the one where the method
-   always returns <var title="">position</var>.) For a given <var
-   title="">parentRow</var>, this method must never return the same
-   value for different values of <var title="">position</var>. The
-   returned value <var title="">x</var> must be in the range
-   0 ≤ <var title="">x</var> < <var
-   title="">n</var>, where <var title="">n</var> is the value returned
-   by <code title="dom-provider-getRowCount">getRowCount(<var
-   title="">parentRow</var>)</code>.</dd>
 
-   <dt><dfn title="dom-provider-getColumnCount"><code>getColumnCount()</code></dfn></dt>
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-addColumn">addColumn</code>(<var title="">id</var>, <var title="">label</var>, <var title="">type</var> [, <var title="">icon</var> [, <var title="">sortable</var> [, <var title="">visible</var> ] ] ] )</dt>
+   <dd>
 
-   <dd>Must return the number of columns currently in the data model
-   (including columns that might be hidden). May be omitted if there
-   is only one column. If the value that this method would return
-   changes, the <code>datagrid</code>'s <code
-   title="dom-datagrid-updateEverything">updateEverything()</code>
-   method must be called.</dd>
+    <p>Adds a column to the <code>datagrid</code>.</p>
 
-   <dt><dfn title="dom-provider-getCaptionText"><code>getCaptionText(<var title="">column</var>)</code></dfn></dt>
+    <p>If a column with the given identifier has already been added,
+    it just replaces the information for that column.</p>
 
-   <dd>Must return the caption, or label, for column <var
-   title="">column</var>. May be omitted if the columns have no
-   captions. If the value that this method would return changes, the
-   <code>datagrid</code>'s <code
-   title="dom-datagrid-updateColumnChanged">updateColumnChanged()</code>
-   method must be called with the appropriate column index.</dd>
+    <p>The possible types are enumerated in the previous section.</p>
 
-   <dt><dfn title="dom-provider-getCaptionClasses"><code>getCaptionClasses(<var title="">column</var>, <var title="">classes</var>)</code></dfn></dt>
+   </dd>
 
-   <dd>Must add the classes that apply to column <var
-   title="">column</var> to the <var title="">classes</var> object.
-   May be omitted if the columns have no special classes. If the
-   classes that this method would add changes, the
-   <code>datagrid</code>'s <code
-   title="dom-datagrid-updateColumnChanged">updateColumnChanged()</code>
-   method must be called with the appropriate column index. Some
-   classes have <a href="#datagridClassSummary">predefined
-   meanings</a>.</dd>
 
-   <dt><dfn title="dom-provider-getRowImage"><code>getRowImage(<var title="">row</var>)</code></dfn></dt>
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-sortColumn">sortColumn</code> [ = <var title="">value</var> ]</dt>
+   <dd>
 
-   <dd>Must return a <span>URL</span> giving the address of an image
-   that represents row <var title="">row</var>, or the empty string if
-   there is no applicable image. May be omitted if no rows have
-   associated images. If the value that this method would return
-   changes, the <code>datagrid</code>'s update methods must be called
-   to update the row in question.</dd>
+    <p>Returns the identifier of the column by which the data is to be
+    sorted.</p>
 
-   <dt><dfn title="dom-provider-getRowMenu"><code>getRowMenu(<var title="">row</var>)</code></dfn></dt>
+    <p>Can be set, to indicate that the sort order has changed. This
+    will cause the <code>datagrid</code> to clear its position
+    information for rows, so <code
+    title="dom-datagrid-setRows">setRows()</code> will have to be
+    called again with the new sort order.</p>
 
-   <dd>Must return an <code>HTMLMenuElement</code> object that is to
-   be used as a context menu for row <var title="">row</var>, 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.</dd>
+    <p>The columns are not actually sorted by the
+    <code>datagrid</code>; the data has to be sorted by the script
+    that adds the rows to the <code>datagrid</code>.</p>
 
-   <dt><dfn title="dom-provider-getRowClasses"><code>getRowClasses(<var title="">row</var>, <var title="">classes</var>)</code></dfn></dt>
+   </dd>
 
-   <dd>Must add the classes that apply to row <var title="">row</var>
-   to the <var title="">classes</var> object. May be omitted if the
-   rows have no special classes. If the classes that this method would
-   add changes, the <code>datagrid</code>'s update methods must be
-   called to update the row in question. Some classes have <a
-   href="#datagridClassSummary">predefined meanings</a>.</dd>
 
-   <dt><dfn title="dom-provider-getCellData"><code>getCellData(<var title="">row</var>, <var title="">column</var>)</code></dfn></dt>
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-sortAscending">sortAscending</code> [ = <var title="">value</var> ]</dt>
+   <dd>
 
-   <dd>Must return the value of the cell on row <var
-   title="">row</var> in column <var title="">column</var>. For text
-   cells, this must be the text to show for that cell. For <span
-   title="datagrid-cell-class-progress">progress bar cells</span>,
-   this must be either a floating point number in the range 0.0 to 1.0
-   (converted to a string representation<!-- XXX this isn't
-   technically enough to define what the author must be doing here,
-   but let's let that slide until someone notices -->), indicating the
-   fraction of the progress bar to show as full (1.0 meaning
-   complete), or the empty string, indicating an indeterminate
-   progress bar. If the value that this method would return changes,
-   the <code>datagrid</code>'s update methods must be called to update
-   the rows that changed. If only one cell changed, the <code
-   title="dom-datagrid-updateCellChanged">updateCellChanged()</code>
-   method may be used.</dd>
+    <p>Returns true if the data is to be sorted with small values
+    first; otherwise, returns false, indicating that bigger values are
+    to be put first.</p>
 
-   <dt><dfn title="dom-provider-getCellClasses"><code>getCellClasses(<var title="">row</var>, <var title="">column</var>, <var title="">classes</var>)</code></dfn></dt>
+    <p>Can be set, to indicate that the order is about to change.</p>
 
-   <dd>Must add the classes that apply to the cell on row <var
-   title="">row</var> in column <var title="">column</var> to the <var
-   title="">classes</var> object. May be omitted if the cells have no
-   special classes. If the classes that this method would add changes,
-   the <code>datagrid</code>'s update methods must be called to update
-   the rows or cells in question. Some classes have <a
-   href="#datagridClassSummary">predefined meanings</a>.</dd>
+   </dd>
 
-   <dt><dfn title="dom-provider-toggleColumnSortState"><code>toggleColumnSortState(<var title="">column</var>)</code></dfn></dt>
 
-   <dd>Called by the <code>datagrid</code> when the user tries to sort
-   the data using a particular column <var title="">column</var>. The
-   data provider must update its state so that the <code
-   title="dom-provider-getChildAtPosition">GetChildAtPosition()</code>
-   method returns the new order, and the classes of the columns
-   returned by <code
-   title="dom-provider-getCaptionClasses">getCaptionClasses()</code>
-   represent the new sort status. There is no need to tell the
-   <code>datagrid</code> that it the data has changed, as the
-   <code>datagrid</code> automatically assumes that the entire data
-   model will need updating.</dd>
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-clearColumns">clearColumns</code>()</dt>
+   <dd>
 
-   <dt><dfn title="dom-provider-setCellCheckedState"><code>setCellCheckedState(<var title="">row</var>, <var title="">column</var>, <var title="">state</var>)</code></dfn></dt>
+    <p>Removes all the columns in the <code>datagrid</code>,
+    reinstating the implied column.</p>
 
-   <dd>Called by the <code>datagrid</code> when the user changes the
-   state of a checkbox cell on row <var title="">row</var>, column
-   <var title="">column</var>. The checkbox should be toggled to the
-   state given by <var title="">state</var>, 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 (&#x2212;1) if it is to be set to the
-   indeterminate state. There is no need to tell the
-   <code>datagrid</code> that the cell has changed, as the
-   <code>datagrid</code> automatically assumes that the given cell
-   will need updating.</dd>
+   </dd>
 
-   <dt><dfn title="dom-provider-cycleCell"><code>cycleCell(<var title="">row</var>, <var title="">column</var>)</code></dfn></dt>
 
-   <dd>Called by the <code>datagrid</code> when the user changes the
-   state of a cyclable cell on row <var title="">row</var>, column
-   <var title="">column</var>. The data provider should change the
-   state of the cell to the new state, as appropriate. There is no
-   need to tell the <code>datagrid</code> that the cell has
-   changed, as the <code>datagrid</code> automatically assumes that
-   the given cell will need updating.</dd>
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-setRowCount">setRowCount</code>(<var title="">childCount</var>, <var title="">rowCount</var>)</dt>
+   <dd>
 
-   <dt><dfn title="dom-provider-editCell"><code>editCell(<var title="">row</var>, <var title="">column</var>, <var title="">data</var>)</code></dfn></dt>
+    <p>Sets the numbers of rows in the <code>datagrid</code>,
+    excluding rows that are descendants of rows that are closed.</p>
 
-   <dd>Called by the <code>datagrid</code> when the user edits the
-   cell on row <var title="">row</var>, column <var
-   title="">column</var>. The new value of the cell is given by <var
-   title="">data</var>. The data provider should update the cell
-   accordingly. There is no need to tell the <code>datagrid</code>
-   that the cell has changed, as the <code>datagrid</code>
-   automatically assumes that the given cell will need updating.</dd>
+    <p>Throws a <code>DATAGRID_MODEL_ERR</code> exception if the
+    arguments contradict each other or previously declared information
+    (e.g. declaring that the <code>datagrid</code> has three rows when
+    the 12th row has been declared).</p>
 
-<!--XXXPA
-  void performAction(in DOMString action); // required if .performAction() is ever invoked on the datagrid
-  void performActionOnRow(in <span>RowSpecification</span> row, in DOMString action); // required if getRowClasses ever includes 'deletable' or if .performActionOnRow() is ever invoked on the datagrid
-  void performActionOnCell(in <span>RowSpecification</span> row, in unsigned long column, in DOMString action); // required if .performActionOnCell() is ever invoked on the datagrid
--->
+   </dd>
 
+
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-setRows">setRows</code>(<var title="">rows</var>)</dt>
+   <dd>
+
+    <p>Updates data for rows in the <code>datagrid</code>, or fills in
+    data for rows previously implied by a call to <code
+    title="dom-datagrid-setRowCount">setRowCount()</code> but not
+    previously declared.</p>
+
+    <p>The <var title="">rows</var> argument is an array of rows, each
+    represented by a further array consisting of:</p>
+
+    <ol class="brief">
+
+     <li>A <code>RowID</code> object identifying the row.</li>
+
+     <li>An integer giving the position of the row in its parent,
+     given the current sort order, or &#x2212;1 to set other row data
+     without setting a position or changing a previously declared
+     position.</li>
+
+     <li>An integer giving the number of children of the row, or 0 if
+     the row has no children, or &#x2212;1 if the row has children but
+     the count is currently unknown. If the number of children has
+     already been set to 0 or a positive integer, then passing
+     &#x2212;1 leaves the previous count unchanged.</li>
+
+     <li>An array giving the data for zero or more cells in the row,
+     as described below.</li>
+
+     <li>A boolean declaring whether the row is open or not. This
+     entry, if omitted, is assumed to be false (closed), unless the
+     row has already been declared as open.</li>
+
+     <li>An integer giving the number of rows that are descendants of
+     this row, excluding those that are descendants of descendants of
+     this row that are closed. This entry can be omitted if the row is
+     closed or if it has already been declared.</li>
+
+    </ol>
+
+    <p>The array giving the data for the cells in the row consists of
+    a further set of arrays, one per cell. The first item of each of
+    these arrays is the column's identifier; the subsequent values
+    vary based on the type of the column, as follows:</p>
+
+    <dl>
+
+     <dt><code title="datagrid-type-text">text</code></dt>
+     <dd>
+      <ol class="brief">
+       <li>A string giving the cell's value.
+       <li>Optionally, an <code>img</code> element giving an icon for the cell.
+      </ol>
+     </dd>
+
+     <dt><code title="datagrid-type-editable">editable</code></dt>
+     <dd>
+      <ol class="brief">
+       <li>A string giving the cell's value.
+       <li>Optionally, a <code>datalist</code> element giving a set of predefined options.
+       <li>Optionally, an <code>img</code> element giving an icon for the cell.
+      </ol>
+     </dd>
+
+     <dt><code title="datagrid-type-checkable">checkable</code></dt>
+     <dd>
+      <ol class="brief">
+       <li>A string giving the cell's value.
+       <li>A boolean, indicating whether the cell is checked (true) or not (false).
+       <li>Optionally, a boolean indicating whether the value of the cell is obscured as indeterminate (true), or not (false).
+       <li>Optionally, an <code>img</code> element giving an icon for the cell.
+      </ol>
+     </dd>
+
+     <dt><code title="datagrid-type-list">list</code></dt>
+     <dd>
+      <ol class="brief">
+       <li>A string giving the cell's current value.
+       <li>A <code>select</code> element giving the <span title="concept-select-option-list">list of options</span>.
+       <li>Optionally, an <code>img</code> element giving an icon for the cell.
+      </ol>
+     </dd>
+
+     <dt><code title="datagrid-type-progress">progress</code></dt>
+     <dd>
+      <ol class="brief">
+       <li>A value in the range 0.0 (no progress) to 1.0 (task complete).
+      </ol>
+     </dd>
+
+     <dt><code title="datagrid-type-meter">meter</code></dt>
+     <dd>
+      <ol class="brief">
+       <li>A number giving the cell's value.
+       <li>Optionally, a number giving the maximum value, if it's not 1.
+       <li>Optionally, a number giving the minimum value, if it's not 0.
+       <li>Optionally, a number giving the highest value that is considered "low".
+       <li>Optionally, a number giving the lowest value that is considered "high".
+       <li>Optionally, a number giving the value that is considered optimal.
+      </ol>
+     </dd>
+
+     <dt><code title="datagrid-type-custom">custom</code></dt>
+     <dd>
+      <ol class="brief">
+       <li>A number giving the minimum width of the cell, in CSS pixels, that is desired.
+       <li>A number giving the minimum height of the cell, in CSS pixels, that is desired.
+       <li>A function that is passed a <code>CanvasRenderingContext2D</code> object, along with the width and height (in CSS pixels) of the cell that the context will draw on.
+      </ol>
+     </dd>
+
+    </dl>
+
+    <p>While the rows in a single call to the <code
+    title="dom-datagrid-setRows">setRows()</code> method can be in any
+    order, for each row, it is important that all its ancestor rows
+    and all its open previous siblings are also declared, either in
+    the same call or in an earlier one.</p>
+
+    <p>Throws a <code>DATAGRID_MODEL_ERR</code> exception if the
+    arguments contradict each other or previously declared information
+    (e.g. saying that a row's position is 5 when the parent row only
+    has 3 children, or naming a column that doesn't exist, or
+    declaring a row without declaring its parent, or changing the
+    number of children that a row has while that row and its ancestors
+    are all open).</p>
+
+   </dd>
+
+
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-insertRows">insertRows</code>(<var title="">rows</var>)</dt>
+   <dd>
+
+    <p>Inserts the given rows into the <code>datagrid</code>,
+    increasing the numbers of rows that the <code>datagrid</code>
+    assumes are present.</p>
+
+    <p>The <var title="">rows</var> argument is an array of rows in
+    the same structure as the argument to the <code
+    title="dom-datagrid-setRows">setRows()</code> method described
+    above, with the same expectations of consistency (a given row's
+    ancestors and earlier open siblings being listed either earlier or
+    in the same call as a given row). However, unlike with the <code
+    title="dom-datagrid-setRows">setRows()</code> method, if a row is
+    inserted along with its child, the child is not included in the
+    child and row counts of the parent row; every row in the <var
+    title="">rows</var> argument will increase its parent's counts
+    automatically.</p>
+
+    <p>Throws a <code>DATAGRID_MODEL_ERR</code> exception if the
+    arguments contradict each other or previously declared
+    information.</p>
+
+   </dd>
+
+
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-deleteRows">deleteRows</code>(<var title="">rows</var>)</dt>
+   <dd>
+
+    <p>Removes the given rows from the <code>datagrid</code>, and
+    updates the number of rows known to be in the
+    <code>datagrid</code> accordingly. The argument is an array of
+    <code>RowID</code> objects identifying the rows to remove.</p>
+
+    <p>Throws a <code>DATAGRID_MODEL_ERR</code> exception if the argument
+    includes a row the <code>datagrid</code> doesn't know about.</p>
+    <!-- since otherwise behaviour might depend on where the user
+    scrolled! -->
+
+   </dd>
+
+
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-repaint">repaint</code>(<var title="">row</var>, <var title="">column</var>)</dt>
+   <dd>
+
+    <p>If the given column's type is <code
+    title="datagrid-type-custom">custom</code>, then causes the
+    <code>datagrid</code> to reinvoke the function that obtains the
+    desired rendering.</p>
+
+   </dd>
+
+
+   <dt><var title="">datagrid</var> . <code title="dom-datagrid-clearRows">clearRows</code>()</dt>
+   <dd>
+
+    <p>Clears the <code>datagrid</code> of all row data, resetting it
+    to empty<!-- v2DGS:, and clears the selection-->.</p>
+
+   </dd>
+
   </dl>
 
-  <p>The following classes (for rows, columns, and cells) may be
-  usefully used in conjunction with this interface:</p>
 
-  <table id="datagridClassSummary">
-   <tr>
-    <th>Class name</th>
-    <th>Applies to</th>
-    <th>Description</th>
-   </tr>
+  <div class="impl">
 
-   <tr>
-    <td><!--checked--><dfn title="datagrid-cell-class-checked"><code>checked</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell has a checkbox and it is checked. (The <code
-    title="datagrid-cell-class-cyclable">cyclable</code> and <code
-    title="datagrid-cell-class-progress">progress</code> classes
-    override this, though.)</td>
-   </tr>
+  <h6>The listener</h6>
 
-   <tr>
-    <td><!--cyclable--><dfn title="datagrid-cell-class-cyclable"><code>cyclable</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell can be cycled through multiple values. (The <code
-    title="datagrid-cell-class-progress">progress</code> class
-    overrides this, though.)</td>
-   </tr>
+  <p>The <dfn
+  title="dom-datagrid-listener"><code>listener</code></dfn> DOM
+  attribute allows authors to specify an object that will receive all
+  the notifications from the <code>datagrid</code>. Initially, its
+  value must be null. On getting, it must return its value. On
+  setting, its value must be set to the new value, and then the user
+  agent must <span>queue a task</span> to call the <code
+  title="dom-listener-initialize">initalize()</code> method with the
+  <code>datagrid</code> element as its only argument.</p>
 
-   <tr>
-    <td><!--editable--><dfn title="datagrid-cell-class-editable"><code>editable</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell can be edited. (The <code
-    title="datagrid-cell-class-cyclable">cyclable</code>, <code
-    title="datagrid-cell-class-progress">progress</code>, <code
-    title="datagrid-cell-class-checked">checked</code>, <code
-    title="datagrid-cell-class-checked">unchecked</code> and <code
-    title="datagrid-cell-class-checked">indeterminate</code> classes
-    override this, though.)</td>
-   </tr>
 
-   <tr>
-    <td><!--header--><dfn title="datagrid-row-class-header"><code>header</code></dfn></td>
-    <td>Rows</td>
-    <td>The row is a heading, not a data row.</td>
-   </tr>
+  <h6>The columns</h6>
 
-   <tr>
-    <td><!--indeterminate--><dfn title="datagrid-cell-class-indeterminate"><code>indeterminate</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell has a checkbox, and it can be set to an indeterminate
-    state. If neither the <code
-    title="datagrid-cell-class-checked">checked</code> nor <code
-    title="datagrid-cell-class-checked">unchecked</code> classes are
-    present, then the checkbox is in that state, too. (The <code
-    title="datagrid-cell-class-cyclable">cyclable</code> and <code
-    title="datagrid-cell-class-progress">progress</code> classes
-    override this, though.)</td>
-   </tr>
+  <p>The columns are represented by the <dfn>column list</dfn>, an
+  ordered list of entries for columns, each of which consists of:</p>
 
-   <tr>
-    <td><!--initially-hidden--><dfn title="datagrid-column-class-initially-hidden"><code>initially-hidden</code></dfn></td>
-    <td>Columns</td>
-    <td>The column will not be shown when the <code>datagrid</code> is
-    initially rendered. If this class is not present on the column
-    when the <code>datagrid</code> is initially rendered, the column
-    will be visible if space allows.</td>
-   </tr>
+  <dl>
 
-   <tr>
-    <td><!--initially-closed--><dfn title="datagrid-row-class-initially-closed"><code>initially-closed</code></dfn></td>
-    <td>Rows</td>
-    <td>The row will be closed when the <code>datagrid</code> is
-    initially rendered. If neither this class nor the <code
-    title="datagrid-row-class-initially-open">initially-open</code>
-    class is present on the row when the <code>datagrid</code> is
-    initially rendered, the initial state will depend on platform
-    conventions.</td>
-   </tr>
+   <dt>An identifier</dt>
 
-   <tr>
-    <td><!--initially-open--><dfn title="datagrid-row-class-initially-open"><code>initially-open</code></dfn></td>
-    <td>Rows</td>
-    <td>The row will be opened when the <code>datagrid</code> is
-    initially rendered. If neither this class nor the <code
-    title="datagrid-row-class-initially-closed">initially-closed</code>
-    class is present on the row when the <code>datagrid</code> is
-    initially rendered, the initial state will depend on platform
-    conventions.</td>
-   </tr>
+   <dd>A string used to identify the column in the API.</dd>
 
-   <tr>
-    <td><!--progress--><dfn title="datagrid-cell-class-progress"><code>progress</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell is a progress bar.</td>
-   </tr>
+   <dt>A label</dt>
 
-   <tr>
-    <td><!--reversed--><dfn title="datagrid-column-class-reversed"><code>reversed</code></dfn></td>
-    <td>Columns</td>
-    <td>If the cell is sorted, the sort direction is descending,
-    instead of ascending.</td>
-   </tr>
+   <dd>A string used in the user interface.</dd>
 
-   <tr>
-    <td><!--selectable-separator--><dfn title="datagrid-row-class-selectable-separator"><code>selectable-separator</code></dfn></td>
-    <td>Rows</td>
-    <td>The row is a normal, selectable, data row, except that instead
-    of having data, it only has a separator. (The <code
-    title="datagrid-row-class-header">header</code> and <code
-    title="datagrid-row-class-separator">separator</code> classes
-    override this, though.)</td>
-   </tr>
+   <dt>A type</dt>
 
-   <tr>
-    <td><!--separator--><dfn title="datagrid-row-class-separator"><code>separator</code></dfn></td>
-    <td>Rows</td>
-    <td>The row is a separator row, not a data row. (The <code
-    title="datagrid-row-class-header">header</code> class
-    overrides this, though.)</td>
-   </tr>
+   <dd>One of the types described below.</dd>
 
-   <tr>
-    <td><!--sortable--><dfn title="datagrid-column-class-sortable"><code>sortable</code></dfn></td>
-    <td>Columns</td>
-    <td>The data can be sorted by this column.</td>
-   </tr>
+   <dt>An icon</dt>
 
-   <tr>
-    <td><!--sorted--><dfn title="datagrid-column-class-sorted"><code>sorted</code></dfn></td>
-    <td>Columns</td>
-    <td>The data is sorted by this column. Unless the <code
-    title="datagrid-column-class-reversed">reversed</code> class is
-    also present, the sort direction is ascending.</td>
-   </tr>
+   <dd>An image, copied from an <code>img</code> element when the
+   column was declared.</dd>
 
-   <tr>
-    <td><!--unchecked--><dfn title="datagrid-cell-class-unchecked"><code>unchecked</code></dfn></td>
-    <td>Cells</td>
-    <td>The cell has a checkbox and, unless the <code
-    title="datagrid-cell-class-checked">checked</code> class is
-    present as well, it is unchecked. (The <code
-    title="datagrid-cell-class-cyclable">cyclable</code> and <code
-    title="datagrid-cell-class-progress">progress</code> classes
-    override this, though.)</td>
-   </tr>
+   <dt>Whether the column is sortable</dt>
 
-<!--XXXPA
-   <tr>
-    <td><!- -deletable- -><dfn title="datagrid-row-class-deletable"><code>deletable</code></dfn></td>
-    <td>Rows</td>
-    <td></td>
-   </tr>
--->
+   <dd>A boolean indicating whether the user can request that the data
+   be sorted by this column (true), or not (false).</dd>
 
-  </table>
+   <dt>Whether the column is visible</dt>
 
+   <dd>A boolean indicating whether the column is part of the
+   <code>datagrid</code>'s rendering.</dd>
 
-  <h5>The default data provider</h5>
+  </dl>
 
-  <p>The user agent must supply a default data provider for the case
-  where the <code>datagrid</code>'s <code
-  title="dom-datagrid-data">data</code> attribute is null. It must act
-  as described in this section.</p>
+  <p>Initially, the <span>column list</span> must have a single
+  column, the <dfn>default column</dfn>, whose identifier is the empty
+  string, whose label is the empty string, whose type is <code
+  title="datagrid-type-text">text</code>, with no icon, which is not
+  sortable, and which <em>is</em> visible.</p>
 
-  <p>The behavior of the default data provider depends on the nature
-  of the first element child of the <code>datagrid</code>.</p>
+  <hr>
 
-  <dl class="switch">
+  <p>The <dfn title="dom-datagrid-addColumn"><code>addColumn(<var
+  title="">id</var>, <var title="">label</var>, <var
+  title="">type</var>, <var title="">icon</var>, <var
+  title="">sortable</var>, <var title="">visible</var>)</code></dfn>
+  method must run the following steps:</p>
 
-   <!-- XXX some of these entries say "the method must return" and
-   other say "the characteristic must be"; this should be rationalized
-   -->
+  <ol>
 
-   <dt>While the first element child is a <code>table</code> element</dt>
+   <li><p>If there is already an entry in <span>column list</span>,
+   other than the <span>default column</span>, whose identifier is
+   <var title="">id</var>, throw a <code>DATAGRID_MODEL_ERR</code>
+   exception and abort these steps.</p></li>
 
+   <li>
+
+    <p>If <var title="">type</var> is not a string equal to one of the
+    <span>allowed <code>datagrid</code> column types</span>, then
+    throw a <code>DATAGRID_MODEL_ERR</code> exception and abort these
+    steps.</p>
+
+   </li>
+
+   <li><p>If the <var title="">icon</var> argument is present and not
+   null, and the given <code>img</code> element's <code
+   title="dom-img-complete">complete</code> attribute is false, then
+   throw an <code>INVALID_STATE_ERR</code> exception and abort these
+   steps.</p></li>
+
+   <li><p>If the <var title="">icon</var> argument is present and not
+   null, then copy the image data from that <code>img</code> element,
+   and let <var title="">image</var> be the copy of that image
+   data. Otherwise, let <var title="">image</var> be nothing.</p></li>
+
+   <li><p>Append a new entry to the <span>column list</span>, with
+   <var title="">id</var> as its identifier, <var title="">label</var>
+   as its label, <var title="">type</var> as its type, and <var
+   title="">image</var> as its icon. Let the column be sortable if the
+   <var title="">sortable</var> argument is present and true, and make
+   it visible if the <var title="">visible</var> argument is absent or
+   true.</p></li>
+
+   <li><p>If the <span>column list</span> contains the <span>default
+   column</span>, then remove the <span>default column</span> from the
+   <span>column list</span>, discard any data for cells in that column
+   in any rows in the <code>datagrid</code>, set <code
+   title="dom-datagrid-sortColumn">sortColumn</code> to <var
+   title="">id</var>, set <code
+   title="dom-datagrid-sortAscending">sortAscending</code> to true,
+   and run the <span><code>datagrid</code> resort
+   steps</span>.</p></li>
+
+  </ol>
+
+  <hr>
+
+  <p>The <dfn
+  title="dom-datagrid-sortColumn"><code>sortColumn</code></dfn> DOM
+  attribute gives the current column used for sorting.  Initially, its
+  value must be the empty string. On getting, it must return its
+  current value. On setting, if the new value doesn't match the
+  identifier of one of the columns in the <span>column list</span>,
+  then the user agent must throw a <code>DATAGRID_MODEL_ERR</code>
+  exception. Otherwise, if the new value is not the same as its
+  current value, then the user agent must set the attribute to the new
+  value, and then run the <span><code>datagrid</code> resort
+  steps</span>.</p>
+
+  <p>The <dfn
+  title="dom-datagrid-sortAscending"><code>sortAscending</code></dfn>
+  DOM attribute specifies the direction that the tree is sorted in,
+  ascending (true) or descending (false). Initially, its value must be
+  true (ascending). On getting, it must return its current value. On
+  setting, if the new value is not the same as its current value, then
+  the user agent must set the attribute to the new value, and then run
+  the <span><code>datagrid</code> resort steps</span>.</p>
+
+  <p>When a column is marked as being sortable, the user agent should
+  allow the user to select that column to be the column used for
+  sorting, and should allow the user to chose whether the sort order
+  is ascending or descending.</p>
+
+  <p>When the user changes the sort order in this manner, the user
+  agent must update the <code
+  title="dom-datagrid-sortColumn">sortColumn</code> and <code
+  title="dom-datagrid-sortAscending">sortAscending</code> attributes
+  appropriately, and then run the <span><code>datagrid</code> resort
+  steps</span>.</p>
+
+  <p class="note">The <span><code>datagrid</code> resort steps</span>
+  are described in the next section.</p>
+
+  <hr>
+  
+  <p>The <dfn
+  title="dom-datagrid-clearColumns"><code>clearColumns()</code></dfn>
+  method, if the <span>column list</span> doesn't contain the
+  <span>default column</span>, must empty the <span>column
+  list</span>, append the <span>default column</span> to the now empty
+  <span>column list</span>, discard any data for cells in all rows in
+  the <code>datagrid</code>, set <code
+  title="dom-datagrid-sortColumn">sortColumn</code> to the empty
+  string, set <code
+  title="dom-datagrid-sortAscending">sortAscending</code> to true, and
+  run the <span><code>datagrid</code> resort steps</span>. (If the
+  <span>column list</span> is already just the <span>default
+  column</span>, then the method does nothing.)</p>
+
+
+  <h6>The rows</h6>
+
+  <p>A <code>datagrid</code> element is intended to show a
+  representation of a tree, where typically the user only sees a
+  small part of the tree at a time.</p>
+
+  <p>To make this efficent, the <code>datagrid</code> element
+  <em>actually</em> shows a small part of a <em>sparse</em> tree, so
+  that only relevant parts of the data structure need be loaded at any
+  time. Specifically, the model requires only that all the ancestor
+  rows of the displayed rows be loaded, as well as any open earlier
+  siblings (in the displayed sort order) of the displayed rows.</p>
+
+  <p>Conceptually, therefore, a <code>datagrid</code> has a number of
+  related sparse data structures backing it.</p>
+
+  <p>The first is the <dfn>natural order sparse data tree</dfn>. This
+  is the structure in which rows are entered as they are declared, in
+  their natural order. This can differ from the order actually
+  displayed to the user. It consists of nested sparse lists of
+  rows. In the <span>natural order sparse data tree</span>, a row will
+  always have all its parents already declared. Once a row is added to
+  this structure, it can only be removed by the <code
+  title="dom-datagrid-deleteRows">deleteRows()</code> and <code
+  title="dom-datagrid-clearRows">clearRows()</code> methods. The order of
+  nodes in this tree never changes; to move a node in this tree, it
+  has to be removed and then another row (with the same data)
+  reinserted elsewhere.</p>
+
+  <p>The second structure is the <dfn>display order sparse data
+  tree</dfn>. This is a similar structure that contains a subset of
+  the rows in the <span>natural order sparse data tree</span>, ordered
+  in the order given by the <code
+  title="dom-datagrid-sortAscending">sortAscending</code> and <code
+  title="dom-datagrid-sortColumn">sortColumn</code> attributes, and
+  excluding rows with one or more ancestors that are closed. This tree
+  is cleared whenever the <code
+  title="dom-datagrid-sortAscending">sortAscending</code> and <code
+  title="dom-datagrid-sortColumn">sortColumn</code> attributes
+  change.</p>
+
+  <p>The third structure is the <dfn>display order sparse data
+  list</dfn>. This structure is a flattened representation of the
+  <span>display order sparse data tree</span>.</p>
+
+  <p>At any time, a number of consecutive rows in the <span>display
+  order sparse data list</span> are physically visible to the
+  user. The <code>datagrid</code> fires notifications to a <span
+  title="dom-datagrid-listener">listener</span> (provided by script),
+  and the listener, or other some script, is expected to feed the
+  <code>datagrid</code> with the information needed to render the
+  control.</p>
+
+  <p>A <code>datagrid</code> has a <dfn>pending <code>datagrid</code>
+  rows list</dfn>, which is a list of rows in the <span>display order
+  sparse data list</span> for which the <code>datagrid</code> has sent
+  notifications requesting information but not yet received
+  information about.</p>
+
+  <p>A <code>datagrid</code> also has a <dfn>pending
+  <code>datagrid</code> <em>cells</em> list</dfn>, which is a list of
+  row/column pairs (cells) for which the <code>datagrid</code> has
+  sent notifications requesting information but not yet received
+  information about.</p>
+
+  <p>User agents may discard information about rows that are not
+  displayed and that are not ancestors or open earlier siblings of
+  rows or ancestors of rows that are displayed.</p>
+
+  <hr>
+
+  <p>These structures are different views of the collection of rows
+  that form the <code>datagrid</code>. Each row has the following
+  information associated with it:</p>
+
+  <dl>
+
+   <dt>A parent</dt>
+
+   <dd><p>Either another row, or the <code>datagrid</code> itself. This
+   is the parent of the row in the <span>natural order sparse data
+   tree</span> and the <span>display order sparse data tree</span>
+   for the <code>datagrid</code>.</p></dd>
+
+   <dt>A natural order position relative to the other rows with the
+   same parent</dt>
+
    <dd>
 
-    <p><strong><code
-    title="dom-provider-getRowCount">getRowCount(<var title="">row</var>)</code></strong>:
-    The number of rows returned by the default data provider for the
-    root of the tree (when <var title="">row</var> is empty) must be the total number of <code>tr</code> elements
-    that are children of <code>tbody</code> elements that are children
-    of the <code>table</code>, if there are any such child
-    <code>tbody</code> elements. If there are no such
-    <code>tbody</code> elements then the number of rows returned for
-    the root must be the number of <code>tr</code> elements that are
-    children of the <code>table</code>.</p>
+    <p>This is the number of rows that precede this row under the same
+    parent in the <span>natural order sparse data tree</span>. This
+    number can't be changed relative to other rows in the same parent;
+    to change the relative natural order of data in the
+    <code>datagrid</code>, the original rows have to be removed and
+    new rows (with the same data but different natural positions)
+    inserted in their place. (The exact number of a row can change, as
+    new rows can be inserted above it.)</p>
 
-    <p>When <var title="">row</var> is not empty, the number of rows
-    returned must be zero.</p>
+    <p>A row can be identified by a <code>RowID</code> object. This is
+    an array of numbers, consisting of the natural order positions of
+    each ancestor row and the row itself, starting from the furthest
+    ancestor. Thus, for instance, the fourth child row of the first
+    child row of the second row in a <code>datagrid</code> would be
+    identified by a <code>RowID</code> object whose value is <code
+    title="">[1, 0, 3]</code>. A row's identifier changes if rows are
+    <span title="dom-datagrid-insertRows">inserted before it</span> in
+    the <code>datagrid</code>.</p>
 
-    <p class="note">The <code>table</code>-based default data provider
-    cannot represent a tree.</p>
+   </dd>
 
-    <p class="note">Rows in <code>thead</code> elements do not
-    contribute to the number of rows returned, although they do affect
-    the columns and column captions. Rows in <code>tfoot</code>
-    elements are <span title="ignore">ignored</span> completely by
-    this algorithm.</p>
+   <dt>A display order position relative to the other rows with
+   the same parent</dt>
 
-    <p id="defaultDataProviderTableMapper"><strong><code
-    title="dom-provider-getChildAtPosition">getChildAtPosition(<var
-    title="">row</var>, <var title="">i</var>)</code></strong>: The
-    default data provider must return the mapping appropriate to the
-    <a href="#defaultDataProviderTableSort">current sort
-    order</a>.</p>
+   <dd><p>This is the number of rows that precede this row under the
+   same parent in the <span>display order sparse data
+   tree</span>. This number can be unknown. If the sort order
+   changes, then this information is lost (as the <span>display order
+   sparse data tree</span> is cleared).</p></dd>
 
-    <p><strong><code
-    title="dom-provider-getColumnCount">getColumnCount()</code></strong>:
-    The number of columns returned must be the number of
-    <code>td</code> element children in the first <code>tr</code>
-    element child of the first <code>tbody</code> element child of the
-    <code>table</code>, if there are any such <code>tbody</code>
-    elements. If there are no such <code>tbody</code> elements, then
-    it must be the number of <code>td</code> element children in the
-    first <code>tr</code> element child of the <code>table</code>, if
-    any, or otherwise 1. If the number that would be returned by these
-    rules is 0, then 1 must be returned instead.</p>
+   <dt>A child count</dt>
 
-    <p><strong><code
-    title="dom-provider-getCaptionText">getCaptionText(<var
-    title="">i</var>)</code></strong>: If the <code>table</code> has
-    no <code>thead</code> element child, or if its first
-    <code>thead</code> element child has no <code>tr</code> element
-    child, the default data provider must return the empty string for
-    all captions. Otherwise, the value of the <code>textContent</code>
-    attribute of the <var title="">i</var>th <code>th</code> element
-    child of the first <code>tr</code> element child of the first
-    <code>thead</code> element child of the <code>table</code> element
-    must be returned. If there is no such <code>th</code> element, the
-    empty string must be returned.</p>
+   <dd><p>The number of rows that have this row as a parent. If this is
+   zero, the row cannot be opened. If this is &#x2212;1, then the
+   child count is unknown but the row can be opened. This value can be
+   changed by the <code title="dom-datagrid-setRows">setRows()</code>
+   method only if the current value is &#x2212;1 or if the row or one
+   of its ancestors is closed. Otherwise, it can only be changed
+   indirectly using the <code
+   title="dom-datagrid-insertRows">insertRows()</code> and <code
+   title="dom-datagrid-deleteRows">deleteRows()</code> methods.</p></dd>
 
-    <p><strong><code
-    title="dom-provider-getCaptionClasses">getCaptionClasses(<var
-    title="">i</var>, <var title="">classes</var>)</code></strong>: If
-    the <code>table</code> has no <code>thead</code> element child, or
-    if its first <code>thead</code> element child has no
-    <code>tr</code> element child, the default data provider must not
-    add any classes for any of the captions. Otherwise, each class
-    in the <code title="attr-class">class</code> attribute of the <var
-    title="">i</var>th <code>th</code> element child of the first
-    <code>tr</code> element child of the first <code>thead</code>
-    element child of the <code>table</code> element must be added to
-    the <var title="">classes</var>. If there is no such
-    <code>th</code> element, no classes must be added. The user agent
-    must then:</p>
+   <dt>An open flag</dt>
 
+   <dd><p>A boolean indicating whether the row is open (true) or
+   closed (false). Once set, can only be changed by the user or if one
+   of the row's ancestors is itself closed. A row can also be in a
+   third state, "opening", which is treated as closed for all purposes
+   except that the user agent may indicate that the row is in this
+   special state, and except that when the row is updated to have a
+   row count, the row will switch to being open.</p></dd>
+
+   <dt>A row count</dt>
+
+   <dd><p>The number of rows that have this row as a parent or
+   ancestor, and that do not have an ancestor that is a descendant of
+   this row that is itself closed. If this is &#x2212;1, then the row
+   count is unknown. This value can be changed by the <code
+   title="dom-datagrid-setRows">setRows()</code> method only if the
+   row or one of its ancestors is closed (or opening, but not
+   open). Otherwise, it can only be changed indirectly using the <code
+   title="dom-datagrid-insertRows">insertRows()</code> and <code
+   title="dom-datagrid-deleteRows">deleteRows()</code>
+   methods.</p></dd>
+
+   <dt>Cells</dt>
+
+   <dd><p>The data that applies to this row. Cell data is discussed in
+   more detail below.</p></dd>
+
+  </dl>
+
+  <p>The <code>datagrid</code> itself also has a <dfn title="datagrid
+  child count">child count</dfn> and a <dfn title="datagrid row
+  count">row count</dfn>, which are analogous to the child counts and
+  row counts for rows. Initially these must be zero.</p>
+
+  <hr>
+
+  <p>The <dfn><code>datagrid</code> resort steps</dfn>, which are
+  invoked when the sort order changes as described in the previous
+  section, are as follows:</p>
+
+  <ol>
+
+   <li>
+
+    <p>Clear the <span>display order sparse data tree</span>
+    (i.e. mark the display order position of all the rows in the
+    <code>datagrid</code> as unknown).</p>
+
+    <p>User agents may cache the position information of rows for
+    various values of <code
+    title="dom-datagrid-sortColumn">sortColumn</code> and <code
+    title="dom-datagrid-sortAscending">sortAscending</code>, instead
+    of discarding the information altogether. If the user agent caches
+    this information, and has information that applies to the current
+    values of <code title="dom-datagrid-sortColumn">sortColumn</code>
+    and <code title="dom-datagrid-sortAscending">sortAscending</code>,
+    then the user agent may repopulate the <span>display order sparse
+    data tree</span> from this information.</p>
+
+   </li>
+
+   <li>
+
+    <p>Clear the <span>pending <code>datagrid</code> rows list</span>
+    and the <span>pending <code>datagrid</code> cells list</span>.</p>
+
+   </li>
+
+   <li>
+
+    <p>Invoke the <span><code>datagrid</code> update display
+    algorithm</span>.</p>
+
+   </li>
+
+   <!-- v2: queue a task to fire an event, or tell the listener the
+   sort order changed, or something -->
+
+  </ol>
+
+  <hr>
+
+  <p>The <dfn
+  title="dom-datagrid-renotify"><code>renotify()</code></dfn> method
+  must empty the <span>pending <code>datagrid</code> rows list</span>
+  and the <span>pending <code>datagrid</code> cells list</span>, and
+  invoke the <span><code>datagrid</code> update display
+  algorithm</span>.</p>
+
+  <hr>
+
+  <p>The <dfn title="dom-datagrid-setRowCount"><code>setRowCount(<var
+  title="">childCount</var>, <var
+  title="">rowCount</var>)</code></dfn> method must run the following
+  steps:</p>
+
+  <ol>
+
+   <li>
+
+    <p>Set the <span><code>datagrid</code> child count</span> to <var
+    title="">childCount</var>, the <span><code>datagrid</code> row
+    count</span> to <var title="">rowCount</var>.</p>
+
+   </li>
+
+   <li>
+
+    <p><span>Audit the <code>datagrid</code></span>. If this fails,
+    then revert the changes made in the previous step, throw a
+    <code>DATAGRID_MODEL_ERR</code> exception, and abort these
+    steps.</p>
+
+   </li>
+
+   <li>
+
+    <p>Invoke the <span><code>datagrid</code> update display
+    algorithm</span>.</p>
+
+   </li>
+
+  </ol>
+
+  <hr>
+
+  <p>The <dfn title="dom-datagrid-setRows"><code>setRows(<var
+  title="">rows</var>)</code></dfn> method must run the following
+  steps:</p>
+
+  <ol>
+
+   <li>
+
+    <p><span title="type-check a RowList object">Type-check the <var
+    title="">rows</var> argument</span>. If this fails, throw a
+    <code>TypeError</code> exception, and abort these steps.</p>
+
+   </li>
+
+   <li>
+
+    <p><span title="partially sort a RowList object">Partially sort
+    the <var title="">rows</var> argument</span>.</p>
+
+   </li>
+
+   <li>
+
+    <p>For each <code>Row</code> object in the <var
+    title="">rows</var> argument, in order, perform the appropriate
+    steps from the list below.</p>
+
+    <p class="note">The changes made to the <code>datagrid</code>'s
+    data structures in this step get reverted (as required below) if
+    any consistency errors are detected either in this step or the
+    next.</p>
+
+    <dl>
+
+     <dt>If there already exists a row in the <code>datagrid</code>'s
+     <span>natural order sparse data tree</span> with the same
+     identifier as given by the <code>Row</code> object's
+     <code>RowID</code> object, and that row and all its ancestors are
+     open</dt>
+
+     <dd>
+
+      <p>If one of the following conditions is true, then revert all
+      the changes done in this step, throw a
+      <code>DATAGRID_MODEL_ERR</code> exception, and abort these
+      steps:</p>
+
+      <ul>
+
+       <li>The value of the <code>Row</code> object's second entry is
+       neither &#x2212;1 nor equal to the child count of the
+       preexisting row.</li>
+
+       <li>The <code>Row</code> object has fewer than five entries, or
+       its fifth entry is false.</li>
+
+       <li>The <code>Row</code> object has fewer than six entries, or
+       its sixth entry is not equal to the row count of the
+       preexisting row.</li>
+
+      </ul>
+
+     </dd>
+
+     <dt>If there already exists a row in the <code>datagrid</code>'s
+     <span>natural order sparse data tree</span> with the same
+     identifier as given by the <code>Row</code> object's
+     <code>RowID</code> object, but either that row or one of its
+     ancestors is closed</dt>
+
+     <dd>
+
+      <p>Set the preexisting row's child count to the value of the
+      <code>Row</code> object's second entry.</p>
+
+      <p>If the <code>Row</code> object has five or more entries, and
+      either its fifth entry is true and the preexisting row is closed
+      but not opening, or its fifth entry is false and the preexisting
+      row is open, then: if the preexisting row has no ancestor row
+      that is closed, then revert all the changes done in this step,
+      throw a <code>DATAGRID_MODEL_ERR</code> exception, and abort
+      these steps; otherwise, if the fifth entry is false, then close
+      the row; otherwise, open the row.</p>
+
+      <p>If the <code>Row</code> object has six entries, set the
+      preexisting row's row count to the value of the <code>Row</code>
+      object's sixth entry.</p>
+
+      <p>If the preexisting row is opening, then: increase the
+      <span><code>datagrid</code> row count</span> and the row counts
+      of any ancestor rows by the number of rows that the preexisting
+      row now has in its row count, then open the row.</p> <!-- we
+      should also "update the <span>pending <code>datagrid</code> rows
+      list</span> and the <span>pending <code>datagrid</code> cells
+      list</span> accordingly" -->
+
+
+     </dd>
+
+     <dt>There does not exist a row in the <code>datagrid</code>'s
+     <span>natural order sparse data tree</span> with the same
+     identifier as given by the <code>Row</code> object's
+     <code>RowID</code> object</dt>
+
+     <dd>
+
+      <p>If the <code>RowID</code> object has a length greater than 1,
+      then verify that there is a row identified by the
+      <code>RowID</code> consisting of all but the last number in the
+      <code>Row</code> object's <code>RowID</code>. If there is no
+      such row present in the <span>natural order sparse data
+      tree</span>, then revert all the changes done in this step,
+      throw a <code>DATAGRID_MODEL_ERR</code> exception, and abort
+      these steps.</p>
+
+      <p>Create a row and insert it into the <span>natural order
+      sparse data tree</span>, such that its parent is the row
+      identified by the <code>RowID</code> consisting of all but the
+      last number in the <code>Row</code> object's <code>RowID</code>,
+      or the <code>datagrid</code> if the lenght of the
+      <code>Row</code> object's <code>RowID</code> is 1; with its
+      natural order position being the last number of the
+      <code>Row</code> object's <code>RowID</code>; with the child
+      count being the value of the third entry of the <code>Row</code>
+      object; with the row being marked closed unless the
+      <code>Row</code> object has five or more entries and its fifth
+      entry is true, in which case the row is open; and with its row
+      count being &#x2212;1 unless the <code>Row</code> object has six
+      entries, in which case the row count is equal to the value of
+      the <code>Row</code> object's sixth entry.</p>
+
+     </dd>
+
+    </dl>
+
+   </li>
+
+   <li>
+
+    <p><span>Audit the <code>datagrid</code></span>. If this fails,
+    then revert the changes made in the previous step, throw a
+    <code>DATAGRID_MODEL_ERR</code> exception, and abort these
+    steps.</p>
+
+   </li>
+
+   <li>
+
+    <p>For each <code>Row</code> object in the <var
+    title="">rows</var> argument, in order, <span title="apply a Row
+    object">apply the <code>Row</code> object</span>.</p>
+
+   </li>
+
+   <li>
+
+    <p>Invoke the <span><code>datagrid</code> update display
+    algorithm</span>.</p>
+
+   </li>
+
+  </ol>
+
+  <hr>
+
+  <p>The <dfn title="dom-datagrid-insertRows"><code>insertRows(<var
+  title="">rows</var>)</code></dfn> method must run the following
+  steps:</p>
+
+  <ol>
+
+   <li>
+
+    <p><span title="type-check a RowList object">Type-check the <var
+    title="">rows</var> argument</span>. If this fails, throw a
+    <code>TypeError</code> exception, and abort these steps.</p>
+
+   </li>
+
+   <li>
+
+    <p><span title="partially sort a RowList object">Partially sort
+    the <var title="">rows</var> argument</span>.</p>
+
+   </li>
+
+   <li>
+
+    <p>For each <code>Row</code> object in the <var
+    title="">rows</var> argument, in order, run the following
+    steps:</p>
+
+    <p class="note">The changes made to the <code>datagrid</code>'s
+    data structures in this step get reverted (as required below) if
+    any consistency errors are detected either in this step or the
+    next.</p>
+
     <ol>
 
-     <li>Remove the <code
-     title="datagrid-column-class-sorted">sorted</code> and <code
-     title="datagrid-column-class-reversed">reversed</code>
-     classes.</li>
+     <li>
 
-     <li>If the <code>table</code> element has a <code
-     title="attr-class">class</code> attribute that includes the <code
-     title="">sortable</code> class, add the <code
-     title="datagrid-column-class-sortable">sortable</code>
-     class.</li>
+      <p>Let <var title="">parent</var> be the row identified by the
+      <code>RowID</code> consisting of all but the last number in the
+      <code>Row</code> object's <code>RowID</code>, or the
+      <code>datagrid</code> itself it the <code>Row</code> object's
+      <code>RowID</code> has length 0.</p>
 
-     <li>If the column is the one currently being used to
-     sort the data, add the <code
-     title="datagrid-column-class-sorted">sorted</code> class.</li>
+      <p>If there is no such row present in the <span>natural order
+      sparse data tree</span>, then revert all the changes done in
+      this algorithm, throw a <code>DATAGRID_MODEL_ERR</code>
+      exception, and abort these steps.</p>
 
-     <li>If the column is the one currently being used to sort the
-     data, and it is sorted in descending order, add the <code
-     title="datagrid-column-class-reversed">reversed</code> class as
-     well.</li>
+     </li>
 
+     <li>
+
+      <p>Increment by one the natural order position of all rows whose
+      parent is <var title="">parent</var> and whose natural order
+      position is equal to or greater than the last number of the
+      <code>Row</code> object's <code>RowID</code>.</p>
+
+     </li>
+
+     <li>
+
+      <p>If the value of the <code>Row</code> object's second entry is
+      not &#x2212;1, then increment by one the display order position
+      of all rows whose parent is <var title="">parent</var> and whose
+      display order position is equal to or greater than the value of
+      the <code>Row</code> object's second entry.</p>
+
+     <!--(Not sure how to really say this.)
+      <p>Update the <span>pending <code>datagrid</code> rows
+      list</span> and the <span>pending <code>datagrid</code> cells
+      list</span> accordingly.</p>
+     -->
+
+     </li>
+ 
+     <li>
+
+      <p>Create a row and insert it into the <span>natural order
+      sparse data tree</span>, such that its parent is <var
+      title="">parent</var>; with its natural order position being the
+      last number of the <code>Row</code> object's <code>RowID</code>;
+      with the child count being the value of the third entry of the
+      <code>Row</code> object; with the row being marked closed unless
+      the <code>Row</code> object has five or more entries and its
+      fifth entry is true, in which case the row is open; and with its
+      row count being &#x2212;1 unless the <code>Row</code> object has
+      six entries, in which case the row count is equal to the value
+      of the <code>Row</code> object's sixth entry.</p>
+
+     </li>
+
     </ol>
 
-    <p>The various row- and cell- related methods operate relative to
-    a particular element, the element of the row or cell specified by
-    their arguments.</p>
+   </li>
 
-    <p><strong>For rows</strong>: Since the default data provider for
-    a <code>table</code> 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 <var title="">i</var>.</p>
+   <li>
 
-    <p>If the <code>table</code> has <code>tbody</code> element
-    children, the element for the <var title="">i</var>th row is the
-    <var title="">i</var>th <code>tr</code> element that is a child of
-    a <code>tbody</code> element that is a child of the
-    <code>table</code> element. If the <code>table</code> does not
-    have <code>tbody</code> element children, then the element for the
-    <var title="">i</var>th real row is the <var title="">i</var>th
-    <code>tr</code> element that is a child of the <code>table</code>
-    element.</p>
+    <p>For each <code>Row</code> object in the <var
+    title="">rows</var> argument, in order, <span title="apply a Row
+    object">apply the <code>Row</code> object</span>.</p>
 
-    <p><strong>For cells</strong>: Given a row and its element, the
-    row's <var title="">i</var>th cell's element is the <var
-    title="">i</var>th <code>td</code> element child of the row
-    element.</p>
+   </li>
 
-    <p class="note">The <code>colspan</code> and <code>rowspan</code>
-    attributes are <span title="ignore">ignored</span> by this
-    algorithm.</p>
+   <li>
 
-    <p><strong><code title="dom-provider-getRowImage">getRowImage(<var
-    title="">i</var>)</code></strong>: The <span>URL</span> of the
-    row's image is the <span>absolute URL</span> obtained by <span
-    title="resolve a url">resolving</span> the value of the <code
-    title="attr-img-src">src</code> attribute of the first
-    <code>img</code> element child of the row's first cell's element,
-    relative to that element, if there is one and resolving its
-    attribute is successful. Otherwise, the <span>URL</span> of the
-    row's image is the empty string.</p> <!-- note that if the base
-    URL has changed, this URL can be different than the one that the
-    <img> element fetched when it was created -->
+    <p>Invoke the <span><code>datagrid</code> update display
+    algorithm</span>.</p>
 
-    <p><strong><code title="dom-provider-getRowMenu">getRowMenu(<var
-    title="">i</var>)</code></strong>: If the row's first cell's
-    element has a <code>menu</code> element child, then the row's menu
-    is the first <code>menu</code> element child of the row's first
-    cell's element. Otherwise, the row has no menu.</p>
+   </li>
 
-    <p><strong><code
-    title="dom-provider-getRowClasses">getRowClasses(<var
-    title="">i</var>, <var title="">classes</var>)</code></strong>:
-    The default data provider must never add a class to the row's
-    classes.</p>
+  </ol>
 
-    <p id="defaultDataProviderTableSort"><strong><code
-    title="dom-provider-toggleColumnSortState">toggleColumnSortState(<var
-    title="">i</var>)</code></strong>: 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.)</p>
+  <hr>
 
-    <p>When the sort mapping is changed, the values returned by the
-    <code
-    title="dom-provider-getChildAtPosition">getChildAtPosition()</code>
-    method for the default data provider <a
-    href="#defaultDataProviderTableMapper">will change
-    appropriately</a>.</p>
+  <p>When an algorithm requires the user agent to <dfn>type-check a
+  <code>RowList</code> object</dfn> (an array), each entry in the
+  object must be checked against the following requirements. If any
+  are false, then the type-check fails, otherwise it passes.</p>
 
-    <p><strong><code title="dom-provider-getCellData">getCellData(<var
-    title="">i</var>, <var title="">j</var>)</code>, <code
-    title="dom-provider-getCellClasses">getCellClasses(<var
-    title="">i</var>, <var title="">j</var>, <var
-    title="">classes</var>)</code>, <code
-    title="dom-provider-setCellCheckedState">getCellCheckedState(<var
-    title="">i</var>, <var title="">j</var>, <var
-    title="">state</var>)</code>, <code
-    title="dom-provider-cycleCell">cycleCell(<var title="">i</var>,
-    <var title="">j</var>)</code>, and <code
-    title="dom-provider-editCell">editCell(<var title="">i</var>,
-    <var title="">j</var>, <var title="">data</var>)</code></strong>:
-    See <a href="#commonDefaultDataGridMethodDefinitions">the common
-    definitions below</a>.</p>
+  <ul>
 
-    <p>The data provider must call the <code>datagrid</code>'s update
-    methods appropriately whenever the descendants of the
-    <code>datagrid</code> mutate. For example, if a <code>tr</code> is
-    removed, then the <code
-    title="dom-datagrid-updateRowsRemoved">updateRowsRemoved()</code>
-    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
-    <code>table</code> element stops being the first child of the
-    <code>datagrid</code>, then the data provider must call the <code
-    title="dom-datagrid-updateEverything">updateEverything()</code>
-    method on the <code>datagrid</code>. 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 <code
-    title="dom-datagrid-updateEverything">updateEverything()</code> if
-    the change did affect the sort order.</p>
+   <li><p>The entry is a <code>Row</code> object (an
+   array).</p></li>
 
-   </dd>
+   <li><p>The first value in the <code>Row</code> is a
+   <code>RowID</code> object (also an array), whose length is at least
+   1, and whose values are all integers greater than or equal to
+   zero.</p></li>
 
+   <li><p>The numbers in the <code>RowID</code> object do not exactly
+   match any of the other entries in the <code>RowList</code> object
+   (i.e. no two <code>Row</code> objects have the same
+   identifier).</p></li>
 
-   <dt>While the first element child is a <code>select</code> or <code>datalist</code> element</dt>
+   <li><p>The second value in the <code>Row</code> is an integer that
+   is either &#x2212;1, zero, or a positive integer.</p></li>
 
-   <dd>
+   <li><p>The third value in the <code>Row</code> is an integer that
+   is either &#x2212;1, zero, or a positive integer.</p></li>
 
-    <p>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.</p>
+   <li><p>The fourth value in the <code>Row</code> is a
+   <code>CellList</code> object (yet another array).</p></li>
 
-    <p>For the rows, assume the existence of a node filter view of the
-    descendants of the first element child of the
-    <code>datagrid</code> element (the <code>select</code> or
-    <code>datalist</code> element), that skips all nodes other than
-    <code>optgroup</code> and <code>option</code> elements, as well as
-    any descendants of any <code>option</code> elements.</p>
+   <li><p>Each entry in the <span>CellList</span> object is a
+   <code>Cell</code> object (again, an array).</p></li>
 
-    <p>Given a path <var title="">row</var>, the corresponding element
-    is the one obtained by drilling into the view, taking the child
-    given by the path each time.</p>
+   <li><p>Each <code>Cell</code> object in the <span>CellList</span>
+   object has as its first value a <code>Column</code> object (a
+   string), and its value is the identifier of one of the columns in
+   the <span>column list</span>.</p></li>
 
-    <div class="example">
+   <li>
 
-     <p>Given the following XML markup:</p>
+    <p>Each <code>Cell</code> object in the <span>CellList</span>
+    object has as its second and subsequent entries values that match
+    the following requirements, as determined by the type of the
+    column identified by the first entry:</p>
 
-     <pre><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></pre>
+    <dl>
 
-     <p>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.</p>
+     <dt>If the column's type is <code title="datagrid-type-text">text</code></dt>
+     <dd>
 
-    </div>
+      <p>The second entry's value is a string, and either there are
+      only two entries, or there are three, and the third entry is
+      an <code>img</code> element.</p>
 
-    <p><code title="dom-provider-getRowCount">getRowCount(<var
-    title="">row</var>)</code> 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 <var title="">row</var> is empty, the
-    corresponding element is the <code>select</code> element at the
-    root of the filtered view.)</p>
+      <p>If there is an <code>img</code> element specified, its <code
+      title="dom-img-complete">complete</code> attribute is true.</p>
 
-    <p><code
-    title="dom-provider-getChildAtPosition">getChildAtPosition(<var
-    title="">row</var>, <var title="">position</var>)</code> must
-    return <var title="">position</var>. (The
-    <code>select</code>/<code>datalist</code> default data provider
-    does not support sorting the data grid.)</p>
+     </dd>
 
-    <p><code title="dom-provider-getRowImage">getRowImage(<var
-    title="">i</var>)</code> must return the empty string, <code
-    title="dom-provider-getRowMenu">getRowMenu(<var
-    title="">i</var>)</code> must return null.</p>
+     <dt>If the column's type is <code title="datagrid-type-editable">editable</code></dt>
+     <dd>
 
-    <p><code title="dom-provider-getRowClasses">getRowClasses(<var
-    title="">row</var>, <var title="">classes</var>)</code> must add the
-    classes from the following list to <var title="">classes</var>
-    when their condition is met:</p>
+      <p>The second entry's value is a string, and either there are
+      only two entries, or the third entry is a
+      <code>datalist</code> element, and either there are only three
+      entries, or there are four, and the fourth entry is an
+      <code>img</code> element.</p>
 
-    <ul>
+      <p>If there is an <code>img</code> element specified, its <code
+      title="dom-img-complete">complete</code> attribute is true.</p>
 
-     <li>If the <var title="">row</var>'s corresponding element is an
-     <code>optgroup</code> element: <code
-     title="datagrid-row-class-header">header</code></li>
+     </dd>
 
-     <li>If the <var title="">row</var>'s corresponding element
-     contains other elements that are also in the view, and the
-     element's <code title="attr-class">class</code> attribute
-     contains the <code title="">closed</code> class: <code
-     title="datagrid-row-class-initially-closed">initially-closed</code></li>
+     <dt>If the column's type is <code title="datagrid-type-checkable">checkable</code></dt>
+     <dd>
 
-     <li>If the <var title="">row</var>'s corresponding element
-     contains other elements that are also in the view, and the
-     element's <code title="attr-class">class</code> attribute
-     contains the <code title="">open</code> class: <code
-     title="datagrid-row-class-initially-open">initially-open</code></li>
+      <p>The second entry's value is a string, the third entry is a
+      boolean, and either there are only three entries, or the
+      fourth entry is also a boolean, and either there are only four
+      entries, or there are five, and the fifth entry is an
+      <code>img</code> element.</p>
 
-    </ul>
+      <p>If there is an <code>img</code> element specified, its <code
+      title="dom-img-complete">complete</code> attribute is true.</p>
 
-    <p>The <code title="dom-provider-getCellData">getCellData(<var
-    title="">row</var>, <var title="">cell</var>)</code> method must
-    return the value of the <code
-    title="attr-optgroup-label">label</code> attribute if the <var
-    title="">row</var>'s corresponding element is an
-    <code>optgroup</code> element, otherwise, if the <var
-    title="">row</var>'s corresponding element is an
-    <code>option</code>element, its <code
-    title="attr-option-label">label</code> attribute if it has one,
-    otherwise the value of its <code>textContent</code> DOM
-    attribute.</p>
+     </dd>
 
-    <p>The <code
-    title="dom-provider-getCellClasses">getCellClasses(<var
-    title="">row</var>, <var title="">cell</var>, <var
-    title="">classes</var>)</code> method must add no classes.</p>
+     <dt>If the column's type is <code title="datagrid-type-list">list</code></dt>
+     <dd>
 
-    <p class="XXX"><!-- select-provider-selection
-    XXX-->autoselect some rows when initialized, reflect the selection
-    in the select, reflect the multiple attribute somehow.</p>
+      <p>The second entry's value is a string, the third entry is a
+      <code>select</code> element, and either there are only three
+      entries, or there are four, and the fourth entry is an
+      <code>img</code> element.</p>
 
-    <p>The data provider must call the <code>datagrid</code>'s update
-    methods appropriately whenever the descendants of the
-    <code>datagrid</code> mutate.</p>
+      <p>If there is an <code>img</code> element specified, its <code
+      title="dom-img-complete">complete</code> attribute is true.</p>
 
-   </dd>
+     </dd>
 
+     <dt>If the column's type is <code title="datagrid-type-progress">progress</code></dt>
+     <dd>
 
-   <dt>While the first element child is another element</dt>
+      <p>There are only two entries, the second entry's value is a
+      number, and the number's value is between 0.0 and 1.0
+      inclusive.</p>
 
-   <dd>
+     </dd>
 
-    <p>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.</p>
+     <dt>If the column's type is <code title="datagrid-type-meter">meter</code></dt>
+     <dd>
 
-    <p>For the rows, assume the existence of a node filter view of the
-    descendants of the <code>datagrid</code> that skips all nodes
-    other than <code>li</code>, <code>h1</code>–<code>h6</code>, and
-    <code>hr</code> elements, and skips any descendants of
-    <code>menu</code> elements.</p>
+      <p>There are at least two, but possibly up to seven, entries,
+      all entries but the first one are numbers, and the following
+      relationships hold:</p>
 
-    <p>Given this view, each element in the view represents a row in
-    the data model. The element corresponding to a path <var
-    title="">row</var> 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.</p>
+      <ul class="brief">
 
-    <p><code title="dom-provider-getRowCount">getRowCount(<var
-    title="">row</var>)</code> 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 <var title="">row</var> is
-    empty.</p>
+       <li>The second entry is less than the third, or less than 1.0
+       if the third is absent.</li>
 
-    <div class="example">
+       <li>The second entry is greater than the fourth, or greater
+       than 0.0 if the fourth is absent.</li>
 
-     <p>In the following example, the elements are identified by the
-     paths given by their child text nodes:</p>
+       <li>If there are at least three entries, the third entry is
+       greater than the fourth, or greater than zero if the fourth
+       is absent.</li>
 
-     <pre><datagrid>
- <ol>
-  <li> row 0 </li>
-  <li> row 1
-   <ol>
-    <li> row 1,0 </li>
-   </ol>
-  </li>
-  <li> row 2 </li>
- </ol>
-</datagrid></pre>
+       <li>If there are at least five entries, the fifth is not
+       greater than the third and not less than the fourth.</li>
 
-     <p>In this example, only the <code>li</code> elements actually
-     appear in the data grid; the <code>ol</code> element does not
-     affect the data grid's processing model.</p>
+       <li>If there are at least six entries, the sixth is not
+       greater than the third and not less than the fifth.</li>
 
-    </div>
+       <li>If there are at least seven entries, the fifth is not
+       greater than the third and not less than the fourth.</li>
 
-    <p><code
-    title="dom-provider-getChildAtPosition">getChildAtPosition(<var
-    title="">row</var>, <var title="">position</var>)</code> must
-    return <var title="">position</var>. (The generic default data
-    provider does not support sorting the data grid.)</p>
+      </ul>
 
-    <p><code title="dom-provider-getRowImage">getRowImage(<var
-    title="">i</var>)</code> must return the <span>absolute URL</span>
-    obtained from <span title="resolve a url">resolving</span> the
-    value of the <code title="attr-img-src">src</code> attribute of
-    the first <code>img</code> 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
-    relative to the element itself, is successful. Otherwise, it must
-    return the empty string.</p> <!-- note that if the base URL has
-    changed, this URL can be different than the one that the <img>
-    element fetched when it was created -->
+     </dd>
 
-    <div class="example">
+     <dt>If the column's type is <code title="datagrid-type-custom">custom</code></dt>
+     <dd>
 
-     <p>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:</p>
+      <p>There are four entries, the second and third are numbers
+      that are integers greater than zero, and the fourth is a
+      <code>Rendering2DContextCallback</code> object (a
+      function).</p>
 
-     <pre><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></pre>
+     </dd>
 
-    </div>
+    </dl>
 
-    <p><code title="dom-provider-getRowMenu">getRowMenu(<var
-    title="">i</var>)</code> must return the first <code>menu</code>
-    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.)</p>
+   </li>
 
-    <p><code title="dom-provider-getRowClasses">getRowClasses(<var
-    title="">i</var>, <var title="">classes</var>)</code> must add the
-    classes from the following list to <var title="">classes</var>
-    when their condition is met:</p>
+   <li><p>Either there are only four values in the <code>Row</code>,
+   or the fifth value in the <code>Row</code> is a boolean.</p></li>
 
-    <ul>
+   <li><p>Either there are only four or five values in the
+   <code>Row</code>, or there are six, and the sixth value in the
+   <code>Row</code> an integer that is greater than or equal to
+   zero.</p></li>
 
-     <li>If the row's element contains other elements that are also in
-     the view, and the element's <code title="attr-class">class</code>
-     attribute contains the <code title="">closed</code> class: <code
-     title="datagrid-row-class-initially-closed">initially-closed</code></li>
+  </ul>
 
-     <li>If the row's element contains other elements that are also in
-     the view, and the element's <code title="attr-class">class</code>
-     attribute contains the <code title="">open</code> class: <code
-     title="datagrid-row-class-initially-open">initially-open</code></li>
+  <p>Where the above requirements say that a value is to be a string,
+  the user agent must apply the ToString() conversion operator to the
+  value, assume that the value was indeed a string, and use the result
+  in the rest of the algorithm as if it had that had been the value
+  passed to the method. <a href="#refsECMA262">[ECMA262]</a></p>
 
-     <li>If the row's element is an <code>h1</code>–<code>h6</code>
-     element: <code
-     title="datagrid-row-class-header">header</code></li>
+  <p>Where the above requirements say that a value is to be a number,
+  the user agent must first apply the ToNumber() conversion operator
+  to the value, and then verify that the result is neither the
+  not-a-number NaN value nor an infinite value. If this result is
+  indeed acceptable (i.e. finite), the user agent must use the result
+  in the rest of the algorithm as if it had that had been the value
+  passed to the method. <a href="#refsECMA262">[ECMA262]</a></p>
 
-     <li>If the row's element is an <code>hr</code> element: <code
-     title="datagrid-row-class-separator">separator</code></li> <!--
-     XXX no way to get selectable-separator -->
+  <p>Where the above requirements say that a value is to be an
+  integer, the user agent must first apply the ToNumber() conversion
+  operator to the value, and then verify that the result is a finite
+  integer. If so, the user agent must use the result in the rest of
+  the algorithm as if it had that had been the value passed to the
+  method. <a href="#refsECMA262">[ECMA262]</a></p>
 
-    </ul>
+  <p>Where the above requirements say that a value is to be a boolean,
+  the user agent must apply the ToBoolean() conversion operator to the
+  value, assume that the value was indeed a boolean, and use the
+  result in the rest of the algorithm as if it had that had been the
+  value passed to the method. <a href="#refsECMA262">[ECMA262]</a></p>
 
-    <p>The <code title="dom-provider-getCellData">getCellData(<var
-    title="">i</var>, <var title="">j</var>)</code>, <code
-    title="dom-provider-getCellClasses">getCellClasses(<var
-    title="">i</var>, <var title="">j</var>, <var
-    title="">classes</var>)</code>, <code
-    title="dom-provider-setCellCheckedState">getCellCheckedState(<var
-    title="">i</var>, <var title="">j</var>, <var
-    title="">state</var>)</code>, <code
-    title="dom-provider-cycleCell">cycleCell(<var title="">i</var>,
-    <var title="">j</var>)</code>, and <code
-    title="dom-provider-editCell">editCell(<var title="">i</var>, <var
-    title="">j</var>, <var title="">data</var>)</code> methods must
-    act as described in <a
-    href="#commonDefaultDataGridMethodDefinitions">the common
-    definitions below</a>, treating the row's element as being the
-    cell's element.</p>
+  <hr>
 
-    <p class="XXX" id="generic-provider-selection">selection
-    handling?</p>
+  <p>When an algorithm requires the user agent to <dfn>audit the
+  <code>datagrid</code></dfn>, the <code>datagrid</code> must be
+  checked against the following requirements. If any are false, then
+  the audit fails, otherwise it passes.</p>
 
-    <p>The data provider must call the <code>datagrid</code>'s update
-    methods appropriately whenever the descendants of the
-    <code>datagrid</code> mutate.</p>
+  <ul>
 
-   </dd>
+   <li>There is no row whose natural order position is greater than or
+   equal to the child count of its parent row in the <span>natural
+   order sparse data tree</span>.</li>
 
+   <li>There is no row whose display order position is greater than or
+   equal to the child count of its parent row in the <span>display
+   order sparse data tree</span>.</li>
 
-   <dt>Otherwise, while there is no element child</dt>
+   <li>There is no row such that the sum of that row's child count and
+   the row counts all the open rows that are direct children of that
+   row in the <span>natural order sparse data tree</span> is less than
+   that row's row count.</li>
 
-   <dd>
+   <li>Of the rows whose child count is equal to the number of rows
+   that are direct children of that row in the <span>natural order
+   sparse data tree</span>, there is none such that the sum of that
+   row's child count and the row counts of all the open rows that are
+   direct children of that row in the <span>natural order sparse data
+   tree</span> is greater than that row's row count.</li>
 
-    <p>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 <code>datagrid</code>'s child list changes such
-    that there is a first element child, then the data provider must
-    call the <code
-    title="dom-datagrid-updateEverything">updateEverything()</code>
-    method on the <code>datagrid</code>.</p>
+  </ul>
 
-   </dd>
+  <p>For the purposes of this audit, the <code>datagrid</code> must be
+  treated as the parent row of all the rows that are direct children
+  of the <code>datagrid</code> in the <span>natural order sparse data
+  tree</span> and the <span>display order sparse data tree</span>. The
+  child count of this implied row is the <span><code>datagrid</code>
+  child count</span>, and the row count of this implied row is the
+  <span><code>datagrid</code> row count</span>.</p>
 
-  </dl>
+  <hr>
 
-  <h6 id="commonDefaultDataGridMethodDefinitions">Common default data
-  provider method definitions for cells</h6>
+  <p>When an algorithm requires the user agent to <dfn>partially sort
+  a <code>RowList</code> object</dfn> (an array), the entries in the
+  object must be resorted such that <code>Row</code> objects are
+  listed after any of their ancestors and after any of their earlier
+  siblings. In other words, for any two <code>Row</code> objects <var
+  title="">a</var> and <var title="">b</var> in the
+  <code>RowList</code>, where <var title="">a</var> is before <var
+  title="">b</var> after the sort, the following conditions must
+  hold:</p>
 
-  <p>These definitions are used for the cell-specific methods of the
-  default data providers (other than in the
-  <code>select</code>/<code>datalist</code> 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.</p>
+  <ul>
 
+   <li><p>If their <code>RowID</code> objects are the same length and
+   have values that are equal except for the last value, then the last
+   value of <var title="">a</var>'s <code>RowID</code>'s last value
+   must be less than <var title="">b</var>'s <code>RowID</code>'s last
+   value (i.e. earlier siblings must come before their later
+   siblings).</p></li>
+
+   <li><p>If their <code>RowID</code> objects are not the same length,
+   but the values in the shorter of the two are the same as the first
+   few values in the longer one, then <var title="">a</var>'s
+   <code>RowID</code> must be the shorter one (i.e. ancestors must
+   come before their descendants).</p></li>
+
+  </ul>
+
+  <hr>
+
+  <p>The <dfn title="dom-datagrid-deleteRows"><code>deleteRows(<var
+  title="">rows</var>)</code></dfn> method must run the following
+  steps:</p>
+
+  <ol>
+
+   <li>
+
+    <p>If any of the entries in <var title="">rows</var> are not
+    <code>RowID</code> objects consisting of one or more entries whose
+    values are all integers that are greater than or equal to zero,
+    then throw a <code>TypeError</code> exception and abort these
+    steps.</p>
+
+    <p>To check if a value is an integer, the user agent must first
+    apply the ToNumber() conversion operator to the value, and then
+    verify that the result is a finite integer. If so, the user agent
+    must use the result in the rest of the algorithm as if it had that
+    had been the value passed to the method. <a
+    href="#refsECMA262">[ECMA262]</a></p>
+
+   </li>
+
+   <li>
+
+    <p>If any of the <code>RowID</code> objects in the <var
+    title="">rows</var> argument identify a row that isn't present in
+    the <span>natural order sparse data tree</span>, then throw a
+    <code>DATAGRID_MODEL_ERR</code> exception and abort these
+    steps.</p>
+
+   </li>
+
+   <li>
+
+    <p>If any row is listed twice in the <var title="">rows</var>
+    argument, then throw a <code>DATAGRID_MODEL_ERR</code> exception
+    and abort these steps.</p>
+
+   </li>
+
+   <li>
+
+    <p>Sort the <var title="">rows</var> argument such that the
+    entries are given in the same order as the rows they identify
+    would be visited in a pre-order, depth first traversal of the
+    <span>natural order sparse data tree</span>.</p>
+
+   </li>
+
+   <li>
+
+    <p>For each row identified by entries in <var title="">rows</var>,
+    <em>in reverse order</em>, run the following steps:</p>
+
+    <ol>
+
+     <li>
+
+      <p>Decrement the child count of the row's parent row, if that
+      child count is greater than zero. If the row has no parent,
+      decrement the <span><code>datagrid</code> child
+      count</span>.</p>
+
+      <p>If the row has a parent row, and its child count is now zero,
+      then close that row.</p>
+
+     </li>
+
+     <li>
+
+      <p>Let <var title="">delta</var> be one more than the row's row
+      count if the row is open and its row count is greater than zero;
+      otherwise, let <var title="">delta</var> be one.</p>
+
+     </li>
+
+     <li>
+
+      <p>Let <var title="">ancestor</var> be the row.</p>
+
+     </li>
+
+     <li>
+
+      <p><i>Row count loop:</i> Let <var title="">ancestor</var> be
+      <var title="">ancestor</var>'s parent row, if any, or null if it
+      has none.</p>
+
+     </li>
+
+     <li>
+
+      <p>If <var title="">ancestor</var> is null, then decrement the
+      <span><code>datagrid</code> row count</span> by <var
+      title="">delta</var>. Otherwise, if <var title="">ancestor</var>
+      is open, then decrement its row count by <var
+      title="">delta</var>.</p>
+
+     </li>
+
+     <li>
+
+      <p>If <var title="">ancestor</var> is not null, then jump back
+      to the step labeled <i>row count loop</i> above.</p>
+
+     </li>
+
+     <li>
+
+      <p>Let <var title="">parent</var> be the row's parent, or the
+      <code>datagrid</code> if the row has no parent.</p>
+
+     </li>
+
+     <li>
+
+      <p>Decrement by one the natural order position of all rows whose
+      parent is <var title="">parent</var> and whose natural order
+      position is equal to or greater than the row's own natural order
+      position.</p>
+
+     </li>
+
+     <li>
+
+      <p>If the row is in the <span>display order sparse data
+      tree</span>, then decrement by one the display order position of
+      all rows whose parent is <var title="">parent</var> and whose
+      display order position is equal to or greater than the row's own
+      display order position.</p>
+
+     </li>
+
+     <li>
+
+      <p>Clear the row and its descendants from the
+      <code>Datagrid</code>.</p>
+
+     </li>
+
+    </ol>
+
+   </li>
+
+   <li>
+
+    <p>Invoke the <span><code>datagrid</code> update display
+    algorithm</span>.</p>
+
+   </li>
+
+  </ol>
+
+  <hr>
+
+  <p>The <dfn
+  title="dom-datagrid-clearRows"><code>clearRows()</code></dfn> method
+  must empty the <span>natural order sparse data tree</span>, reset
+  both the <span><code>datagrid</code> child count</span> and the
+  <span><code>datagrid</code> row count</span> to zero, and invoke the
+  <span><code>datagrid</code> update display algorithm</span>.</p>
+
+  <hr>
+
+  <p>The <dfn title="dom-datagrid-repaint"><code>repaint(<var
+  title="">row</var>, <var title="">column</var>)</code></dfn> method
+  must cause the user agent to clear its cache for the cell specified
+  by the identifier <var title="">row</var> and the column <var
+  title="">column</var>, if that column's type is <code
+  title="datagrid-type-custom">custom</code>. If the given column has
+  not been declared, or its type is not <code
+  title="datagrid-type-custom">custom</code>, then the user agent must
+  throw a <code>DATAGRID_MODEL_ERR</code> exception. If the given row
+  is not known, then the method must do nothing. If the cell is indeed
+  cleared, the user agent must reinvoke the previously registered
+  <code>RenderingContext2DCallback</code> callback when it needs to
+  repaint that row.</p>
+
+  <hr>
+
+  <p>If a row has a child count that isn't zero, then the user agent
+  should offer to the user the option of opening and closing the
+  row.</p>
+
+  <p>When a row is opened, if the row's row count is greater than
+  zero, then the user agent must increase the
+  <span><code>datagrid</code> row count</span> and the row counts of
+  any ancestor rows by the number of rows that the newly opened row
+  has in its row count<!-- we should also "update the <span>pending
+  <code>datagrid</code> rows list</span> and the <span>pending
+  <code>datagrid</code> cells list</span> accordingly" -->, then must
+  mark the row as open, then may fill in the <span>display order
+  sparse data tree</span> with any information that the user agent has
+  cached about the display order positions of descendants of the newly
+  opened row, and then must invoke the <code
+  title="dom-listener-rowOpened">rowOpened()</code> method on the
+  current <code title="dom-datagrid-listener">listener</code> with as
+  its first argument a <code>RowID</code> object identifying the row
+  that was opened and as its second argument the boolean false, and
+  then must invoke the <span><code>datagrid</code> update display
+  algorithm</span>.</p>
+
+  <p>On the other hand, when a row is opened and the row's row count
+  is &#x2212;1, then the user agent must mark the row as opening, and
+  then must invoke the <code
+  title="dom-listener-rowOpened">rowOpened()</code> method on the
+  current <code title="dom-datagrid-listener">listener</code> with as
+  its first argument a <code>RowID</code> object identifying the row
+  that was opened and as its second argument the boolean true.</p>
+
+  <p>When a row is closed, the user agent must decrease the
+  <span><code>datagrid</code> row count</span> and the row counts of
+  any ancestor rows by the number of rows that the newly closed row
+  has in its row count, and then must invoke the <code
+  title="dom-listener-rowOpened">rowOpened()</code> method on the
+  current <code title="dom-datagrid-listener">listener</code> with as
+  its first and only argument a <code>RowID</code> object identifying
+  the row that was opened.</p>
+
+
+
+  <h6>The cells</h6>
+
+  <p>Each row has one cell per column. Each cell has the same type as
+  its column. The <dfn>allowed <code>datagrid</code> column
+  types</dfn>, what they represent, and the requirements for when the
+  user interacts with them, are as follows:</p>
+
   <dl>
 
-   <dt>Cyclable cells</dt>
+   <dt><dfn title="datagrid-type-text"><code>text</code></dfn></dt>
+   <dd>
 
+    <p>The cell represents some text and an optional image.</p>
+
+   </dd>
+
+   <dt><dfn title="datagrid-type-editable"><code>editable</code></dfn></dt>
    <dd>
 
-    <p>If the first element child of a cell's element is a
-    <code>select</code> element that has a no <code
-    title="attr-select-multiple">multiple</code> attribute and has at
-    least one <code>option</code> element descendant, then the cell
-    acts as a cyclable cell.</p>
+    <p>The cells represents some editable text, an optional
+    <code>datalist</code> giving autocompletion hints, and an
+    optional image.</p>
 
-    <p>The "current" <code>option</code> element is the selected
-    <code>option</code> element, or the first <code>option</code>
-    element if none is selected.</p>
+    <p>If there is a <code>datalist</code> element, the user agent
+    should offer the suggestions represented by that element to the
+    user. The user agent may use the suggestion's <span
+    title="concept-option-label">label</span> to identify the
+    suggestion. If the user selects a suggestion, then the editable
+    text must be set to the selected suggestion's <span
+    title="concept-option-value">value</span>, as if the user had
+    written that value himself.</p>
 
-    <p>The <code title="dom-provider-getCellData">getCellData()</code>
-    method must return the <code>textContent</code> of the current
-    <code>option</code> element (the <code
-    title="attr-option-label">label</code> attribute is <span
-    title="ignore">ignored</span> in this context as the
-    <code>optgroup</code>s are not displayed).</p>
+    <p>When the user edits the value, either directly or using the
+    <code>datalist</code>, the user agent must invoke the <code
+    title="dom-listener-cellChanged">cellChanged()</code> method on
+    the current <code title="dom-datagrid-listener">listener</code>
+    with as its first argument a <code>RowID</code> identifying the
+    cell's row, as its second argument the identifier of the cell's
+    column, as its third argument the new value, and as its fourth
+    argument the previous value.</p>
 
-    <p>The <code
-    title="dom-provider-getCellClasses">getCellClasses()</code> method
-    must add the <code
-    title="datagrid-cell-class-cyclable">cyclable</code> class and
-    then all the classes of the current <code>option</code>
-    element.</p>
+   </dd>
 
-    <p>The <code title="dom-provider-cycleCell">cycleCell()</code>
-    method must change the selection of the <code>select</code>
-    element such that the next <code>option</code> element after the
-    current <code>option</code> element is the only one that is
-    selected (in <span>tree order</span>). If the current <code>option</code>
-    element is the last <code>option</code> element descendant of the
-    <code>select</code>, then the first <code>option</code> element
-    descendant must be selected instead.</p>
+   <dt><dfn title="datagrid-type-checkable"><code>checkable</code></dfn></dt>
+   <dd>
 
-    <p>The <code
-    title="dom-provider-setCellCheckedState">setCellCheckedState()</code>
-    and <code title="dom-provider-editCell">editCell()</code> methods
-    must do nothing.</p>
+    <p>The cell represents some text, a check box that optionally has
+    its value obscured as indeterminate, and an optional image.</p>
 
+    <p>When the user checks or unchecks the check box, the user agent
+    must change the check box's state appropriately and stop obscuring
+    the check box as indeterminate (if it is obscuring it), and then
+    must invoke the <code
+    title="dom-listener-cellChanged">cellChanged()</code> method on
+    the current <code title="dom-datagrid-listener">listener</code>
+    with as its first argument a <code>RowID</code> identifying the
+    cell's row, as its second argument the identifier of the cell's
+    column, as its third argument true if the check box is now checked
+    and false otherwise, and as its fourth argument true if the check
+    box was previously checked and false otherwise.</p>
+
    </dd>
 
-   <dt>Progress bar cells</dt>
-
+   <dt><dfn title="datagrid-type-list"><code>list</code></dfn></dt>
    <dd>
 
-    <p>If the first element child of a cell's element is a
-    <code>progress</code> element, then the cell acts as a progress
-    bar cell.</p>
+    <p>The cell represents some text giving the current value selected
+    from a dropdown list of options, a <code>select</code> element
+    giving the list of options, and an optional image.</p>
 
-    <p>The <code title="dom-provider-getCellData">getCellData()</code>
-    method must return the value returned by the <code>progress</code>
-    element's <code title="dom-progress-position">position</code> DOM
-    attribute.</p>
+    <p>The user agent should allow the user to change the value of the
+    cell from its current value to one of the <span
+    title="concept-option-value">values</span> given by
+    <code>option</code> elements in the <span
+    title="concept-select-option-list">list of options</span> (if
+    any). The user agent may use the <code>option</code> elements'
+    <span title="concept-option-label">labels</span> to annotate each
+    option.</p>
 
-    <p>The <code
-    title="dom-provider-getCellClasses">getCellClasses()</code> method
-    must add the <code
-    title="datagrid-cell-class-progress">progress</code> class.</p>
+    <p>When the user selects a new value from the <code>select</code>
+    element's <span title="concept-select-option-list">list of
+    options</span>, the user agent must invoke the <code
+    title="dom-listener-cellChanged">cellChanged()</code> method on
+    the current <code title="dom-datagrid-listener">listener</code>
+    with as its first argument a <code>RowID</code> identifying the
+    cell's row, as its second argument the identifier of the cell's
+    column, as its third argument the new value, and as its fourth
+    argument the previous value.</p>
 
-    <p>The <code
-    title="dom-provider-setCellCheckedState">setCellCheckedState()</code>,
-    <code title="dom-provider-cycleCell">cycleCell()</code>, and
-    <code title="dom-provider-editCell">editCell()</code> methods must
-    do nothing.</p>
+   </dd>
 
+   <dt><dfn title="datagrid-type-progress"><code>progress</code></dfn></dt>
+   <dd>
+
+    <p>The cell represents a (determinate) progress bar whose value is
+    between 0.0, indicating no progress, and 1.0, indicating the task
+    is complete.</p>
+
    </dd>
 
-   <dt>Checkbox cells</dt>
-
+   <dt><dfn title="datagrid-type-meter"><code>meter</code></dfn></dt>
    <dd>
 
-    <p>If the first element child of a cell's element is an
-    <code>input</code> element that has a <code
-    title="attr-input-type">type</code> attribute with the value <code
-    title="">checkbox</code>, then the cell acts as a check box
-    cell.</p>
+    <p>The cell represents a gauge, described by one to six
+    numbers.</p>
 
-    <p>The <code title="dom-provider-getCellData">getCellData()</code>
-    method must return the <code>textContent</code> of the cell
-    element.</p>
+    <p>The gauge's actual value is given by the first number.</p>
 
-    <p>The <code
-    title="dom-provider-getCellClasses">getCellClasses()</code> method
-    must add the <code
-    title="datagrid-cell-class-checked">checked</code> class if the
-    <code>input</code> element's <span
-    title="concept-fe-checked">checkedness</span> is true, and the
-    <code title="datagrid-cell-class-unchecked">unchecked</code> class
-    otherwise.</p>
+    <p>If there is a second number, then that number is the maximum
+    value. Otherwise, the maximum value is 1.0.</p>
 
-    <p>The <code
-    title="dom-provider-setCellCheckedState">setCellCheckedState()</code>
-    method must set the <code>input</code> element's checkbox <span
-    title="concept-fe-checked">checkedness</span> to true if the
-    method's third argument is 1, and to false otherwise.</p>
+    <p>If there is a third number, then that number is the minimum
+    value. Otherwise, the minimum value is 1.0.</p>
 
-    <p>The <code title="dom-provider-cycleCell">cycleCell()</code> and
-    <code title="dom-provider-editCell">editCell()</code> methods must
-    do nothing.</p>
+    <p>If there is a fourth number, then that number is the low
+    boundary. Otherwise, the low boundary is the minimum value.</p>
 
+    <p>If there is a fifth number, then that number is the high
+    boundary. Otherwise, the high boundary is the maximum value.</p>
+
+    <p>If there is a sixth number, then the optimal point is the sixth
+    number. Otherwise, the optimum point is the midpoint between the
+    minimum value and the maximum value.</p>
+
+    <!-- next two paragraphs copied from <meter>: -->
+
+    <p>If the optimum point is equal to the low boundary or the high
+    boundary, or anywhere in between them, then the region between the
+    low and high boundaries of the gauge must be treated as the
+    optimum region, and the low and high parts, if any, must be
+    treated as suboptimal. Otherwise, if the optimum point is less
+    than the low boundary, then the region between the minimum value
+    and the low boundary must be treated as the optimum region, the
+    region between the low boundary and the high boundary must be
+    treated as a suboptimal region, and the region between the high
+    boundary and the maximum value must be treated as an even less
+    good region. Finally, if the optimum point is higher than the high
+    boundary, then the situation is reversed; the region between the
+    high boundary and the maximum value must be treated as the optimum
+    region, the region between the high boundary and the low boundary
+    must be treated as a suboptimal region, and the remaining region
+    between the low boundary and the minimum value must be treated as
+    an even less good region.</p>
+
+    <p>User agents should indicate the relative position of the actual
+    actual to the minimum and maximum values, and the relationship
+    between the actual value and the three regions of the gauge.</p>
+
    </dd>
 
-   <dt>Editable cells</dt>
-
+   <dt><dfn title="datagrid-type-custom"><code>custom</code></dfn></dt>
    <dd>
 
-    <p>If the first element child of a cell's element is an
-    <code>input</code> element that has a <code
-    title="attr-input-type">type</code> attribute with the value <code
-    title="">text</code> or that has no <code
-    title="attr-input-type">type</code> attribute at all, then the
-    cell acts as an editable cell.</p>
+    <p>The cell represents a dynamically generated graphical image.</p>
 
-    <p>The <code title="dom-provider-getCellData">getCellData()</code>
-    method must return the <code title="dom-input-value">value</code>
-    of the <code>input</code> element.</p>
+    <p>The cell will have minimum dimensions (specified in CSS
+    pixels), and a callback (in the form of a
+    <code>RenderingContext2DCallback</code> object) to get a rendering
+    for the cell.</p>
 
-    <p>The <code
-    title="dom-provider-getCellClasses">getCellClasses()</code> method
-    must add the <code
-    title="datagrid-cell-class-editable">editable</code> class.</p>
+    <p>The user agent should not allow the cell to be rendered with
+    dimensions less than the given minimum width and height.</p>
 
-    <p>The <code title="dom-provider-editCell">editCell()</code>
-    method must set the <code>input</code> element's <code
-    title="dom-input-value">value</code> DOM attribute to the value of
-    the third argument to the method.</p>
+    <p>When the user agent needs to render the cell, the user agent
+    must <span>queue a task</span> to invoke the
+    <span>RenderingContext2DCallback</span> callback, passing it a
+    newly created <code>CanvasRenderingContext2D</code> object whose
+    <code title="dom-context-2d-canvas">canvas</code> DOM attribute is
+    null as the first argument, the actual cell width in CSS pixels as
+    the second argument, and the actual cell height in CSS pixels as
+    the third argument.</p>
 
-    <p>The <code
-    title="dom-provider-setCellCheckedState">setCellCheckedState()</code>
-    and <code title="dom-provider-cycleCell">cycleCell()</code>
-    methods must do nothing.</p>
+    <p>If the user agent is able to render graphics, then it must
+    render the graphics commands that the callback executed on the
+    provided <code>CanvasRenderingContext2D</code> object onto the
+    cell once the callback returns. The image must be clipped to the
+    dimensions of the cell. The coordinate space of the cell must be
+    aligned with that used by the 2D context such that the top left
+    corner of the cell is the 0,0 origin, with the coordinate space
+    increasing its <var title="">x</var> dimension towards the right
+    of the cell and its <var title="">y</var> axis towards the bottom
+    of the cell, and with the image not scaled (so that one CSS pixel
+    on the final rendering matches one CSS pixel in the coordinate
+    space usd by the 2D context).</p>
 
+    <p>The user agent must then decouple the
+    <code>CanvasRenderingContext2D</code> object and any objects that
+    it created (such as <code>CanvasPattern</code> objects or
+    <code>ImageData</code> objects) from any real drawing surface.</p>
+
+    <p>If the user agent is unable to render graphics, then it must
+    render the text string returned by the callback instead.</p>
+
    </dd>
 
   </dl>
 
-  <!-- XXX Calculated cells, like in spreadsheets? -->
+  <hr>
 
+  <p>When an algorithm requires the user agent to <dfn>apply a
+  <code>Row</code> object</dfn>, the user agent must run the following
+  steps:</p>
 
-  <h5>Populating the <code>datagrid</code> element</h5>
+  <ol>
 
-  <p>A <code>datagrid</code> must be disabled until its end tag has
-  been parsed<!-- XXX do we define that? what if the end tag is never
-  seen, but the element is popped off the stack?--> (in the case of a
-  <code>datagrid</code> element in the original document markup) or
-  until it has been <span title="insert an element into a
-  document">inserted into the document</span> (in the case of a
-  dynamically created element). After that point, the element must
-  fire a single <code title="event-load">load</code> event at itself,
-  which doesn't bubble and cannot be canceled.</p>
+   <li>
 
-  <p class="XXX">The end-tag parsing thing should be moved to
-  the parsing section.</p>
+    <p>If the value of the <code>Row</code> object's second entry is
+    not &#x2212;1, then run these substeps:</p>
 
-  <p>The <code>datagrid</code> must then populate itself using the
-  data provided by the data provider assigned to the <code
-  title="dom-datagrid-data">data</code> DOM attribute. After the view
-  is populated (using the methods described below), the
-  <code>datagrid</code> must invoke the <code
-  title="dom-provider-initialize">initialize()</code> method on the
-  data provider specified by the <code
-  title="dom-datagrid-data">data</code> attribute, passing itself (the
-  <code>HTMLDataGridElement</code> object) as the only argument.</p>
+    <ol>
 
-  <p>When the <code title="dom-datagrid-data">data</code> attribute is
-  null, the <code>datagrid</code> must use the default data provider
-  described in the previous section.</p>
+     <li><p>If there is a row with the same parent as the row
+     specified by the <code>Row</code> object's <code>RowID</code>
+     object, whose display order position is currently the same as the
+     value of the <code>Row</code> object's second entry, then remove
+     that row from the <span>display order sparse data
+     tree</span>.</p></li>
 
-  <p>To obtain data from the data provider, the element must invoke
-  methods on the data provider object in the following ways:</p>
+     <li><p>Set the display order position of the row specified by the
+     <code>Row</code> object's <code>RowID</code> to the value of the
+     <code>Row</code> object's second entry, updating its position in
+     the <span>display order sparse data tree</span>
+     accordingly.</p></li>
 
-  <dl>
+     <li><p>If the row is in the the <span>pending
+     <code>datagrid</code> rows list</span>, remove it.</p></li>
 
-   <dt>To determine the total number of columns</dt>
+    </ol>
 
-   <dd>Invoke the <code
-   title="dom-provider-getColumnCount">getColumnCount()</code> 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.</dd>
+   </li>
 
-   <dt>To get the captions to use for the columns</dt>
+   <li>
 
-   <dd>Invoke the <code
-   title="dom-provider-getCaptionText">getCaptionText()</code> method
-   with the index of the column in question. The index <var
-   title="">i</var> must be in the range 0 ≤ <var title="">i</var>
-   < <var title="">N</var>, where <var title="">N</var> 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.</dd>
+    <p>If the fourth entry in the <code>Row</code> object (a
+    <code>CellList</code> object, an array) is not empty, then for
+    each <code>Cell</code> object in that array update the cell that
+    corresponds to the column identified by the value of the first
+    entry of the <code>Cell</code> object, by using the appropriate
+    set of steps given below as determined by the type of the
+    column. Then, if the cell is in the the <span>pending
+    <code>datagrid</code> cells list</span>, remove it.</p>
 
-   <dt>To establish what classes apply to a column</dt>
+    <dl>
 
-   <dd>Invoke the <code
-   title="dom-provider-getCaptionClasses">getCaptionClasses()</code>
-   method with the index of the column in question, and an object
-   implementing the <code>DOMTokenList</code> interface, associated
-   with an anonymous empty string. The index <var title="">i</var>
-   must be in the range 0 ≤ <var title="">i</var> < <var
-   title="">N</var>, where <var title="">N</var> is the total number
-   of columns. The tokens contained in the string underlying
-   <code>DOMTokenList</code> 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.</dd>
+     <dt>If the column's type is <code title="datagrid-type-text">text</code></dt>
+     <dd>
 
-   <dt>To establish whether a column should be initially included in
-   the visible columns</dt>
+      <p>Update the cell's text to the value given in the
+      <code>Cell</code> object's second entry.</p>
 
-   <dd>Check whether the <code
-   title="datagrid-column-class-initially-hidden">initially-hidden</code>
-   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.</dd>
+      <p>If the <code>Cell</code> object has three entries, then copy
+      the image data from the <code>img</code> element given in the
+      third entry, and let the cell's image be given by that image
+      data. Otherwise, update the cell to have no image.</p>
 
-   <dt id="columnType2">To establish whether the data can be sorted
-   relative to a particular column</dt>
+     </dd>
 
-   <dd>Check whether the <code
-   title="datagrid-column-class-sortable">sortable</code> 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.</dd>
+     <dt>If the column's type is <code title="datagrid-type-editable">editable</code></dt>
+     <dd>
 
-   <dt>To establish if a column is a sorted column</dt>
+      <p>Update the cell's text to the value given in the
+      <code>Cell</code> object's second entry.</p>
 
-   <dd>If the user agent can handle multiple columns being marked as
-   sorted simultaneously: Check whether the <code
-   title="datagrid-column-class-sorted">sorted</code> class applies to
-   the column. If it does, then that column is the sorted column,
-   otherwise it is not.</dd>
+      <p>If the <code>Cell</code> object has three entries, then let
+      the <code>datalist</code> element given in the third entry be
+      the <code>datalist</code> element giving autocompletion
+      hints. Otherwise, update the cell to have no
+      <code>datalist</code> element.</p>
 
-   <dd>If the user agent can only handle one column being marked as
-   sorted at a time: Check each column in turn, starting with the
-   first one, to see whether the <code
-   title="datagrid-column-class-sorted">sorted</code> 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.</dd>
+      <p>If the <code>Cell</code> object has four entries, then copy
+      the image data from the <code>img</code> element given in the
+      fourth entry, and let the cell's image be given by that image
+      data. Otherwise, update the cell to have no image.</p>
 
-   <dt>To establish the sort direction of a sorted column</dt>
+     </dd>
 
-   <dd>Check whether the <code
-   title="datagrid-column-class-reversed">reversed</code> 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).</dd>
+     <dt>If the column's type is <code title="datagrid-type-checkable">checkable</code></dt>
+     <dd>
 
-   <dt>To determine the total number of rows</dt>
+      <p>Update the cell's text to the value given in the
+      <code>Cell</code> object's second entry.</p>
 
-   <dd>Determine the number of rows for the root of the data grid, and
-   determine the number of child rows for each open row. The total
-   number of rows is the sum of all these numbers.</dd>
+      <p>Update the cell's checked state to match the value of the
+      third entry: checked if true, unchecked otherwise.</p>
 
-   <dt>To determine the number of rows for the root of the data grid</dt>
+      <p>If the <code>Cell</code> object has four entries and the
+      fourth entry is true, then update the cell to be obscured as
+      indeterminate. Otherwise, the cell's state is not obscured.</p>
 
-   <dd>Invoke the <code
-   title="dom-provider-getRowCount">getRowCount()</code> method with a
-   <code>RowSpecification</code> 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.</dd>
+      <p>If the <code>Cell</code> object has five entries, then copy
+      the image data from the <code>img</code> element given in the
+      fifth entry, and let the cell's image be given by that image
+      data. Otherwise, update the cell to have no image.</p>
 
-   <dt>To determine the number of child rows for a row</dt>
+     </dd>
 
-   <dd>Invoke the <code
-   title="dom-provider-getRowCount">getRowCount()</code> method with a
-   <code>RowSpecification</code> 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.</dd>
+     <dt>If the column's type is <code title="datagrid-type-list">list</code></dt>
+     <dd>
 
-   <dt>To determine what order to render rows in</dt>
+      <p>Update the cell's text to the value given in the
+      <code>Cell</code> object's second entry, and the
+      <code>select</code> element to be the one given in the
+      <code>Cell</code> object's third entry</p>
 
-   <dd>
+      <p>If the <code>Cell</code> object has four entries, then copy
+      the image data from the <code>img</code> element given in the
+      fourth entry, and let the cell's image be given by that image
+      data. Otherwise, update the cell to have no image.</p>
 
-    <p>Invoke the <code
-    title="dom-provider-getChildAtPosition">getChildAtPosition()</code>
-    method with a <code>RowSpecification</code> 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.</p>
+     </dd>
 
-    <div class="example">
+     <dt>If the column's type is <code title="datagrid-type-progress">progress</code></dt>
+     <dd>
 
-     <p>If the rows are:</p>
+      <p>Update the cell to be a progress bar whose progress, on the
+      scale of 0.0 (no progress) to 1.0 (task complete) is given by
+      the value in the <code>Cell</code> object's second entry.</p>
 
-     <ol>
-      <li> Row "0"
-       <ol>
-        <li> Row "0,0"
-        <li> Row "0,1"
-       </ol>
-      </li>
-      <li> Row "1"
-       <ol>
-        <li> Row "1,0"
-        <li> Row "1,1"
-       </ol>
-      </li>
-     </ol>
+     </dd>
 
-     <p>...and the <code
-    title="dom-provider-getChildAtPosition">getChildAtPosition()</code>
-    method is implemented as follows:</p>
+     <dt>If the column's type is <code title="datagrid-type-meter">meter</code></dt>
+     <dd>
 
-    <pre>function getChildAtPosition(parent, child) {
-  // always return the reverse order
-  return getRowCount(parent)-child-1;
-}</pre>
+      <p>Update the cell to be a gauge configured with the numbers
+      given by the second and subsequent entries of the
+      <code>Cell</code> object.</p>
 
-     <p>...then the rendering would actually be:</p>
+     </dd>
 
-     <ol>
-      <li> Row "1"
-       <ol>
-        <li> Row "1,1"
-        <li> Row "1,0"
-       </ol>
-      </li>
-      <li> Row "0"
-       <ol>
-        <li> Row "0,1"
-        <li> Row "0,0"
-       </ol>
-      </li>
-     </ol>
+     <dt>If the column's type is <code title="datagrid-type-custom">custom</code></dt>
+     <dd>
 
-    </div>
+      <p>Update the cell's minimum width to be the length in CSS
+      pixels given by the <code>Cell</code> object's second entry.</p>
 
-    <p>If the return value of the method is negative, larger than the
-    number of rows that the <code
-    title="dom-provider-getRowCount">getRowCount()</code> 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 <code
-    title="dom-provider-getChildAtPosition">getChildAtPosition()</code>
-    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).</p>
+      <p>Update the cell's minimum height to be the length in CSS
+      pixels given by the <code>Cell</code> object's third entry.</p>
 
-   </dd>
+      <p>Update the cell's callback to be the
+      <code>RenderingContext2DCallback</code> object given by the
+      <code>Cell</code> object's fourth entry.</p>
 
-   <dt>To establish what classes apply to a row</dt>
+     </dd>
 
-   <dd>Invoke the <code
-   title="dom-provider-getRowClasses">getRowClasses()</code> method
-   with a <code>RowSpecification</code> object representing the row in
-   question, and a <code>DOMTokenList</code> associated with an empty
-   string. The tokens contained in the <code>DOMTokenList</code>
-   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.</dd>
+    </dl>
 
-   <dt>To establish whether a row is a data row or a special row</dt>
+   </li>
 
-   <dd>Examine the classes that apply to the row. If the <code
-   title="datagrid-row-class-header">header</code> 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 <code
-   title="datagrid-row-class-separator">separator</code> class applies
-   to the row, then in the place of the row, a separator should be
-   shown. Otherwise, if the <code
-   title="datagrid-row-class-selectable-separator">selectable-separator</code>
-   class applies to the row, then the row should be a data row, but
-   represented as a separator. (The difference between a <code
-   title="datagrid-row-class-separator">separator</code> and a <code
-   title="datagrid-row-class-selectable-separator">selectable-separator</code>
-   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.</dd>
+  </ol>
 
-   <dt id="rowType1">To establish whether a row is openable</dt>
+  <hr>
 
-   <dd>Determine the number of child rows for that row. If there are
-   one or more child rows, then the row is openable.</dd>
+  <p>When the user agent is to run the <dfn><code>datagrid</code>
+  update display algorithm</dfn>, the user agent must invoke the <code
+  title="dom-listener-getRows">getRows()</code> and <code
+  title="dom-listener-getCells">getCells()</code> methods on the
+  current <code title="dom-datagrid-listener">listener</code> such
+  that all the current visible rows in the <span>display order sparse
+  data list</span>, and all the cells in the currently visible columns
+  on all the currently visible rows, have been covered.</p>
 
-   <dt>To establish whether a row should be initially open or closed</dt>
+  <p>A row is considered covered if it is present in the <span>pending
+  <code>datagrid</code> rows list</span>, or if the <code
+  title="dom-listener-getRows">getRows()</code> method is invoked with
+  a range that includes the row in question.</p>
 
-   <dd>If <a href="#rowType1">the row is openable</a>, examine the
-   classes that apply to the row. If the <code
-   title="datagrid-row-class-initially-open">initially-open</code>
-   class applies to the row, then it should be initially
-   open. Otherwise, if the <code
-   title="datagrid-row-class-initially-closed">initially-closed</code>
-   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.</dd>
+  <p>A cell is considered covered if it is present in the
+  <span>pending <code>datagrid</code> cells list</span>, or if the
+  <code title="dom-listener-getRows">getRows()</code> method is
+  invoked with a range that includes the row in question and a list of
+  columns that includes the cell's column, or if the <code
+  title="dom-listener-getCells">getCells()</code> method is invoked
+  with a list of rows and columns that intersects the cell in
+  question. However, the <code
+  title="dom-listener-getCells">getCells()</code> method can only be
+  used if the row is already present in the <span>display order sparse
+  data list</span>.</p>
 
-<!-- XXXPA
-   <dt>To establish whether a row is deletable</dt>
+  <p>The <code title="dom-listener-getRows">getRows()</code> method,
+  if used, must be invoked with five arguments. The first argument
+  must be the index in the <span>display order sparse data list</span>
+  to the first row that the the user agent is requesting, known as the
+  <i>anchor row</i>. The second argument must be the number of
+  consecutive cells for which the user agent is requesting
+  information. The third argument must be the <code>RowID</code> of
+  the row that is the nearest ancestor in the <span>display order
+  sparse data <em>tree</em></span> of the anchor row. If this is the
+  <code>datagrid</code>, then the <code>RowID</code> object must be an
+  empty array. The fourth argument must be the display order position
+  of the anchor row in the <span>display order sparse data
+  tree</span>, assuming that the row identified in the third argument
+  is indeed the anchor row's parent row. The fifth and final argument
+  must be an array of the identifiers of the columns for which the
+  user agent is requesting information, in the order they were added
+  to the <code>datagrid</code>.</p>
 
-   <dd>Check whether the <code
-   title="datagrid-row-class-deletable">deletable</code> class applies
-   to the row. If it does, the row is deletable, and interactive user
-   agents should provide a way for the user to request that the row be
-   deleted. (See the <code
-   title="dom-provider-performActionOnRow">performActionOnRow()</code>
-   method for more details.) Otherwise, the user agent should not
-   provide the user with a method for requesting that the row be
-   deleted.</dd>
--->
+  <p>As the <code title="dom-listener-getRows">getRows()</code> method
+  is invoked, the <span>pending <code>datagrid</code> rows list</span>
+  must be updated to include the rows for which information has been
+  requested, excluding rows for which information is already
+  available; and the <span>pending <code>datagrid</code> cells
+  list</span> must be updated to include the cells for which
+  information has been requested on those rows.</p>
 
-   <dt>To obtain a <span>URL</span> identifying an image representing a row</dt>
+  <p>The <code title="dom-listener-getCells">getCells()</code> method,
+  if used, must be invoked with two arguments. The first argument must
+  be an array of <code>RowID</code> objects identifying the rows for
+  which information is being requested. The second argument must be an
+  array of the identifiers of the columns for which the user agent is
+  requesting information, in the order they were added to the
+  <code>datagrid</code>.</p>
 
-   <dd>Invoke the <code
-   title="dom-provider-getRowImage">getRowImage()</code> method with a
-   <code>RowSpecification</code> object representing the row in
-   question. The return value is a <span>URL</span>. Immediately <span
-   title="resolve a url">resolve</span> that URL, relative to the
-   <code>datagrid</code> element, to obtain an <span>absolute
-   URL</span> 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.</dd> <!-- changing
-   the base URL doesn't change the image used later -->
+  <p>As the <code title="dom-listener-getCells">getCells()</code>
+  method is invoked, the <span>pending <code>datagrid</code> cells
+  list</span> must be updated to include the cells for which
+  information has been requested.</p>
 
-   <dt>To obtain a context menu appropriate for a particular row</dt>
+  <p>Calls to these methods should be batched so that the rows and
+  cells to be covered are handled by the fewest number of calls to
+  these methods as possible. To this end, user agents may invoke the
+  <code title="dom-listener-getRows">getRows()</code> method for a set
+  of rows that includes some rows that are already in the
+  <span>display order sparse data list</span>, and similarly may
+  invoke the <code title="dom-listener-getCells">getCells()</code>
+  method with row/column combinations that cover some cells for which
+  data is already known. Generally, however, user agents should avoid
+  invoking these methods with arguments that cause information to be
+  requested when it has already been requested or is already
+  known.</p>
 
-   <dd>Invoke the <code
-   title="dom-provider-getRowMenu">getRowMenu()</code> method with a
-   <code>RowSpecification</code> object representing the row in
-   question. The return value is a reference to an object implementing
-   the <code>HTMLMenuElement</code> interface, i.e. a
-   <code>menu</code> 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.<!-- XXX update once menu section
-   works; with xrefs -->) If the method returns something that is not
-   an <code>HTMLMenuElement</code>, 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 <code>datagrid</code>
-   element.</dd>
+  <div class="example">
 
-   <dt>To establish the value of a particular cell</dt>
+   <p>For example, consider a case represented by the following table,
+   where the cells marked "Yes" indicate that the data has already
+   been obtained, the cells marked "Pending" indicate that the data
+   has been previously requested but not yet obtained, and the cells
+   with just a dash indicate that no information has ever been
+   obtained, or any information that had been obtained has now been
+   discarded.</p>
 
-   <dd>Invoke the <code
-   title="dom-provider-getCellData">getCellData()</code> method with
-   the first argument being a <code>RowSpecification</code> 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.)</dd>
+   <table>
+    <tr> <td>        <th> Row   <th> Column A  <th> Column B
+    <tr> <th> Row 1  <td> -     <td> -         <td> -
+    <tr> <th> Row 2  <td> Yes   <td> Yes       <td> Yes
+    <tr> <th> Row 3  <td> Yes   <td> Yes       <td> Yes
+    <tr> <th> Row 4  <td> Yes   <td> Yes       <td> Yes
+    <tr> <th> Row 5  <td> -     <td> -         <td> -
+    <tr> <th> Row 6  <td> -     <td> -         <td> -
+    <tr> <th> Row 7  <td> Yes   <td> Pending   <td> -
+    <tr> <th> Row 8  <td> Yes   <td> Pending   <td> Pending
+   </table>
 
-   <dt>To establish what classes apply to a cell</dt>
+   <p>Thus, rows 2, 3, 4, 7, and 8 are already covered, as are the
+   cells from those rows except for the cell in column B of row 7.</p>
 
-   <dd>Invoke the <code
-   title="dom-provider-getCellClasses">getCellClasses()</code> method
-   with the first argument being a <code>RowSpecification</code>
-   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 <code>DOMTokenList</code> 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 <code>DOMTokenList</code> 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.</dd>
+   <p>Now consider what happens if all of these rows become visible at
+   once. The user agent has several choices, including (but not
+   limited to) the following:</p>
 
-   <dt id="cellType1">To establish the type of a cell</dt>
+   <ul>
 
-   <dd>Examine the classes that apply to the cell. If the <code
-   title="datagrid-cell-class-progress">progress</code> class applies
-   to the cell, it is a progress bar. Otherwise, if the <code
-   title="datagrid-cell-class-cyclable">cyclable</code> 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.</dd>
+    <li>Fire the <code title="dom-listener-getRows">getRows()</code>
+    method for rows 1 through 8 and columns A and B all at once.</li>
 
-   <dt>To establish the value of a progress bar cell</dt>
+    <li>Fire the <code title="dom-listener-getRows">getRows()</code>
+    method for row 1, then fire it again for rows 5 through 7.</li>
 
-   <dd>If the value <var title="">x</var> of the cell is a string that
-   can be <span title="rules for parsing floating point number
-   values">converted to a floating-point number</span> in the range
-   0.0 ≤ <var title="">x</var> ≤ 1.0, then
-   the progress bar has that value (0.0 means no progress, 1.0 means
-   complete). Otherwise, the progress bar is an indeterminate progress
-   bar.</dd>
+    <li>Fire the <code title="dom-listener-getRows">getRows()</code>
+    method for row 1, then fire it again for rows 5 and 6, and then
+    fire the <code title="dom-listener-getCells">getCells()</code>
+    method for row 7 column B.</li>
 
-   <dt id="cellType2">To establish how a simple text cell should be presented</dt>
+   </ul>
 
-   <dd>Check whether one of the <code
-   title="datagrid-cell-class-checked">checked</code>, <code
-   title="datagrid-cell-class-unchecked">unchecked</code>, or <code
-   title="datagrid-cell-class-indeterminate">indeterminate</code>
-   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
-   <code title="datagrid-cell-class-editable">editable</code> class
-   applies to the cell. If it does, then the cell value is editable,
-   otherwise the cell value is static.</dd>
+   <p>All three options are allowed, but the latter two are preferable
+   to the former, as they minimise the amount of redundant information
+   requested.</p>
 
-   <dt>To establish the state of a cell's checkbox, if it has one</dt>
+   <p>In any case, the data model now looks like this:</p>
 
-   <dd>Check whether the <code
-   title="datagrid-cell-class-checked">checked</code> class applies to
-   the cell. If it does, the cell is checked. Otherwise, check whether
-   the <code title="datagrid-cell-class-unchecked">unchecked</code>
-   class applies to the cell. If it does, the cell is unchecked.
-   Otherwise, the <code
-   title="datagrid-cell-class-indeterminate">indeterminate</code>
-   class applies to the cell and the cell's checkbox is in an
-   indeterminate state. When the <code
-   title="datagrid-cell-class-indeterminate">indeterminate</code>
-   class applies to the cell, the checkbox is a tristate checkbox,
-   and the user can set it to the indeterminate state. Otherwise, only
-   the <code title="datagrid-cell-class-checked">checked</code> and/or
-   <code title="datagrid-cell-class-unchecked">unchecked</code>
-   classes apply to the cell, and the cell can only be toggled between
-   those two states.</dd>
+   <table>
+    <tr> <td>        <th> Row     <th> Column A  <th> Column B  <th> Column C
+    <tr> <th> Row 1  <td> Pending <td> Pending   <td> Pending   <td> -
+    <tr> <th> Row 2  <td> Yes     <td> Yes       <td> Yes       <td> -
+    <tr> <th> Row 3  <td> Yes     <td> Yes       <td> Yes       <td> -
+    <tr> <th> Row 4  <td> Yes     <td> Yes       <td> Yes       <td> -
+    <tr> <th> Row 5  <td> Pending <td> Pending   <td> Pending   <td> -
+    <tr> <th> Row 6  <td> Pending <td> Pending   <td> Pending   <td> -
+    <tr> <th> Row 7  <td> Yes     <td> Pending   <td> Pending   <td> -
+    <tr> <th> Row 8  <td> Yes     <td> Pending   <td> Pending   <td> -
+   </table>
 
-  </dl>
+   <p>Now consider the case where a third column, column C, is added
+   to the data model. The user agent once again has several choices,
+   including (but not limited to) the following:</p>
 
-  <p>If the data provider ever raises an exception while the
-  <code>datagrid</code> is invoking one of its methods, the
-  <code>datagrid</code> must act, for the purposes of that particular
-  method call, as if the relevant method had not been defined.</p>
+   <ul>
 
-  <p>A <code>RowSpecification</code> object <var title="">p</var> with
-  <var title="">n</var> path components passed to a method of the data
-  provider must fulfill the constraint <span>0 ≤ <var
-  title="">p<sub title=""><var
-  title="">i</var></sub></var> < <var
-  title="">m</var>-1</span> for all integer values of <var
-  title="">i</var> in the range <span>0 ≤ <var
-  title="">i</var> < <var title="">n</var>-1</span>,
-  where <var title="">m</var> is the value that was last returned by
-  the <code title="dom-provider-getRowCount">getRowCount()</code>
-  method when it was passed the <code>RowSpecification</code> object
-  <var title="">q</var> with <span title=""><var title="">i</var>-1</span>
-  items, where <span title=""><var title="">p<sub title=""><var
-  title="">i</var></sub></var> = <var title="">q<sub
-  title=""><var title="">i</var></sub></var></span> for all integer
-  values of <var title="">i</var> in the range
-  <span>0 ≤ <var title="">i</var> < <var
-  title="">n</var>-1</span>, with any changes implied by the update
-  methods taken into account.</p>
+    <li>Fire the <code title="dom-listener-getRows">getRows()</code>
+    method for rows 1 through 8 again, this time listing just column
+    C.</li>
 
-  <p id="inconsistentDataProvider">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 <code>datagrid</code> element. If a user
-  agent is returned inconsistent data, for example if the number of
-  rows returned by <code
-  title="dom-provider-getRowCount">getRowCount()</code> varies in ways
-  that do not match the calls made to the update methods, the user
-  agent may disable the <code>datagrid</code>. User agents that do not
-  disable the <code>datagrid</code> in inconsistent cases must honor
-  the most recently returned values.</p>
+    <li>Fire the <code title="dom-listener-getRows">getRows()</code>
+    method for row 1, then fire it again for rows 5 and 6, and then
+    fire the <code title="dom-listener-getCells">getCells()</code>
+    method for the other rows (in all three cases, listing just column
+    C).</li>
 
-  <p>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 <code
-  title="dom-provider-getRowMenu">getRowMenu</code> method.</p>
+   </ul>
 
-  <p>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.</p> <!-- XXX speaking of which, do we actually want that
-  limitation? -->
+   <p>The two options here are as bad as each other; the former
+   involves a lot of overlap, but the latter involves a lot of method
+   calls. Unfortunately the user agent can't do the obvious thing,
+   namely just to invoke the <code
+   title="dom-listener-getCells">getCells()</code> method for all the
+   rows listing just column C, because it doesn't have the row
+   information for all the rows yet (rows 1, 5 and 6 are still
+   pending).</p>
 
+   <p>In any case, the data model now looks like this:</p>
 
-  <h5>Updating the <code>datagrid</code></h5>
+   <table>
+    <tr> <td>        <th> Row     <th> Column A  <th> Column B  <th> Column C
+    <tr> <th> Row 1  <td> Pending <td> Pending   <td> Pending   <td> Pending
+    <tr> <th> Row 2  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr> <th> Row 3  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr> <th> Row 4  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr> <th> Row 5  <td> Pending <td> Pending   <td> Pending   <td> Pending
+    <tr> <th> Row 6  <td> Pending <td> Pending   <td> Pending   <td> Pending
+    <tr> <th> Row 7  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+    <tr> <th> Row 8  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+   </table>
 
-  <p>Whenever the <code title="dom-datagrid-data">data</code>
-  attribute is set to a new value, the <code>datagrid</code> 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.</p>
+   <p>If at this point the user scrolls around anywhere within this
+   <code>datagrid</code>, the user agent won't fire the <code
+   title="dom-listener-getRos">getRos()</code> and <code
+   title="dom-listener-getCells">getCells()</code> methods, because
+   all of the rows and cells are covered.</p>
 
-  <p>There are a number of update methods that can be invoked on the
-  <code>datagrid</code> element to cause it to refresh itself in
-  slightly less drastic ways:</p>
+   <p>Now consider the case where the user agent receives row
+   information, but no cell information, for rows 1, 5, and 6:</p>
 
-  <p>When the <dfn
-  title="dom-datagrid-updateEverything"><code>updateEverything()</code></dfn>
-  method is called, the user agent must repopulate the entire
-  <code>datagrid</code>. 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.</p>
+   <table>
+    <tr> <td>        <th> Row     <th> Column A  <th> Column B  <th> Column C
+    <tr> <th> Row 1  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+    <tr> <th> Row 2  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr> <th> Row 3  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr> <th> Row 4  <td> Yes     <td> Yes       <td> Yes       <td> Pending
+    <tr> <th> Row 5  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+    <tr> <th> Row 6  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+    <tr> <th> Row 7  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+    <tr> <th> Row 8  <td> Yes     <td> Pending   <td> Pending   <td> Pending
+   </table>
 
-  <p>When the <dfn
-  title="dom-datagrid-updateRowsChanged"><code>updateRowsChanged(<var
-  title="">row</var>, <var title="">count</var>)</code></dfn> method
-  is called, the user agent must refresh the rendering of the rows
-  starting from the row specified by <var title="">row</var>, and
-  including the <var title="">count</var> next siblings of the row (or
-  as many next siblings as it has, if that is less than <var
-  title="">count</var>), including all descendant rows.</p>
+   <p>The user agent still won't fire any methods when the user
+   scrolls, because the data is still covered. But if the script then
+   calls the <code title="dom-datagrid-renotify">renotify()</code>
+   method, the "Pending" flags would get reset, and the model would
+   now look like this:</p>
 
-  <p>When the <dfn
-  title="dom-datagrid-updateRowsInserted"><code>updateRowsInserted(<var
-  title="">row</var>, <var title="">count</var>)</code></dfn> method
-  is called, the user agent must assume that <var title="">count</var>
-  new rows have been inserted, such that the first new row is
-  identified by <var title="">row</var>. The user agent must update
-  its rendering and the selection accordingly. The new rows should not
-  be selected.</p>
+   <table>
+    <tr> <td>        <th> Row     <th> Column A  <th> Column B  <th> Column C
+    <tr> <th> Row 1  <td> Yes     <td> -         <td> -         <td> -      
+    <tr> <th> Row 2  <td> Yes     <td> Yes       <td> Yes       <td> -      
+    <tr> <th> Row 3  <td> Yes     <td> Yes       <td> Yes       <td> -      
+    <tr> <th> Row 4  <td> Yes     <td> Yes       <td> Yes       <td> -      
+    <tr> <th> Row 5  <td> Yes     <td> -         <td> -         <td> -      
+    <tr> <th> Row 6  <td> Yes     <td> -         <td> -         <td> -      
+    <tr> <th> Row 7  <td> Yes     <td> -         <td> -         <td> -      
+    <tr> <th> Row 8  <td> Yes     <td> -         <td> -         <td> -      
+   </table>
 
-  <p>When the <dfn
-  title="dom-datagrid-updateRowsRemoved"><code>updateRowsRemoved(<var
-  title="">row</var>, <var title="">count</var>)</code></dfn> method
-  is called, the user agent must assume that <var title="">count</var>
-  rows have been removed starting from the row that used to be
-  identifier by <var title="">row</var>.  The user agent must update
-  its rendering and the selection accordingly.</p>
+   <p>Now, assuming that all eight rows and all three columns are
+   still visible, the user agent has the following choices (amongst
+   others):</p>
 
-  <p>The <dfn
-  title="dom-datagrid-updateRowChanged"><code>updateRowChanged(<var
-  title="">row</var>)</code></dfn> method must be exactly equivalent
-  to calling <code
-  title="dom-datagrid-updateRowsChanged">updateRowsChanged(<var
-  title="">row</var>, 1)</code>.</p>
+   <ul>
 
-  <p>When the <dfn
-  title="dom-datagrid-updateColumnChanged"><code>updateColumnChanged(<var
-  title="">column</var>)</code></dfn> method is called, the user agent
-  must refresh the rendering of the specified column <var
-  title="">column</var>, for all rows.</p>
+    <li>Fire the <code title="dom-listener-getRows">getCells()</code>
+    method for rows 1 through 8, listing all three columns.</li>
 
-  <p>When the <dfn
-  title="dom-datagrid-updateCellChanged"><code>updateCellChanged(<var
-  title="">row</var>, <var title="">column</var>)</code></dfn> method
-  is called, the user agent must refresh the rendering of the cell on
-  row <var title="">row</var>, in column <var
-  title="">column</var>.</p>
+    <li>Fire the <code title="dom-listener-getRows">getCells()</code>
+    method for rows 1 and 5 through 8, listing all three columns, and
+    then fire the method for rows 2 through 4, listing just column
+    C.</li>
 
-  <p>Any effects the update methods have on the
-  <code>datagrid</code>'s selection is not considered a change to the
-  selection, and must therefore not fire the <code
-  title="event-select">select</code> event.</p>
+    <li>Fire the <code title="dom-listener-getRows">getCells()</code>
+    method for rows 1 and 5 through 8, listing just columns A abd B,
+    and then fire the method for rows 1 through 8, listing just column
+    C.</li>
 
-  <p>These update methods should be called only by the data provider,
-  or code acting on behalf of the data provider. In particular,
-  calling the <code
-  title="dom-datagrid-updateRowsInserted">updateRowsInserted()</code>
-  and <code
-  title="dom-datagrid-updateRowsRemoved">updateRowsRemoved()</code>
-  methods without actually inserting or removing rows from the data
-  provider is <a href="#inconsistentDataProvider">likely to result in
-  inconsistent renderings</a>, and the user agent is likely to disable
-  the data grid.</p>
+   </ul>
 
+   <p>Here the latter two are preferable because they result in less
+   overlap than the first.</p>
 
-  <h5>Requirements for interactive user agents</h5>
+  </div>
 
-  <p><em>This section only applies to interactive user agents.</em></p>
+  <hr>
 
-  <p>If the <code>datagrid</code> element has a <dfn
-  title="attr-datagrid-disabled"><code>disabled</code></dfn>
-  attribute, then the user agent must disable the
-  <code>datagrid</code>, preventing the user from interacting with it.
-  The <code>datagrid</code> element should still continue to update
-  itself when the data provider signals changes to the data, though.
-  Obviously, conformance requirements stating that
-  <code>datagrid</code> elements must react to users in particular
-  ways do not apply when one is disabled.</p>
+  <p>The <span>task source</span> for tasks queued on behalf of a
+  <code>datagrid</code> is the <span>DOM manipulation task
+  source</span>.</p>
 
-  <p>If <a href="#rowType1">a row is openable</a>, 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.</p>
+  </div>
 
-  <p>If a cell is a cell whose value <a href="#cellType1">can be
-  cycled between multiple states</a>, 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
-  <code>datagrid</code> must invoke the data provider's <code
-  title="dom-provider-cycleCell">cycleCell()</code> method, with a
-  <code>RowSpecification</code> object representing the cell's row as
-  the first argument and the cell's column index as the second. The
-  <code>datagrid</code> must then act as if the
-  <code>datagrid</code>'s <code
-  title="dom-datagrid-updateCellChanged">updateCellChanged()</code>
-  method had been invoked with those same arguments.</p>
 
-  <p>When a cell <a href="#cellType2">has a checkbox</a>, 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
-  <code>datagrid</code> must invoke the data provider's <code
-  title="dom-provider-setCellCheckedState">setCellCheckedState()</code>
-  method, with a <code>RowSpecification</code> 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 &#x2212;1 if the new state is
-  indeterminate (which must be possible only if the cell has the <code
-  title="datagrid-cell-class-indeterminate">indeterminate</code> class
-  set). The <code>datagrid</code> must then act as if the
-  <code>datagrid</code>'s <code
-  title="dom-datagrid-updateCellChanged">updateCellChanged()</code>
-  method had been invoked, specifying the same cell.</p>
+  <h5>Listening to notifications from the <code>datagrid</code></h5>
 
-  <p>If a cell <a href="#cellType2">is editable</a>, 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 <code
-  title="dom-provider-editCell">editCell()</code> method of the data
-  provider with three arguments: a <code>RowSpecification</code>
-  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 <code
-  title="dom-datagrid-updateCellChanged">updateCellChanged()</code>
-  method had been invoked, with the same row and column specified.</p>
+  <p><em>The conformance criteria in this section apply to any
+  implementation of the <code>DataGridListener</code> interface,
+  including (and most commonly) the content author's
+  implementation(s).</em></p>
 
-  <!-- XXXPA <p class="XXX">define actions (performAction(), etc)</p> -->
+  <pre class="idl">// To be implemented by Web authors as a JS object
+[NoInterfaceObject] interface <dfn>DataGridListener</dfn> {
+  void <span title="dom-listener-initialize">initialize</span>(in <span>HTMLDataGridElement</span> datagrid);
 
+  void <span title="dom-listener-getRows">getRows</span>(in unsigned long rowIndex, in unsigned long rowCount, in <span>RowID</span> parentRow, in unsigned long position, in <span>ColumnList</span> columns);
+  void <span title="dom-listener-getCells">getCells</span>(in <span>RowIDList</span> rows, in <span>ColumnList</span> columns);
+  void <span title="dom-listener-rowOpened">rowOpened</span>(in <span>RowID</span> row, in boolean rowCountNeeded);
+  void <span title="dom-listener-rowClosed">rowClosed</span>(in <span>RowID</span> row);
+
+  void <span title="dom-listener-cellChanged">cellChanged</span>(in <span>RowID</span> row, in <span>Column</span> column, in any newValue, in any prevValue);
+  <span>HTMLMenuElement</span> <span title="dom-listener-getRowMenu">getRowMenu</span>(in <span>RowID</span> row);
+<!--vsDGDND
+  boolean <span title="dom-listener-canDrop">canDrop</span>(in <span>RowID</span> row, in <span>RowID</span> position, data);
+  boolean <span title="dom-listener-dropped">dropped</span>(in <span>RowID</span> row, in <span>RowID</span> position, data);
+--><!--v2DGPA
+  void <span title="dom-listener-performAction">performAction</span>(in <span>RowID</span> row, in DOMString action);
+-->};</pre>
+
+  <p>The <code>DataGridDataProvider</code> interface, once implemented
+  by an object in a script and hooked up to a <code>datagrid</code>
+  using the <dfn title="dom-datagrid-data"><code>data</code></dfn> DOM
+  attribute, receives notifications when the <code>datagrid</code>
+  needs information (such as which rows exist) for display.</p>
+
+  <p>The following methods may be usefully implemented:</p>
+
+  <dl>
+
+   <dt><dfn title="dom-listener-initialize"><code>initialize(<var title="">datagrid</var>)</code></dfn></dt>
+
+   <dd>
+
+    <p>Called by the <code>datagrid</code> element (the one given by
+    the <var title="">datagrid</var> argument) when the <code
+    title="dom-datagrid-listener">listener</code> attribute is
+    set.</p>
+
+   </dd>
+
+   <dt><dfn title="dom-listener-getRows"><code>getRows(<var title="">rowIndex</var>, <var title="">rowCount</var>, <var title="">parentRow</var>, <var title="">position</var>, <var title="">columns</var>)</code></dfn></dt>
+
+   <dd>
+
+    <p>Called by the <code>datagrid</code> element when the user agent
+    finds itself needing to render rows for which it is lacking
+    information.</p>
+
+    <p>The <var title="">rowIndex</var> argument gives the flattened
+    index of the first row for which it needs information, ignoring
+    the tree structure of the <code>datagrid</code> model, where zero
+    is the first row of the entire tree.</p>
+
+    <p>The <var title="">rowCount</var> argument gives the number of
+    rows for which the user agent would like information.</p>
+
+    <p>The <var title="">parentRow</var> argument gives the
+    <code>RowID</code> object identifying the nearest ancestor of the
+    first row that the user agent is aware of. After the sort order
+    has changed, this will typically be the root of the tree
+    (identified by a <code>RowID</code> object consisting of an empty
+    array).
+
+    <p>The <var title="">columns</var> argument gives the columns for
+    which the user agent is lacking information, as an array of column
+    identifiers (as passed to <code
+    title="dom-datagrid-addColumn">addColumn()</code>).</p>
+
+   </dd>
+
+   <dt><dfn title="dom-listener-getCells"><code>getCells(<var title="">rows</var>, <var title="">columns</var>)</code></dfn></dt>
+
+   <dd>
+
+    <p>Called by the <code>datagrid</code> element when the user agent
+    finds itself needing to render cells for which it is lacking
+    information in rows that it does know about.</p>
+
+    <p>The <var title="">rows</var> argument gives an array of
+    <code>RowID</code> objects identifying the various rows for which
+    the user agent is lacking information.</p>
+
+    <p>The <var title="">columns</var> argument gives the columns for
+    which the user agent is lacking information, as an array of column
+    identifiers (as passed to <code
+    title="dom-datagrid-addColumn">addColumn()</code>).</p>
+
+   </dd>
+
+   <dt><dfn title="dom-listener-rowOpened"><code>rowOpened(<var title="">row</var>, <var title="">rowCountNeeded</var>)</code></dfn></dt>
+
+   <dd>
+
+    <p>Called by the <code>datagrid</code> element when the user has
+    opened a row.</p>
+
+    <p>The <var title="">row</var> argument gives an
+    <code>RowID</code> object identifying the row that was opened.</p>
+
+    <p>If the user agent also knows how many children that row has,
+    then the <var title="">rowCountNeeded</var> argument will be
+    false. Otherwise, the argument will be true, and the row will
+    remain closed until the <code
+    title="dom-datagrid-setRows">setRows()</code> method is called
+    with an accurate row count.</p>
+
+   </dd>
+
+   <dt><dfn title="dom-listener-rowClosed"><code>rowClosed(<var title="">row</var>)</code></dfn></dt>
+
+   <dd>
+
+    <p>Called by the <code>datagrid</code> element when the user has
+    opened a row.</p>
+
+    <p>The <var title="">row</var> argument gives an
+    <code>RowID</code> object identifying the row that was closed.</p>
+
+   </dd>
+
+   <dt><dfn title="dom-listener-cellChanged"><code>cellChanged(<var title="">row</var>, <var title="">column</var>, <var title="">newValue</var>, <var title="">prevValue</var>)</code></dfn></dt>
+
+   <dd>
+
+    <p>Called by the <code>datagrid</code> element when the user has
+    edited a cell or checked a check box in a cell.</p>
+
+    <p>The <var title="">row</var> argument gives an
+    <code>RowID</code> object identifying the row of the cell, and the
+    <var title="">column</var> argument gives the identifier of the
+    cell's column.</p>
+
+    <p>The <var title="">newValue</var> argument gives the new value,
+    and the <var title="">prevValue</var> argument gives the previous
+    value.</p>
+
+   </dd>
+
+   <dt><dfn title="dom-listener-getRowMenu"><code>getRowMenu(<var title="">row</var>)</code></dfn></dt>
+
+   <dd>Must return an <code>HTMLMenuElement</code> object that is to
+   be used as a context menu for row <var title="">row</var>, 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.</dd>
+
+   <!--v2DGDND, v2DFPA-->
+
+  </dl>
+
+  <div class="impl">
+
+  <p>Objects that implement the <code>DataGridListener</code>
+  interface may omit any or all of the methods. When a method is
+  omitted, a user agent intending to call that method must instead
+  skip the method call, and must assume that the method's return value
+  is null.</p>
+
+  </div>
+
+
+
+<!-- v2DGS: <datagrid> selection (search for the bits marked "..." to see what needs filling in, at a minimum)
+
   <h5>The selection</h5>
 
-  <p><em>This section only applies to interactive user agents. For
-  other user agents, the <code
-  title="dom-datagrid-selection">selection</code> attribute must
-  return null.</em></p>
-
   <pre class="idl">interface <dfn>DataGridSelection</dfn> {
-  readonly attribute unsigned long <span title="dom-DataGridSelection-count">length</span>;
-  [IndexGetter] <span>RowSpecification</span> <span title="dom-DataGridSelection-item">item</span>(in unsigned long index);
-  boolean <span title="dom-DataGridSelection-isSelected">isSelected</span>(in <span>RowSpecification</span> row);
-  void <span title="dom-DataGridSelection-setSelected">setSelected</span>(in <span>RowSpecification</span> row, in boolean selected);
-<!--  void <span title="dom-DataGridSelection-addRange">addRange</span>(in <span>RowSpecification</span> first, in <span>RowSpecification</span> last);
-  void <span title="dom-DataGridSelection-removeRange">removeRange</span>(in <span>RowSpecification</span> first, in <span>RowSpecification</span> last);
-XXX selection ranges -->
+  readonly attribute unsigned long <span title="dom-DataGridSelection-length">length</span>;
+  [IndexGetter] <span>RowID</span> <span title="dom-DataGridSelection-item">item</span>(in unsigned long index);
+  boolean <span title="dom-DataGridSelection-isSelected">isSelected</span>(in <span>RowID</span> row);
+  void <span title="dom-DataGridSelection-setSelected">setSelected</span>(in <span>RowID</span> row, in boolean selected);
   void <span title="dom-DataGridSelection-selectAll">selectAll</span>();
-  void <span title="dom-DataGridSelection-invert">invert</span>();
   void <span title="dom-DataGridSelection-clear">clear</span>();
 };</pre>
 
+  <dl class="domintro">
+
+   ...
+
+  </dl>
+
+  <div class="impl">
+
   <p>Each <code>datagrid</code> 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. <!--XXX
-  select-provider-selection The default data provider, for instance,
-  changes which rows are selected when it is first initialized.--></p>
+  be changed via the methods described in this section.</p>
 
   <p>The selection of a <code>datagrid</code> is represented by its
   <dfn title="dom-datagrid-selection"><code>selection</code></dfn> DOM
   attribute, which must be a <code>DataGridSelection</code> object.</p>
 
   <p><code>DataGridSelection</code> 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.</p>
+  selection. In the selection the rows must be ordered in their
+  natural order (and not, e.g., the display order). A row with an
+  ancestor that is closed cannot be selected.</p>
 
-  <p class="note">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.</p>
-
   <p>The <dfn
   title="dom-DataGridSelection-length"><code>length</code></dfn>
   attribute must return the number of rows currently present in the
@@ -41997,7 +42668,8 @@
   properties</span>.</p>
 
   <p>The <dfn title="dom-DataGridSelection-item"><code>item(<var
-  title="">index</var>)</code></dfn> method must return the <var
+  title="">index</var>)</code></dfn> method must return a
+  <code>RowID</code> object identifying the <var
   title="">index</var>th 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 <code>INDEX_SIZE_ERR</code>
@@ -42006,8 +42678,9 @@
   <p>The <dfn
   title="dom-DataGridSelection-isSelected"><code>isSelected()</code></dfn>
   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.</p>
+  argument. If the specified row is in the <span>natural order sparse
+  data tree</span> and is selected, the method must return true,
+  otherwise it must return false.</p>
 
   <p>The <dfn
   title="dom-DataGridSelection-setSelected"><code>setSelected()</code></dfn>
@@ -42015,116 +42688,51 @@
   title="">selected</var>. When invoked, it must set the selection
   state of row <var title="">row</var> to selected if <var
   title="">selected</var> is true, and unselected if it is false. If
-  <var title="">row</var> is not a row in the data grid, the method
-  must raise an <code>INDEX_SIZE_ERR</code> exception. If the
-  specified row is not rendered because one of its ancestors is
-  closed, the method must do nothing.</p>
+  <var title="">row</var> does not specify a row in the <span>natural
+  order sparse data tree</span> ...
 
   <p>The <dfn
   title="dom-DataGridSelection-selectAll"><code>selectAll()</code></dfn>
-  method must mark all the rows in the data grid as selected. After a
-  call to <code
-  title="dom-DataGridSelection-selectAll">selectAll()</code>, the
-  <code title="dom-DataGridSelection-length">length</code> attribute
-  will return the number of rows in the data grid, not counting
-  children of closed rows.</p>
+  method must ...
 
   <p>The <dfn
-  title="dom-DataGridSelection-invert"><code>invert()</code></dfn>
-  method must cause all the rows in the selection that were marked as
-  selected to now be marked as not selected, and vice versa.</p>
-
-  <p>The <dfn
   title="dom-DataGridSelection-clear"><code>clear()</code></dfn>
-  method must mark all the rows in the data grid to be marked as not
-  selected.  After a call to <code
+  method must mark all the rows in the <code>datagrid</code> as not
+  selected. After a call to <code
   title="dom-DataGridSelection-clear">clear()</code>, the <code
   title="dom-DataGridSelection-length">length</code> attribute will
   return zero.</p>
 
-  <p>If the <code>datagrid</code> element has a <dfn
-  title="attr-datagrid-multiple"><code>multiple</code></dfn>
-  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.</p>
+  <p>If the <code>datagrid</code> element has a <code
+  title="attr-datagrid-multiple">multiple</code> 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
+  should allow the user to select a row, and must not allow the user
+  to select more than a single row at a time; selecting another one
+  must unselect all the other rows.</p>
 
   <p class="note">This only applies to the user. Scripts can select
   multiple rows even when the <code
   title="attr-datagrid-multiple">multiple</code> attribute is
   absent.</p>
 
-  <p>Whenever the selection of a <code>datagrid</code> changes,
-  whether due to the user interacting with the element, or as a result
-  of calls to methods of the <code
-  title="dom-datagrid-selection">selection</code> object, a <dfn
-  title="event-select"><code>select</code></dfn><!-- XXX check if we
-  really should be DFNing this here. It's a DOM3 Core event. What's
-  our story going to be regarding events and defining them? --> event
-  that bubbles but is not cancelable must be fired on the
-  <code>datagrid</code> element. If changes are made to the selection
-  via calls to the object's methods during the execution of a
-  script<!-- XXX should xref to a better explanation -->, then the
-  <code title="event-select">select</code> events must be coalesced
-  into one, which must then be fired<!--XXX xref again--> when the
-  script execution has completed<!-- XXX xref -->.</p>
+  ...event on selection change?...
 
+  </div>
+
   <p class="note">The <code>DataGridSelection</code> interface has no
   relation to the <code>Selection</code> interface.</p>
 
+-->
 
-  <h5>Columns and captions</h5>
 
-  <p><em>This section only applies to interactive user agents.</em></p>
-
-  <p>Each <code>datagrid</code> element must keep track of which
-  columns are currently being rendered. User agents should initially
-  show all the columns except those with the <code
-  title="datagrid-column-class-initially-hidden">initially-hidden</code>
-  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.</p>
-
-  <p>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.</p>
-
-  <p>If none of the columns have any captions (i.e. if the data
-  provider does not provide a <code
-  title="dom-provider-getCaptionText">getCaptionText()</code> 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).</p>
-
-  <p class="note">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 <code
-  title="dom-provider-getcolumnCount">getColumnCount()</code> method
-  of the data provider.</p>
-
-  <p>If <a href="#columnType2">a column is sortable</a>, 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 <code>datagrid</code>
-  must invoke the data provider's <code
-  title="dom-provider-toggleColumnSortState">toggleColumnSortState()</code>
-  method, with the column's index as the only argument. The
-  <code>datagrid</code> must <em>then</em> act as if the
-  <code>datagrid</code>'s <code
-  title="dom-datagrid-updateEverything">updateEverything()</code>
-  method had been invoked.</p>
-
-<!--XXXDND
+<!--vsDGDND
   <h5>Drag and drop in <code>datagrid</code>s</h5>
 
   <p><em>This section only applies to interactive user agents.</em></p>
 
-  <p class="XXX">define drag and drop in datagrids; selectiondraggable, etc.</p>
+  ...define drag and drop in datagrids; selectiondraggable...
 -->
-</div>
 
 
   <h4 id="the-command">The <dfn><code>command</code></dfn> element</h4>
@@ -74606,6 +75214,7 @@
  XXX * should check all cases of 'active document' and change the
        relevant ones to 'fully active document'.
  XXX * use <code>Document</code> consistently instead of 'document'.
+ XXX * s/raise/throw/g
 -->
 
  </body>




More information about the Commit-Watchers mailing list