Fix selection handling for insertParagraph/Text
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Thu, 11 Aug 2011 15:19:29 -0600
changeset 519 2dea04282819
parent 518 c4ef24e60c09
child 520 da6f8f48e839
Fix selection handling for insertParagraph/Text

This makes the selection go in the right place when you type letters or
hit Enter in editor.html. More fixes to come.
editing.html
implementation.js
source.html
--- a/editing.html	Thu Aug 11 14:55:07 2011 -0600
+++ b/editing.html	Thu Aug 11 15:19:29 2011 -0600
@@ -7885,10 +7885,8 @@
   <li>If the <a href=#active-range>active range</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</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>node</a> is neither
   <a href=#editable>editable</a> nor an <a href=#editing-host>editing host</a>, abort these steps.
 
-  <li>Let <var title="">range</var> be the <a href=#active-range>active range</a>.
-
-  <li>Let <var title="">node</var> and <var title="">offset</var> be <var title="">range</var>'s
-  <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</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>node</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>offset</a>.
+  <li>Let <var title="">node</var> and <var title="">offset</var> be the <a href=#active-range>active
+  range</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</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>node</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>offset</a>.
 
   <li>If <var title="">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> node, and <var title="">offset</var> is neither 0
   nor the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of <var title="">node</var>, call
@@ -7902,8 +7900,8 @@
   <var title="">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 <var title="">node</var>, then set
   <var title="">node</var> to its <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>Set <var title="">range</var>'s <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> to
-  (<var title="">node</var>, <var title="">offset</var>).
+  <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var>)</a></code> on the
+  <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
 
   <li>Let <var title="">container</var> equal <var title="">node</var>.
 
@@ -7923,8 +7921,8 @@
     <li>Let <var title="">tag</var> be the <a href=#default-single-line-container-name>default single-line container
     name</a>.
 
-    <li><a href=#block-extend>Block-extend</a> <var title="">range</var>, and let <var title="">new
-    range</var> be the result.
+    <li><a href=#block-extend>Block-extend</a> the <a href=#active-range>active range</a>, 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.
 
@@ -7943,18 +7941,19 @@
       case where deleting can leave the cursor inside a &lt;tr&gt;.
 
       <p>If <var title="">tag</var> is not an <a href=#allowed-child>allowed child</a> of
-      <var title="">range</var>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</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>node</a>, abort these steps.
+      the <a href=#active-range>active range</a>'s <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-start title=concept-range-start>start</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>node</a>, abort these steps.
 
       <li>Set <var title="">container</var> to the result of calling
       <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement(<var title="">tag</var>)</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>.
 
-      <li>Call <code class=external data-anolis-spec=domrange title=dom-Range-insertNode><a href=http://html5.org/specs/dom-range.html#dom-range-insertnode>insertNode(<var title="">container</var>)</a></code> on <var title="">range</var>.
+      <li>Call <code class=external data-anolis-spec=domrange title=dom-Range-insertNode><a href=http://html5.org/specs/dom-range.html#dom-range-insertnode>insertNode(<var title="">container</var>)</a></code> on the <a href=#active-range>active
+      range</a>.
 
       <li>Call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>, and append the
       result as the last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">container</var>.
 
-      <li>Set <var title="">range</var>'s <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> to
-      (<var title="">container</var>, 0).
+      <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">container</var>, 0)</a></code> on the
+      <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
 
       <li>Abort these steps.
     </ol>
@@ -8003,10 +8002,10 @@
     <li>Let <var title="">br</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on
     the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>.
 
-    <li>Call <code class=external data-anolis-spec=domrange title=dom-Range-insertNode><a href=http://html5.org/specs/dom-range.html#dom-range-insertnode>insertNode(<var title="">br</var>)</a></code> on <var title="">range</var>.
-
-    <li>Increment <var title="">range</var>'s <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-offset title=concept-boundary-point-offset>offsets</a>.
+    <li>Call <code class=external data-anolis-spec=domrange title=dom-Range-insertNode><a href=http://html5.org/specs/dom-range.html#dom-range-insertnode>insertNode(<var title="">br</var>)</a></code> on the <a href=#active-range>active range</a>.
+
+    <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">node</var>, <var title="">offset</var> + 1)</a></code> on the
+    <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
 
     <li>
     <p class=comments>Necessary because adding a br to the end of a block
