tor-browser

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

FormControlRange-interactive-basic.html (3820B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <script src="/resources/testharness.js"></script>
      4 <script src="/resources/testharnessreport.js"></script>
      5 <script src="/resources/testdriver.js"></script>
      6 <script src="/resources/testdriver-vendor.js"></script>
      7 <script src="/resources/testdriver-actions.js"></script>
      8 <body></body>
      9 <script>
     10 'use strict';
     11 
     12 const BACKSPACE = '\uE003';
     13 const DELETE = '\uE017';
     14 const controls = ['input', 'textarea'];
     15 
     16 function setup(control, value) {
     17  document.body.innerHTML = control === 'input' ? '<input type="text">' : '<textarea></textarea>';
     18  const element = document.body.firstElementChild;
     19  element.value = value;
     20  element.focus();
     21  return element;
     22 }
     23 
     24 async function typeKeys(element, text) { await test_driver.send_keys(element, text); }
     25 
     26 function makeRange(element, start, end) {
     27  const range = new FormControlRange();
     28  range.setFormControlRange(element, start, end);
     29  return range;
     30 }
     31 
     32 controls.forEach(control => {
     33  [
     34    {
     35      name: 'at start boundary keeps start; end extends (multi-char)',
     36      init: { value:'ABCDE', s:1, e:3, caret:1, ins:'pq' },
     37      exp:  { s:1, e:5, text:'pqBC' }
     38    },
     39    {
     40      name: 'inside range extends end by length',
     41      init: { value:'ABCDE', s:1, e:4, caret:2, ins:'pq' },
     42      exp:  { s:1, e:6, text:'BpqCD' }
     43    },
     44    {
     45      name: 'at end boundary leaves offsets unchanged (multi-char)',
     46      init: { value:'ABCDE', s:1, e:3, caret:3, ins:'pq' },
     47      exp:  { s:1, e:3, text:'BC' }
     48    },
     49  ].forEach(({ name, init, exp }) => {
     50    promise_test(async t => {
     51      const element = setup(control, init.value);
     52      const range = makeRange(element, init.s, init.e);
     53      element.setSelectionRange(init.caret, init.caret);
     54      await typeKeys(element, init.ins);
     55      assert_equals(range.startOffset, exp.s, 'startOffset');
     56      assert_equals(range.endOffset, exp.e, 'endOffset');
     57      assert_equals(range.toString(), exp.text, 'range text');
     58    }, `Insertion: ${name} (${control}).`);
     59  });
     60 
     61  [
     62    { name: 'single char inside range',
     63      init:{ value:'ABCDE', s:1, e:4, a:2, b:3, text:'q' },
     64      exp:{ s:1, e:4, text:'BqD' }
     65    },
     66  ].forEach(({ name, init, exp }) => {
     67    promise_test(async t => {
     68      const element = setup(control, init.value);
     69      const range = makeRange(element, init.s, init.e);
     70      element.setSelectionRange(init.a, init.b);
     71      await typeKeys(element, init.text);
     72      assert_equals(range.startOffset, exp.s);
     73      assert_equals(range.endOffset, exp.e);
     74      assert_equals(range.toString(), exp.text);
     75    }, `Equal-length replacement: ${name} (${control}).`);
     76  });
     77 
     78  [
     79    { name:'backspace before range shifts both left',
     80      init:{ value:'ABCDE', s:2, e:5, caret:2, key:BACKSPACE },
     81      exp:{ value:'ACDE', s:1, e:4, text:'CDE' } },
     82    { name:'forward delete inside range contracts end by 1',
     83      init:{ value:'ABCDE', s:1, e:4, caret:2, key:DELETE },
     84      exp:{ value:'ABDE', s:1, e:3, text:'BD' } },
     85    { name:'forward delete at end boundary no effect on range',
     86      init:{ value:'ABCDE', s:1, e:3, caret:3, key:DELETE },
     87      exp:{ value:'ABCE', s:1, e:3, text:'BC' } },
     88    { name:'backspace at control start is no-op',
     89      init:{ value:'ABCDE', s:0, e:2, caret:0, key:BACKSPACE },
     90      exp:{ value:'ABCDE', s:0, e:2, text:'AB' } },
     91  ].forEach(({ name, init, exp }) => {
     92    promise_test(async t => {
     93      const element = setup(control, init.value);
     94      const range = makeRange(element, init.s, init.e);
     95      element.setSelectionRange(init.caret, init.caret);
     96      await typeKeys(element, init.key);
     97      assert_equals(element.value, exp.value);
     98      assert_equals(range.startOffset, exp.s);
     99      assert_equals(range.endOffset, exp.e);
    100      assert_equals(range.toString(), exp.text);
    101    }, `Deletion: ${name} (${control}).`);
    102  });
    103 });
    104 </script>