<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test-pre.js"></script>
<script src="../resources/event-sender-util.js"></script>
<script src="../resources/shadow-test-driver.js"></script>
<script src="polyfill.js"></script>
</head>
<body>

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

<script>
function createShadowDOM(shadowRoot, name) {
    var hostInShadowRoot = document.createElement('span');
    var nestedShadowRoot = hostInShadowRoot.webkitCreateShadowRoot();
    var spanInShadow = createSpanWithText('SPAN IN NESTED IN SHADOW ' + name);
    nestedShadowRoot.appendChild(spanInShadow);

    var span1 = createSpanWithText('SPAN 1 IN' + name);
    var span2 = createSpanWithText('SPAN 2 IN' + name);
    var span3 = createSpanWithText('SPAN 3 IN' + name);

    shadowRoot.appendChild(span1);
    shadowRoot.appendChild(hostInShadowRoot);
    shadowRoot.appendChild(span2);
    shadowRoot.appendChild(document.createElement('shadow'));
    shadowRoot.appendChild(span3);

    return new Array(spanInShadow, span1, span2, span3);
}

var spanInContainer1 = createSpanWithText('CONTAINER1');
var spanInContainer2 = createSpanWithText('CONTAINER2');

var host = document.createElement('div');
var spanInHost = createSpanWithText('IN HOST');
host.appendChild(spanInHost);

var olderShadowRoot = host.webkitCreateShadowRoot();
var spans1 = createShadowDOM(olderShadowRoot, 'OLDER');

var youngerShadowRoot = host.webkitCreateShadowRoot();
var spans2 = createShadowDOM(youngerShadowRoot, 'YOUNGER');

var container = document.getElementById('container');
container.appendChild(spanInContainer1);
container.appendChild(host);
container.appendChild(spanInContainer2);

var allSpans = new Array(spanInContainer1, spanInContainer2, spanInHost);
allSpans = allSpans.concat(spans1);
allSpans = allSpans.concat(spans2);

// Do Layout
container.offsetLeft;

// Selects all combinations of spans.
for (var i = 0; i < allSpans.length; ++i) {
    for (var j = 0; j < allSpans.length; ++j) {
        mouseMoveToElem(allSpans[i]);
        eventSender.mouseDown();
        mouseMoveToElem(allSpans[j]);
        eventSender.mouseUp();

        // Checks havings the same selection.
        debug(allSpans[i].textContent + ' --> ' + allSpans[j].textContent);
        shouldBe("internals.treeScopeRootNode(window.getSelection().anchorNode)", 
                 "internals.treeScopeRootNode(window.getSelection().focusNode)"); 

        // clear seleciton.
        window.getSelection().removeAllRanges();
    }
}

// Do double click for all spans.
for (var i = 0; i < allSpans.length; ++i) {
    mouseMoveToElem(allSpans[i]);
    eventSender.mouseDown();
    eventSender.mouseUp();
    eventSender.mouseDown();
    eventSender.mouseUp();

    // Checks havings the same selection.
    debug(allSpans[i].textContent + ": double click");
    shouldBe("internals.treeScopeRootNode(window.getSelection().anchorNode)", 
             "internals.treeScopeRootNode(window.getSelection().focusNode)"); 

    window.getSelection().removeAllRanges();
}

// Removes
while (container.firstChild)
    container.removeChild(container.firstChild);

var successfullyParsed = true;
</script>
<script src="../../../resources/js-test-post.js"></script>
</body>

</html>
