Block-extending should select whole lis
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Thu, 05 May 2011 13:51:33 -0600
changeset 88 381a4d2e48ad
parent 87 b5cb0161423b
child 89 7bcd2fc49ec1
Block-extending should select whole lis

This means that will

<ol>
<li>foo<br>[bar]</li>
</ol>

will extend to select the whole <li>, for indenting or outdenting.
autoimplementation.html
editcommands.html
implementation.js
preprocess
source.html
--- a/autoimplementation.html	Thu May 05 13:09:04 2011 -0600
+++ b/autoimplementation.html	Thu May 05 13:51:33 2011 -0600
@@ -538,11 +538,17 @@
 		'<ol><li>foo</ol>[bar]',
 		'<ol><li>[foo]<br>bar<li>baz</ol>',
 		'<ol><li>foo<br>[bar]<li>baz</ol>',
+		'<ol><li><div>[foo]</div>bar<li>baz</ol>',
 		'<ol><li>foo<ol><li>[bar]<li>baz</ol><li>quz</ol>',
-		'<ol><li>foo<ul><li>[bar]<li>baz</ul><li>quz</ol>',
+		'<ol><li>foo<ol><li>bar<li>[baz]</ol><li>quz</ol>',
 		'<ol><li>foo</li><ol><li>[bar]<li>baz</ol><li>quz</ol>',
-		'<ol><li>foo</li><ul><li>[bar]<li>baz</ul><li>quz</ol>',
+		'<ol><li>foo</li><ol><li>bar<li>[baz]</ol><li>quz</ol>',
+		'<ol><li>[foo]<ol><li>bar</ol><li>baz</ol>',
+		'<ol><li>[foo]</li><ol><li>bar</ol><li>baz</ol>',
 		'<ol><li>foo<li>[bar]<ol><li>baz</ol><li>quz</ol>',
