<html>
<body onload="startTest()">

<script src="../../resources/js-test-pre.js"></script>

<script>

description("This test checks that the page visibility event propagation does not crash the browser when frames are added / deleted.");

var jsTestIsAsync = true;

var numVisibilityChanges = 0;
var frame1, frame2, frame3, frame4, frame5, subframe1, subFrame2, subFrame3;

var docsLoaded = 0;
var mainPageVisibilityChangeDone = false;
var frame2VisiblityChangeDone = false;

function startTest() {
    ++docsLoaded;
    if (docsLoaded < 8) {
      return;
   }

    debug("Loaded all frames.");

    frame1 = document.getElementById("topFrame1");
    frame2 = document.getElementById("topFrame2");
    frame3 = document.getElementById("topFrame3");
    frame4 = document.getElementById("topFrame4");
    subFrame1 = frame3.contentDocument.getElementById("subIframe1");
    subFrame2 = frame3.contentDocument.getElementById("subIframe2");

    document.addEventListener(
        "visibilitychange", onMainPageVisibilityChange, false);
    frame2.contentDocument.addEventListener(
        "visibilitychange", onFrame2VisibilityChange, false);
    // Change the visibility of the current page to invisible.
    if (window.testRunner) {
        numVisibilityChanges++;
        testRunner.setPageVisibility("hidden");
    }
}

function finishTest() {
    if (window.testRunner)
        testRunner.resetPageVisibility();
    finishJSTest();
}

function onMainPageVisibilityChange() {
    if (mainPageVisibilityChangeDone && frame2VisiblityChangeDone) {
        finishTest();
    } else if (!mainPageVisibilityChangeDone) {
        debug("Visibility of main document changed.");
        // Delete frame 4.
        document.body.removeChild(frame4);

        // Delete subframe 2.
        frame3.contentDocument.body.removeChild(subFrame2);

        // Add a new frame to top level.
        frame5 = document.createElement("iframe");
        frame5.src = '';
        document.body.appendChild(frame5);

        // Add a new frame to frame2.
        subFrame3 = frame2.contentDocument.createElement("iframe");
        subFrame3.src = '';
        frame2.contentDocument.body.appendChild(subFrame3);

        mainPageVisibilityChangeDone = true;
    }

    if (mainPageVisibilityChangeDone && frame2VisiblityChangeDone) {
        finishTest();
    }
}

function onFrame2VisibilityChange() {
    if (mainPageVisibilityChangeDone && frame2VisiblityChangeDone) {
        finishTest();
    } else if (!frame2VisiblityChangeDone) {
        debug("Visibility of sub frame 2 changed.");

        // Delete frame 1.
        document.body.removeChild(frame1);

        frame2VisiblityChangeDone = true;
    }

    if (mainPageVisibilityChangeDone && frame2VisiblityChangeDone) {
        finishTest();
    }
}

</script>

<script src="../../resources/js-test-post.js"></script>

<iframe id="topFrame1" onload="startTest()" ></iframe>
<iframe id="topFrame2" onload="startTest()" ></iframe>
<iframe id="topFrame3" onload="startTest()" src="resources/page-visibility-iframe-delete-test-frame.html"></iframe>
<iframe id="topFrame4" onload="startTest()" ></iframe>
</body>
</html>
