Skip to content

Fix shift+tab from post title #69520

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

Merged
merged 9 commits into from
Mar 21, 2025
Merged

Fix shift+tab from post title #69520

merged 9 commits into from
Mar 21, 2025

Conversation

stokesman
Copy link
Contributor

@stokesman stokesman commented Mar 10, 2025

What?

Closes #69486

Enables shift+tab from the post title (in "post-only" mode) to navigate to the preceding tab stop as expected.

Why?

The inability to navigate to the previous tab stop from the post title breaks keyboard use and is a regression since WP 6.7.

How?

  • Avoids an error if focus capture elements are not present by returning early.
  • Supports navigation from generic elements within the container, such as the post title, by removing an early return for no block selection.

Testing Instructions

E2E test

  1. Checkout the first commit on this branch which adds an e2e test
  2. Run the test:
    npm run test:e2e -- test/e2e/specs/editor/various/writing-flow.spec.js:893 
  3. Confirm that it fails
  4. Checkout the full branch again (git switch -)
  5. Run the test
  6. Confirm that it passes

Testing Instructions for Keyboard

  1. Open a post in "post-only" mode
  2. Navigate to the post title
  3. Press shift+tab
  4. Confirm that focus moved to the preceding tab stop (could be the notice close button if one happens to be open but it’s probably the "Options" button).
  5. Repeat these steps in a non-iframe context (activate a classic theme and have block registered that’s less than v3)

General testing of tab navigation

  1. Tab through the canvas and make sure it works as before
  2. Go the other direction and make sure it works as before
  3. Repeat these steps in a non-iframe context (activate a classic theme and have block registered that’s less than v3)

