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

Fix Link UI incorrect text replacement in Rich Text #45710

Merged
merged 4 commits into from
Jan 27, 2023

Conversation

getdave
Copy link
Contributor

@getdave getdave commented Nov 10, 2022

What?

Fixes a bug whereby editing the text of links with identical text content within a rich text field could result in the wrong link's text being updated.

Closes #41771

Why?

It's important that only the text of the currently active link (active format) is updated.

How?

The code was using the @wordpress/rich-text replace() utility to update the RichTextValue object with the modified text. However, replace only operates on the first match it finds. Therefore if the same rich text value contained mulitple links all with the same text then the replace operation would update the text on the first link even if this was not the one being edited.

This PR fixes this by splitting the value at the boundary of the active link format. The replace() is then only run against the second portion of the split value thereby ensuring that the active link format is the first matched by replace.

This PR has to work around what I think may be a bug in split() whereby the split point for the second portion of the value is determined based on the value.end. As values may have start and end which don't match this can result in the string being split incorrectly.

Testing Instructions

  • New Post.
  • Switch to code view and paste:
<!-- wp:paragraph -->
<p><a href="http://www.wordpress.org" data-type="URL" data-id="www.wordpress.org">example</a> is another <a href="http://www.yahoo.com" data-type="URL" data-id="www.yahoo.com">example</a> and another <a href="http://www.wordpress.com" data-type="URL" data-id="www.wordpress.com">example</a></p>
<!-- /wp:paragraph -->

Screenshots or screencast

Screen.Capture.on.2022-11-10.at.10-13-22.mp4
Screen.Capture.on.2022-11-10.at.10-15-05.mp4

@codesandbox
Copy link

codesandbox bot commented Nov 10, 2022

CodeSandbox logoCodeSandbox logo  Open in CodeSandbox Web Editor | VS Code | VS Code Insiders

@getdave getdave self-assigned this Nov 10, 2022
@getdave getdave added [Type] Bug An existing feature does not function as intended [Feature] Link Editing Link components (LinkControl, URLInput) and integrations (RichText link formatting) labels Nov 10, 2022
@getdave getdave marked this pull request as ready for review November 10, 2022 17:16
@getdave getdave requested review from draganescu and removed request for draganescu November 10, 2022 17:19
@github-actions
Copy link

github-actions bot commented Nov 10, 2022

Size Change: +11.3 kB (+1%)

Total Size: 1.31 MB

