<!DOCTYPE html>
<html>
<head>
<style>
.editing {
    border: 2px solid red;
    padding: 12px;
    font-size: 24px;
}
</style>
<script src="../editing.js"></script>
<script src="../../resources/ui-helper.js"></script>
<script src="../../resources/js-test.js"></script>
</head>
<body>

<div id="container"></div>

<script>
description("Tests spelling and grammar markers for misspellings.");

jsTestIsAsync = true;

if (window.internals) {
    internals.settings.setUnifiedTextCheckerEnabled(true);
    internals.settings.setAsynchronousSpellCheckingEnabled(true);
}

function createEditableElement(parent, textContent) {
    var e = document.createElement("div");
    e.setAttribute("contentEditable", "true");
    e.textContent = textContent;
    e.className = "editing";

    parent.appendChild(e);
    return e;
}

function typeText(elem, text) {
    elem.focus();
    selectAllCommand();
    deleteCommand();
    for (let character of text)
        typeCharacterCommand(character);
}

const container = document.getElementById("container");
const elementWithGrammarIssue = createEditableElement(container, "I have a issue.");
const elementWithSpellingIssue  = createEditableElement(container, "zz.");
const elementWithGrammarAndSpellingIssue = createEditableElement(container, "orange,zz,apple.");

const misspellings = [
    { marker: "spelling",  issue: "a" },
    { marker: "grammar",  issue: "a" },
    { marker: "grammar",  issue: "I have a issue." },
    { marker: "spelling", issue: "zz" },
    { marker: "grammar",  issue: "orange,zz,apple." },
    { marker: "spelling",  issue: "orange,zz,apple" },
];

const results = [
    { "type": "spelling", "from": 7, "to": 8 },
    {
        "type": "grammar",
        "from": 7,
        "to": 8,
        "details": [{ "from": 0, "to": 1 }]
    },
    {
        "type": "grammar",
        "from": 0,
        "to": 15,
        "details": [{ "from": 7, "to": 8 }]
    }
];

window.element = null;
window.oppositeMarker = null;
window.misspellingData = null;

async function verifyDesiredMarkers(e, misspellings, overrideSpellCheckingResults)
{
    await UIHelper.delayFor(0);

    window.element = e;
    const textToCheck = e.firstChild.nodeValue;

    let spellCheckerResults = { };
    if (overrideSpellCheckingResults)
        spellCheckerResults[textToCheck] = overrideSpellCheckingResults;
    await UIHelper.setSpellCheckerResults(spellCheckerResults);

    for (let misspelling of misspellings) {
        window.misspellingData = misspelling;

        typeText(e, textToCheck);

        debug(`Checking for issue on "${textToCheck}"`);

        await new Promise(resolve => shouldBecomeDifferent("internals.markerRangeForNode(element.firstChild, misspellingData.marker, 0)", "null", resolve));
        range = internals.markerRangeForNode(element.firstChild, misspellingData.marker, 0);
        shouldBeEqualToString("range.toString()", misspellingData.issue);
        debug("");
    }
}

async function verifyUnexpectedMarkers(e, misspellings, overrideSpellCheckingResults)
{
    await UIHelper.delayFor(0);

    window.element = e;
    const textToCheck = e.firstChild.nodeValue;

    let spellCheckerResults = { };
    if (overrideSpellCheckingResults)
        spellCheckerResults[textToCheck] = overrideSpellCheckingResults;
    await UIHelper.setSpellCheckerResults(spellCheckerResults);

    for (let misspelling of misspellings) {
        window.misspellingData = misspelling;

        typeText(e, textToCheck);

        if (misspellingData.marker == "grammar")
            window.oppositeMarker = "spelling";
        else if (misspellingData.marker == "spelling")
            window.oppositeMarker = "grammar";

        debug(`Checking for no other issues on "${textToCheck}"`);

        await new Promise(resolve => shouldBecomeEqual("internals.markerCountForNode(element.firstChild, oppositeMarker)", "0", resolve));
        debug("");
    }
}

addEventListener("load", async function() {
    await verifyDesiredMarkers(elementWithGrammarIssue, misspellings.slice(0, 1), results.slice(0, 1));
    await verifyDesiredMarkers(elementWithGrammarIssue, misspellings.slice(1, 2), results.slice(1, 2));
    await verifyDesiredMarkers(elementWithGrammarIssue, misspellings.slice(0, 2), results.slice(0, 2));
    await verifyDesiredMarkers(elementWithSpellingIssue, misspellings.slice(3, 4));
    await verifyDesiredMarkers(elementWithGrammarAndSpellingIssue, misspellings.slice(4, 6));
    await verifyUnexpectedMarkers(elementWithGrammarIssue, misspellings.slice(0, 1), results.slice(0, 1));
    await verifyUnexpectedMarkers(elementWithGrammarIssue, misspellings.slice(1, 2), results.slice(1, 2));
    await verifyUnexpectedMarkers(elementWithSpellingIssue, misspellings.slice(3, 4));
    finishJSTest();
});
</script>
</body>
</html>
