character.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.keypressBehavior = void 0;
  6. var _dom = require("@testing-library/dom");
  7. var _shared = require("../shared");
  8. var _utils = require("../../utils");
  9. /**
  10. * This file should cover the behavior for keys that produce character input
  11. */
  12. const keypressBehavior = [{
  13. matches: (keyDef, element) => {
  14. var _keyDef$key;
  15. return ((_keyDef$key = keyDef.key) == null ? void 0 : _keyDef$key.length) === 1 && (0, _utils.isElementType)(element, 'input', {
  16. type: 'time',
  17. readOnly: false
  18. });
  19. },
  20. handle: (keyDef, element, options, state) => {
  21. var _state$carryValue;
  22. let newEntry = keyDef.key;
  23. const textToBeTyped = ((_state$carryValue = state.carryValue) != null ? _state$carryValue : '') + newEntry;
  24. const timeNewEntry = (0, _utils.buildTimeValue)(textToBeTyped);
  25. if ((0, _utils.isValidInputTimeValue)(element, timeNewEntry)) {
  26. newEntry = timeNewEntry;
  27. }
  28. const {
  29. newValue,
  30. newSelectionStart
  31. } = (0, _utils.calculateNewValue)(newEntry, element);
  32. const prevValue = (0, _utils.getValue)(element); // this check was provided by fireInputEventIfNeeded
  33. // TODO: verify if it is even needed by this handler
  34. if (prevValue !== newValue) {
  35. (0, _shared.fireInputEvent)(element, {
  36. newValue,
  37. newSelectionStart,
  38. eventOverrides: {
  39. data: keyDef.key,
  40. inputType: 'insertText'
  41. }
  42. });
  43. }
  44. (0, _shared.fireChangeForInputTimeIfValid)(element, prevValue, timeNewEntry);
  45. state.carryValue = textToBeTyped;
  46. }
  47. }, {
  48. matches: (keyDef, element) => {
  49. var _keyDef$key2;
  50. return ((_keyDef$key2 = keyDef.key) == null ? void 0 : _keyDef$key2.length) === 1 && (0, _utils.isElementType)(element, 'input', {
  51. type: 'date',
  52. readOnly: false
  53. });
  54. },
  55. handle: (keyDef, element, options, state) => {
  56. var _state$carryValue2;
  57. let newEntry = keyDef.key;
  58. const textToBeTyped = ((_state$carryValue2 = state.carryValue) != null ? _state$carryValue2 : '') + newEntry;
  59. const isValidToBeTyped = (0, _utils.isValidDateValue)(element, textToBeTyped);
  60. if (isValidToBeTyped) {
  61. newEntry = textToBeTyped;
  62. }
  63. const {
  64. newValue,
  65. newSelectionStart
  66. } = (0, _utils.calculateNewValue)(newEntry, element);
  67. const prevValue = (0, _utils.getValue)(element); // this check was provided by fireInputEventIfNeeded
  68. // TODO: verify if it is even needed by this handler
  69. if (prevValue !== newValue) {
  70. (0, _shared.fireInputEvent)(element, {
  71. newValue,
  72. newSelectionStart,
  73. eventOverrides: {
  74. data: keyDef.key,
  75. inputType: 'insertText'
  76. }
  77. });
  78. }
  79. if (isValidToBeTyped) {
  80. _dom.fireEvent.change(element, {
  81. target: {
  82. value: textToBeTyped
  83. }
  84. });
  85. }
  86. state.carryValue = textToBeTyped;
  87. }
  88. }, {
  89. matches: (keyDef, element) => {
  90. var _keyDef$key3;
  91. return ((_keyDef$key3 = keyDef.key) == null ? void 0 : _keyDef$key3.length) === 1 && (0, _utils.isElementType)(element, 'input', {
  92. type: 'number',
  93. readOnly: false
  94. });
  95. },
  96. handle: (keyDef, element, options, state) => {
  97. var _ref, _state$carryValue3, _newValue$match, _newValue$match2;
  98. if (!/[\d.\-e]/.test(keyDef.key)) {
  99. return;
  100. }
  101. const oldValue = (_ref = (_state$carryValue3 = state.carryValue) != null ? _state$carryValue3 : (0, _utils.getValue)(element)) != null ? _ref :
  102. /* istanbul ignore next */
  103. '';
  104. const {
  105. newValue,
  106. newSelectionStart
  107. } = (0, _utils.calculateNewValue)(keyDef.key, element, oldValue); // the browser allows some invalid input but not others
  108. // it allows up to two '-' at any place before any 'e' or one directly following 'e'
  109. // it allows one '.' at any place before e
  110. const valueParts = newValue.split('e', 2);
  111. if (Number((_newValue$match = newValue.match(/-/g)) == null ? void 0 : _newValue$match.length) > 2 || Number((_newValue$match2 = newValue.match(/\./g)) == null ? void 0 : _newValue$match2.length) > 1 || valueParts[1] && !/^-?\d*$/.test(valueParts[1])) {
  112. return;
  113. }
  114. (0, _shared.fireInputEvent)(element, {
  115. newValue,
  116. newSelectionStart,
  117. eventOverrides: {
  118. data: keyDef.key,
  119. inputType: 'insertText'
  120. }
  121. });
  122. const appliedValue = (0, _utils.getValue)(element);
  123. if (appliedValue === newValue) {
  124. state.carryValue = undefined;
  125. } else {
  126. state.carryValue = newValue;
  127. }
  128. }
  129. }, {
  130. matches: (keyDef, element) => {
  131. var _keyDef$key4;
  132. return ((_keyDef$key4 = keyDef.key) == null ? void 0 : _keyDef$key4.length) === 1 && ((0, _utils.isElementType)(element, ['input', 'textarea'], {
  133. readOnly: false
  134. }) && !(0, _utils.isClickableInput)(element) || (0, _utils.isContentEditable)(element)) && (0, _utils.getSpaceUntilMaxLength)(element) !== 0;
  135. },
  136. handle: (keyDef, element) => {
  137. const {
  138. newValue,
  139. newSelectionStart
  140. } = (0, _utils.calculateNewValue)(keyDef.key, element);
  141. (0, _shared.fireInputEvent)(element, {
  142. newValue,
  143. newSelectionStart,
  144. eventOverrides: {
  145. data: keyDef.key,
  146. inputType: 'insertText'
  147. }
  148. });
  149. }
  150. }, {
  151. matches: (keyDef, element) => keyDef.key === 'Enter' && ((0, _utils.isElementType)(element, 'textarea', {
  152. readOnly: false
  153. }) || (0, _utils.isContentEditable)(element)) && (0, _utils.getSpaceUntilMaxLength)(element) !== 0,
  154. handle: (keyDef, element, options, state) => {
  155. const {
  156. newValue,
  157. newSelectionStart
  158. } = (0, _utils.calculateNewValue)('\n', element);
  159. const inputType = (0, _utils.isContentEditable)(element) && !state.modifiers.shift ? 'insertParagraph' : 'insertLineBreak';
  160. (0, _shared.fireInputEvent)(element, {
  161. newValue,
  162. newSelectionStart,
  163. eventOverrides: {
  164. inputType
  165. }
  166. });
  167. }
  168. }];
  169. exports.keypressBehavior = keypressBehavior;