<html>
<head>
<script src="../../resources/js-test.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>
