--- a/editing.html Tue Nov 08 12:17:45 2011 -0700
+++ b/editing.html Wed Nov 09 10:58:32 2011 -0700
@@ -67,7 +67,7 @@
<body class=draft>
<div class=head id=head>
<h1>HTML Editing APIs</h1>
-<h2 class="no-num no-toc" id=work-in-progress-—-last-update-8-november-2011>Work in Progress — Last Update 8 November 2011</h2>
+<h2 class="no-num no-toc" id=work-in-progress-—-last-update-9-november-2011>Work in Progress — Last Update 9 November 2011</h2>
<dl>
<dt>Editor
<dd>Aryeh Gregor <<a href=mailto:ayg@aryeh.name>ayg@aryeh.name</a>>
@@ -4560,6 +4560,20 @@
<p>The <dfn id=default-single-line-container-name>default single-line container name</dfn> is "p".
+<p>The <dfn id=block-node-of>block node of</dfn> a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> <var title="">node</var> is either a
+<a href=#block-node>block node</a> or null, as returned by the following algorithm:
+
+<ol>
+ <li>While <var title="">node</var> is an <a href=#inline-node>inline node</a>, set <var title="">node</var>
+ to its <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
+
+ <li>Return <var title="">node</var>.
+</ol>
+
+<p>Two <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>nodes</a> are <dfn id=in-the-same-block>in the same block</dfn> if the <a href=#block-node-of>block node
+of</a> the first is non-null and the same as the <a href=#block-node-of>block node of</a>
+the second.
+
<h3 id=assorted-block-formatting-command-algorithms>Assorted block formatting command algorithms</h3>
@@ -4838,6 +4852,91 @@
<li>Return "left".
</ol>
+<p class=note>Sometimes one location corresponds to multiple distinct boundary
+points. For instance, in the DOM <code title=""><p>Hello</p></code>, a boundary point might
+lie at the beginning of the text node or the beginning of the element node, but
+these don't logically differ much and will appear the same to the user, so we
+often want to treat them the same. The algorithms here allow navigating
+through such equivalent boundary points, for when we want to make the selection
+as inclusive or exclusive as possible. For deletion, we want to delete as few
+nodes as possible, so we move the start node forward and the end node backward.
+In other cases we might do the reverse, expanding the selection. In still
+other cases we might want to move forward or backward to try getting to a text
+node.
+
+<p>Given a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-bp title=concept-range-bp>boundary point</a> (<var title="">node</var>, <var title="">offset</var>), the
+<dfn id=next-equivalent-point>next equivalent point</dfn> is either a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-bp title=concept-range-bp>boundary point</a> or null, as
+returned by the following algorithm:
+
+<ol>
+ <li>If <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a> is zero, return null.
+
+ <li class=note>We don't want to move into or out of zero-length nodes,
+ because that would move us straight through them. For instance, if
+ <code title="">{}<span></span></code> were equivalent to <code title=""><span>{}</span></code>, it
+ would also be equivalent to <code title=""><span></span>{}</code>. This produces very
+ unexpected results for nodes like <code title=""><br></code>.
+
+ <li>If <var title="">offset</var> is <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a>, and
+ <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is not null, return (<var title="">node</var>'s
+ <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>, 1 + <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-index title=concept-tree-index>index</a>).
+
+ <li class=note>For instance, <code title=""><span>foo[]</span></code> is equivalent to
+ <code title=""><span>foo{}</span></code>, which is equivalent to <code title=""><span>foo</span>{}</code>.
+
+ <li>If <var title="">node</var> has a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-index title=concept-tree-index>index</a> <var title="">offset</var>,
+ and that <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a> is not zero, return (that <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>, 0).
+
+ <li class=note>For instance, <code title="">{}<span>foo</span></code> is equivalent to
+ <code title=""><span>{}foo</span></code>, which is equivalent to
+ <code title=""><span>[]foo</span></code>. As noted before, though, we don't descend into
+ empty nodes.
+
+ <li>Return null.
+</ol>
+
+<p>Given a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-bp title=concept-range-bp>boundary point</a> (<var title="">node</var>, <var title="">offset</var>), the
+<dfn id=previous-equivalent-point>previous equivalent point</dfn> is either a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-bp title=concept-range-bp>boundary point</a> or null, as
+returned by the following algorithm:
+
+<ol>
+ <li>If <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a> is zero, return null.
+
+ <li>If <var title="">offset</var> is 0, and <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is not null,
+ return (<var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>, <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-index title=concept-tree-index>index</a>).
+
+ <li>If <var title="">node</var> has a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-index title=concept-tree-index>index</a> <var title="">offset</var>
+ − 1, and that <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a> is not zero, return (that
+ <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>, that <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a>).
+
+ <li>Return null.
+</ol>
+
+<!-- Turned out not to be necessary here, but I've left it in case it turns out
+to be handy elsewhere. -->
+<!--
+<p>Two <span data-anolis-spec=dom title=concept-range-bp>boundary points</span> <var title>A</var> and <var title>B</var> are <dfn>equivalent
+boundary points</dfn> if the following algorithm returns true:
+
+<p class=note>This is indeed an <a
+href=http://en.wikipedia.org/wiki/Equivalence_relation>equivalence
+relation</a>. Reflexivity, symmetry, and transitivity are all fairly obvious
+from the definition. It also isn't hard to check that using <span>next
+equivalent point</span> instead of <span>previous equivalent point</span> would
+yield the same definition, because the two algorithms are inverses if neither
+output is null.
+
+<ol>
+ <li>While <var title>A</var>'s <span>previous equivalent point</span> is not null,
+ set <var title>A</var> to its <span>previous equivalent point</span>.
+
+ <li>While <var title>B</var>'s <span>previous equivalent point</span> is not null,
+ set <var title>B</var> to its <span>previous equivalent point</span>.
+
+ <li>Return true if <var title>A</var> is the same as <var title>B</var>, otherwise false.
+</ol>
+-->
+
<h3 id=block-extending-a-range>Block-extending a range</h3>
@@ -5162,103 +5261,6 @@
<!--@}-->
<h3 id=deleting-the-selection>Deleting the selection</h3>
-<p class=note>Sometimes one location corresponds to multiple distinct boundary
-points. For instance, in the DOM <code title=""><p>Hello</p></code>, a boundary point might
-lie at the beginning of the text node or the beginning of the element node, but
-these don't logically differ much and will appear the same to the user, so we
-often want to treat them the same. The algorithms here (currently used only
-for the delete algorithm) allow navigating through such equivalent boundary
-points, for when we want to make the selection as inclusive or exclusive as
-possible. For deletion, we want to delete as few nodes as possible, so we move
-the start node forward and the end node backward. In other cases we might do
-the reverse, expanding the selection.
-
-<p>Given a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-bp title=concept-range-bp>boundary point</a> (<var title="">node</var>, <var title="">offset</var>), the
-<dfn id=next-equivalent-point>next equivalent point</dfn> is either a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-bp title=concept-range-bp>boundary point</a> or null, as
-returned by the following algorithm:
-
-<ol>
- <li>If <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a> is zero, return null.
-
- <li class=note>We don't want to move into or out of zero-length nodes,
- because that would move us straight through them. For instance, if
- <code title="">{}<span></span></code> were equivalent to <code title=""><span>{}</span></code>, it
- would also be equivalent to <code title=""><span></span>{}</code>. This produces very
- unexpected results for nodes like <code title=""><br></code>.
-
- <li>If <var title="">offset</var> is <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a>, and
- <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is not null, return (<var title="">node</var>'s
- <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>, 1 + <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-index title=concept-tree-index>index</a>).
-
- <li class=note>For instance, <code title=""><span>foo[]</span></code> is equivalent to
- <code title=""><span>foo{}</span></code>, which is equivalent to <code title=""><span>foo</span>{}</code>.
-
- <li>If <var title="">node</var> has a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-index title=concept-tree-index>index</a> <var title="">offset</var>,
- and that <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a> is not zero, return (that <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>, 0).
-
- <li class=note>For instance, <code title="">{}<span>foo</span></code> is equivalent to
- <code title=""><span>{}foo</span></code>, which is equivalent to
- <code title=""><span>[]foo</span></code>. As noted before, though, we don't descend into
- empty nodes.
-
- <li>Return null.
-</ol>
-
-<p>Given a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-bp title=concept-range-bp>boundary point</a> (<var title="">node</var>, <var title="">offset</var>), the
-<dfn id=previous-equivalent-point>previous equivalent point</dfn> is either a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-bp title=concept-range-bp>boundary point</a> or null, as
-returned by the following algorithm:
-
-<ol>
- <li>If <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a> is zero, return null.
-
- <li>If <var title="">offset</var> is 0, and <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is not null,
- return (<var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>, <var title="">node</var>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-index title=concept-tree-index>index</a>).
-
- <li>If <var title="">node</var> has a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> with <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-index title=concept-tree-index>index</a> <var title="">offset</var>
- − 1, and that <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a> is not zero, return (that
- <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>, that <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length title=concept-node-length>length</a>).
-
- <li>Return null.
-</ol>
-
-<!-- Turned out not to be necessary here, but I've left it in case it turns out
-to be handy elsewhere. -->
-<!--
-<p>Two <span data-anolis-spec=dom title=concept-range-bp>boundary points</span> <var title>A</var> and <var title>B</var> are <dfn>equivalent
-boundary points</dfn> if the following algorithm returns true:
-
-<p class=note>This is indeed an <a
-href=http://en.wikipedia.org/wiki/Equivalence_relation>equivalence
-relation</a>. Reflexivity, symmetry, and transitivity are all fairly obvious
-from the definition. It also isn't hard to check that using <span>next
-equivalent point</span> instead of <span>previous equivalent point</span> would
-yield the same definition, because the two algorithms are inverses if neither
-output is null.
-
-<ol>
- <li>While <var title>A</var>'s <span>previous equivalent point</span> is not null,
- set <var title>A</var> to its <span>previous equivalent point</span>.
-
- <li>While <var title>B</var>'s <span>previous equivalent point</span> is not null,
- set <var title>B</var> to its <span>previous equivalent point</span>.
-
- <li>Return true if <var title>A</var> is the same as <var title>B</var>, otherwise false.
-</ol>
--->
-
-<p>The <dfn id=block-node-of>block node of</dfn> a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> <var title="">node</var> is either a
-<a href=#block-node>block node</a> or null, as returned by the following algorithm:
-
-<ol>
- <li>While <var title="">node</var> is an <a href=#inline-node>inline node</a>, set <var title="">node</var>
- to its <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
-
- <li>Return <var title="">node</var>.
-</ol>
-
-<p>Two <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>nodes</a> are <dfn id=in-the-same-block>in the same block</dfn> if the <a href=#block-node-of>block node
-of</a> the first is non-null and the same as the <a href=#block-node-of>block node of</a>
-the second.
<p class=comments>TODO: Consider what should happen for block merging in corner
cases like display: inline-table.
--- a/implementation.js Tue Nov 08 12:17:45 2011 -0700
+++ b/implementation.js Wed Nov 09 10:58:32 2011 -0700
@@ -3756,6 +3756,22 @@
// "The default single-line container name is "p"."
var defaultSingleLineContainerName = "p";
+function getBlockNodeOf(node) {
+ // "While node is an inline node, set node to its parent."
+ while (isInlineNode(node)) {
+ node = node.parentNode;
+ }
+
+ // "Return node."
+ return node;
+}
+
+// "Two nodes are in the same block if the block node of the first is non-null
+// and the same as the block node of the second."
+function inSameBlock(node1, node2) {
+ return getBlockNodeOf(node1)
+ && getBlockNodeOf(node1) === getBlockNodeOf(node2);
+}
//@}
///// Assorted block formatting command algorithms /////
@@ -3999,6 +4015,54 @@
return "left";
}
+function getNextEquivalentPoint(node, offset) {
+ // "If node's length is zero, return null."
+ if (getNodeLength(node) == 0) {
+ return null;
+ }
+
+ // "If offset is node's length, and node's parent is not null, return
+ // (node's parent, 1 + node's index)."
+ if (offset == getNodeLength(node) && node.parentNode) {
+ return [node.parentNode, 1 + getNodeIndex(node)];
+ }
+
+ // "If node has a child with index offset, and that child's length is not
+ // zero, return (that child, 0)."
+ if (0 <= node.childNodes.length
+ && offset < node.childNodes.length
+ && getNodeLength(node.childNodes[offset]) != 0) {
+ return [node.childNodes[offset], 0];
+ }
+
+ // "Return null."
+ return null;
+}
+
+function getPreviousEquivalentPoint(node, offset) {
+ // "If node's length is zero, return null."
+ if (getNodeLength(node) == 0) {
+ return null;
+ }
+
+ // "If offset is 0, and node's parent is not null, return (node's parent,
+ // node's index)."
+ if (offset == 0 && node.parentNode) {
+ return [node.parentNode, getNodeIndex(node)];
+ }
+
+ // "If node has a child with index offset − 1, and that child's length is
+ // not zero, return (that child, that child's length)."
+ if (0 <= node.childNodes.length
+ && offset - 1 < node.childNodes.length
+ && getNodeLength(node.childNodes[offset - 1]) != 0) {
+ return [node.childNodes[offset - 1], getNodeLength(node.childNodes[offset - 1])];
+ }
+
+ // "Return null."
+ return null;
+}
+
//@}
///// Block-extending a range /////
//@{
@@ -4386,71 +4450,6 @@
///// Deleting the selection /////
//@{
-function getNextEquivalentPoint(node, offset) {
- // "If node's length is zero, return null."
- if (getNodeLength(node) == 0) {
- return null;
- }
-
- // "If offset is node's length, and node's parent is not null, return
- // (node's parent, 1 + node's index)."
- if (offset == getNodeLength(node) && node.parentNode) {
- return [node.parentNode, 1 + getNodeIndex(node)];
- }
-
- // "If node has a child with index offset, and that child's length is not
- // zero, return (that child, 0)."
- if (0 <= node.childNodes.length
- && offset < node.childNodes.length
- && getNodeLength(node.childNodes[offset]) != 0) {
- return [node.childNodes[offset], 0];
- }
-
- // "Return null."
- return null;
-}
-
-function getPreviousEquivalentPoint(node, offset) {
- // "If node's length is zero, return null."
- if (getNodeLength(node) == 0) {
- return null;
- }
-
- // "If offset is 0, and node's parent is not null, return (node's parent,
- // node's index)."
- if (offset == 0 && node.parentNode) {
- return [node.parentNode, getNodeIndex(node)];
- }
-
- // "If node has a child with index offset − 1, and that child's length is
- // not zero, return (that child, that child's length)."
- if (0 <= node.childNodes.length
- && offset - 1 < node.childNodes.length
- && getNodeLength(node.childNodes[offset - 1]) != 0) {
- return [node.childNodes[offset - 1], getNodeLength(node.childNodes[offset - 1])];
- }
-
- // "Return null."
- return null;
-}
-
-function getBlockNodeOf(node) {
- // "While node is an inline node, set node to its parent."
- while (isInlineNode(node)) {
- node = node.parentNode;
- }
-
- // "Return node."
- return node;
-}
-
-// "Two nodes are in the same block if the block node of the first is non-null
-// and the same as the block node of the second."
-function inSameBlock(node1, node2) {
- return getBlockNodeOf(node1)
- && getBlockNodeOf(node1) === getBlockNodeOf(node2);
-}
-
// The flags argument is a dictionary that can have blockMerging,
// stripWrappers, and/or direction as keys.
function deleteSelection(flags) {
--- a/source.html Tue Nov 08 12:17:45 2011 -0700
+++ b/source.html Wed Nov 09 10:58:32 2011 -0700
@@ -4601,6 +4601,20 @@
<p>The <dfn>default single-line container name</dfn> is "p".
+<p>The <dfn>block node of</dfn> a [[node]] <var>node</var> is either a
+<span>block node</span> or null, as returned by the following algorithm:
+
+<ol>
+ <li>While <var>node</var> is an <span>inline node</span>, set <var>node</var>
+ to its [[parent]].
+
+ <li>Return <var>node</var>.
+</ol>
+
+<p>Two [[nodes]] are <dfn>in the same block</dfn> if the <span>block node
+of</span> the first is non-null and the same as the <span>block node of</span>
+the second.
+
<!-- @} -->
<h3>Assorted block formatting command algorithms</h3>
<!-- @{ -->
@@ -4881,6 +4895,92 @@
<li>Return "left".
</ol>
+<p class=note>Sometimes one location corresponds to multiple distinct boundary
+points. For instance, in the DOM {{code|<p>Hello</p>}}, a boundary point might
+lie at the beginning of the text node or the beginning of the element node, but
+these don't logically differ much and will appear the same to the user, so we
+often want to treat them the same. The algorithms here allow navigating
+through such equivalent boundary points, for when we want to make the selection
+as inclusive or exclusive as possible. For deletion, we want to delete as few
+nodes as possible, so we move the start node forward and the end node backward.
+In other cases we might do the reverse, expanding the selection. In still
+other cases we might want to move forward or backward to try getting to a text
+node.
+
+<p>Given a [[boundarypoint]] (<var>node</var>, <var>offset</var>), the
+<dfn>next equivalent point</dfn> is either a [[boundarypoint]] or null, as
+returned by the following algorithm:
+
+<ol>
+ <li>If <var>node</var>'s [[length]] is zero, return null.
+
+ <li class=note>We don't want to move into or out of zero-length nodes,
+ because that would move us straight through them. For instance, if
+ {{code|{}<span></span>}} were equivalent to {{code|<span>{}</span>}}, it
+ would also be equivalent to {{code|<span></span>{} }}. This produces very
+ unexpected results for nodes like {{code|<br>}}.
+
+ <li>If <var>offset</var> is <var>node</var>'s [[length]], and
+ <var>node</var>'s [[parent]] is not null, return (<var>node</var>'s
+ [[parent]], 1 + <var>node</var>'s [[index]]).
+
+ <li class=note>For instance, {{code|<span>foo[]</span>}} is equivalent to
+ {{code|<span>foo{}</span>}}, which is equivalent to {{code|<span>foo</span>{}
+ }}.
+
+ <li>If <var>node</var> has a [[child]] with [[index]] <var>offset</var>,
+ and that [[child]]'s [[length]] is not zero, return (that [[child]], 0).
+
+ <li class=note>For instance, {{code|{}<span>foo</span>}} is equivalent to
+ {{code|<span>{}foo</span>}}, which is equivalent to
+ {{code|<span>[]foo</span>}}. As noted before, though, we don't descend into
+ empty nodes.
+
+ <li>Return null.
+</ol>
+
+<p>Given a [[boundarypoint]] (<var>node</var>, <var>offset</var>), the
+<dfn>previous equivalent point</dfn> is either a [[boundarypoint]] or null, as
+returned by the following algorithm:
+
+<ol>
+ <li>If <var>node</var>'s [[length]] is zero, return null.
+
+ <li>If <var>offset</var> is 0, and <var>node</var>'s [[parent]] is not null,
+ return (<var>node</var>'s [[parent]], <var>node</var>'s [[index]]).
+
+ <li>If <var>node</var> has a [[child]] with [[index]] <var>offset</var>
+ − 1, and that [[child]]'s [[length]] is not zero, return (that
+ [[child]], that [[child]]'s [[length]]).
+
+ <li>Return null.
+</ol>
+
+<!-- Turned out not to be necessary here, but I've left it in case it turns out
+to be handy elsewhere. -->
+<!--
+<p>Two [[boundarypoints]] <var>A</var> and <var>B</var> are <dfn>equivalent
+boundary points</dfn> if the following algorithm returns true:
+
+<p class=note>This is indeed an <a
+href=http://en.wikipedia.org/wiki/Equivalence_relation>equivalence
+relation</a>. Reflexivity, symmetry, and transitivity are all fairly obvious
+from the definition. It also isn't hard to check that using <span>next
+equivalent point</span> instead of <span>previous equivalent point</span> would
+yield the same definition, because the two algorithms are inverses if neither
+output is null.
+
+<ol>
+ <li>While <var>A</var>'s <span>previous equivalent point</span> is not null,
+ set <var>A</var> to its <span>previous equivalent point</span>.
+
+ <li>While <var>B</var>'s <span>previous equivalent point</span> is not null,
+ set <var>B</var> to its <span>previous equivalent point</span>.
+
+ <li>Return true if <var>A</var> is the same as <var>B</var>, otherwise false.
+</ol>
+-->
+
<!-- @} -->
<h3>Block-extending a range</h3>
<!-- @{ -->
@@ -5213,104 +5313,6 @@
<!--@}-->
<h3>Deleting the selection</h3>
<!-- @{ -->
-<p class=note>Sometimes one location corresponds to multiple distinct boundary
-points. For instance, in the DOM {{code|<p>Hello</p>}}, a boundary point might
-lie at the beginning of the text node or the beginning of the element node, but
-these don't logically differ much and will appear the same to the user, so we
-often want to treat them the same. The algorithms here (currently used only
-for the delete algorithm) allow navigating through such equivalent boundary
-points, for when we want to make the selection as inclusive or exclusive as
-possible. For deletion, we want to delete as few nodes as possible, so we move
-the start node forward and the end node backward. In other cases we might do
-the reverse, expanding the selection.
-
-<p>Given a [[boundarypoint]] (<var>node</var>, <var>offset</var>), the
-<dfn>next equivalent point</dfn> is either a [[boundarypoint]] or null, as
-returned by the following algorithm:
-
-<ol>
- <li>If <var>node</var>'s [[length]] is zero, return null.
-
- <li class=note>We don't want to move into or out of zero-length nodes,
- because that would move us straight through them. For instance, if
- {{code|{}<span></span>}} were equivalent to {{code|<span>{}</span>}}, it
- would also be equivalent to {{code|<span></span>{} }}. This produces very
- unexpected results for nodes like {{code|<br>}}.
-
- <li>If <var>offset</var> is <var>node</var>'s [[length]], and
- <var>node</var>'s [[parent]] is not null, return (<var>node</var>'s
- [[parent]], 1 + <var>node</var>'s [[index]]).
-
- <li class=note>For instance, {{code|<span>foo[]</span>}} is equivalent to
- {{code|<span>foo{}</span>}}, which is equivalent to {{code|<span>foo</span>{}
- }}.
-
- <li>If <var>node</var> has a [[child]] with [[index]] <var>offset</var>,
- and that [[child]]'s [[length]] is not zero, return (that [[child]], 0).
-
- <li class=note>For instance, {{code|{}<span>foo</span>}} is equivalent to
- {{code|<span>{}foo</span>}}, which is equivalent to
- {{code|<span>[]foo</span>}}. As noted before, though, we don't descend into
- empty nodes.
-
- <li>Return null.
-</ol>
-
-<p>Given a [[boundarypoint]] (<var>node</var>, <var>offset</var>), the
-<dfn>previous equivalent point</dfn> is either a [[boundarypoint]] or null, as
-returned by the following algorithm:
-
-<ol>
- <li>If <var>node</var>'s [[length]] is zero, return null.
-
- <li>If <var>offset</var> is 0, and <var>node</var>'s [[parent]] is not null,
- return (<var>node</var>'s [[parent]], <var>node</var>'s [[index]]).
-
- <li>If <var>node</var> has a [[child]] with [[index]] <var>offset</var>
- − 1, and that [[child]]'s [[length]] is not zero, return (that
- [[child]], that [[child]]'s [[length]]).
-
- <li>Return null.
-</ol>
-
-<!-- Turned out not to be necessary here, but I've left it in case it turns out
-to be handy elsewhere. -->
-<!--
-<p>Two [[boundarypoints]] <var>A</var> and <var>B</var> are <dfn>equivalent
-boundary points</dfn> if the following algorithm returns true:
-
-<p class=note>This is indeed an <a
-href=http://en.wikipedia.org/wiki/Equivalence_relation>equivalence
-relation</a>. Reflexivity, symmetry, and transitivity are all fairly obvious
-from the definition. It also isn't hard to check that using <span>next
-equivalent point</span> instead of <span>previous equivalent point</span> would
-yield the same definition, because the two algorithms are inverses if neither
-output is null.
-
-<ol>
- <li>While <var>A</var>'s <span>previous equivalent point</span> is not null,
- set <var>A</var> to its <span>previous equivalent point</span>.
-
- <li>While <var>B</var>'s <span>previous equivalent point</span> is not null,
- set <var>B</var> to its <span>previous equivalent point</span>.
-
- <li>Return true if <var>A</var> is the same as <var>B</var>, otherwise false.
-</ol>
--->
-
-<p>The <dfn>block node of</dfn> a [[node]] <var>node</var> is either a
-<span>block node</span> or null, as returned by the following algorithm:
-
-<ol>
- <li>While <var>node</var> is an <span>inline node</span>, set <var>node</var>
- to its [[parent]].
-
- <li>Return <var>node</var>.
-</ol>
-
-<p>Two [[nodes]] are <dfn>in the same block</dfn> if the <span>block node
-of</span> the first is non-null and the same as the <span>block node of</span>
-the second.
<p class=comments>TODO: Consider what should happen for block merging in corner
cases like display: inline-table.