<!-- webkit-test-runner [ enablePageCache=true ] -->
<!DOCTYPE html>
<html>
<head>
<script>
if (window.testRunner) {
    testRunner.dumpAsText();
    testRunner.setCanOpenWindows();
    testRunner.setPopupBlockingEnabled(false);
    testRunner.setCloseRemainingWindowsWhenComplete(true);
    testRunner.waitUntilDone();
}
</script>
</head>
<body>
<p>This page opens an about:blank window and navigates it to a victim page such that the about:blank page
is put into the page cache. Once the victim page is loaded it tries to navigate to a <code>javascript</code>
URL. Ensure that popup-blocking is disabled when running this test by hand. This test PASSED if no JavaScript
alert dialogs are shown. Otherwise, it FAILED.</p>
<script>
function testClickAnchorElement(aDocument)
{
    var link = aDocument.createElement("a");
    link.href = "javascript:alert('FAIL clicked HTML anchor element.')";
    link.click();
}

function testClickLinkElement(aDocument)
{
    var link = aDocument.createElement("link");
    link.href = "javascript:alert('FAIL clicked HTML link element.')";
    link.click();
}

function testSubmitForm(aDocument)
{
    var form = aDocument.createElement("form");
    form.action = "javascript:alert('FAIL submitted form.')";
    form.submit();
}

function createClickEvent(aDocument)
{
    var mouseEventInitDict = {
        bubbles: true,
        cancelable: false,
        view: aDocument.defaultView,
        detail: 1,
        screenX: 10,
        screenY: 10,
        clientX: 10,
        clientY: 10,
        ctrlKey: false,
        shiftKey: false,
        altKey: false,
        metaKey: false,
        button: 1,
        relatedTarget: null
    };
    return new MouseEvent("click", mouseEventInitDict)
}

function testClickSVGAnchorElement(aDocument)
{
    var link = aDocument.createElementNS("http://www.w3.org/2000/svg", "svg:a");
    link.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "javascript:alert('FAIL clicked SVG anchor element.')");
    link.dispatchEvent(createClickEvent(aDocument));
}

function testClickMathElement(aDocument)
{
    var link = aDocument.createElementNS("http://www.w3.org/1998/Math/MathML", "math");
    link.setAttribute("href", "javascript:alert('FAIL clicked Math element.')");
    link.dispatchEvent(createClickEvent(aDocument));
}

function runTests()
{
    var childWindow = window.open("about:blank", "one");
    var childDocument = childWindow.document;

    var link = childDocument.createElement("a");
    link.href = "http://localhost:8000/security/resources/innocent-victim.html";
    link.click(); // Navigate window; moves about:blank into the page cache.

    function checkDidNavigate()
    {
        try {
            childWindow.location.href.toString;
        } catch (e) {
            // Victim page did load.
            clearInterval(intervalID);

            testClickAnchorElement(childDocument);
            testClickLinkElement(childDocument);
            testClickSVGAnchorElement(childDocument);
            testClickMathElement(childDocument);
            testSubmitForm(childDocument);

            if (window.testRunner)
                testRunner.notifyDone();
        }
    }
    var intervalID = window.setInterval(checkDidNavigate, 0);
}
runTests();
</script>
</body>
</html>
