tor-browser

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

support.js (3900B)


      1 // ----------------------------------------
      2 // Test Utilities
      3 // ----------------------------------------
      4 
      5 setup({explicit_timeout: true});
      6 
      7 const tests = [];
      8 window.addEventListener('DOMContentLoaded', e => {
      9  const header = document.createElement('h1');
     10  header.innerText = document.title;
     11  document.body.appendChild(header);
     12  const elem = document.createElement('div');
     13  elem.style.cssText = 'height: 50px; border: 1px dotted red;';
     14  elem.innerHTML = 'Drop or paste the <b>support/upload</b> directory here.</div>';
     15  document.body.appendChild(elem);
     16  elem.addEventListener('dragover', e => {
     17    e.preventDefault();
     18  });
     19  const onDropOrPaste = dataTransfer => {
     20    for (let i = 0; i < dataTransfer.items.length; ++i) {
     21      const item = dataTransfer.items[i];
     22      if (item.kind !== 'file')
     23        continue;
     24      const entry = item.webkitGetAsEntry();
     25      elem.parentElement.removeChild(elem);
     26      tests.forEach(f => f(entry, item));
     27      break;
     28    }
     29  };
     30  elem.addEventListener('drop', e => {
     31    e.preventDefault();
     32    onDropOrPaste(e.dataTransfer);
     33  });
     34  elem.addEventListener('paste', e => {
     35    e.preventDefault();
     36    onDropOrPaste(e.clipboardData);
     37  });
     38 });
     39 
     40 
     41 // Registers a test to be run when an entry is dropped. Calls |func|
     42 // with (test, entry, item); |func| must call `test.done()` when complete.
     43 function entry_test(func, description) {
     44  const test = async_test(description);
     45  tests.push(test.step_func((entry, item) => func(test, entry, item)));
     46 }
     47 
     48 // Registers a test to be run when an entry is dropped. Digs the named
     49 // |file| out of the dropped entry and calls |func| with
     50 // (test, file_entry); |func| must call `test.done()` when complete.
     51 function file_entry_test(name, func, description) {
     52  return entry_test((t, entry, item) => {
     53    getChildEntry(entry, name,
     54                  t.step_func((entry) => func(t, entry)),
     55                  t.unreached_func('Did not find expected file: ' + name));
     56  }, description);
     57 }
     58 
     59 
     60 // ----------------------------------------
     61 // Paths
     62 // ----------------------------------------
     63 
     64 const INVALID_PATHS = [
     65  '\x00', 'a-\x00-b',
     66  '\\', 'a-\\-b'
     67 ];
     68 const EMPTY_PATHS = ['', null, undefined];
     69 const NOT_FOUND_PATHS = [
     70  'nope',
     71  '/upload/nope',
     72  './nope',
     73  'subdir/../nope',
     74  '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f',
     75  '\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f',
     76 ];
     77 
     78 const DIR_PATHS = [
     79  'subdir',
     80  '/upload/subdir',
     81  './subdir',
     82  'subdir/.',
     83  'subdir/../subdir',
     84  'subdir/./../subdir',
     85  'subdir/../subdir/.',
     86  '//upload/subdir',
     87  '/upload//subdir',
     88  './/subdir',
     89  'subdir//.',
     90 ];
     91 const FILE_PATHS = [
     92  'file.txt',
     93  '/upload/file.txt',
     94  'subdir/../file.txt',
     95  '//upload/file.txt',
     96  '/upload//file.txt',
     97  'subdir/./../file.txt',
     98 ];
     99 
    100 // ----------------------------------------
    101 // Helpers
    102 // ----------------------------------------
    103 
    104 // Wrapper for FileSystemDirectoryReader that yields all entries via a
    105 // Promise.
    106 
    107 function getEntriesAsPromise(dirEntry) {
    108  return new Promise((resolve, reject) => {
    109    const result = [];
    110    const reader = dirEntry.createReader();
    111    const doBatch = () => {
    112      reader.readEntries(entries => {
    113        if (entries.length > 0) {
    114          entries.forEach(e => result.push(e));
    115          doBatch();
    116        } else {
    117          resolve(result);
    118        }
    119      }, reject);
    120    };
    121    doBatch();
    122  });
    123 }
    124 
    125 
    126 // Wrapper for FileSystemDirectoryReader that yields a single entry by
    127 // name via a callback. Can be used instead of getFile() or
    128 // getDirectory() since not all implementations support those.
    129 
    130 function getChildEntry(dirEntry, name, callback, errback) {
    131  getEntriesAsPromise(dirEntry)
    132    .then(entries => {
    133      const entry = entries.filter(entry => entry.name === name)[0];
    134      if (!entry)
    135        throw new Error('No such file: ' + name);
    136      return entry;
    137    }).then(callback, errback);
    138 }