<body>
<script>

function addRow(table)
{
    var tableRow = document.createElement("tr");
    table.appendChild(tableRow);
    return tableRow;
}

function addCellWithNodeContents(tableRow, contents)
{
    var tableCell = document.createElement("td");
    tableCell.appendChild(contents);
    tableRow.appendChild(tableCell);
    return tableCell;
}

function addCellWithTextContents(tableRow, contents)
{
    return addCellWithNodeContents(tableRow, document.createTextNode(contents));
}

function addHeaderWithTextContents(tableRow, contents)
{
    var tableCell = document.createElement("th");   
    tableCell.appendChild(document.createTextNode(contents));
    tableRow.appendChild(tableCell);
    return tableCell;
}

function setFontSizeOnContent(size)
{
    window.getSelection().selectAllChildren(editableDiv);
    document.execCommand("FontSize", false, size);
    return editableDiv.firstChild;
}

function setFontFamilyOnContent(fontFamily)
{
    window.getSelection().selectAllChildren(editableDiv);
    document.execCommand("FontName", false, fontFamily);
    return editableDiv.firstChild;
}

function reportSizeForSpan(span, comment)
{
    var tableRow = addRow(table);
    addCellWithTextContents(tableRow, comment);
    addCellWithTextContents(tableRow, span.parentNode.innerHTML); // sill FF has no outerHTML
    window.getSelection().selectAllChildren(span.parentNode);
    addCellWithTextContents(tableRow, "" + document.queryCommandValue("FontSize"));
}

function testExecCommandFontSize(size, fontFamily)
{
    editableDiv.innerHTML = "test";
    var sizedContent = setFontSizeOnContent(size);
    if (fontFamily)
        sizedContent = setFontFamilyOnContent(fontFamily);
    var sizeString = (typeof(size) == "string") ? ("'" + size + "'") : size;
    reportSizeForSpan(sizedContent, "execCommand('FontSize', " + sizeString + ")");
}

function testManualFontSize(size)
{
    editableDiv.innerHTML = "<span style='font-size: " + size + "'>test</span>";
    reportSizeForSpan(editableDiv.firstChild, "manual CSS font-size: " + size);
}

if (window.testRunner)
    window.testRunner.dumpAsText();

var editableDiv = document.createElement("div");
editableDiv.contentEditable = true;
document.body.appendChild(editableDiv);

var table = document.createElement("table");
table.border = "1px";
table.width = "100%";
document.body.appendChild(table);

var tableRow = addRow(table);
addHeaderWithTextContents(tableRow, "test");
addHeaderWithTextContents(tableRow, "html");
addHeaderWithTextContents(tableRow, "queryCommandValue result");

for (var size = -2; size < 8; size++) {
    testExecCommandFontSize(size);
}
testExecCommandFontSize("8px");
testExecCommandFontSize("2px");

testManualFontSize("3px");
testManualFontSize("0.2em");
testManualFontSize("17px");
testManualFontSize("31px");
testManualFontSize("50px");
testManualFontSize("5em");
testManualFontSize("10px");

tableRow = addRow(table);
addHeaderWithTextContents(tableRow, "monospace tests to ensure the bug 19161 does not affect queryCommandValue's values");

for (var size = -2; size < 8; size++) {
    testExecCommandFontSize(size, 'monospace');
}

document.body.removeChild(editableDiv);

</script>
