tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_user_select.html (11529B)


      1 <!DOCTYPE>
      2 <html>
      3 <head>
      4 <title>user-select selection tests</title>
      5  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      6  <script src="/tests/SimpleTest/EventUtils.js"></script>
      7  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
      8 
      9 <style type="text/css">
     10 @font-face {
     11  font-family: Ahem;
     12  src: url("Ahem.ttf");
     13 }
     14 body { font-family: Ahem; font-size: 20px; }
     15 s, .non-selectable { user-select: none; }
     16 n { display: none; }
     17 a { position:absolute; bottom: 0; right:0; }
     18 .text { user-select: text; }
     19 </style>
     20 
     21 </head>
     22 <body>
     23 
     24 <div id="test1">aaaaaaa<s>bbbbbbbb</s>ccccccc</div>
     25 <div id="test2"><s>aaaaaaa</s>bbbbbbbbccccccc</div>
     26 <div id="test3">aaaaaaabbbbbbbb<s>ccccccc</s></div>
     27 <div id="test4">aaaaaaa<x><s>bbbbbbbb</s></x>ccccccc</div>
     28 <div id="test5"><x><s>aaaaaaa</s></x>bbbbbbbbccccccc</div>
     29 <div id="test6">aaaaaaabbbbbbbb<x><s>ccccccc</s></x></div>
     30 <div id="test7">aaaaaaa<x><s><n>bbbb</n>bbbb</s></x>ccccccc</div>
     31 <div id="test8"><x><s>aa<n>aaa</n>aa</s></x>bbbbbbbbccccccc</div>
     32 <div id="test9">aaaaaaabbbbbbbb<x><s>cc<n>ccccc</n></s></x></div>
     33 <div id="testA">aaaaaaa<n>bbb<s>bbbbb</s></n>ccccccc</div>
     34 <div id="testB"><n><s>aaaa</s>aaa</n>bbbbbbbbccccccc</div>
     35 <div id="testC">aaaaaaabbbbbbbb<n>cc<s>c</s>cccc</n></div>
     36 <div id="testE">aaa<s id="testEc1">aaaa<a class="text">bbbb</a>dd<a>cccc</a>ddddddd</s>eeee</div>
     37 <div id="testI">aaa<span contenteditable="true" spellcheck="false">bbb</span><s>ccc</s>ddd</div>
     38 <div id="testF">aaaa
     39 <div class="non-selectable">x</div>
     40 <div class="non-selectable">x</div>
     41 <div class="non-selectable">x</div>
     42 bbbb</div>
     43 <div id="testG" style="white-space:pre">aaaa
     44 <div class="non-selectable">x</div>
     45 <div class="non-selectable">x</div>
     46 <div class="non-selectable">x</div>
     47 bbbb</div>
     48 <div id="testH" style="white-space:pre">aaaa
     49 <div class="non-selectable">x</div><input>
     50 bbbbbbb</div>
     51 
     52 <iframe id="testD" srcdoc="<body>aaaa<span style='user-select:none'>bbbb</span>cccc"></iframe>
     53 
     54 <pre id="test">
     55 <script class="testbody" type="text/javascript">
     56 
     57 function test()
     58 {
     59  const excludeNonSelectableNodes = SpecialPowers.getBoolPref("dom.selection.exclude_non_selectable_nodes");
     60 
     61  function clear(w)
     62  {
     63    var sel = (w ? w : window).getSelection();
     64    sel.removeAllRanges();
     65  }
     66  function doneTest(e)
     67  {
     68    // We hide the elements we're done with so that later tests
     69    // are inside the rather narrow iframe mochitest gives us.
     70    // It matters for synthesizeMouse event tests.
     71    e.style.display = 'none';
     72    e.offsetHeight;
     73  }
     74 
     75  function dragSelect(e, x1, x2, x3)
     76  {
     77    dir = x2 > x1 ? 1 : -1;
     78    synthesizeMouse(e, x1, 5, { type: "mousedown" });
     79    synthesizeMouse(e, x1 + dir, 5, { type: "mousemove" });
     80    if (x3)
     81      synthesizeMouse(e, x3, 5, { type: "mousemove" });
     82    synthesizeMouse(e, x2 - dir, 5, { type: "mousemove" });
     83    synthesizeMouse(e, x2, 5, { type: "mouseup" });
     84  }
     85 
     86  function shiftClick(e, x)
     87  {
     88    synthesizeMouse(e, x, 5, { type: "mousedown", shiftKey: true });
     89    synthesizeMouse(e, x, 5, { type: "mouseup", shiftKey: true });
     90  }
     91 
     92  function init(arr, e)
     93  {
     94    clear();
     95    var sel = window.getSelection();
     96    for (i = 0; i < arr.length; ++i) {
     97      var data = arr[i];
     98      var r = new Range()
     99      r.setStart(node(e, data[0]), data[1]);
    100      r.setEnd(node(e, data[2]), data[3]);
    101      sel.addRange(r);
    102    }
    103  }
    104 
    105  function NL(s) { return s.replace(/(\r\n|\n\r|\r)/g, '\n'); }
    106 
    107  function checkText(text, e)
    108  {
    109    var sel = window.getSelection();
    110    is(NL(sel.toString()), text, e.id + ": selected text")
    111  }
    112 
    113  function checkRangeText(text, index)
    114  {
    115    var r = window.getSelection().getRangeAt(index);
    116    is(NL(r.toString()), text, e.id + ": range["+index+"].toString()")
    117  }
    118 
    119  function node(e, arg)
    120  {
    121    if (typeof arg == "number")
    122      return arg == -1 ? e : e.childNodes[arg];
    123    return arg;
    124  }
    125 
    126  function checkRangeCount(n, e)
    127  {
    128    var sel = window.getSelection();
    129    is(sel.rangeCount, n, e.id + ": Selection range count");
    130  }
    131 
    132  function checkRange(i, expected, e) {
    133    var sel = window.getSelection();
    134    var r = sel.getRangeAt(i);
    135    is(r.startContainer, node(e, expected[0]), e.id + ": range["+i+"].startContainer");
    136    is(r.startOffset, expected[1], e.id + ": range["+i+"].startOffset");
    137    is(r.endContainer, node(e, expected[2]), e.id + ": range["+i+"].endContainer");
    138    is(r.endOffset, expected[3], e.id + ": range["+i+"].endOffset");
    139  }
    140 
    141  function checkRanges(arr, e)
    142  {
    143    checkRangeCount(arr.length, e);
    144    for (i = 0; i < arr.length; ++i) {
    145      var expected = arr[i];
    146      checkRange(i, expected, e);
    147    }
    148  }
    149 
    150  // ======================================================
    151  // ================== dragSelect tests ==================
    152  // ======================================================
    153 
    154  var e = document.getElementById('test1');
    155  dragSelect(e, 20, 340);
    156  checkText('aaaaaacc', e);
    157  checkRanges(
    158    excludeNonSelectableNodes ? [[0,1,-1,1], [2,0,2,2]] : [[0,1,2,2]],
    159    e
    160  );
    161 
    162  clear();
    163  dragSelect(e, 20, 260, 120);
    164  checkText('aaaaa', e);
    165  checkRanges([[0,1,0,6]], e);
    166  doneTest(e);
    167 
    168  clear();
    169  e = document.getElementById('test2');
    170  dragSelect(e, 20, 340);
    171  checkText('', e);
    172  checkRanges([], e);
    173 
    174  clear();
    175  dragSelect(e, 340, 20, 141);
    176  checkText('bbbbbbbbcc', e);
    177  checkRanges([[1,0,1,10]], e);
    178  // #test2 is used again below
    179 
    180  clear();
    181  e = document.getElementById('test3');
    182  dragSelect(e, 20, 340, 295);
    183  checkText('aaaaaabbbbbbbb', e);
    184  checkRanges([[0,1,0,15]], e);
    185  // #test3 is used again below
    186 
    187  clear();
    188  e = document.getElementById('test4');
    189  dragSelect(e, 20, 340);
    190  checkText('aaaaaacc', e);
    191  checkRanges(
    192    excludeNonSelectableNodes ? [[0,1,1,0], [2,0,2,2]] : [[0,1,2,2]],
    193    e
    194  );
    195  doneTest(e);
    196 
    197  clear();
    198  e = document.getElementById('test5');
    199  dragSelect(e, 340, 20, 141);
    200  checkText('bbbbbbbbcc', e);
    201  checkRanges([[1,0,1,10]], e);
    202  doneTest(e);
    203 
    204  clear();
    205  e = document.getElementById('test6');
    206  dragSelect(e, 20, 340, 295);
    207  checkText('aaaaaabbbbbbbb', e);
    208  checkRanges([[0,1,0,15]], e);
    209  doneTest(e);
    210 
    211  clear();
    212  e = document.getElementById('test7');
    213  dragSelect(e, 20, 340);
    214  checkText('aaaaaacccccc', e);
    215  checkRanges(
    216    excludeNonSelectableNodes ? [[0,1,1,0], [2,0,2,6]] : [[0,1,2,6]],
    217    e
    218  );
    219  doneTest(e);
    220 
    221  clear();
    222  e = document.getElementById('test8');
    223  dragSelect(e, 340, 20, 140);
    224  checkText('bbbbbccccc', e);
    225  checkRanges([[1,3,1,13]], e);
    226  doneTest(e);
    227 
    228  clear();
    229  e = document.getElementById('test9');
    230  dragSelect(e, 20, 340, 295);
    231  checkText('aaaaaabbbbbbbb', e);
    232  checkRanges([[0,1,0,15]], e);
    233  doneTest(e);
    234 
    235  clear();
    236  e = document.getElementById('testA');
    237  dragSelect(e, 20, 340);
    238  checkText('aaaaaaccccccc', e);
    239  checkRanges([[0,1,2,7]], e);
    240  checkRangeText('aaaaaabbbbbbbbccccccc', 0);
    241  doneTest(e);
    242 
    243  clear();
    244  e = document.getElementById('testB');
    245  dragSelect(e, 340, 20, 140);
    246  checkText('bbbbbbbccccccc', e);
    247  checkRanges([[1,1,1,15]], e);
    248  doneTest(e);
    249 
    250  clear();
    251  e = document.getElementById('testE');
    252  dragSelect(e, 20, 360, 295);
    253  checkText('aa\nbbbb\nee', e);
    254  if (excludeNonSelectableNodes) {
    255    checkRangeCount(3, e);
    256    checkRange(0, [0,1,-1,1], e);
    257    checkRange(1, [1,0,-1,2], e.children[0]);
    258    checkRange(2, [2,0,2,2], e);
    259  } else {
    260    checkRangeCount(1, e);
    261    checkRanges([[0,1,2,2]], e);
    262  }
    263  doneTest(e);
    264 
    265  clear();
    266  e = document.getElementById('testI');
    267  dragSelect(e, 200, 80);
    268  checkText('bbd', e);
    269  checkRangeCount(excludeNonSelectableNodes ? 2 : 1, e);
    270  doneTest(e);
    271 
    272  // ======================================================
    273  // ================== shift+click tests =================
    274  // ======================================================
    275 
    276  // test extending a selection that starts in a -moz-user-select:none node
    277  clear();
    278  e = document.getElementById('test2');
    279  init([[0,0,0,1]], e);
    280  checkRangeText('aaaaaaa', 0);
    281  checkText('', e);
    282  shiftClick(e, 340);
    283  checkText('bbbbbbbbcc', e);
    284  if (excludeNonSelectableNodes) {
    285    checkRangeText('bbbbbbbbcc', 0);
    286    checkRanges([[-1,1,1,10]], e);
    287  } else {
    288    checkRangeText('aaaaaaabbbbbbbbcc', 0);
    289    checkRanges([[0,0,1,10]], e);
    290  }
    291  doneTest(e);
    292 
    293  // test extending a selection that end in a -moz-user-select:none node
    294  clear();
    295  e = document.getElementById('test3');
    296  init([[1,0,1,1]], e);
    297  checkRangeText('ccccccc', 0);
    298  checkText('', e);
    299  shiftClick(e, 20);
    300  checkRangeText('aaaaaabbbbbbbb', 0);
    301  checkText('aaaaaabbbbbbbb', e);
    302  checkRanges(
    303    excludeNonSelectableNodes ? [[0,1,-1,1]] : [[0,1,1,0]],
    304    e
    305  );
    306  doneTest(e);
    307 
    308  clear();
    309  e = document.getElementById('testF');
    310  synthesizeMouse(e, 1, 1, {});
    311  synthesizeMouse(e, 400, 100, { shiftKey: true });
    312  checkText("aaaa bbbb", e);
    313  checkRanges(
    314    excludeNonSelectableNodes ? [[0,0,-1,1],[6,0,6,5]] : [[0,0,6,5]],
    315    e
    316  );
    317  doneTest(e);
    318 
    319  clear();
    320  e = document.getElementById('testG');
    321  synthesizeMouse(e, 1, 1, {});
    322  synthesizeMouse(e, 400, 180, { shiftKey: true });
    323  checkText("aaaa\n\n\n\nbbbb", e);
    324  checkRanges(
    325    excludeNonSelectableNodes ? [[0,0,-1,1],[2,0,-1,3],[4,0,-1,5],[6,0,6,5]] : [[0,0,6,5]],
    326    e
    327  );
    328  doneTest(e);
    329 
    330  clear();
    331  e = document.getElementById('testH');
    332  synthesizeMouse(e, 1, 1, {});
    333  synthesizeMouse(e, 30, 90, { shiftKey: true });
    334  synthesizeMouse(e, 50, 90, { shiftKey: true });
    335  synthesizeMouse(e, 70, 90, { shiftKey: true });
    336  checkText("aaaa\n\nbbb", e);
    337  checkRanges(
    338    excludeNonSelectableNodes ? [[0,0,-1,1],[-1,2,3,4]] : [[0,0,3,4]],
    339    e
    340  );
    341 
    342  doneTest(e);
    343  // ======================================================
    344  // ==================== Script tests ====================
    345  // ======================================================
    346 
    347  clear();
    348  e = document.getElementById('testD');
    349  clear(e.contentWindow);
    350  sel = e.contentWindow.getSelection();
    351  sel.selectAllChildren(e.contentDocument.body);
    352  is(window.getSelection().rangeCount, 0, "testD: no selection in outer window");
    353  is(sel.toString(), 'aaaacccc', "testD: scripted selection");
    354  is(sel.rangeCount, 1, "testD: scripted selection isn't filtered");
    355  is(sel.getRangeAt(0).toString(), 'aaaabbbbcccc', "testD: scripted selection isn't filtered");
    356 
    357  // ======================================================
    358  // ================== Kbd command tests =================
    359  // ======================================================
    360 
    361  clear();
    362  e = document.getElementById('testD');
    363  clear(e.contentWindow);
    364  e.contentWindow.focus();
    365  synthesizeKey("a", { accelKey:true }, e.contentWindow);
    366  sel = e.contentWindow.getSelection();
    367  is(window.getSelection().rangeCount, 0, "testD: no selection in outer window");
    368  is(sel.toString(), 'aaaacccc', "testD: kbd selection");
    369  if (excludeNonSelectableNodes) {
    370    is(sel.rangeCount, 2, "testD: kbd selection is filtered");
    371    is(sel.getRangeAt(0).toString(), 'aaaa', "testD: kbd selection is filtered");
    372    is(sel.getRangeAt(1).toString(), 'cccc', "testD: kbd selection is filtered");
    373  } else {
    374    is(sel.rangeCount, 1, "testD: kbd selection is filtered");
    375    is(sel.getRangeAt(0).toString(), 'aaaabbbbcccc', "testD: kbd selection is filtered");
    376  }
    377  doneTest(e);
    378 
    379  clear();
    380  SimpleTest.finish();
    381 }
    382 
    383 // These tests depends on the Ahem font being loaded and rendered so wait for
    384 // font to load, then wait a frame for them to be rendered too.
    385 window.onload = function() {
    386  document.fonts.ready.then(function() {
    387    requestAnimationFrame(test);
    388  });
    389 };
    390 
    391 SimpleTest.waitForExplicitFinish();
    392 </script>
    393 </pre>
    394 </body>
    395 </html>