Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redefine userEvent.paste behavior #782

Closed
ph-fritsche opened this issue Nov 15, 2021 · 4 comments · Fixed by #785
Closed

Redefine userEvent.paste behavior #782

ph-fritsche opened this issue Nov 15, 2021 · 4 comments · Fixed by #785
Milestone

Comments

@ph-fritsche
Copy link
Member

Problem description:

The current implementation of userEvent.paste(element, text, init, options) does:

  1. Throw error if element is neither editable input nor textarea.
  2. Do nothing on disabled.
  3. Focus element without properly updating selection.
  4. If element supports selection range and selection is 0,0 set selection so options.initialSelectionStart, options.initialSelectionEnd if given, element.value.length, element.value.length otherwise.
  5. Fire paste event with user supplied EventInit init.
  6. Return on readonly element
  7. Input (inputType: 'insertFromPaste') text` at current range.

This does not reflect an interaction a user could perform.
It does not support contenteditable or properly honor selection range.
It does not support paste events outside of editable context.

Suggested solution:

Replace API with userEvent.paste(clipboardData?: DataTransfer | string) that:

  1. If clipboardData is a string, create a DataTransfer object with it.
  2. If clipboardData is undefined, try to read data from Clipboard API if available. (This step requires the new implementation to be async.)
  3. If clipboardData is undefined and data could not be retrieved from Clipboard, reject.
  4. Dispatch paste event.
  5. If in editable context, insert the data into DOM and dispatch an input event.

This would allow
a) the user to paste outside of input/textarea.
b) the user to test workflows using Clipboard API if it is available. (Clipboard API could also be mocked in Jsdom.)
c) the user to paste non-text elements.
d) us to implement copy/paste of DOM elements in contenteditable later.

@ph-fritsche ph-fritsche added this to the userEvent v14 milestone Nov 15, 2021
@ph-fritsche
Copy link
Member Author

@kentcdodds @nickmccurdy Any opinion on this?

@kentcdodds
Copy link
Member

Looks pretty good to me! One thing, what about disabled elements?

@ph-fritsche
Copy link
Member Author

ph-fritsche commented Nov 16, 2021

The document.activeElement should never be a disabled element.
If a user e.g. clicks on a disabled element, the closest focusable element will gain focus and be the new activeElement.
The redefined API would have no element parameter and always dispatch events on the activeElement.

(I say should because the behavior in browsers if the activeElement gets disabled seems to be inconsistent. Chrome sets document.activeElement to the document.body, Firefox stops dispatching any events even if you tab to another element until the next click that sets focus)

@kentcdodds
Copy link
Member

Makes sense! Sounds great!

@ph-fritsche ph-fritsche linked a pull request Nov 17, 2021 that will close this issue
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants