--- a/autoimplementation.html Thu Mar 17 16:14:25 2011 -0600
+++ b/autoimplementation.html Fri Mar 18 16:14:18 2011 -0600
@@ -1,11 +1,12 @@
<!doctype html>
-<title>Auto-running execCommand() bold tests</title>
+<title>Auto-running execCommand() tests</title>
<style>
.yes { color: green }
.no { color: red }
b, strong { font-weight: bold }
.bold { font-weight: bold }
.notbold { font-weight: normal }
+#purple { color: purple }
td > div:first-child {
padding-bottom: 0.2em;
border-bottom: 1px solid black;
@@ -13,105 +14,266 @@
td > div:last-child {
padding-top: 0.2em;
}
+/* https://bugs.webkit.org/show_bug.cgi?id=56670 */
+dfn { font-style: italic }
+/* We don't want test cells to not wrap */
+listing, plaintext, pre, xmp { white-space: pre-wrap }
</style>
<p>Legend: {[ are the selection anchor, }] are the selection focus, {}
represent an element boundary point, [] represent a text node boundary point.
Syntax and some of the tests taken from <a
href=http://www.browserscope.org/richtext2/test>Browserscope</a>.
+<h1>Table of Contents</h1>
+<ul>
+ <li><a href=#bold>bold</a>
+ <li><a href=#fontname>fontname</a>
+ <li><a href=#forecolor>forecolor</a>
+ <li><a href=#italic>italic</a>
+</ul>
+
+<div id=bold>
+<h1>bold</h1>
+
+<table border=1><tr><th>Input <th>Spec <th>Browser <th>Same?</table>
+
<p><label>Enter new test here: <input></label>
-<button onclick="addTest(document.querySelector('input').value)">Add test</button>
+<button onclick="addTest('bold', document.querySelector('input').value)">Add test</button>
+</div>
-<div>
+<div id=fontname>
+<h1>fontname</h1>
+
+<p>Tests set the font-family to "serif".
+
<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('input').value)">Add test</button>
+</div>
+
+<div id=forecolor>
+<h1>forecolor</h1>
+
+<p>Tests set the color to "#FF0000".
+
+<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('input').value)">Add test</button>
+</div>
+
+<div id=italic>
+<h1>italic</h1>
+
+<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('input').value)">Add test</button>
</div>
<script src=implementation.js></script>
<script>
-// Note: this data format can only yield selections whose start and end are
-// inside text nodes.
-var tests = [
- 'foo[bar]baz',
- 'foo]bar[baz',
- 'foo[bar<i>baz]qoz</i>quz',
- 'foo<span style="font-weight: bold">[bar]</span>baz',
- 'foo<b>[bar]</b>baz',
- 'foo[<b>bar</b>]baz',
- 'foo[<b>bar]</b>baz',
- 'foo<b>[bar</b>]baz',
- 'foo<strong>[bar]</strong>baz',
- 'foo[<strong>bar</strong>]baz',
- 'foo[<strong>bar]</strong>baz',
- 'foo<strong>[bar</strong>]baz',
- 'foo<span style="font-weight: bold">[bar]</span>baz',
- 'foo[<span style="font-weight: bold">bar</span>]baz',
- 'foo[<span style="font-weight: bold">bar]</span>baz',
- 'foo<span style="font-weight: bold">[bar</span>]baz',
- '<b>{<p>foo</p><p>bar</p>}<p>baz</p></b>',
- '<b><p>foo[<i>bar</i>}</p><p>baz</p></b>',
- 'foo [bar <b>baz] qoz</b> quz sic',
- 'foo bar <b>baz [qoz</b> quz] sic',
- '<b id=foo>bar [baz] qoz</b>',
- 'foo<span style="font-weight: 100">[bar]</span>baz',
- 'foo<span style="font-weight: 400">[bar]</span>baz',
- 'foo<span style="font-weight: 700">[bar]</span>baz',
- 'foo<span style="font-weight: 900">[bar]</span>baz',
- 'foo<span style="font-weight: normal">[bar]</span>baz',
- 'foo<span style="font-weight: 100">[bar</span>]baz',
- 'foo<span style="font-weight: 400">[bar</span>]baz',
- 'foo<span style="font-weight: 700">[bar</span>]baz',
- 'foo<span style="font-weight: 900">[bar</span>]baz',
- 'foo<span style="font-weight: normal">[bar</span>]baz',
- 'foo[<span style="font-weight: 100">bar]</span>baz',
- 'foo[<span style="font-weight: 400">bar]</span>baz',
- 'foo[<span style="font-weight: 700">bar]</span>baz',
- 'foo[<span style="font-weight: 900">bar]</span>baz',
- 'foo[<span style="font-weight: normal">bar]</span>baz',
- 'foo[<span style="font-weight: 100">bar</span>]baz',
- 'foo[<span style="font-weight: 400">bar</span>]baz',
- 'foo[<span style="font-weight: 700">bar</span>]baz',
- 'foo[<span style="font-weight: 900">bar</span>]baz',
- 'foo[<span style="font-weight: normal">bar</span>]baz',
- '<span style="font-weight: 100">foo[bar]baz</span>',
- '<span style="font-weight: 400">foo[bar]baz</span>',
- '<span style="font-weight: 700">foo[bar]baz</span>',
- '<span style="font-weight: 900">foo[bar]baz</span>',
- '<span style="font-weight: normal">foo[bar]baz</span>',
- '{<span style="font-weight: 100">foobar]baz</span>',
- '{<span style="font-weight: 400">foobar]baz</span>',
- '{<span style="font-weight: 700">foobar]baz</span>',
- '{<span style="font-weight: 900">foobar]baz</span>',
- '{<span style="font-weight: normal">foobar]baz</span>',
- '<span style="font-weight: 100">foo[barbaz</span>}',
- '<span style="font-weight: 400">foo[barbaz</span>}',
- '<span style="font-weight: 700">foo[barbaz</span>}',
- '<span style="font-weight: 900">foo[barbaz</span>}',
- '<span style="font-weight: normal">foo[barbaz</span>}',
- '<h3>Foo[bar]baz</h3>',
- '{<h3>Foobar]baz</h3>',
- '<h3>Foo[barbaz</h3>}',
- '<h3>[Foobarbaz]</h3>',
- '{<h3>Foobarbaz]</h3>',
- '<h3>[Foobarbaz</h3>}',
- '{<h3>Foobarbaz</h3>}',
- '<b>Foo<span style="font-weight: normal">bar<b>[baz]</b>quz</span>qoz</b>',
- '<b>Foo<span style="font-weight: normal">[bar]</span>baz</b>',
- '{<b>Foo</b> <b>bar</b>}',
- '{<h3>Foo</h3><b>bar</b>}',
- '<i><b>Foo</b></i>[bar]<i><b>baz</b></i>',
- '<i><b>Foo</b></i>[bar]<b>baz</b>',
- '<b>Foo</b>[bar]<i><b>baz</b></i>',
- '{<p><p> <p>Foo</p>}',
- '[Foo<span class=notbold>bar</span>baz]',
-];
+var tests = {
+ bold: [
+ 'foo[bar]baz',
+ 'foo]bar[baz',
+ '{<p><p> <p>Foo</p>}',
+ 'foo[bar<i>baz]qoz</i>quz',
+ 'foo<span style="font-weight: bold">[bar]</span>baz',
+ 'foo<b>[bar]</b>baz',
+ 'foo[<b>bar</b>]baz',
+ 'foo[<b>bar]</b>baz',
+ 'foo<b>[bar</b>]baz',
+ 'foo<strong>[bar]</strong>baz',
+ 'foo[<strong>bar</strong>]baz',
+ 'foo[<strong>bar]</strong>baz',
+ 'foo<strong>[bar</strong>]baz',
+ 'foo<span style="font-weight: bold">[bar]</span>baz',
+ 'foo[<span style="font-weight: bold">bar</span>]baz',
+ 'foo[<span style="font-weight: bold">bar]</span>baz',
+ 'foo<span style="font-weight: bold">[bar</span>]baz',
+ '<b>{<p>foo</p><p>bar</p>}<p>baz</p></b>',
+ '<b><p>foo[<i>bar</i>}</p><p>baz</p></b>',
+ 'foo [bar <b>baz] qoz</b> quz sic',
+ 'foo bar <b>baz [qoz</b> quz] sic',
+ '<b id=purple>bar [baz] qoz</b>',
+ 'foo<span style="font-weight: 100">[bar]</span>baz',
+ 'foo<span style="font-weight: 400">[bar]</span>baz',
+ 'foo<span style="font-weight: 700">[bar]</span>baz',
+ 'foo<span style="font-weight: 900">[bar]</span>baz',
+ 'foo<span style="font-weight: 400">[bar</span>]baz',
+ 'foo<span style="font-weight: 700">[bar</span>]baz',
+ 'foo[<span style="font-weight: 400">bar]</span>baz',
+ 'foo[<span style="font-weight: 700">bar]</span>baz',
+ 'foo[<span style="font-weight: 400">bar</span>]baz',
+ 'foo[<span style="font-weight: 700">bar</span>]baz',
+ '<span style="font-weight: 100">foo[bar]baz</span>',
+ '<span style="font-weight: 400">foo[bar]baz</span>',
+ '<span style="font-weight: 700">foo[bar]baz</span>',
+ '<span style="font-weight: 900">foo[bar]baz</span>',
+ '{<span style="font-weight: 100">foobar]baz</span>',
+ '{<span style="font-weight: 400">foobar]baz</span>',
+ '{<span style="font-weight: 700">foobar]baz</span>',
+ '{<span style="font-weight: 900">foobar]baz</span>',
+ '<span style="font-weight: 100">foo[barbaz</span>}',
+ '<span style="font-weight: 400">foo[barbaz</span>}',
+ '<span style="font-weight: 700">foo[barbaz</span>}',
+ '<span style="font-weight: 900">foo[barbaz</span>}',
+ '<h3>Foo[bar]baz</h3>',
+ '{<h3>Foobar]baz</h3>',
+ '<h3>Foo[barbaz</h3>}',
+ '<h3>[Foobarbaz]</h3>',
+ '{<h3>Foobarbaz]</h3>',
+ '<h3>[Foobarbaz</h3>}',
+ '{<h3>Foobarbaz</h3>}',
+ '<b>Foo<span style="font-weight: normal">bar<b>[baz]</b>quz</span>qoz</b>',
+ '<b>Foo<span style="font-weight: normal">[bar]</span>baz</b>',
+ '{<b>Foo</b> <b>bar</b>}',
+ '{<h3>Foo</h3><b>bar</b>}',
+ '<i><b>Foo</b></i>[bar]<i><b>baz</b></i>',
+ '<i><b>Foo</b></i>[bar]<b>baz</b>',
+ '<b>Foo</b>[bar]<i><b>baz</b></i>',
+ '[Foo<span class=notbold>bar</span>baz]',
+ ],
+ fontname: [
+ 'foo[bar]baz',
+ 'foo]bar[baz',
+ '{<p><p> <p>Foo</p>}',
-for (var i = 0; i < tests.length; i++) {
- addTest(tests[i]);
+ 'foo<code>[bar]</code>baz',
+ 'foo<kbd>[bar]</kbd>baz',
+ 'foo<listing>[bar]</listing>baz',
+ 'foo<pre>[bar]</pre>baz',
+ 'foo<samp>[bar]</samp>baz',
+ 'foo<tt>[bar]</tt>baz',
+
+ 'foo<code>b[a]r</code>baz',
+ 'foo<kbd>b[a]r</kbd>baz',
+ 'foo<listing>b[a]r</listing>baz',
+ 'foo<pre>b[a]r</pre>baz',
+ 'foo<samp>b[a]r</samp>baz',
+ 'foo<tt>b[a]r</tt>baz',
+
+ '[foo<code>bar</code>baz]',
+ '[foo<kbd>bar</kbd>baz]',
+ '[foo<listing>bar</listing>baz]',
+ '[foo<pre>bar</pre>baz]',
+ '[foo<samp>bar</samp>baz]',
+ '[foo<tt>bar</tt>baz]',
+
+ '[foo<code>ba]r</code>baz',
+ '[foo<kbd>ba]r</kbd>baz',
+ '[foo<listing>ba]r</listing>baz',
+ '[foo<pre>ba]r</pre>baz',
+ '[foo<samp>ba]r</samp>baz',
+ '[foo<tt>ba]r</tt>baz',
+
+ 'foo<code>b[ar</code>baz]',
+ 'foo<kbd>b[ar</kbd>baz]',
+ 'foo<listing>b[ar</listing>baz]',
+ 'foo<pre>b[ar</pre>baz]',
+ 'foo<samp>b[ar</samp>baz]',
+ 'foo<tt>b[ar</tt>baz]',
+
+ 'foo<span style="font-family: serif">[bar]</span>baz',
+ 'foo<span style="font-family: serif">b[a]r</span>baz',
+ 'foo<span style="font-family: monospace">[bar]</span>baz',
+ 'foo<span style="font-family: monospace">b[a]r</span>baz',
+ ],
+ forecolor: [
+ 'foo[bar]baz',
+ 'foo]bar[baz',
+ '{<p><p> <p>Foo</p>}',
+ 'foo[bar<i>baz]qoz</i>quz',
+ 'foo<font color=red>[bar]</font>baz',
+ 'foo{<font color=red>bar</font>}baz',
+ '<span style="color: red">foo<span style="color: blue">[bar]</span>baz</span>',
+ '<span style="color: #f00">foo<span style="color: blue">[bar]</span>baz</span>',
+ '<span style="color: #ff0000">foo<span style="color: blue">[bar]</span>baz</span>',
+ '<span style="color: rgb(255, 0, 0)">foo<span style="color: blue">[bar]</span>baz</span>',
+ '<font color=red>foo<font color=blue>[bar]</font>baz</font>',
+ '<span style="color: rgb(255, 0, 0)">foo<span style="color: blue">b[ar]</span>baz</span>',
+ 'foo<span id=purple>ba[r</span>ba]z',
+ '<span style="color: rgb(255, 0, 0)">foo<span id=purple>b[a]r</span>baz</span>',
+ ],
+ italic: [
+ 'foo[bar]baz',
+ 'foo]bar[baz',
+ '{<p><p> <p>Foo</p>}',
+ 'foo[bar<b>baz]qoz</b>quz',
+ 'foo<span style="font-style: italic">[bar]</span>baz',
+ 'foo<address>[bar]</address>baz',
+ 'foo<cite>[bar]</cite>baz',
+ 'foo<dfn>[bar]</dfn>baz',
+ 'foo<em>[bar]</em>baz',
+ 'foo<i>[bar]</i>baz',
+ 'foo<var>[bar]</var>baz',
+ 'foo{<address>bar</address>}baz',
+ 'foo{<cite>bar</cite>}baz',
+ 'foo{<dfn>bar</dfn>}baz',
+ 'foo{<em>bar</em>}baz',
+ 'foo{<i>bar</i>}baz',
+ 'foo{<var>bar</var>}baz',
+ 'foo<address>b[a]r</address>baz',
+ 'foo<cite>b[a]r</cite>baz',
+ 'foo<dfn>b[a]r</dfn>baz',
+ 'foo<em>b[a]r</em>baz',
+ 'foo<i>b[a]r</i>baz',
+ 'foo<var>b[a]r</var>baz',
+ 'fo[o<address>bar</address>b]az',
+ 'fo[o<cite>bar</cite>b]az',
+ 'fo[o<dfn>bar</dfn>b]az',
+ 'fo[o<em>bar</em>b]az',
+ 'fo[o<i>bar</i>b]az',
+ 'fo[o<var>bar</var>b]az',
+ 'foo[<address>bar</address>baz]',
+ 'foo[<cite>bar</cite>baz]',
+ 'foo[<dfn>bar</dfn>baz]',
+ 'foo[<em>bar</em>baz]',
+ 'foo[<i>bar</i>baz]',
+ 'foo[<var>bar</var>baz]',
+ '[foo<address>bar</address>]baz',
+ '[foo<cite>bar</cite>]baz',
+ '[foo<dfn>bar</dfn>]baz',
+ '[foo<em>bar</em>]baz',
+ '[foo<i>bar</i>]baz',
+ '[foo<var>bar</var>]baz',
+ 'foo<span style="font-style: italic">[bar]</span>baz',
+ 'foo<span style="font-style: oblique">[bar]</span>baz',
+ 'foo<span style="font-style: oblique">b[a]r</span>baz',
+ '<i>{<p>foo</p><p>bar</p>}<p>baz</p></i>',
+ '<i><p>foo[<b>bar</b>}</p><p>baz</p></i>',
+ 'foo [bar <b>baz] qoz</b> quz sic',
+ 'foo bar <b>baz [qoz</b> quz] sic',
+ 'foo [bar <i>baz] qoz</i> quz sic',
+ 'foo bar <i>baz [qoz</i> quz] sic',
+ ],
+};
+
+for (testCat in tests) {
+ for (var i = 0; i < tests[testCat].length; i++) {
+ addTest(testCat, tests[testCat][i]);
+ }
}
-function addTest(test) {
- document.querySelector("div").contentEditable = "true";
- var table = document.querySelector("table");
+function addTest(command, test) {
+ var value = {
+ bold: null,
+ fontname: "serif",
+ forecolor: "#FF0000",
+ italic: null,
+ }[command];
+ var styleWithCss = {
+ bold: false,
+ fontname: true,
+ forecolor: true,
+ italic: false,
+ }[command];
+
+ var div = document.getElementById(command);
+ div.contentEditable = "true";
+ var table = div.querySelector("table");
var tr = document.createElement("tr");
// Insert at the top, because Chrome debugger doesn't let you scroll down
@@ -128,28 +290,40 @@
tr.appendChild(inputCell);
var specCell = document.createElement("td");
- specCell.innerHTML = test;
+ specCell.appendChild(document.createElement("div"));
+ specCell.appendChild(document.createElement("div"));
+ specCell.firstChild.innerHTML = test;
tr.appendChild(specCell);
try {
- selectBrackets(specCell);
- myExecCommand("bold");
- specCell.innerHTML = "<div>" + specCell.innerHTML + "</div><div>" + specCell.innerHTML.replace(/\&/g, "&").replace(/</g, "<") + "</div>";
+ var points = parseBrackets(specCell);
+ var range = document.createRange();
+ range.setStart(points[0], points[1]);
+ range.setEnd(points[2], points[3]);
+ // The points might be backwards
+ if (range.collapsed) {
+ range.setEnd(points[0], points[1]);
+ }
+ myExecCommand(command, false, value, range);
+ specCell.lastChild.textContent = specCell.firstChild.innerHTML;
} catch (e) {
specCell.textContent = "Exception: " + e;
}
var browserCell = document.createElement("td");
- browserCell.innerHTML = test;
+ browserCell.appendChild(document.createElement("div"));
+ browserCell.appendChild(document.createElement("div"));
+ browserCell.firstChild.innerHTML = test;
tr.appendChild(browserCell);
try {
- selectBrackets(browserCell);
+ var points = parseBrackets(browserCell);
+ setSelection(points[0], points[1], points[2], points[3]);
try {
- document.execCommand("styleWithCSS", null, false);
+ document.execCommand("styleWithCss", false, styleWithCss);
} catch (e) {
// IE, we don't care
}
- document.execCommand("bold", null, false);
- browserCell.innerHTML = "<div>" + browserCell.innerHTML + "</div><div>" + browserCell.innerHTML.replace(/\&/g, "&").replace(/</g, "<") + "</div>";
+ document.execCommand(command, false, value);
+ browserCell.lastChild.textContent = browserCell.innerHTML;
} catch (e) {
browserCell.textContent = "Exception: " + e;
}
@@ -160,6 +334,8 @@
.replace(/;? ?"/g, '"');
var normalizedBrowserCell = browserCell.lastChild.textContent
.replace(/;? ?"/g, '"')
+ .replace(/<(\/?)strong/g, '<$1b')
+ .replace(/<(\/?)em/g, '<$1i')
.replace(/ class="Apple-style-span"/g, "");
if (normalizedSpecCell == normalizedBrowserCell) {
sameCell.className = "yes";
@@ -171,10 +347,10 @@
tr.appendChild(sameCell);
getSelection().removeAllRanges();
- document.querySelector("div").contentEditable = "inherit";
+ div.contentEditable = "inherit";
}
-function selectBrackets(node) {
+function parseBrackets(node) {
if (node.textContent.replace(/[^{[]/g, "").length != 1) {
throw "Need one [ or {, found " + node.textContent.replace(/[^{[]/g, "").length;
}
@@ -249,6 +425,10 @@
}
}
+ return [startNode, startOffset, endNode, endOffset];
+}
+
+function setSelection(startNode, startOffset, endNode, endOffset) {
if (navigator.userAgent.indexOf("Opera") != -1) {
// Yes, browser sniffing is evil, but I can't be bothered to debug
// Opera.
--- a/implementation.js Thu Mar 17 16:14:25 2011 -0600
+++ b/implementation.js Fri Mar 18 16:14:18 2011 -0600
@@ -265,6 +265,7 @@
"h1", "h2", "h3", "h4", "h5", "h6", "p", "hr", "pre", "blockquote",
"ol", "ul", "li", "dl", "dt", "dd", "div", "table", "caption",
"colgroup", "col", "tbody", "thead", "tfoot", "tr", "th", "td",
+ "address"
].indexOf(node.tagName.toLowerCase()) != -1;
}
@@ -700,6 +701,38 @@
}
function forceStyle(node, property, newValue) {
+ // "If node is an Element, Text, Comment, or ProcessingInstruction node,
+ // and is not an unwrappable element:"
+ if ((node.nodeType == Node.ELEMENT_NODE
+ || node.nodeType == Node.TEXT_NODE
+ || node.nodeType == Node.COMMENT_NODE
+ || node.nodeType == Node.PROCESSING_INSTRUCTION_NODE)
+ && !isUnwrappableElement(node)) {
+ // "If node's previousSibling is a simple styling element whose
+ // specified style and computed style for property are both new value,
+ // append node as the last child of its previousSibling and abort this
+ // algorithm."
+ if (isSimpleStylingElement(node.previousSibling)
+ && cssValuesEqual(property, getSpecifiedStyle(node.previousSibling, property), newValue)
+ && cssValuesEqual(property, getComputedStyle(node.previousSibling)[property], newValue)) {
+ node.previousSibling.appendChild(node);
+ return;
+ }
+
+ // "If node's nextSibling is a simple styling element whose specified
+ // style and computed style for property are both new value, insert
+ // node as the first child of its nextSibling and abort this
+ // algorithm."
+ if (isSimpleStylingElement(node.nextSibling)
+ && cssValuesEqual(property, getSpecifiedStyle(node.nextSibling, property), newValue)
+ && cssValuesEqual(property, getComputedStyle(node.nextSibling)[property], newValue)) {
+ node.nextSibling.insertBefore(node, node.nextSibling.childNodes.length
+ ? node.nextSibling.childNodes[0]
+ : null);
+ return;
+ }
+ }
+
// "If node is an Element and property computes to new value on node, abort
// this algorithm."
if (node.nodeType == Node.ELEMENT_NODE
@@ -743,28 +776,6 @@
return;
}
- // "If node's previousSibling is a simple styling element whose specified
- // style and computed style for property are both new value, append node as
- // the last child of its previousSibling and abort this algorithm."
- if (isSimpleStylingElement(node.previousSibling)
- && cssValuesEqual(property, getSpecifiedStyle(node.previousSibling, property), newValue)
- && cssValuesEqual(property, getComputedStyle(node.previousSibling)[property], newValue)) {
- node.previousSibling.appendChild(node);
- return;
- }
-
- // "If node's nextSibling is a simple styling element whose specified style
- // and computed style for property are both new value, insert node as the
- // first child of its nextSibling and abort this algorithm."
- if (isSimpleStylingElement(node.nextSibling)
- && cssValuesEqual(property, getSpecifiedStyle(node.nextSibling, property), newValue)
- && cssValuesEqual(property, getComputedStyle(node.nextSibling)[property], newValue)) {
- node.nextSibling.insertBefore(node, node.nextSibling.childNodes.length
- ? node.nextSibling.childNodes[0]
- : null);
- return;
- }
-
// "If node is a Comment or ProcessingInstruction, abort this algorithm."
if (node.nodeType == Node.COMMENT_NODE
|| node.nodeType == Node.PROCESSING_INSTRUCTION_NODE) {
@@ -788,7 +799,7 @@
// "If property is "font-weight" and new value is "bold", let tag be "b"."
var tag;
- if (property == "fontWeight" && newValue == "bold") {
+ if (property == "fontWeight" && (newValue == "bold" || newValue == "700")) {
tag = "b";
// "If property is "font-style" and new value is "italic", let tag be "i"."
} else if (property == "fontStyle" && newValue == "italic") {
@@ -819,10 +830,17 @@
newParent.appendChild(node);
// "If node is an Element and the computed value of property for node is
- // not new value, set the CSS property property of node to new value."
+ // not new value:"
if (node.nodeType == Node.ELEMENT_NODE
&& !cssValuesEqual(property, getComputedStyle(node)[property], newValue)) {
+ // "Set the CSS property property of node to new value."
node.style[property] = newValue;
+
+ // "Insert node into the parent of new parent before new parent."
+ newParent.parentNode.insertBefore(node, newParent);
+
+ // "Remove new parent from its parent."
+ newParent.parentNode.removeChild(newParent);
}
}
@@ -893,9 +911,12 @@
}
}
-function myExecCommand(commandId, showUI, value) {
+function myExecCommand(commandId, showUI, value, range) {
commandId = commandId.toLowerCase();
- var range = getActiveRange(document);
+
+ if (typeof range == "undefined") {
+ range = getActiveRange(document);
+ }
if (!range) {
return;
@@ -991,6 +1012,28 @@
}
*/
+ case "fontname":
+ // "Decompose the Range, then style each returned Node with property
+ // equal to "font-family" and new value equal to value."
+ var nodeList = decomposeRange(range);
+ for (var i = 0; i < nodeList.length; i++) {
+ styleNode(nodeList[i], "fontFamily", 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
+ // style each returned Node with property equal to "color" and new
+ // value equal to value."
+ //
+ // Ignore validation for now.
+ var nodeList = decomposeRange(range);
+ for (var i = 0; i < nodeList.length; i++) {
+ styleNode(nodeList[i], "color", value);
+ }
+ break;
+
case "italic":
// "Decompose the Range. If the state of the Range for this command is
// then true, style each returned Node with property "font-style" and