@@ -8016,7 +8015,7 @@
     <p>If <var title="">br</var> is the last <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="">container</var>,
     let <var title="">br</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the
     <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>, then call <code class=external data-anolis-spec=domrange title=dom-Range-insertNode><a href=http://html5.org/specs/dom-range.html#dom-range-insertnode>insertNode(<var title="">br</var>)</a></code> on
-    <var title="">range</var>.
+    the <a href=#active-range>active range</a>.
 
     <li>Abort these steps.
   </ol>
@@ -8055,7 +8054,7 @@
   </ol>
 
   <li>Let <var title="">new line range</var> be a new <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> is
-  the same as <var title="">range</var>'s, and whose <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> is
+  the same as the <a href=#active-range>active range</a>'s, and whose <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range-end title=concept-range-end>end</a> is
   (<var title="">container</var>, <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-node-length title=concept-node-length>length</a> of <var title="">container</var>).
 
   <li>
@@ -8144,8 +8143,8 @@
   call <code class=external data-anolis-spec=domcore title=dom-Document-createElement><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createelement>createElement("br")</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>, and append the result
   as the last <a class=external data-anolis-spec=domcore href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of <var title="">new container</var>.
 
-  <li>Set 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> of <var title="">range</var> to (<var title="">new container</var>,
-  0).
+  <li>Call <code class=external data-anolis-spec=domrange title=dom-Selection-collapse><a href=http://html5.org/specs/dom-range.html#dom-selection-collapse>collapse(<var title="">new container</var>, 0)</a></code> on the
+  <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#context-object>context object</a>'s <code class=external data-anolis-spec=domrange><a href=http://html5.org/specs/dom-range.html#selection>Selection</a></code>.
 </ol>
 
 
--- a/implementation.js	Thu Aug 11 14:55:07 2011 -0600
+++ b/implementation.js	Thu Aug 11 15:19:29 2011 -0600
@@ -189,7 +189,6 @@
 	return getDirectionality(element.parentNode);
 }
 
-
 //@}
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -6771,12 +6770,9 @@
 			return;
 		}
 
-		// "Let range be the active range."
-		var range = getActiveRange();
-
-		// "Let node and offset be range's start node and offset."
-		var node = range.startContainer;
-		var offset = range.startOffset;
+		// "Let node and offset be the active range's start node and offset."
+		var node = getActiveRange().startContainer;
+		var offset = getActiveRange().startOffset;
 
 		// "If node is a Text node, and offset is neither 0 nor the length of
 		// node, call splitText(offset) on node."
@@ -6802,9 +6798,10 @@
 			node = node.parentNode;
 		}
 
-		// "Set range's start and end to (node, offset)."
-		range.setStart(node, offset);
-		range.setEnd(node, offset);
+		// "Call collapse(node, offset) on the context object's Selection."
+		getSelection().collapse(node, offset);
+		getActiveRange().setStart(node, offset);
+		getActiveRange().setEnd(node, offset);
 
 		// "Let container equal node."
 		var container = node;
@@ -6826,8 +6823,9 @@
 			// "Let tag be the default single-line container name."
 			var tag = defaultSingleLineContainerName;
 
-			// "Block-extend range, and let new range be the result."
-			var newRange = blockExtend(range);
+			// "Block-extend the active range, and let new range be the
+			// result."
+			var newRange = blockExtend(getActiveRange());
 
 			// "Let node list be a list of nodes, initially empty."
 			//
