Handle indentation in delete command
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Sun, 12 Jun 2011 15:00:06 -0600
changeset 261 a0c5e24746f5
parent 260 b380de7b4ecf
child 262 687ca0631209
Handle indentation in delete command
editcommands.html
implementation.js
source.html
tests.js
--- a/editcommands.html	Sun Jun 12 14:34:36 2011 -0600
+++ b/editcommands.html	Sun Jun 12 15:00:06 2011 -0600
@@ -2587,8 +2587,6 @@
     <li>Abort these steps.
   </ol>
 
-  <p class=XXX>blockquote?
-
   <!-- By this point, we're almost certainly going to merge something, and the
   only question is what. -->
   <li>Let <var title="">start node</var> equal <var title="">node</var> and let <var title="">start
@@ -2602,6 +2600,34 @@
   node.
 
   <!--
+  At the beginning of an indented block, outdent it, similar to a list item.
+  -->
+  <li>If <var title="">offset</var> is zero, and <var title="">node</var> has an
+  <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#ancestor-container title="ancestor container">ancestor container</a> that is both a <a href=#potential-indentation-element>potential indentation
+  element</a> and a <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-descendant title=concept-tree-descendant>descendant</a> of <var title="">start node</var>:
+
+  <p class=XXX>This copy-pastes from the outdent command action.  I'm also not
+  totally sure it's correct.
+
+  <ol>
+    <li><a href=#block-extend>Block-extend</a> the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a> whose <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> are both (<var title="">node</var>, 0), and let <var title="">new range</var> be
+    the result.
+
+    <li>Let <var title="">node list</var> be a list of <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>nodes</a>, initially empty.
+
+    <li>For each <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> <var title="">current node</var> <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#contained>contained</a> in <var title="">new
+    range</var>, append <var title="">current node</var> to <var title="">node list</var> if the
+    last member of <var title="">node list</var> (if any) is not an <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-ancestor title=concept-tree-ancestor>ancestor</a> of
+    <var title="">current node</var>, and <var title="">current node</var> is
+    <a href=#editable>editable</a> but has no <a href=#editable>editable</a> <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-descendant title=concept-tree-descendant>descendants</a>.
+
+    <li><a href=#outdent>Outdent</a> each <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> in <var title="">node list</var>.
+
+    <li>Abort these steps.
+  </ol>
+
+  <!--
   This is to avoid stripping a line break from
 
     foo<br><br><table><tr><td>[]bar</table>
--- a/implementation.js	Sun Jun 12 14:34:36 2011 -0600
+++ b/implementation.js	Sun Jun 12 15:00:06 2011 -0600
@@ -3319,6 +3319,47 @@
 			startNode = startNode.parentNode;
 		}
 
