dom/events/test/test_drag_empty.html
author Michael Layzell <michael@thelayzells.com>
Fri, 21 Apr 2017 16:38:12 -0400
changeset 577242 314678959de293fef3e7b4c7cfd9df0cd574f420
parent 569741 492fab8fac4e3a7773720d68898219aaff18e101
permissions -rw-r--r--
Bug 1352852 - Add dummy data to the DataTransfer when dragging a draggable object, r=enndeakin When dragging a `draggable=true` HTML DOM node, if no data is added to the DataTransfer during the DragStart event, we currently cancel the drag. This is inconsistent with Chrome's behaviour. This patch adds a chrome-only (hidden from content) item to the DataTransfer: application/x-moz-dummy-data. This data is added only when no other data has been added to the DataTransfer, and the target of the dragstart event was a draggable=true HTML DOM node. This hidden node allows for the drag event to complete successfully, while appearing the same as Chrome's behavior to content scripts. MozReview-Commit-ID: HVqEr7aR6DD

<html>
<head>
  <title>Tests for the dragstart event</title>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
</head>

<body>
<!--
 This test checks the behaviour of the dragstart event when no data is added to the DataTransfer.
  -->
  <style>
    #droptarget { width: 100px; height: 100px; background-color: #550000; }
  </style>

<div id="draggable" draggable="true" ondragstart="onDragStart(event)">This is a bit of text.</div>

<div id="droptarget" ondragover="onDragOver(event)" ondrop="onDrop(event)">THIS IS A DROP TARGET?!?!?</div>

<script>
  let dragStartFired = false;
  function onDragStart(event) {
    dragStartFired = true;
    info("dragstart fired");
  }

  let dragOverFired = false;
  function onDragOver(event) {
    dragOverFired = true;
    event.preventDefault();
    info("dragover fired");
  }

  let dropFired = false;
  function onDrop(event) {
    dropFired = true;
    is(event.dataTransfer.types.length, 0,
       "There shouldn't be any data on the DataTransfer");
    info("drop fired");
  }

  let loaded = new Promise(resolve => document.body.onload = resolve);

  add_task(function*() {
    var ds = SpecialPowers.Cc["@mozilla.org/widget/dragservice;1"].
             getService(SpecialPowers.Ci.nsIDragService);
    ok(!ds.getCurrentSession(), "There should be no drag session in progress");

    // XXX: Make sure that we've finished loading the document before we start
    // trying to do work with drag events.
    yield loaded;

    var draggable = $("draggable");
    var droptarget = $("droptarget");
    // Fire the dragstart event - this should start a drag session
    synthesizeMouse(draggable, 6, 6, { type: "mousedown" });
    synthesizeMouse(draggable, 14, 14, { type: "mousemove" });
    // drags are asynchronous on Linux, so this extra event is needed to make
    // sure the drag gets processed
    synthesizeMouse(draggable, 15, 15, { type: "mousemove" });

    ok(dragStartFired, "dragstart should have fired");
    ok(ds.getCurrentSession(), "The drag session should have started");

    // Synthesize the dragover and drop events on the target node.
    var [result, dataTransfer] = synthesizeDragOver(draggable, droptarget);
    synthesizeDropAfterDragOver(result, dataTransfer, droptarget);
    ds.endDragSession(true);

    ok(dropFired, "drop should have been fired");
    ok(dragOverFired, "dragover should have been fired");
    ok(!ds.getCurrentSession(), "The drag session should have ended");
  });
</script>
</body>
</html>