Merge adjacent links with the same URL when pasting#719
Merge adjacent links with the same URL when pasting#719yanfroes wants to merge 4 commits intobasecamp:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes issue #594 where pasting a URL over a selection containing multiple words creates separate LinkNode elements instead of a single merged link. The solution adds link merging functionality that runs after $toggleLink() to consolidate adjacent links with the same URL.
Changes:
- Added
$isLinkNodeimport from@lexical/linkfor type checking - Implemented
#mergeAdjacentLinks()to collect parent elements and trigger merging - Implemented
#mergeAdjacentLinksInElement()to merge consecutive sibling links with matching URLs
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/editor/contents.js
Outdated
| $toggleLink(url) | ||
| this.#mergeAdjacentLinks() |
There was a problem hiding this comment.
There's potentially a more direct route by clearing the existing link?
| $toggleLink(url) | |
| this.#mergeAdjacentLinks() | |
| $toggleLink(null) | |
| $toggleLink(url) |
There was a problem hiding this comment.
@samuelpecher just implemented it! 100% it is a more direct and simpler route, transformed the fix into a one line fix! I think I went the route of merging the links because of the issue description, but your solution was way better!
When pasting a URL over a selection that spans multiple text nodes or existing links, Lexical creates separate LinkNodes for each segment. This results in multiple adjacent anchor tags with the same URL, which is semantically incorrect and causes issues when editing. After applying a link via paste, scan the parent elements of the selection and merge any consecutive LinkNodes that share the same URL by moving children from the second link into the first and removing the duplicate. Fixes basecamp#594
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Instead of merging adjacent LinkNodes after $toggleLink(), clear any existing links first with $toggleLink(null) so Lexical creates a single LinkNode over the entire selection. Also fixed the test.
9701cf6 to
699d0bf
Compare
Fixes #594
Problem:
When pasting a URL over a selection containing multiple words or existing links, Lexical creates separate
LinkNodeelements for each text segment. This results in HTML like:<a href="https://example.com">link1</a><a href="https://example.com"> </a><a href="https://example.com">link2</a>Instead of the expected single link:
<a href="https://example.com">link1 link2</a>This also affects selections spanning multiple list items or other block elements.
Solution:
Before applying the new link, we now clear any existing links in the selection with
$toggleLink(null). This ensures Lexical sees a flat selection of text nodes with no pre-existing link boundaries, so the subsequent$toggleLink(url)creates a singleLinkNodeover the entire selection.Changes:
createLinkWithSelectedTextto clear existing links before applying the new URL