inert-polyfill/suite.js

222 строки
6.7 KiB
JavaScript

/*
* Copyright 2015 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
void function() {
/**
* Sends a tab event on this document. Note that this is a copy of
* dispatchTabEvent from the polyfill source.
*
* @param {boolean=} opt_shiftKey whether to send this tab with shiftKey
*/
function sendTab(opt_shiftKey) {
let ev = null;
try {
ev = new KeyboardEvent('keydown', {
keyCode: 9,
which: 9,
key: 'Tab',
code: 'Tab',
keyIdentifier: 'U+0009',
shiftKey: !!opt_shiftKey,
bubbles: true
});
} catch (e) {
try {
// Internet Explorer
ev = document.createEvent('KeyboardEvent');
ev.initKeyboardEvent(
'keydown',
true,
true,
window,
'Tab',
0,
opt_shiftKey ? 'Shift' : '',
false,
'en'
)
} catch (e) {}
}
if (ev) {
try {
Object.defineProperty(ev, 'keyCode', { value: 9 });
} catch (e) {}
document.dispatchEvent(ev);
}
}
/**
* Creates a text input element and adds it to <body>.
*
* @param {string=} opt_text to use as placeholder
* @return {!HTMLInputElement} added to page
*/
function createInput(opt_text) {
const input = document.createElement('input');
input.type = 'text';
input.placeholder = opt_text || '';
holder.appendChild(input);
return input;
}
let holder; // global holder for all tests
setup(function() {
holder = document.createElement('div');
document.body.appendChild(holder);
});
teardown(function() {
holder.parentNode && holder.parentNode.removeChild(holder);
});
test('normal input should get focus', function() {
const div = document.createElement('div');
const input = document.createElement('input');
input.type = 'text';
input.value = 'dummy';
div.appendChild(input);
holder.appendChild(div);
input.focus();
assert.equal(document.activeElement, input);
// TODO(samthor): If focus is prevented, Firefox shows an odd state: highlighted, with a
// selection defined on the input, but without a caret visible. It's weird. Can we test for it?
});
test('no programatic focus', function() {
const div = document.createElement('div');
div.setAttribute('inert', '');
holder.appendChild(div);
const input = createInput('test inert');
div.appendChild(input);
// TODO: fails when developer console is open, even though focus doesn't go
// anywhere
input.focus();
assert.notEqual(document.activeElement, input, 'element should not be focusable');
div.tabIndex = 1;
div.focus();
assert.notEqual(document.activeElement, div, 'inert element itself unavailable');
});
test('support inert property', function() {
const div = document.createElement('div');
div.inert = true;
assert(div.hasAttribute('inert'));
div.inert = false;
assert(!div.hasAttribute('inert'));
div.setAttribute('inert', '');
assert(div.inert);
div.removeAttribute('inert');
assert(!div.inert);
});
test('click prevented', function() {
let clickCount = 0;
const div = document.createElement('div');
holder.appendChild(div);
const button = document.createElement('button');
button.addEventListener('click', function() {
++clickCount;
});
div.appendChild(button);
button.click();
assert.equal(clickCount, 1, 'programatic click once');
div.setAttribute('inert', '');
button.click();
assert.equal(clickCount, 1, 'programatic click disabled via inert');
});
test('focused click prevented', function() {
let clickCount = 0;
const div = document.createElement('div');
holder.appendChild(div);
const input = document.createElement('input');
input.type = 'text';
input.addEventListener('click', function() {
++clickCount;
});
div.appendChild(input);
input.focus();
assert.equal(document.activeElement, input);
input.click();
assert.equal(clickCount, 1, 'programatic click once');
div.setAttribute('inert', '');
input.click();
assert.equal(clickCount, 1, 'programatic click, even while ? focused, disabled via inert');
});
test('tab-over works', function() {
const beforeInput = createInput('before');
const duringInputInert = createInput('during');
const afterInput = createInput('after');
duringInputInert.setAttribute('inert', '');
beforeInput.focus();
assert.equal(document.activeElement, beforeInput, 'sanity check before input focused');
sendTab();
if (document.activeElement == beforeInput) {
// TODO: work around Firefox not actually acting on tab
console.warn('manual focus after tab');
duringInputInert.focus();
}
assert.equal(document.activeElement, afterInput, 'tab-over inert works');
sendTab(true);
if (document.activeElement == afterInput) {
// TODO: work around Firefox not actually acting on tab
console.warn('manual focus after shift-tab');
duringInputInert.focus();
}
assert.equal(document.activeElement, beforeInput, 'tab-over (reverse) inert works');
});
const testEl = document.createElement('div');
if (testEl.createShadowRoot || testEl.attachShadow) {
// test this
test('inert within shadow root', function() {
const el = document.createElement('div');
holder.appendChild(el);
const root = el.createShadowRoot ? el.createShadowRoot() : el.attachShadow({mode: 'open'});
const button = document.createElement('button');
root.appendChild(button);
button.focus();
assert.equal(document.activeElement, el, 'shadow host itself is focused');
assert.equal(root.activeElement, button, 'button within shadow is focused');
const inertButton = document.createElement('button');
inertButton.setAttribute('inert', '');
root.appendChild(inertButton);
inertButton.focus();
assert.notEqual(root.activeElement, inertButton, 'shadow root button inert');
inertButton.click();
assert.notEqual(root.activeElement, inertButton, 'shadow root button inert when clicked');
});
}
}();