+		'<ol><li>foo<li>[bar]</li><ol><li>baz</ol><li>quz</ol>',
+		'<ol><li>foo<ol><li>bar<li>baz</ol><li>[quz]</ol>',
+		'<ol><li>foo</li><ol><li>bar<li>baz</ol><li>[quz]</ol>',
 	],
 	inserthorizontalrule: [
 		'foo[]bar',
--- a/editcommands.html	Thu May 05 13:09:04 2011 -0600
+++ b/editcommands.html	Thu May 05 13:51:33 2011 -0600
@@ -662,7 +662,11 @@
   and <var title="">end offset</var> be the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</a> and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-node title=concept-boundary-point-node>nodes</a>
   and <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-boundary-point-offset title=concept-boundary-point-offset>offsets</a> of <var title="">range</var>.
 
-  <li>Repeat the following steps:
+  <li>If some <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#ancestor-container title="ancestor container">ancestor container</a> of <var title="">start node</var> is an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code>, set
+  <var title="">start offset</var> to the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of the last such <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> in
+  <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#tree-order>tree order</a>, and set <var title="">start node</var> to that <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
+
+  <li>Otherwise, repeat the following steps:
 
   <ol>
     <li>If <var title="">start node</var> is a <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> or <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#comment>Comment</a></code> node or
@@ -687,7 +691,11 @@
     <li>Otherwise, break from this loop.
   </ol>
 
-  <li>Repeat the following steps:
+  <li>If some <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#ancestor-container title="ancestor container">ancestor container</a> of <var title="">end node</var> is an <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code>, set
+  <var title="">end offset</var> to one plus the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-indexof title=concept-indexof>index</a> of the last such <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code> in
+  <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#tree-order>tree order</a>, and set <var title="">end node</var> to that <code class=external data-anolis-spec=html title="the li element"><a href=http://www.whatwg.org/html/#the-li-element>li</a></code>'s <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a>.
+
+  <li>Otherwise, repeat the following steps:
 
   <ol>
     <li>If <var title="">end offset</var> is 0, set <var title="">end offset</var> to the
--- a/implementation.js	Thu May 05 13:09:04 2011 -0600
+++ b/implementation.js	Thu May 05 13:51:33 2011 -0600
@@ -1196,81 +1196,119 @@
 	var endNode = range.endContainer;
 	var endOffset = range.endOffset;
 
-	// "Repeat the following steps:"
-	while (true) {
-		// "If start node is a Text or Comment node or start offset is 0,
-		// set start offset to the index of start node and then set start
-		// node to its parent."
-		if (startNode.nodeType == Node.TEXT_NODE
-		|| startNode.nodeType == Node.COMMENT_NODE
-		|| startOffset == 0) {
-			startOffset = getNodeIndex(startNode);
-			startNode = startNode.parentNode;
-
-		// "Otherwise, if start offset is equal to the length of start
-		// node, set start offset to one plus the index of start node and
-		// then set start node to its parent."
-		} else if (startOffset == getNodeLength(startNode)) {
-			startOffset = 1 + getNodeIndex(startNode);
-			startNode = startNode.parentNode;
-
-		// "Otherwise, if the child of start node with index start offset and
-		// its previousSibling are both inline nodes and neither is a br,
-		// subtract one from start offset."
-		} else if (isInlineNode(startNode.childNodes[startOffset])
-		&& isInlineNode(startNode.childNodes[startOffset].previousSibling)
-		&& (
-			!isHtmlElement(startNode.childNodes[startOffset])
-			|| startNode.childNodes[startOffset].tagName != "BR"
-		) && (
-			!isHtmlElement(startNode.childNodes[startOffset].previousSibling)
-			|| startNode.childNodes[startOffset].previousSibling.tagName != "BR"
-		)) {
-			startOffset--;
-
-		// "Otherwise, break from this loop."
-		} else {
+	// "If some ancestor container of start node is an li, set start offset to
+	// the index of the last such li in tree order, and set start node to that
+	// li's parent."
+	var inLi = false;
+	for (
+		var ancestorContainer = startNode;
+		ancestorContainer;
+		ancestorContainer = ancestorContainer.parentNode
+	) {
+		if (isHtmlElement(ancestorContainer, "LI")) {
+			startOffset = getNodeIndex(ancestorContainer);
+			startNode = ancestorContainer.parentNode;
+			inLi = true;
 			break;
 		}
 	}
 
-	// "Repeat the following steps:"
-	while (true) {
-		// "If end offset is 0, set end offset to the index of end node and
-		// then set end node to its parent."
-		if (endOffset == 0) {
-			endOffset = getNodeIndex(endNode);
-			endNode = endNode.parentNode;
-
-		// "Otherwise, if end node is a Text or Comment node or end offset
-		// is equal to the length of end node, set end offset to one plus
-		// the index of end node and then set end node to its parent."
-		} else if (endNode.nodeType == Node.TEXT_NODE
-		|| endNode.nodeType == Node.COMMENT_NODE
-		|| endOffset == getNodeLength(endNode)) {
-			endOffset = 1 + getNodeIndex(endNode);
-			endNode = endNode.parentNode;
-
-		// "Otherwise, if the child of end node with index end offset and its
-		// previousSibling are both inline nodes and neither is a br, add one
-		// to end offset."
-		} else if (isInlineNode(endNode.childNodes[endOffset])
-		&& isInlineNode(endNode.childNodes[endOffset].previousSibling)
-		&& (
-			!isHtmlElement(endNode.childNodes[endOffset])
-			|| endNode.childNodes[endOffset].tagName != "BR"
-		) && (
-			!isHtmlElement(endNode.childNodes[endOffset].previousSibling)
-			|| endNode.childNodes[endOffset].previousSibling.tagName != "BR"
-		)) {
-			endOffset++;
-
-		// "Otherwise, break from this loop."
-		} else {
+	// "Otherwise, repeat the following steps:"
+	if (!inLi) {
+		while (true) {
+			// "If start node is a Text or Comment node or start offset is 0,
+			// set start offset to the index of start node and then set start
+			// node to its parent."
+			if (startNode.nodeType == Node.TEXT_NODE
+			|| startNode.nodeType == Node.COMMENT_NODE
+			|| startOffset == 0) {
+				startOffset = getNodeIndex(startNode);
+				startNode = startNode.parentNode;
+
+			// "Otherwise, if start offset is equal to the length of start
+			// node, set start offset to one plus the index of start node and
+			// then set start node to its parent."
+			} else if (startOffset == getNodeLength(startNode)) {
+				startOffset = 1 + getNodeIndex(startNode);
+				startNode = startNode.parentNode;
+
+			// "Otherwise, if the child of start node with index start offset and
+			// its previousSibling are both inline nodes and neither is a br,
+			// subtract one from start offset."
+			} else if (isInlineNode(startNode.childNodes[startOffset])
+			&& isInlineNode(startNode.childNodes[startOffset].previousSibling)
+			&& (
+				!isHtmlElement(startNode.childNodes[startOffset])
+				|| startNode.childNodes[startOffset].tagName != "BR"
+			) && (
+				!isHtmlElement(startNode.childNodes[startOffset].previousSibling)
+				|| startNode.childNodes[startOffset].previousSibling.tagName != "BR"
+			)) {
+				startOffset--;
+
+			// "Otherwise, break from this loop."
+			} else {
+				break;
+			}
+		}
+	}
+
+	// "If some ancestor container of end node is an li, set end offset to one
+	// plus the index of the last such li in tree order, and set end node to
+	// that li's parent."
+	var inLi = false;
+	for (
+		var ancestorContainer = endNode;
+		ancestorContainer;
+		ancestorContainer = ancestorContainer.parentNode
+	) {
+		if (isHtmlElement(ancestorContainer, "LI")) {
+			endOffset = 1 + getNodeIndex(ancestorContainer);
+			endNode = ancestorContainer.parentNode;
+			inLi = true;
 			break;
 		}
 	}
 
+	// "Otherwise, repeat the following steps:"
+	if (!inLi) {
+		while (true) {
+			// "If end offset is 0, set end offset to the index of end node and
+			// then set end node to its parent."
+			if (endOffset == 0) {
+				endOffset = getNodeIndex(endNode);
+				endNode = endNode.parentNode;
+
+			// "Otherwise, if end node is a Text or Comment node or end offset
+			// is equal to the length of end node, set end offset to one plus
+			// the index of end node and then set end node to its parent."
+			} else if (endNode.nodeType == Node.TEXT_NODE
+			|| endNode.nodeType == Node.COMMENT_NODE
+			|| endOffset == getNodeLength(endNode)) {
+				endOffset = 1 + getNodeIndex(endNode);
+				endNode = endNode.parentNode;
+
+			// "Otherwise, if the child of end node with index end offset and its
+			// previousSibling are both inline nodes and neither is a br, add one
+			// to end offset."
+			} else if (isInlineNode(endNode.childNodes[endOffset])
+			&& isInlineNode(endNode.childNodes[endOffset].previousSibling)
+			&& (
+				!isHtmlElement(endNode.childNodes[endOffset])
+				|| endNode.childNodes[endOffset].tagName != "BR"
+			) && (
+				!isHtmlElement(endNode.childNodes[endOffset].previousSibling)
+				|| endNode.childNodes[endOffset].previousSibling.tagName != "BR"
+			)) {
+				endOffset++;
+
+			// "Otherwise, break from this loop."
+			} else {
+				break;
+			}
+		}
+	}
+
 	// "Let new range be a new range whose start and end nodes and offsets
 	// are start node, start offset, end node, and end offset."
 	var newRange = startNode.ownerDocument.createRange();
--- a/preprocess	Thu May 05 13:09:04 2011 -0600
+++ b/preprocess	Thu May 05 13:51:33 2011 -0600
@@ -8,6 +8,7 @@
 replace = {
     'a': '<code data-anolis-spec=html title="the a element">a</code>',
     'ancestor': '<span data-anolis-spec=domcore title=concept-tree-ancestor>ancestor</span>',
+    'ancestorcontainer': '<span data-anolis-spec=domrange title="ancestor container">ancestor container</span>',
     'attrlocalname': '<span data-anolis-spec=domcore title=concept-attr-local-name>local name</span>',
     'attrvalue': '<span data-anolis-spec=domcore title=concept-attr-value>value</span>',
     'b': '<code data-anolis-spec=html title="the b element">b</code>',
--- a/source.html	Thu May 05 13:09:04 2011 -0600
+++ b/source.html	Thu May 05 13:51:33 2011 -0600
@@ -659,7 +659,11 @@
   and <var>end offset</var> be the [[rangestart]] and [[rangeend]] [[bpnodes]]
   and [[bpoffsets]] of <var>range</var>.
 
-  <li>Repeat the following steps:
+  <li>If some [[ancestorcontainer]] of <var>start node</var> is an [[li]], set
+  <var>start offset</var> to the [[index]] of the last such [[li]] in
+  [[treeorder]], and set <var>start node</var> to that [[li]]'s [[parent]].
+
+  <li>Otherwise, repeat the following steps:
 
   <ol>
     <li>If <var>start node</var> is a [[text]] or [[comment]] node or
@@ -685,7 +689,11 @@
     <li>Otherwise, break from this loop.
   </ol>
 
-  <li>Repeat the following steps:
+  <li>If some [[ancestorcontainer]] of <var>end node</var> is an [[li]], set
+  <var>end offset</var> to one plus the [[index]] of the last such [[li]] in
+  [[treeorder]], and set <var>end node</var> to that [[li]]'s [[parent]].
+
+  <li>Otherwise, repeat the following steps:
 
   <ol>
     <li>If <var>end offset</var> is 0, set <var>end offset</var> to the