Revision b55e29597d92ab89063673f031151e2bdb4b9479 authored by Joe Downing on 22 March 2018, 07:35:35 UTC, committed by Chromium WPT Sync on 22 March 2018, 07:35:35 UTC
This change moves the KeyboardLock API methods to a 'keyboard'
namespace on the Navigator object.  We are doing this work now as
there has been a request for additional keyboard functionality that
would also be placed on the new keyboard object and we wanted to
move the KeyboardLock methods there for consistency before we launch.

KeyboardLock API Spec is here:
https://w3c.github.io/keyboard-lock/#API

Old calling pattern:
Navigator.keyboardLock();
Navigator.keyboardUnlock();

New calling pattern:
Navigator.keyboard.lock();
Navigator.keyboard.unlock();

Note: The main logic in the KeyboardLock.cpp class and tests is the
same as it was, however the file changed enough that git does not
recognize it as a file move.

BUG=680809

Change-Id: I234b2ab12d5ecd44c894ed5103863fd96fd548d4
Reviewed-on: https://chromium-review.googlesource.com/969656
Reviewed-by: Philip Jägenstedt <foolip@chromium.org>
Reviewed-by: Gary Kacmarcik <garykac@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#544996}
1 parent 1a8c195
Raw File
support.js
// ----------------------------------------
// Test Utilities
// ----------------------------------------

setup({explicit_timeout: true});

const tests = [];
window.addEventListener('DOMContentLoaded', e => {
  const header = document.createElement('h1');
  header.innerText = document.title;
  document.body.appendChild(header);
  const elem = document.createElement('div');
  elem.style.cssText = 'height: 50px; border: 1px dotted red;';
  elem.innerHTML = 'Drop the <b>support/upload</b> directory here.</div>';
  document.body.appendChild(elem);
  elem.addEventListener('dragover', e => {
    e.preventDefault();
  });
  elem.addEventListener('drop', e => {
    e.preventDefault();
    for (let i = 0; i < e.dataTransfer.items.length; ++i) {
      const item = e.dataTransfer.items[i];
      if (item.kind !== 'file')
        continue;
      const entry = item.webkitGetAsEntry();
      elem.parentElement.removeChild(elem);
      tests.forEach(f => f(entry, item));
      break;
    }
  });
});


// Registers a test to be run when an entry is dropped. Calls |func|
// with (test, entry, item); |func| must call `test.done()` when complete.
function entry_test(func, description) {
  const test = async_test(description);
  tests.push(test.step_func((entry, item) => func(test, entry, item)));
}

// Registers a test to be run when an entry is dropped. Digs the named
// |file| out of the dropped entry and calls |func| with
// (test, file_entry); |func| must call `test.done()` when complete.
function file_entry_test(name, func, description) {
  return entry_test((t, entry, item) => {
    getChildEntry(entry, name,
                  t.step_func((entry) => func(t, entry)),
                  t.unreached_func('Did not find expected file: ' + name));
  }, description);
}


// ----------------------------------------
// Paths
// ----------------------------------------

const INVALID_PATHS = [
  '\x00', 'a-\x00-b',
  '\\', 'a-\\-b'
];
const EMPTY_PATHS = ['', null, undefined];
const NOT_FOUND_PATHS = [
  'nope',
  '/upload/nope',
  './nope',
  'subdir/../nope',
  '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f',
  '\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f',
];

const DIR_PATHS = [
  'subdir',
  '/upload/subdir',
  './subdir',
  'subdir/.',
  'subdir/../subdir',
  'subdir/./../subdir',
  'subdir/../subdir/.',
  '//upload/subdir',
  '/upload//subdir',
  './/subdir',
  'subdir//.',
];
const FILE_PATHS = [
  'file.txt',
  '/upload/file.txt',
  'subdir/../file.txt',
  '//upload/file.txt',
  '/upload//file.txt',
  'subdir/./../file.txt',
];

// ----------------------------------------
// Helpers
// ----------------------------------------

// Wrapper for FileSystemDirectoryReader that yields all entries via a
// Promise.

function getEntriesAsPromise(dirEntry) {
  return new Promise((resolve, reject) => {
    const result = [];
    const reader = dirEntry.createReader();
    const doBatch = () => {
      reader.readEntries(entries => {
        if (entries.length > 0) {
          entries.forEach(e => result.push(e));
          doBatch();
        } else {
          resolve(result);
        }
      }, reject);
    };
    doBatch();
  });
}


// Wrapper for FileSystemDirectoryReader that yields a single entry by
// name via a callback. Can be used instead of getFile() or
// getDirectory() since not all implementations support those.

function getChildEntry(dirEntry, name, callback, errback) {
  getEntriesAsPromise(dirEntry)
    .then(entries => {
      const entry = entries.filter(entry => entry.name === name)[0];
      if (!entry)
        throw new Error('No such file: ' + name);
      return entry;
    }).then(callback, errback);
}
back to top