<!DOCTYPE html>
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<script src="../../resources/ui-helper.js"></script>
<script>
var wheelCount = 0;
function onScrollWheel(evt) {
    wheelCount = wheelCount + 1;
}

function onLoad() {
    document.addEventListener("mousewheel", onScrollWheel);
    window.addEventListener("scroll", onPageScroll);
}
</script>
</head>
<body onload="onLoad();">
<script>

var iframeTarget;
var pageScrollPositionBefore;
var iFrameScrollPositionBefore;
var continueCount = 5;

function onPageScroll()
{
    if (document.scrollingElement.scrollTop >= 70)
        checkForScroll();
}

function checkForScroll()
{
    // The IFrame should not have scrolled at all.
    var pageScrollPositionAfter = document.scrollingElement.scrollTop;
    var iFrameScrollPositionAfter = window.frames['target'].document.scrollingElement.scrollTop;

    if (iFrameScrollPositionBefore != iFrameScrollPositionAfter)
        testFailed("IFrame consumed wheel events.");
    else
        testPassed("IFrame did not receive wheel events.");

    if (window.internals) {
        document.getElementById('layers').innerText = internals.layerTreeAsText(document,
            internals.LAYER_TREE_INCLUDES_VISIBLE_RECTS | internals.LAYER_TREE_INCLUDES_TILE_CACHES);
    }

    testRunner.notifyDone();
}

async function scrollTest()
{
    pageScrollPositionBefore = document.scrollingElement.scrollTop;
    iFrameScrollPositionBefore = window.frames['target'].document.scrollingElement.scrollTop;

    iframeTarget = document.getElementById('target');

    // Scroll the #source until we reach the #target.
    const startPosX = Math.round(iframeTarget.offsetLeft) + 20;
    const startPosY = Math.round(iframeTarget.offsetTop) - 42; // Slightly more than one wheel scroll away from the IFrame

    const events = [
        {
            type : "wheel",
            viewX : startPosX,
            viewY : startPosY,
            deltaY : -10,
            phase : "began"
        },
        {
            type : "wheel",
            deltaY : -10,
            phase : "changed"
        },
        {
            type : "wheel",
            deltaY : -10,
            phase : "changed"
        },
        {
            type : "wheel",
            phase : "ended"
        },
        {
            type : "wheel",
            deltaY : -10,
            momentumPhase : "began"
        },
        {
            type : "wheel",
            deltaY : -40,
            momentumPhase : "changed"
        },
        {
            type : "wheel",
            momentumPhase : "ended"
        }
    ];

    await UIHelper.mouseWheelSequence({ events: events });
    checkForScroll();
    // We should finish via the scroll event; this will fire in the case of failure when the page doesn't scroll.
}

function setupTopLevel()
{
    if (window.eventSender) {
        testRunner.dumpAsText();
        testRunner.waitUntilDone();
        setTimeout(scrollTest, 0);
    } else {
        var messageLocation = document.getElementById('parent');
        var message = document.createElement('div');
        message.innerHTML = "<p>This test is better run under DumpRenderTree. To manually test it, place the mouse pointer<br/>"
            + "at the top of the page, and then use the mouse wheel or a two-finger swipe to scroll the<br/>"
            + "down past the IFrame.<br/><br/>"
            + "You should not see the row of END labels if this test is successful.</p>";
        messageLocation.appendChild(message);
    }
}

</script>
<div id="parent" style="height: 2000px;">
    <div id="source" style="height: 100px">
        Put mouse here and flick downwards
    </div>
    <iframe id="target" name="target" style="border:solid 1px green; height: 300px; width: 500px;" 
     src= "data:text/html,
     <div id='notToBeScrolled' style='height: 1000px; width: 1000px;'>
     TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP TOP<br/><br/>
     This should still be visible inside the frame after you scroll down
     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
     <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
     This should NOT be visible inside the frame after you scroll down<br/>
     <br/>
     END END END END END END END END END END END END END
     </div>
     "
     onload="setupTopLevel();"
     >
    </iframe>
</div>
<div id="console"></div>
<script>
description("Tests that iframe doesn't consume wheel events when scroll ");
</script>
<pre id="layers">Layer tree goes here</p>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
