<!DOCTYPE html>
<html>
<head>
<title>Selections in hidden elements</title>
<meta name="timeout" content="long">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<style>
container, my-text {
    display: block;
}

.hide {
    position:relative;
    overflow:hidden;
    height:0px;
    width:10px;
}
.select {
    height:11px;
    width:1px;
    padding:0px;
    border:1px solid blue;
    box-sizing:content-box;
    overflow:hidden;
}
.abs {
    position: absolute;
}
.borderBox {
    box-sizing:border-box;
}
</style>
<container>
<textarea class=select>test text</textarea>
<my-text class=select>test text</my-text>
</container>
<button id="nextStepButton" onclick="runNextStep()">Run next step</button>
<div id="output" contenteditable></div>
<script>
let runNextStep = null;
async function checkSelectable(test, element, expected)
{
    const selectText = () => {
        var selection = document.getSelection();
        if (element.select)
            element.select();
        else
            selection.selectAllChildren(element);
    };

    const copyPromise = new Promise((resolve) => {
        runNextStep = () => {
            test.step(() => {
                selectText();
                document.execCommand('copy');
            });
            setTimeout(resolve, 0);
        }
    });
    if (window.testRunner || document.queryCommandEnabled('copy'))
        runNextStep();

    await copyPromise;

    const pastePromise = new Promise((resolve) => {
        runNextStep = () => {
            test.step(() => {
                output.textContent = '';
                let pastedContent = null;
                output.addEventListener('paste', (event) => {
                    pastedContent = event.clipboardData.getData('text/plain');
                }, {once: true});
                output.focus();
                getSelection().collapse(output, 0);
                document.execCommand('paste');
                if (expected)
                    assert_equals(output.textContent, "test text");
                else
                    assert_equals(output.textContent, "");
            });
            test.done();
            setTimeout(resolve, 0);
        }
    });
    if (window.testRunner || document.queryCommandEnabled('paste'))
        runNextStep();

    await pastePromise;
}

if (window.testRunner)
    nextStepButton.style.display = 'none';

var textarea = document.querySelector("textarea");
var myText = document.querySelector("my-text");

let test1 = null;
async_test(function (test) {
    test1 = checkSelectable(test, textarea, true);
}, "Selecting in barely visible textarea");

let test2 = null;
async_test(function (test) {
    test2 = test1.then(() => checkSelectable(test, myText, true));
}, "Selecting in barely visible div");  

let test3 = null;
async_test(function (test) {
    test3 = test2.then(() => {
        document.querySelector("container").classList.add("hide");
        return checkSelectable(test, textarea, false);
    });
}, "Selecting in textarea hidden by container");

let test4 = null;
async_test(function (test) {
    test4 = test3.then(() => checkSelectable(test, myText, false));
}, "Selecting in div hidden by container");

let test5 = null;
async_test(function (test) {
    test5 = test4.then(() => {
        textarea.classList.add("abs");
        myText.classList.add("abs");
        return checkSelectable(test, textarea, true);
    });
}, "Selecting in absolute positioned textarea hidden by container");

let test6 = null;
async_test(function (test) {
    test6 = test5.then(() => checkSelectable(test, myText, true));
}, "Selecting in absolute positioned div hidden by container");

let test7 = null;
async_test(function (test) {
    test7 = test6.then(() => {
        textarea.classList.add("borderBox");
        myText.classList.add("borderBox");
        return checkSelectable(test, textarea, true);
    });
}, "Selecting in absolute positioned zero content width textarea hidden by container (quirk behavior)");

async_test(function (test) {
    test7.then(() => checkSelectable(test, myText, false));
}, "Selecting in absolute positioned zero content width div hidden by container");

</script>
</body>
</html>
