Ensure createLink doesn't make unserializable DOMs
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Fri, 13 May 2011 15:54:19 -0600
changeset 120 577781808581
parent 119 fe300217c1b0
child 121 02f81db3e26b
Ensure createLink doesn't make unserializable DOMs
editcommands.html
implementation.js
source.html
--- a/editcommands.html	Fri May 13 15:42:04 2011 -0600
+++ b/editcommands.html	Fri May 13 15:54:19 2011 -0600
@@ -1298,10 +1298,35 @@
     of <var title="">new parent</var> to <var title="">new value</var>.
   </ol>
 
-  <li>If <var title="">command</var> is "createLink" or "unlink", let <var title="">new
-  parent</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("a")</a></code> on the
-  <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>, then set the <code class=external data-anolis-spec=html title=attr-hyperlink-href><a href=http://www.whatwg.org/html/#attr-hyperlink-href>href</a></code> attribute of
-  <var title="">new parent</var> to <var title="">new value</var>.
+  <li>If <var title="">command</var> is "createLink" or "unlink":
+
+  <ol>
+    <li>Let <var title="">new parent</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("a")</a></code> on the
+    <code class=external data-anolis-spec=domcore title=dom-Node-ownerDocument><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-ownerdocument>ownerDocument</a></code> of <var title="">node</var>.
+
+    <li>Set the <code class=external data-anolis-spec=html title=attr-hyperlink-href><a href=http://www.whatwg.org/html/#attr-hyperlink-href>href</a></code> attribute of <var title="">new parent</var> to <var title="">new
+    value</var>.
+
+    <!-- Nested a elements are bad, because they can't be serialized to
+    text/html.  hrefs should already have been cleared in a previous step, but
+    we might have <a name> or such lurking about. -->
+    <li>Let <var title="">ancestor</var> be <var title="">node</var>'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>While <var title="">ancestor</var> is not null:
+
+    <ol>
+      <li>If <var title="">ancestor</var> is an <code class=external data-anolis-spec=html title="the a element"><a href=http://www.whatwg.org/html/#the-a-element>a</a></code>, <a href=#set-the-tag-name>set the tag name</a> of
+      <var title="">ancestor</var> to "span", and let <var title="">ancestor</var> be the
+      result.
+
+      <p class=XXX>This will mean any link-specific attributes will be
+      transferred, which makes them both invalid and useless.  Is that okay?  I
+      don't really want to list them all, because that sort of list is prone to
+      bitrot.
+
+      <li>Set <var title="">ancestor</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>.
+    </ol>
+  </ol>
 
   <!-- WebKit is the only engine that ever outputs anything but font tags for
   fontSize.  For size=7, it uses font-size: -webkit-xxx-large.  We just output
--- a/implementation.js	Fri May 13 15:42:04 2011 -0600
+++ b/implementation.js	Fri May 13 15:54:19 2011 -0600
@@ -1905,12 +1905,29 @@
 		}
 	}
 
-	// "If command is "createLink" or "unlink", let new parent be the result of
-	// calling createElement("a") on the ownerDocument of node, then set the
-	// href attribute of new parent to new value."
+	// "If command is "createLink" or "unlink":"
 	if (command == "createlink" || command == "unlink") {
+		// "Let new parent be the result of calling createElement("a") on the
+		// ownerDocument of node."
 		newParent = node.ownerDocument.createElement("a");
+
+		// "Set the href attribute of new parent to new value."
 		newParent.setAttribute("href", newValue);
+
+		// "Let ancestor be node's parent."
+		var ancestor = node.parentNode;
+
+		// "While ancestor is not null:"
+		while (ancestor) {
+			// "If ancestor is an a, set the tag name of ancestor to "span",
+			// and let ancestor be the result."
+			if (isHtmlElement(ancestor, "A")) {
+				ancestor = setTagName(ancestor, "span");
+			}
+
+			// "Set ancestor to its parent."
+			ancestor = ancestor.parentNode;
+		}
 	}
 
 	// "If command is "fontSize"; and new value is one of "xx-small", "small",
--- a/source.html	Fri May 13 15:42:04 2011 -0600
+++ b/source.html	Fri May 13 15:54:19 2011 -0600
@@ -1314,11 +1314,37 @@
     of <var>new parent</var> to <var>new value</var>.
   </ol>
 
-  <li>If <var>command</var> is "createLink" or "unlink", let <var>new
-  parent</var> be the result of calling <code data-anolis-spec=domcore
-  title=dom-Document-createElement>createElement("a")</code> on the
-  [[ownerdocument]] of <var>node</var>, then set the [[href]] attribute of
-  <var>new parent</var> to <var>new value</var>.
+  <li>If <var>command</var> is "createLink" or "unlink":
+
+  <ol>
+    <li>Let <var>new parent</var> be the result of calling <code
+    data-anolis-spec=domcore
+    title=dom-Document-createElement>createElement("a")</code> on the
+    [[ownerdocument]] of <var>node</var>.
+
+    <li>Set the [[href]] attribute of <var>new parent</var> to <var>new
+    value</var>.
+
+    <!-- Nested a elements are bad, because they can't be serialized to
+    text/html.  hrefs should already have been cleared in a previous step, but
+    we might have <a name> or such lurking about. -->
+    <li>Let <var>ancestor</var> be <var>node</var>'s [[parent]].
+
+    <li>While <var>ancestor</var> is not null:
+
+    <ol>
+      <li>If <var>ancestor</var> is an [[a]], <span>set the tag name</span> of
+      <var>ancestor</var> to "span", and let <var>ancestor</var> be the
+      result.
+
+      <p class=XXX>This will mean any link-specific attributes will be
+      transferred, which makes them both invalid and useless.  Is that okay?  I
+      don't really want to list them all, because that sort of list is prone to
+      bitrot.
+
+      <li>Set <var>ancestor</var> to its [[parent]].
+    </ol>
+  </ol>
 
   <!-- WebKit is the only engine that ever outputs anything but font tags for
   fontSize.  For size=7, it uses font-size: -webkit-xxx-large.  We just output