Filename Size Change
build/a11y/index.min.js 993 B +11 B (+1%)
build/annotations/index.min.js 2.78 kB +18 B (+1%)
build/api-fetch/index.min.js 2.27 kB +10 B (0%)
build/autop/index.min.js 2.15 kB +8 B (0%)
build/blob/index.min.js 483 B +8 B (+2%)
build/block-directory/index.min.js 7.16 kB +76 B (+1%)
build/block-directory/style-rtl.css 1.04 kB +46 B (+5%) 🔍
build/block-directory/style.css 1.04 kB +47 B (+5%) 🔍
build/block-editor/default-editor-styles-rtl.css 403 B +25 B (+7%) 🔍
build/block-editor/default-editor-styles.css 403 B +25 B (+7%) 🔍
build/block-editor/index.min.js 191 kB +16.1 kB (+9%) 🔍
build/block-editor/style-rtl.css 14.3 kB -1.55 kB (-10%) 👏
build/block-editor/style.css 14.3 kB -1.56 kB (-10%) 👏
build/block-library/blocks/audio/theme-rtl.css 138 B +12 B (+10%) ⚠️
build/block-library/blocks/audio/theme.css 138 B +12 B (+10%) ⚠️
build/block-library/blocks/block/editor-rtl.css 305 B +144 B (+89%) 🆘
build/block-library/blocks/block/editor.css 305 B +144 B (+89%) 🆘
build/block-library/blocks/button/editor-rtl.css 485 B +3 B (+1%)
build/block-library/blocks/button/editor.css 485 B +3 B (+1%)
build/block-library/blocks/cover/style-rtl.css 1.57 kB +8 B (+1%)
build/block-library/blocks/cover/style.css 1.56 kB +8 B (+1%)
build/block-library/blocks/embed/theme-rtl.css 138 B +12 B (+10%) ⚠️
build/block-library/blocks/embed/theme.css 138 B +12 B (+10%) ⚠️
build/block-library/blocks/file/view.min.js 353 B +7 B (+2%)
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB +2 B (0%)
build/block-library/blocks/gallery/editor-rtl.css 984 B +36 B (+4%)
build/block-library/blocks/gallery/editor.css 988 B +38 B (+4%)
build/block-library/blocks/gallery/style-rtl.css 1.55 kB +19 B (+1%)
build/block-library/blocks/gallery/style.css 1.55 kB +19 B (+1%)
build/block-library/blocks/gallery/theme-rtl.css 122 B +14 B (+13%) ⚠️
build/block-library/blocks/gallery/theme.css 122 B +14 B (+13%) ⚠️
build/block-library/blocks/group/editor-rtl.css 654 B +260 B (+66%) 🆘
build/block-library/blocks/group/editor.css 654 B +260 B (+66%) 🆘
build/block-library/blocks/html/editor-rtl.css 332 B +5 B (+2%)
build/block-library/blocks/html/editor.css 333 B +4 B (+1%)
build/block-library/blocks/image/editor-rtl.css 829 B -51 B (-6%)
build/block-library/blocks/image/editor.css 828 B -52 B (-6%)
build/block-library/blocks/image/theme-rtl.css 137 B +11 B (+9%) 🔍
build/block-library/blocks/image/theme.css 137 B +11 B (+9%) 🔍
build/block-library/blocks/navigation-link/editor-rtl.css 716 B +4 B (+1%)
build/block-library/blocks/navigation-link/editor.css 715 B +4 B (+1%)
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B +3 B (+1%)
build/block-library/blocks/navigation-submenu/editor.css 299 B +4 B (+1%)
build/block-library/blocks/navigation/editor-rtl.css 2.13 kB -19 B (-1%)
build/block-library/blocks/navigation/editor.css 2.14 kB -19 B (-1%)
build/block-library/blocks/navigation/style-rtl.css 2.22 kB +5 B (0%)
build/block-library/blocks/navigation/style.css 2.2 kB +1 B (0%)
build/block-library/blocks/navigation/view-modal.min.js 2.81 kB +28 B (+1%)
build/block-library/blocks/navigation/view.min.js 447 B +4 B (+1%)
build/block-library/blocks/page-list/editor-rtl.css 376 B +13 B (+4%)
build/block-library/blocks/page-list/editor.css 376 B +13 B (+4%)
build/block-library/blocks/post-featured-image/style-rtl.css 318 B +3 B (+1%)
build/block-library/blocks/post-featured-image/style.css 318 B +3 B (+1%)
build/block-library/blocks/rss/editor-rtl.css 149 B -53 B (-26%) 🎉
build/block-library/blocks/rss/editor.css 149 B -55 B (-27%) 🎉
build/block-library/blocks/shortcode/editor-rtl.css 474 B +10 B (+2%)
build/block-library/blocks/shortcode/editor.css 474 B +10 B (+2%)
build/block-library/blocks/spacer/editor-rtl.css 332 B +10 B (+3%)
build/block-library/blocks/spacer/editor.css 332 B +10 B (+3%)
build/block-library/blocks/table/editor-rtl.css 433 B -72 B (-14%) 👏
build/block-library/blocks/table/editor.css 433 B -72 B (-14%) 👏
build/block-library/blocks/table/style-rtl.css 651 B +20 B (+3%)
build/block-library/blocks/table/style.css 650 B +19 B (+3%)
build/block-library/blocks/table/theme-rtl.css 157 B -15 B (-9%)
build/block-library/blocks/table/theme.css 157 B -15 B (-9%)
build/block-library/blocks/template-part/editor-rtl.css 404 B +169 B (+72%) 🆘
build/block-library/blocks/template-part/editor.css 404 B +169 B (+72%) 🆘
build/block-library/blocks/verse/style-rtl.css 99 B +12 B (+14%) ⚠️
build/block-library/blocks/verse/style.css 99 B +12 B (+14%) ⚠️
build/block-library/blocks/video/style-rtl.css 179 B +5 B (+3%)
build/block-library/blocks/video/style.css 179 B +5 B (+3%)
build/block-library/blocks/video/theme-rtl.css 139 B +13 B (+10%) ⚠️
build/block-library/blocks/video/theme.css 139 B +13 B (+10%) ⚠️
build/block-library/common-rtl.css 1.05 kB +35 B (+3%)
build/block-library/common.css 1.05 kB +34 B (+3%)
build/block-library/editor-rtl.css 11.7 kB +344 B (+3%)
build/block-library/editor.css 11.6 kB +336 B (+3%)
build/block-library/index.min.js 199 kB +6.25 kB (+3%)
build/block-library/style-rtl.css 12.4 kB +47 B (0%)
build/block-library/style.css 12.4 kB +47 B (0%)
build/block-library/theme-rtl.css 698 B -6 B (-1%)
build/block-library/theme.css 703 B -5 B (-1%)
build/block-serialization-default-parser/index.min.js 1.13 kB +8 B (+1%)
build/blocks/index.min.js 50.4 kB +464 B (+1%)
build/components/index.min.js 203 kB +477 B (0%)
build/components/style-rtl.css 11.6 kB +295 B (+3%)
build/components/style.css 11.7 kB +290 B (+3%)
build/compose/index.min.js 12.3 kB +95 B (+1%)
build/core-data/index.min.js 15.9 kB +431 B (+3%)
build/customize-widgets/index.min.js 11.7 kB +384 B (+3%)
build/customize-widgets/style-rtl.css 1.41 kB +27 B (+2%)
build/customize-widgets/style.css 1.41 kB +27 B (+2%)
build/data-controls/index.min.js 663 B +10 B (+2%)
build/data/index.min.js 8.06 kB -18 B (0%)
build/date/index.min.js 32.1 kB +6 B (0%)
build/deprecated/index.min.js 518 B +11 B (+2%)
build/dom-ready/index.min.js 336 B +12 B (+4%)
build/dom/index.min.js 4.71 kB +20 B (0%)
build/edit-navigation/index.min.js 0 B -16.1 kB (removed) 🏆
build/edit-navigation/style-rtl.css 0 B -3.99 kB (removed) 🏆
build/edit-navigation/style.css 0 B -4 kB (removed) 🏆
build/edit-post/classic-rtl.css 571 B +25 B (+5%) 🔍
build/edit-post/classic.css 571 B +24 B (+4%)
build/edit-post/index.min.js 34.4 kB +242 B (+1%)
build/edit-post/style-rtl.css 7.46 kB +149 B (+2%)
build/edit-post/style.css 7.45 kB +151 B (+2%)
build/edit-site/index.min.js 63.5 kB +5.31 kB (+9%) 🔍
build/edit-site/style-rtl.css 9.52 kB +1.16 kB (+14%) ⚠️
build/edit-site/style.css 9.53 kB +1.17 kB (+14%) ⚠️
build/edit-widgets/index.min.js 16.8 kB +96 B (+1%)
build/edit-widgets/style-rtl.css 4.49 kB +146 B (+3%)
build/edit-widgets/style.css 4.49 kB +147 B (+3%)
build/editor/index.min.js 45.2 kB +1.56 kB (+4%)
build/editor/style-rtl.css 3.68 kB +81 B (+2%)
build/editor/style.css 3.67 kB +81 B (+2%)
build/element/index.min.js 4.93 kB +251 B (+5%) 🔍
build/escape-html/index.min.js 548 B +11 B (+2%)
build/experiments/index.min.js 870 B +2 B (0%)
build/format-library/index.min.js 7.23 kB +285 B (+4%)
build/format-library/style-rtl.css 598 B +27 B (+5%) 🔍
build/format-library/style.css 597 B +26 B (+5%) 🔍
build/hooks/index.min.js 1.66 kB +28 B (+2%)
build/html-entities/index.min.js 454 B +6 B (+1%)
build/i18n/index.min.js 3.79 kB +17 B (0%)
build/is-shallow-equal/index.min.js 535 B +8 B (+2%)
build/keyboard-shortcuts/index.min.js 1.79 kB +11 B (+1%)
build/keycodes/index.min.js 1.88 kB +52 B (+3%)
build/list-reusable-blocks/index.min.js 2.14 kB +6 B (0%)
build/list-reusable-blocks/style-rtl.css 865 B +30 B (+4%)
build/list-reusable-blocks/style.css 865 B +30 B (+4%)
build/media-utils/index.min.js 2.99 kB +64 B (+2%)
build/notices/index.min.js 977 B +14 B (+1%)
build/nux/index.min.js 0 B -2.06 kB (removed) 🏆
build/nux/style-rtl.css 0 B -732 B (removed) 🏆
build/nux/style.css 0 B -728 B (removed) 🏆
build/plugins/index.min.js 1.95 kB +9 B (0%)
build/preferences-persistence/index.min.js 2.23 kB +9 B (0%)
build/preferences/index.min.js 1.35 kB +16 B (+1%)
build/primitives/index.min.js 960 B +16 B (+2%)
build/priority-queue/index.min.js 1.52 kB -60 B (-4%)
build/react-i18n/index.min.js 702 B +6 B (+1%)
build/react-refresh-entry/index.min.js 8.44 kB +5 B (0%)
build/react-refresh-runtime/index.min.js 7.31 kB -2 B (0%)
build/redux-routine/index.min.js 2.75 kB +10 B (0%)
build/reusable-blocks/index.min.js 2.27 kB +61 B (+3%)
build/reusable-blocks/style-rtl.css 265 B +9 B (+4%)
build/reusable-blocks/style.css 265 B +9 B (+4%)
build/rich-text/index.min.js 10.8 kB +94 B (+1%)
build/server-side-render/index.min.js 2.09 kB +317 B (+18%) ⚠️
build/shortcode/index.min.js 1.52 kB -2 B (0%)
build/style-engine/index.min.js 1.53 kB +47 B (+3%)
build/token-list/index.min.js 650 B +6 B (+1%)
build/url/index.min.js 3.69 kB +82 B (+2%)
build/vendors/react-dom.min.js 41.8 kB +3.26 kB (+8%) 🔍
build/vendors/react.min.js 4.02 kB -317 B (-7%)
build/viewport/index.min.js 1.09 kB +9 B (+1%)
build/warning/index.min.js 280 B +12 B (+4%)
build/widgets/index.min.js 7.31 kB +91 B (+1%)
build/widgets/style-rtl.css 1.18 kB -4 B (0%)
build/widgets/style.css 1.18 kB -5 B (0%)
build/wordcount/index.min.js 1.06 kB +2 B (0%)
ℹ️ View Unchanged
Filename Size
build/block-editor/content-rtl.css 3.66 kB
build/block-editor/content.css 3.66 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 84 B
build/block-library/blocks/avatar/style.css 84 B
build/block-library/blocks/button/style-rtl.css 532 B
build/block-library/blocks/button/style.css 532 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 100 B
build/block-library/blocks/categories/style.css 100 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 612 B
build/block-library/blocks/cover/editor.css 613 B
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 253 B
build/block-library/blocks/file/style.css 254 B
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/image/style-rtl.css 627 B
build/block-library/blocks/image/style.css 630 B
build/block-library/blocks/latest-comments/style-rtl.css 298 B
build/block-library/blocks/latest-comments/style.css 298 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 507 B
build/block-library/blocks/media-text/style.css 505 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 174 B
build/block-library/blocks/paragraph/editor.css 174 B
build/block-library/blocks/paragraph/style-rtl.css 279 B
build/block-library/blocks/paragraph/style.css 281 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 501 B
build/block-library/blocks/post-comments-form/style.css 501 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 586 B
build/block-library/blocks/post-featured-image/editor.css 584 B
build/block-library/blocks/post-navigation-link/style-rtl.css 153 B
build/block-library/blocks/post-navigation-link/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 282 B
build/block-library/blocks/post-template/style.css 282 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 326 B
build/block-library/blocks/pullquote/style.css 325 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 440 B
build/block-library/blocks/query/editor.css 440 B
build/block-library/blocks/quote/style-rtl.css 213 B
build/block-library/blocks/quote/style.css 213 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 409 B
build/block-library/blocks/search/style.css 406 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 234 B
build/block-library/blocks/separator/style.css 234 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/site-logo/editor-rtl.css 490 B
build/block-library/blocks/site-logo/editor.css 490 B
build/block-library/blocks/site-logo/style-rtl.css 203 B
build/block-library/blocks/site-logo/style.css 203 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.4 kB
build/block-library/blocks/social-links/style.css 1.39 kB
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/video/editor-rtl.css 691 B
build/block-library/blocks/video/editor.css 694 B
build/block-library/classic-rtl.css 162 B
build/block-library/classic.css 162 B
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/vendors/inert-polyfill.min.js 2.48 kB