@stokesman stokesman added [Type] Bug An existing feature does not function as intended [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... labels Mar 10, 2025
Copy link

github-actions bot commented Mar 10, 2025

Size Change: +18 B (0%)

Total Size: 1.84 MB

Filename Size Change
build/block-editor/index.min.js 263 kB +18 B (+0.01%)
ℹ️ View Unchanged
Filename Size
build-module/a11y/index.min.js 482 B
build-module/block-library/file/view.min.js 447 B
build-module/block-library/form/view.min.js 533 B
build-module/block-library/image/view.min.js 1.8 kB
build-module/block-library/navigation/view.min.js 1.18 kB
build-module/block-library/query/view.min.js 767 B
build-module/block-library/search/view.min.js 639 B
build-module/interactivity-router/index.min.js 3.03 kB
build-module/interactivity/debug.min.js 17.5 kB
build-module/interactivity/index.min.js 13.9 kB
build/a11y/index.min.js 952 B
build/annotations/index.min.js 2.26 kB
build/api-fetch/index.min.js 2.4 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 579 B
build/block-directory/index.min.js 7.15 kB
build/block-directory/style-rtl.css 1.03 kB
build/block-directory/style.css 1.03 kB
build/block-editor/content-rtl.css 4.42 kB
build/block-editor/content.css 4.41 kB
build/block-editor/default-editor-styles-rtl.css 394 B
build/block-editor/default-editor-styles.css 394 B
build/block-editor/style-rtl.css 15.9 kB
build/block-editor/style.css 15.9 kB
build/block-library/blocks/archives/editor-rtl.css 84 B
build/block-library/blocks/archives/editor.css 83 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 149 B
build/block-library/blocks/audio/editor.css 151 B
build/block-library/blocks/audio/style-rtl.css 132 B
build/block-library/blocks/audio/style.css 132 B
build/block-library/blocks/audio/theme-rtl.css 134 B
build/block-library/blocks/audio/theme.css 134 B
build/block-library/blocks/avatar/editor-rtl.css 115 B
build/block-library/blocks/avatar/editor.css 115 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/button/editor-rtl.css 265 B
build/block-library/blocks/button/editor.css 265 B
build/block-library/blocks/button/style-rtl.css 555 B
build/block-library/blocks/button/style.css 555 B
build/block-library/blocks/buttons/editor-rtl.css 291 B
build/block-library/blocks/buttons/editor.css 291 B
build/block-library/blocks/buttons/style-rtl.css 345 B
build/block-library/blocks/buttons/style.css 345 B
build/block-library/blocks/calendar/style-rtl.css 240 B
build/block-library/blocks/calendar/style.css 240 B
build/block-library/blocks/categories/editor-rtl.css 132 B
build/block-library/blocks/categories/editor.css 131 B
build/block-library/blocks/categories/style-rtl.css 152 B
build/block-library/blocks/categories/style.css 152 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 139 B
build/block-library/blocks/code/style.css 139 B
build/block-library/blocks/code/theme-rtl.css 122 B
build/block-library/blocks/code/theme.css 122 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 420 B
build/block-library/blocks/columns/style.css 420 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 124 B
build/block-library/blocks/comment-author-avatar/editor.css 124 B
build/block-library/blocks/comment-author-name/style-rtl.css 72 B
build/block-library/blocks/comment-author-name/style.css 72 B
build/block-library/blocks/comment-content/style-rtl.css 120 B
build/block-library/blocks/comment-content/style.css 120 B
build/block-library/blocks/comment-date/style-rtl.css 65 B
build/block-library/blocks/comment-date/style.css 65 B
build/block-library/blocks/comment-edit-link/style-rtl.css 70 B
build/block-library/blocks/comment-edit-link/style.css 70 B
build/block-library/blocks/comment-reply-link/style-rtl.css 71 B
build/block-library/blocks/comment-reply-link/style.css 71 B
build/block-library/blocks/comment-template/style-rtl.css 191 B
build/block-library/blocks/comment-template/style.css 191 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 238 B
build/block-library/blocks/comments-pagination/editor.css 231 B
build/block-library/blocks/comments-pagination/style-rtl.css 245 B
build/block-library/blocks/comments-pagination/style.css 241 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 842 B
build/block-library/blocks/comments/editor.css 842 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 637 B
build/block-library/blocks/cover/editor-rtl.css 631 B
build/block-library/blocks/cover/editor.css 631 B
build/block-library/blocks/cover/style-rtl.css 1.7 kB
build/block-library/blocks/cover/style.css 1.69 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 331 B
build/block-library/blocks/embed/editor.css 331 B
build/block-library/blocks/embed/style-rtl.css 419 B
build/block-library/blocks/embed/style.css 419 B
build/block-library/blocks/embed/theme-rtl.css 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 326 B
build/block-library/blocks/file/style-rtl.css 278 B
build/block-library/blocks/file/style.css 279 B
build/block-library/blocks/footnotes/style-rtl.css 198 B
build/block-library/blocks/footnotes/style.css 197 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 229 B
build/block-library/blocks/form-input/style-rtl.css 349 B
build/block-library/blocks/form-input/style.css 349 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 344 B
build/block-library/blocks/form-submission-notification/editor.css 341 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/freeform/editor-rtl.css 2.59 kB
build/block-library/blocks/freeform/editor.css 2.59 kB
build/block-library/blocks/gallery/editor-rtl.css 688 B
build/block-library/blocks/gallery/editor.css 691 B
build/block-library/blocks/gallery/style-rtl.css 1.83 kB
build/block-library/blocks/gallery/style.css 1.82 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 334 B
build/block-library/blocks/group/editor.css 334 B
build/block-library/blocks/group/style-rtl.css 103 B
build/block-library/blocks/group/style.css 103 B
build/block-library/blocks/group/theme-rtl.css 79 B
build/block-library/blocks/group/theme.css 79 B
build/block-library/blocks/heading/style-rtl.css 188 B
build/block-library/blocks/heading/style.css 188 B
build/block-library/blocks/html/editor-rtl.css 346 B
build/block-library/blocks/html/editor.css 347 B
build/block-library/blocks/image/editor-rtl.css 763 B
build/block-library/blocks/image/editor.css 763 B
build/block-library/blocks/image/style-rtl.css 1.6 kB
build/block-library/blocks/image/style.css 1.59 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/latest-comments/style-rtl.css 355 B
build/block-library/blocks/latest-comments/style.css 354 B
build/block-library/blocks/latest-posts/editor-rtl.css 139 B
build/block-library/blocks/latest-posts/editor.css 138 B
build/block-library/blocks/latest-posts/style-rtl.css 520 B
build/block-library/blocks/latest-posts/style.css 520 B
build/block-library/blocks/list/style-rtl.css 107 B
build/block-library/blocks/list/style.css 107 B
build/block-library/blocks/loginout/style-rtl.css 61 B
build/block-library/blocks/loginout/style.css 61 B
build/block-library/blocks/media-text/editor-rtl.css 321 B
build/block-library/blocks/media-text/editor.css 320 B
build/block-library/blocks/media-text/style-rtl.css 552 B
build/block-library/blocks/media-text/style.css 550 B
build/block-library/blocks/more/editor-rtl.css 427 B
build/block-library/blocks/more/editor.css 427 B
build/block-library/blocks/navigation-link/editor-rtl.css 566 B
build/block-library/blocks/navigation-link/editor.css 568 B
build/block-library/blocks/navigation-link/style-rtl.css 192 B
build/block-library/blocks/navigation-link/style.css 191 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 295 B
build/block-library/blocks/navigation-submenu/editor.css 294 B
build/block-library/blocks/navigation/editor-rtl.css 2.2 kB
build/block-library/blocks/navigation/editor.css 2.2 kB
build/block-library/blocks/navigation/style-rtl.css 2.24 kB
build/block-library/blocks/navigation/style.css 2.23 kB
build/block-library/blocks/nextpage/editor-rtl.css 392 B
build/block-library/blocks/nextpage/editor.css 392 B
build/block-library/blocks/page-list/editor-rtl.css 378 B
build/block-library/blocks/page-list/editor.css 378 B
build/block-library/blocks/page-list/style-rtl.css 192 B
build/block-library/blocks/page-list/style.css 192 B
build/block-library/blocks/paragraph/editor-rtl.css 251 B
build/block-library/blocks/paragraph/editor.css 251 B
build/block-library/blocks/paragraph/style-rtl.css 341 B
build/block-library/blocks/paragraph/style.css 340 B
build/block-library/blocks/post-author-biography/style-rtl.css 74 B
build/block-library/blocks/post-author-biography/style.css 74 B
build/block-library/blocks/post-author-name/style-rtl.css 69 B
build/block-library/blocks/post-author-name/style.css 69 B
build/block-library/blocks/post-author/editor-rtl.css 107 B
build/block-library/blocks/post-author/editor.css 107 B
build/block-library/blocks/post-author/style-rtl.css 188 B
build/block-library/blocks/post-author/style.css 189 B
build/block-library/blocks/post-comments-count/style-rtl.css 72 B
build/block-library/blocks/post-comments-count/style.css 72 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 527 B
build/block-library/blocks/post-comments-form/style.css 528 B
build/block-library/blocks/post-comments-link/style-rtl.css 71 B
build/block-library/blocks/post-comments-link/style.css 71 B
build/block-library/blocks/post-content/style-rtl.css 61 B
build/block-library/blocks/post-content/style.css 61 B
build/block-library/blocks/post-date/style-rtl.css 62 B
build/block-library/blocks/post-date/style.css 62 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 155 B
build/block-library/blocks/post-excerpt/style.css 155 B
build/block-library/blocks/post-featured-image/editor-rtl.css 722 B
build/block-library/blocks/post-featured-image/editor.css 720 B
build/block-library/blocks/post-featured-image/style-rtl.css 347 B
build/block-library/blocks/post-featured-image/style.css 347 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/style-rtl.css 414 B
build/block-library/blocks/post-template/style.css 414 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-time-to-read/style-rtl.css 70 B
build/block-library/blocks/post-time-to-read/style.css 70 B
build/block-library/blocks/post-title/style-rtl.css 162 B
build/block-library/blocks/post-title/style.css 162 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 134 B
build/block-library/blocks/pullquote/editor.css 134 B
build/block-library/blocks/pullquote/style-rtl.css 358 B
build/block-library/blocks/pullquote/style.css 358 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 121 B
build/block-library/blocks/query-pagination-numbers/editor.css 118 B
build/block-library/blocks/query-pagination/editor-rtl.css 154 B
build/block-library/blocks/query-pagination/editor.css 154 B
build/block-library/blocks/query-pagination/style-rtl.css 237 B
build/block-library/blocks/query-pagination/style.css 237 B
build/block-library/blocks/query-title/style-rtl.css 64 B
build/block-library/blocks/query-title/style.css 64 B
build/block-library/blocks/query-total/style-rtl.css 64 B
build/block-library/blocks/query-total/style.css 64 B
build/block-library/blocks/query/editor-rtl.css 404 B
build/block-library/blocks/query/editor.css 404 B
build/block-library/blocks/quote/style-rtl.css 238 B
build/block-library/blocks/quote/style.css 238 B
build/block-library/blocks/quote/theme-rtl.css 233 B
build/block-library/blocks/quote/theme.css 236 B
build/block-library/blocks/read-more/style-rtl.css 131 B
build/block-library/blocks/read-more/style.css 131 B
build/block-library/blocks/rss/editor-rtl.css 126 B
build/block-library/blocks/rss/editor.css 126 B
build/block-library/blocks/rss/style-rtl.css 284 B
build/block-library/blocks/rss/style.css 283 B
build/block-library/blocks/search/editor-rtl.css 199 B
build/block-library/blocks/search/editor.css 199 B
build/block-library/blocks/search/style-rtl.css 660 B
build/block-library/blocks/search/style.css 658 B
build/block-library/blocks/search/theme-rtl.css 113 B
build/block-library/blocks/search/theme.css 113 B
build/block-library/blocks/separator/editor-rtl.css 100 B
build/block-library/blocks/separator/editor.css 100 B
build/block-library/blocks/separator/style-rtl.css 248 B
build/block-library/blocks/separator/style.css 248 B
build/block-library/blocks/separator/theme-rtl.css 195 B
build/block-library/blocks/separator/theme.css 195 B
build/block-library/blocks/shortcode/editor-rtl.css 286 B
build/block-library/blocks/shortcode/editor.css 286 B
build/block-library/blocks/site-logo/editor-rtl.css 773 B
build/block-library/blocks/site-logo/editor.css 770 B
build/block-library/blocks/site-logo/style-rtl.css 218 B
build/block-library/blocks/site-logo/style.css 218 B
build/block-library/blocks/site-tagline/editor-rtl.css 87 B
build/block-library/blocks/site-tagline/editor.css 87 B
build/block-library/blocks/site-tagline/style-rtl.css 65 B
build/block-library/blocks/site-tagline/style.css 65 B
build/block-library/blocks/site-title/editor-rtl.css 85 B
build/block-library/blocks/site-title/editor.css 85 B
build/block-library/blocks/site-title/style-rtl.css 143 B
build/block-library/blocks/site-title/style.css 143 B
build/block-library/blocks/social-link/editor-rtl.css 314 B
build/block-library/blocks/social-link/editor.css 314 B
build/block-library/blocks/social-links/editor-rtl.css 690 B
build/block-library/blocks/social-links/editor.css 688 B
build/block-library/blocks/social-links/style-rtl.css 1.51 kB
build/block-library/blocks/social-links/style.css 1.51 kB
build/block-library/blocks/spacer/editor-rtl.css 346 B
build/block-library/blocks/spacer/editor.css 346 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table-of-contents/style-rtl.css 83 B
build/block-library/blocks/table-of-contents/style.css 83 B
build/block-library/blocks/table/editor-rtl.css 394 B
build/block-library/blocks/table/editor.css 394 B
build/block-library/blocks/table/style-rtl.css 640 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 B
build/block-library/blocks/tag-cloud/editor-rtl.css 92 B
build/block-library/blocks/tag-cloud/editor.css 92 B
build/block-library/blocks/tag-cloud/style-rtl.css 266 B
build/block-library/blocks/tag-cloud/style.css 265 B
build/block-library/blocks/template-part/editor-rtl.css 368 B
build/block-library/blocks/template-part/editor.css 368 B
build/block-library/blocks/template-part/theme-rtl.css 113 B
build/block-library/blocks/template-part/theme.css 113 B
build/block-library/blocks/term-description/style-rtl.css 126 B
build/block-library/blocks/term-description/style.css 126 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 165 B
build/block-library/blocks/text-columns/style.css 165 B
build/block-library/blocks/verse/style-rtl.css 98 B
build/block-library/blocks/verse/style.css 98 B
build/block-library/blocks/video/editor-rtl.css 441 B
build/block-library/blocks/video/editor.css 442 B
build/block-library/blocks/video/style-rtl.css 192 B
build/block-library/blocks/video/style.css 192 B
build/block-library/blocks/video/theme-rtl.css 134 B
build/block-library/blocks/video/theme.css 134 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.08 kB
build/block-library/common.css 1.08 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 11.4 kB
build/block-library/editor.css 11.4 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/index.min.js 226 kB
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/style-rtl.css 15 kB
build/block-library/style.css 15 kB
build/block-library/theme-rtl.css 708 B
build/block-library/theme.css 712 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 52.6 kB
build/commands/index.min.js 16.2 kB
build/commands/style-rtl.css 955 B
build/commands/style.css 952 B
build/components/index.min.js 229 kB
build/components/style-rtl.css 12.5 kB
build/components/style.css 12.5 kB
build/compose/index.min.js 12.8 kB
build/core-commands/index.min.js 3.09 kB
build/core-data/index.min.js 74.3 kB
build/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.43 kB
build/customize-widgets/style.css 1.43 kB
build/data-controls/index.min.js 641 B
build/data/index.min.js 8.69 kB
build/date/index.min.js 18 kB
build/deprecated/index.min.js 458 B
build/dom-ready/index.min.js 325 B
build/dom/index.min.js 4.67 kB
build/edit-post/classic-rtl.css 578 B
build/edit-post/classic.css 580 B
build/edit-post/index.min.js 13.4 kB
build/edit-post/style-rtl.css 2.74 kB
build/edit-post/style.css 2.73 kB
build/edit-site/index.min.js 222 kB
build/edit-site/posts-rtl.css 7.49 kB
build/edit-site/posts.css 7.5 kB
build/edit-site/style-rtl.css 13.6 kB
build/edit-site/style.css 13.6 kB
build/edit-widgets/index.min.js 17.6 kB
build/edit-widgets/style-rtl.css 4.05 kB
build/edit-widgets/style.css 4.06 kB
build/editor/index.min.js 116 kB
build/editor/style-rtl.css 9.07 kB
build/editor/style.css 9.07 kB
build/element/index.min.js 4.82 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.07 kB
build/format-library/style-rtl.css 474 B
build/format-library/style.css 474 B
build/hooks/index.min.js 1.65 kB
build/html-entities/index.min.js 445 B
build/i18n/index.min.js 3.58 kB
build/is-shallow-equal/index.min.js 526 B
build/keyboard-shortcuts/index.min.js 1.31 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.13 kB
build/list-reusable-blocks/style-rtl.css 852 B
build/list-reusable-blocks/style.css 852 B
build/media-utils/index.min.js 3.69 kB
build/notices/index.min.js 946 B
build/nux/index.min.js 1.62 kB
build/nux/style-rtl.css 767 B
build/nux/style.css 763 B
build/patterns/index.min.js 7.37 kB
build/patterns/style-rtl.css 687 B
build/patterns/style.css 685 B
build/plugins/index.min.js 1.86 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/index.min.js 2.9 kB
build/preferences/style-rtl.css 554 B
build/preferences/style.css 554 B
build/primitives/index.min.js 829 B
build/priority-queue/index.min.js 1.54 kB
build/private-apis/index.min.js 978 B
build/react-i18n/index.min.js 630 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.76 kB
build/redux-routine/index.min.js 2.7 kB
build/reusable-blocks/index.min.js 2.55 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.3 kB
build/router/index.min.js 5.44 kB
build/server-side-render/index.min.js 1.94 kB
build/shortcode/index.min.js 1.4 kB
build/style-engine/index.min.js 2.04 kB
build/token-list/index.min.js 581 B
build/url/index.min.js 3.93 kB
build/vendors/react-dom.min.js 41.7 kB
build/vendors/react-jsx-runtime.min.js 556 B
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 965 B
build/vips/index.min.js 36.2 kB
build/warning/index.min.js 250 B
build/widgets/index.min.js 7.16 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.03 kB

compressed-size-action

@stokesman
Copy link
Contributor Author

stokesman commented Mar 11, 2025

The e2e test I added is failing in Firefox yet testing manually in Firefox works as expected. In the e2e focus is ending up on the "Publish" button like it somehow skips the "Options" button "Open publish panel" button 😕. I’m at loss for how to resolve that at the moment.

UPDATE: I can reproduce testing manually. It only happens when the canvas is iframed and the post is new. The "Open publish panel" button is the last tab stop in the page. It’s like Firefox is moving focus as if the active element were the body.

@t-hamano
Copy link
Contributor

UPDATE: I can reproduce testing manually. It only happens when the canvas is iframed and the post is new. The "Open publish panel" button is the last tab stop in the page. It’s like Firefox is moving focus as if the active element were the body.

I've discovered a few clues regarding this. It seems that the tab focus doesn't work well if the block inserter button is displayed in Firefox:

157e2275d4bc809adcac96740b3296a3.mp4

But I don't know why this problem only occurs in Firefox 🤷

@stokesman stokesman changed the title Fix shift+tab from post title and writing flow container Fix shift+tab from post title Mar 12, 2025
@stokesman
Copy link
Contributor Author

stokesman commented Mar 12, 2025

I figured out the issue in Firefox. It stems from two event listeners moving focus—first on keydown then focusout. In Firefox, the second one actually works whereas other browsers aren’t honoring it. The first focus movement is the desired/expected one but it’s overridden by the second.

Like Aki noted, this corresponds with when the default block appender button is visible, though merely because the second focus move is conditioned to happen only if no blocks are present.

The solution I’ve tried in 1e40320 was to remove the second movement. From my testing the conditions where it actually happened are very rare and I haven’t yet seen what good it actually does. On the contrary it causes a focus loss in some. I have tried to figure it out by looking into the history, it’s from ac07149 which doesn’t make it obvious. It’s clearly intended for an undo related concern so that pretty much means it should not be happening from a tab navigation. An alternative to removing it would be refining the conditions so won’t interfere with tab navigation.


Now the e2e I added is passing but many other tests aren’t. They seem unrelated failures and they’re passing locally. I noticed some of the recent PRs are experiencing the same. I’ll keep this drafted anyway until that’s sorted out.

- Avoid error if focus capture elements are not present by
  returning early.
- Support navigation from generic elements within the container,
  such as the post title, by removing early return for no block
  selection.
@t-hamano
Copy link
Contributor

All e2e tests seem to pass now, so let's undraft it.

@t-hamano t-hamano marked this pull request as ready for review March 13, 2025 07:55
@t-hamano t-hamano requested a review from ellatrix as a code owner March 13, 2025 07:55
Copy link

github-actions bot commented Mar 13, 2025

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 props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: stokesman <presstoke@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: afercia <afercia@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-project-automation github-project-automation bot moved this to 🔎 Needs Review in WordPress 6.8 Editor Tasks Mar 13, 2025
@t-hamano
Copy link
Contributor

The solution I’ve tried in 1e40320 was to remove the second movement. From my testing the conditions where it actually happened are very rare and I haven’t yet seen what good it actually does.

This may be very rare, but I found that the focus might be lost in the following situations:

  • Disable Paragraph block.
  • Open the new post.
  • Insert a block of some kind.
  • Delete the block.
  • Focus is lost? (Confirm that the screen reader reads "document" when the block is deleted in the following video).
Video
e5d2dc69c56ac3acd7c6a65263a4b599.mp4

If I revert 1e40320, the focus isn't lost as the writing flow wrapper gets focus (Confirm that the screen reader reads "section" when the block is deleted in the following video).

Video
7336d21b6c01a0eb67c8420526d28c4c.mp4

Is there a another approach to solve this problem?

@t-hamano
Copy link
Contributor

I'm thinking about adding the Tab key check to the conditional statement:

function onFocusOut( event ) {
	// ...
	if (
		! event.relatedTarget &&
		ownerDocument.activeElement === ownerDocument.body &&
		getBlockCount() === 0 &&
		event.keyCode !== TAB
	) {
		node.focus();
	}

If pressing the Tab key causes focus to be lost, it should mean the focus is moved outside of the editor, which is what should be expected.

@stokesman
Copy link
Contributor Author

stokesman commented Mar 16, 2025

Thanks for testing Aki. I am glad you found this context where this logic seems suitable. I’ve pushed d057813 that restores it with an added condition that stops it from interfering with shift+tab from the post title in Firefox.

Still, I want to touch on a point regarding how this worked with the logic removed.

If I revert 1e40320, the focus isn't lost as the writing flow wrapper gets focus

When I test the same scenario, after deleting the last block the activeElement is the wrapper whether or not 1e40320 is reverted. Next, I find that tabbing from that point works the same with or without reverting. So, for browsers and tab order, focus does not seem lost. That’s not to disregard the result you had with the screen reader. I don’t get how that comes about. If the browser already has the wrapper as the activeElement and in iframed contexts (as your test appeared to be) the body is the wrapper, then how does it label that a "section"?

Aside from that, there is also another "hole" in the implementation. In Firefox, deleting a block does not cause a focusout event. While that seems like a browser bug it also means this logic doesn’t run there.

One more general point about this. It does not seem to belong in the tab nav hook. Tabbing never makes the block count change. So while I believe something like this is a useful idea, I feel like it should be implemented elsewhere. Additionally, I think we can do better than focus the wrapper in most cases by focusing a child (either the appender button or the post title) since one will almost always be available. This would be akin to how if you delete a single block and there is a previous sibling then focus goes to that sibling.

@stokesman
Copy link
Contributor Author

stokesman commented Mar 16, 2025

If pressing the Tab key causes focus to be lost, it should mean the focus is moved outside of the editor, which is what should be expected.

Thanks for the suggestion 🙇 The catch is that since it’s a focusout the event won’t include key data. It could still work by keeping a ref updated from keydown that stores whether the key was tab. I briefly tested it and found that it still allowed this logic to run in some cases it shouldn’t. E.g. when no blocks are present and the default block appender button is pressed. In most browsers that didn’t cause trouble but in Firefox prevents the popover from getting focus.

Copy link

github-actions bot commented Mar 16, 2025

Flaky tests detected in c21a8b8.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/13960634244
📝 Reported issues:

Copy link
Contributor

@t-hamano t-hamano left a comment

Choose a reason for hiding this comment

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

Thanks for the detailed explanation! This PR solves the problem with a very simple approach. As far as I've tested, it all works correctly.

I think it's worth backporting into 6.8 as this PR fixes the issue that first appears in 6.8.

@t-hamano t-hamano added the Backport to WP 6.8 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Mar 18, 2025
@t-hamano
Copy link
Contributor

@stokesman Would it be ok to merge/backport this PR?

It's not a big problem, so maybe we could include it in RC1 instead of Beta3. cc @Mamaduka

@Mamaduka
Copy link
Member

Yes, let's sync this in RC1. I've already released packages for beta 3.

Co-authored-by: Aki Hamano <54422211+t-hamano@users.noreply.github.com>
@Mamaduka
Copy link
Member

@t-hamano, @stokesman, is this good to merge?

@stokesman
Copy link
Contributor Author

As far as I can tell this is good to merge.

Copy link
Member

@Mamaduka Mamaduka left a comment

Choose a reason for hiding this comment

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

As far as I can tell this is good to merge.

@stokesman, agreed! I just left one suggestion that could be helpful in the future. Feel free to merge this at your leisure.

@@ -125,20 +124,26 @@ export default function useTabNav() {
return;
}

if ( ! hasMultiSelection() && ! getSelectedBlockClientId() ) {
Copy link
Member

Choose a reason for hiding this comment

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

@stokesman, could you add a comment here about why we can remove this condition now? This is primarily for the future.

Copy link
Contributor Author

@stokesman stokesman Mar 21, 2025

Choose a reason for hiding this comment

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

This condition and early return when met lets focus to move, as it does innately, to the closest adjacent tab stop. Since the post title is not a block, when shift+tabbing from there it was trapping focus because:

  1. shift+tab moves focus to the writing flow wrapper (closest adjacent tab stop)
  2. a subsequent shift+tab moves focus to the focus capture element which moves it back to the post title

By removing this conditional early return, tabbing from the post title moves focus to the adjacent tab stop outside of the wrapper. Thus it avoids the sibling focus capture elements and the focus trap.

For further reference, this early return was removed in #65204 previous to this PR but that surfaced another bug #69037. It wasn’t clear that the removing the early return had been intentional so we restored it in #69079. That’s how we got here. Though I’m still not sure its prior removal was intentional.

It’s also worth nothing that prior to #65204 when the same conditional early return was there shift+tabbing from the post title worked differently. It took two steps to get outside the canvas, the first step focusing the canvas/writing flow wrapper. I didn’t figure out why/how it worked like that before and why now this same condition/return caused trapping of focus.

@stokesman
Copy link
Contributor Author

stokesman commented Mar 21, 2025

For further reference, this early return was removed in #65204 previous to this PR

It occurred to me that this seems it could change behavior for consumers but it’s been shipping that way in Gutenberg for some time so perhaps it’s fine.

The scenario in which I'm thinking of would be a consumer that’s adding some tabbable elements as children of BlockCanvas but that are not within blocks. The post title is an example of such a thing. With this condition for no block selection causing an early return it means that tabbing would navigate between such elements. Without this condition tabbing is going to be exiting the canvas.

I'm unaware of consumers for which this would be applicable. I did get concerned about WooCommerce because I know their beta product editor uses the canvas and has various tabbable elements in it. I tested that out and it looks like they are always wrapped in blocks so nothing should change. Nor did I find any changes from my quick testing.

@Mamaduka
Copy link
Member

That's interesting. I was testing that behavior on WP 6.7, and it seems broken.

  1. Create a new post.
  2. The title gets focus.
  3. The tab moves to the default inserter "paragraph".
  4. I would expect Shift+Tab to move focus back to the Title, previously focused element.
  5. Instead, the focus moves to the "Add Block" button.

I think this is a good improvement, so let's go with this fix in WP 6.8.

@t-hamano
Copy link
Contributor

The scenario in which I'm thinking of would be a consumer that’s adding some tabbable elements as children of BlockCanvas but that are not within blocks. The post title is an example of such a thing. With this condition for no block selection causing an early return it means that tabbing would navigate between such elements. Without this condition tabbing is going to be exiting the canvas.

In my experience as well, I have never heard of a plugin that injects such elements.

I think it’s safe to merge this PR and backport it to 6.8.

@stokesman
Copy link
Contributor Author

I also think this is an improvement and should be safe. Thanks for the reviews and consideration.

I was testing that behavior on WP 6.7, and it seems broken.

Yes, that particular scenario is confusing. I think it’d be nice to follow up on that and see if we can make the tab order match the visual order. The "Add block" button appears to be after the paragraph but it’s in a popover that precedes the entire canvas.

@stokesman stokesman merged commit 599d7b0 into trunk Mar 21, 2025
62 checks passed
@stokesman stokesman deleted the fix/tab-nav-hook branch March 21, 2025 15:03
@github-project-automation github-project-automation bot moved this from 🔎 Needs Review to ✅ Done in WordPress 6.8 Editor Tasks Mar 21, 2025
@github-actions github-actions bot added this to the Gutenberg 20.6 milestone Mar 21, 2025
@github-actions github-actions bot removed the Backport to WP 6.8 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Mar 21, 2025
gutenbergplugin pushed a commit that referenced this pull request Mar 21, 2025
* Add e2e test for shift+tab

* Fix tab nav hook

- Avoid error if focus capture elements are not present by
  returning early.
- Support navigation from generic elements within the container,
  such as the post title, by removing early return for no block
  selection.

* Rename ref

* Reduce changes; remove condition for container having focus

* Don’t move focus to writing flow wrapper on focus out

* Do move focus to writing flow wrapper if target is block

* Move check for focus capture elements after check for tab key

* Simplify e2e test

* Use a better locator in e2e test

Co-authored-by: Aki Hamano <54422211+t-hamano@users.noreply.github.com>

---------

Co-authored-by: stokesman <presstoke@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: afercia <afercia@git.wordpress.org>
@github-actions github-actions bot added the Backported to WP Core Pull request that has been successfully merged into WP Core label Mar 21, 2025
Copy link

I just cherry-picked this PR to the wp/6.8 branch to get it included in the next release: 4b49562

chriszarate pushed a commit to chriszarate/gutenberg that referenced this pull request Jul 1, 2025
* Add e2e test for shift+tab

* Fix tab nav hook

- Avoid error if focus capture elements are not present by
  returning early.
- Support navigation from generic elements within the container,
  such as the post title, by removing early return for no block
  selection.

* Rename ref

* Reduce changes; remove condition for container having focus

* Don’t move focus to writing flow wrapper on focus out

* Do move focus to writing flow wrapper if target is block

* Move check for focus capture elements after check for tab key

* Simplify e2e test

* Use a better locator in e2e test

Co-authored-by: Aki Hamano <54422211+t-hamano@users.noreply.github.com>

---------

Co-authored-by: stokesman <presstoke@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: afercia <afercia@git.wordpress.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backported to WP Core Pull request that has been successfully merged into WP Core [Feature] Writing Flow Block selection, navigation, splitting, merging, deletion... [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Type] Bug An existing feature does not function as intended
Projects
Development

Successfully merging this pull request may close these issues.

Unable to shift+tab from post title
3 participants