Spec and implement insertHorizontalRule
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Tue, 12 Apr 2011 15:54:14 -0600
changeset 57 862c9fe11c1c
parent 56 c540bdbe5897
child 58 07ce1caaa8c6
Spec and implement insertHorizontalRule
autoimplementation.html
editcommands.html
implementation.js
source.html
--- a/autoimplementation.html	Tue Apr 12 15:31:49 2011 -0600
+++ b/autoimplementation.html	Tue Apr 12 15:54:14 2011 -0600
@@ -50,6 +50,7 @@
 	<li><a href=#fontsize>fontsize</a>
 	<li><a href=#forecolor>forecolor</a>
 	<li><a href=#hilitecolor>hilitecolor</a>
+	<li><a href=#inserthorizontalrule>inserthorizontalrule</a>
 	<li><a href=#insertimage>insertimage</a>
 	<li><a href=#italic>italic</a>
 	<li><a href=#removeformat>removeformat</a>
@@ -151,6 +152,17 @@
 <button onclick="addTest('hilitecolor')">Add test</button>
 </div>
 
+<div id=inserthorizontalrule>
+<h1>inserthorizontalrule</h1>
+
+<button onclick="runTests('inserthorizontalrule')">Run tests</button>
+
+<table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
+
+<p><label>New test input: <input></label><label>New test value: <input></label>
+<button onclick="addTest('inserthorizontalrule')">Add test</button>
+</div>
+
 <div id=insertimage>
 <h1>insertimage</h1>
 
@@ -576,6 +588,11 @@
 		'<div style="background-color: #ff8888"><p style="background-color: aqua">b[ar]</p></div>',
 		'<span style="display: block; background-color: #ff8888"><span style="display: block; background-color: aqua">b[ar]</span></span>',
 	],
+	inserthorizontalrule: [
+		["abc", 'foo[bar]baz'],
+		'foo[bar]baz',
+		'foo<b>{bar}</b>baz',
+	],
 	insertimage: [
 		["", 'foo[bar]baz'],
 		'foo[bar]baz',
@@ -999,6 +1016,7 @@
 	fontsize: "4",
 	forecolor: "#FF0000",
 	hilitecolor: "#FF8888",
+	inserthorizontalrule: "",
 	insertimage: "/img/lion.svg",
 };
 
