handle-form-element.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import simulateEvent from './simulate-event';
  2. function formEvent(element, data) {
  3. if (data.type === 'text-field') {
  4. const code = /\s/.test(data.value)
  5. ? 'Space'
  6. : `key${data.value.toUpperCase()}`;
  7. simulateEvent(element, 'keydown', {
  8. code,
  9. bubbles: true,
  10. cancelable: true,
  11. key: data.value,
  12. });
  13. simulateEvent(element, 'keyup', {
  14. code,
  15. bubbles: true,
  16. cancelable: true,
  17. key: data.value,
  18. });
  19. }
  20. simulateEvent(element, 'input', {
  21. inputType: 'insertText',
  22. data: data.value,
  23. bubbles: true,
  24. cancelable: true,
  25. });
  26. element.dispatchEvent(
  27. new Event('change', { bubbles: true, cancelable: true })
  28. );
  29. }
  30. function inputText({ data, element, isEditable, index = 0, callback }) {
  31. const noDelay = data.delay === 0;
  32. const currentChar = data.value[index] ?? '';
  33. const elementKey = isEditable ? 'textContent' : 'value';
  34. element[elementKey] += noDelay ? data.value : currentChar;
  35. formEvent(element, { type: 'text-field', value: currentChar, isEditable });
  36. if (!noDelay && index + 1 !== data.value.length) {
  37. setTimeout(() => {
  38. inputText({ data, element, callback, isEditable, index: index + 1 });
  39. }, data.delay);
  40. } else {
  41. callback();
  42. }
  43. }
  44. export default function (element, data) {
  45. return new Promise((callback) => {
  46. const textFields = ['INPUT', 'TEXTAREA'];
  47. const isEditable =
  48. element.hasAttribute('contenteditable') && element.isContentEditable;
  49. if (isEditable) {
  50. if (data.clearValue) element.innerText = '';
  51. inputText({ data, element, callback, isEditable });
  52. return;
  53. }
  54. if (data.type === 'text-field' && textFields.includes(element.tagName)) {
  55. if (data.clearValue) element.value = '';
  56. inputText({ data, element, callback });
  57. return;
  58. }
  59. if (data.type === 'checkbox' || data.type === 'radio') {
  60. element.checked = data.selected;
  61. formEvent(element, { type: data.type, value: data.selected });
  62. callback(element.checked);
  63. return;
  64. }
  65. if (data.type === 'select') {
  66. element.value = data.value;
  67. formEvent(element, data);
  68. callback(element.value);
  69. return;
  70. }
  71. callback('');
  72. });
  73. }