+		// "If offset is zero, and node has an ancestor container that is both
+		// a potential indentation element and a descendant of start node:"
+		var outdentableAncestor = false;
+		for (
+			var ancestor = node;
+			isDescendant(ancestor, startNode);
+			ancestor = ancestor.parentNode
+		) {
+			if (isPotentialIndentationElement(ancestor)) {
+				outdentableAncestor = true;
+				break;
+			}
+		}
+		if (offset == 0
+		&& outdentableAncestor) {
+			// "Block-extend the range whose start and end are both (node, 0),
+			// and let new range be the result."
+			var newRange = document.createRange();
+			newRange.setStart(node, 0);
+			newRange = blockExtendRange(newRange);
+
+			// "Let node list be a list of nodes, initially empty."
+			//
+			// "For each node current node contained in new range, append
+			// current node to node list if the last member of node list (if
+			// any) is not an ancestor of current node, and current node is
+			// editable but has no editable descendants."
+			var nodeList = collectContainedNodes(newRange, function(currentNode) {
+				return isEditable(currentNode)
+					&& !hasEditableDescendants(currentNode);
+			});
+
+			// "Outdent each node in node list."
+			for (var i = 0; i < nodeList.length; i++) {
+				outdentNode(nodeList[i]);
+			}
+
+			// "Abort these steps."
+			return;
+		}
+
 		// "If the child of start node with index start offset is a table,
 		// abort these steps."
 		if (isHtmlElement(startNode.childNodes[startOffset], "table")) {
--- a/source.html	Sun Jun 12 14:34:36 2011 -0600
+++ b/source.html	Sun Jun 12 15:00:06 2011 -0600
@@ -2567,8 +2567,6 @@
     <li>Abort these steps.
   </ol>
 
-  <p class=XXX>blockquote?
-
   <!-- By this point, we're almost certainly going to merge something, and the
   only question is what. -->
   <li>Let <var>start node</var> equal <var>node</var> and let <var>start
@@ -2582,6 +2580,34 @@
   node.
 
   <!--
+  At the beginning of an indented block, outdent it, similar to a list item.
+  -->
+  <li>If <var>offset</var> is zero, and <var>node</var> has an
+  [[ancestorcontainer]] that is both a <span>potential indentation
+  element</span> and a [[descendant]] of <var>start node</var>:
+
+  <p class=XXX>This copy-pastes from the outdent command action.  I'm also not
+  totally sure it's correct.
+
+  <ol>
+    <li><span>Block-extend</span> the [[range]] whose [[rangestart]] and
+    [[rangeend]] are both (<var>node</var>, 0), and let <var>new range</var> be
+    the result.
+
+    <li>Let <var>node list</var> be a list of [[nodes]], initially empty.
+
+    <li>For each [[node]] <var>current node</var> [[contained]] in <var>new
+    range</var>, append <var>current node</var> to <var>node list</var> if the
+    last member of <var>node list</var> (if any) is not an [[ancestor]] of
+    <var>current node</var>, and <var>current node</var> is
+    <span>editable</span> but has no <span>editable</span> [[descendants]].
+
+    <li><span>Outdent</span> each [[node]] in <var>node list</var>.
+
+    <li>Abort these steps.
+  </ol>
+
+  <!--
   This is to avoid stripping a line break from
 
     foo<br><br><table><tr><td>[]bar</table>
--- a/tests.js	Sun Jun 12 14:34:36 2011 -0600
+++ b/tests.js	Sun Jun 12 15:00:06 2011 -0600
@@ -321,6 +321,24 @@
 		'<dl><dt>foo<dt>[]bar<dd>baz</dl>',
 		'<dl><dt>foo<dd>bar<dd>[]baz</dl>',
 
+		// Indented stuff with collapsed selection
+		'foo<blockquote>[]bar</blockquote>',
+		'foo<blockquote><blockquote>[]bar</blockquote></blockquote>',
+		'foo<blockquote><div>[]bar</div></blockquote>',
+		'foo<blockquote style="color: red">[]bar</blockquote>',
+
+		'foo<blockquote><blockquote><p>[]bar<p>baz</blockquote></blockquote>',
+		'foo<blockquote><div><p>[]bar<p>baz</div></blockquote>',
+		'foo<blockquote style="color: red"><p>[]bar<p>baz</blockquote>',
+
+		'foo<blockquote><p><b>[]bar</b><p>baz</blockquote>',
+		'foo<blockquote><p><strong>[]bar</strong><p>baz</blockquote>',
+		'foo<blockquote><p><span>[]bar</span><p>baz</blockquote>',
+
+		'foo<blockquote><ol><li>[]bar</ol></blockquote><p>extra',
+		'foo<blockquote>bar<ol><li>[]baz</ol>quz</blockquote><p>extra',
+		'foo<blockquote><ol><li>bar</li><ol><li>[]baz</ol><li>quz</ol></blockquote><p>extra',
+
 		// Invisible stuff with collapsed selection
 		'foo<span></span>[]bar',
 		'foo<span><span></span></span>[]bar',