Spec and implement fontSize
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Mon, 11 Apr 2011 14:48:46 -0600
changeset 53 9ca0b4ae819d
parent 52 10cf964f203e
child 54 b9b2593b33a9
Spec and implement fontSize

This one was a pain, and there are still some wrinkles.
autoimplementation.html
editcommands.html
implementation.js
source.html
--- a/autoimplementation.html	Sun Apr 10 15:12:29 2011 -0600
+++ b/autoimplementation.html	Mon Apr 11 14:48:46 2011 -0600
@@ -4,6 +4,9 @@
 body { font-family: serif }
 .yes { color: green }
 .no { color: red }
+/* http://www.w3.org/Bugs/Public/show_bug.cgi?id=12154
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=589124
+ * https://bugs.webkit.org/show_bug.cgi?id=56400 */
 b, strong { font-weight: bold }
 .bold { font-weight: bold }
 .notbold { font-weight: normal }
@@ -43,6 +46,7 @@
 	<li><a href=#bold>bold</a>
 	<li><a href=#createlink>createlink</a>
 	<li><a href=#fontname>fontname</a>
+	<li><a href=#fontsize>fontsize</a>
 	<li><a href=#forecolor>forecolor</a>
 	<li><a href=#hilitecolor>hilitecolor</a>
 	<li><a href=#italic>italic</a>
@@ -66,8 +70,8 @@
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('backcolor', document.querySelector('#backcolor input').value)">Add test</button>
+<p><label>New test input: <input></label><label>New test value: <input></label>
+<button onclick="addTest('backcolor')">Add test</button>
 </div>
 
 <div id=bold>
@@ -78,8 +82,8 @@
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('bold', document.querySelector('#bold input').value)">Add test</button>
+<p><label>New test input: <input></label>
+<button onclick="addTest('bold')">Add test</button>
 </div>
 
 <div id=createlink>
@@ -87,12 +91,10 @@
 
 <button onclick="runTests('createlink')">Run tests</button>
 
-<p>Tests set the href to "http://www.google.com/".
-
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('createlink', document.querySelector('#createlink input').value)">Add test</button>
+<p><label>New test input: <input></label><label>New test value: <input></label>
+<button onclick="addTest('createlink')">Add test</button>
 </div>
 
 <div id=fontname>
@@ -100,13 +102,25 @@
 
 <button onclick="runTests('fontname')">Run tests</button>
 
-<p>Tests set the font-family to "sans-serif".  Note that the body's font-family is "serif".
+<p>Note that the body's font-family is "serif".
 
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('fontname', document.querySelector('#fontname input').value)">Add test</button>
+<p><label>New test input: <input></label><label>New test value: <input></label>
+<button onclick="addTest('fontname')">Add test</button>
+</div>
+
+<div id=fontsize>
+<h1>fontsize</h1>
+
+<button onclick="runTests('fontsize')">Run tests</button>
+
+<table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
+<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('fontsize')">Add test</button>
 </div>
 
 <div id=forecolor>
@@ -114,13 +128,11 @@
 
 <button onclick="runTests('forecolor')">Run tests</button>
 
-<p>Tests set the color to "#FF0000".
-
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('forecolor', document.querySelector('#forecolor input').value)">Add test</button>
+<p><label>New test input: <input></label><label>New test value: <input></label>
+<button onclick="addTest('forecolor')">Add test</button>
 </div>
 
 <div id=hilitecolor>
@@ -128,12 +140,12 @@
 
 <button onclick="runTests('hilitecolor')">Run tests</button>
 
-<p>Tests set the color to "#FF8888".  In IE we run backColor instead of hiliteColor.
+<p>In IE we run backColor instead of hiliteColor.
 
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('hilitecolor', document.querySelector('#hilitecolor input').value)">Add test</button>
+<p><label>New test input: <input></label><label>New test value: <input></label>
+<button onclick="addTest('hilitecolor')">Add test</button>
 </div>
 
 <div id=italic>
@@ -144,8 +156,8 @@
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('italic', document.querySelector('#italic input').value)">Add test</button>
+<p><label>New test input: <input></label>
+<button onclick="addTest('italic')">Add test</button>
 </div>
 
 <div id=strikethrough>
@@ -156,8 +168,8 @@
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('strikethrough', document.querySelector('#strikethrough input').value)">Add test</button>
+<p><label>New test input: <input></label>
+<button onclick="addTest('strikethrough')">Add test</button>
 </div>
 
 <div id=subscript>
@@ -168,8 +180,8 @@
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('subscript', document.querySelector('#subscript input').value)">Add test</button>
+<p><label>New test input: <input></label>
+<button onclick="addTest('subscript')">Add test</button>
 </div>
 
 <div id=superscript>
@@ -180,8 +192,8 @@
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('superscript', document.querySelector('#superscript input').value)">Add test</button>
+<p><label>New test input: <input></label>
+<button onclick="addTest('superscript')">Add test</button>
 </div>
 
 <div id=underline>
@@ -192,8 +204,8 @@
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('underline', document.querySelector('#underline input').value)">Add test</button>
+<p><label>New test input: <input></label>
+<button onclick="addTest('underline')">Add test</button>
 </div>
 
 <div id=unlink>
@@ -203,27 +215,12 @@
 
 <table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
 
-<p><label>Enter new test here: <input></label>
-<button onclick="addTest('unlink', document.querySelector('#unlink input').value)">Add test</button>
+<p><label>New test input: <input></label>
+<button onclick="addTest('unlink')">Add test</button>
 </div>
 
 <script src=implementation.js></script>
 <script>