@@ -6838,9 +6836,9 @@
 
 			// "If node list is empty:"
 			if (!nodeList.length) {
-				// "If tag is not an allowed child of range's start node, abort
-				// these steps."
-				if (!isAllowedChild(tag, range.startContainer)) {
+				// "If tag is not an allowed child of the active range's start
+				// node, abort these steps."
+				if (!isAllowedChild(tag, getActiveRange().startContainer)) {
 					return;
 				}
 
@@ -6848,16 +6846,18 @@
 				// on the context object."
 				container = document.createElement(tag);
 
-				// "Call insertNode(container) on range."
-				range.insertNode(container);
+				// "Call insertNode(container) on the active range."
+				getActiveRange().insertNode(container);
 
 				// "Call createElement("br") on the context object, and append
 				// the result as the last child of container."
 				container.appendChild(document.createElement("br"));
 
-				// "Set range's start and end to (container, 0)."
-				range.setStart(container, 0);
-				range.setEnd(container, 0);
+				// "Call collapse(container, 0) on the context object's
+				// Selection."
+				getSelection().collapse(container, 0);
+				getActiveRange().setStart(container, 0);
+				getActiveRange().setEnd(container, 0);
 
 				// "Abort these steps."
 				return;
@@ -6888,27 +6888,25 @@
 			// context object."
 			var br = document.createElement("br");
 
-			// "Call insertNode(br) on range."
-			//
-			// Work around browser bugs: some browsers select the inserted
-			// node, not per spec.
-			range.insertNode(br);
-			range.setEnd(range.startContainer, range.startOffset);
-
-			// "Increment range's start and end offsets."
-			//
-			// Incrementing the start will increment the end as well, because
-			// the range is collapsed.
-			range.setStart(range.startContainer, range.startOffset + 1);
+			// "Call insertNode(br) on the active range."
+			getActiveRange().insertNode(br);
+
+			// "Call collapse(node, offset + 1) on the context object's
+			// Selection."
+			getSelection().collapse(node, offset + 1);
+			getActiveRange().setStart(node, offset + 1);
+			getActiveRange().setEnd(node, offset + 1);
 
 			// "If br is the last descendant of container, let br be the result
 			// of calling createElement("br") on the context object, then call
-			// insertNode(br) on range."
+			// insertNode(br) on the active range."
 			//
-			// Work around browser bugs again.
+			// Work around browser bugs: some browsers select the
+			// newly-inserted node, not per spec.
 			if (!isDescendant(nextNode(br), container)) {
-				range.insertNode(document.createElement("br"));
-				range.setEnd(range.startContainer, range.startOffset);
+				getActiveRange().insertNode(document.createElement("br"));
+				getSelection().collapse(node, offset + 1);
+				getActiveRange().setEnd(node, offset + 1);
 			}
 
 			// "Abort these steps."
@@ -6951,9 +6949,10 @@
 		}
 
 		// "Let new line range be a new range whose start is the same as
-		// range's, and whose end is (container, length of container)."
+		// the active range's, and whose end is (container, length of
+		// container)."
 		var newLineRange = document.createRange();
-		newLineRange.setStart(range.startContainer, range.startOffset);
+		newLineRange.setStart(getActiveRange().startContainer, getActiveRange().startOffset);
 		newLineRange.setEnd(container, getNodeLength(container));
 
 		// "While new line range's start offset is zero and its start node is
@@ -7054,8 +7053,10 @@
 			newContainer.appendChild(document.createElement("br"));
 		}
 
-		// "Set the start of range to (new container, 0)."
-		range.setStart(newContainer, 0);
+		// "Call collapse(new container, 0) on the context object's Selection."
+		getSelection().collapse(newContainer, 0);
+		getActiveRange().setStart(newContainer, 0);
+		getActiveRange().setEnd(newContainer, 0);
 	}
 };
 
@@ -7143,10 +7144,12 @@
 			node.insertData(offset, value);
 
 			// "Call collapse(node, offset) on the context object's Selection."
-			//
+			getSelection().collapse(node, offset);
+			getActiveRange().setStart(node, offset);
+
 			// "Call extend(node, offset + 1) on the context object's
 			// Selection."
-			getActiveRange().setStart(node, offset);
+			getSelection().extend(node, offset + 1);
 			getActiveRange().setEnd(node, offset + 1);
 
 		// "Otherwise:"
@@ -7169,9 +7172,11 @@
 			getActiveRange().insertNode(text);
 
 			// "Call collapse(text, 0) on the context object's Selection."
-			//
+			getSelection().collapse(text, 0);
+			getActiveRange().setStart(text, 0);
+
 			// "Call extend(text, 1) on the context object's Selection."
-			getActiveRange().setStart(text, 0);
+			getSelection().extend(text, 1);
 			getActiveRange().setEnd(text, 1);
 		}
 
@@ -7185,6 +7190,7 @@
 		canonicalizeWhitespace(getActiveRange().endContainer, getActiveRange().endOffset);
 
 		// "Call collapseToEnd() on the context object's Selection."
+		getSelection().collapseToEnd();
 		getActiveRange().collapse(false);
 	}
 };
--- a/source.html	Thu Aug 11 14:55:07 2011 -0600
+++ b/source.html	Thu Aug 11 15:19:29 2011 -0600
@@ -7950,10 +7950,8 @@
   <li>If the <span>active range</span>'s [[startnode]] is neither
   <span>editable</span> nor an <span>editing host</span>, abort these steps.
 
