<html>
<head>
<script src="../resources/js-test-pre.js"></script>
<script src="../resources/accessibility-helper.js"></script>
</head>
<body>

<p>Before</p>

<iframe id="iframe" title="InnerFrame"></iframe>

<p>After</p>

<p>End of test</p>

<p id="description"></p>
<div id="console"></div>

<script>
    description("This tests that when an iframe finishes loading, it sends a notification.");

    if (window.testRunner)
        testRunner.waitUntilDone();

    window.jsTestIsAsync = true;

    // Recursively search the entire accessibility tree starting at the given
    // AccessibilityUIElement (inclusive) and return the element whose title
    // contains the given string. This makes it possible to find a node even
    // when there are platform differences in the tree, i.e. due to different
    // nodes being ignored.
    function findByAccessibleTitleSubstring(startElement, titleSubstring)
    {
        if (startElement.title.indexOf(titleSubstring) >= 0)
            return startElement;

        for (var i = 0; i < startElement.childrenCount; i++) {
            var found = findByAccessibleTitleSubstring(startElement.childAtIndex(i), titleSubstring);
            if (found)
                return found;
        }

        return null;
    }

    function runTest()
    {
        window.gotIframeNotification = false;

        if (window.accessibilityController) {
            window.root = accessibilityController.rootElement;

            // Initially, the iframe should not be loaded, so we shouldn't be able to find this button.
            shouldBeFalse("findByAccessibleTitleSubstring(root, 'InnerButton') != null");

            window.accessibilityController.addNotificationListener(function (target, notification) {
                // Ignore this notification if it's not on the iframe or not about the iframe being loaded.

                var targetString = platformValueForW3CName(target);
                if (targetString.indexOf("InnerFrame") == -1
                    || (notification != "AXLoadComplete" && notification != "AXLayoutComplete"))
                    return;

                debug("Got notification on iframe.");
                gotIframeNotification = true;

                // Check that the button within the iframe is now reachable from the root.
                shouldBeTrue("findByAccessibleTitleSubstring(root, 'InnerButton') != null");
            });
        }

        window.iframeElement = document.getElementById("iframe");
        iframeElement.addEventListener("load", function() {
            window.setTimeout(function() {
                shouldBeTrue("gotIframeNotification");
                if (window.accessibilityController)
                    accessibilityController.removeNotificationListener();

                finishJSTest();
            }, 10);
        }, false);

        // Load content into the iframe. This will trigger the event
        // handler above, which will check that the accessibility tree
        // was updated with new content.
        window.iframeElement.src = "data:text/html,<body><button>InnerButton</button></body>";
    }

    window.addEventListener('load', function() {
        setTimeout(runTest, 10);
    }, false);

</script>

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