<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<style>
#dropTarget, #dragMe { text-align: center; display: table-cell; vertical-align: middle }
#dropTarget {width: 256px; height: 256px; border: 1px dashed}
#dragMe {-webkit-user-drag: element; -webkit-user-select: none; background: #ff0000; width: 64px; height: 64px; color: white}
#console { height: 250px; overflow:scroll }
</style>
<script>
    var dragMe;
    var dropTarget;
    var consoleElm;
    var event;
    
    var ALLOWED_EFFECTS = 'none';
    var DROP_EFFECT = 'copy';
    
    var lastDragOrDragOverEventFired = null;
    var didDragEnterTarget = false;
    
    var DRAG_EVENT = "drag";
    var DRAGOVER_EVENT = "dragover";
    
    window.onload = function()
    {
        dragMe = document.getElementById("dragMe");
        dropTarget = document.getElementById("dropTarget");
        consoleElm = document.getElementById("console");
        
        if (!dragMe || !dropTarget || !consoleElm)
            return;
        
        dragMe.ondragstart = dragStart;
        dragMe.ondragend = dragEnd;
        dragMe.ondrag = dragOverWithRespectToSource;
        
        dropTarget.ondragenter = dragEntered;
        dropTarget.ondragleave = dragLeft;
        dropTarget.ondragover = dragOver;
        dropTarget.ondrop = drop;
        
        runTest();
    }
    
    function dragStart(e)
    {
        event = e;
        e.dataTransfer.effectAllowed = ALLOWED_EFFECTS;
        e.dataTransfer.setData('Text', e.target.textContent);
    }
    
    function dragEnd(e)
    {
        return;
    }
    
    function dragEntered(e)
    {
        didDragEnterTarget = true;
        dragEnteredAndUpdated(e);
    }
    
    function dragLeft(e)
    {
        didDragEnterTarget = false;
        cancelDrag(e);
    }
    
    function dragOverWithRespectToSource(e)
    {
        checkDragState(e);
        lastDragOrDragOverEventFired = DRAG_EVENT;
        cancelDrag(e);
    }
    
    function dragOver(e)
    {
        checkDragState(e);
        lastDragOrDragOverEventFired = DRAGOVER_EVENT;
        dragEnteredAndUpdated(e);
    }
    
    function dragEnteredAndUpdated(e)
    {
        event = e;
        e.dataTransfer.dropEffect = DROP_EFFECT;
        cancelDrag(e);
    }
    
    function drop(e)
    {
        cancelDrag(e);
    }
    
    function cancelDrag(e)
    {
        if (e.preventDefault)
            e.preventDefault();
        else {
            // Assume this script is executing within Internet Explorer
            e.returnValue = false;
        }
    }
    
    function checkDragState(e)
    {
        event = e;
        if (didDragEnterTarget && e.type == "drag" && lastDragOrDragOverEventFired == DRAG_EVENT)
            testFailed('dragover should have fired after drag. Instead, drag fired again.');
        else if (e.type == "dragover") {
            if (lastDragOrDragOverEventFired == DRAG_EVENT)
                testPassed('drag fired before dragover.');
            else
                testFailed('drag should have fired before dragover. Instead, dragover fired first.');
        }
    }

    function runTest()
    {
        if (!window.eventSender)
            return;
            
        if (window.testRunner)
            testRunner.dumpAsText();
            
        var startX = dragMe.offsetLeft + 10;
        var startY = dragMe.offsetTop + dragMe.offsetHeight / 2;
        var endX = dropTarget.offsetLeft + 10;
        var endY = dropTarget.offsetTop + dropTarget.offsetHeight / 2;
        
        eventSender.mouseMoveTo(startX, startY);
        eventSender.mouseDown();
        eventSender.leapForward(100);
        eventSender.mouseMoveTo(endX, endY);
        eventSender.mouseUp();
        
        var testContainer = document.getElementById("test-container");
        if (testContainer)
            document.body.removeChild(testContainer);
        debug('<br /><span class="pass">TEST COMPLETE</span>');
    }
</script>
</head>
<body>
    <p id="description"></p>
    <div id="test-container">
        <label for="effectAllowed">effectAllowed:</label> <code><script>document.write(ALLOWED_EFFECTS)</script></code>
        <br/><br/>
        <div id="dropTarget">Drop the red square onto me.</div>
        <hr/>
        <p>Items that can be dragged to the drop target:</p>
        <div id="dragMe" draggable="true">Square</div>
        <hr/>
    </div>
    <div id="console"></div>
    <script>
        description("This test checks that the event handlers ondrag and ondragover fire in that order, " + 
        "as per http://www.whatwg.org/specs/web-apps/current-work/#current-drag-operation.");
    </script>
</body>
</html>
