<!DOCTYPE html>
<html>
<head>
<title>Shadow DOM: The indicated part of the document should not match an element inside a shadow tree</title>
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<meta name="assert" content="An element inside a shadow tree should not be the indicated part of the document even if its ID is exactly equal to the decoded fragid or its name attribute is exactly equal to the fragid">
<link rel="help" href="https://html.spec.whatwg.org/multipage/browsers.html#scroll-to-the-fragment-identifier">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<div id="testContainer"></div>
<script>

var tests = [
    {test: async_test('The user agent scroll to the fragment when there is an element with an ID exactly equal to the decoded fragid'),
        execute: testScrollingToElementInDocumentTree.bind(this, 'div')},
    {test: async_test('The user agent scroll to the fragment when there is an anchor element with a name attribute exactly equal to the decoded fragid'),
        execute: testScrollingToElementInDocumentTree.bind(this, 'a')},

    {test: async_test('The user agent should not scroll to an element with an ID exactly equal to the decoded fragid in an open shadow tree'),
        execute: testScrollingToElementInShadowTree.bind(this, 'div', 'open')},
    {test: async_test('The user agent should not scroll to an element with an ID exactly equal to the decoded fragid in a closed shadow tree'),
        execute: testScrollingToElementInShadowTree.bind(this, 'div', 'closed')},
    {test: async_test('The user agent should not scroll to an anchor element with a name attribute exactly equal to the decoded fragid in an open shadow tree'),
        execute: testScrollingToElementInShadowTree.bind(this, 'a', 'open')},
    {test: async_test('The user agent should not scroll to an anchor element with a name attribute exactly equal to the decoded fragid in a closed shadow tree'),
        execute: testScrollingToElementInShadowTree.bind(this, 'a', 'closed')},

    {test: async_test('The user agent should scroll to an element with an ID exactly equal to the decoded fragid in the document tree'
        + ' even if there was another element with the same ID inside an open shadow tree earlier in tree order'),
        execute: testScrollingToElementInDocumentTreeAfterElementInShadowTreeWithSameID.bind(this, 'div', 'open')},
    {test: async_test('The user agent should scroll to an element with an ID exactly equal to the decoded fragid in the document tree'
        + ' even if there was another element with the same ID inside a closed shadow tree earlier in tree order'),
        execute: testScrollingToElementInDocumentTreeAfterElementInShadowTreeWithSameID.bind(this, 'div', 'closed')},
    {test: async_test('The user agent should scroll to an anchor element with a name attribute exactly equal to the decoded fragid in the document tree'
        + ' even if there was another element with the same ID inside an open shadow tree earlier in tree order'),
        execute: testScrollingToElementInDocumentTreeAfterElementInShadowTreeWithSameID.bind(this, 'a', 'open')},
    {test: async_test('The user agent should scroll to an anchor element with a name attribute exactly equal to the decoded fragid in the document tree'
        + ' even if there was another element with the same ID inside a closed shadow tree earlier in tree order'),
        execute: testScrollingToElementInDocumentTreeAfterElementInShadowTreeWithSameID.bind(this, 'a', 'closed')},
];

function executeNextTest()
{
    window.scrollTo(0, 0);

    currentFragIdSuffix++;
    var nextTest = tests.shift();
    if (!nextTest)
        return;
    setTimeout(function () {
        nextTest.execute(nextTest.test);
    }, 0);
}

var testContainer = document.getElementById('testContainer');
var currentFragIdSuffix = 0;

function tallElementMarkup()
{
    return '<div style="height: ' + (window.innerHeight * 2) + 'px"><a href="#fragid' + currentFragIdSuffix + '">Go to fragment</a></div>';
}

function targetMarkup(elementType)
{
    return elementType == 'div' ? ('<div id="fragid' + currentFragIdSuffix + '">hello</div>') : ('<a name="fragid' + currentFragIdSuffix + '">hello</a>');
}

function clickFirstAnchorAndRunStep(test, step)
{
    setTimeout(function () {
        testContainer.querySelector('a').click();
        setTimeout(function () {
            test.step(step);
            testContainer.innerHTML = '';
            test.done();
            executeNextTest();
        }, 0);
    }, 0);
}

function testScrollingToElementInDocumentTree(elementType, test)
{
    test.step(function () {
        testContainer.innerHTML = tallElementMarkup() + targetMarkup(elementType);
        assert_equals(window.pageYOffset, 0);
    });
    clickFirstAnchorAndRunStep(test, function () {
        assert_not_equals(window.pageYOffset, 0);
    });
}

function testScrollingToElementInShadowTree(elementType, mode, test)
{
    test.step(function () {
        testContainer.innerHTML = tallElementMarkup() + '<div id="host"></div>';
        var host = document.querySelector('#host');
        var shadowRoot = host.attachShadow({mode: mode});
        shadowRoot.innerHTML = targetMarkup(elementType);
        assert_equals(window.pageYOffset, 0);
    });
    clickFirstAnchorAndRunStep(test, function () {
        assert_equals(window.pageYOffset, 0);
    });
}

function testScrollingToElementInDocumentTreeAfterElementInShadowTreeWithSameID(elementType, mode, test)
{
    test.step(function () {
        testContainer.innerHTML = tallElementMarkup() + '<div id="host"></div>' + tallElementMarkup() + targetMarkup(elementType);
        var host = document.querySelector('#host');
        var shadowRoot = host.attachShadow({mode: mode});
        shadowRoot.innerHTML = targetMarkup(elementType);
        assert_equals(window.pageYOffset, 0);
    });
    clickFirstAnchorAndRunStep(test, function () {
        assert_true(window.pageYOffset > testContainer.querySelector('#host').offsetTop);
    });
}

executeNextTest();

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