<head>
<script>
function log(message) {
    console_doc = frames[2].document;
    var item = console_doc.createElement("li");
    item.appendChild(console_doc.createTextNode(message));
    console_doc.getElementById('console_messages').appendChild(item);
}

function test() {
    if (window.layoutTestController) {
        layoutTestController.dumpAsText();
        layoutTestController.waitUntilDone();

        // Find the element to drag
        elementToDrag = frames[0].document.getElementById("elementToDrag");
        x1 = elementToDrag.offsetLeft + elementToDrag.offsetWidth / 2;
        y1 = elementToDrag.offsetTop + elementToDrag.offsetHeight / 2;

        // Drag to the middle of the destination element in the same frame
        dragTarget = frames[0].document.getElementById("dragTarget");
        x2 = dragTarget.offsetLeft + dragTarget.offsetWidth / 2;
        y2 = dragTarget.offsetTop + dragTarget.offsetHeight / 2;

        eventSender.mouseMoveTo(x1,y1);
        eventSender.mouseDown();
        eventSender.mouseMoveTo(x2, y2);
        eventSender.mouseMoveTo(x2, y2+1);
        eventSender.mouseMoveTo(x2, y2+2);

        // Drag to the middle of the destination element in another frame
        dragTarget2 = frames[1].document.getElementById("dragTarget2");
        x3 = 150 + dragTarget2.offsetLeft + dragTarget2.offsetWidth / 2;
        y3 = dragTarget2.offsetTop + dragTarget2.offsetHeight / 2;

        eventSender.mouseMoveTo(x3, y3);
        eventSender.mouseMoveTo(x3, y3+1);
        eventSender.mouseUp();

        document.write("<body>" + 
            frames[2].document.body.innerHTML + 
            "<p>These results are just \"sensible\" at the moment, meaning that " +
            "all the events fire on the right elements, nothing more. The order in particular "+
            "can rightfully change.</p>" +
            "<scr" + "ipt>layoutTestController.notifyDone();</scr" + "ipt>" + 
            "</body>");
    }
}
</script>
</head>
<!-- frames -->
<frameset  cols="150,150,*" border="0" onload="test();">

    <frame name="left" src="resources/drag-in-frames-left.html" marginwidth="10" marginheight="10" scrolling="auto" frameborder="0"
                 ondrag="alert('ondrag left frame')"
                 ondrop="alert('ondrop left frame')"
                 ondragstart="alert('ondragstart left frame')"
                 ondragend="alert('ondragend left frame')"
                 ondragenter="log('ondragenter left frame')"
                 ondragover="log('ondragover left frame')"
                 ondragleave="log('ondragleave left frame')">
    <frame name="right" src="resources/drag-in-frames-right.html" marginwidth="10" marginheight="10" scrolling="auto" frameborder="0"
                 ondrag="alert('ondrag right frame')"
                 ondrop="alert('ondrop right frame')"
                 ondragstart="alert('ondragstart right frame')"
                 ondragend="alert('ondragend right frame')"
                 ondragenter="log('ondragenter right frame')"
                 ondragover="log('ondragover right frame')"
                 ondragleave="log('ondragleave right frame')">
    <frame name="console" src="resources/drag-in-frames-console.html"  marginwidth="10" marginheight="10" scrolling="auto" frameborder="0">
</frameset>