compressed-size-action

const [ valBefore, valAfter ] = split(
value,
boundary.start,
boundary.start
Copy link
Contributor Author

@getdave getdave Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ellatrix I don't think passing this should be necessary but it is.

Firstly the split() function only accepts 2 args not 3. The only reason this works is that it uses ...arguments to delegate to the splitAtSelection function which does accept a 3rd parameter.

By default the 3rd param of splitAtSelection defaults to the passed value's end property. In the case of split() we always want to split the string at position X as defined by the 2nd argument. However in some cases the start and end of the value may not match and thus the value is split incorrectly.

I'm having to pass boundary.start as the 3rd ("end") argument to ensure that the value is split in-two at the start of the boundary. Otherwise the second half of the split value often doesj't match what you'd expect.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, by default all of these functions look at the rich text value's current selection. We allow you to override that, and to do that properly you need to provide both a new selection start and end.

Copy link
Contributor Author

@getdave getdave Nov 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...but split() doesn't actually have an end argument, it just has string (which can be used to provide a start index):

export function split( { formats, replacements, text, start, end }, string ) {

* @param {number|string} [string] Start index, or string at which to split.

The only reason the method I'm using in this PR works is that ...arguments is utilised to pass all of split's arguments to splitAtSelection:

if ( typeof string !== 'string' ) {
return splitAtSelection( ...arguments );
}

So it's not obvious from the function signature that you can/should provide an end.

We allow you to override that, and to do that properly you need to provide both a new selection start and end.

Is the intention that you manually update the selection on the value being passed into split before it's passed in?

I still feel it's confusing...

endIndex is set to value.end

function splitAtSelection(
{ formats, replacements, text, start, end },
startIndex = start,
endIndex = end
) {

....which may produce unexpected results when (as instructed in the doc block) you've passed an explicit Start index into the split() as the 2nd string argument.

If I pass X as string then I'd expect the value to be split at X. What can actually happen is the value is split at X but the (remaining) second half of the value is not split at X but at whatever value.end is.

const after = {
formats: formats.slice( endIndex ),
replacements: replacements.slice( endIndex ),
text: text.slice( endIndex ),
start: 0,
end: 0,
};

Could / should we instead default endIndex to startIndex so that (by default) if a start index is passed to split as string then it will split where you expect it to?

@mreishus
Copy link
Contributor

In my testing, this is fixing the issue described in #41771 👍

@getdave getdave added [Package] Format library /packages/format-library [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable and removed [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable labels Nov 15, 2022
scruffian
scruffian previously approved these changes Nov 17, 2022
Copy link
Contributor

@scruffian scruffian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense and works as advertised. It does seem unfortunate that it relies on a quirk of splitAtSelection, so I think it would also make sense to get a review from @ellatrix.

@ellatrix
Copy link
Member

ellatrix commented Nov 18, 2022

@getdave Most important things first, could we add an e2e test please? ☺️

@@ -148,14 +151,37 @@ function InlineLinkUI( {
newText.length
);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting on folded code above here. What happens to existing formats? I see that you're creating a new rich text value with the new text, and then applying a link format to it. But by replacing the exiting selection with this new rich text value, any existing formatting will be removed (e.g. bold or italic).

Perhaps this is the wrong way to approach the text replacement? I think we should do the replacement in two steps:

  1. Replace the link format's URL as we would normally do.
  2. Replace the active link's text only.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeh clobbering other formats doesn't sound great 😰

@getdave getdave dismissed scruffian’s stale review November 18, 2022 11:01

Needs more work

@getdave getdave requested review from ntwb and nerrad as code owners January 26, 2023 19:43
@getdave getdave requested a review from ajitbohra as a code owner January 26, 2023 19:43
@getdave
Copy link
Contributor Author

getdave commented Jan 26, 2023

@getdave Most important things first, could we add an e2e test please? ☺️

@ellatrix This now has an e2e test which emulates the Issue reported and verifies the result is now as expected (i.e. no bug).

We should still address your feedback but in a follow up.

@getdave getdave requested review from ellatrix and scruffian January 26, 2023 19:44
@getdave getdave changed the title Fix Link UI incorrect text replacement Fix Link UI incorrect text replacement in Rich Text Jan 26, 2023
Copy link
Contributor

@draganescu draganescu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR fixes the problem, but will need one follow up for tweaking how the fix is applied. Most importantly:

  • applying a link on a text that has a link removes all previous formatting

However, the problem it fixes should be worth the trade off for now.

@draganescu draganescu merged commit ac2f060 into trunk Jan 27, 2023
@draganescu draganescu deleted the fix/link-ui-text-incorrect-replacement branch January 27, 2023 10:28
@github-actions github-actions bot added this to the Gutenberg 15.1 milestone Jan 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Link Editing Link components (LinkControl, URLInput) and integrations (RichText link formatting) [Package] Format library /packages/format-library [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Link UI: Changing link text can modify the wrong text
5 participants