You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

174 lines
5.5 KiB

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getNextKeyDef = getNextKeyDef;
var bracketDict;
(function (bracketDict) {
bracketDict["{"] = "}";
bracketDict["["] = "]";
})(bracketDict || (bracketDict = {}));
var legacyModifiers;
(function (legacyModifiers) {
legacyModifiers["alt"] = "alt";
legacyModifiers["ctrl"] = "ctrl";
legacyModifiers["meta"] = "meta";
legacyModifiers["shift"] = "shift";
})(legacyModifiers || (legacyModifiers = {}));
var legacyKeyMap;
/**
* Get the next key from keyMap
*
* Keys can be referenced by `{key}` or `{special}` as well as physical locations per `[code]`.
* Everything else will be interpreted as a typed character - e.g. `a`.
* Brackets `{` and `[` can be escaped by doubling - e.g. `foo[[bar` translates to `foo[bar`.
* Keeping the key pressed can be written as `{key>}`.
* When keeping the key pressed you can choose how long (how many keydown and keypress) the key is pressed `{key>3}`.
* You can then release the key per `{key>3/}` or keep it pressed and continue with the next key.
* Modifiers like `{shift}` imply being kept pressed. This can be turned of per `{shift/}`.
*/
(function (legacyKeyMap) {
legacyKeyMap["ctrl"] = "Control";
legacyKeyMap["del"] = "Delete";
legacyKeyMap["esc"] = "Escape";
legacyKeyMap["space"] = " ";
})(legacyKeyMap || (legacyKeyMap = {}));
function getNextKeyDef(text, options) {
var _options$keyboardMap$;
const {
type,
descriptor,
consumedLength,
releasePrevious,
releaseSelf,
repeat
} = readNextDescriptor(text);
const keyDef = (_options$keyboardMap$ = options.keyboardMap.find(def => {
if (type === '[') {
var _def$code;
return ((_def$code = def.code) == null ? void 0 : _def$code.toLowerCase()) === descriptor.toLowerCase();
} else if (type === '{') {
var _def$key;
const key = mapLegacyKey(descriptor);
return ((_def$key = def.key) == null ? void 0 : _def$key.toLowerCase()) === key.toLowerCase();
}
return def.key === descriptor;
})) != null ? _options$keyboardMap$ : {
key: 'Unknown',
code: 'Unknown',
[type === '[' ? 'code' : 'key']: descriptor
};
return {
keyDef,
consumedLength,
releasePrevious,
releaseSelf,
repeat
};
}
function readNextDescriptor(text) {
let pos = 0;
const startBracket = text[pos] in bracketDict ? text[pos] : '';
pos += startBracket.length; // `foo{{bar` is an escaped char at position 3,
// but `foo{{{>5}bar` should be treated as `{` pressed down for 5 keydowns.
const startBracketRepeated = startBracket ? text.match(new RegExp(`^\\${startBracket}+`))[0].length : 0;
const isEscapedChar = startBracketRepeated === 2 || startBracket === '{' && startBracketRepeated > 3;
const type = isEscapedChar ? '' : startBracket;
return {
type,
...(type === '' ? readPrintableChar(text, pos) : readTag(text, pos, type))
};
}
function readPrintableChar(text, pos) {
const descriptor = text[pos];
assertDescriptor(descriptor, text, pos);
pos += descriptor.length;
return {
consumedLength: pos,
descriptor,
releasePrevious: false,
releaseSelf: true,
repeat: 1
};
}
function readTag(text, pos, startBracket) {
var _text$slice$match, _text$slice$match$, _text$slice$match2;
const releasePreviousModifier = text[pos] === '/' ? '/' : '';
pos += releasePreviousModifier.length;
const descriptor = (_text$slice$match = text.slice(pos).match(/^\w+/)) == null ? void 0 : _text$slice$match[0];
assertDescriptor(descriptor, text, pos);
pos += descriptor.length;
const repeatModifier = (_text$slice$match$ = (_text$slice$match2 = text.slice(pos).match(/^>\d+/)) == null ? void 0 : _text$slice$match2[0]) != null ? _text$slice$match$ : '';
pos += repeatModifier.length;
const releaseSelfModifier = text[pos] === '/' || !repeatModifier && text[pos] === '>' ? text[pos] : '';
pos += releaseSelfModifier.length;
const expectedEndBracket = bracketDict[startBracket];
const endBracket = text[pos] === expectedEndBracket ? expectedEndBracket : '';
if (!endBracket) {
throw new Error(getErrorMessage([!repeatModifier && 'repeat modifier', !releaseSelfModifier && 'release modifier', `"${expectedEndBracket}"`].filter(Boolean).join(' or '), text[pos], text));
}
pos += endBracket.length;
return {
consumedLength: pos,
descriptor,
releasePrevious: !!releasePreviousModifier,
repeat: repeatModifier ? Math.max(Number(repeatModifier.substr(1)), 1) : 1,
releaseSelf: hasReleaseSelf(startBracket, descriptor, releaseSelfModifier, repeatModifier)
};
}
function assertDescriptor(descriptor, text, pos) {
if (!descriptor) {
throw new Error(getErrorMessage('key descriptor', text[pos], text));
}
}
function getEnumValue(f, key) {
return f[key];
}
function hasReleaseSelf(startBracket, descriptor, releaseSelfModifier, repeatModifier) {
if (releaseSelfModifier) {
return releaseSelfModifier === '/';
}
if (repeatModifier) {
return false;
}
if (startBracket === '{' && getEnumValue(legacyModifiers, descriptor.toLowerCase())) {
return false;
}
return true;
}
function mapLegacyKey(descriptor) {
var _getEnumValue;
return (_getEnumValue = getEnumValue(legacyKeyMap, descriptor)) != null ? _getEnumValue : descriptor;
}
function getErrorMessage(expected, found, text) {
return `Expected ${expected} but found "${found != null ? found : ''}" in "${text}"
See https://github.com/testing-library/user-event/blob/main/README.md#keyboardtext-options
for more information about how userEvent parses your input.`;
}