UNPKG

95.9 kBJavaScriptView Raw
1var __defProp = Object.defineProperty;
2var __defProps = Object.defineProperties;
3var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5var __hasOwnProp = Object.prototype.hasOwnProperty;
6var __propIsEnum = Object.prototype.propertyIsEnumerable;
7var __pow = Math.pow;
8var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9var __spreadValues = (a, b) => {
10 for (var prop in b || (b = {}))
11 if (__hasOwnProp.call(b, prop))
12 __defNormalProp(a, prop, b[prop]);
13 if (__getOwnPropSymbols)
14 for (var prop of __getOwnPropSymbols(b)) {
15 if (__propIsEnum.call(b, prop))
16 __defNormalProp(a, prop, b[prop]);
17 }
18 return a;
19};
20var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21var __export = (target, all) => {
22 for (var name in all)
23 __defProp(target, name, { get: all[name], enumerable: true });
24};
25var __async = (__this, __arguments, generator) => {
26 return new Promise((resolve, reject) => {
27 var fulfilled = (value) => {
28 try {
29 step(generator.next(value));
30 } catch (e) {
31 reject(e);
32 }
33 };
34 var rejected = (value) => {
35 try {
36 step(generator.throw(value));
37 } catch (e) {
38 reject(e);
39 }
40 };
41 var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
42 step((generator = generator.apply(__this, __arguments)).next());
43 });
44};
45
46// src/utils/misc/isElementType.ts
47function isElementType(element, tag, props) {
48 if (element.namespaceURI && element.namespaceURI !== "http://www.w3.org/1999/xhtml") {
49 return false;
50 }
51 tag = Array.isArray(tag) ? tag : [tag];
52 if (!tag.includes(element.tagName.toLowerCase())) {
53 return false;
54 }
55 if (props) {
56 return Object.entries(props).every(([k, v]) => element[k] === v);
57 }
58 return true;
59}
60
61// src/utils/click/isClickableInput.ts
62var CLICKABLE_INPUT_TYPES = [
63 "button",
64 "color",
65 "file",
66 "image",
67 "reset",
68 "submit",
69 "checkbox",
70 "radio"
71];
72function isClickableInput(element) {
73 return isElementType(element, "button") || isElementType(element, "input") && CLICKABLE_INPUT_TYPES.includes(element.type);
74}
75
76// src/utils/dataTransfer/Blob.ts
77function readBlobText(blob) {
78 return new Promise((res, rej) => {
79 const fr = new FileReader();
80 fr.onerror = rej;
81 fr.onabort = rej;
82 fr.onload = () => {
83 res(String(fr.result));
84 };
85 fr.readAsText(blob);
86 });
87}
88
89// src/utils/dataTransfer/FileList.ts
90function createFileList(files) {
91 const list = __spreadProps(__spreadValues({}, files), {
92 length: files.length,
93 item: (index) => list[index],
94 [Symbol.iterator]: function* nextFile() {
95 for (let i = 0; i < list.length; i++) {
96 yield list[i];
97 }
98 }
99 });
100 list.constructor = FileList;
101 Object.setPrototypeOf(list, FileList.prototype);
102 Object.freeze(list);
103 return list;
104}
105
106// src/utils/dataTransfer/DataTransfer.ts
107var DataTransferItemStub = class {
108 constructor(dataOrFile, type3) {
109 this.file = null;
110 this.data = void 0;
111 if (typeof dataOrFile === "string") {
112 this.kind = "string";
113 this.type = String(type3);
114 this.data = dataOrFile;
115 } else {
116 this.kind = "file";
117 this.type = dataOrFile.type;
118 this.file = dataOrFile;
119 }
120 }
121 getAsFile() {
122 return this.file;
123 }
124 getAsString(callback) {
125 if (typeof this.data === "string") {
126 callback(this.data);
127 }
128 }
129 webkitGetAsEntry() {
130 throw new Error("not implemented");
131 }
132};
133var DataTransferItemListStub = class extends Array {
134 add(...args) {
135 const item = new DataTransferItemStub(args[0], args[1]);
136 this.push(item);
137 return item;
138 }
139 clear() {
140 this.splice(0, this.length);
141 }
142 remove(index) {
143 this.splice(index, 1);
144 }
145};
146function getTypeMatcher(type3, exact) {
147 const [group, sub] = type3.split("/");
148 const isGroup = !sub || sub === "*";
149 return (item) => {
150 return exact ? item.type === (isGroup ? group : type3) : isGroup ? item.type.startsWith(`${group}/`) : item.type === group;
151 };
152}
153var DataTransferStub = class {
154 constructor() {
155 this.dropEffect = "none";
156 this.effectAllowed = "uninitialized";
157 this.items = new DataTransferItemListStub();
158 this.files = createFileList([]);
159 }
160 getData(format) {
161 var _a;
162 const match = (_a = this.items.find(getTypeMatcher(format, true))) != null ? _a : this.items.find(getTypeMatcher(format, false));
163 let text = "";
164 match == null ? void 0 : match.getAsString((t) => {
165 text = t;
166 });
167 return text;
168 }
169 setData(format, data) {
170 const matchIndex = this.items.findIndex(getTypeMatcher(format, true));
171 const item = new DataTransferItemStub(data, format);
172 if (matchIndex >= 0) {
173 this.items.splice(matchIndex, 1, item);
174 } else {
175 this.items.push(item);
176 }
177 }
178 clearData(format) {
179 if (format) {
180 const matchIndex = this.items.findIndex(getTypeMatcher(format, true));
181 if (matchIndex >= 0) {
182 this.items.remove(matchIndex);
183 }
184 } else {
185 this.items.clear();
186 }
187 }
188 get types() {
189 const t = [];
190 if (this.files.length) {
191 t.push("Files");
192 }
193 this.items.forEach((i) => t.push(i.type));
194 Object.freeze(t);
195 return t;
196 }
197 setDragImage() {
198 }
199};
200function createDataTransfer(files = []) {
201 const dt = typeof DataTransfer === "undefined" ? new DataTransferStub() : new DataTransfer();
202 Object.defineProperty(dt, "files", { get: () => createFileList(files) });
203 return dt;
204}
205function getBlobFromDataTransferItem(item) {
206 if (item.kind === "file") {
207 return item.getAsFile();
208 }
209 let data = "";
210 item.getAsString((s) => {
211 data = s;
212 });
213 return new Blob([data], { type: item.type });
214}
215
216// src/utils/dataTransfer/Clipboard.ts
217var ClipboardItemStub = class {
218 constructor(data) {
219 this.data = data;
220 }
221 get types() {
222 return Array.from(Object.keys(this.data));
223 }
224 getType(type3) {
225 return __async(this, null, function* () {
226 const data = yield this.data[type3];
227 if (!data) {
228 throw new Error(`${type3} is not one of the available MIME types on this item.`);
229 }
230 return data instanceof Blob ? data : new Blob([data], { type: type3 });
231 });
232 }
233};
234var ClipboardStubControl = Symbol("Manage ClipboardSub");
235var ClipboardStub = class extends EventTarget {
236 constructor() {
237 super(...arguments);
238 this.items = [];
239 }
240 read() {
241 return __async(this, null, function* () {
242 return Array.from(this.items);
243 });
244 }
245 readText() {
246 return __async(this, null, function* () {
247 let text = "";
248 for (const item of this.items) {
249 const type3 = item.types.includes("text/plain") ? "text/plain" : item.types.find((t) => t.startsWith("text/"));
250 if (type3) {
251 text += yield item.getType(type3).then((b) => readBlobText(b));
252 }
253 }
254 return text;
255 });
256 }
257 write(data) {
258 return __async(this, null, function* () {
259 this.items = data;
260 });
261 }
262 writeText(text) {
263 return __async(this, null, function* () {
264 this.items = [createClipboardItem(text)];
265 });
266 }
267};
268ClipboardStubControl;
269function createClipboardItem(...blobs) {
270 const constructor = typeof ClipboardItem === "undefined" ? ClipboardItemStub : ClipboardItem;
271 return new constructor(Object.fromEntries(blobs.map((b) => [
272 typeof b === "string" ? "text/plain" : b.type,
273 Promise.resolve(b)
274 ])));
275}
276function attachClipboardStubToView(window2) {
277 if (window2.navigator.clipboard instanceof ClipboardStub) {
278 return window2.navigator.clipboard[ClipboardStubControl];
279 }
280 const realClipboard = Object.getOwnPropertyDescriptor(window2.navigator, "clipboard");
281 let stub = new ClipboardStub();
282 const control = {
283 resetClipboardStub: () => {
284 stub = new ClipboardStub();
285 stub[ClipboardStubControl] = control;
286 },
287 detachClipboardStub: () => {
288 if (realClipboard) {
289 Object.defineProperty(window2.navigator, "clipboard", realClipboard);
290 } else {
291 Object.defineProperty(window2.navigator, "clipboard", {
292 value: void 0,
293 configurable: true
294 });
295 }
296 }
297 };
298 stub[ClipboardStubControl] = control;
299 Object.defineProperty(window2.navigator, "clipboard", {
300 get: () => stub,
301 configurable: true
302 });
303 return stub[ClipboardStubControl];
304}
305function resetClipboardStubOnView(window2) {
306 if (window2.navigator.clipboard instanceof ClipboardStub) {
307 window2.navigator.clipboard[ClipboardStubControl].resetClipboardStub();
308 }
309}
310function detachClipboardStubFromView(window2) {
311 if (window2.navigator.clipboard instanceof ClipboardStub) {
312 window2.navigator.clipboard[ClipboardStubControl].detachClipboardStub();
313 }
314}
315function readDataTransferFromClipboard(document2) {
316 return __async(this, null, function* () {
317 var _a;
318 const clipboard = (_a = document2.defaultView) == null ? void 0 : _a.navigator.clipboard;
319 const items = clipboard && (yield clipboard.read());
320 if (!items) {
321 throw new Error("The Clipboard API is unavailable.");
322 }
323 const dt = createDataTransfer();
324 for (const item of items) {
325 for (const type3 of item.types) {
326 dt.setData(type3, yield item.getType(type3).then((b) => readBlobText(b)));
327 }
328 }
329 return dt;
330 });
331}
332function writeDataTransferToClipboard(document2, clipboardData) {
333 return __async(this, null, function* () {
334 var _a;
335 const clipboard = (_a = document2.defaultView) == null ? void 0 : _a.navigator.clipboard;
336 const items = [];
337 for (let i = 0; i < clipboardData.items.length; i++) {
338 const dtItem = clipboardData.items[i];
339 const blob = getBlobFromDataTransferItem(dtItem);
340 items.push(createClipboardItem(blob));
341 }
342 const written = clipboard && (yield clipboard.write(items).then(() => true, () => false));
343 if (!written) {
344 throw new Error("The Clipboard API is unavailable.");
345 }
346 });
347}
348if (typeof afterEach === "function") {
349 afterEach(() => resetClipboardStubOnView(window));
350}
351if (typeof afterAll === "function") {
352 afterAll(() => detachClipboardStubFromView(window));
353}
354
355// src/utils/edit/isContentEditable.ts
356function isContentEditable(element) {
357 return element.hasAttribute("contenteditable") && (element.getAttribute("contenteditable") == "true" || element.getAttribute("contenteditable") == "");
358}
359function getContentEditable(node) {
360 const element = getElement(node);
361 return element && (element.closest('[contenteditable=""]') || element.closest('[contenteditable="true"]'));
362}
363function getElement(node) {
364 return node.nodeType === 1 ? node : node.parentElement;
365}
366
367// src/utils/edit/getValue.ts
368function getValue(element) {
369 if (!element) {
370 return null;
371 }
372 if (isContentEditable(element)) {
373 return element.textContent;
374 }
375 return getUIValue(element);
376}
377
378// src/utils/edit/buildTimeValue.ts
379function buildTimeValue(value) {
380 const onlyDigitsValue = value.replace(/\D/g, "");
381 if (onlyDigitsValue.length < 2) {
382 return value;
383 }
384 const firstDigit = parseInt(onlyDigitsValue[0], 10);
385 const secondDigit = parseInt(onlyDigitsValue[1], 10);
386 if (firstDigit >= 3 || firstDigit === 2 && secondDigit >= 4) {
387 let index;
388 if (firstDigit >= 3) {
389 index = 1;
390 } else {
391 index = 2;
392 }
393 return build(onlyDigitsValue, index);
394 }
395 if (value.length === 2) {
396 return value;
397 }
398 return build(onlyDigitsValue, 2);
399}
400function build(onlyDigitsValue, index) {
401 const hours = onlyDigitsValue.slice(0, index);
402 const validHours = Math.min(parseInt(hours, 10), 23);
403 const minuteCharacters = onlyDigitsValue.slice(index);
404 const parsedMinutes = parseInt(minuteCharacters, 10);
405 const validMinutes = Math.min(parsedMinutes, 59);
406 return `${validHours.toString().padStart(2, "0")}:${validMinutes.toString().padStart(2, "0")}`;
407}
408
409// src/utils/edit/isValidDateOrTimeValue.ts
410function isValidDateOrTimeValue(element, value) {
411 const clone = element.cloneNode();
412 clone.value = value;
413 return clone.value === value;
414}
415
416// src/utils/edit/maxLength.ts
417var maxLengthSupportedTypes = /* @__PURE__ */ ((maxLengthSupportedTypes2) => {
418 maxLengthSupportedTypes2["email"] = "email";
419 maxLengthSupportedTypes2["password"] = "password";
420 maxLengthSupportedTypes2["search"] = "search";
421 maxLengthSupportedTypes2["telephone"] = "telephone";
422 maxLengthSupportedTypes2["text"] = "text";
423 maxLengthSupportedTypes2["url"] = "url";
424 return maxLengthSupportedTypes2;
425})(maxLengthSupportedTypes || {});
426function getSpaceUntilMaxLength(element) {
427 const value = getValue(element);
428 if (value === null) {
429 return void 0;
430 }
431 const maxLength = getSanitizedMaxLength(element);
432 return maxLength ? maxLength - value.length : void 0;
433}
434function getSanitizedMaxLength(element) {
435 var _a;
436 if (!supportsMaxLength(element)) {
437 return void 0;
438 }
439 const attr = (_a = element.getAttribute("maxlength")) != null ? _a : "";
440 return /^\d+$/.test(attr) && Number(attr) >= 0 ? Number(attr) : void 0;
441}
442function supportsMaxLength(element) {
443 return isElementType(element, "textarea") || isElementType(element, "input") && Boolean(maxLengthSupportedTypes[element.type]);
444}
445
446// src/utils/edit/input.ts
447function isDateOrTime(element) {
448 return isElementType(element, "input") && ["date", "time"].includes(element.type);
449}
450function input(config, element, data, inputType = "insertText") {
451 const inputRange = getInputRange(element);
452 if (!inputRange) {
453 return;
454 }
455 if (!isDateOrTime(element)) {
456 const unprevented = dispatchUIEvent(config, element, "beforeinput", {
457 inputType,
458 data
459 });
460 if (!unprevented) {
461 return;
462 }
463 }
464 if ("startContainer" in inputRange) {
465 editContenteditable(config, element, inputRange, data, inputType);
466 } else {
467 editInputElement(config, element, inputRange, data, inputType);
468 }
469}
470function editContenteditable(config, element, inputRange, data, inputType) {
471 let del = false;
472 if (!inputRange.collapsed) {
473 del = true;
474 inputRange.deleteContents();
475 } else if (["deleteContentBackward", "deleteContentForward"].includes(inputType)) {
476 const nextPosition = getNextCursorPosition(inputRange.startContainer, inputRange.startOffset, inputType === "deleteContentBackward" ? -1 : 1, inputType);
477 if (nextPosition) {
478 del = true;
479 const delRange = inputRange.cloneRange();
480 if (delRange.comparePoint(nextPosition.node, nextPosition.offset) < 0) {
481 delRange.setStart(nextPosition.node, nextPosition.offset);
482 } else {
483 delRange.setEnd(nextPosition.node, nextPosition.offset);
484 }
485 delRange.deleteContents();
486 }
487 }
488 if (data) {
489 if (inputRange.endContainer.nodeType === 3) {
490 const offset = inputRange.endOffset;
491 inputRange.endContainer.insertData(offset, data);
492 inputRange.setStart(inputRange.endContainer, offset + data.length);
493 inputRange.setEnd(inputRange.endContainer, offset + data.length);
494 } else {
495 const text = element.ownerDocument.createTextNode(data);
496 inputRange.insertNode(text);
497 inputRange.setStart(text, data.length);
498 inputRange.setEnd(text, data.length);
499 }
500 }
501 if (del || data) {
502 dispatchUIEvent(config, element, "input", { inputType });
503 }
504}
505function editInputElement(config, element, inputRange, data, inputType) {
506 let dataToInsert = data;
507 const spaceUntilMaxLength = getSpaceUntilMaxLength(element);
508 if (spaceUntilMaxLength !== void 0) {
509 if (spaceUntilMaxLength > 0) {
510 dataToInsert = data.substring(0, spaceUntilMaxLength);
511 } else {
512 return;
513 }
514 }
515 const { newValue, newOffset, oldValue } = calculateNewValue(dataToInsert, element, inputRange, inputType);
516 if (newValue === oldValue && newOffset === inputRange.startOffset && newOffset === inputRange.endOffset) {
517 return;
518 }
519 if (isElementType(element, "input", { type: "number" }) && !isValidNumberInput(newValue)) {
520 return;
521 }
522 setUIValue(element, newValue);
523 setSelection({
524 focusNode: element,
525 anchorOffset: newOffset,
526 focusOffset: newOffset
527 });
528 if (isDateOrTime(element)) {
529 if (isValidDateOrTimeValue(element, newValue)) {
530 commitInput(config, element, oldValue, newValue, newOffset, {});
531 dispatchUIEvent(config, element, "change");
532 }
533 } else {
534 commitInput(config, element, oldValue, newValue, newOffset, {
535 data,
536 inputType
537 });
538 }
539}
540function calculateNewValue(inputData, node, {
541 startOffset,
542 endOffset
543}, inputType) {
544 const value = getUIValue(node);
545 const prologEnd = Math.max(0, startOffset === endOffset && inputType === "deleteContentBackward" ? startOffset - 1 : startOffset);
546 const prolog = value.substring(0, prologEnd);
547 const epilogStart = Math.min(value.length, startOffset === endOffset && inputType === "deleteContentForward" ? startOffset + 1 : endOffset);
548 const epilog = value.substring(epilogStart, value.length);
549 let newValue = `${prolog}${inputData}${epilog}`;
550 let newOffset = prologEnd + inputData.length;
551 if (isElementType(node, "input", { type: "time" })) {
552 const builtValue = buildTimeValue(newValue);
553 if (builtValue !== "" && isValidDateOrTimeValue(node, builtValue)) {
554 newValue = builtValue;
555 newOffset = builtValue.length;
556 }
557 }
558 return {
559 oldValue: value,
560 newValue,
561 newOffset
562 };
563}
564function commitInput(config, element, oldValue, newValue, newOffset, inputInit) {
565 startTrackValue(element);
566 dispatchUIEvent(config, element, "input", inputInit);
567 const tracked = endTrackValue(element);
568 if ((tracked == null ? void 0 : tracked.length) === 2 && tracked[0] === oldValue && tracked[1] === newValue) {
569 setSelection({
570 focusNode: element,
571 anchorOffset: newOffset,
572 focusOffset: newOffset
573 });
574 }
575}
576function isValidNumberInput(value) {
577 var _a, _b;
578 const valueParts = value.split("e", 2);
579 return !(/[^\d.\-e]/.test(value) || Number((_a = value.match(/-/g)) == null ? void 0 : _a.length) > 2 || Number((_b = value.match(/\./g)) == null ? void 0 : _b.length) > 1 || valueParts[1] && !/^-?\d*$/.test(valueParts[1]));
580}
581
582// src/utils/edit/isEditable.ts
583function isEditable(element) {
584 return isEditableInput(element) || isElementType(element, "textarea", { readOnly: false }) || isContentEditable(element);
585}
586var editableInputTypes = /* @__PURE__ */ ((editableInputTypes2) => {
587 editableInputTypes2["text"] = "text";
588 editableInputTypes2["date"] = "date";
589 editableInputTypes2["datetime-local"] = "datetime-local";
590 editableInputTypes2["email"] = "email";
591 editableInputTypes2["month"] = "month";
592 editableInputTypes2["number"] = "number";
593 editableInputTypes2["password"] = "password";
594 editableInputTypes2["search"] = "search";
595 editableInputTypes2["tel"] = "tel";
596 editableInputTypes2["time"] = "time";
597 editableInputTypes2["url"] = "url";
598 editableInputTypes2["week"] = "week";
599 return editableInputTypes2;
600})(editableInputTypes || {});
601function isEditableInput(element) {
602 return isElementType(element, "input", { readOnly: false }) && Boolean(editableInputTypes[element.type]);
603}
604
605// src/utils/edit/setFiles.ts
606var fakeFiles = Symbol("files and value properties are mocked");
607function setFiles(el, files) {
608 var _a;
609 (_a = el[fakeFiles]) == null ? void 0 : _a.restore();
610 const objectDescriptors = Object.getOwnPropertyDescriptors(el);
611 const prototypeDescriptors = Object.getOwnPropertyDescriptors(Object.getPrototypeOf(el));
612 function restore() {
613 Object.defineProperties(el, {
614 files: __spreadValues(__spreadValues({}, prototypeDescriptors.files), objectDescriptors.files),
615 value: __spreadValues(__spreadValues({}, prototypeDescriptors.value), objectDescriptors.value),
616 type: __spreadValues(__spreadValues({}, prototypeDescriptors.type), objectDescriptors.type)
617 });
618 }
619 el[fakeFiles] = { restore };
620 Object.defineProperties(el, {
621 files: __spreadProps(__spreadValues(__spreadValues({}, prototypeDescriptors.files), objectDescriptors.files), {
622 get: () => files
623 }),
624 value: __spreadProps(__spreadValues(__spreadValues({}, prototypeDescriptors.value), objectDescriptors.value), {
625 get: () => files.length ? `C:\\fakepath\\${files[0].name}` : "",
626 set(v) {
627 var _a2;
628 if (v === "") {
629 restore();
630 } else {
631 (_a2 = objectDescriptors.value.set) == null ? void 0 : _a2.call(el, v);
632 }
633 }
634 }),
635 type: __spreadProps(__spreadValues(__spreadValues({}, prototypeDescriptors.type), objectDescriptors.type), {
636 set(v) {
637 if (v !== "file") {
638 restore();
639 el.type = v;
640 }
641 }
642 })
643 });
644}
645
646// src/utils/misc/eventWrapper.ts
647import { getConfig } from "@testing-library/dom";
648function eventWrapper(cb) {
649 let result;
650 getConfig().eventWrapper(() => {
651 result = cb();
652 });
653 return result;
654}
655
656// src/utils/misc/isDisabled.ts
657function isDisabled(element) {
658 var _a;
659 for (let el = element; el; el = el.parentElement) {
660 if (isElementType(el, [
661 "button",
662 "input",
663 "select",
664 "textarea",
665 "optgroup",
666 "option"
667 ])) {
668 if (el.hasAttribute("disabled")) {
669 return true;
670 }
671 } else if (isElementType(el, "fieldset")) {
672 if (el.hasAttribute("disabled") && !((_a = el.querySelector(":scope > legend")) == null ? void 0 : _a.contains(element))) {
673 return true;
674 }
675 } else if (el.tagName.includes("-")) {
676 if (el.constructor.formAssociated && el.hasAttribute("disabled")) {
677 return true;
678 }
679 }
680 }
681 return false;
682}
683
684// src/utils/focus/getActiveElement.ts
685function getActiveElement(document2) {
686 const activeElement = document2.activeElement;
687 if (activeElement == null ? void 0 : activeElement.shadowRoot) {
688 return getActiveElement(activeElement.shadowRoot);
689 } else {
690 if (isDisabled(activeElement)) {
691 return document2.ownerDocument ? document2.ownerDocument.body : document2.body;
692 }
693 return activeElement;
694 }
695}
696
697// src/utils/focus/selector.ts
698var FOCUSABLE_SELECTOR = [
699 "input:not([type=hidden]):not([disabled])",
700 "button:not([disabled])",
701 "select:not([disabled])",
702 "textarea:not([disabled])",
703 '[contenteditable=""]',
704 '[contenteditable="true"]',
705 "a[href]",
706 "[tabindex]:not([disabled])"
707].join(", ");
708
709// src/utils/focus/isFocusable.ts
710function isFocusable(element) {
711 return element.matches(FOCUSABLE_SELECTOR);
712}
713
714// src/utils/focus/blur.ts
715function blur(element) {
716 if (!isFocusable(element))
717 return;
718 const wasActive = getActiveElement(element.ownerDocument) === element;
719 if (!wasActive)
720 return;
721 eventWrapper(() => element.blur());
722}
723
724// src/utils/focus/cursor.ts
725function getNextCursorPosition(node, offset, direction, inputType) {
726 if (isTextNode(node) && offset + direction >= 0 && offset + direction <= node.nodeValue.length) {
727 return { node, offset: offset + direction };
728 }
729 const nextNode = getNextCharacterContentNode(node, offset, direction);
730 if (nextNode) {
731 if (isTextNode(nextNode)) {
732 return {
733 node: nextNode,
734 offset: direction > 0 ? Math.min(1, nextNode.nodeValue.length) : Math.max(nextNode.nodeValue.length - 1, 0)
735 };
736 } else if (isElementType(nextNode, "br")) {
737 const nextPlusOne = getNextCharacterContentNode(nextNode, void 0, direction);
738 if (!nextPlusOne) {
739 if (direction < 0 && inputType === "deleteContentBackward") {
740 return {
741 node: nextNode.parentNode,
742 offset: getOffset(nextNode)
743 };
744 }
745 return void 0;
746 } else if (isTextNode(nextPlusOne)) {
747 return {
748 node: nextPlusOne,
749 offset: direction > 0 ? 0 : nextPlusOne.nodeValue.length
750 };
751 } else if (direction < 0 && isElementType(nextPlusOne, "br")) {
752 return {
753 node: nextNode.parentNode,
754 offset: getOffset(nextNode)
755 };
756 } else {
757 return {
758 node: nextPlusOne.parentNode,
759 offset: getOffset(nextPlusOne) + (direction > 0 ? 0 : 1)
760 };
761 }
762 } else {
763 return {
764 node: nextNode.parentNode,
765 offset: getOffset(nextNode) + (direction > 0 ? 1 : 0)
766 };
767 }
768 }
769}
770function getNextCharacterContentNode(node, offset, direction) {
771 const nextOffset = Number(offset) + (direction < 0 ? -1 : 0);
772 if (offset !== void 0 && isElement(node) && nextOffset >= 0 && nextOffset < node.children.length) {
773 node = node.children[nextOffset];
774 }
775 return walkNodes(node, direction === 1 ? "next" : "previous", isTreatedAsCharacterContent);
776}
777function isTreatedAsCharacterContent(node) {
778 if (isTextNode(node)) {
779 return true;
780 }
781 if (isElement(node)) {
782 if (isElementType(node, ["input", "textarea"])) {
783 return node.type !== "hidden";
784 } else if (isElementType(node, "br")) {
785 return true;
786 }
787 }
788 return false;
789}
790function getOffset(node) {
791 let i = 0;
792 while (node.previousSibling) {
793 i++;
794 node = node.previousSibling;
795 }
796 return i;
797}
798function isElement(node) {
799 return node.nodeType === 1;
800}
801function isTextNode(node) {
802 return node.nodeType === 3;
803}
804function walkNodes(node, direction, callback) {
805 var _a;
806 for (; ; ) {
807 const sibling = node[`${direction}Sibling`];
808 if (sibling) {
809 node = getDescendant(sibling, direction === "next" ? "first" : "last");
810 if (callback(node)) {
811 return node;
812 }
813 } else if (node.parentNode && (!isElement(node.parentNode) || !isContentEditable(node.parentNode) && node.parentNode !== ((_a = node.ownerDocument) == null ? void 0 : _a.body))) {
814 node = node.parentNode;
815 } else {
816 break;
817 }
818 }
819}
820function getDescendant(node, direction) {
821 while (node.hasChildNodes()) {
822 node = node[`${direction}Child`];
823 }
824 return node;
825}
826
827// src/utils/focus/selection.ts
828function setSelectionRange(element, anchorOffset, focusOffset) {
829 var _a;
830 if (hasOwnSelection(element)) {
831 return setSelection({
832 focusNode: element,
833 anchorOffset,
834 focusOffset
835 });
836 }
837 if (isContentEditable(element) && ((_a = element.firstChild) == null ? void 0 : _a.nodeType) === 3) {
838 return setSelection({
839 focusNode: element.firstChild,
840 anchorOffset,
841 focusOffset
842 });
843 }
844 throw new Error("Not implemented. The result of this interaction is unreliable.");
845}
846function hasOwnSelection(node) {
847 return isElement2(node) && (isElementType(node, "textarea") || isElementType(node, "input") && node.type in editableInputTypes);
848}
849function isElement2(node) {
850 return node.nodeType === 1;
851}
852function getTargetTypeAndSelection(node) {
853 const element = getElement2(node);
854 if (element && hasOwnSelection(element)) {
855 return {
856 type: "input",
857 selection: getUISelection(element)
858 };
859 }
860 const selection = element == null ? void 0 : element.ownerDocument.getSelection();
861 const isCE = getContentEditable(node) && (selection == null ? void 0 : selection.anchorNode) && getContentEditable(selection.anchorNode);
862 return {
863 type: isCE ? "contenteditable" : "default",
864 selection
865 };
866}
867function getElement2(node) {
868 return node.nodeType === 1 ? node : node.parentElement;
869}
870function updateSelectionOnFocus(element) {
871 var _a;
872 const selection = element.ownerDocument.getSelection();
873 if (!(selection == null ? void 0 : selection.focusNode)) {
874 return;
875 }
876 if (hasOwnSelection(element)) {
877 const contenteditable = getContentEditable(selection.focusNode);
878 if (contenteditable) {
879 if (!selection.isCollapsed) {
880 const focusNode = ((_a = contenteditable.firstChild) == null ? void 0 : _a.nodeType) === 3 ? contenteditable.firstChild : contenteditable;
881 selection.setBaseAndExtent(focusNode, 0, focusNode, 0);
882 }
883 } else {
884 selection.setBaseAndExtent(element, 0, element, 0);
885 }
886 }
887}
888function getInputRange(focusNode) {
889 var _a;
890 const typeAndSelection = getTargetTypeAndSelection(focusNode);
891 if (typeAndSelection.type === "input") {
892 return typeAndSelection.selection;
893 } else if (typeAndSelection.type === "contenteditable") {
894 return (_a = typeAndSelection.selection) == null ? void 0 : _a.getRangeAt(0);
895 }
896}
897function setSelection({
898 focusNode,
899 focusOffset,
900 anchorNode = focusNode,
901 anchorOffset = focusOffset
902}) {
903 var _a, _b;
904 const typeAndSelection = getTargetTypeAndSelection(focusNode);
905 if (typeAndSelection.type === "input") {
906 return setUISelection(focusNode, {
907 anchorOffset,
908 focusOffset
909 });
910 }
911 (_b = (_a = anchorNode.ownerDocument) == null ? void 0 : _a.getSelection()) == null ? void 0 : _b.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
912}
913function moveSelection(node, direction) {
914 if (hasOwnSelection(node)) {
915 const selection = getUISelection(node);
916 setSelection({
917 focusNode: node,
918 focusOffset: selection.startOffset === selection.endOffset ? selection.focusOffset + direction : direction < 0 ? selection.startOffset : selection.endOffset
919 });
920 } else {
921 const selection = node.ownerDocument.getSelection();
922 if (!selection) {
923 return;
924 }
925 if (selection.isCollapsed) {
926 const nextPosition = getNextCursorPosition(selection.focusNode, selection.focusOffset, direction);
927 if (nextPosition) {
928 setSelection({
929 focusNode: nextPosition.node,
930 focusOffset: nextPosition.offset
931 });
932 }
933 } else {
934 selection[direction < 0 ? "collapseToStart" : "collapseToEnd"]();
935 }
936 }
937}
938
939// src/utils/focus/copySelection.ts
940function copySelection(target) {
941 const data = hasOwnSelection(target) ? { "text/plain": readSelectedValueFromInput(target) } : { "text/plain": String(target.ownerDocument.getSelection()) };
942 const dt = createDataTransfer();
943 for (const type3 in data) {
944 if (data[type3]) {
945 dt.setData(type3, data[type3]);
946 }
947 }
948 return dt;
949}
950function readSelectedValueFromInput(target) {
951 const sel = getUISelection(target);
952 const val = getUIValue(target);
953 return val.substring(sel.startOffset, sel.endOffset);
954}
955
956// src/utils/misc/findClosest.ts
957function findClosest(element, callback) {
958 let el = element;
959 do {
960 if (callback(el)) {
961 return el;
962 }
963 el = el.parentElement;
964 } while (el && el !== element.ownerDocument.body);
965 return void 0;
966}
967
968// src/utils/focus/focus.ts
969function focus(element) {
970 const target = findClosest(element, isFocusable);
971 const activeElement = getActiveElement(element.ownerDocument);
972 if ((target != null ? target : element.ownerDocument.body) === activeElement) {
973 return;
974 } else if (target) {
975 eventWrapper(() => target.focus());
976 } else {
977 eventWrapper(() => activeElement == null ? void 0 : activeElement.blur());
978 }
979 updateSelectionOnFocus(target != null ? target : element.ownerDocument.body);
980}
981
982// src/utils/misc/isVisible.ts
983import { getWindowFromNode } from "@testing-library/dom/dist/helpers.js";
984function isVisible(element) {
985 const window2 = getWindowFromNode(element);
986 for (let el = element; el == null ? void 0 : el.ownerDocument; el = el.parentElement) {
987 const { display, visibility } = window2.getComputedStyle(el);
988 if (display === "none") {
989 return false;
990 }
991 if (visibility === "hidden") {
992 return false;
993 }
994 }
995 return true;
996}
997
998// src/utils/focus/getTabDestination.ts
999function getTabDestination(activeElement, shift) {
1000 const document2 = activeElement.ownerDocument;
1001 const focusableElements = document2.querySelectorAll(FOCUSABLE_SELECTOR);
1002 const enabledElements = Array.from(focusableElements).filter((el) => el === activeElement || el.getAttribute("tabindex") !== "-1" && !isDisabled(el) && isVisible(el));
1003 if (activeElement.getAttribute("tabindex") !== "-1") {
1004 enabledElements.sort((a, b) => {
1005 const i = Number(a.getAttribute("tabindex"));
1006 const j = Number(b.getAttribute("tabindex"));
1007 if (i === j) {
1008 return 0;
1009 } else if (i === 0) {
1010 return 1;
1011 } else if (j === 0) {
1012 return -1;
1013 }
1014 return i - j;
1015 });
1016 }
1017 const checkedRadio = {};
1018 let prunedElements = [document2.body];
1019 const activeRadioGroup = isElementType(activeElement, "input", {
1020 type: "radio"
1021 }) ? activeElement.name : void 0;
1022 enabledElements.forEach((currentElement) => {
1023 const el = currentElement;
1024 if (isElementType(el, "input", { type: "radio" }) && el.name) {
1025 if (el === activeElement) {
1026 prunedElements.push(el);
1027 return;
1028 } else if (el.name === activeRadioGroup) {
1029 return;
1030 }
1031 if (el.checked) {
1032 prunedElements = prunedElements.filter((e) => !isElementType(e, "input", { type: "radio", name: el.name }));
1033 prunedElements.push(el);
1034 checkedRadio[el.name] = el;
1035 return;
1036 }
1037 if (typeof checkedRadio[el.name] !== "undefined") {
1038 return;
1039 }
1040 }
1041 prunedElements.push(el);
1042 });
1043 const currentIndex = prunedElements.findIndex((el) => el === activeElement);
1044 const nextIndex = shift ? currentIndex - 1 : currentIndex + 1;
1045 const defaultIndex = shift ? prunedElements.length - 1 : 0;
1046 return prunedElements[nextIndex] || prunedElements[defaultIndex];
1047}
1048
1049// src/utils/focus/selectAll.ts
1050function selectAll(target) {
1051 var _a;
1052 if (isElementType(target, "textarea") || isElementType(target, "input") && target.type in editableInputTypes) {
1053 return setSelection({
1054 focusNode: target,
1055 anchorOffset: 0,
1056 focusOffset: getUIValue(target).length
1057 });
1058 }
1059 const focusNode = (_a = getContentEditable(target)) != null ? _a : target.ownerDocument.body;
1060 setSelection({
1061 focusNode,
1062 anchorOffset: 0,
1063 focusOffset: focusNode.childNodes.length
1064 });
1065}
1066function isAllSelected(target) {
1067 var _a;
1068 if (isElementType(target, "textarea") || isElementType(target, "input") && target.type in editableInputTypes) {
1069 return getUISelection(target).startOffset === 0 && getUISelection(target).endOffset === getUIValue(target).length;
1070 }
1071 const focusNode = (_a = getContentEditable(target)) != null ? _a : target.ownerDocument.body;
1072 const selection = target.ownerDocument.getSelection();
1073 return (selection == null ? void 0 : selection.anchorNode) === focusNode && selection.focusNode === focusNode && selection.anchorOffset === 0 && selection.focusOffset === focusNode.childNodes.length;
1074}
1075
1076// src/utils/keyboard/getKeyEventProps.ts
1077function getKeyEventProps(keyDef) {
1078 return {
1079 key: keyDef.key,
1080 code: keyDef.code
1081 };
1082}
1083
1084// src/utils/keyboard/getUIEventModifiers.ts
1085function getUIEventModifiers(keyboardState) {
1086 return {
1087 altKey: keyboardState.modifiers.Alt,
1088 ctrlKey: keyboardState.modifiers.Control,
1089 metaKey: keyboardState.modifiers.Meta,
1090 shiftKey: keyboardState.modifiers.Shift,
1091 modifierAltGraph: keyboardState.modifiers.AltGraph,
1092 modifierCapsLock: keyboardState.modifiers.CapsLock,
1093 modifierFn: keyboardState.modifiers.Fn,
1094 modifierFnLock: keyboardState.modifiers.FnLock,
1095 modifierNumLock: keyboardState.modifiers.NumLock,
1096 modifierScrollLock: keyboardState.modifiers.ScrollLock,
1097 modifierSymbol: keyboardState.modifiers.Symbol,
1098 modifierSymbolLock: keyboardState.modifiers.SymbolLock
1099 };
1100}
1101
1102// src/utils/keyDef/readNextDescriptor.ts
1103var bracketDict = /* @__PURE__ */ ((bracketDict2) => {
1104 bracketDict2["{"] = "}";
1105 bracketDict2["["] = "]";
1106 return bracketDict2;
1107})(bracketDict || {});
1108function readNextDescriptor(text) {
1109 let pos = 0;
1110 const startBracket = text[pos] in bracketDict ? text[pos] : "";
1111 pos += startBracket.length;
1112 const isEscapedChar = new RegExp(`^\\${startBracket}{2}`).test(text);
1113 const type3 = isEscapedChar ? "" : startBracket;
1114 return __spreadValues({
1115 type: type3
1116 }, type3 === "" ? readPrintableChar(text, pos) : readTag(text, pos, type3));
1117}
1118function readPrintableChar(text, pos) {
1119 const descriptor = text[pos];
1120 assertDescriptor(descriptor, text, pos);
1121 pos += descriptor.length;
1122 return {
1123 consumedLength: pos,
1124 descriptor,
1125 releasePrevious: false,
1126 releaseSelf: true,
1127 repeat: 1
1128 };
1129}
1130function readTag(text, pos, startBracket) {
1131 var _a, _b, _c;
1132 const releasePreviousModifier = text[pos] === "/" ? "/" : "";
1133 pos += releasePreviousModifier.length;
1134 const escapedDescriptor = startBracket === "{" && text[pos] === "\\";
1135 pos += Number(escapedDescriptor);
1136 const descriptor = escapedDescriptor ? text[pos] : (_a = text.slice(pos).match(startBracket === "{" ? /^\w+|^[^}>/]/ : /^\w+/)) == null ? void 0 : _a[0];
1137 assertDescriptor(descriptor, text, pos);
1138 pos += descriptor.length;
1139 const repeatModifier = (_c = (_b = text.slice(pos).match(/^>\d+/)) == null ? void 0 : _b[0]) != null ? _c : "";
1140 pos += repeatModifier.length;
1141 const releaseSelfModifier = text[pos] === "/" || !repeatModifier && text[pos] === ">" ? text[pos] : "";
1142 pos += releaseSelfModifier.length;
1143 const expectedEndBracket = bracketDict[startBracket];
1144 const endBracket = text[pos] === expectedEndBracket ? expectedEndBracket : "";
1145 if (!endBracket) {
1146 throw new Error(getErrorMessage([
1147 !repeatModifier && "repeat modifier",
1148 !releaseSelfModifier && "release modifier",
1149 `"${expectedEndBracket}"`
1150 ].filter(Boolean).join(" or "), text[pos], text));
1151 }
1152 pos += endBracket.length;
1153 return {
1154 consumedLength: pos,
1155 descriptor,
1156 releasePrevious: !!releasePreviousModifier,
1157 repeat: repeatModifier ? Math.max(Number(repeatModifier.substr(1)), 1) : 1,
1158 releaseSelf: hasReleaseSelf(releaseSelfModifier, repeatModifier)
1159 };
1160}
1161function assertDescriptor(descriptor, text, pos) {
1162 if (!descriptor) {
1163 throw new Error(getErrorMessage("key descriptor", text[pos], text));
1164 }
1165}
1166function hasReleaseSelf(releaseSelfModifier, repeatModifier) {
1167 if (releaseSelfModifier) {
1168 return releaseSelfModifier === "/";
1169 }
1170 if (repeatModifier) {
1171 return false;
1172 }
1173}
1174function getErrorMessage(expected, found, text) {
1175 return `Expected ${expected} but found "${found != null ? found : ""}" in "${text}"
1176 See https://github.com/testing-library/user-event/blob/main/README.md#keyboardtext-options
1177 for more information about how userEvent parses your input.`;
1178}
1179
1180// src/utils/misc/cloneEvent.ts
1181function cloneEvent(event) {
1182 return new event.constructor(event.type, event);
1183}
1184
1185// src/utils/misc/getDocumentFromNode.ts
1186function getDocumentFromNode(el) {
1187 return isDocument(el) ? el : el.ownerDocument;
1188}
1189function isDocument(node) {
1190 return node.nodeType === 9;
1191}
1192
1193// src/utils/misc/isDescendantOrSelf.ts
1194function isDescendantOrSelf(potentialDescendant, potentialAncestor) {
1195 let el = potentialDescendant;
1196 do {
1197 if (el === potentialAncestor) {
1198 return true;
1199 }
1200 el = el.parentElement;
1201 } while (el);
1202 return false;
1203}
1204
1205// src/utils/misc/level.ts
1206var Level = Symbol("Api level refs");
1207function setLevelRef(config, level) {
1208 var _a;
1209 (_a = config[Level]) != null ? _a : config[Level] = {};
1210 config[Level][level] = {};
1211}
1212function getLevelRef(config, level) {
1213 var _a;
1214 return (_a = config[Level]) == null ? void 0 : _a[level];
1215}
1216
1217// src/utils/misc/wait.ts
1218function wait(time) {
1219 return new Promise((resolve) => setTimeout(() => resolve(), time));
1220}
1221
1222// src/utils/pointer/cssPointerEvents.ts
1223import { getWindowFromNode as getWindowFromNode2 } from "@testing-library/dom/dist/helpers.js";
1224
1225// src/keyboard/keyMap.ts
1226var defaultKeyMap = [
1227 ..."0123456789".split("").map((c) => ({ code: `Digit${c}`, key: c })),
1228 ...")!@#$%^&*(".split("").map((c, i) => ({ code: `Digit${i}`, key: c, shiftKey: true })),
1229 ..."abcdefghijklmnopqrstuvwxyz".split("").map((c) => ({ code: `Key${c.toUpperCase()}`, key: c })),
1230 ..."ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("").map((c) => ({ code: `Key${c}`, key: c, shiftKey: true })),
1231 { code: "Space", key: " " },
1232 { code: "AltLeft", key: "Alt", location: 1 /* LEFT */ },
1233 { code: "AltRight", key: "Alt", location: 2 /* RIGHT */ },
1234 {
1235 code: "ShiftLeft",
1236 key: "Shift",
1237 location: 1 /* LEFT */
1238 },
1239 {
1240 code: "ShiftRight",
1241 key: "Shift",
1242 location: 2 /* RIGHT */
1243 },
1244 {
1245 code: "ControlLeft",
1246 key: "Control",
1247 location: 1 /* LEFT */
1248 },
1249 {
1250 code: "ControlRight",
1251 key: "Control",
1252 location: 2 /* RIGHT */
1253 },
1254 { code: "MetaLeft", key: "Meta", location: 1 /* LEFT */ },
1255 {
1256 code: "MetaRight",
1257 key: "Meta",
1258 location: 2 /* RIGHT */
1259 },
1260 { code: "OSLeft", key: "OS", location: 1 /* LEFT */ },
1261 { code: "OSRight", key: "OS", location: 2 /* RIGHT */ },
1262 { code: "Tab", key: "Tab" },
1263 { code: "CapsLock", key: "CapsLock" },
1264 { code: "Backspace", key: "Backspace" },
1265 { code: "Enter", key: "Enter" },
1266 { code: "Escape", key: "Escape" },
1267 { code: "ArrowUp", key: "ArrowUp" },
1268 { code: "ArrowDown", key: "ArrowDown" },
1269 { code: "ArrowLeft", key: "ArrowLeft" },
1270 { code: "ArrowRight", key: "ArrowRight" },
1271 { code: "Home", key: "Home" },
1272 { code: "End", key: "End" },
1273 { code: "Delete", key: "Delete" },
1274 { code: "PageUp", key: "PageUp" },
1275 { code: "PageDown", key: "PageDown" },
1276 { code: "Fn", key: "Fn" },
1277 { code: "Symbol", key: "Symbol" },
1278 { code: "AltRight", key: "AltGraph" }
1279];
1280
1281// src/pointer/keyMap.ts
1282var defaultKeyMap2 = [
1283 { name: "MouseLeft", pointerType: "mouse", button: "primary" },
1284 { name: "MouseRight", pointerType: "mouse", button: "secondary" },
1285 { name: "MouseMiddle", pointerType: "mouse", button: "auxiliary" },
1286 { name: "TouchA", pointerType: "touch" },
1287 { name: "TouchB", pointerType: "touch" },
1288 { name: "TouchC", pointerType: "touch" }
1289];
1290
1291// src/options.ts
1292var PointerEventsCheckLevel = /* @__PURE__ */ ((PointerEventsCheckLevel2) => {
1293 PointerEventsCheckLevel2[PointerEventsCheckLevel2["EachTrigger"] = 4] = "EachTrigger";
1294 PointerEventsCheckLevel2[PointerEventsCheckLevel2["EachApiCall"] = 2] = "EachApiCall";
1295 PointerEventsCheckLevel2[PointerEventsCheckLevel2["EachTarget"] = 1] = "EachTarget";
1296 PointerEventsCheckLevel2[PointerEventsCheckLevel2["Never"] = 0] = "Never";
1297 return PointerEventsCheckLevel2;
1298})(PointerEventsCheckLevel || {});
1299var defaultOptionsDirect = {
1300 applyAccept: true,
1301 autoModify: true,
1302 delay: 0,
1303 document: global.document,
1304 keyboardMap: defaultKeyMap,
1305 pointerMap: defaultKeyMap2,
1306 pointerEventsCheck: 2 /* EachApiCall */,
1307 skipAutoClose: false,
1308 skipClick: false,
1309 skipHover: false,
1310 writeToClipboard: false
1311};
1312var defaultOptionsSetup = __spreadProps(__spreadValues({}, defaultOptionsDirect), {
1313 writeToClipboard: true
1314});
1315
1316// src/utils/pointer/cssPointerEvents.ts
1317function hasPointerEvents(element) {
1318 const window2 = getWindowFromNode2(element);
1319 for (let el = element; el == null ? void 0 : el.ownerDocument; el = el.parentElement) {
1320 const pointerEvents = window2.getComputedStyle(el).pointerEvents;
1321 if (pointerEvents && !["inherit", "unset"].includes(pointerEvents)) {
1322 return pointerEvents !== "none";
1323 }
1324 }
1325 return true;
1326}
1327var PointerEventsCheck = Symbol("Last check for pointer-events");
1328function assertPointerEvents(config, element) {
1329 const lastCheck = element[PointerEventsCheck];
1330 const needsCheck = config.pointerEventsCheck !== 0 /* Never */ && (!lastCheck || hasBitFlag(config.pointerEventsCheck, 2 /* EachApiCall */) && lastCheck[1 /* Call */] !== getLevelRef(config, 1 /* Call */) || hasBitFlag(config.pointerEventsCheck, 4 /* EachTrigger */) && lastCheck[2 /* Trigger */] !== getLevelRef(config, 2 /* Trigger */));
1331 if (!needsCheck) {
1332 return;
1333 }
1334 const result = hasPointerEvents(element);
1335 element[PointerEventsCheck] = {
1336 [1 /* Call */]: getLevelRef(config, 1 /* Call */),
1337 [2 /* Trigger */]: getLevelRef(config, 2 /* Trigger */),
1338 result
1339 };
1340 if (!result) {
1341 throw new Error('Unable to perform pointer interaction as the element has or inherits pointer-events set to "none".');
1342 }
1343}
1344function hasBitFlag(conf, flag) {
1345 return (conf & flag) > 0;
1346}
1347
1348// src/utils/pointer/mouseButtons.ts
1349var MouseButton = {
1350 primary: 0,
1351 secondary: 1,
1352 auxiliary: 2,
1353 back: 3,
1354 X1: 3,
1355 forward: 4,
1356 X2: 4
1357};
1358var MouseButtonFlip = {
1359 auxiliary: 1,
1360 secondary: 2,
1361 1: 2,
1362 2: 1
1363};
1364function getMouseButton(button) {
1365 if (button in MouseButtonFlip) {
1366 return MouseButtonFlip[button];
1367 }
1368 return typeof button === "number" ? button : MouseButton[button];
1369}
1370function getMouseButtons(...buttons) {
1371 let v = 0;
1372 for (const t of buttons) {
1373 const pos = typeof t === "number" ? t : MouseButton[t];
1374 v |= __pow(2, pos);
1375 }
1376 return v;
1377}
1378
1379// src/event/createEvent.ts
1380import { createEvent as createEventBase } from "@testing-library/dom";
1381
1382// src/event/eventMap.ts
1383import { eventMap as baseEventMap } from "@testing-library/dom/dist/event-map.js";
1384var eventMap = __spreadProps(__spreadValues({}, baseEventMap), {
1385 beforeInput: {
1386 EventType: "InputEvent",
1387 defaultInit: { bubbles: true, cancelable: true, composed: true }
1388 }
1389});
1390var eventMapKeys = Object.fromEntries(Object.keys(eventMap).map((k) => [k.toLowerCase(), k]));
1391
1392// src/event/eventTypes.ts
1393import { eventMap as eventMap2 } from "@testing-library/dom/dist/event-map.js";
1394var eventKeys = Object.fromEntries(Object.keys(eventMap2).map((k) => [k.toLowerCase(), k]));
1395function getEventClass(type3) {
1396 return type3 in eventKeys ? eventMap2[eventKeys[type3]].EventType : "Event";
1397}
1398var mouseEvents = ["MouseEvent", "PointerEvent"];
1399function isMouseEvent(type3) {
1400 return mouseEvents.includes(getEventClass(type3));
1401}
1402function isKeyboardEvent(type3) {
1403 return getEventClass(type3) === "KeyboardEvent";
1404}
1405
1406// src/event/createEvent.ts
1407function createEvent(type3, target, init) {
1408 const event = createEventBase(type3, target, init, eventMap[eventMapKeys[type3]]);
1409 if (isMouseEvent(type3) && init) {
1410 assignPositionInit(event, init);
1411 assignPointerInit(event, init);
1412 }
1413 return event;
1414}
1415function assignProps(obj, props) {
1416 for (const [key, value] of Object.entries(props)) {
1417 Object.defineProperty(obj, key, { get: () => value });
1418 }
1419}
1420function assignPositionInit(obj, {
1421 x,
1422 y,
1423 clientX,
1424 clientY,
1425 offsetX,
1426 offsetY,
1427 pageX,
1428 pageY,
1429 screenX,
1430 screenY
1431}) {
1432 var _a, _b, _c, _d;
1433 assignProps(obj, {
1434 x: (_a = x != null ? x : clientX) != null ? _a : 0,
1435 y: (_b = y != null ? y : clientY) != null ? _b : 0,
1436 clientX: (_c = x != null ? x : clientX) != null ? _c : 0,
1437 clientY: (_d = y != null ? y : clientY) != null ? _d : 0,
1438 offsetX: offsetX != null ? offsetX : 0,
1439 offsetY: offsetY != null ? offsetY : 0,
1440 pageX: pageX != null ? pageX : 0,
1441 pageY: pageY != null ? pageY : 0,
1442 screenX: screenX != null ? screenX : 0,
1443 screenY: screenY != null ? screenY : 0
1444 });
1445}
1446function assignPointerInit(obj, { isPrimary, pointerId, pointerType }) {
1447 assignProps(obj, {
1448 isPrimary,
1449 pointerId,
1450 pointerType
1451 });
1452}
1453
1454// src/event/behavior/registry.ts
1455var behavior = {};
1456
1457// src/event/behavior/click.ts
1458behavior.click = (event, target, config) => {
1459 const context = target.closest("button,input,label,textarea");
1460 const control = context && isElementType(context, "label") && context.control;
1461 if (control) {
1462 return () => {
1463 if (isFocusable(control)) {
1464 focus(control);
1465 }
1466 dispatchEvent(config, control, cloneEvent(event));
1467 };
1468 } else if (isElementType(target, "input", { type: "file" })) {
1469 return () => {
1470 blur(target);
1471 target.dispatchEvent(new Event("fileDialog"));
1472 focus(target);
1473 };
1474 }
1475};
1476
1477// src/event/behavior/cut.ts
1478behavior.cut = (event, target, config) => {
1479 return () => {
1480 if (isEditable(target)) {
1481 input(config, target, "", "deleteByCut");
1482 }
1483 };
1484};
1485
1486// src/event/behavior/keydown.ts
1487behavior.keydown = (event, target, config) => {
1488 var _a, _b;
1489 return (_b = (_a = keydownBehavior[event.key]) == null ? void 0 : _a.call(keydownBehavior, event, target, config)) != null ? _b : combinationBehavior(event, target, config);
1490};
1491var keydownBehavior = {
1492 ArrowLeft: (event, target) => () => moveSelection(target, -1),
1493 ArrowRight: (event, target) => () => moveSelection(target, 1),
1494 Backspace: (event, target, config) => {
1495 if (isEditable(target)) {
1496 return () => {
1497 input(config, target, "", "deleteContentBackward");
1498 };
1499 }
1500 },
1501 Delete: (event, target, config) => {
1502 if (isEditable(target)) {
1503 return () => {
1504 input(config, target, "", "deleteContentForward");
1505 };
1506 }
1507 },
1508 End: (event, target) => {
1509 if (isElementType(target, ["input", "textarea"]) || isContentEditable(target)) {
1510 return () => {
1511 var _a, _b;
1512 const newPos = (_b = (_a = getValue(target)) == null ? void 0 : _a.length) != null ? _b : 0;
1513 setSelectionRange(target, newPos, newPos);
1514 };
1515 }
1516 },
1517 Home: (event, target) => {
1518 if (isElementType(target, ["input", "textarea"]) || isContentEditable(target)) {
1519 return () => {
1520 setSelectionRange(target, 0, 0);
1521 };
1522 }
1523 },
1524 PageDown: (event, target) => {
1525 if (isElementType(target, ["input"])) {
1526 return () => {
1527 const newPos = getValue(target).length;
1528 setSelectionRange(target, newPos, newPos);
1529 };
1530 }
1531 },
1532 PageUp: (event, target) => {
1533 if (isElementType(target, ["input"])) {
1534 return () => {
1535 setSelectionRange(target, 0, 0);
1536 };
1537 }
1538 },
1539 Tab: (event, target, { keyboardState }) => {
1540 return () => {
1541 const dest = getTabDestination(target, keyboardState.modifiers.Shift);
1542 focus(dest);
1543 if (hasOwnSelection(dest)) {
1544 setUISelection(dest, {
1545 anchorOffset: 0,
1546 focusOffset: dest.value.length
1547 });
1548 }
1549 };
1550 }
1551};
1552var combinationBehavior = (event, target, config) => {
1553 if (event.code === "KeyA" && config.keyboardState.modifiers.Control) {
1554 return () => selectAll(target);
1555 }
1556};
1557
1558// src/event/behavior/keypress.ts
1559behavior.keypress = (event, target, config) => {
1560 if (event.key === "Enter") {
1561 if (isElementType(target, "button") || isElementType(target, "input") && ClickInputOnEnter.includes(target.type) || isElementType(target, "a") && Boolean(target.href)) {
1562 return () => {
1563 dispatchUIEvent(config, target, "click");
1564 };
1565 } else if (isElementType(target, "input")) {
1566 const form = target.form;
1567 const submit = form == null ? void 0 : form.querySelector('input[type="submit"], button:not([type]), button[type="submit"]');
1568 if (submit) {
1569 return () => dispatchUIEvent(config, submit, "click");
1570 } else if (form && SubmitSingleInputOnEnter.includes(target.type) && form.querySelectorAll("input").length === 1) {
1571 return () => dispatchUIEvent(config, form, "submit");
1572 } else {
1573 return;
1574 }
1575 }
1576 }
1577 if (isEditable(target)) {
1578 const inputType = event.key === "Enter" ? isContentEditable(target) && !config.keyboardState.modifiers.Shift ? "insertParagraph" : "insertLineBreak" : "insertText";
1579 const inputData = event.key === "Enter" ? "\n" : event.key;
1580 return () => input(config, target, inputData, inputType);
1581 }
1582};
1583var ClickInputOnEnter = [
1584 "button",
1585 "color",
1586 "file",
1587 "image",
1588 "reset",
1589 "submit"
1590];
1591var SubmitSingleInputOnEnter = [
1592 "email",
1593 "month",
1594 "password",
1595 "search",
1596 "tel",
1597 "text",
1598 "url",
1599 "week"
1600];
1601
1602// src/event/behavior/keyup.ts
1603behavior.keyup = (event, target, config) => {
1604 var _a;
1605 return (_a = keyupBehavior[event.key]) == null ? void 0 : _a.call(keyupBehavior, event, target, config);
1606};
1607var keyupBehavior = {
1608 " ": (event, target, config) => {
1609 if (isClickableInput(target)) {
1610 return () => dispatchUIEvent(config, target, "click");
1611 }
1612 }
1613};
1614
1615// src/event/behavior/paste.ts
1616behavior.paste = (event, target, config) => {
1617 if (isEditable(target)) {
1618 return () => {
1619 var _a;
1620 const insertData = (_a = event.clipboardData) == null ? void 0 : _a.getData("text");
1621 if (insertData) {
1622 input(config, target, insertData, "insertFromPaste");
1623 }
1624 };
1625 }
1626};
1627
1628// src/event/wrapEvent.ts
1629import { getConfig as getConfig2 } from "@testing-library/dom";
1630function wrapEvent(cb, _element) {
1631 return getConfig2().eventWrapper(cb);
1632}
1633
1634// src/event/dispatchEvent.ts
1635function dispatchEvent(config, target, event, preventDefault = false) {
1636 var _a, _b;
1637 const type3 = event.type;
1638 const behaviorImplementation = preventDefault ? () => {
1639 } : (_b = (_a = behavior)[type3]) == null ? void 0 : _b.call(_a, event, target, config);
1640 if (behaviorImplementation) {
1641 event.preventDefault();
1642 let defaultPrevented = false;
1643 Object.defineProperty(event, "defaultPrevented", {
1644 get: () => defaultPrevented
1645 });
1646 Object.defineProperty(event, "preventDefault", {
1647 value: () => {
1648 defaultPrevented = event.cancelable;
1649 }
1650 });
1651 wrapEvent(() => target.dispatchEvent(event), target);
1652 if (!defaultPrevented) {
1653 behaviorImplementation();
1654 }
1655 return !defaultPrevented;
1656 }
1657 return wrapEvent(() => target.dispatchEvent(event), target);
1658}
1659
1660// src/event/index.ts
1661function dispatchUIEvent(config, target, type3, init, preventDefault = false) {
1662 if (isMouseEvent(type3) || isKeyboardEvent(type3)) {
1663 init = __spreadValues(__spreadValues({}, init), getUIEventModifiers(config.keyboardState));
1664 }
1665 const event = createEvent(type3, target, init);
1666 return dispatchEvent(config, target, event, preventDefault);
1667}
1668function bindDispatchUIEvent(config) {
1669 return dispatchUIEvent.bind(void 0, config);
1670}
1671
1672// src/document/interceptor.ts
1673var Interceptor = Symbol("Interceptor for programmatical calls");
1674function prepareInterceptor(element, propName, interceptorImpl) {
1675 const prototypeDescriptor = Object.getOwnPropertyDescriptor(element.constructor.prototype, propName);
1676 const objectDescriptor = Object.getOwnPropertyDescriptor(element, propName);
1677 const target = (prototypeDescriptor == null ? void 0 : prototypeDescriptor.set) ? "set" : "value";
1678 if (typeof (prototypeDescriptor == null ? void 0 : prototypeDescriptor[target]) !== "function" || prototypeDescriptor[target][Interceptor]) {
1679 return;
1680 }
1681 function intercept(...args) {
1682 const { applyNative = true, realArgs } = interceptorImpl.call(this, ...args);
1683 const realFunc = (!applyNative && objectDescriptor || prototypeDescriptor)[target];
1684 if (target === "set") {
1685 realFunc.call(this, realArgs);
1686 } else {
1687 realFunc.call(this, ...realArgs);
1688 }
1689 }
1690 ;
1691 intercept[Interceptor] = Interceptor;
1692 Object.defineProperty(element, propName, __spreadProps(__spreadValues({}, objectDescriptor != null ? objectDescriptor : prototypeDescriptor), {
1693 [target]: intercept
1694 }));
1695}
1696
1697// src/document/selection.ts
1698var UISelection = Symbol("Displayed selection in UI");
1699function prepareSelectionInterceptor(element) {
1700 prepareInterceptor(element, "setSelectionRange", function interceptorImpl(start, end, direction = "none") {
1701 const isUI = start && typeof start === "object" && start[UISelection];
1702 if (!isUI) {
1703 this[UISelection] = void 0;
1704 }
1705 return {
1706 realArgs: [Number(start), end, direction]
1707 };
1708 });
1709 prepareInterceptor(element, "selectionStart", function interceptorImpl(v) {
1710 this[UISelection] = void 0;
1711 return { realArgs: v };
1712 });
1713 prepareInterceptor(element, "selectionEnd", function interceptorImpl(v) {
1714 this[UISelection] = void 0;
1715 return { realArgs: v };
1716 });
1717}
1718function setUISelection(element, {
1719 focusOffset: focusOffsetParam,
1720 anchorOffset: anchorOffsetParam = focusOffsetParam
1721}, mode = "replace") {
1722 const valueLength = getUIValue(element).length;
1723 const sanitizeOffset = (o) => Math.max(0, Math.min(valueLength, o));
1724 const anchorOffset = mode === "replace" || element[UISelection] === void 0 ? sanitizeOffset(anchorOffsetParam) : element[UISelection].anchorOffset;
1725 const focusOffset = sanitizeOffset(focusOffsetParam);
1726 const startOffset = Math.min(anchorOffset, focusOffset);
1727 const endOffset = Math.max(anchorOffset, focusOffset);
1728 element[UISelection] = {
1729 anchorOffset,
1730 focusOffset
1731 };
1732 if (element.selectionStart === startOffset && element.selectionEnd === endOffset) {
1733 return;
1734 }
1735 const startObj = new Number(startOffset);
1736 startObj[UISelection] = UISelection;
1737 try {
1738 element.setSelectionRange(startObj, endOffset);
1739 } catch (e) {
1740 }
1741}
1742function getUISelection(element) {
1743 var _a, _b, _c;
1744 const sel = (_c = element[UISelection]) != null ? _c : {
1745 anchorOffset: (_a = element.selectionStart) != null ? _a : 0,
1746 focusOffset: (_b = element.selectionEnd) != null ? _b : 0
1747 };
1748 return __spreadProps(__spreadValues({}, sel), {
1749 startOffset: Math.min(sel.anchorOffset, sel.focusOffset),
1750 endOffset: Math.max(sel.anchorOffset, sel.focusOffset)
1751 });
1752}
1753function clearUISelection(element) {
1754 element[UISelection] = void 0;
1755}
1756
1757// src/document/value.ts
1758var UIValue = Symbol("Displayed value in UI");
1759var InitialValue = Symbol("Initial value to compare on blur");
1760var TrackChanges = Symbol("Track programmatic changes for React workaround");
1761function valueInterceptor(v) {
1762 const isUI = typeof v === "object" && v[UIValue];
1763 this[UIValue] = isUI ? String(v) : void 0;
1764 if (!isUI) {
1765 trackValue(this, String(v));
1766 this[InitialValue] = String(v);
1767 clearUISelection(this);
1768 }
1769 return {
1770 applyNative: !!isUI,
1771 realArgs: String(v)
1772 };
1773}
1774function prepareValueInterceptor(element) {
1775 prepareInterceptor(element, "value", valueInterceptor);
1776}
1777function setUIValue(element, value) {
1778 element.value = {
1779 [UIValue]: UIValue,
1780 toString: () => value
1781 };
1782}
1783function getUIValue(element) {
1784 return element[UIValue] === void 0 ? element.value : String(element[UIValue]);
1785}
1786function setInitialValue(element) {
1787 element[InitialValue] = element.value;
1788}
1789function getInitialValue(element) {
1790 return element[InitialValue];
1791}
1792function startTrackValue(element) {
1793 element[TrackChanges] = [];
1794}
1795function trackValue(element, v) {
1796 var _a;
1797 (_a = element[TrackChanges]) == null ? void 0 : _a.push(v);
1798}
1799function endTrackValue(element) {
1800 const tracked = element[TrackChanges];
1801 element[TrackChanges] = void 0;
1802 return tracked;
1803}
1804
1805// src/document/index.ts
1806var isPrepared = Symbol("Node prepared with document state workarounds");
1807function prepareDocument(document2) {
1808 if (document2[isPrepared]) {
1809 return;
1810 }
1811 document2.addEventListener("focus", (e) => {
1812 const el = e.target;
1813 prepareElement(el);
1814 }, {
1815 capture: true,
1816 passive: true
1817 });
1818 if (document2.activeElement) {
1819 prepareElement(document2.activeElement);
1820 }
1821 document2.addEventListener("blur", (e) => {
1822 const el = e.target;
1823 const initialValue = getInitialValue(el);
1824 if (typeof initialValue === "string" && el.value !== initialValue) {
1825 dispatchUIEvent({}, el, "change");
1826 }
1827 }, {
1828 capture: true,
1829 passive: true
1830 });
1831 document2[isPrepared] = isPrepared;
1832}
1833function prepareElement(el) {
1834 if ("value" in el) {
1835 setInitialValue(el);
1836 }
1837 if (el[isPrepared]) {
1838 return;
1839 }
1840 if ("value" in el) {
1841 prepareValueInterceptor(el);
1842 prepareSelectionInterceptor(el);
1843 }
1844 el[isPrepared] = isPrepared;
1845}
1846
1847// src/keyboard/modifiers.ts
1848var modifierKeys = [
1849 "Alt",
1850 "AltGraph",
1851 "Control",
1852 "Fn",
1853 "Meta",
1854 "Shift",
1855 "Symbol"
1856];
1857function isModifierKey(key) {
1858 return modifierKeys.includes(key);
1859}
1860var modifierLocks = [
1861 "CapsLock",
1862 "FnLock",
1863 "NumLock",
1864 "ScrollLock",
1865 "SymbolLock"
1866];
1867function isModifierLock(key) {
1868 return modifierLocks.includes(key);
1869}
1870function preKeydownBehavior(config, { key }, element) {
1871 var _a;
1872 if (isModifierKey(key)) {
1873 config.keyboardState.modifiers[key] = true;
1874 if (key === "AltGraph") {
1875 const ctrlKeyDef = (_a = config.keyboardMap.find((k) => k.key === "Control")) != null ? _a : { key: "Control", code: "Control" };
1876 dispatchUIEvent(config, element, "keydown", getKeyEventProps(ctrlKeyDef));
1877 }
1878 } else if (isModifierLock(key)) {
1879 config.keyboardState.modifierPhase[key] = config.keyboardState.modifiers[key];
1880 if (!config.keyboardState.modifierPhase[key]) {
1881 config.keyboardState.modifiers[key] = true;
1882 }
1883 }
1884}
1885function preKeyupBehavior(config, { key }) {
1886 if (isModifierKey(key)) {
1887 config.keyboardState.modifiers[key] = false;
1888 } else if (isModifierLock(key)) {
1889 if (config.keyboardState.modifierPhase[key]) {
1890 config.keyboardState.modifiers[key] = false;
1891 }
1892 }
1893}
1894function postKeyupBehavior(config, { key }, element) {
1895 var _a;
1896 if (key === "AltGraph") {
1897 const ctrlKeyDef = (_a = config.keyboardMap.find((k) => k.key === "Control")) != null ? _a : { key: "Control", code: "Control" };
1898 dispatchUIEvent(config, element, "keyup", getKeyEventProps(ctrlKeyDef));
1899 }
1900}
1901
1902// src/keyboard/keyboardAction.ts
1903function keyboardAction(config, actions) {
1904 return __async(this, null, function* () {
1905 for (let i = 0; i < actions.length; i++) {
1906 yield keyboardKeyAction(config, actions[i]);
1907 if (typeof config.delay === "number" && i < actions.length - 1) {
1908 yield wait(config.delay);
1909 }
1910 }
1911 });
1912}
1913function keyboardKeyAction(_0, _1) {
1914 return __async(this, arguments, function* (config, { keyDef, releasePrevious, releaseSelf, repeat }) {
1915 const { document: document2, keyboardState, delay } = config;
1916 const getCurrentElement = () => getActive(document2);
1917 const pressed = keyboardState.pressed.find((p) => p.keyDef === keyDef);
1918 if (pressed) {
1919 yield keyup(keyDef, getCurrentElement, config, pressed.unpreventedDefault);
1920 }
1921 if (!releasePrevious) {
1922 let unpreventedDefault = true;
1923 for (let i = 1; i <= repeat; i++) {
1924 unpreventedDefault = yield keydown(keyDef, getCurrentElement, config);
1925 if (unpreventedDefault && hasKeyPress(keyDef, config)) {
1926 yield keypress(keyDef, getCurrentElement, config);
1927 }
1928 if (typeof delay === "number" && i < repeat) {
1929 yield wait(delay);
1930 }
1931 }
1932 if (releaseSelf) {
1933 yield keyup(keyDef, getCurrentElement, config, unpreventedDefault);
1934 }
1935 }
1936 });
1937}
1938function getActive(document2) {
1939 var _a;
1940 return (_a = getActiveElement(document2)) != null ? _a : document2.body;
1941}
1942function releaseAllKeys(config) {
1943 return __async(this, null, function* () {
1944 const getCurrentElement = () => getActive(config.document);
1945 for (const k of config.keyboardState.pressed) {
1946 yield keyup(k.keyDef, getCurrentElement, config, k.unpreventedDefault);
1947 }
1948 });
1949}
1950function keydown(keyDef, getCurrentElement, config) {
1951 return __async(this, null, function* () {
1952 const element = getCurrentElement();
1953 if (element !== config.keyboardState.activeElement) {
1954 config.keyboardState.carryValue = void 0;
1955 config.keyboardState.carryChar = "";
1956 }
1957 config.keyboardState.activeElement = element;
1958 preKeydownBehavior(config, keyDef, element);
1959 const unpreventedDefault = dispatchUIEvent(config, element, "keydown", getKeyEventProps(keyDef));
1960 config.keyboardState.pressed.push({ keyDef, unpreventedDefault });
1961 return unpreventedDefault;
1962 });
1963}
1964function keypress(keyDef, getCurrentElement, config) {
1965 return __async(this, null, function* () {
1966 const element = getCurrentElement();
1967 dispatchUIEvent(config, element, "keypress", __spreadProps(__spreadValues({}, getKeyEventProps(keyDef)), {
1968 charCode: keyDef.key === "Enter" ? 13 : String(keyDef.key).charCodeAt(0)
1969 }));
1970 });
1971}
1972function keyup(keyDef, getCurrentElement, config, unprevented) {
1973 return __async(this, null, function* () {
1974 const element = getCurrentElement();
1975 preKeyupBehavior(config, keyDef);
1976 dispatchUIEvent(config, element, "keyup", getKeyEventProps(keyDef), !unprevented);
1977 config.keyboardState.pressed = config.keyboardState.pressed.filter((k) => k.keyDef !== keyDef);
1978 postKeyupBehavior(config, keyDef, element);
1979 });
1980}
1981function hasKeyPress(keyDef, config) {
1982 var _a;
1983 return (((_a = keyDef.key) == null ? void 0 : _a.length) === 1 || keyDef.key === "Enter") && !config.keyboardState.modifiers.Control && !config.keyboardState.modifiers.Alt;
1984}
1985
1986// src/keyboard/parseKeyDef.ts
1987function parseKeyDef(keyboardMap, text) {
1988 var _a;
1989 const defs = [];
1990 do {
1991 const {
1992 type: type3,
1993 descriptor,
1994 consumedLength,
1995 releasePrevious,
1996 releaseSelf = true,
1997 repeat
1998 } = readNextDescriptor(text);
1999 const keyDef = (_a = keyboardMap.find((def) => {
2000 var _a2, _b;
2001 if (type3 === "[") {
2002 return ((_a2 = def.code) == null ? void 0 : _a2.toLowerCase()) === descriptor.toLowerCase();
2003 } else if (type3 === "{") {
2004 return ((_b = def.key) == null ? void 0 : _b.toLowerCase()) === descriptor.toLowerCase();
2005 }
2006 return def.key === descriptor;
2007 })) != null ? _a : {
2008 key: "Unknown",
2009 code: "Unknown",
2010 [type3 === "[" ? "code" : "key"]: descriptor
2011 };
2012 defs.push({ keyDef, releasePrevious, releaseSelf, repeat });
2013 text = text.slice(consumedLength);
2014 } while (text);
2015 return defs;
2016}
2017
2018// src/keyboard/index.ts
2019function keyboard(text) {
2020 return __async(this, null, function* () {
2021 const actions = parseKeyDef(this[Config].keyboardMap, text);
2022 return keyboardAction(this[Config], actions);
2023 });
2024}
2025function createKeyboardState() {
2026 return {
2027 activeElement: null,
2028 pressed: [],
2029 carryChar: "",
2030 modifiers: {
2031 Alt: false,
2032 AltGraph: false,
2033 Control: false,
2034 CapsLock: false,
2035 Fn: false,
2036 FnLock: false,
2037 Meta: false,
2038 NumLock: false,
2039 ScrollLock: false,
2040 Shift: false,
2041 Symbol: false,
2042 SymbolLock: false
2043 },
2044 modifierPhase: {}
2045 };
2046}
2047
2048// src/pointer/parseKeyDef.ts
2049function parseKeyDef2(pointerMap, keys) {
2050 const defs = [];
2051 do {
2052 const {
2053 descriptor,
2054 consumedLength,
2055 releasePrevious,
2056 releaseSelf = true
2057 } = readNextDescriptor(keys);
2058 const keyDef = pointerMap.find((p) => p.name === descriptor);
2059 if (keyDef) {
2060 defs.push({ keyDef, releasePrevious, releaseSelf });
2061 }
2062 keys = keys.slice(consumedLength);
2063 } while (keys);
2064 return defs;
2065}
2066
2067// src/pointer/firePointerEvents.ts
2068function firePointerEvent(config, target, type3, {
2069 pointerType,
2070 button,
2071 coords,
2072 pointerId,
2073 isPrimary,
2074 clickCount
2075}) {
2076 const init = __spreadValues({}, coords);
2077 if (type3 === "click" || type3.startsWith("pointer")) {
2078 init.pointerId = pointerId;
2079 init.pointerType = pointerType;
2080 }
2081 if (["pointerdown", "pointerup"].includes(type3)) {
2082 init.isPrimary = isPrimary;
2083 }
2084 init.button = getMouseButton(button != null ? button : 0);
2085 init.buttons = getMouseButtons(...config.pointerState.pressed.filter((p) => p.keyDef.pointerType === pointerType).map((p) => {
2086 var _a;
2087 return (_a = p.keyDef.button) != null ? _a : 0;
2088 }));
2089 if (["mousedown", "mouseup", "click", "dblclick", "contextmenu"].includes(type3)) {
2090 init.detail = clickCount;
2091 }
2092 return dispatchUIEvent(config, target, type3, init);
2093}
2094
2095// src/pointer/resolveSelectionTarget.ts
2096function resolveSelectionTarget({
2097 target,
2098 node,
2099 offset
2100}) {
2101 if (isElementType(target, ["input", "textarea"])) {
2102 return {
2103 node: target,
2104 offset: offset != null ? offset : getUIValue(target).length
2105 };
2106 } else if (node) {
2107 return {
2108 node,
2109 offset: offset != null ? offset : node.nodeType === 3 ? node.nodeValue.length : node.childNodes.length
2110 };
2111 }
2112 return findNodeAtTextOffset(target, offset);
2113}
2114function findNodeAtTextOffset(node, offset, isRoot = true) {
2115 let i = offset === void 0 ? node.childNodes.length - 1 : 0;
2116 const step = offset === void 0 ? -1 : 1;
2117 while (offset === void 0 ? i >= (isRoot ? Math.max(node.childNodes.length - 1, 0) : 0) : i <= node.childNodes.length) {
2118 const c = node.childNodes.item(i);
2119 const text = String(c.textContent);
2120 if (text.length) {
2121 if (offset !== void 0 && text.length < offset) {
2122 offset -= text.length;
2123 } else if (c.nodeType === 1) {
2124 return findNodeAtTextOffset(c, offset, false);
2125 } else {
2126 if (c.nodeType === 3) {
2127 return {
2128 node: c,
2129 offset: offset != null ? offset : c.nodeValue.length
2130 };
2131 }
2132 }
2133 }
2134 i += step;
2135 }
2136 return { node, offset: node.childNodes.length };
2137}
2138
2139// src/pointer/pointerMove.ts
2140function pointerMove(_0, _1) {
2141 return __async(this, arguments, function* (config, { pointerName = "mouse", target, coords, node, offset }) {
2142 const { pointerState } = config;
2143 if (!(pointerName in pointerState.position)) {
2144 throw new Error(`Trying to move pointer "${pointerName}" which does not exist.`);
2145 }
2146 const {
2147 pointerId,
2148 pointerType,
2149 target: prevTarget,
2150 coords: prevCoords,
2151 selectionRange
2152 } = pointerState.position[pointerName];
2153 if (prevTarget && prevTarget !== target) {
2154 setLevelRef(config, 2 /* Trigger */);
2155 assertPointerEvents(config, prevTarget);
2156 fireMove(prevTarget, prevCoords);
2157 if (!isDescendantOrSelf(target, prevTarget)) {
2158 fireLeave(prevTarget, prevCoords);
2159 }
2160 }
2161 setLevelRef(config, 2 /* Trigger */);
2162 assertPointerEvents(config, target);
2163 pointerState.position[pointerName] = __spreadProps(__spreadValues({}, pointerState.position[pointerName]), {
2164 target,
2165 coords
2166 });
2167 if (prevTarget !== target) {
2168 if (!prevTarget || !isDescendantOrSelf(prevTarget, target)) {
2169 fireEnter(target, coords);
2170 }
2171 }
2172 fireMove(target, coords);
2173 if (selectionRange) {
2174 const selectionFocus = resolveSelectionTarget({ target, node, offset });
2175 if ("node" in selectionRange) {
2176 if (selectionFocus.node === selectionRange.node) {
2177 const anchorOffset = selectionFocus.offset < selectionRange.start ? selectionRange.end : selectionRange.start;
2178 const focusOffset = selectionFocus.offset > selectionRange.end || selectionFocus.offset < selectionRange.start ? selectionFocus.offset : selectionRange.end;
2179 setUISelection(selectionRange.node, { anchorOffset, focusOffset });
2180 }
2181 } else {
2182 const range = selectionRange.cloneRange();
2183 const cmp = range.comparePoint(selectionFocus.node, selectionFocus.offset);
2184 if (cmp < 0) {
2185 range.setStart(selectionFocus.node, selectionFocus.offset);
2186 } else if (cmp > 0) {
2187 range.setEnd(selectionFocus.node, selectionFocus.offset);
2188 }
2189 const selection = target.ownerDocument.getSelection();
2190 selection.removeAllRanges();
2191 selection.addRange(range.cloneRange());
2192 }
2193 }
2194 function fireMove(eventTarget, eventCoords) {
2195 fire(eventTarget, "pointermove", eventCoords);
2196 if (pointerType === "mouse" && !isDisabled(eventTarget)) {
2197 fire(eventTarget, "mousemove", eventCoords);
2198 }
2199 }
2200 function fireLeave(eventTarget, eventCoords) {
2201 fire(eventTarget, "pointerout", eventCoords);
2202 fire(eventTarget, "pointerleave", eventCoords);
2203 if (pointerType === "mouse" && !isDisabled(eventTarget)) {
2204 fire(eventTarget, "mouseout", eventCoords);
2205 fire(eventTarget, "mouseleave", eventCoords);
2206 }
2207 }
2208 function fireEnter(eventTarget, eventCoords) {
2209 fire(eventTarget, "pointerover", eventCoords);
2210 fire(eventTarget, "pointerenter", eventCoords);
2211 if (pointerType === "mouse" && !isDisabled(eventTarget)) {
2212 fire(eventTarget, "mouseover", eventCoords);
2213 fire(eventTarget, "mouseenter", eventCoords);
2214 }
2215 }
2216 function fire(eventTarget, type3, eventCoords) {
2217 return firePointerEvent(config, eventTarget, type3, {
2218 coords: eventCoords,
2219 pointerId,
2220 pointerType
2221 });
2222 }
2223 });
2224}
2225
2226// src/pointer/pointerPress.ts
2227function pointerPress(config, action) {
2228 return __async(this, null, function* () {
2229 const { keyDef, target, releasePrevious, releaseSelf } = action;
2230 const previous = config.pointerState.pressed.find((p) => p.keyDef === keyDef);
2231 const pointerName = keyDef.pointerType === "touch" ? keyDef.name : keyDef.pointerType;
2232 const targetIsDisabled = isDisabled(target);
2233 if (previous) {
2234 up(config, pointerName, action, previous, targetIsDisabled);
2235 }
2236 if (!releasePrevious) {
2237 const press = down(config, pointerName, action, targetIsDisabled);
2238 if (releaseSelf) {
2239 up(config, pointerName, action, press, targetIsDisabled);
2240 }
2241 }
2242 });
2243}
2244function getNextPointerId(state) {
2245 state.pointerId = state.pointerId + 1;
2246 return state.pointerId;
2247}
2248function down(config, pointerName, { keyDef, node, offset, target, coords }, targetIsDisabled) {
2249 var _a, _b, _c;
2250 setLevelRef(config, 2 /* Trigger */);
2251 assertPointerEvents(config, target);
2252 const { pointerState } = config;
2253 const { name, pointerType, button } = keyDef;
2254 const pointerId = pointerType === "mouse" ? 1 : getNextPointerId(pointerState);
2255 pointerState.position[pointerName] = __spreadProps(__spreadValues({}, pointerState.position[pointerName]), {
2256 pointerId,
2257 pointerType,
2258 target,
2259 coords
2260 });
2261 let isMultiTouch = false;
2262 let isPrimary = true;
2263 if (pointerType !== "mouse") {
2264 for (const obj of pointerState.pressed) {
2265 if (obj.keyDef.pointerType === pointerType) {
2266 obj.isMultiTouch = true;
2267 isMultiTouch = true;
2268 isPrimary = false;
2269 }
2270 }
2271 }
2272 if (((_a = pointerState.activeClickCount) == null ? void 0 : _a[0]) !== name) {
2273 delete pointerState.activeClickCount;
2274 }
2275 const clickCount = Number((_c = (_b = pointerState.activeClickCount) == null ? void 0 : _b[1]) != null ? _c : 0) + 1;
2276 pointerState.activeClickCount = [name, clickCount];
2277 const pressObj = {
2278 keyDef,
2279 downTarget: target,
2280 pointerId,
2281 unpreventedDefault: true,
2282 isMultiTouch,
2283 isPrimary,
2284 clickCount
2285 };
2286 pointerState.pressed.push(pressObj);
2287 if (pointerType !== "mouse") {
2288 fire("pointerover");
2289 fire("pointerenter");
2290 }
2291 if (pointerType !== "mouse" || !pointerState.pressed.some((p) => p.keyDef !== keyDef && p.keyDef.pointerType === pointerType)) {
2292 fire("pointerdown");
2293 }
2294 if (pointerType === "mouse") {
2295 if (!targetIsDisabled) {
2296 pressObj.unpreventedDefault = fire("mousedown");
2297 }
2298 if (pressObj.unpreventedDefault) {
2299 mousedownDefaultBehavior({
2300 target,
2301 targetIsDisabled,
2302 clickCount,
2303 position: pointerState.position[pointerName],
2304 node,
2305 offset
2306 });
2307 }
2308 if (button === "secondary") {
2309 fire("contextmenu");
2310 }
2311 }
2312 return pressObj;
2313 function fire(type3) {
2314 return firePointerEvent(config, target, type3, {
2315 button,
2316 clickCount,
2317 coords,
2318 isPrimary,
2319 pointerId,
2320 pointerType
2321 });
2322 }
2323}
2324function up(config, pointerName, {
2325 keyDef: { pointerType, button },
2326 target,
2327 coords,
2328 node,
2329 offset
2330}, pressed, targetIsDisabled) {
2331 setLevelRef(config, 2 /* Trigger */);
2332 assertPointerEvents(config, target);
2333 const { pointerState } = config;
2334 pointerState.pressed = pointerState.pressed.filter((p) => p !== pressed);
2335 const { isMultiTouch, isPrimary, pointerId, clickCount } = pressed;
2336 let { unpreventedDefault } = pressed;
2337 pointerState.position[pointerName] = __spreadProps(__spreadValues({}, pointerState.position[pointerName]), {
2338 target,
2339 coords
2340 });
2341 if (pointerType !== "mouse" || !pointerState.pressed.filter((p) => p.keyDef.pointerType === pointerType).length) {
2342 fire("pointerup");
2343 }
2344 if (pointerType !== "mouse") {
2345 fire("pointerout");
2346 fire("pointerleave");
2347 }
2348 if (pointerType !== "mouse" && !isMultiTouch) {
2349 if (!targetIsDisabled) {
2350 if (clickCount === 1) {
2351 fire("mouseover");
2352 fire("mouseenter");
2353 }
2354 fire("mousemove");
2355 unpreventedDefault = fire("mousedown") && unpreventedDefault;
2356 }
2357 if (unpreventedDefault) {
2358 mousedownDefaultBehavior({
2359 target,
2360 targetIsDisabled,
2361 clickCount,
2362 position: pointerState.position[pointerName],
2363 node,
2364 offset
2365 });
2366 }
2367 }
2368 delete pointerState.position[pointerName].selectionRange;
2369 if (!targetIsDisabled) {
2370 if (pointerType === "mouse" || !isMultiTouch) {
2371 unpreventedDefault = fire("mouseup") && unpreventedDefault;
2372 const canClick = pointerType !== "mouse" || button === "primary";
2373 if (canClick && target === pressed.downTarget) {
2374 fire("click");
2375 if (clickCount === 2) {
2376 fire("dblclick");
2377 }
2378 }
2379 }
2380 }
2381 function fire(type3) {
2382 return firePointerEvent(config, target, type3, {
2383 button,
2384 clickCount,
2385 coords,
2386 isPrimary,
2387 pointerId,
2388 pointerType
2389 });
2390 }
2391}
2392function mousedownDefaultBehavior({
2393 position,
2394 target,
2395 targetIsDisabled,
2396 clickCount,
2397 node,
2398 offset
2399}) {
2400 focus(target);
2401 if (!targetIsDisabled) {
2402 const hasValue = isElementType(target, ["input", "textarea"]);
2403 const text = String(hasValue ? getUIValue(target) : target.textContent);
2404 const [start, end] = node ? [offset, offset] : getTextRange(text, offset, clickCount);
2405 if (hasValue) {
2406 setUISelection(target, {
2407 anchorOffset: start != null ? start : text.length,
2408 focusOffset: end != null ? end : text.length
2409 });
2410 position.selectionRange = {
2411 node: target,
2412 start: start != null ? start : 0,
2413 end: end != null ? end : text.length
2414 };
2415 } else {
2416 const { node: startNode, offset: startOffset } = resolveSelectionTarget({
2417 target,
2418 node,
2419 offset: start
2420 });
2421 const { node: endNode, offset: endOffset } = resolveSelectionTarget({
2422 target,
2423 node,
2424 offset: end
2425 });
2426 const range = new Range();
2427 range.setStart(startNode, startOffset);
2428 range.setEnd(endNode, endOffset);
2429 position.selectionRange = range;
2430 const selection = target.ownerDocument.getSelection();
2431 selection.removeAllRanges();
2432 selection.addRange(range.cloneRange());
2433 }
2434 }
2435}
2436function getTextRange(text, pos, clickCount) {
2437 if (clickCount % 3 === 1 || text.length === 0) {
2438 return [pos, pos];
2439 }
2440 const textPos = pos != null ? pos : text.length;
2441 if (clickCount % 3 === 2) {
2442 return [
2443 textPos - text.substr(0, pos).match(/(\w+|\s+|\W)?$/)[0].length,
2444 pos === void 0 ? pos : pos + text.substr(pos).match(/^(\w+|\s+|\W)?/)[0].length
2445 ];
2446 }
2447 return [
2448 textPos - text.substr(0, pos).match(/[^\r\n]*$/)[0].length,
2449 pos === void 0 ? pos : pos + text.substr(pos).match(/^[^\r\n]*/)[0].length
2450 ];
2451}
2452
2453// src/pointer/pointerAction.ts
2454function pointerAction(config, actions) {
2455 return __async(this, null, function* () {
2456 var _a, _b;
2457 for (let i = 0; i < actions.length; i++) {
2458 const action = actions[i];
2459 const pointerName = "pointerName" in action && action.pointerName ? action.pointerName : "keyDef" in action ? action.keyDef.pointerType === "touch" ? action.keyDef.name : action.keyDef.pointerType : "mouse";
2460 const target = (_a = action.target) != null ? _a : getPrevTarget(pointerName, config.pointerState);
2461 const coords = (_b = action.coords) != null ? _b : pointerName in config.pointerState.position ? config.pointerState.position[pointerName].coords : void 0;
2462 yield "keyDef" in action ? pointerPress(config, __spreadProps(__spreadValues({}, action), { target, coords })) : pointerMove(config, __spreadProps(__spreadValues({}, action), { target, coords }));
2463 if (typeof config.delay === "number") {
2464 if (i < actions.length - 1) {
2465 yield wait(config.delay);
2466 }
2467 }
2468 }
2469 delete config.pointerState.activeClickCount;
2470 });
2471}
2472function getPrevTarget(pointerName, state) {
2473 if (!(pointerName in state.position) || !state.position[pointerName].target) {
2474 throw new Error("This pointer has no previous position. Provide a target property!");
2475 }
2476 return state.position[pointerName].target;
2477}
2478
2479// src/pointer/index.ts
2480function pointer(input2) {
2481 return __async(this, null, function* () {
2482 const { pointerMap } = this[Config];
2483 const actions = [];
2484 (Array.isArray(input2) ? input2 : [input2]).forEach((actionInput) => {
2485 if (typeof actionInput === "string") {
2486 actions.push(...parseKeyDef2(pointerMap, actionInput));
2487 } else if ("keys" in actionInput) {
2488 actions.push(...parseKeyDef2(pointerMap, actionInput.keys).map((i) => __spreadValues(__spreadValues({}, actionInput), i)));
2489 } else {
2490 actions.push(actionInput);
2491 }
2492 });
2493 return pointerAction(this[Config], actions).then(() => void 0);
2494 });
2495}
2496function createPointerState(document2) {
2497 return {
2498 pointerId: 1,
2499 position: {
2500 mouse: {
2501 pointerType: "mouse",
2502 pointerId: 1,
2503 target: document2.body,
2504 coords: {
2505 clientX: 0,
2506 clientY: 0,
2507 offsetX: 0,
2508 offsetY: 0,
2509 pageX: 0,
2510 pageY: 0,
2511 x: 0,
2512 y: 0
2513 }
2514 }
2515 },
2516 pressed: []
2517 };
2518}
2519
2520// src/setup/config.ts
2521var Config = Symbol("Config");
2522
2523// src/setup/api.ts
2524var api_exports = {};
2525__export(api_exports, {
2526 clear: () => clear,
2527 click: () => click,
2528 copy: () => copy,
2529 cut: () => cut,
2530 dblClick: () => dblClick,
2531 deselectOptions: () => deselectOptions,
2532 hover: () => hover,
2533 keyboard: () => keyboard,
2534 paste: () => paste,
2535 pointer: () => pointer,
2536 selectOptions: () => selectOptions,
2537 tab: () => tab,
2538 tripleClick: () => tripleClick,
2539 type: () => type,
2540 unhover: () => unhover,
2541 upload: () => upload
2542});
2543
2544// src/convenience/click.ts
2545function click(element) {
2546 return __async(this, null, function* () {
2547 const pointerIn = [];
2548 if (!this[Config].skipHover) {
2549 pointerIn.push({ target: element });
2550 }
2551 pointerIn.push({ keys: "[MouseLeft]", target: element });
2552 return this.pointer(pointerIn);
2553 });
2554}
2555function dblClick(element) {
2556 return __async(this, null, function* () {
2557 return this.pointer([{ target: element }, "[MouseLeft][MouseLeft]"]);
2558 });
2559}
2560function tripleClick(element) {
2561 return __async(this, null, function* () {
2562 return this.pointer([{ target: element }, "[MouseLeft][MouseLeft][MouseLeft]"]);
2563 });
2564}
2565
2566// src/convenience/hover.ts
2567function hover(element) {
2568 return __async(this, null, function* () {
2569 return this.pointer({ target: element });
2570 });
2571}
2572function unhover(element) {
2573 return __async(this, null, function* () {
2574 return this.pointer({ target: element.ownerDocument.body });
2575 });
2576}
2577
2578// src/convenience/tab.ts
2579function tab() {
2580 return __async(this, arguments, function* ({
2581 shift
2582 } = {}) {
2583 return this.keyboard(shift === true ? "{Shift>}{Tab}{/Shift}" : shift === false ? "[/ShiftLeft][/ShiftRight]{Tab}" : "{Tab}");
2584 });
2585}
2586
2587// src/clipboard/copy.ts
2588function copy() {
2589 return __async(this, null, function* () {
2590 var _a;
2591 const doc = this[Config].document;
2592 const target = (_a = doc.activeElement) != null ? _a : doc.body;
2593 const clipboardData = copySelection(target);
2594 if (clipboardData.items.length === 0) {
2595 return;
2596 }
2597 if (this.dispatchUIEvent(target, "copy", {
2598 clipboardData
2599 }) && this[Config].writeToClipboard) {
2600 yield writeDataTransferToClipboard(doc, clipboardData);
2601 }
2602 return clipboardData;
2603 });
2604}
2605
2606// src/clipboard/cut.ts
2607function cut() {
2608 return __async(this, null, function* () {
2609 var _a;
2610 const doc = this[Config].document;
2611 const target = (_a = doc.activeElement) != null ? _a : doc.body;
2612 const clipboardData = copySelection(target);
2613 if (clipboardData.items.length === 0) {
2614 return;
2615 }
2616 if (this.dispatchUIEvent(target, "cut", {
2617 clipboardData
2618 }) && this[Config].writeToClipboard) {
2619 yield writeDataTransferToClipboard(target.ownerDocument, clipboardData);
2620 }
2621 return clipboardData;
2622 });
2623}
2624
2625// src/clipboard/paste.ts
2626function paste(clipboardData) {
2627 return __async(this, null, function* () {
2628 var _a, _b;
2629 const doc = this[Config].document;
2630 const target = (_a = doc.activeElement) != null ? _a : doc.body;
2631 const dataTransfer = (_b = typeof clipboardData === "string" ? getClipboardDataFromString(clipboardData) : clipboardData) != null ? _b : yield readDataTransferFromClipboard(doc).catch(() => {
2632 throw new Error("`userEvent.paste()` without `clipboardData` requires the `ClipboardAPI` to be available.");
2633 });
2634 this.dispatchUIEvent(target, "paste", {
2635 clipboardData: dataTransfer
2636 });
2637 });
2638}
2639function getClipboardDataFromString(text) {
2640 const dt = createDataTransfer();
2641 dt.setData("text", text);
2642 return dt;
2643}
2644
2645// src/utility/clear.ts
2646function clear(element) {
2647 return __async(this, null, function* () {
2648 if (!isEditable(element) || isDisabled(element)) {
2649 throw new Error("clear()` is only supported on editable elements.");
2650 }
2651 focus(element);
2652 if (element.ownerDocument.activeElement !== element) {
2653 throw new Error("The element to be cleared could not be focused.");
2654 }
2655 selectAll(element);
2656 if (!isAllSelected(element)) {
2657 throw new Error("The element content to be cleared could not be selected.");
2658 }
2659 input(this[Config], element, "", "deleteContentBackward");
2660 });
2661}
2662
2663// src/utility/selectOptions.ts
2664import { getConfig as getConfig3 } from "@testing-library/dom";
2665function selectOptions(select, values) {
2666 return __async(this, null, function* () {
2667 return selectOptionsBase.call(this, true, select, values);
2668 });
2669}
2670function deselectOptions(select, values) {
2671 return __async(this, null, function* () {
2672 return selectOptionsBase.call(this, false, select, values);
2673 });
2674}
2675function selectOptionsBase(newValue, select, values) {
2676 return __async(this, null, function* () {
2677 if (!newValue && !select.multiple) {
2678 throw getConfig3().getElementError(`Unable to deselect an option in a non-multiple select. Use selectOptions to change the selection instead.`, select);
2679 }
2680 const valArray = Array.isArray(values) ? values : [values];
2681 const allOptions = Array.from(select.querySelectorAll('option, [role="option"]'));
2682 const selectedOptions = valArray.map((val) => {
2683 if (typeof val !== "string" && allOptions.includes(val)) {
2684 return val;
2685 } else {
2686 const matchingOption = allOptions.find((o) => o.value === val || o.innerHTML === val);
2687 if (matchingOption) {
2688 return matchingOption;
2689 } else {
2690 throw getConfig3().getElementError(`Value "${String(val)}" not found in options`, select);
2691 }
2692 }
2693 }).filter((option) => !isDisabled(option));
2694 if (isDisabled(select) || !selectedOptions.length)
2695 return;
2696 const selectOption = (option) => {
2697 option.selected = newValue;
2698 this.dispatchUIEvent(select, "input", {
2699 bubbles: true,
2700 cancelable: false,
2701 composed: true
2702 });
2703 this.dispatchUIEvent(select, "change");
2704 };
2705 if (isElementType(select, "select")) {
2706 if (select.multiple) {
2707 for (const option of selectedOptions) {
2708 const withPointerEvents = this[Config].pointerEventsCheck === 0 ? true : hasPointerEvents(option);
2709 if (withPointerEvents) {
2710 this.dispatchUIEvent(option, "pointerover");
2711 this.dispatchUIEvent(select, "pointerenter");
2712 this.dispatchUIEvent(option, "mouseover");
2713 this.dispatchUIEvent(select, "mouseenter");
2714 this.dispatchUIEvent(option, "pointermove");
2715 this.dispatchUIEvent(option, "mousemove");
2716 this.dispatchUIEvent(option, "pointerdown");
2717 this.dispatchUIEvent(option, "mousedown");
2718 }
2719 focus(select);
2720 if (withPointerEvents) {
2721 this.dispatchUIEvent(option, "pointerup");
2722 this.dispatchUIEvent(option, "mouseup");
2723 }
2724 selectOption(option);
2725 if (withPointerEvents) {
2726 this.dispatchUIEvent(option, "click");
2727 }
2728 }
2729 } else if (selectedOptions.length === 1) {
2730 const withPointerEvents = this[Config].pointerEventsCheck === 0 ? true : hasPointerEvents(select);
2731 if (withPointerEvents) {
2732 yield this.click(select);
2733 } else {
2734 focus(select);
2735 }
2736 selectOption(selectedOptions[0]);
2737 if (withPointerEvents) {
2738 this.dispatchUIEvent(select, "pointerover");
2739 this.dispatchUIEvent(select, "pointerenter");
2740 this.dispatchUIEvent(select, "mouseover");
2741 this.dispatchUIEvent(select, "mouseenter");
2742 this.dispatchUIEvent(select, "pointerup");
2743 this.dispatchUIEvent(select, "mouseup");
2744 this.dispatchUIEvent(select, "click");
2745 }
2746 } else {
2747 throw getConfig3().getElementError(`Cannot select multiple options on a non-multiple select`, select);
2748 }
2749 } else if (select.getAttribute("role") === "listbox") {
2750 for (const option of selectedOptions) {
2751 yield this.click(option);
2752 yield this.unhover(option);
2753 }
2754 } else {
2755 throw getConfig3().getElementError(`Cannot select options on elements that are neither select nor listbox elements`, select);
2756 }
2757 });
2758}
2759
2760// src/utility/type.ts
2761function type(_0, _1) {
2762 return __async(this, arguments, function* (element, text, {
2763 skipClick = this[Config].skipClick,
2764 skipAutoClose = this[Config].skipAutoClose,
2765 initialSelectionStart,
2766 initialSelectionEnd
2767 } = {}) {
2768 if (element.disabled)
2769 return;
2770 if (!skipClick) {
2771 yield this.click(element);
2772 }
2773 if (initialSelectionStart !== void 0) {
2774 setSelectionRange(element, initialSelectionStart, initialSelectionEnd != null ? initialSelectionEnd : initialSelectionStart);
2775 }
2776 yield this.keyboard(text);
2777 if (!skipAutoClose) {
2778 yield releaseAllKeys(this[Config]);
2779 }
2780 });
2781}
2782
2783// src/utility/upload.ts
2784function upload(element, fileOrFiles) {
2785 return __async(this, null, function* () {
2786 const input2 = isElementType(element, "label") ? element.control : element;
2787 if (!input2 || !isElementType(input2, "input", { type: "file" })) {
2788 throw new TypeError(`The ${input2 === element ? "given" : "associated"} ${input2 == null ? void 0 : input2.tagName} element does not accept file uploads`);
2789 }
2790 if (isDisabled(element))
2791 return;
2792 const files = (Array.isArray(fileOrFiles) ? fileOrFiles : [fileOrFiles]).filter((file) => !this[Config].applyAccept || isAcceptableFile(file, input2.accept)).slice(0, input2.multiple ? void 0 : 1);
2793 const fileDialog = () => {
2794 var _a;
2795 if (files.length === ((_a = input2.files) == null ? void 0 : _a.length) && files.every((f, i) => {
2796 var _a2;
2797 return f === ((_a2 = input2.files) == null ? void 0 : _a2.item(i));
2798 })) {
2799 return;
2800 }
2801 setFiles(input2, createFileList(files));
2802 this.dispatchUIEvent(input2, "input");
2803 this.dispatchUIEvent(input2, "change");
2804 };
2805 input2.addEventListener("fileDialog", fileDialog);
2806 yield this.click(element);
2807 input2.removeEventListener("fileDialog", fileDialog);
2808 });
2809}
2810function isAcceptableFile(file, accept) {
2811 if (!accept) {
2812 return true;
2813 }
2814 const wildcards = ["audio/*", "image/*", "video/*"];
2815 return accept.split(",").some((acceptToken) => {
2816 if (acceptToken.startsWith(".")) {
2817 return file.name.endsWith(acceptToken);
2818 } else if (wildcards.includes(acceptToken)) {
2819 return file.type.startsWith(acceptToken.substr(0, acceptToken.length - 1));
2820 }
2821 return file.type === acceptToken;
2822 });
2823}
2824
2825// src/setup/wrapAsync.ts
2826import { getConfig as getDOMTestingLibraryConfig } from "@testing-library/dom";
2827function wrapAsync(implementation) {
2828 return getDOMTestingLibraryConfig().asyncWrapper(implementation);
2829}
2830
2831// src/setup/setup.ts
2832function createConfig(options = {}, defaults = defaultOptionsSetup, node) {
2833 const document2 = getDocument(options, node);
2834 const {
2835 keyboardState = createKeyboardState(),
2836 pointerState = createPointerState(document2)
2837 } = options;
2838 return __spreadProps(__spreadValues(__spreadValues({}, defaults), options), {
2839 document: document2,
2840 keyboardState,
2841 pointerState
2842 });
2843}
2844function setupMain(options = {}) {
2845 var _a;
2846 const config = createConfig(options);
2847 prepareDocument(config.document);
2848 const view = (_a = config.document.defaultView) != null ? _a : window;
2849 attachClipboardStubToView(view);
2850 return doSetup(config);
2851}
2852function setupDirect(options = {}, node) {
2853 const config = createConfig(options, defaultOptionsDirect, node);
2854 prepareDocument(config.document);
2855 return {
2856 config,
2857 api: doSetup(config)
2858 };
2859}
2860function setupSub(options) {
2861 return doSetup(__spreadValues(__spreadValues({}, this[Config]), options));
2862}
2863function wrapAndBindImpl(instance, impl) {
2864 function method(...args) {
2865 setLevelRef(instance[Config], 1 /* Call */);
2866 return wrapAsync(() => impl.apply(instance, args));
2867 }
2868 Object.defineProperty(method, "name", { get: () => impl.name });
2869 return method;
2870}
2871function doSetup(config) {
2872 const instance = __spreadValues({
2873 [Config]: config,
2874 dispatchUIEvent: bindDispatchUIEvent(config)
2875 }, api_exports);
2876 return __spreadProps(__spreadValues({}, Object.fromEntries(Object.entries(api_exports).map(([name, api]) => [
2877 name,
2878 wrapAndBindImpl(instance, api)
2879 ]))), {
2880 setup: setupSub.bind(instance)
2881 });
2882}
2883function getDocument(options, node) {
2884 var _a, _b;
2885 return (_b = (_a = options.document) != null ? _a : node && getDocumentFromNode(node)) != null ? _b : document;
2886}
2887
2888// src/setup/directApi.ts
2889var directApi_exports = {};
2890__export(directApi_exports, {
2891 clear: () => clear2,
2892 click: () => click2,
2893 copy: () => copy2,
2894 cut: () => cut2,
2895 dblClick: () => dblClick2,
2896 deselectOptions: () => deselectOptions2,
2897 hover: () => hover2,
2898 keyboard: () => keyboard2,
2899 paste: () => paste2,
2900 pointer: () => pointer2,
2901 selectOptions: () => selectOptions2,
2902 tab: () => tab2,
2903 tripleClick: () => tripleClick2,
2904 type: () => type2,
2905 unhover: () => unhover2,
2906 upload: () => upload2
2907});
2908function clear2(element) {
2909 return setupDirect().api.clear(element);
2910}
2911function click2(element, options = {}) {
2912 return setupDirect(options, element).api.click(element);
2913}
2914function copy2(options = {}) {
2915 return setupDirect(options).api.copy();
2916}
2917function cut2(options = {}) {
2918 return setupDirect(options).api.cut();
2919}
2920function dblClick2(element, options = {}) {
2921 return setupDirect(options).api.dblClick(element);
2922}
2923function deselectOptions2(select, values, options = {}) {
2924 return setupDirect(options).api.deselectOptions(select, values);
2925}
2926function hover2(element, options = {}) {
2927 return setupDirect(options).api.hover(element);
2928}
2929function keyboard2(_0) {
2930 return __async(this, arguments, function* (text, options = {}) {
2931 const { config, api } = setupDirect(options);
2932 return api.keyboard(text).then(() => config.keyboardState);
2933 });
2934}
2935function pointer2(_0) {
2936 return __async(this, arguments, function* (input2, options = {}) {
2937 const { config, api } = setupDirect(options);
2938 return api.pointer(input2).then(() => config.pointerState);
2939 });
2940}
2941function paste2(clipboardData, options) {
2942 return setupDirect(options).api.paste(clipboardData);
2943}
2944function selectOptions2(select, values, options = {}) {
2945 return setupDirect(options).api.selectOptions(select, values);
2946}
2947function tripleClick2(element, options = {}) {
2948 return setupDirect(options).api.tripleClick(element);
2949}
2950function type2(element, text, options = {}) {
2951 return setupDirect(options, element).api.type(element, text, options);
2952}
2953function unhover2(element, options = {}) {
2954 const { config, api } = setupDirect(options);
2955 config.pointerState.position.mouse.target = element;
2956 return api.unhover(element);
2957}
2958function upload2(element, fileOrFiles, options = {}) {
2959 return setupDirect(options).api.upload(element, fileOrFiles);
2960}
2961function tab2(options = {}) {
2962 return setupDirect().api.tab(options);
2963}
2964
2965// src/setup/index.ts
2966var userEvent = __spreadProps(__spreadValues({}, directApi_exports), {
2967 setup: setupMain
2968});
2969export {
2970 PointerEventsCheckLevel,
2971 userEvent as default
2972};