tor-browser

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

common.js (2765B)


      1 const KEY_CODE_MAP = {
      2  'ArrowLeft':  '\uE012',
      3  'ArrowUp':    '\uE013',
      4  'ArrowRight': '\uE014',
      5  'ArrowDown':  '\uE015',
      6  'PageUp':     '\uE00E',
      7  'PageDown':   '\uE00F',
      8  'End':        '\uE010',
      9  'Home':       '\uE011',
     10  'Space':      ' ',
     11 };
     12 
     13 // Send key event to the target element using test driver. Supports human
     14 // friendly key names for common keyboard scroll operations e.g., arrow keys,
     15 // page keys, etc.
     16 async function keyPress(target, key) {
     17  let code = key;
     18  if (KEY_CODE_MAP.hasOwnProperty(key))
     19    code = KEY_CODE_MAP[key];
     20 
     21  // First move pointer on target and click to ensure it receives the key.
     22  return test_driver.send_keys(target, code);
     23 }
     24 
     25 // Use rAF to wait for the value of the getter function passed to not change for
     26 // at least 15 frames or timeout after 1 second.
     27 //
     28 // Example usage:
     29 //    await waitForAnimationEnd(() => scroller.scrollTop);
     30 function waitForAnimationEnd(getValue) {
     31  const TIMEOUT = 1000; // milliseconds
     32  const MAX_UNCHANGED_FRAMES = 15;
     33 
     34  const start_time = performance.now();
     35  let last_changed_frame = 0;
     36  let last_value = getValue();
     37 
     38  return new Promise((resolve, reject) => {
     39    function tick(frames, time) {
     40    // We requestAnimationFrame either for TIMEOUT milliseconds or until
     41    // MAX_UNCHANGED_FRAMES with no change have been observed.
     42      if (time - start_time > TIMEOUT ||
     43          frames - last_changed_frame >= MAX_UNCHANGED_FRAMES) {
     44        resolve(time);
     45      } else {
     46        current_value = getValue();
     47        if (last_value != current_value) {
     48          last_changed_frame = frames;
     49          last_value = current_value;
     50        }
     51        requestAnimationFrame(tick.bind(this, frames + 1));
     52      }
     53    }
     54    tick(0, start_time);
     55  });
     56 }
     57 
     58 
     59 function waitForEvent(eventTarget, type) {
     60  return new Promise(resolve => {
     61    eventTarget.addEventListener(type, resolve, { once: true });
     62  });
     63 }
     64 
     65 function waitForScrollEvent(eventTarget) {
     66  return waitForEvent(eventTarget, 'scroll');
     67 }
     68 
     69 function waitForWheelEvent(eventTarget) {
     70  return waitForEvent(eventTarget, 'wheel');
     71 }
     72 
     73 function waitForScrollTo(eventTarget, getValue, targetValue) {
     74  return new Promise((resolve, reject) => {
     75    const scrollListener = (evt) => {
     76      if (getValue() == targetValue) {
     77        eventTarget.removeEventListener('scroll', scrollListener);
     78        resolve(evt);
     79      }
     80    };
     81    if (getValue() == targetValue)
     82      resolve();
     83    else
     84      eventTarget.addEventListener('scroll', scrollListener);
     85  });
     86 }
     87 
     88 function waitForNextFrame() {
     89  return new Promise(resolve => {
     90    const start = performance.now();
     91    requestAnimationFrame(frameTime => {
     92      if (frameTime < start) {
     93        requestAnimationFrame(resolve);
     94      } else {
     95        resolve();
     96      }
     97    });
     98  });
     99 }