-var values = {
-	backcolor: "#FF8888",
-	bold: null,
-	createlink: "http://www.google.com/",
-	fontname: "sans-serif",
-	forecolor: "#FF0000",
-	hilitecolor: "#FF8888",
-	italic: null,
-	strikethrough: null,
-	subscript: null,
-	superscript: null,
-	underline: null,
-	unlink: null,
-};
-
 var tests = {
 	backcolor: [
 		'<p>foo[bar]baz',
@@ -430,6 +427,76 @@
 		'foo<span style="font-family: monospace">[bar]</span>baz',
 		'foo<span style="font-family: monospace">b[a]r</span>baz',
 	],
+	fontsize: [
+		["1", 'foo[bar]baz'],
+		["0", 'foo[bar]baz'],
+		["-5", 'foo[bar]baz'],
+		["6", 'foo[bar]baz'],
+		["7", 'foo[bar]baz'],
+		["8", 'foo[bar]baz'],
+		["100", 'foo[bar]baz'],
+		["2em", 'foo[bar]baz'],
+		["20pt", 'foo[bar]baz'],
+		["xx-large", 'foo[bar]baz'],
+		[" 1 ", 'foo[bar]baz'],
+		["1.", 'foo[bar]baz'],
+		["1.0", 'foo[bar]baz'],
+		["1.0e2", 'foo[bar]baz'],
+		["1.1", 'foo[bar]baz'],
+		["1.9", 'foo[bar]baz'],
+		["+0", 'foo[bar]baz'],
+		["+1", 'foo[bar]baz'],
+		["+9", 'foo[bar]baz'],
+		["-0", 'foo[bar]baz'],
+		["-1", 'foo[bar]baz'],
+		["-9", 'foo[bar]baz'],
+		["", 'foo[bar]baz'],
+
+		'{<p><p> <p>foo</p>}',
+		'foo[bar<i>baz]qoz</i>quz',
+
+		'<table><tbody><tr><td>foo<td>b[a]r<td>baz</table>',
+		'<table><tbody><tr data-start=1 data-end=2><td>foo<td>bar<td>baz</table>',
+		'<table><tbody><tr data-start=0 data-end=2><td>foo<td>bar<td>baz</table>',
+		'<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>',
+		'<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>',
+		'{<table><tr><td>foo<td>bar<td>baz</table>}',
+
+		'foo<font size=1>[bar]</font>baz',
+		'<font size=1>foo[bar]baz</font>',
+		'foo<font size=3>[bar]</font>baz',
+		'<font size=3>foo[bar]baz</font>',
+		'foo<font size=4>[bar]</font>baz',
+		'<font size=4>foo[bar]baz</font>',
+		'foo<font size=+1>[bar]</font>baz',
+		'<font size=+1>foo[bar]baz</font>',
+		'<font size=4>foo<font size=1>b[a]r</font>baz</font>',
+
+		'foo<span style="font-size: xx-small">[bar]</span>baz',
+		'<span style="font-size: xx-small">foo[bar]baz</span>',
+		'foo<span style="font-size: medium">[bar]</span>baz',
+		'<span style="font-size: medium">foo[bar]baz</span>',
+		'foo<span style="font-size: large">[bar]</span>baz',
+		'<span style="font-size: large">foo[bar]baz</span>',
+		'<span style="font-size: large">foo<span style="font-size: xx-small">b[a]r</span>baz</span>',
+
+		'foo<span style="font-size: 2em">[bar]</span>baz',
+		'<span style="font-size: 2em">foo[bar]baz</span>',
+
+		'<p style="font-size: xx-small">foo[bar]baz</p>',
+		'<p style="font-size: medium">foo[bar]baz</p>',
+		'<p style="font-size: large">foo[bar]baz</p>',
+		'<p style="font-size: 2em">foo[bar]baz</p>',
+
+		["3", '<p style="font-size: xx-small">foo[bar]baz</p>'],
+		["3", '<p style="font-size: medium">foo[bar]baz</p>'],
+		["3", '<p style="font-size: large">foo[bar]baz</p>'],
+		["3", '<p style="font-size: 2em">foo[bar]baz</p>'],
+
+		// Minor algorithm bug: this changes the size of the "b" and "r" in
+		// "bar" when we pull down styles
+		["3", '<font size=6>foo <span style="font-size: 2em">b[a]r</span> baz</font>'],
+	],
 	forecolor: [
 		'foo[bar]baz',
 		'foo]bar[baz',
@@ -739,25 +806,42 @@
 	],
 };
 
+var defaultValues = {
+	backcolor: "#FF8888",
+	createlink: "http://www.google.com/",
+	fontname: "sans-serif",
+	fontsize: "4",
+	forecolor: "#FF0000",
+	hilitecolor: "#FF8888",
+};
+
 function runTests(command) {
 	var runTestsButton = document.querySelector("#" + command + " button");
 	runTestsButton.parentNode.removeChild(runTestsButton);
 
 	var addTestButton = document.querySelector("#" + command + " button");
-	var input = document.querySelector("#" + command + " input");
+	var inputs = document.getElementById(command).getElementsByTagName("input");
 	for (var i = 0; i < tests[command].length; i++) {
-		// The following code should logically be equivalent to:
-		//   addTest(command, tests[command][i]);
-		// But that only works to set one cell, in IE9.  All the other tests
-		// fail.  So, um, WTF, but it works.
-		input.value = tests[command][i];
-		input.focus();
+		// This code actually focuses and clicks everything because for some
+		// reason, anything else doesn't work in IE9 . . .
+		if (typeof tests[command][i] == "string") {
+			inputs[0].value = tests[command][i];
+			if (inputs.length == 2) {
+				inputs[1].value = defaultValues[command]
+			}
+		} else {
+			inputs[0].value = tests[command][i][1];
+			inputs[1].value = tests[command][i][0];
+		}
+		inputs[0].focus();
 		addTestButton.click();
 	}
-	input.value = "";
+	for (var i = 0; i < inputs.length; i++) {
+		inputs[i].value = "";
+	}
 }
 
