Guard drops whose position resolves outside of the editor - #6105
Open
janpaepke wants to merge 1 commit into
Open
Guard drops whose position resolves outside of the editor#6105janpaepke wants to merge 1 commit into
janpaepke wants to merge 1 commit into
Conversation
… of the editor `<Editable>` resolved the drop target via `caretRangeFromPoint`, which can land on a node outside of the editor although the event's target is inside it: the drop is dispatched to the target of the last `dragover` while the coordinates are the drop's own, so a page scroll in between separates them. The resulting "Cannot resolve a Slate point from DOM point" escaped the handler and the drop was lost. `findEventRange` gains `suppressThrow`, mirroring `toSlatePoint` and `toSlateRange`, and the drop handler falls back to the current selection (or the end of the document) when there is no range. An internal drag without a target leaves its content in place rather than re-inserting it over itself.
🦋 Changeset detectedLatest commit: ed1bde2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Dropping into
<Editable>throwsCannot resolve a Slate point from DOM pointwhen the browser resolves the drop position to a node outside of the editor, and the drop is lost.onDropchecks thatevent.targetis inside the editor, then resolves the range fromclientX/clientYviacaretRangeFromPoint. The two can disagree: WebKit dispatchesdropto the element captured at the lastdragoverwhile the coordinates are the drop's own, so a page scroll during the drag lands the caret on neighbouring text. Seen in production in Safari 18.6 on macOS, where the caret resolved to the end of a<label>above the editor.With this change the dropped data is inserted at the current selection (or the end of the document when there is none), and an internal drag without a resolvable target leaves its content where it is.
Issue
No dedicated issue. Related: #5107 (the same
caretRangeFromPointfragility inside shadow DOM).Example
Before: the handler threw, nothing was inserted and the error surfaced as uncaught. After: the data lands at the selection.
Context
DOMEditor.findEventRangegets an optionalsuppressThrow, followingtoSlatePoint/toSlateRangeand the optionuseSelectedgained in fix(slate-react): prevent useSelected from throwing when element is removed #6073. It forwards the flag totoSlateRangeand returnsnullfor the two early throws as well.toSlatePoint/toSlateRange, the options object is optional and the generic defaults tofalse, so existing callers keep the plainRangereturn type; only callers passingtrueseeRange | null.<Editable>'sonDropbranches on the result: with a range, behaviour is unchanged; without one and an internal drag, it returns afterpreventDefault; otherwise it selects the end of the document when nothing is selected and callsinsertDataas before. Thechildren.length > 0guard mirrorsfocus.onDropcases dispatching a realdropevent through React with a stubbedcaretRangeFromPoint(jsdom implements neither it norDataTransfer).Checks
yarn test:jest(101 passed).yarn lint:typescript; eslint and prettier on the changed files).slate-domminor,slate-reactpatch).