Skip to content

fix: normalize DataTransfer format aliases - #1326

Open
dylanpulver wants to merge 1 commit into
testing-library:mainfrom
dylanpulver:fix/datatransfer-format-aliases
Open

fix: normalize DataTransfer format aliases#1326
dylanpulver wants to merge 1 commit into
testing-library:mainfrom
dylanpulver:fix/datatransfer-format-aliases

Conversation

@dylanpulver

Copy link
Copy Markdown

What

DataTransfer.getData(), setData() and clearData() now normalize their format argument the way the HTML spec requires. The format is converted to ASCII lowercase, and the shorthands text and url are replaced with text/plain and text/uri-list.

Fixes #1269

Why

userEvent.paste('foo') builds its DataTransfer with setData('text', ...), and the stub stored that string verbatim as the item type. A paste handler reading event.clipboardData.types therefore saw ['text'], so the check reported in #1269, types.includes('text/plain'), was false. No browser produces a text type on a clipboard event, so handlers written against real clipboard data did not match.

Two related cases were wrong in the same way on main. setData('url', ...) stored the type url, which left getData('text/uri-list') returning an empty string. Separately, clearData('text') failed to remove an item stored as text/plain, and a format containing uppercase letters was stored and looked up as a type distinct from its lowercase spelling.

The spec puts this mapping inside each of the three methods. setData() converts the format to ASCII lowercase, then changes text to text/plain and url to text/uri-list, at https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-setdata. getData() repeats both steps before looking the item up, at https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-getdata, and clearData() does the same before removing one, at https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-cleardata.

How

The mapping lives in a normalizeFormat() helper in src/utils/dataTransfer/DataTransfer.ts, and all three methods run their format argument through it.

It belongs there rather than in src/clipboard/paste.ts because the type is decided by setData(), not by its callers, so fixing it at the method covers every caller at once. copySelection() and any DataTransfer a user builds and hands to userEvent.paste() reach the same methods, and a change confined to paste.ts would have left the url shorthand and the case handling broken for all of them. paste.ts is untouched and now yields text/plain on its own, which is what the added end to end test asserts.

One part of the spec algorithm is deliberately left out. getData('url') is also supposed to parse a text/uri-list body down to its first URL, which is a separate step from format normalization and is not included here.

tests/utils/dataTransfer/DataTransfer.ts gains a setData and getData round trip through both shorthands, the same round trip written in mixed case, an overwrite where an item declared under one spelling is replaced by writing the other, and a clearData() call that removes an item by its shorthand. tests/clipboard/paste.ts gains the reported scenario, asserting that a paste event built from a string exposes text/plain in types and returns the string from getData('text/plain'). Every added test fails on main and passes with this change.

The whole Jest suite passes at 514 tests in 54 files, npm run validate reports no type errors, and eslint reports no new problems on the changed files.

Checklist

  • Documentation
  • Tests
  • Ready to be merged

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 this pull request may close these issues.

Passing string to userEvent.paste() uses invalid MIME type "text" instead of "text/plain"

1 participant