keyboardImplementation.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.keyboardImplementation = keyboardImplementation;
  6. exports.releaseAllKeys = releaseAllKeys;
  7. var _dom = require("@testing-library/dom");
  8. var _utils = require("../utils");
  9. var _getNextKeyDef = require("./getNextKeyDef");
  10. var plugins = _interopRequireWildcard(require("./plugins"));
  11. var _getEventProps = require("./getEventProps");
  12. function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
  13. function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  14. async function keyboardImplementation(text, options, state) {
  15. var _state$repeatKey;
  16. const {
  17. document
  18. } = options;
  19. const getCurrentElement = () => getActive(document);
  20. const {
  21. keyDef,
  22. consumedLength,
  23. releasePrevious,
  24. releaseSelf,
  25. repeat
  26. } = (_state$repeatKey = state.repeatKey) != null ? _state$repeatKey : (0, _getNextKeyDef.getNextKeyDef)(text, options);
  27. const replace = applyPlugins(plugins.replaceBehavior, keyDef, getCurrentElement(), options, state);
  28. if (!replace) {
  29. const pressed = state.pressed.find(p => p.keyDef === keyDef); // Release the key automatically if it was pressed before.
  30. // Do not release the key on iterations on `state.repeatKey`.
  31. if (pressed && !state.repeatKey) {
  32. keyup(keyDef, getCurrentElement, options, state, pressed.unpreventedDefault);
  33. }
  34. if (!releasePrevious) {
  35. const unpreventedDefault = keydown(keyDef, getCurrentElement, options, state);
  36. if (unpreventedDefault && hasKeyPress(keyDef, state)) {
  37. keypress(keyDef, getCurrentElement, options, state);
  38. } // Release the key only on the last iteration on `state.repeatKey`.
  39. if (releaseSelf && repeat <= 1) {
  40. keyup(keyDef, getCurrentElement, options, state, unpreventedDefault);
  41. }
  42. }
  43. }
  44. if (repeat > 1) {
  45. state.repeatKey = {
  46. // don't consume again on the next iteration
  47. consumedLength: 0,
  48. keyDef,
  49. releasePrevious,
  50. releaseSelf,
  51. repeat: repeat - 1
  52. };
  53. } else {
  54. delete state.repeatKey;
  55. }
  56. if (text.length > consumedLength || repeat > 1) {
  57. if (options.delay > 0) {
  58. await (0, _utils.wait)(options.delay);
  59. }
  60. return keyboardImplementation(text.slice(consumedLength), options, state);
  61. }
  62. return void undefined;
  63. }
  64. function getActive(document) {
  65. var _getActiveElement;
  66. return (_getActiveElement = (0, _utils.getActiveElement)(document)) != null ? _getActiveElement :
  67. /* istanbul ignore next */
  68. document.body;
  69. }
  70. function releaseAllKeys(options, state) {
  71. const getCurrentElement = () => getActive(options.document);
  72. for (const k of state.pressed) {
  73. keyup(k.keyDef, getCurrentElement, options, state, k.unpreventedDefault);
  74. }
  75. }
  76. function keydown(keyDef, getCurrentElement, options, state) {
  77. const element = getCurrentElement(); // clear carried characters when focus is moved
  78. if (element !== state.activeElement) {
  79. state.carryValue = undefined;
  80. state.carryChar = '';
  81. }
  82. state.activeElement = element;
  83. applyPlugins(plugins.preKeydownBehavior, keyDef, element, options, state);
  84. const unpreventedDefault = _dom.fireEvent.keyDown(element, (0, _getEventProps.getKeyEventProps)(keyDef, state));
  85. state.pressed.push({
  86. keyDef,
  87. unpreventedDefault
  88. });
  89. if (unpreventedDefault) {
  90. // all default behavior like keypress/submit etc is applied to the currentElement
  91. applyPlugins(plugins.keydownBehavior, keyDef, getCurrentElement(), options, state);
  92. }
  93. return unpreventedDefault;
  94. }
  95. function keypress(keyDef, getCurrentElement, options, state) {
  96. const element = getCurrentElement();
  97. const unpreventedDefault = _dom.fireEvent.keyPress(element, (0, _getEventProps.getKeyEventProps)(keyDef, state));
  98. if (unpreventedDefault) {
  99. applyPlugins(plugins.keypressBehavior, keyDef, getCurrentElement(), options, state);
  100. }
  101. }
  102. function keyup(keyDef, getCurrentElement, options, state, unprevented) {
  103. const element = getCurrentElement();
  104. applyPlugins(plugins.preKeyupBehavior, keyDef, element, options, state);
  105. const unpreventedDefault = _dom.fireEvent.keyUp(element, (0, _getEventProps.getKeyEventProps)(keyDef, state));
  106. if (unprevented && unpreventedDefault) {
  107. applyPlugins(plugins.keyupBehavior, keyDef, getCurrentElement(), options, state);
  108. }
  109. state.pressed = state.pressed.filter(k => k.keyDef !== keyDef);
  110. applyPlugins(plugins.postKeyupBehavior, keyDef, element, options, state);
  111. }
  112. function applyPlugins(pluginCollection, keyDef, element, options, state) {
  113. const plugin = pluginCollection.find(p => p.matches(keyDef, element, options, state));
  114. if (plugin) {
  115. plugin.handle(keyDef, element, options, state);
  116. }
  117. return !!plugin;
  118. }
  119. function hasKeyPress(keyDef, state) {
  120. var _keyDef$key;
  121. return (((_keyDef$key = keyDef.key) == null ? void 0 : _keyDef$key.length) === 1 || keyDef.key === 'Enter') && !state.modifiers.ctrl && !state.modifiers.alt;
  122. }