chromium/third_party/blink/web_tests/editing/selection/mouse/drags_within_user-select_combos.html

<!doctype html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<title>Test for crbug.com/771573: Make links draggable despite 'user-select' styling</title>

<em>This test assumes 'user-select' never affects draggability (this is not spec'ed clearly, but it's the behavior we're used to).</em>

<p>Normal <a href="www" id="link">links</a> are draggable (might change if the CSS spec starts to say that <i>user-select: text</i> forces selectability).</p>

<p><input type="submit" id="button"> buttons are not draggable.</p>

<p>But <img src="../../resources/abe.png" id="image"> images are.</p>

<p><span draggable="true" id="draggable_span" style="background: lime">dragme</span>-spans are also.</p>

<p><a href="www" id="editable_link" contenteditable="true">Editable links</a> are not draggable.</p>

<div draggable="true">
  <p><a href="www" id="editable_link2" contenteditable="true">Editable links</a> are editable even when parent is draggable.</p>
</div>

<script>
function compareResults(id, expectedResult, actualResult) {
  assert_equals(actualResult.length, expectedResult.length, 'results length for ' + id);
  for (let i = 0; i < expectedResult.length; i++) {
    assert_equals(actualResult[i], expectedResult[i], id);
  }
}

function registerEventListenersWithResults(resultArray) {
  document.ondragstart = function() {
    resultArray.push('dragstart');
  }

  document.onmousedown = function(event) {
    resultArray.push('mousedown');
  }
}

function dragFromTopOfElement(element) {
  getSelection().removeAllRanges();
  let startX = Math.round(element.offsetLeft + element.offsetWidth / 2);
  let startY = Math.round(element.offsetTop + 1.0);

  eventSender.mouseMoveTo(startX, startY);
  eventSender.mouseDown();
  eventSender.mouseMoveTo(startX, startY + element.offsetHeight / 2);
  eventSender.mouseUp();
}

let onload = new Promise(resolve => {
  window.addEventListener('load', resolve);
});

function runDragTests(styling) {
  promise_test(async () => {
    await onload;
    document.body.style.userSelect = styling;
    let draggableResults = [];
    registerEventListenersWithResults(draggableResults);
    dragFromTopOfElement(document.getElementById('link'));
    compareResults('link', ['mousedown', 'dragstart'], draggableResults);
  }, `link (style: ${styling})`);

  promise_test(async () => {
    await onload;
    document.body.style.userSelect = styling;
    let draggableResults = [];
    registerEventListenersWithResults(draggableResults);
    dragFromTopOfElement(document.getElementById('button'));
    compareResults('button', ['mousedown'], draggableResults);
  }, `button (style: ${styling})`);

  promise_test(async () => {
    await onload;
    document.body.style.userSelect = styling;
    let draggableResults = [];
    registerEventListenersWithResults(draggableResults);
    dragFromTopOfElement(document.getElementById('image'));
    compareResults('image', ['mousedown', 'dragstart'], draggableResults);
  }, `image (style: ${styling})`);

  promise_test(async () => {
    await onload;
    document.body.style.userSelect = styling;
    let draggableResults = [];
    registerEventListenersWithResults(draggableResults);
    dragFromTopOfElement(document.getElementById('draggable_span'));
    compareResults('draggable_span', ['mousedown', 'dragstart'], draggableResults);
  }, `draggable_span (style: ${styling})`);

  promise_test(async () => {
    await onload;
    document.body.style.userSelect = styling;
    let draggableResults = [];
    registerEventListenersWithResults(draggableResults);
    dragFromTopOfElement(document.getElementById('editable_link'));
    compareResults('editable_link', ['mousedown'], draggableResults);
  }, `editable_link (style: ${styling})`);

  promise_test(async () => {
    await onload;
    document.body.style.userSelect = styling;
    let draggableResults = [];
    registerEventListenersWithResults(draggableResults);
    dragFromTopOfElement(document.getElementById('editable_link2'));
    compareResults('editable_link2', ['mousedown'], draggableResults);
  }, `editable_link2 (style: ${styling})`);
}

runDragTests("auto");
runDragTests("none");
runDragTests("all");
runDragTests("text");
</script>