@@ -1014,7 +1032,7 @@
 		if (typeof tests[command][i] == "string") {
 			inputs[0].value = tests[command][i];
 			if (inputs.length == 2) {
-				inputs[1].value = defaultValues[command]
+				inputs[1].value = defaultValues[command];
 			}
 		} else {
 			inputs[0].value = tests[command][i][1];
--- a/editcommands.html	Tue Apr 12 15:31:49 2011 -0600
+++ b/editcommands.html	Tue Apr 12 15:54:14 2011 -0600
@@ -1570,6 +1570,51 @@
 <dd><strong>Relevant CSS Property</strong>: "background-color"
 
 
+<dt><code title=""><dfn id=command-inserthorizontalrule title=command-inserthorizontalrule>insertHorizontalRule</dfn></code>
+
+<dd><strong>Action</strong>:
+<!-- You'd think interop here would be simple, right?  Nope: we have three
+different behaviors across four browsers.  Opera 11.00 is the only one that
+acts more or less like the spec.  IE9 and Chrome 12 dev treat the value as an
+id, which is weird and probably useless, so I don't do it.  Firefox 4.0
+produces <hr size=2 width=100%> instead of <hr>, which is also weird and almost
+definitely useless, so I don't do it. -->
+
+<ol>
+  <li>Run <code class=external data-anolis-spec=domrange title=dom-Range-deleteContents><a href=http://html5.org/specs/dom-range.html#dom-range-deletecontents>deleteContents()</a></code> on the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a>.
+
+  <li>Let (<var title="">node</var>, <var title="">offset</var>) be the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>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>.
+
+  <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> 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 and 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>
+  is null, abort these steps and do nothing.
+
+  <li>Let <var title="">hr</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("hr")</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> (or on <var title="">node</var> itself if it's a
+  <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#document>Document</a></code>).
+
+  <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 not
+  equal to 0 or 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>, run <code class=external data-anolis-spec=domcore title=dom-Text-splitText><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-text-splittext>splitText(<var title="">offset</var>)</a></code> on
+  <var title="">node</var>.
+
+  <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 equal to
+  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>, set <var title="">node</var> to its
+  <code class=external data-anolis-spec=domcore title=dom-Node-nextSibling><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-nextsibling>nextSibling</a></code>.
+
+  <li>If <var title="">node</var> is null or 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, run
+  <code class=external data-anolis-spec=domcore title=dom-Node-insertBefore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-insertbefore>insertBefore(<var title="">hr</var>,
+  <var title="">node</var>)</a></code> on the parent of <var title="">node</var>.
+
+  <li>Otherwise, let <var title="">child</var> be the <var title="">offset</var>th child of
+  <var title="">node</var> (or null if there is no such child), and run <code class=external data-anolis-spec=domcore title=dom-Node-insertBefore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-node-insertbefore>insertBefore(<var title="">hr</var>,
+  <var title="">child</var>)</a></code> on <var title="">node</var>.
+</ol>
+
+<dd><strong>State</strong>:
+
+<dd><strong>Value</strong>:
+
+
 <dt><code title=""><dfn id=command-insertimage title=command-insertimage>insertImage</dfn></code>
 
 <dd><strong>Action</strong>:
@@ -1713,7 +1758,7 @@
   include non-conforming elements, which HTML doesn't give content models.  If
   everything had categories, we'd want something like "either it's
   unrecognized, or it's phrasing content that's not also embedded or
-  interactive.  Except this has weird corner-cases like ins and del that are
+  interactive".  Except this has weird corner-cases like ins and del that are
   sometimes phrasing and sometimes flow.
 
   <li>For each <var title="">element</var> in <var title="">affected elements</var>:
--- a/implementation.js	Tue Apr 12 15:31:49 2011 -0600
+++ b/implementation.js	Tue Apr 12 15:54:14 2011 -0600
@@ -1828,6 +1828,58 @@
 		}
 		break;
 
+		case "inserthorizontalrule":
+		// "Run deleteContents() on the range."
+		range.deleteContents();
+
+		// "Let (node, offset) be the range's start."
+		var node = range.startContainer;
+		var offset = range.startOffset;
+
+		// "If node is a Text or Comment node and its parent is null, abort
+		// these steps and do nothing."
+		if (!node.parentNode
+		&& (node.nodeType == Node.TEXT_NODE
+		|| node.nodeType == Node.COMMENT_NODE)) {
+			return;
+		}
+
+		// "Let hr be the result of calling createElement("hr") on the
+		// ownerDocument of node (or on node itself if it's a Document)."
+		var hr = (node.nodeType == Node.DOCUMENT_NODE
+			? node : node.ownerDocument).createElement("hr");
+
+		// "If node is a Text node, and offset is not equal to 0 or the length
+		// of node, run splitText(offset) on node."
+		if (node.nodeType == Node.TEXT_NODE
+		&& offset != 0
+		&& offset != node.length) {
+			node.splitText(offset);
+		}
+
+		// "If node is a Text node, and offset is equal to the length of node,
+		// set node to its nextSibling."
+		if (node.nodeType == Node.TEXT_NODE
+		&& offset == node.length) {
+			node = node.nextSibling;
+		}
+
+		// "If node is null or is a Text or Comment node, run insertBefore(hr,
+		// node) on the parent of node."
+		if (!node
+		|| node.nodeType == Node.TEXT_NODE
+		|| node.nodeType == Node.COMMENT_NODE) {
+			node.parentNode.insertBefore(hr, node);
+		// "Otherwise, let child be the offsetth child of node (or null if
+		// there is no such child), and run insertBefore(img, child) on node."
+		} else {
+			var child = node.childNodes.length == offset
+				? null
+				: node.childNodes[offset];
+			node.insertBefore(hr, child);
+		}
+		break;
+
 		case "insertimage":
 		// "If value is the empty string, abort these steps and do nothing."
 		if (value === "") {
--- a/source.html	Tue Apr 12 15:31:49 2011 -0600
+++ b/source.html	Tue Apr 12 15:54:14 2011 -0600
@@ -1583,6 +1583,59 @@
 <dd><strong>Relevant CSS Property</strong>: "background-color"
 
 
+<dt><code title><dfn title=command-inserthorizontalrule>insertHorizontalRule</dfn></code>
+
+<dd><strong>Action</strong>:
+<!-- You'd think interop here would be simple, right?  Nope: we have three
+different behaviors across four browsers.  Opera 11.00 is the only one that
+acts more or less like the spec.  IE9 and Chrome 12 dev treat the value as an
+id, which is weird and probably useless, so I don't do it.  Firefox 4.0
+produces <hr size=2 width=100%> instead of <hr>, which is also weird and almost
+definitely useless, so I don't do it. -->
+
+<ol>
+  <li>Run <code data-anolis-spec=domrange
+  title=dom-Range-deleteContents>deleteContents()</code> on the [[range]].
+
+  <li>Let (<var>node</var>, <var>offset</var>) be the [[range]]'s
+  [[rangestart]].
+
+  <li>If <var>node</var> is a [[text]] or [[comment]] node and its [[parent]]
+  is null, abort these steps and do nothing.
+
+  <li>Let <var>hr</var> be the result of calling <code
+  data-anolis-spec=domcore
+  title=dom-Document-createElement>createElement("hr")</code> on the
+  [[ownerdocument]] of <var>node</var> (or on <var>node</var> itself if it's a
+  [[document]]).
+
+  <li>If <var>node</var> is a [[text]] node, and <var>offset</var> is not
+  equal to 0 or the [[nodelength]] of <var>node</var>, run <code
+  data-anolis-spec=domcore
+  title=dom-Text-splitText>splitText(<var>offset</var>)</code> on
+  <var>node</var>.
+
+  <li>If <var>node</var> is a [[text]] node, and <var>offset</var> is equal to
+  the [[nodelength]] of <var>node</var>, set <var>node</var> to its
+  [[nextsibling]].
+
+  <li>If <var>node</var> is null or is a [[text]] or [[comment]] node, run
+  <code data-anolis-spec=domcore
+  title=dom-Node-insertBefore>insertBefore(<var>hr</var>,
+  <var>node</var>)</code> on the parent of <var>node</var>.
+
+  <li>Otherwise, let <var>child</var> be the <var>offset</var>th child of
+  <var>node</var> (or null if there is no such child), and run <code
+  data-anolis-spec=domcore
+  title=dom-Node-insertBefore>insertBefore(<var>hr</var>,
+  <var>child</var>)</code> on <var>node</var>.
+</ol>
+
+<dd><strong>State</strong>:
+
+<dd><strong>Value</strong>:
+
+
 <dt><code title><dfn title=command-insertimage>insertImage</dfn></code>
 
 <dd><strong>Action</strong>:
@@ -1735,7 +1788,7 @@
   include non-conforming elements, which HTML doesn't give content models.  If
   everything had categories, we'd want something like "either it's
   unrecognized, or it's phrasing content that's not also embedded or
-  interactive.  Except this has weird corner-cases like ins and del that are
+  interactive".  Except this has weird corner-cases like ins and del that are
   sometimes phrasing and sometimes flow.
 
   <li>For each <var>element</var> in <var>affected elements</var>: