Fix unserializable DOM bug in insertParagraph
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Tue, 14 Jun 2011 13:30:27 -0600
changeset 266 1d0a04ff0556
parent 265 d0c3ee5a4708
child 267 3269074b8e4f
Fix unserializable DOM bug in insertParagraph

Something like <table>{<tr><td>foo</tr>}</table> would become
<table>{}<tr><td></table> and then <table><p>{}<br></p><tr><td></table>
or similar. There might be other cases where this could have cropped up
too.
editcommands.html
implementation.js
source.html
tests.js
--- a/editcommands.html	Tue Jun 14 12:58:44 2011 -0600
+++ b/editcommands.html	Tue Jun 14 13:30:27 2011 -0600
@@ -5037,6 +5037,14 @@
     <li>If <var title="">node list</var> is empty:
 
     <ol>
+      <!-- Ideally, we should normalize things so that the cursor is never in a
+      weird place after deletion, but let's be safe and bail out if we do hit
+      this scenario.  It's not clear if we need this line in the long term, but
+      at the time of this writing there's at least one corner case where
+      deleting can leave the cursor inside a <tr>. -->
+      <li>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.
+
       <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>.
 
--- a/implementation.js	Tue Jun 14 12:58:44 2011 -0600
+++ b/implementation.js	Tue Jun 14 13:30:27 2011 -0600
@@ -3883,6 +3883,12 @@
 
 			// "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)) {
+					return;
+				}
+
 				// "Set container to the result of calling createElement(tag)
 				// on the context object."
 				container = document.createElement(tag);
--- a/source.html	Tue Jun 14 12:58:44 2011 -0600
+++ b/source.html	Tue Jun 14 13:30:27 2011 -0600
@@ -5057,6 +5057,14 @@
     <li>If <var>node list</var> is empty:
 
     <ol>
+      <!-- Ideally, we should normalize things so that the cursor is never in a
+      weird place after deletion, but let's be safe and bail out if we do hit
+      this scenario.  It's not clear if we need this line in the long term, but
+      at the time of this writing there's at least one corner case where
+      deleting can leave the cursor inside a <tr>. -->
+      <li>If <var>tag</var> is not an <span>allowed child</span> of
+      <var>range</var>'s [[startnode]], abort these steps.
+
       <li>Set <var>container</var> to the result of calling
       [[createelement|<var>tag</var>]] on the [[contextobject]].
 
--- a/tests.js	Tue Jun 14 12:58:44 2011 -0600
+++ b/tests.js	Tue Jun 14 13:30:27 2011 -0600
@@ -1293,6 +1293,15 @@
 	],
 	insertparagraph: [
 		'foo[bar]baz',
+		'fo[o<table><tr><td>b]ar</table>',
+		'<table><tr><td>[foo<td>bar]<tr><td>baz<td>quz</table>',
+		'<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<tr><td>baz<td>quz</table>',
+		'<table><tr><td>fo[o</table>b]ar',
+		'<table><tr><td>fo[o<td>b]ar<td>baz</table>',
+		'{<table><tr><td>foo</table>}',
+		'<table><tr><td>[foo]</table>',
+		'<ol><li>[foo]<li>bar</ol>',
+		'<ol><li>f[o]o<li>bar</ol>',
 
 		'[]foo',
 		'foo[]',
@@ -1361,6 +1370,16 @@
 		'<table><tr><td>foo[]bar</table>',
 		'<table><tr><td><p>foo[]bar</table>',
 
+		'<blockquote>[]foo</blockquote>',
+		'<blockquote>foo[]</blockquote>',
+		'<blockquote>foo[]<br></blockquote>',
+		'<blockquote>foo[]bar</blockquote>',
+		'<blockquote><p>[]foo</blockquote>',
+		'<blockquote><p>foo[]</blockquote>',
+		'<blockquote><p>foo[]bar</blockquote>',
+		'<blockquote><p>foo[]<p>bar</blockquote>',
+		'<blockquote><p>foo[]bar<p>baz</blockquote>',
+
 		'<span>foo[]bar</span>',
 		'<span>foo[]bar</span>baz',
 		'<b>foo[]bar</b>',
@@ -1374,7 +1393,12 @@
 		'<p><b>foo[]bar</b></p>',
 		'<p><b>[]foo</b></p>',
 		'<p><b id=x class=y>foo[]bar</b></p>',
-		'<div><b>foo[]bar</b></div>'
+		'<div><b>foo[]bar</b></div>',
+
+		'<a href=foo>foo[]bar</a>',
+		'<a href=foo>foo[]bar</a>baz',
+		'<a href=foo>foo[]</a>bar',
+		'foo<a href=foo>[]bar</a>',
 	],
 	insertunorderedlist: [
 		'foo[]bar',