RichText: useAnchor: Fix TypeError in virtual element#75900
Conversation
|
I'll note that this one would have readily been caught by our type checker if it were enabled in that file (by converting it to |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Size Change: -21 B (0%) Total Size: 6.84 MB
ℹ️ View Unchanged
|
|
While debugging I noticed this: Screen.Recording.2026-02-25.at.10.58.02.movIs it a smell that the virtual element's |
| const rect = getRectangleFromRange( range ); | ||
| if ( rect ) { | ||
| return rect; | ||
| } |
There was a problem hiding this comment.
Use instead of
Range.getBoundingClientRect(), which is often broken, especially for collapsed ranges.
Based on this documentation part, I wonder which is better in this case. Returning editableContentElement.getBoundingClientRect() as a fallback or trying Range.getBoundingClientRect(). Ref: #73853.
There was a problem hiding this comment.
Not sure. Does it matter much? Also cc @ntsekouras
There was a problem hiding this comment.
With the cursor/text-selection rects, inline popovers should have better (more accurate) positioning.
There was a problem hiding this comment.
Yeah, I see what you mean. So, to confirm, the chain of fallbacks you were thinking of was:
- getRectangleFromRange
- Range.getBoundingClientRect
- editableContentElement.getBoundingClientRect
Yes?
There was a problem hiding this comment.
Yeah, seems "safest" approach.
Though it would be nice to get a second opinion from folks who are more familiar with this anchor logic. cc @ellatrix, @ciampo
diff --git a/packages/rich-text/src/hook/use-anchor.js b/packages/rich-text/src/hook/use-anchor.js
index 4746b15d95f..36d7390af3e 100644
--- a/packages/rich-text/src/hook/use-anchor.js
+++ b/packages/rich-text/src/hook/use-anchor.js
@@ -88,10 +88,10 @@ function createVirtualAnchorElement( range, editableContentElement ) {
contextElement: editableContentElement,
getBoundingClientRect() {
if ( editableContentElement.contains( range.startContainer ) ) {
- const rect = getRectangleFromRange( range );
- if ( rect ) {
- return rect;
- }
+ return (
+ getRectangleFromRange( range ) ??
+ range.getBoundingClientRect()
+ );
}
return editableContentElement.getBoundingClientRect();There was a problem hiding this comment.
This feels like a good approach to me. From what I recall, getRectangleFromRange returns nullin a very specific edge case (multiple rects for a collapsed range), and in that case, range.getBoundingClientRect() feels like a reasonable fallback (always guaranteed to return a DomRect, and also not too far from the cursor).
I think that's expected behaviour (the underlying
1000%. IMO we should try to convert these files to TS as much as possible, as we get an extra layer of static linting that can really iron out a lot of subtle bugs, such as the one fixed in this PR. |
|
Thanks for the feedback, everyone! I've pushed the change with the fallback. I also have a Git stash that fixes all type errors in the module, will put up a PR after lunch. |
Props Mamaduka
6105318 to
2a77135
Compare
This commit is to be removed once #75900 is merged and the branch is rebased on top of trunk.
|
I appreciate the quick fix folks ❤️ |
|
Added the backport label for the bugfix. It's a bug that affects the Gutenberg version included in this release. |
* RichText: useAnchor: Fix TypeError in virtual element Fixes #75897 * Fall back to range.getBoundingClientRect when possible Props Mamaduka Co-authored-by: mcsf <mcsf@git.wordpress.org> Co-authored-by: Mamaduka <mamaduka@git.wordpress.org> Co-authored-by: ciampo <mciampini@git.wordpress.org> Co-authored-by: youknowriad <youknowriad@git.wordpress.org>
|
I just cherry-picked this PR to the wp/7.0 branch to get it included in the next release: b1cccdf |
CI run: #11059. See #64595. --- I've included a log of the Gutenberg changes with the following command: git log --reverse --format="- %s" 23b566c72e9c4a36219ef5d6e62890f05551f6cb..022d8dd3d461f91b15c1f0410649d3ebb027207f | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy - Pattern Editing: Fix nested patterns/sections (WordPress/gutenberg#75772) - QuickEdit: rename status label and remove extra labels in popup (WordPress/gutenberg#75824) - Fix block editing modes not recomputing when isolated editor value changes (WordPress/gutenberg#75821) - Synced patterns: Fix block editing mode of synced pattern content when nested in an unsynced pattern (WordPress/gutenberg#75818) - Block Support: Fix custom CSS not saved when style schema is not defined (WordPress/gutenberg#75797) - Gallery: Fixes keyboard focus escaping the lightbox overlay when navigating a gallery with Tab/Shift+Tab. (WordPress/gutenberg#75852) - Navigation Overlay Close: Set Close as default text, rather than using a placeholder (WordPress/gutenberg#75692) - RTC: Fix entity save call / initial persistence. (WordPress/gutenberg#75841) - Real-time collaboration: Improve collaboration within the same rich text (WordPress/gutenberg#75703) - Client Side Media: Add device/browser capability detection (WordPress/gutenberg#75863) - Navigation editing: simplify edit/view buttons (WordPress/gutenberg#75819) - Add core/icon block to theme.json schema (WordPress/gutenberg#75813) - Fix error when undoing newly added pattern (WordPress/gutenberg#75850) - Page List Item: Replace RawHTML with dangerouslySetInnerHTML for label and title (WordPress/gutenberg#75890) - REST API: Make filter_wp_unique_filename() static to match core, plus avoid duplicate routes (WordPress/gutenberg#75782) - RichText: useAnchor: Fix TypeError in virtual element (WordPress/gutenberg#75900) - DataViews: Remove menu divider again. (WordPress/gutenberg#75908) - Theme: Add build plugins to inject design token fallbacks (WordPress/gutenberg#75901) - Theme: Remove global stylesheet (WordPress/gutenberg#75879) - Real-time collaboration: Remove ghost awareness state explicitly when refreshing (WordPress/gutenberg#75883) - Real-time collaboration: Expand mergeCrdtBlocks() automated testing (WordPress/gutenberg#75923) - Fix client-side media file naming (WordPress/gutenberg#75817) - Add: Connectors screen (WordPress/gutenberg#75833) - Merge document meta into state map (WordPress/gutenberg#75830) - Move WordPress meta key from sync package to core-data (WordPress/gutenberg#75846) - Bugfix: Fix casing of getPersistedCRDTDoc (WordPress/gutenberg#75922) - Add debug logging to SyncManager (WordPress/gutenberg#75924) - DataForm: fix label colors (WordPress/gutenberg#75730) - DataViews: minimize padding for primary action buttons (WordPress/gutenberg#75721) (WordPress/gutenberg#75947) - Connectors: Add `_ai_` prefix to connector setting names and fix naming inconsistencies (WordPress/gutenberg#75948) - Connectors: Unhook Core callbacks in Gutenberg coexistence (WordPress/gutenberg#75935) - Unsynced patterns: Rename 'Disconnect pattern' to 'Detach pattern' in context menu (WordPress/gutenberg#75807) - Editor: Remove View dropdown and pinned items from revisions header (WordPress/gutenberg#75951) - Fix: Template revisions infinite spinner (WordPress/gutenberg#75953) - Backport: Avoid flickering while refreshing (WordPress/gutenberg#74572) (WordPress/gutenberg#75952) - Add wp_ prefix to real time collaberation option. (WordPress/gutenberg#75837) git-svn-id: https://develop.svn.wordpress.org/trunk@61750 602fd350-edb4-49c9-b593-d223f7449a82
CI run: WordPress/wordpress-develop#11059. See #64595. --- I've included a log of the Gutenberg changes with the following command: git log --reverse --format="- %s" 23b566c72e9c4a36219ef5d6e62890f05551f6cb..022d8dd3d461f91b15c1f0410649d3ebb027207f | sed 's|#\([0-9][0-9]*\)|https://github.com/WordPress/gutenberg/pull/\1|g; /github\.com\/WordPress\/gutenberg\/pull/!d' | pbcopy - Pattern Editing: Fix nested patterns/sections (WordPress/gutenberg#75772) - QuickEdit: rename status label and remove extra labels in popup (WordPress/gutenberg#75824) - Fix block editing modes not recomputing when isolated editor value changes (WordPress/gutenberg#75821) - Synced patterns: Fix block editing mode of synced pattern content when nested in an unsynced pattern (WordPress/gutenberg#75818) - Block Support: Fix custom CSS not saved when style schema is not defined (WordPress/gutenberg#75797) - Gallery: Fixes keyboard focus escaping the lightbox overlay when navigating a gallery with Tab/Shift+Tab. (WordPress/gutenberg#75852) - Navigation Overlay Close: Set Close as default text, rather than using a placeholder (WordPress/gutenberg#75692) - RTC: Fix entity save call / initial persistence. (WordPress/gutenberg#75841) - Real-time collaboration: Improve collaboration within the same rich text (WordPress/gutenberg#75703) - Client Side Media: Add device/browser capability detection (WordPress/gutenberg#75863) - Navigation editing: simplify edit/view buttons (WordPress/gutenberg#75819) - Add core/icon block to theme.json schema (WordPress/gutenberg#75813) - Fix error when undoing newly added pattern (WordPress/gutenberg#75850) - Page List Item: Replace RawHTML with dangerouslySetInnerHTML for label and title (WordPress/gutenberg#75890) - REST API: Make filter_wp_unique_filename() static to match core, plus avoid duplicate routes (WordPress/gutenberg#75782) - RichText: useAnchor: Fix TypeError in virtual element (WordPress/gutenberg#75900) - DataViews: Remove menu divider again. (WordPress/gutenberg#75908) - Theme: Add build plugins to inject design token fallbacks (WordPress/gutenberg#75901) - Theme: Remove global stylesheet (WordPress/gutenberg#75879) - Real-time collaboration: Remove ghost awareness state explicitly when refreshing (WordPress/gutenberg#75883) - Real-time collaboration: Expand mergeCrdtBlocks() automated testing (WordPress/gutenberg#75923) - Fix client-side media file naming (WordPress/gutenberg#75817) - Add: Connectors screen (WordPress/gutenberg#75833) - Merge document meta into state map (WordPress/gutenberg#75830) - Move WordPress meta key from sync package to core-data (WordPress/gutenberg#75846) - Bugfix: Fix casing of getPersistedCRDTDoc (WordPress/gutenberg#75922) - Add debug logging to SyncManager (WordPress/gutenberg#75924) - DataForm: fix label colors (WordPress/gutenberg#75730) - DataViews: minimize padding for primary action buttons (WordPress/gutenberg#75721) (WordPress/gutenberg#75947) - Connectors: Add `_ai_` prefix to connector setting names and fix naming inconsistencies (WordPress/gutenberg#75948) - Connectors: Unhook Core callbacks in Gutenberg coexistence (WordPress/gutenberg#75935) - Unsynced patterns: Rename 'Disconnect pattern' to 'Detach pattern' in context menu (WordPress/gutenberg#75807) - Editor: Remove View dropdown and pinned items from revisions header (WordPress/gutenberg#75951) - Fix: Template revisions infinite spinner (WordPress/gutenberg#75953) - Backport: Avoid flickering while refreshing (WordPress/gutenberg#74572) (WordPress/gutenberg#75952) - Add wp_ prefix to real time collaberation option. (WordPress/gutenberg#75837) Built from https://develop.svn.wordpress.org/trunk@61750 git-svn-id: http://core.svn.wordpress.org/trunk@61056 1a063a9b-81f0-0310-95a4-ce76da25c4cd
What?
Fixes #75897
Steps to reproduce are in the parent issue