-function addTest(command, test) {
+function addTest(command) {
 	var doubleTesting = ["backcolor", "bold", "italic", "strikethrough",
 	"underline", "forecolor", "fontname", "fontsize", "subscript",
 	"superscript"].indexOf(command) != -1;
@@ -772,6 +856,14 @@
 
 	var tr = doSetup(command, 0);
 
+	var test;
+	var inputs = document.getElementById(command).getElementsByTagName("input");
+	if (inputs.length == 1) {
+		test = inputs[0].value;
+	} else {
+		test = [inputs[1].value, inputs[0].value];
+	}
+
 	doInputCell(tr, test);
 	doSpecCell(tr, test, command, false);
 	doBrowserCell(tr, test, command, false);
@@ -807,15 +899,28 @@
 }
 
 function doInputCell(tr, test) {
+	var value = null;
+	if (typeof test != "string") {
+		value = test[0];
+		test = test[1];
+	}
 	var inputCell = document.createElement("td");
 	inputCell.innerHTML = "<div></div><div></div>";
 	inputCell.firstChild.innerHTML = test;
 	inputCell.lastChild.textContent = inputCell.firstChild.innerHTML;
+	if (value !== null) {
+		inputCell.lastChild.textContent += ' (value: "' + value + '")';
+	}
 	tr.appendChild(inputCell);
 }
 
 function doSpecCell(tr, test, command, styleWithCss) {
-	var value = values[command];
+	var value;
+
+	if (typeof test != "string") {
+		value = test[0];
+		test = test[1];
+	}
 
 	var specCell = document.createElement("td");
 	tr.appendChild(specCell);
@@ -840,7 +945,7 @@
 
 	var key = "execcommand-" + command
 		+ "-" + Number(myQueryCommandState("styleWithCSS"))
-		+ "-" + test;
+		+ "-" + tr.firstChild.lastChild.textContent;
 
 	var oldValue = localStorage[key];
 	localStorage[key] = specCell.lastChild.textContent;
@@ -854,7 +959,12 @@
 }
 
 function doBrowserCell(tr, test, command, styleWithCss) {
-	var value = values[command];
+	var value;
+
+	if (typeof test != "string") {
+		value = test[0];
+		test = test[1];
+	}
 
 	if (command == "hilitecolor" && navigator.userAgent.indexOf("MSIE") != -1) {
 		// IE behaves differently, and I want to see how it works.
--- a/editcommands.html	Sun Apr 10 15:12:29 2011 -0600
+++ b/editcommands.html	Mon Apr 11 14:48:46 2011 -0600
@@ -27,7 +27,7 @@
 <body class=draft>
 <div class=head id=head>
 <h1>HTML Editing Commands</h1>
-<h2 class="no-num no-toc" id=work-in-progress-&mdash;-last-update-10-april-2011>Work in Progress &mdash; Last Update 10 April 2011</h2>
+<h2 class="no-num no-toc" id=work-in-progress-&mdash;-last-update-11-april-2011>Work in Progress &mdash; Last Update 11 April 2011</h2>
 <dl>
  <dt>Editor
  <dd>Aryeh Gregor &lt;ayg+spec@aryeh.name&gt;
@@ -302,6 +302,9 @@
 given <var title="">command</var> is returned by the following algorithm, which will
 return either a string or null:
 
+<p class=XXX>"Specified value" already means something in CSS, I need to find a
+different name.
+
 <ol>
   <li>If <var title="">command</var> is "hiliteColor" and the <code class=external data-anolis-spec=domcore><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code>'s
   display property does not compute to "inline", return null.
@@ -369,7 +372,8 @@
 
   <li>If <var title="">element</var> is a <code class=external data-anolis-spec=html title=font><a href=http://www.whatwg.org/html/#font>font</a></code> element that has an attribute whose
   effect is to create a <a class=external data-anolis-spec=html href=http://www.whatwg.org/html/#presentational-hints title="presentational hints">presentational hint</a> for <var title="">property</var>, return
-  the value that the hint sets <var title="">property</var> to.
+  the value that the hint sets <var title="">property</var> to.  (For a <code class=external data-anolis-spec=html title=dom-font-size><a href=http://www.whatwg.org/html/#dom-font-size>size</a></code> of
+  7, this will be the non-CSS value "xxx-large".)
 
   <li>If <var title="">element</var> is in the following list, and <var title="">property</var> is
   equal to the CSS property name listed for it, return the string listed for
@@ -720,6 +724,11 @@
       value</a> for <var title="">command</var> is neither null nor equal to
       <var title="">propagated value</var>, continue with the next <var title="">child</var>.
 
+      <p class=XXX>This will be incorrect for relative font sizes.  If the font
+      size on the parent was removed and the font size on the child is in ems
+      or percents or something, it will now change value.  This isn't likely to
+      come up, so we'll ignore it for now.
+
       <li>If <var title="">child</var> is the last member of <var title="">ancestor list</var>,
       continue with the next <var title="">child</var>.
 
@@ -918,11 +927,6 @@
     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("font")</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=dom-font-face><a href=http://www.whatwg.org/html/#dom-font-face>face</a></code> attribute
     of <var title="">new parent</var> to <var title="">new value</var>.
-
-    <li>If <var title="">command</var> is "fontSize", 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("font")</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=dom-font-size><a href=http://www.whatwg.org/html/#dom-font-size>size</a></code> attribute
-    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
@@ -930,6 +934,28 @@
   <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>.
 
+  <!-- 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 font tag no matter what. -->
+  <li>If <var title="">command</var> is "fontSize"; and <var title="">new value</var> is one of
+  "xx-small", "small", "medium", "large", "x-large", "xx-large", or
+  "xxx-large"; and either the <a href=#css-styling-flag>CSS styling flag</a> is false, or
+  <var title="">new value</var> is "xxx-large": 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("font")</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=dom-font-size><a href=http://www.whatwg.org/html/#dom-font-size>size</a></code> attribute of
+  <var title="">new parent</var> to the number from the following table based on
+  <var title="">new value</var>:
+
+  <dl class=switch>
+    <dt>xx-small <dd>1
+    <dt>small <dd>2
+    <dt>normal <dd>3
+    <dt>large <dd>4
+    <dt>x-large <dd>5
+    <dt>xx-large <dd>6
+    <dt>xxx-large <dd>7
+  </dl>
+
   <!-- We always use sup/sub elements, even in CSS mode, following Gecko and
   contradicting WebKit.  This is because <span value="vertical-align:
   sub/super">, the obvious equivalent (and what WebKit uses), behaves quite
@@ -953,7 +979,8 @@
   <li>If the <a href=#effective-value>effective value</a> of <var title="">command</var> for <var title="">new
   parent</var> is not <var title="">new value</var>, and the <a href=#relevant-css-property>relevant CSS
   property</a> for <var title="">command</var> is not null, set that CSS property of
-  <var title="">new parent</var> to <var title="">new value</var>.
+  <var title="">new parent</var> to <var title="">new value</var> (if the new value would be
+  valid).
 
   <li>If <var title="">command</var> is "strikethrough", and <var title="">new value</var> is
   "line-through", and the <a href=#effective-value>effective value</a> of "strikethrough" for
@@ -977,8 +1004,10 @@
 
     <li>Remove <var title="">new parent</var> from 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>If <var title="">new parent</var> is a <code class=external data-anolis-spec=html title="the span element"><a href=http://www.whatwg.org/html/#the-span-element>span</a></code>, and either <var title="">command</var>
-    is "underline" or <var title="">command</var> is "strikethrough" or the
+    <li>If <var title="">new parent</var> is a <code class=external data-anolis-spec=html title="the span element"><a href=http://www.whatwg.org/html/#the-span-element>span</a></code>, and either a)
+    <var title="">command</var> is "underline" or "strikethrough", or b)
+    <var title="">command</var> is "fontSize" and <var title="">new value</var> is not
+    "xxx-large", or c) <var title="">command</var> is not "fontSize" and the
     <a href=#relevant-css-property>relevant CSS property</a> for <var title="">command</var> is not null:
 
     <ol>
@@ -1355,6 +1384,116 @@
 <dd><strong>Relevant CSS Property</strong>: "font-family"
 
 
+<dt><code title=""><dfn id=command-fontsize title=command-fontsize>fontSize</dfn></code>
+
+<dd><strong>Action</strong>:
+<!--
+IE 9: Parses the value as a number (allowing floating-point), rounds to the
+  nearest integer, then clamps to the range 1 to 7.  If the value is not a
+  valid number, including if it has trailing characters (like "2em"), does
+  nothing.  Normalizes relative sizes, so "+0" is the same as "+3", etc.
+  Treats empty string the same as "1".
+Firefox 4.0: Passes the value through literally to <font size=>, so "2em" gets
+  you <font size="2em">.  Always uses <font>, even with styleWithCss true.
+  Ignores the command if the value is the empty string.
+Chrome 12 dev: Parses the value as a legacy font size, so "2em" becomes "2",
+  then outputs a <font> with the resulting number.  If there is no resulting
+  number, like for a value of "xx-small", does nothing.  In styleWithCss mode,
+  outputs a span with corresponding CSS keywords: 1 = x-small, 2 = small,
+  . . ., 6 = xx-large, 7 = -webkit-xxx-large.  Normalizes relative sizes, so
+  "+0" is the same as "3", etc.  Ignores the command if the value is the empty
+  string.
+Opera 11: Parses the value as an integer (ignoring floating-point as trailing
+  characters), then outputs that.  This means that "+0" becomes <font size=0>
+  instead of <font size=+0> or <font size=3>.  Non-numeric values get
+  interpreted as 0.  Does not clamp, and is willing to output negative numbers.
+  Treats empty string as "0".
+
+What all of these have in common is that they force the author to deal with
+legacy font values and don't let them use CSS.  This is undesirable, so I
+ignore how implementations behave.  Practically any value that did the same
+thing in IE and Firefox should still do the same thing here, so I'm only
+respecifying non-interoperable behavior anyway.
+-->
+<ol>
+  <li>If <var title="">value</var> is the empty string, do nothing and abort these
+  steps.
+
+  <li><a class=external data-anolis-spec=html href=http://www.whatwg.org/html/#strip-leading-and-trailing-whitespace>Strip leading and trailing whitespace</a>
+  from <var title="">value</var>.
+
+  <li>If <var title="">value</var> is a <a class=external data-anolis-spec=html href=http://www.whatwg.org/html/#valid-floating-point-number>valid floating point
+  number</a>, or would be a <a class=external data-anolis-spec=html href=http://www.whatwg.org/html/#valid-floating-point-number>valid floating point
+  number</a> if a single leading "+" character were stripped:
+
+  <ol>
+    <li>If the first character of <var title="">value</var> is "+", delete the character
+    and let <var title="">mode</var> be "relative-plus".
+
+    <li>Otherwise, if the first character of <var title="">value</var> is "-", delete
+    the character and let <var title="">mode</var> be "relative-minus".
+
+    <li>Otherwise, let <var title="">mode</var> be "absolute".
+
+    <li>Apply the <a class=external data-anolis-spec=html href=http://www.whatwg.org/html/#rules-for-parsing-non-negative-integers>rules for parsing non-negative
+    integers</a> to <var title="">value</var>, and let <var title="">number</var> be the
+    result.
+
+    <li>If <var title="">mode</var> is "relative-plus", add three to <var title="">number</var>.
+
+    <li>If <var title="">mode</var> is "relative-minus", negate <var title="">number</var>, then
+    add three to it.
+
+    <li>If <var title="">number</var> is less than one, let <var title="">number</var> equal 1.
+
+    <li>If <var title="">number</var> is greater than seven, let <var title="">number</var> equal
+    7.
+
+    <li>Set <var title="">value</var> to the string here corresponding to
+    <var title="">number</var>:
+
+    <dl class=switch>
+      <dt>1 <dd>xx-small
+      <dt>2 <dd>small
+      <dt>3 <dd>normal
+      <dt>4 <dd>large
+      <dt>5 <dd>x-large
+      <dt>6 <dd>xx-large
+      <dt>7 <dd>xxx-large
+    </dl>
+
+    <p class=XXX>The entry for 7 here is an issue: there's no CSS value that
+    corresponds to it.  Even if we got one added to the drafts, it wouldn't be
+    backward-compatible to use it.  WebKit is the only engine that supports CSS
+    output for fontSize, and it uses -webkit-xxx-large in this case, which is
+    unworkable.  Instead, we just always output a font tag for size 7.  If
+    authors want conforming markup, they'll need to give CSS sizes above size
+    7, not legacy sizes.
+  </ol>
+
+  <li>If <var title="">value</var> is not one of the strings "xx-small", "x-small",
+  "small", "medium", "large", "x-large", "xx-large", "xxx-large", and is not a
+  valid CSS absolute length, then do nothing and abort these steps.
+
+  <p class=XXX>Not sure this is the best way to do it.  We don't want to allow
+  relative lengths, because those can have very weird user-visible behavior.
+  For instance, a size of 2em would sometimes double the text size, but if you
+  applied it a second time it would do nothing, but if you deselected one
+  character it would suddenly double the size again.  Current UAs just only
+  allow numeric values.  There's no harm in allowing "x-small" and absolute
+  sizes, I don't think.
+
+  <li><a href=#decompose>Decompose</a> the <a class=external data-anolis-spec=domrange href=http://html5.org/specs/dom-range.html#concept-range title=concept-range>range</a>, then <a href=#set-the-value>set the value</a> of
+  each returned <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> to <var title="">value</var>.
+</ol>
+
+<dd><strong>State</strong>:
+
+<dd><strong>Value</strong>:
+
+<dd><strong>Relevant CSS Property</strong>: "font-size"
+
+
 <dt><code title=""><dfn id=command-forecolor title=command-forecolor>foreColor</dfn></code>
 
 <dd><strong>Action</strong>: If <var title="">value</var> is not a valid CSS color,
--- a/implementation.js	Sun Apr 10 15:12:29 2011 -0600
+++ b/implementation.js	Mon Apr 11 14:48:46 2011 -0600
@@ -60,6 +60,8 @@
 function convertProperty(property) {
 	// Special-case for now
 	var map = {
+		"fontFamily": "font-family",
+		"fontSize": "font-size",
 		"fontStyle": "font-style",
 		"fontWeight": "font-weight",
 		"textDecoration": "text-decoration",
@@ -71,9 +73,25 @@
 	return property;
 }
 
+// Return the <font size=X> value for the given CSS size, or undefined if there
+// is none.
+function getFontSize(cssVal) {
+	return {
+		"xx-small": 1,
+		"small": 2,
+		"medium": 3,
+		"large": 4,
+		"x-large": 5,
+		"xx-large": 6,
+		"xxx-large": 7
+	}[cssVal];
+}
+
+// This entire function is a massive hack to work around browser
+// incompatibility.  It wouldn't work in real life, but it's good enough for a
+// test implementation.  It's not clear how all this should actually be specced
+// in practice, since CSS defines no notion of equality, does it?
 function valuesEqual(command, val1, val2) {
-	// This is a bad hack to work around browser incompatibility.  It wouldn't
-	// work in real life, but it's good enough for a test implementation.
 	if (val1 === null || val2 === null) {
 		return val1 === val2;
 	}
@@ -95,7 +113,54 @@
 	var test2 = document.createElement("span");
 	test2.style[property] = val2;
 
-	return test1.style[property] == test2.style[property];
+	// Computing style doesn't seem to always work if the elements aren't in
+	// the body?
+	document.body.appendChild(test1);
+	document.body.appendChild(test2);
+
+	// We can't test xxx-large with CSS.  Also, some browsers (WebKit?) don't
+	// actually make <span style="font-size: xx-small"> have the same size as
+	// <font size="1">, and so on.  So we have to test both . . .
+	var test1b = null, test2b = null;
+	if (command == "fontsize") {
+		if (typeof getFontSize(val1) != "undefined") {
+			test1b = document.createElement("font");
+			test1b.size = getFontSize(val1);
+			document.body.appendChild(test1b);
+		}
+		if (typeof getFontSize(val2) != "undefined") {
+			test2b = document.createElement("font");
+			test2b.size = getFontSize(val2);
+			document.body.appendChild(test2b);
+		}
+	}
+
+	var computed1b = test1b
+		? getComputedStyle(test1b)[property]
+		: null;
+	var computed2b = test2b
+		? getComputedStyle(test2b)[property]
+		: null;
+	var computed1 = command == "fontsize" && val1 == "xxx-large"
+		? computed1b
+		: getComputedStyle(test1)[property];
+	var computed2 = command == "fontsize" && val2 == "xxx-large"
+		? computed2b
+		: getComputedStyle(test2)[property];
+
+	document.body.removeChild(test1);
+	document.body.removeChild(test2);
+
+	if (test1b) {
+		document.body.removeChild(test1b);
+	}
+	if (test2b) {
+		document.body.removeChild(test2b);
+	}
+
+	return computed1 == computed2
+		|| computed1 === computed2b
+		|| computed1b === computed2;
 }
 
 // Opera 11 puts HTML elements in the null namespace, it seems.
@@ -542,10 +607,8 @@
 
 	// "If element is a font element that has an attribute whose effect is
 	// to create a presentational hint for property, return the value that the
-	// hint sets property to."
-	//
-	// I'm cheating on this one for simplicity.  Font-size is especially wrong,
-	// and will have to be fixed when I implement execCommand() for that.
+	// hint sets property to.  (For a size of 7, this will be the non-CSS value
+	// "xxx-large".)"
 	if (isHtmlNamespace(element.namespaceURI)
 	&& element.tagName == "FONT") {
 		if (property == "color" && element.hasAttribute("color")) {
@@ -555,7 +618,23 @@
 			return element.face;
 		}
 		if (property == "fontSize" && element.hasAttribute("size")) {
-			return element.size;
+			// This is not even close to correct in general.
+			var size = parseInt(element.size);
+			if (size < 1) {
+				size = 1;
+			}
+			if (size > 7) {
+				size = 7;
+			}
+			return {
+				1: "xx-small",
+				2: "small",
+				3: "medium",
+				4: "large",
+				5: "x-large",
+				6: "xx-large",
+				7: "xxx-large"
+			}[size];
 		}
 	}
 
@@ -1315,14 +1394,6 @@
 			newParent = node.ownerDocument.createElement("font");
 			newParent.face = newValue;
 		}
-
-		// "If command is "fontSize", let new parent be the result of calling
-		// createElement("font") on the ownerDocument of node, then set the
-		// size attribute of new parent to new value."
-		if (command == "fontsize") {
-			newParent = node.ownerDocument.createElement("font");
-			newParent.size = newValue;
-		}
 	}
 
 	// "If command is "createLink" or "unlink", let new parent be the result of
