author Michael Layzell <>
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

  <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>

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

<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>

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

  let dragOverFired = false;
  function onDragOver(event) {
    dragOverFired = true;
    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[";1"].
    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);

    ok(dropFired, "drop should have been fired");
    ok(dragOverFired, "dragover should have been fired");
    ok(!ds.getCurrentSession(), "The drag session should have ended");