Skip to content

Commit c40e614

Browse files
authored
fix(document): use setters/methods on element as default (#987)
1 parent 29bdf14 commit c40e614

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

src/document/interceptor.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function prepareInterceptor<
5151
...args: Params<ElementType[PropName]>
5252
) {
5353
const {
54-
applyNative = true,
54+
applyNative = false,
5555
realArgs,
5656
then,
5757
} = interceptorImpl.call(this, ...args)

src/document/selection.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ export function prepareSelectionInterceptor(
3232
function interceptorImpl(
3333
this: HTMLInputElement | HTMLTextAreaElement,
3434
start: number | Value | null,
35-
end: number | null,
36-
direction: 'forward' | 'backward' | 'none' = 'none',
35+
...others
3736
) {
3837
const isUI = start && typeof start === 'object' && start[UISelection]
3938

@@ -42,10 +41,11 @@ export function prepareSelectionInterceptor(
4241
}
4342

4443
return {
45-
realArgs: [Number(start), end, direction] as [
44+
applyNative: !!isUI,
45+
realArgs: [Number(start), ...others] as [
4646
number,
4747
number,
48-
typeof direction,
48+
'forward' | 'backward' | 'none' | undefined,
4949
],
5050
}
5151
},

tests/document/index.ts

+42
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,45 @@ test('track changes to value and selection per setRangeText', () => {
202202
expect(getUIValue(element)).toBe('aYcd')
203203
expect(getUISelection(element)).toHaveProperty('focusOffset', 1)
204204
})
205+
206+
test('circumvent setters/methods for UI changes', () => {
207+
const {element} = render<HTMLInputElement>(`<input/>`, {focus: false})
208+
209+
const prototypeDescr = Object.getOwnPropertyDescriptors<HTMLInputElement>(
210+
Object.getPrototypeOf(element) as HTMLInputElement,
211+
)
212+
const valueSpy = jest.fn(prototypeDescr.value.set)
213+
const setSelectionRangeSpy = jest.fn(prototypeDescr.setSelectionRange.value)
214+
215+
Object.defineProperties(element, {
216+
value: {
217+
get: () => {
218+
throw new Error()
219+
},
220+
...prototypeDescr.value,
221+
set: valueSpy,
222+
},
223+
setSelectionRange: {
224+
...prototypeDescr.setSelectionRange,
225+
value: setSelectionRangeSpy,
226+
},
227+
})
228+
229+
prepare(element)
230+
element.focus()
231+
232+
setUIValue(element, 'abcd')
233+
setUISelection(element, {focusOffset: 3})
234+
235+
expect(element).toHaveValue('abcd')
236+
expect(element).toHaveProperty('selectionStart', 3)
237+
expect(valueSpy).not.toBeCalled()
238+
expect(setSelectionRangeSpy).not.toBeCalled()
239+
240+
element.value = 'efgh'
241+
element.setSelectionRange(1, 2)
242+
expect(element).toHaveValue('efgh')
243+
expect(element).toHaveProperty('selectionStart', 1)
244+
expect(valueSpy).toBeCalledWith('efgh')
245+
expect(setSelectionRangeSpy).toBeCalledWith(1, 2)
246+
})

0 commit comments

Comments
 (0)