emulate-key-in-browser
Version:
emulate browsers reactions on special keys
307 lines (296 loc) • 13.2 kB
JavaScript
define(['exports', 'emulate-tab'], function (exports, emulateTab) { 'use strict';
function isTextInputElement(element) {
return (element instanceof HTMLInputElement)
|| (element instanceof HTMLTextAreaElement);
}
function getValueLength(target) {
return target.value && target.value.length || 0;
}
function findSelectionStart(target, valueLength) {
if (valueLength === void 0) { valueLength = getValueLength(target); }
if (typeof target.selectionStart === 'number')
return target.selectionStart;
if (typeof target.selectionEnd === 'number')
return target.selectionEnd;
return valueLength;
}
function findSelectionEnd(target, valueLength) {
if (valueLength === void 0) { valueLength = getValueLength(target); }
if (typeof target.selectionEnd === 'number')
return target.selectionEnd;
if (typeof target.selectionStart === 'number')
return target.selectionStart;
return valueLength;
}
function findKeyTarget() {
return document.activeElement || document.body;
}
function emulateKeyEvents(key, textInputAction, target, options) {
if (target === void 0) { target = findKeyTarget(); }
var executeDefaultActions = target.dispatchEvent(new KeyboardEvent('keydown', { key: key, cancelable: true, bubbles: true }));
executeDefaultActions = target.dispatchEvent(new KeyboardEvent('keypress', { key: key, cancelable: true, bubbles: options === null || options === void 0 ? void 0 : options.keypressBubbles })) && executeDefaultActions;
if (executeDefaultActions && textInputAction && isTextInputElement(target)) {
executeDefaultActions = textInputAction(target);
}
executeDefaultActions = target.dispatchEvent(new KeyboardEvent('keyup', { key: key, cancelable: true })) && executeDefaultActions;
}
var noEventThatCouldGetCanceled = true;
var emulateArrow = {
up: function () { return emulateArrowUp(); },
right: function () { return emulateArrowRight(); },
down: function () { return emulateArrowDown(); },
left: function () { return emulateArrowLeft(); },
shift: {
up: function () { return emulateShiftArrowUp(); },
right: function () { return emulateShiftArrowRight(); },
down: function () { return emulateShiftArrowDown(); },
left: function () { return emulateShiftArrowLeft(); }
}
};
function emulateArrowUp() {
return emulateKeyEvents('ArrowUp', function (target) {
var lineLength = lineLengthOf(target);
var selectionStart = findSelectionStart(target);
setCursorOf(target, Math.max(selectionStart - lineLength, 0));
return noEventThatCouldGetCanceled;
});
}
function setCursorOf(target, position) {
target.setSelectionRange(position, position, 'none');
}
function lineLengthOf(target, valueLength) {
if (valueLength === void 0) { valueLength = valueLengthOf(target); }
return target instanceof HTMLTextAreaElement ? target.cols : valueLength;
}
function valueLengthOf(target) {
return target.value && target.value.length || 0;
}
function emulateArrowRight() {
return emulateKeyEvents('ArrowRight', function (target) {
if (target.selectionStart !== target.selectionEnd) {
setCursorOf(target, findSelectionEnd(target));
return noEventThatCouldGetCanceled;
}
var valueLength = valueLengthOf(target);
var selectionEnd = findSelectionEnd(target);
if (selectionEnd < valueLength) {
setCursorOf(target, selectionEnd + 1);
}
return noEventThatCouldGetCanceled;
});
}
function emulateArrowDown() {
return emulateKeyEvents('ArrowDown', function (target) {
var valueLength = valueLengthOf(target);
var lineLength = lineLengthOf(target, valueLength);
var selectionEnd = findSelectionEnd(target);
setCursorOf(target, Math.min(selectionEnd + lineLength, valueLength));
return noEventThatCouldGetCanceled;
});
}
function emulateArrowLeft() {
return emulateKeyEvents('ArrowLeft', function (target) {
if (target.selectionStart !== target.selectionEnd) {
setCursorOf(target, findSelectionStart(target));
target.selectionEnd = target.selectionStart;
return noEventThatCouldGetCanceled;
}
var selectionStart = findSelectionStart(target);
if (selectionStart > 0) {
setCursorOf(target, selectionStart - 1);
}
return noEventThatCouldGetCanceled;
});
}
function emulateShiftArrowUp() {
return emulateKeyEvents('ArrowUp', function (target) {
var lineLength = lineLengthOf(target);
if (isSelectionDirectionOf(target, 'forward')) {
reduceSelectionAtSelectionEnd(target, lineLength);
}
else {
extendSelectionAtSelectionStart(target, lineLength);
}
return noEventThatCouldGetCanceled;
});
}
function isSelectionDirectionOf(target, direction) {
return target.selectionDirection === direction && (target.selectionStart !== target.selectionEnd);
}
function extendSelectionAtSelectionStart(target, lengthToExtend) {
var selectionStart = findSelectionStart(target);
var newSelectionStart = Math.max(selectionStart - lengthToExtend, 0);
target.selectionStart = newSelectionStart;
if (target.selectionDirection !== 'backward') {
target.selectionDirection = 'backward';
}
}
function reduceSelectionAtSelectionEnd(target, lengthToReduce) {
var selectionStart = findSelectionStart(target);
var selectionEnd = findSelectionEnd(target);
var newSelectionEnd = selectionEnd - lengthToReduce;
if (selectionStart < newSelectionEnd) {
target.selectionEnd = newSelectionEnd;
}
else {
target.selectionEnd = selectionStart;
target.selectionDirection = 'none';
}
}
function emulateShiftArrowRight() {
return emulateKeyEvents('ArrowRight', function (target) {
if (isSelectionDirectionOf(target, 'backward')) {
reduceSelectionAtSelectionStart(target, 1);
}
else {
extendSelectionAtSelectionEnd(target, 1);
}
return noEventThatCouldGetCanceled;
});
}
function extendSelectionAtSelectionEnd(target, lengthToExtend) {
var valueLength = valueLengthOf(target);
var selectionEnd = findSelectionEnd(target, valueLength);
target.selectionEnd = Math.min(selectionEnd + lengthToExtend, valueLength);
if (target.selectionDirection !== 'forward') {
target.selectionDirection = 'forward';
}
}
function reduceSelectionAtSelectionStart(target, lengthToReduce) {
var selectionStart = findSelectionStart(target);
var selectionEnd = findSelectionEnd(target);
var newSelectionStart = selectionStart + lengthToReduce;
if (newSelectionStart < selectionEnd) {
target.selectionStart = newSelectionStart;
}
else {
target.selectionStart = selectionEnd;
target.selectionDirection = 'none';
}
}
function emulateShiftArrowDown() {
return emulateKeyEvents('ArrowDown', function (target) {
var lineLength = lineLengthOf(target);
if (isSelectionDirectionOf(target, 'backward')) {
reduceSelectionAtSelectionStart(target, lineLength);
}
else {
extendSelectionAtSelectionEnd(target, lineLength);
}
return noEventThatCouldGetCanceled;
});
}
function emulateShiftArrowLeft() {
return emulateKeyEvents('ArrowLeft', function (target) {
if (isSelectionDirectionOf(target, 'forward')) {
reduceSelectionAtSelectionEnd(target, 1);
}
else {
extendSelectionAtSelectionStart(target, 1);
}
return noEventThatCouldGetCanceled;
});
}
function emulateBackspace() {
return emulateKeyEvents('Backspace', function (target) {
var value = target.value || '';
var valueLength = value.length;
if (valueLength > 0) {
var selectionStart = findSelectionStart(target, valueLength);
var selectionEnd = findSelectionEnd(target, valueLength);
if (selectionStart !== selectionEnd) {
target.value = value.substr(0, selectionStart) + value.substr(selectionEnd);
target.setSelectionRange(selectionStart, selectionStart, 'none');
}
else if (selectionStart > 0) {
var newSelectionStart = selectionStart - 1;
target.value = value.substr(0, newSelectionStart) + value.substr(selectionEnd);
target.setSelectionRange(newSelectionStart, newSelectionStart, 'none');
}
}
return target.dispatchEvent(new InputEvent('input'));
});
}
function emulateDelete() {
return emulateKeyEvents('Delete', function (target) {
var value = target.value || '';
var valueLength = value.length;
if (valueLength > 0) {
var selectionStart = findSelectionStart(target, valueLength);
var selectionEnd = findSelectionEnd(target, valueLength);
if (selectionStart !== selectionEnd) {
target.value = value.substr(0, selectionStart) + value.substr(selectionEnd);
target.setSelectionRange(selectionStart, selectionStart, 'none');
}
else if (selectionEnd < valueLength) {
target.value = value.substr(0, selectionEnd) + value.substr(selectionEnd + 1);
target.setSelectionRange(selectionEnd, selectionEnd, 'none');
}
}
return target.dispatchEvent(new InputEvent('input'));
});
}
var emulateMouse;
(function (emulateMouse) {
emulateMouse.hover = triggerMouseover;
})(emulateMouse || (emulateMouse = {}));
function triggerMouseover(element) {
var offsetBox = getOffsetBox(element);
var clientX = offsetBox.left + Math.floor(offsetBox.width / 2);
var clientY = offsetBox.top + Math.floor(offsetBox.height / 2);
return element.dispatchEvent(new MouseEvent('mouseover', { clientX: clientX, clientY: clientY, button: 0, buttons: 0 }));
}
function getOffsetBox(element) {
var pos = getOffsetPosition(element);
var left = pos.left;
var top = pos.top;
var width = element.offsetWidth;
var height = element.offsetHeight;
var right = left + width;
var bottom = top + height;
return { top: top, right: right, bottom: bottom, left: left, width: width, height: height };
}
function getOffsetPosition(element) {
var left = element.offsetLeft;
var top = element.offsetTop;
var parent = element.offsetParent;
if (parent instanceof HTMLElement) {
var parentPos = getOffsetPosition(parent);
left += parentPos.left;
top += parentPos.top;
}
return { left: left, top: top };
}
function emulateWriteText(keys) {
keys.split('').forEach(writeKey);
}
function writeKey(key) {
return emulateKeyEvents(key, function (target) {
var value = target.value || '';
var valueLength = value.length;
var selectionStart = findSelectionStart(target, valueLength);
if (selectionStart !== valueLength) {
var selectionEnd = findSelectionEnd(target, valueLength);
target.value = value.substr(0, selectionStart) + key + value.substr(selectionEnd);
target.selectionStart = target.selectionEnd = selectionStart + 1;
target.selectionDirection = 'none';
}
else {
target.value += key;
}
return target.dispatchEvent(new InputEvent('input', { bubbles: true }));
}, undefined, { keypressBubbles: true });
}
var emulateKey = {
tab: emulateTab.emulateTab,
shiftTab: emulateTab.emulateTab.backwards,
backspace: emulateBackspace,
"delete": emulateDelete,
mouse: emulateMouse,
arrow: emulateArrow,
shiftArrow: emulateArrow.shift,
writeText: emulateWriteText
};
exports.emulateKey = emulateKey;
Object.defineProperty(exports, '__esModule', { value: true });
});