@@ -1333,6 +1404,27 @@
 		newParent.setAttribute("href", newValue);
 	}
 
+	// "If command is "fontSize"; and new value is one of "xx-small", "small",
+	// "medium", "large", "x-large", "xx-large", or "xxx-large"; and either the
+	// CSS styling flag is false, or new value is "xxx-large": let new parent
+	// be the result of calling createElement("font") on the ownerDocument of
+	// node, then set the size attribute of new parent to the number from the
+	// following table based on new value: [table omitted]"
+	if (command == "fontsize"
+	&& ["xx-small", "small", "medium", "large", "x-large", "xx-large", "xxx-large"].indexOf(newValue) != -1
+	&& (!cssStylingFlag || newValue == "xxx-large")) {
+		newParent = node.ownerDocument.createElement("font");
+		newParent.size = {
+			"xx-small": 1,
+			"small": 2,
+			"medium": 3,
+			"large": 4,
+			"x-large": 5,
+			"xx-large": 6,
+			"xxx-large": 7
+		}[newValue];
+	}
+
 	// "If command is "subscript" and new value is "sub", let new parent be the
 	// result of calling createElement("sub") on the ownerDocument of node."
 	if (command == "subscript" && newValue == "sub") {
@@ -1357,7 +1449,7 @@
 
 	// "If the effective value of command for new parent is not new value, and
 	// the relevant CSS property for command is not null, set that CSS property
-	// of new parent to new value."
+	// of new parent to new value (if the new value would be valid)."
 	var property = getRelevantCssProperty(command);
 	if (property !== null
 	&& !valuesEqual(command, getEffectiveValue(newParent, command), newValue)) {
@@ -1396,11 +1488,16 @@
 		// "Remove new parent from its parent."
 		newParent.parentNode.removeChild(newParent);
 
-		// "If new parent is a span, and either command is "underline" or
-		// command is "strikethrough" or the relevant CSS property for command
-		// is not null:"
+		// "If new parent is a span, and either a) command is "underline" or
+		// "strikethrough", or b) command is "fontSize" and new value is not
+		// "xxx-large", or c) command is not "fontSize" and the relevant CSS
+		// property for command is not null:"
 		if (newParent.tagName == "SPAN"
-		&& (command == "underline" || command == "strikethrough" || property !== null)) {
+		&& (
+			(command == "underline" || command == "strikethrough")
+			|| (command == "fontsize" && newValue != "xxx-large")
+			|| (command != "fontsize" && property !== null)
+		)) {
 			// "If the relevant CSS property for command is not null, set that
 			// CSS property of node to new value."
 			if (property !== null) {
@@ -1530,6 +1627,7 @@
 	var prop = {
 		bold: "fontWeight",
 		fontname: "fontFamily",
+		fontsize: "fontSize",
 		forecolor: "color",
 		hilitecolor: "backgroundColor",
 		italic: "fontStyle",
@@ -1609,6 +1707,96 @@
 		}
 		break;
 
+		case "fontsize":
+		// "If value is the empty string, do nothing and abort these steps."
+		if (value === "") {
+			return;
+		}
+
+		// "Strip leading and trailing whitespace from value."
+		//
+		// Cheap hack, not following the actual algorithm.
+		value = value.trim();
+
+		// "If value is a valid floating point number, or would be a valid
+		// floating point number if a single leading "+" character were
+		// stripped:"
+		if (/^[-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?$/.test(value)) {
+			var mode;
+
+			// "If the first character of value is "+", delete the character
+			// and let mode be "relative-plus"."
+			if (value[0] == "+") {
+				value = value.slice(1);
+				mode = "relative-plus";
+			// "Otherwise, if the first character of value is "-", delete the
+			// character and let mode be "relative-minus"."
+			} else if (value[0] == "-") {
+				value = value.slice(1);
+				mode = "relative-minus";
+			// "Otherwise, let mode be "absolute"."
+			} else {
+				mode = "absolute";
+			}
+
+			// "Apply the rules for parsing non-negative integers to value, and
+			// let number be the result."
+			//
+			// Another cheap hack.
+			var num = parseInt(value);
+
+			// "If mode is "relative-plus", add three to number."
+			if (mode == "relative-plus") {
+				num += 3;
+			}
+
+			// "If mode is "relative-minus", negate number, then add three to
+			// it."
+			if (mode == "relative-minus") {
+				num = 3 - num;
+			}
+
+			// "If number is less than one, let number equal 1."
+			if (num < 1) {
+				num = 1;
+			}
+
+			// "If number is greater than seven, let number equal 7."
+			if (num > 7) {
+				num = 7;
+			}
+
+			// "Set value to the string here corresponding to number:" [table
+			// omitted]
+			value = {
+				1: "xx-small",
+				2: "small",
+				3: "medium",
+				4: "large",
+				5: "x-large",
+				6: "xx-large",
+				7: "xxx-large"
+			}[num];
+		}
+
+		// "If value is not one of the strings "xx-small", "x-small", "small",
+		// "medium", "large", "x-large", "xx-large", "xxx-large", and is not a
+		// valid CSS absolute length, then do nothing and abort these steps."
+		//
+		// More cheap hacks to skip of valid CSS absolute length checks.
+		if (["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "xxx-large"].indexOf(value) == -1
+		&& !/^[0-9]+(\.[0-9]+)?(cm|mm|in|pt|pc)$/.test(value)) {
+			return;
+		}
+
+		// "Decompose the range, then set the value of each returned node to
+		// value."
+		var nodeList = decomposeRange(range);
+		for (var i = 0; i < nodeList.length; i++) {
+			setNodeValue(nodeList[i], command, value);
+		}
+		break;
+
 		case "forecolor":
 		// "If value is not a valid CSS color, the user agent must do nothing
 		// and abort these steps. Otherwise, it must decompose the range, then
--- a/source.html	Sun Apr 10 15:12:29 2011 -0600
+++ b/source.html	Mon Apr 11 14:48:46 2011 -0600
@@ -291,6 +291,9 @@
 given <var>command</var> is returned by the following algorithm, which will
 return either a string or null:
 
+<p class=XXX>"Specified value" already means something in CSS, I need to find a
+different name.
+
 <ol>
   <li>If <var>command</var> is "hiliteColor" and the [[element]]'s
   display property does not compute to "inline", return null.
@@ -358,7 +361,8 @@
 
   <li>If <var>element</var> is a [[font]] element that has an attribute whose
   effect is to create a [[presentationalhint]] for <var>property</var>, return
-  the value that the hint sets <var>property</var> to.
+  the value that the hint sets <var>property</var> to.  (For a [[fontsize]] of
+  7, this will be the non-CSS value "xxx-large".)
 
   <li>If <var>element</var> is in the following list, and <var>property</var> is
   equal to the CSS property name listed for it, return the string listed for
@@ -713,6 +717,11 @@
       value</span> for <var>command</var> is neither null nor equal to
       <var>propagated value</var>, continue with the next <var>child</var>.
 
+      <p class=XXX>This will be incorrect for relative font sizes.  If the font
+      size on the parent was removed and the font size on the child is in ems
+      or percents or something, it will now change value.  This isn't likely to
+      come up, so we'll ignore it for now.
+
       <li>If <var>child</var> is the last member of <var>ancestor list</var>,
       continue with the next <var>child</var>.
 
@@ -922,12 +931,6 @@
     title=dom-Document-createElement>createElement("font")</code> on the
     [[ownerdocument]] of <var>node</var>, then set the [[fontface]] attribute
     of <var>new parent</var> to <var>new value</var>.
-
-    <li>If <var>command</var> is "fontSize", let <var>new parent</var> be the
-    result of calling <code data-anolis-spec=domcore
-    title=dom-Document-createElement>createElement("font")</code> on the
-    [[ownerdocument]] of <var>node</var>, then set the [[fontsize]] attribute
-    of <var>new parent</var> to <var>new value</var>.
   </ol>
 
   <li>If <var>command</var> is "createLink" or "unlink", let <var>new
@@ -936,6 +939,29 @@
   [[ownerdocument]] of <var>node</var>, then set the [[href]] attribute of
   <var>new parent</var> to <var>new value</var>.
 
+  <!-- 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 font tag no matter what. -->
+  <li>If <var>command</var> is "fontSize"; and <var>new value</var> is one of
+  "xx-small", "small", "medium", "large", "x-large", "xx-large", or
+  "xxx-large"; and either the <span>CSS styling flag</span> is false, or
+  <var>new value</var> is "xxx-large": let <var>new parent</var> be the result
+  of calling <code data-anolis-spec=domcore
+  title=dom-Document-createElement>createElement("font")</code> on the
+  [[ownerdocument]] of <var>node</var>, then set the [[fontsize]] attribute of
+  <var>new parent</var> to the number from the following table based on
+  <var>new value</var>:
+
+  <dl class=switch>
+    <dt>xx-small <dd>1
+    <dt>small <dd>2
+    <dt>normal <dd>3
+    <dt>large <dd>4
+    <dt>x-large <dd>5
+    <dt>xx-large <dd>6
+    <dt>xxx-large <dd>7
+  </dl>
+
   <!-- We always use sup/sub elements, even in CSS mode, following Gecko and
   contradicting WebKit.  This is because <span value="vertical-align:
   sub/super">, the obvious equivalent (and what WebKit uses), behaves quite
@@ -964,7 +990,8 @@
   <li>If the <span>effective value</span> of <var>command</var> for <var>new
   parent</var> is not <var>new value</var>, and the <span>relevant CSS
   property</span> for <var>command</var> is not null, set that CSS property of
-  <var>new parent</var> to <var>new value</var>.
+  <var>new parent</var> to <var>new value</var> (if the new value would be
+  valid).
 
   <li>If <var>command</var> is "strikethrough", and <var>new value</var> is
   "line-through", and the <span>effective value</span> of "strikethrough" for
@@ -988,8 +1015,10 @@
 
     <li>Remove <var>new parent</var> from its [[parent]].
 
-    <li>If <var>new parent</var> is a [[span]], and either <var>command</var>
-    is "underline" or <var>command</var> is "strikethrough" or the
+    <li>If <var>new parent</var> is a [[span]], and either a)
+    <var>command</var> is "underline" or "strikethrough", or b)
+    <var>command</var> is "fontSize" and <var>new value</var> is not
+    "xxx-large", or c) <var>command</var> is not "fontSize" and the
     <span>relevant CSS property</span> for <var>command</var> is not null:
 
     <ol>
@@ -1370,6 +1399,116 @@
 <dd><strong>Relevant CSS Property</strong>: "font-family"
 
 
+<dt><code title><dfn title=command-fontsize>fontSize</dfn></code>
+
+<dd><strong>Action</strong>:
+<!--
+IE 9: Parses the value as a number (allowing floating-point), rounds to the
+  nearest integer, then clamps to the range 1 to 7.  If the value is not a
+  valid number, including if it has trailing characters (like "2em"), does
+  nothing.  Normalizes relative sizes, so "+0" is the same as "+3", etc.
+  Treats empty string the same as "1".
+Firefox 4.0: Passes the value through literally to <font size=>, so "2em" gets
+  you <font size="2em">.  Always uses <font>, even with styleWithCss true.
+  Ignores the command if the value is the empty string.
+Chrome 12 dev: Parses the value as a legacy font size, so "2em" becomes "2",
+  then outputs a <font> with the resulting number.  If there is no resulting
+  number, like for a value of "xx-small", does nothing.  In styleWithCss mode,
+  outputs a span with corresponding CSS keywords: 1 = x-small, 2 = small,
+  . . ., 6 = xx-large, 7 = -webkit-xxx-large.  Normalizes relative sizes, so
+  "+0" is the same as "3", etc.  Ignores the command if the value is the empty
+  string.
+Opera 11: Parses the value as an integer (ignoring floating-point as trailing
+  characters), then outputs that.  This means that "+0" becomes <font size=0>
+  instead of <font size=+0> or <font size=3>.  Non-numeric values get
+  interpreted as 0.  Does not clamp, and is willing to output negative numbers.
+  Treats empty string as "0".
+
+What all of these have in common is that they force the author to deal with
+legacy font values and don't let them use CSS.  This is undesirable, so I
+ignore how implementations behave.  Practically any value that did the same
+thing in IE and Firefox should still do the same thing here, so I'm only
+respecifying non-interoperable behavior anyway.
+-->
+<ol>
+  <li>If <var>value</var> is the empty string, do nothing and abort these
+  steps.
+
+  <li><span data-anolis-spec=html>Strip leading and trailing whitespace</span>
+  from <var>value</var>.
+
+  <li>If <var>value</var> is a <span data-anolis-spec=html>valid floating point
+  number</span>, or would be a <span data-anolis-spec=html>valid floating point
+  number</span> if a single leading "+" character were stripped:
+
+  <ol>
+    <li>If the first character of <var>value</var> is "+", delete the character
+    and let <var>mode</var> be "relative-plus".
+
+    <li>Otherwise, if the first character of <var>value</var> is "-", delete
+    the character and let <var>mode</var> be "relative-minus".
+
+    <li>Otherwise, let <var>mode</var> be "absolute".
+
+    <li>Apply the <span data-anolis-spec=html>rules for parsing non-negative
+    integers</span> to <var>value</var>, and let <var>number</var> be the
+    result.
+
+    <li>If <var>mode</var> is "relative-plus", add three to <var>number</var>.
+
+    <li>If <var>mode</var> is "relative-minus", negate <var>number</var>, then
+    add three to it.
+
+    <li>If <var>number</var> is less than one, let <var>number</var> equal 1.
+
+    <li>If <var>number</var> is greater than seven, let <var>number</var> equal
+    7.
+
+    <li>Set <var>value</var> to the string here corresponding to
+    <var>number</var>:
+
+    <dl class=switch>
+      <dt>1 <dd>xx-small
+      <dt>2 <dd>small
+      <dt>3 <dd>normal
+      <dt>4 <dd>large
+      <dt>5 <dd>x-large
+      <dt>6 <dd>xx-large
+      <dt>7 <dd>xxx-large
+    </dl>
+
+    <p class=XXX>The entry for 7 here is an issue: there's no CSS value that
+    corresponds to it.  Even if we got one added to the drafts, it wouldn't be
+    backward-compatible to use it.  WebKit is the only engine that supports CSS
+    output for fontSize, and it uses -webkit-xxx-large in this case, which is
+    unworkable.  Instead, we just always output a font tag for size 7.  If
+    authors want conforming markup, they'll need to give CSS sizes above size
+    7, not legacy sizes.
+  </ol>
+
+  <li>If <var>value</var> is not one of the strings "xx-small", "x-small",
+  "small", "medium", "large", "x-large", "xx-large", "xxx-large", and is not a
+  valid CSS absolute length, then do nothing and abort these steps.
+
+  <p class=XXX>Not sure this is the best way to do it.  We don't want to allow
+  relative lengths, because those can have very weird user-visible behavior.
+  For instance, a size of 2em would sometimes double the text size, but if you
+  applied it a second time it would do nothing, but if you deselected one
+  character it would suddenly double the size again.  Current UAs just only
+  allow numeric values.  There's no harm in allowing "x-small" and absolute
+  sizes, I don't think.
+
+  <li><span>Decompose</span> the [[range]], then <span>set the value</span> of
+  each returned [[node]] to <var>value</var>.
+</ol>
+
+<dd><strong>State</strong>:
+
+<dd><strong>Value</strong>:
+
+<dd><strong>Relevant CSS Property</strong>: "font-size"
+
+
 <dt><code title><dfn title=command-forecolor>foreColor</dfn></code>
 
 <dd><strong>Action</strong>: If <var>value</var> is not a valid CSS color,