<!doctype html>
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<style>
:matches(#with-renderer, #without-renderer) * {
    background-color: rgb(1, 2, 3);
}
:matches(#with-renderer, #without-renderer) :invalid {
    background-color: rgb(4, 5, 6);
}
</style>
</head>
<body>
    <template id="test-source">
        <form class="form1">
            <div class="div1">
                <fieldset class="fieldset1">
                    <div class="div2">
                        <input class="input1" required value="valid">
                    </div>
                </fieldset>
                <textarea class="textarea1" required></textarea>
            </div>
        </form>
        <form class="form2">
            <div class="div3">
            </div>
        </form>
    </template>
    <div id="with-renderer"></div>
    <div id="without-renderer" style="display:none;"></div>
</body>
<script>
description('Test style update for :invalid applied on a form.');

var withRenderer = document.getElementById("with-renderer");
var withoutRenderer = document.getElementById("without-renderer");
var source = document.getElementById("test-source").content;

withRenderer.appendChild(source.cloneNode(true));
withoutRenderer.appendChild(source.cloneNode(true));

function testStyleAtId(rootId, matchedClass) {
    var allElements = document.getElementById(rootId).querySelectorAll('*');
    for (var i = 0; i < allElements.length; ++i) {
        var expectedStyle = matchedClass.indexOf(allElements[i].className) >= 0 ? 'rgb(4, 5, 6)' : 'rgb(1, 2, 3)';
        shouldBeEqualToString('getComputedStyle(document.getElementById("' + rootId + '").querySelector(".' + allElements[i].className + '")).backgroundColor', expectedStyle);
    }
}

function testStyle(matchedClass) {
    testStyleAtId('with-renderer', matchedClass);
    testStyleAtId('without-renderer', matchedClass);
}

function modifyTree(updateFunction) {
    updateFunction(withRenderer);
    updateFunction(withoutRenderer);
}

debug('');
debug('Initial state');
testStyle(['form1', 'textarea1']);

debug('');
debug("Make the text area valid.");
modifyTree(function(root) {
    root.querySelector('.textarea1').value = "Valid";
});
testStyle([]);

debug('');
debug("Back to invalid. We should be in the initial state.");
modifyTree(function(root) {
    root.querySelector('.textarea1').value = "";
});
testStyle(['form1', 'textarea1']);


debug('');
debug("Move the invalid text area into form2.");
modifyTree(function(root) {
    var textArea = root.querySelector('.textarea1');
    var form2 = root.querySelector('.form2');
    form2.appendChild(textArea);
});
testStyle(['form2', 'textarea1']);

debug('');
debug("Make the text area valid.");
modifyTree(function(root) {
    root.querySelector('.textarea1').value = "Valid";
});
testStyle([]);

debug('');
debug("Make the input invalid.");
modifyTree(function(root) {
    root.querySelector('.input1').value = "";
});
testStyle(['form1', 'fieldset1', 'input1']);

debug('');
debug("Move text area as a child of form1.");
modifyTree(function(root) {
    var textArea = root.querySelector('.textarea1');
    var form1 = root.querySelector('.form1');
    form1.appendChild(textArea);
});
testStyle(['form1', 'fieldset1', 'input1']);

debug('');
debug("Move text area as a child of div1.");
modifyTree(function(root) {
    var textArea = root.querySelector('.textarea1');
    var div1 = root.querySelector('.div1');
    div1.appendChild(textArea);
});
testStyle(['form1', 'fieldset1', 'input1']);

debug('');
debug("Make the text area invalid.");
modifyTree(function(root) {
    root.querySelector('.textarea1').value = "";
});
testStyle(['form1', 'fieldset1', 'input1', 'textarea1']);

debug('');
debug("Make the input valid.");
modifyTree(function(root) {
    root.querySelector('.input1').value = "Valid";
});
testStyle(['form1', 'textarea1']);

debug('');
debug("Make the text area valid, everything should be valid.");
modifyTree(function(root) {
    root.querySelector('.textarea1').value = "Valid";
});
testStyle([]);

debug('');
debug("Make the input invalid.");
modifyTree(function(root) {
    root.querySelector('.input1').value = "";
});
testStyle(['form1', 'fieldset1', 'input1']);


debug('');
debug("Move fieldset1 inside div3");
modifyTree(function(root) {
    var fieldset1 = root.querySelector('.fieldset1');
    var div3 = root.querySelector('.div3');
    div3.appendChild(fieldset1);
});
testStyle(['form2', 'fieldset1', 'input1']);

debug('');
debug("Destroy the content of div2");
modifyTree(function(root) {
    root.querySelector('.div2').textContent = '';
});
testStyle([]);

// Remove the content otherwise it will appear in the results.
withRenderer.style.display = 'none';
</script>
<script src="../../resources/js-test-post.js"></script>
</html>
