UNPKG

@testing-library/user-event

Version:
101 lines (98 loc) 3.92 kB
import '../utils/click/isClickableInput.js'; import '../utils/dataTransfer/Clipboard.js'; import '../utils/edit/maxLength.js'; import '../utils/edit/isEditable.js'; import '@testing-library/dom'; import '@testing-library/dom/dist/helpers.js'; import '../utils/keyDef/readNextDescriptor.js'; import '../utils/misc/level.js'; import '../options.js'; import '../event/eventMap.js'; import '../event/behavior/click.js'; import '../event/behavior/cut.js'; import '../event/behavior/keydown.js'; import '../event/behavior/keypress.js'; import '../event/behavior/keyup.js'; import '../event/behavior/paste.js'; import { prepareInterceptor } from './interceptor.js'; import { getUIValue } from './value.js'; const UISelection = Symbol('Displayed selection in UI'); function prepareSelectionInterceptor(element) { prepareInterceptor(element, 'setSelectionRange', function interceptorImpl(start, ...others) { const isUI = start && typeof start === 'object' && start[UISelection]; if (!isUI) { this[UISelection] = undefined; } return { applyNative: !!isUI, realArgs: [ Number(start), ...others ] }; }); prepareInterceptor(element, 'selectionStart', function interceptorImpl(v) { this[UISelection] = undefined; return { realArgs: v }; }); prepareInterceptor(element, 'selectionEnd', function interceptorImpl(v) { this[UISelection] = undefined; return { realArgs: v }; }); prepareInterceptor(element, 'select', function interceptorImpl() { this[UISelection] = { anchorOffset: 0, focusOffset: getUIValue(element).length }; return { realArgs: [] }; }); } function setUISelection(element, { focusOffset: focusOffsetParam , anchorOffset: anchorOffsetParam = focusOffsetParam }, mode = 'replace') { const valueLength = getUIValue(element).length; const sanitizeOffset = (o)=>Math.max(0, Math.min(valueLength, o)); const anchorOffset = mode === 'replace' || element[UISelection] === undefined ? sanitizeOffset(anchorOffsetParam) : element[UISelection].anchorOffset; const focusOffset = sanitizeOffset(focusOffsetParam); const startOffset = Math.min(anchorOffset, focusOffset); const endOffset = Math.max(anchorOffset, focusOffset); element[UISelection] = { anchorOffset, focusOffset }; if (element.selectionStart === startOffset && element.selectionEnd === endOffset) { return; } // eslint-disable-next-line no-new-wrappers const startObj = new Number(startOffset); startObj[UISelection] = UISelection; try { element.setSelectionRange(startObj, endOffset); } catch { // DOMException for invalid state is expected when calling this // on an element without support for setSelectionRange } } function getUISelection(element) { var _selectionStart, _selectionEnd, _UISelection; const sel = (_UISelection = element[UISelection]) !== null && _UISelection !== void 0 ? _UISelection : { anchorOffset: (_selectionStart = element.selectionStart) !== null && _selectionStart !== void 0 ? _selectionStart : 0, focusOffset: (_selectionEnd = element.selectionEnd) !== null && _selectionEnd !== void 0 ? _selectionEnd : 0 }; return { ...sel, startOffset: Math.min(sel.anchorOffset, sel.focusOffset), endOffset: Math.max(sel.anchorOffset, sel.focusOffset) }; } function hasUISelection(element) { return !!element[UISelection]; } /** Flag the IDL selection as clean. This does not change the selection. */ function setUISelectionClean(element) { element[UISelection] = undefined; } export { getUISelection, hasUISelection, prepareSelectionInterceptor, setUISelection, setUISelectionClean };