<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.");

    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>
