<html>

<head>

<script>

var modified;
var oldElement;
var oldContent;
var failureCount = 0;

function setModifiedFlag()
{
    modified = true;
}

function print(message)
{
    var div = document.createElement("div");
    div.appendChild(document.createTextNode(message));
    document.getElementById("results").appendChild(div);
}

function summarizeResult()
{
    if (!modified)
        return "not modified";
    var parent = document.getElementById("parent");
    if (parent.firstChild !== oldElement)
        return "replaced";
    if (oldElement.firstChild !== oldContent)
        return "modified";
    return "modified, with same first child";
}

function runTest(markup, propertyName, newValue, expectedResult)
{
    var parent = document.getElementById("parent");
    parent.innerHTML = "<div>" + markup + "</div>";
    modified = false;
    oldElement = parent.firstChild;
    oldContent = parent.firstChild.firstChild;
    parent.firstChild[propertyName] = newValue;
    var resultValue;
    if (propertyName == "outerHTML")
        resultValue = parent.innerHTML;
    else
        resultValue = parent.firstChild[propertyName];
    var result = resultValue == newValue ? summarizeResult() : "modified incorrectly";
    if (propertyName == "outerHTML")
        markup = "<div>" + markup + "</div>";
    testName = 'starting with "' + markup + '", setting ' + propertyName + ' to "' + newValue + '"';
    if (result == expectedResult)
        print("PASS: " + testName);
    else {
        print("FAIL: " + testName + " -- " + result + ", but expected " + expectedResult);
        ++failureCount;
    }
    if (result == "modified incorrectly")
        print("value was " + resultValue);
}

function test()
{
    if (window.testRunner)
        testRunner.dumpAsText();

    var parent = document.getElementById("parent");
    parent.addEventListener("DOMSubtreeModified", setModifiedFlag, true);

    runTest('', 'innerHTML', '', 'not modified');
    runTest('', 'innerHTML', 'text', 'modified');
    runTest('', 'innerHTML', '<a></a>', 'modified');
    runTest('', 'innerHTML', '<a></a><b></b>', 'modified');

    runTest('text', 'innerHTML', '', 'modified');
    runTest('text', 'innerHTML', 'different text', 'modified');
    runTest('text', 'innerHTML', 'text', 'modified');
    runTest('text', 'innerHTML', '<a></a>', 'modified');
    runTest('text', 'innerHTML', '<a></a><b></b>', 'modified');

    runTest('<a></a>', 'innerHTML', '', 'modified');
    runTest('<a></a>', 'innerHTML', 'text', 'modified');
    runTest('<a></a>', 'innerHTML', '<a></a>', 'modified');
    runTest('<a></a>', 'innerHTML', '<a href=""></a>', 'modified');
    runTest('<a></a>', 'innerHTML', '<a>text</a>', 'modified');
    runTest('<a></a>', 'innerHTML', '<a></a><b></b>', 'modified');

    runTest('<a>text</a>', 'innerHTML', '<a>text</a>', 'modified');
    runTest('<a>text</a>', 'innerHTML', '<a>different text</a>', 'modified');

    runTest('<a href="b"></a>', 'innerHTML', '<a name="c" href="b"></a>', 'modified');
    runTest('<a href="b" name="c"></a>', 'innerHTML', '<a href="b" name="c"></a>', 'modified');
    runTest('<a href="b" name="c"></a>', 'innerHTML', '<a name="c" href="b"></a>', 'modified');

    runTest('', 'innerText', '', 'not modified');
    runTest('', 'innerText', 'text', 'modified');
    runTest('', 'innerText', '<a></a>', 'modified');
    runTest('', 'innerText', '<a></a><b></b>', 'modified');

    runTest('text', 'innerText', '', 'modified');
    runTest('text', 'innerText', 'different text', 'modified');
    runTest('text', 'innerText', 'text', 'modified');

    runTest('<a></a>', 'innerText', '', 'modified');
    runTest('<a></a>', 'innerText', 'text', 'modified');

    runTest('', 'outerHTML', '', 'replaced');
    runTest('', 'outerHTML', 'text', 'replaced');
    runTest('', 'outerHTML', '<a></a>', 'replaced');
    runTest('', 'outerHTML', '<a></a><b></b>', 'replaced');
    runTest('', 'outerHTML', '<div></div>', 'replaced');
    runTest('', 'outerHTML', '<div>text</div>', 'replaced');
    runTest('', 'outerHTML', '<div><a></a></div>', 'replaced');
    runTest('', 'outerHTML', '<div><a></a><b></b></div>', 'replaced');

    runTest('text', 'outerHTML', '', 'replaced');
    runTest('text', 'outerHTML', 'text', 'replaced');
    runTest('text', 'outerHTML', '<a></a>', 'replaced');
    runTest('text', 'outerHTML', '<a></a><b></b>', 'replaced');
    runTest('text', 'outerHTML', '<div></div>', 'replaced');
    runTest('text', 'outerHTML', '<div>text</div>', 'replaced');
    runTest('text', 'outerHTML', '<div>different text</div>', 'replaced');
    runTest('text', 'outerHTML', '<div><a></a></div>', 'replaced');
    runTest('text', 'outerHTML', '<div><a></a><b></b></div>', 'replaced');

    runTest('<a></a>', 'outerHTML', '', 'replaced');
    runTest('<a></a>', 'outerHTML', 'text', 'replaced');
    runTest('<a></a>', 'outerHTML', '<a></a>', 'replaced');
    runTest('<a></a>', 'outerHTML', '<a href=""></a>', 'replaced');
    runTest('<a></a>', 'outerHTML', '<a>text</a>', 'replaced');
    runTest('<a></a>', 'outerHTML', '<a></a><b></b>', 'replaced');
    runTest('<a></a>', 'outerHTML', '<div></div>', 'replaced');
    runTest('<a></a>', 'outerHTML', '<div>text</div>', 'replaced');
    runTest('<a></a>', 'outerHTML', '<div>different text</div>', 'replaced');
    runTest('<a></a>', 'outerHTML', '<div><a></a></div>', 'replaced');
    runTest('<a></a>', 'outerHTML', '<div><a></a><b></b></div>', 'replaced');

    runTest('<a>text</a>', 'outerHTML', '<div><a>text</a></div>', 'replaced');
    runTest('<a>text</a>', 'outerHTML', '<div><a>different text</a></div>', 'replaced');

    runTest('<a href="b"></a>', 'outerHTML', '<div><a name="c" href="b"></a></div>', 'replaced');
    runTest('<a href="b" name="c"></a>', 'outerHTML', '<div><a href="b" name="c"></a></div>', 'replaced');
    runTest('<a href="b" name="c"></a>', 'outerHTML', '<div><a name="c" href="b"></a></div>', 'replaced');

    parent.outerHTML = "";

    if (failureCount == 0)
        print("ALL TESTS PASSED");
    else
        print(failureCount + " TESTS FAILED");
}

</script>

</head>

<body onload="test()">

<p>
    This tests calls to setInnerHTML, setInnerText, and setOuterHTML to see what kind of DOM modifications they cause.
    The calls are optimized to not do any work in cases where the DOM would not change at all.
</p>

<p id="results"></p>

<div id="parent"></div>

</body>

</html>
