--- 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-—-last-update-10-april-2011>Work in Progress — Last Update 10 April 2011</h2>
+<h2 class="no-num no-toc" id=work-in-progress-—-last-update-11-april-2011>Work in Progress — Last Update 11 April 2011</h2>
<dl>
<dt>Editor
<dd>Aryeh Gregor <ayg+spec@aryeh.name>
@@ -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,