<html>
<head>
<script>
    if (window.testRunner) {
        testRunner.dumpAsText();
        testRunner.waitUntilDone();
    }

    var container1;
    var container2;
    var elem;

    function handler2()
    {
        container2.appendChild(elem);
    }

    function onload()
    {
        container1 = document.getElementById("newcontainer1");
        container2 = document.getElementById("newcontainer2");

        if (!window.eventSender)
            return;

        var rect = document.getElementById("trigger").getBoundingClientRect();
        eventSender.mouseMoveTo(rect.left + rect.width / 2, rect.top + rect.height / 2);
        eventSender.mouseDown();
        eventSender.mouseUp();
    }

    function onpress()
    {
        elem = document.getElementById("subcontainer1");
        document.getElementById("sub1").focus();

        try {
            container1.appendChild(elem);
            container1.removeChild(elem);
            elem = null;
        }
        catch (e) { }

        // Force GC.
        if (this.GCController)
            GCController.collect();
        else {
            for (var i = 0; i < 10000; ++i) {
                ({ });
            }
        }

        document.body.removeChild(container2);

        if (window.testRunner)
            testRunner.notifyDone();

    }

</script>
</head>
<body onload="onload()">
<p>Tests for proper handling of DOM changes during a blur event. If the test doesn't crash, it passed.
<div id="subcontainer1">
    <textarea id="sub1" onblur="handler2()"></textarea>
</div>

<input id="trigger" type="button" name="Press" value="press" onclick="onpress()">
<div id="newcontainer1"></div>
<div id="newcontainer2"></div>

</body>
</html>
