<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<script src="resources/js-test-selection-shared.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script>
description('For Bug 72939: Asynchronous SpellChecker should consider multiple requests.');

jsTestIsAsync = true;

if (window.internals)
    internals.settings.setAsynchronousSpellCheckingEnabled(true);

var testRoot = document.createElement("div");
document.body.insertBefore(testRoot, document.body.firstChild);

var source1 = document.createElement("div");
source1.innerHTML = "foo bar";
testRoot.appendChild(source1);

var source2 = document.createElement("div");
source2.innerHTML = "zz apple orange";
testRoot.appendChild(source2);

function createInput(testRoot) {
    var e = document.createElement('input');
    e.setAttribute("type", "text");
    testRoot.appendChild(e);

    return e;
}

function createTextArea(testRoot) {
    var e = document.createElement("textarea");
    testRoot.appendChild(e);

    return e;
}

function createContentEditable(testRoot) {
    var e = document.createElement("div");
    e.setAttribute("contentEditable", "true");
    testRoot.appendChild(e);

    return e;
}

var destinations = [
    createInput(testRoot),
    createTextArea(testRoot),
    createContentEditable(testRoot),
    createInput(testRoot),
    createTextArea(testRoot),
    createContentEditable(testRoot),
    createInput(testRoot),
    createTextArea(testRoot),
    createContentEditable(testRoot),
];

var sel = window.getSelection();

var tests = [];
for (var i = 0; i < destinations.length; ++i) {
    var t = function(i) {
        return function() { verify(source2, destinations[i], ["zz"]); }
    }(i);
    tests.push(t);
}

function verifyIfAny()
{
    var next = tests.shift();
    if (next) {
        next();
        return;
    }

    testRoot.style.display = "none";
    finishJSTest();
}

function findFirstTextNode(node)
{
    function iterToFindFirstTextNode(node)
    {
        if (node instanceof Text)
            return node;

        var childNodes = node.childNodes;
        for (var i = 0; i < childNodes.length; ++i) {
            var n = iterToFindFirstTextNode(childNodes[i]);
            if (n)
                return n;
        }

        return null;
    }


    if (node instanceof HTMLInputElement || node instanceof HTMLTextAreaElement)
        return iterToFindFirstTextNode(internals.shadowRoot(node));
    else
        return iterToFindFirstTextNode(node);
}

function verifyMarker(node, expectedMarked)
{
    if (!window.testRunner || !window.internals)
        return false;

    var textNode = findFirstTextNode(node);

    var num = internals.markerCountForNode(textNode, "spelling");
    if (num != expectedMarked.length)
        return false;
    for (var i = 0; i < num; ++i) {
        var range = internals.markerRangeForNode(textNode, "spelling", i);
        if (range.toString() != expectedMarked[i])
            return false;
    }

    return true;
}

function copyAndPaste(source, dest)
{
    sel.selectAllChildren(source);
    document.execCommand("Copy");

    if (dest instanceof HTMLInputElement || dest instanceof HTMLTextAreaElement) {
        dest.value = "";
        dest.focus();
    } else {
        dest.innerHTML = "";
        sel.selectAllChildren(dest);
    }
    document.execCommand("Paste");
}

function verify(source, dest, expectedMarked)
{
    var nretry = 10;
    var nsleep = 1;
    function trial() {
        var verified = verifyMarker(dest, expectedMarked);
        if (verified) {
            testPassed(dest.tagName + " has a marker on '" + source.innerHTML + "'");
            verifyIfAny();
            return;
        }

        nretry--;
        if (0 == nretry) {
            testFailed(dest.tagName + " should have a marker on for '" + source.innerHTML + "'");
            verifyIfAny();
            return;
        }

        nsleep *= 2;
        window.setTimeout(trial, nsleep);
    };
    trial();
}


// paste "foo bar"
for (var i = 0; i < destinations.length; ++i)
    copyAndPaste(source1, destinations[i]);

// paste "zz apple orange"
for (var i = 0; i < destinations.length; ++i)
    copyAndPaste(source2, destinations[i]);

verifyIfAny();

var successfullyParsed = true;

</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