-  <li>Let <var>range</var> be the <span>active range</span>.
-
-  <li>Let <var>node</var> and <var>offset</var> be <var>range</var>'s
-  [[rangestart]] [[bpnode]] and [[bpoffset]].
+  <li>Let <var>node</var> and <var>offset</var> be the <span>active
+  range</span>'s [[rangestart]] [[bpnode]] and [[bpoffset]].
 
   <li>If <var>node</var> is a [[text]] node, and <var>offset</var> is neither 0
   nor the [[nodelength]] of <var>node</var>, call
@@ -7967,8 +7965,8 @@
   <var>offset</var> to the [[index]] of <var>node</var>, then set
   <var>node</var> to its [[parent]].
 
-  <li>Set <var>range</var>'s [[rangestart]] and [[rangeend]] to
-  (<var>node</var>, <var>offset</var>).
+  <li>Call [[selcollapse|<var>node</var>, <var>offset</var>]] on the
+  [[contextobject]]'s [[selection]].
 
   <li>Let <var>container</var> equal <var>node</var>.
 
@@ -7988,8 +7986,8 @@
     <li>Let <var>tag</var> be the <span>default single-line container
     name</span>.
 
-    <li><span>Block-extend</span> <var>range</var>, and let <var>new
-    range</var> be the result.
+    <li><span>Block-extend</span> the <span>active range</span>, and let
+    <var>new range</var> be the result.
 
     <li>Let <var>node list</var> be a list of [[nodes]], initially empty.
 
@@ -8008,18 +8006,19 @@
       case where deleting can leave the cursor inside a &lt;tr>.
 
       <p>If <var>tag</var> is not an <span>allowed child</span> of
-      <var>range</var>'s [[startnode]], abort these steps.
+      the <span>active range</span>'s [[startnode]], abort these steps.
 
       <li>Set <var>container</var> to the result of calling
       [[createelement|<var>tag</var>]] on the [[contextobject]].
 
-      <li>Call [[insertnode|<var>container</var>]] on <var>range</var>.
+      <li>Call [[insertnode|<var>container</var>]] on the <span>active
+      range</span>.
 
       <li>Call [[createelement|"br"]] on the [[contextobject]], and append the
       result as the last [[child]] of <var>container</var>.
 
-      <li>Set <var>range</var>'s [[rangestart]] and [[rangeend]] to
-      (<var>container</var>, 0).
+      <li>Call [[selcollapse|<var>container</var>, 0]] on the
+      [[contextobject]]'s [[selection]].
 
       <li>Abort these steps.
     </ol>
@@ -8068,10 +8067,10 @@
     <li>Let <var>br</var> be the result of calling [[createelement|"br"]] on
     the [[contextobject]].
 
-    <li>Call [[insertnode|<var>br</var>]] on <var>range</var>.
-
-    <li>Increment <var>range</var>'s [[rangestart]] and [[rangeend]]
-    [[bpoffsets]].
+    <li>Call [[insertnode|<var>br</var>]] on the <span>active range</span>.
+
+    <li>Call [[selcollapse|<var>node</var>, <var>offset</var> + 1]] on the
+    [[contextobject]]'s [[selection]].
 
     <li>
     <p class=comments>Necessary because adding a br to the end of a block
@@ -8081,7 +8080,7 @@
     <p>If <var>br</var> is the last [[descendant]] of <var>container</var>,
     let <var>br</var> be the result of calling [[createelement|"br"]] on the
     [[contextobject]], then call [[insertnode|<var>br</var>]] on
-    <var>range</var>.
+    the <span>active range</span>.
 
     <li>Abort these steps.
   </ol>
@@ -8120,7 +8119,7 @@
   </ol>
 
   <li>Let <var>new line range</var> be a new [[range]] whose [[rangestart]] is
-  the same as <var>range</var>'s, and whose [[rangeend]] is
+  the same as the <span>active range</span>'s, and whose [[rangeend]] is
   (<var>container</var>, [[nodelength]] of <var>container</var>).
 
   <li>
@@ -8210,8 +8209,8 @@
   call [[createelement|"br"]] on the [[contextobject]], and append the result
   as the last [[child]] of <var>new container</var>.
 
-  <li>Set the [[rangestart]] of <var>range</var> to (<var>new container</var>,
-  0).
+  <li>Call [[selcollapse|<var>new container</var>, 0]] on the
+  [[contextobject]]'s [[selection]].
 </ol>
 
 <!-- @} -->