Skip to content

Editor: leave undo to the browser in fields that handle their own undo - #80768

Merged
t-hamano merged 11 commits into
trunkfrom
fix/undo-self-contained-fields
Jul 29, 2026
Merged

t-hamano merged 11 commits into
trunkfrom
fix/undo-self-contained-fields

Conversation

@ellatrix

@ellatrix ellatrix commented Jul 27, 2026 •

Copy link
Copy Markdown
Member

What?

Fixes #80541. Fixes #38731. Fixes the link dialog and "Edit as HTML" problems reported in this comment on #44238; the scroll jump that issue originally reports could not be reproduced and remains open. Cmd+Z inside the link dialog, a block's "Edit as HTML" view, the Custom HTML block's editing dialog, or a classic meta box field no longer rewinds the editor history. The browser's own undo acts on the field instead.

Why?

The undo and redo shortcuts are global, so they fire from any focused element. Fields whose text is not in the editor history (the link dialog commits on Apply, the HTML view on blur) cannot be undone by it, so undo there rewound an earlier, unrelated change: the dialog closed, other blocks lost content, and redo could not always restore it.

How?

An element that relies on the browser's own undo registers itself through a private useNativeUndo ref hook, and the global handlers leave the shortcut alone within it (checked via the paired usesNativeUndo( event )). The registry is a module-private WeakSet, deliberately invisible in the DOM so the mechanism is not adoptable as a de facto public API and can change later. The link dialog, the "Edit as HTML" textarea, the Custom HTML block's editing dialog, and the meta box areas register. Meta box contents are plugin-rendered classic form fields whose values are never part of the editor history, so the whole area registers as one. Since canvas keyboard events are re-dispatched on the iframe element, the real target is resolved through the frame's focused element. Everything else is unchanged, including plugin fields synced to block attributes.

Alternatives considered:

  • Attaching the handlers to editor surfaces (canvas, list view, header) or one root node with popovers mounted outside: the surface is a proxy for the real criterion (is this text in the editor history?) and misses in both directions. It is overinclusive (the HTML editing textarea lives in the canvas, so it stays hijacked) and underinclusive (plugin panels whose fields sync to block attributes lose undo).
  • stopPropagation() in the field: every such field must know an ancestor is listening, and it silences all other listeners.
  • event.defaultPrevented as the signal: unavailable, because rich text prevents the default of these keys to suppress the browser's content editable undo, expecting the editor history to take over.
  • Skipping input/textarea targets: changes undo in fields synced per keystroke to block attributes (e.g. PlainText blocks), where editor undo is correct.
  • A data- attribute as the marker: works identically, but a readable attribute is a public API the moment it ships; hiding it behind the hook keeps the mechanism replaceable.

This deliberately does not close #18755, the umbrella issue. Remaining for that:

  • Register the remaining core local-state fields (block rename modal, create-pattern modal, inline image size popover, and similar).
  • Consider a blanket rule for modals: registering the Modal component covers them all, but requires moving the registry below block-editor (e.g. @wordpress/compose) so components can use it.
  • Document that fields synced to block attributes or post fields intentionally keep editor undo.
  • A public opt-in for plugin fields; the mechanism is private until proven.

Testing Instructions

  1. Select a word, press Cmd+K, type in the URL field, press Cmd+Z: the typing reverts, the dialog stays open, the canvas is untouched.
  2. Switch a block to Edit as HTML, type in the textarea, press Cmd+Z: the typing reverts, other blocks stay intact, Cmd+Shift+Z restores it.

Covered by four regression tests (three in the undo suite, one in the meta boxes suite); all fail on trunk. The Custom HTML one asserts redo restores the typing, which distinguishes the browser's own undo from the editor history remounting the dialog: the remount resets the field to the same committed value, but destroys the browser's redo stack with it.

Use of AI Tools

Written with Claude Code, reviewed and tested by me.

ellatrix and others added 3 commits July 27, 2026 16:55
@ellatrix
ellatrix requested a review from getdave as a code owner July 27, 2026 23:59
@github-actions

github-actions Bot commented Jul 27, 2026 •

Copy link
Copy Markdown

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.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @Michael-Z-Freeman, @maksymmamontov, @smerriman, @himanshu-mahendra-jain, @landwire.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

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

Unlinked contributors: Michael-Z-Freeman, maksymmamontov, smerriman, himanshu-mahendra-jain, landwire.

Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: scruffian <scruffian@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: aduth <aduth@git.wordpress.org>
Co-authored-by: youknowriad <youknowriad@git.wordpress.org>
Co-authored-by: paaljoachim <paaljoachim@git.wordpress.org>
Co-authored-by: eliot-akira <miyarakira@git.wordpress.org>
Co-authored-by: stokesman <presstoke@git.wordpress.org>
Co-authored-by: Thelmachido <thelmachido@git.wordpress.org>
Co-authored-by: ndiego <ndiego@git.wordpress.org>
Co-authored-by: sybrew <cybr@git.wordpress.org>
Co-authored-by: rmorse <codeamp@git.wordpress.org>
Co-authored-by: rilwis <rilwis@git.wordpress.org>
Co-authored-by: cbirdsong <cbirdsong@git.wordpress.org>

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

@github-actions github-actions Bot added [Package] Editor /packages/editor [Package] Block editor /packages/block-editor labels Jul 27, 2026
@github-actions

github-actions Bot commented Jul 28, 2026 •

Copy link
Copy Markdown

Size Change: +282 B (0%)

Total Size: 7.76 MB

📦 View Changed
Filename Size Change
build/scripts/block-editor/index.min.js 428 kB +124 B (+0.03%)
build/scripts/block-library/index.min.js 356 kB +34 B (+0.01%)
build/scripts/customize-widgets/index.min.js 14.6 kB +31 B (+0.21%)
build/scripts/edit-post/index.min.js 52 kB +38 B (+0.07%)
build/scripts/edit-widgets/index.min.js 22.3 kB +48 B (+0.22%)
build/scripts/editor/index.min.js 500 kB +7 B (0%)

compressed-size-action

@github-actions

github-actions Bot commented Jul 28, 2026 •

Copy link
Copy Markdown

Flaky tests detected in f719f0f.
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/30384356206
📝 Reported issues:

@Mamaduka Mamaduka added the [Type] Bug An existing feature does not function as intended label Jul 28, 2026
@Mamaduka

Copy link
Copy Markdown
Member

We could also resolve #80541 and #38731 with the same method on our end. #18755 - here, I don't think we should apply the attribute globally, but let consumers opt out.

Also, what do you think about using a more general name? Something like data-native-undo="true"?

ellatrix and others added 5 commits July 28, 2026 09:40
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na
@github-actions github-actions Bot added the [Package] Block library /packages/block-library label Jul 28, 2026
ellatrix and others added 2 commits July 28, 2026 10:45
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na
@ellatrix
ellatrix requested review from nerrad and ntwb as code owners July 28, 2026 17:45
@github-actions github-actions Bot added the [Package] Edit Post /packages/edit-post label Jul 28, 2026
@ellatrix ellatrix added the Backport to WP 7.1 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Jul 28, 2026
@scruffian

Copy link
Copy Markdown
Contributor

Should we also run the E2E tests in Webkit and Firefox for better coverage?

@scruffian

Copy link
Copy Markdown
Contributor

Should we add CHANGELOG entries in block-editor, block-library, editor, and edit-post?

@ellatrix

Copy link
Copy Markdown
Member Author

For change log, there's nothing affecting package consumers, it's all internal? The whole thing is opt-in.

Not sure if webkit and Firefox could behave differently here, but I suppose we could.

@scruffian scruffian left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This fixes #80541 and the code looks good. I didn't read the tests in full yet.

@t-hamano t-hamano left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm considering whether to backport this PR to 7.1 Beta 4. Should we also add the usesNativeUndo guard to the shortcuts for edit-widgets and customize-widgets? Otherwise, I feel there will be a difference in the behavior of the undo shortcuts.

The widget editors register their own undo and redo shortcuts instead of
going through EditorProvider, so the guard added to the editor package
never reached them. The same link dialog behaved differently depending on
the screen it was opened from.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the [Package] Edit Widgets /packages/edit-widgets label Jul 29, 2026
@t-hamano

Copy link
Copy Markdown
Contributor

Should we also add the usesNativeUndo guard to the shortcuts for edit-widgets and customize-widgets? Otherwise, I feel there will be a difference in the behavior of the undo

This has been addressed in df3b53c. This should ensure consistent undo behavior across all editors.

Before

before.mp4

After

after.mp4

@t-hamano

Copy link
Copy Markdown
Contributor

I'm going to merge this and backport it to 7.1.

@t-hamano
t-hamano merged commit b9d5bdd into trunk Jul 29, 2026
46 checks passed
@t-hamano
t-hamano deleted the fix/undo-self-contained-fields branch July 29, 2026 10:20
@github-actions github-actions Bot added this to the Gutenberg 23.7 milestone Jul 29, 2026
@github-actions github-actions Bot removed the Backport to WP 7.1 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Jul 29, 2026
gutenbergplugin pushed a commit that referenced this pull request Jul 29, 2026
#80768)

* Leave undo to the browser within elements that declare their own undo handling

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na

* Mark the link dialog and the HTML editing field as handling their own undo

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na

* Add regression tests for undo inside the link dialog and the HTML editing field

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na

* Rename the opt-out attribute to data-wp-native-undo

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na

* Resolve the canvas target through a single frame level

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na

* Hide the native undo marker behind a private hook

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na

* Keep undo native inside the Custom HTML editing dialog

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na

* Add a regression test for undo inside the Custom HTML dialog

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na

* Keep undo native inside meta box areas

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na

* Add a regression test for undo inside a meta box field

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GQNdFF1FUU9JXfNGZev2na

* Keep undo native inside the widget screens too

The widget editors register their own undo and redo shortcuts instead of
going through EditorProvider, so the guard added to the editor package
never reached them. The same link dialog behaved differently depending on
the screen it was opened from.

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Unlinked contributors: Michael-Z-Freeman, maksymmamontov, smerriman, himanshu-mahendra-jain, landwire.

Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: scruffian <scruffian@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: aduth <aduth@git.wordpress.org>
Co-authored-by: youknowriad <youknowriad@git.wordpress.org>
Co-authored-by: paaljoachim <paaljoachim@git.wordpress.org>
Co-authored-by: eliot-akira <miyarakira@git.wordpress.org>
Co-authored-by: stokesman <presstoke@git.wordpress.org>
Co-authored-by: Thelmachido <thelmachido@git.wordpress.org>
Co-authored-by: ndiego <ndiego@git.wordpress.org>
Co-authored-by: sybrew <cybr@git.wordpress.org>
Co-authored-by: rmorse <codeamp@git.wordpress.org>
Co-authored-by: rilwis <rilwis@git.wordpress.org>
Co-authored-by: cbirdsong <cbirdsong@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 Jul 29, 2026
@github-actions

Copy link
Copy Markdown

I just cherry-picked this PR to the wp/7.1 branch to get it included in the next release: f65b5d5

dd32 pushed a commit to dd32/wordpress-develop that referenced this pull request Jul 29, 2026
This updates the pinned commit hash of the Gutenberg repository from `4997026b75c922d8a6f77a03d72ed7cad04c7073` to `fd715a6833679d098d9fee84b642f8f1bc27341b`.

A full list of changes included in this commit can be found on GitHub: 
WordPress/gutenberg@4997026...fd715a6

- Update view config API versioning (WordPress/gutenberg#80319)
- Perf Tests: Fix 'Selecting blocks' metric reporting 0 ms (WordPress/gutenberg#80524)
- Notes: Register the inline note format at import time (WordPress/gutenberg#80576)
- Media: Stop forcing crossorigin on IMG tags in media templates (WordPress/gutenberg#80532)
- GradientPicker: select by slug so two presets sharing a gradient keep their identity (WordPress/gutenberg#80554)
- Media Editor: Show a loading state while the cropped file loads (WordPress/gutenberg#80460)
- Remove default paragraph from tab-panel template (WordPress/gutenberg#80565)
- Global Styles: Resolve link element styles in block inspector controls for blocks that are links (WordPress/gutenberg#80607)
- Media REST API: Backport sideload from url path upload size check (WordPress/gutenberg#80659)
- Rich text: remove tabIndex from editable elements again to fix shift+click selection (WordPress/gutenberg#80651)
- Gallery: make dynamic mode conversion a single undo level (WordPress/gutenberg#80665)
- Background image control: Remove duplicated focus ring (WordPress/gutenberg#80671)
- Detach core's note mention kses filter in the baseline strip test (WordPress/gutenberg#80656)
- wp-build: sync the page template preload field list with core-data (WordPress/gutenberg#80648)
- Read the contentEditable attribute in ownsSelection, not isContentEditable (WordPress/gutenberg#80549)
- Writing flow: extend block selections with shift+arrow when there is no native selection (WordPress/gutenberg#80687)
- Notes: Capture the target block before saving a block-level note (WordPress/gutenberg#80690)
- Theme JSON: Level block-level preset class specificity with :where() (WordPress/gutenberg#80657)
- Notes: Sync the sidebar selection to the inline marker under the caret (WordPress/gutenberg#80610)
- Writing flow: use isMultiSelecting for shift+click (WordPress/gutenberg#80286) (WordPress/gutenberg#80726)
- Block supports: Return from layout support before resolving global settings (WordPress/gutenberg#80771)
- Notes: Report save success consistently from note actions (WordPress/gutenberg#80748)
- Dynamic Gallery: Rename toolbar button to Detach and add a modal explaining what will happen (WordPress/gutenberg#80727) (WordPress/gutenberg#80774)
- ToolsPanel: Migrate styles to an SCSS Module (WordPress/gutenberg#80445) (WordPress/gutenberg#80800)
- Add a responsiveEditingEnabled editor setting to hide the Responsive styles option (WordPress/gutenberg#80814)
- iOS: remove jumping hack, add typewriter (WordPress/gutenberg#74596)
- Writing flow: stop the page scrolling on caret moves within blocks taller than the viewport (WordPress/gutenberg#80708)
- Global Styles: Put the inheritance UI behind a Gutenberg experiment (… (WordPress/gutenberg#80818)
- Notes: Cancel in-flight hover highlight when focus leaves a note thread (WordPress/gutenberg#80752)
- Block Editor: Try to fix typing performance regression (WordPress/gutenberg#80507)
- List Block: Preserve ordered type on indent (WordPress/gutenberg#75353)
- Make editableRoot a private block setting Symbol, not a public support (WordPress/gutenberg#80820)
- Fix cursor position during forward delete of empty blocks (WordPress/gutenberg#80827)
- Navigation: Fixes `aria-expanded` not updating on hover submenu inside overlay (WordPress/gutenberg#80828)
- Remove redundant @jest-environment jsdom pragma and lint against it (WordPress/gutenberg#80676)
- View config: reject shape-mismatched merges, define empty-array semantics, strip nulls from appended members (WordPress/gutenberg#80829)
- Editor: leave undo to the browser in fields that handle their own undo (WordPress/gutenberg#80768)
- Fix: New route-based admin pages are empty when no JS (WordPress/gutenberg#80839)

Props wildworks.
See #65529.

git-svn-id: https://develop.svn.wordpress.org/trunk@62896 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Jul 29, 2026
This updates the pinned commit hash of the Gutenberg repository from `4997026b75c922d8a6f77a03d72ed7cad04c7073` to `fd715a6833679d098d9fee84b642f8f1bc27341b`.

A full list of changes included in this commit can be found on GitHub: 
WordPress/gutenberg@4997026...fd715a6

- Update view config API versioning (WordPress/gutenberg#80319)
- Perf Tests: Fix 'Selecting blocks' metric reporting 0 ms (WordPress/gutenberg#80524)
- Notes: Register the inline note format at import time (WordPress/gutenberg#80576)
- Media: Stop forcing crossorigin on IMG tags in media templates (WordPress/gutenberg#80532)
- GradientPicker: select by slug so two presets sharing a gradient keep their identity (WordPress/gutenberg#80554)
- Media Editor: Show a loading state while the cropped file loads (WordPress/gutenberg#80460)
- Remove default paragraph from tab-panel template (WordPress/gutenberg#80565)
- Global Styles: Resolve link element styles in block inspector controls for blocks that are links (WordPress/gutenberg#80607)
- Media REST API: Backport sideload from url path upload size check (WordPress/gutenberg#80659)
- Rich text: remove tabIndex from editable elements again to fix shift+click selection (WordPress/gutenberg#80651)
- Gallery: make dynamic mode conversion a single undo level (WordPress/gutenberg#80665)
- Background image control: Remove duplicated focus ring (WordPress/gutenberg#80671)
- Detach core's note mention kses filter in the baseline strip test (WordPress/gutenberg#80656)
- wp-build: sync the page template preload field list with core-data (WordPress/gutenberg#80648)
- Read the contentEditable attribute in ownsSelection, not isContentEditable (WordPress/gutenberg#80549)
- Writing flow: extend block selections with shift+arrow when there is no native selection (WordPress/gutenberg#80687)
- Notes: Capture the target block before saving a block-level note (WordPress/gutenberg#80690)
- Theme JSON: Level block-level preset class specificity with :where() (WordPress/gutenberg#80657)
- Notes: Sync the sidebar selection to the inline marker under the caret (WordPress/gutenberg#80610)
- Writing flow: use isMultiSelecting for shift+click (WordPress/gutenberg#80286) (WordPress/gutenberg#80726)
- Block supports: Return from layout support before resolving global settings (WordPress/gutenberg#80771)
- Notes: Report save success consistently from note actions (WordPress/gutenberg#80748)
- Dynamic Gallery: Rename toolbar button to Detach and add a modal explaining what will happen (WordPress/gutenberg#80727) (WordPress/gutenberg#80774)
- ToolsPanel: Migrate styles to an SCSS Module (WordPress/gutenberg#80445) (WordPress/gutenberg#80800)
- Add a responsiveEditingEnabled editor setting to hide the Responsive styles option (WordPress/gutenberg#80814)
- iOS: remove jumping hack, add typewriter (WordPress/gutenberg#74596)
- Writing flow: stop the page scrolling on caret moves within blocks taller than the viewport (WordPress/gutenberg#80708)
- Global Styles: Put the inheritance UI behind a Gutenberg experiment (… (WordPress/gutenberg#80818)
- Notes: Cancel in-flight hover highlight when focus leaves a note thread (WordPress/gutenberg#80752)
- Block Editor: Try to fix typing performance regression (WordPress/gutenberg#80507)
- List Block: Preserve ordered type on indent (WordPress/gutenberg#75353)
- Make editableRoot a private block setting Symbol, not a public support (WordPress/gutenberg#80820)
- Fix cursor position during forward delete of empty blocks (WordPress/gutenberg#80827)
- Navigation: Fixes `aria-expanded` not updating on hover submenu inside overlay (WordPress/gutenberg#80828)
- Remove redundant @jest-environment jsdom pragma and lint against it (WordPress/gutenberg#80676)
- View config: reject shape-mismatched merges, define empty-array semantics, strip nulls from appended members (WordPress/gutenberg#80829)
- Editor: leave undo to the browser in fields that handle their own undo (WordPress/gutenberg#80768)
- Fix: New route-based admin pages are empty when no JS (WordPress/gutenberg#80839)

Props wildworks.
See #65529.
Built from https://develop.svn.wordpress.org/trunk@62896


git-svn-id: http://core.svn.wordpress.org/trunk@62163 1a063a9b-81f0-0310-95a4-ce76da25c4cd
@ellatrix

Copy link
Copy Markdown
Member Author

Thanks Aki!

@Mamaduka

Copy link
Copy Markdown
Member

@ellatrix, discovered a small issue when trying to opt out of editor undo for the RichText field. Below is the gist form debugging session.


An empty editable renders as [#text(""), #text("\uFEFF"), <span data-rich-text-placeholder>] (to-tree.js:323-338). Chrome types into the \uFEFF node. Rich text then has to strip that padding, and applyValue does it with replaceChild.

Chrome's pending typing command points at that text node. Replacing it detaches the node, so undoing the first character becomes a no-op. Chars 2+ reference the surviving node and undo fine. Hence, the first character is stuck.

wporg-sync pushed a commit to WordPress/wordpress-develop that referenced this pull request Sep 8, 2026
This updates the pinned commit hash of the Gutenberg repository from `2872d71cde528d82675f14862a1b84e2b8abbaea` to `5a0417990a9404cc2562cdd35e3054cb0d3e546e` (version `23.7.0`).

A full list of changes included in this commit can be found on GitHub: https://github.com/WordPress/gutenberg/compare/2872d71cde528d82675f14862a1b84e2b8abbaea..v23.7.0.

- Release: Fix cherry-pick success detection (WordPress/gutenberg#80249)
- Add Table of Contents e2e user story coverage (WordPress/gutenberg#80199)
- Only include icon library SVGs listed as `public` in the Zip file published to GitHub Container Registry for `wordpress-develop` (WordPress/gutenberg#79338)
- fix: set dataviews popover hover text color (WordPress/gutenberg#80105)
- added missing doc (WordPress/gutenberg#80172)
- DataViews: Fix the unintended gap between `list` layout items when `groupBy` is set (WordPress/gutenberg#80254)
- Social Link: Fix stray closing tag in Tumblr icon markup (WordPress/gutenberg#80257)
- DataViews: Fix the `list` layout ignoring some settings when `groupBy` is set (WordPress/gutenberg#80255)
- Icon block: Show text and background color controls by default. (WordPress/gutenberg#80251)
- DataViews: Add shift-click range selection (WordPress/gutenberg#80046)
- UI: Remove unused direction factor CSS property (WordPress/gutenberg#80269)
- theme: Disallow src in published package (WordPress/gutenberg#80213)
- Fix: stale post edit message in modal (WordPress/gutenberg#79997)
- Icons: Validate SVG icons include viewBox (WordPress/gutenberg#80273)
- Remove obsolete __unstable-large size props (WordPress/gutenberg#80081)
- Responsive Editing: support editing pattern styles (WordPress/gutenberg#80233)
- Tab List: Add toolbar buttons to reorder tabs (WordPress/gutenberg#80107)
- Move image editor styles to the block editor package (WordPress/gutenberg#80165)
- Cover/Accordion: Exit on Enter (WordPress/gutenberg#77301)
- Hide color controls for Navigation and Social Icons when viewport states are active (WordPress/gutenberg#80289)
- Icons: Fix collection unregister not removing icons after core added its own registry (WordPress/gutenberg#80292)
- Widget Dashboard: collapse inline attribute controls into a dropdown (WordPress/gutenberg#80208)
- Notes: increase contrast between avatar border colors (WordPress/gutenberg#80285)
- Playlist: Fix track insertion (WordPress/gutenberg#80200)
- Fix: Allow icon labels to wrap with word breaks and no ellipsis (WordPress/gutenberg#80256)
- Dedupe deprecated prop types in composite components (WordPress/gutenberg#80277)
- Core Abilities: Restore the ready promise and lazy-load via dynamic import (WordPress/gutenberg#79155)
- Notes: Replace blur-deselect bookkeeping with useFocusOutside (WordPress/gutenberg#80222)
- UI: Hook Popover into the wp compat overlay slot (WordPress/gutenberg#80278)
- Playlist: Update @SInCE tags to 7.1.0 (WordPress/gutenberg#80317)
- Remove unused useDeprecated36pxDefaultSizeProp helper. (WordPress/gutenberg#80311)
- fix playlist block Dimensions Design (WordPress/gutenberg#80312)
- UI: Keep the compat overlay slot accessible inside Modal (WordPress/gutenberg#80310)
- Theme: Add typography token showcase (WordPress/gutenberg#80212)
- Cover: Create the initial paragraph when the block gains a background (WordPress/gutenberg#80028)
- Notes: Arm the mention kses allowance on REST note creation (WordPress/gutenberg#80221)
- Check for post lock modal and text, not specific title and button (WordPress/gutenberg#79979)
- Worker threads: reject pending RPC calls on worker failure or termination (WordPress/gutenberg#79955)
- RTC: Fix empty revision from peer autosave (WordPress/gutenberg#79911)
- Client Side Media: Honor image_strip_meta and image_max_bit_depth on the client upload path (WordPress/gutenberg#80218)
- Vips/upload-media: consolidate optional params into options objects (WordPress/gutenberg#80330)
- Editor: allow selecting which block styles to apply globally (WordPress/gutenberg#79839)
- Global Styles: Reject non-string custom CSS in the REST controller (WordPress/gutenberg#80338)
- Open inspector sidebar when toggling responsive editing (WordPress/gutenberg#80307)
- Fix upload hang when converting long animated GIFs: decode only the first frame for still outputs (WordPress/gutenberg#80260)
- Fix: Critical error related to simple-git (WordPress/gutenberg#80102)
- Hide block style variations when state is enabled in global styles (WordPress/gutenberg#80341)
- Media REST API: Fix sideload and finalize for EXIF rotated images (WordPress/gutenberg#80295)
- Fix upload snackbar stuck in uploading state on server-side uploads (WordPress/gutenberg#80345)
- Try fixing responsive layout in Nav block (WordPress/gutenberg#80305)
- tools: Remove redundant parseArgs arguments (WordPress/gutenberg#80327)
- Responsive styles: Use viewport dropdown to control states for in-editor global styles sidebar (WordPress/gutenberg#80339)
- Use Add track instead of only Add (WordPress/gutenberg#80336)
- Interactivity API: refactor directives into self-registering modules (WordPress/gutenberg#79975)
- Fix: Critical error websocket-driver fix (WordPress/gutenberg#80348)
- Release: Resolve commander from the test file in the release CLI test (WordPress/gutenberg#80357)
- Release: Extract npm release lifecycle (WordPress/gutenberg#80190)
- Fix multiple MP3 playlist uploads (WordPress/gutenberg#80101)
- Table of Contents: render front-end list from current post headings (WordPress/gutenberg#80318)
- UI: improve component code readability in Storybook by using arrays for children (WordPress/gutenberg#80352)
- Infra: Use devEngines in root package.json and pin npm version in CI (WordPress/gutenberg#80188)
- Automated Testing: Skip type-checking in bundle size comparison build (WordPress/gutenberg#80366)
- Theme: Update colorjs.io dependency and drop bug workaround (WordPress/gutenberg#80272)
- RichTextControl: Replace DOM focus tracking with a single React-tree focus boundary (WordPress/gutenberg#80324)
- Notes: Finish WPDS treatment for mention chips (WordPress/gutenberg#80300)
- Notes: Add placeholders to the RichText fields (WordPress/gutenberg#80296)
- Fix flaky test in `tabs.spec.js` (WordPress/gutenberg#80373)
- Packages: Update exports to avoid deprecated folder export syntax (WordPress/gutenberg#80270)
- Theme: Widen peer dependency ranges to support new versions of Vite, ESBuild, and Stylelint (WordPress/gutenberg#80267)
- Components: Skip polymorphism prop typings on intersection (WordPress/gutenberg#80364)
- Post Content: Use the default block appender for empty content (WordPress/gutenberg#80026)
- Device preview dropdown: use active color for device icon when responsive styles are active (WordPress/gutenberg#80346)
- Fix default aspect ratio for lazy loaded Featured image (WordPress/gutenberg#80386)
- Docs: Add client-side media processing documentation (WordPress/gutenberg#75895)
- Autocompleters: Don't pre-encode mention search terms (WordPress/gutenberg#80377)
- Animated GIF uploads: generate sub-sizes from the first frame, matching core (WordPress/gutenberg#80268)
- Media: Add timeout and size guardrails to client-side GIF to video conversion (WordPress/gutenberg#80379)
- Widget Primitives: Ship as a script module (WordPress/gutenberg#80149)
- SearchControl: Render the suffix only if there's one. (WordPress/gutenberg#80356)
- Custom CSS: Fix cascade order against block style variations (WordPress/gutenberg#80340)
- React 19: add e2e compat test for boolean inert attribute (WordPress/gutenberg#80397)
- Fix post excerpt rendering to conditionally include space before more… (WordPress/gutenberg#70217)
- Add wp-theme as a style dependency of wp-components (WordPress/gutenberg#80362)
- Dashboard Widgets: declarative actions in the widget schema (WordPress/gutenberg#80363)
- @wordpress/ui: Add Button Storybook example for keyboard shortcut composition (WordPress/gutenberg#80353)
- SlotFill: Validate cross-document SCSS module styles (WordPress/gutenberg#80384)
- Components: migrate ConfirmDialog to SCSS module (WordPress/gutenberg#80394)
- SearchControl: Remove redundant conditional and prop. (WordPress/gutenberg#80406)
- Tools: resolve dependencies independently of the node_modules layout (WordPress/gutenberg#80414)
- Components: Migrate ToggleGroupControl to SCSS Modules (WordPress/gutenberg#80381)
- Rich Text: Restore the selection when focus returns to the editable (WordPress/gutenberg#80396)
- RTC: Use requestAnimationFrame for awareness cursor resize redraws (WordPress/gutenberg#79685)
- Remove __shouldNotWarnDeprecated36pxSize internal prop (WordPress/gutenberg#80323)
- Fix upload snackbar double-counting a single HEIC upload in Safari (WordPress/gutenberg#80371)
- Fix Root `.prettierrc.js` override issue (WordPress/gutenberg#80422)
- Fix Color Picker Cursor Shaking Issue (WordPress/gutenberg#80205)
- Storybook: pre-bundle CJS deps (WordPress/gutenberg#80426)
- ContentEditableControl: fix invalid label association with contenteditable div (WordPress/gutenberg#80344)
- Writing flow: use isMultiSelecting for shift+click (WordPress/gutenberg#80286)
- Added Missing Global Documentation (WordPress/gutenberg#80442)
- Editor: Disable canvas resizing while zoomed out (WordPress/gutenberg#80391)
- Misc fixes for WordPress-Develop 7.0 merges (WordPress/gutenberg#75985)
- RTC: Preserve collaborators' unsaved edits when another user saves (WordPress/gutenberg#79936)
- RTC: Disable Quick Edit while a post is being edited (WordPress/gutenberg#80016)
- Storybook: build the resolve specifier as a URL-style string (WordPress/gutenberg#80416)
- Style Book: Restore live global styles updates on the styles route (WordPress/gutenberg#80459)
- Editor: Restore fixed device preview height for mobile and tablet (WordPress/gutenberg#80271)
- Block Supports: Handle nested array block gap values properly (WordPress/gutenberg#80464)
- Block Editor: Guard against non-string spacing preset values (WordPress/gutenberg#80467)
- Move real-time collaboration code to lib/experimental/collaboration (WordPress/gutenberg#80469)
- RTC: Fix deleted-user test on multisite (WordPress/gutenberg#80463)
- Build: add independent react-18 vendor package (WordPress/gutenberg#80367)
- Fix `useHomeEnd` on tabs in mac testing (WordPress/gutenberg#80374)
- Block Editor: Reflect inherited Global Styles values in block inspector controls (WordPress/gutenberg#77894)
- Media: Remove the redundant __heicUploadSupport flag (WordPress/gutenberg#80452)
- Writing flow: fully select the ancestor when a text selection crosses a nesting boundary (WordPress/gutenberg#80462)
- fix: show add block button when editing a template part inside a template (WordPress/gutenberg#78427)
- Autocomplete: Reference the suggestions list with `aria-controls` and `aria-haspopup` (WordPress/gutenberg#80403)
- Dashboard Widgets: Sanitize help link hrefs. (WordPress/gutenberg#80409)
- State control - avoid tertiary variant on toggle to match style of other dropdown toggles (WordPress/gutenberg#80505)
- Widget Dashboard: measure the header fit and document the chrome (WordPress/gutenberg#80423)
- DataViews/Font Library: Give search fields a fixed width to stop layout shift (WordPress/gutenberg#80315)
- Fix crashes when manipulating locked blocks (WordPress/gutenberg#80509)
- RTC: Use str_contains() in WP_Sync_Config type parsing (WordPress/gutenberg#80476)
- Table of Contents: Use str_contains() instead of strpos() check (WordPress/gutenberg#80418)
- Build: Handle project paths containing spaces in dev script (WordPress/gutenberg#80519)
- Components: migrate SearchControl to SCSS module (WordPress/gutenberg#80474)
- Icons: Store the sanitized SVG content when registering an icon (WordPress/gutenberg#80508)
- Resolve Prettier explicitly for isolated layout (WordPress/gutenberg#80529)
- Playlist: Fix playback of tracks served without CORS headers (WordPress/gutenberg#80533)
- Remove unnecessary __next40pxDefaultSize props from form controls (WordPress/gutenberg#80540)
- GitHub workflows: Fix changelog checks for forked PRs (WordPress/gutenberg#80538)
- Redirect editing events to extension handlers under editableRoot (WordPress/gutenberg#80287)
- Writing flow: fully select the items when a selection extends down into a nested item (WordPress/gutenberg#80492)
- Global Styles panels: fix wrong preset committed and shown when two color presets share a hex (WordPress/gutenberg#80497)
- Replaces the `title` attributes used by revision inline diff annotations with `aria-describedby` (WordPress/gutenberg#80440)
- Account for non-lowercase VIDEO tag in render_block filter (WordPress/gutenberg#80537)
- Components: migrate FormTokenField to SCSS module (WordPress/gutenberg#80472)
- Revisions: Specify block level diff status via aria-label (WordPress/gutenberg#77779)
- Notes: Remove "Add note" from the inline styles dropdown (WordPress/gutenberg#80531)
- Global Styles: Resolve per-level heading element styles in block inspector controls (WordPress/gutenberg#80495)
- Notes: Render @ mentions as span chips and narrow the kses class allowance (WordPress/gutenberg#80528)
- Backport from Core: improve icon name unit tests (WordPress/gutenberg#80552)
- Read the contentEditable attribute in ownsSelection, not isContentEditable (WordPress/gutenberg#80549)
- Device type preview: fix collapsing to content height (WordPress/gutenberg#80553)
- Wrap notices in ThemeProvider with 0 corner radius (WordPress/gutenberg#79523)
- Perf Tests: Fix 'Selecting blocks' metric reporting 0 ms (WordPress/gutenberg#80524)
- Global Styles: Limit the inherited value treatment to the Gutenberg plugin (WordPress/gutenberg#80555)
- RTC: Use array_any() for newer-compaction check in polling sync server (WordPress/gutenberg#80522)
- Fix: Update webpack-dev-server to ^5.2.1 to help with dep alerts (WordPress/gutenberg#80347)
- Notes: align floating threads with their inline marker (WordPress/gutenberg#79877)
- WP Build: avoid infinite worker build loop (WordPress/gutenberg#80361)
- Update view config API versioning (WordPress/gutenberg#80319)
- Docs: Update plugin release docs for GitHub's Release label UI (WordPress/gutenberg#80567)
- Release: Require a working GitHub CLI for cherry-picking (WordPress/gutenberg#80568)
- Improve the various Alignment controls props handling (WordPress/gutenberg#63696)
- Reduce duplicated preset utility implementations (WordPress/gutenberg#80245)
- Dashboard Widgets: harden action `href` sanitization (WordPress/gutenberg#80510)
- Notes: Register the inline note format at import time (WordPress/gutenberg#80576)
- Fix preset round-trip test imports after preset utils consolidation (WordPress/gutenberg#80589)
- ExternalLink: Use shared focus ring mixin (WordPress/gutenberg#80573)
- Combobox, Select, SelectControl: Add Group and GroupLabel (WordPress/gutenberg#80574)
- Query Loop: Add translation context to the 'Offset' setting label (WordPress/gutenberg#80582)
- Media: Stop forcing crossorigin on IMG tags in media templates (WordPress/gutenberg#80532)
- GradientPicker: select by slug so two presets sharing a gradient keep their identity (WordPress/gutenberg#80554)
- Media Editor: Show a loading state while the cropped file loads (WordPress/gutenberg#80460)
- Remove default paragraph from tab-panel template (WordPress/gutenberg#80565)
- Global Styles: Resolve link element styles in block inspector controls for blocks that are links (WordPress/gutenberg#80607)
- Math: Use ValidatedTextareaControl for LaTeX input (WordPress/gutenberg#80500)
- Navigation: Fixes `aria-expanded` not updating on hover submenu inside overlay (WordPress/gutenberg#77563)
- Core Data: Move EntitiesSavedState component out of editor (rebase of WordPress/gutenberg#71948) (WordPress/gutenberg#80485)
- Fix: Pullquote custom line height in the editor. (WordPress/gutenberg#80586)
- Block Tools: Fix empty block appender position inside blocks that capture toolbars (WordPress/gutenberg#80592)
- Editor: Avoid unnecessary term re-fetches in FlatTermSelector (WordPress/gutenberg#80623)
- DependencyExtractionWebpackPlugin: Include extracted styles in the asset version hash (WordPress/gutenberg#80601)
- Base styles: Allow overriding focus ring color in outset-ring__focus (WordPress/gutenberg#80587)
- UI: Add Autocomplete.Row primitive (WordPress/gutenberg#80490)
- Site Editor: Add E2E coverage for view config extensibility (WordPress/gutenberg#80577)
- View config: reject shape-mismatched merges, define empty-array semantics, strip nulls from appended members (WordPress/gutenberg#80571)
- Theme: Update Storybook admin color scheme examples (WordPress/gutenberg#80569)
- Detach core's note mention kses filter in the baseline strip test (WordPress/gutenberg#80656)
- Media REST API: Backport sideload from url path upload size check (WordPress/gutenberg#80659)
- Rich text: remove tabIndex from editable elements again to fix shift+click selection (WordPress/gutenberg#80651)
- Storybook: Remove Emotion as JSX import source (WordPress/gutenberg#80647)
- Gallery: make dynamic mode conversion a single undo level (WordPress/gutenberg#80665)
- Docs: Update iframe guidance for Gutenberg 23.6 (WordPress/gutenberg#80629)
- Background image control: Remove duplicated focus ring (WordPress/gutenberg#80671)
- DataViewsPicker: Add Shift+Click range selection to the `picker-table`, `picker-grid`, and `picker-activity` layouts (WordPress/gutenberg#80413)
- Docs: Require view config filter callbacks to return the container (WordPress/gutenberg#80642)
- Duotone: Dedupe duotone utils into global-styles-engine (WordPress/gutenberg#80598)
- Input: Hide native spin controls for `type="number"` (WordPress/gutenberg#80646)
- Make `useSelectionProps` hook layout agnostic (WordPress/gutenberg#80677)
- Remove redundant @jest-environment jsdom pragma and lint against it (WordPress/gutenberg#80676)
- Base Styles: Remove accent color parameter from input-control (WordPress/gutenberg#80595)
- wp-build: sync the page template preload field list with core-data (WordPress/gutenberg#80648)
- Add progressive-discovery pattern for agent instructions and skills and general guidelines (WordPress/gutenberg#80650)
- Writing flow: extend block selections with shift+arrow when there is no native selection (WordPress/gutenberg#80687)
- Fix cursor position during forward delete of empty blocks (WordPress/gutenberg#77525)
- Global Styles: Extract shared preset management from shadows and font sizes (WordPress/gutenberg#79810)
- Notes: Capture the target block before saving a block-level note (WordPress/gutenberg#80690)
- Rename unit tests, removing `spec.js` to match the convention. (WordPress/gutenberg#80711)
- Used @link for url in inline documentation (WordPress/gutenberg#80716)
- Block Library: Guards against error throwing attribute values (WordPress/gutenberg#80558)
- Theme JSON: Level block-level preset class specificity with :where() (WordPress/gutenberg#80657)
- Notes: Sync the sidebar selection to the inline marker under the caret (WordPress/gutenberg#80610)
- Page List: Use null coalescing operator for parentPageID attribute (WordPress/gutenberg#80728)
- Fix font library navigation page select font size to match DataViews. (WordPress/gutenberg#80617)
- Meta boxes: Match heading styles with Gutenberg panels (WordPress/gutenberg#80670)
- Edit Site: Replace Theme usage in canvas loader with CSS (WordPress/gutenberg#80688)
- Jest: Fix ignore patterns with dots (WordPress/gutenberg#80737)
- Components: Migrate Disabled to SCSS module (WordPress/gutenberg#80643)
- Enhance sandbox component to accept sandbox prop (WordPress/gutenberg#69617)
- Docs: Expand the back-porting to WP Core guide (WordPress/gutenberg#80593)
- Add nvm use instructions to AGENTS.md (WordPress/gutenberg#80755)
- Docs: Clarify agent guidance discovery (WordPress/gutenberg#80753)
- Block Editor: Fix floated blocks overlapping sticky blocks (WordPress/gutenberg#80749)
- Shorten playlist track toolbar button label (WordPress/gutenberg#80759)
- Block supports: Return from layout support before resolving global settings (WordPress/gutenberg#80771)
- Notes: Report save success consistently from note actions (WordPress/gutenberg#80748)
- Dynamic Gallery: Rename toolbar button to Detach and add a modal explaining what will happen (WordPress/gutenberg#80727)
- Docs: Clarify getBlock behavior with inner block controllers (WordPress/gutenberg#80773)
- Update docs for server-side view config filters (WordPress/gutenberg#80744)
- createInterpolateElement: handle unmatched closing tags gracefully (WordPress/gutenberg#80618)
- Components: Remove private Theme component (WordPress/gutenberg#80691)
- Block Editor: Refactor 'URLInput' to function component (WordPress/gutenberg#80721)
- UI: add Dialog vs Drawer design guidance (WordPress/gutenberg#80783)
- Packages: Update date-fns to 4.4.0 (WordPress/gutenberg#80763)
- Theme: Update Color.js to 0.7.1 (WordPress/gutenberg#80762)
- ESLint: Add missing not-recommended components to denylist (WordPress/gutenberg#80754)
- Jest: Update to v30 (breaking) (WordPress/gutenberg#80767)
- Packages: Update memize to 2.1.1 (WordPress/gutenberg#80764)
- ToolsPanel: Migrate styles to an SCSS Module (WordPress/gutenberg#80445)
- RTC: Prevent controlled block synchronization from intercepting undo (WordPress/gutenberg#80503)
- Build Plugin ZIP: don't abort when changelog can't be generated (WordPress/gutenberg#80791)
- RTC: Compact during serialization (WordPress/gutenberg#80707)
- DataForm: Stop card and details validation from hijacking focus (WordPress/gutenberg#80685)
- Only use Flakiness.io in canonical Gutenberg repo. (WordPress/gutenberg#80816)
- Global Styles: Put the inheritance UI behind a Gutenberg experiment (WordPress/gutenberg#80815)
- Add a responsiveEditingEnabled editor setting to hide the Responsive styles option (WordPress/gutenberg#80814)
- iOS: remove jumping hack, add typewriter (WordPress/gutenberg#74596)
- Writing flow: stop the page scrolling on caret moves within blocks taller than the viewport (WordPress/gutenberg#80708)
- List Block: Preserve ordered type on indent (WordPress/gutenberg#75353)
- Block Editor: Try to fix typing performance regression (WordPress/gutenberg#80507)
- Notes: Cancel in-flight hover highlight when focus leaves a note thread (WordPress/gutenberg#80752)
- Make editableRoot a private block setting Symbol, not a public support (WordPress/gutenberg#80820)
- Editor: leave undo to the browser in fields that handle their own undo (WordPress/gutenberg#80768)
- Improve pre-flight npm access checks (WordPress/gutenberg#80334)

Fixes #66065.

git-svn-id: https://develop.svn.wordpress.org/trunk@63533 602fd350-edb4-49c9-b593-d223f7449a82
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Sep 8, 2026
This updates the pinned commit hash of the Gutenberg repository from `2872d71cde528d82675f14862a1b84e2b8abbaea` to `5a0417990a9404cc2562cdd35e3054cb0d3e546e` (version `23.7.0`).

A full list of changes included in this commit can be found on GitHub: https://github.com/WordPress/gutenberg/compare/2872d71cde528d82675f14862a1b84e2b8abbaea..v23.7.0.

- Release: Fix cherry-pick success detection (WordPress/gutenberg#80249)
- Add Table of Contents e2e user story coverage (WordPress/gutenberg#80199)
- Only include icon library SVGs listed as `public` in the Zip file published to GitHub Container Registry for `wordpress-develop` (WordPress/gutenberg#79338)
- fix: set dataviews popover hover text color (WordPress/gutenberg#80105)
- added missing doc (WordPress/gutenberg#80172)
- DataViews: Fix the unintended gap between `list` layout items when `groupBy` is set (WordPress/gutenberg#80254)
- Social Link: Fix stray closing tag in Tumblr icon markup (WordPress/gutenberg#80257)
- DataViews: Fix the `list` layout ignoring some settings when `groupBy` is set (WordPress/gutenberg#80255)
- Icon block: Show text and background color controls by default. (WordPress/gutenberg#80251)
- DataViews: Add shift-click range selection (WordPress/gutenberg#80046)
- UI: Remove unused direction factor CSS property (WordPress/gutenberg#80269)
- theme: Disallow src in published package (WordPress/gutenberg#80213)
- Fix: stale post edit message in modal (WordPress/gutenberg#79997)
- Icons: Validate SVG icons include viewBox (WordPress/gutenberg#80273)
- Remove obsolete __unstable-large size props (WordPress/gutenberg#80081)
- Responsive Editing: support editing pattern styles (WordPress/gutenberg#80233)
- Tab List: Add toolbar buttons to reorder tabs (WordPress/gutenberg#80107)
- Move image editor styles to the block editor package (WordPress/gutenberg#80165)
- Cover/Accordion: Exit on Enter (WordPress/gutenberg#77301)
- Hide color controls for Navigation and Social Icons when viewport states are active (WordPress/gutenberg#80289)
- Icons: Fix collection unregister not removing icons after core added its own registry (WordPress/gutenberg#80292)
- Widget Dashboard: collapse inline attribute controls into a dropdown (WordPress/gutenberg#80208)
- Notes: increase contrast between avatar border colors (WordPress/gutenberg#80285)
- Playlist: Fix track insertion (WordPress/gutenberg#80200)
- Fix: Allow icon labels to wrap with word breaks and no ellipsis (WordPress/gutenberg#80256)
- Dedupe deprecated prop types in composite components (WordPress/gutenberg#80277)
- Core Abilities: Restore the ready promise and lazy-load via dynamic import (WordPress/gutenberg#79155)
- Notes: Replace blur-deselect bookkeeping with useFocusOutside (WordPress/gutenberg#80222)
- UI: Hook Popover into the wp compat overlay slot (WordPress/gutenberg#80278)
- Playlist: Update @SInCE tags to 7.1.0 (WordPress/gutenberg#80317)
- Remove unused useDeprecated36pxDefaultSizeProp helper. (WordPress/gutenberg#80311)
- fix playlist block Dimensions Design (WordPress/gutenberg#80312)
- UI: Keep the compat overlay slot accessible inside Modal (WordPress/gutenberg#80310)
- Theme: Add typography token showcase (WordPress/gutenberg#80212)
- Cover: Create the initial paragraph when the block gains a background (WordPress/gutenberg#80028)
- Notes: Arm the mention kses allowance on REST note creation (WordPress/gutenberg#80221)
- Check for post lock modal and text, not specific title and button (WordPress/gutenberg#79979)
- Worker threads: reject pending RPC calls on worker failure or termination (WordPress/gutenberg#79955)
- RTC: Fix empty revision from peer autosave (WordPress/gutenberg#79911)
- Client Side Media: Honor image_strip_meta and image_max_bit_depth on the client upload path (WordPress/gutenberg#80218)
- Vips/upload-media: consolidate optional params into options objects (WordPress/gutenberg#80330)
- Editor: allow selecting which block styles to apply globally (WordPress/gutenberg#79839)
- Global Styles: Reject non-string custom CSS in the REST controller (WordPress/gutenberg#80338)
- Open inspector sidebar when toggling responsive editing (WordPress/gutenberg#80307)
- Fix upload hang when converting long animated GIFs: decode only the first frame for still outputs (WordPress/gutenberg#80260)
- Fix: Critical error related to simple-git (WordPress/gutenberg#80102)
- Hide block style variations when state is enabled in global styles (WordPress/gutenberg#80341)
- Media REST API: Fix sideload and finalize for EXIF rotated images (WordPress/gutenberg#80295)
- Fix upload snackbar stuck in uploading state on server-side uploads (WordPress/gutenberg#80345)
- Try fixing responsive layout in Nav block (WordPress/gutenberg#80305)
- tools: Remove redundant parseArgs arguments (WordPress/gutenberg#80327)
- Responsive styles: Use viewport dropdown to control states for in-editor global styles sidebar (WordPress/gutenberg#80339)
- Use Add track instead of only Add (WordPress/gutenberg#80336)
- Interactivity API: refactor directives into self-registering modules (WordPress/gutenberg#79975)
- Fix: Critical error websocket-driver fix (WordPress/gutenberg#80348)
- Release: Resolve commander from the test file in the release CLI test (WordPress/gutenberg#80357)
- Release: Extract npm release lifecycle (WordPress/gutenberg#80190)
- Fix multiple MP3 playlist uploads (WordPress/gutenberg#80101)
- Table of Contents: render front-end list from current post headings (WordPress/gutenberg#80318)
- UI: improve component code readability in Storybook by using arrays for children (WordPress/gutenberg#80352)
- Infra: Use devEngines in root package.json and pin npm version in CI (WordPress/gutenberg#80188)
- Automated Testing: Skip type-checking in bundle size comparison build (WordPress/gutenberg#80366)
- Theme: Update colorjs.io dependency and drop bug workaround (WordPress/gutenberg#80272)
- RichTextControl: Replace DOM focus tracking with a single React-tree focus boundary (WordPress/gutenberg#80324)
- Notes: Finish WPDS treatment for mention chips (WordPress/gutenberg#80300)
- Notes: Add placeholders to the RichText fields (WordPress/gutenberg#80296)
- Fix flaky test in `tabs.spec.js` (WordPress/gutenberg#80373)
- Packages: Update exports to avoid deprecated folder export syntax (WordPress/gutenberg#80270)
- Theme: Widen peer dependency ranges to support new versions of Vite, ESBuild, and Stylelint (WordPress/gutenberg#80267)
- Components: Skip polymorphism prop typings on intersection (WordPress/gutenberg#80364)
- Post Content: Use the default block appender for empty content (WordPress/gutenberg#80026)
- Device preview dropdown: use active color for device icon when responsive styles are active (WordPress/gutenberg#80346)
- Fix default aspect ratio for lazy loaded Featured image (WordPress/gutenberg#80386)
- Docs: Add client-side media processing documentation (WordPress/gutenberg#75895)
- Autocompleters: Don't pre-encode mention search terms (WordPress/gutenberg#80377)
- Animated GIF uploads: generate sub-sizes from the first frame, matching core (WordPress/gutenberg#80268)
- Media: Add timeout and size guardrails to client-side GIF to video conversion (WordPress/gutenberg#80379)
- Widget Primitives: Ship as a script module (WordPress/gutenberg#80149)
- SearchControl: Render the suffix only if there's one. (WordPress/gutenberg#80356)
- Custom CSS: Fix cascade order against block style variations (WordPress/gutenberg#80340)
- React 19: add e2e compat test for boolean inert attribute (WordPress/gutenberg#80397)
- Fix post excerpt rendering to conditionally include space before more… (WordPress/gutenberg#70217)
- Add wp-theme as a style dependency of wp-components (WordPress/gutenberg#80362)
- Dashboard Widgets: declarative actions in the widget schema (WordPress/gutenberg#80363)
- @wordpress/ui: Add Button Storybook example for keyboard shortcut composition (WordPress/gutenberg#80353)
- SlotFill: Validate cross-document SCSS module styles (WordPress/gutenberg#80384)
- Components: migrate ConfirmDialog to SCSS module (WordPress/gutenberg#80394)
- SearchControl: Remove redundant conditional and prop. (WordPress/gutenberg#80406)
- Tools: resolve dependencies independently of the node_modules layout (WordPress/gutenberg#80414)
- Components: Migrate ToggleGroupControl to SCSS Modules (WordPress/gutenberg#80381)
- Rich Text: Restore the selection when focus returns to the editable (WordPress/gutenberg#80396)
- RTC: Use requestAnimationFrame for awareness cursor resize redraws (WordPress/gutenberg#79685)
- Remove __shouldNotWarnDeprecated36pxSize internal prop (WordPress/gutenberg#80323)
- Fix upload snackbar double-counting a single HEIC upload in Safari (WordPress/gutenberg#80371)
- Fix Root `.prettierrc.js` override issue (WordPress/gutenberg#80422)
- Fix Color Picker Cursor Shaking Issue (WordPress/gutenberg#80205)
- Storybook: pre-bundle CJS deps (WordPress/gutenberg#80426)
- ContentEditableControl: fix invalid label association with contenteditable div (WordPress/gutenberg#80344)
- Writing flow: use isMultiSelecting for shift+click (WordPress/gutenberg#80286)
- Added Missing Global Documentation (WordPress/gutenberg#80442)
- Editor: Disable canvas resizing while zoomed out (WordPress/gutenberg#80391)
- Misc fixes for WordPress-Develop 7.0 merges (WordPress/gutenberg#75985)
- RTC: Preserve collaborators' unsaved edits when another user saves (WordPress/gutenberg#79936)
- RTC: Disable Quick Edit while a post is being edited (WordPress/gutenberg#80016)
- Storybook: build the resolve specifier as a URL-style string (WordPress/gutenberg#80416)
- Style Book: Restore live global styles updates on the styles route (WordPress/gutenberg#80459)
- Editor: Restore fixed device preview height for mobile and tablet (WordPress/gutenberg#80271)
- Block Supports: Handle nested array block gap values properly (WordPress/gutenberg#80464)
- Block Editor: Guard against non-string spacing preset values (WordPress/gutenberg#80467)
- Move real-time collaboration code to lib/experimental/collaboration (WordPress/gutenberg#80469)
- RTC: Fix deleted-user test on multisite (WordPress/gutenberg#80463)
- Build: add independent react-18 vendor package (WordPress/gutenberg#80367)
- Fix `useHomeEnd` on tabs in mac testing (WordPress/gutenberg#80374)
- Block Editor: Reflect inherited Global Styles values in block inspector controls (WordPress/gutenberg#77894)
- Media: Remove the redundant __heicUploadSupport flag (WordPress/gutenberg#80452)
- Writing flow: fully select the ancestor when a text selection crosses a nesting boundary (WordPress/gutenberg#80462)
- fix: show add block button when editing a template part inside a template (WordPress/gutenberg#78427)
- Autocomplete: Reference the suggestions list with `aria-controls` and `aria-haspopup` (WordPress/gutenberg#80403)
- Dashboard Widgets: Sanitize help link hrefs. (WordPress/gutenberg#80409)
- State control - avoid tertiary variant on toggle to match style of other dropdown toggles (WordPress/gutenberg#80505)
- Widget Dashboard: measure the header fit and document the chrome (WordPress/gutenberg#80423)
- DataViews/Font Library: Give search fields a fixed width to stop layout shift (WordPress/gutenberg#80315)
- Fix crashes when manipulating locked blocks (WordPress/gutenberg#80509)
- RTC: Use str_contains() in WP_Sync_Config type parsing (WordPress/gutenberg#80476)
- Table of Contents: Use str_contains() instead of strpos() check (WordPress/gutenberg#80418)
- Build: Handle project paths containing spaces in dev script (WordPress/gutenberg#80519)
- Components: migrate SearchControl to SCSS module (WordPress/gutenberg#80474)
- Icons: Store the sanitized SVG content when registering an icon (WordPress/gutenberg#80508)
- Resolve Prettier explicitly for isolated layout (WordPress/gutenberg#80529)
- Playlist: Fix playback of tracks served without CORS headers (WordPress/gutenberg#80533)
- Remove unnecessary __next40pxDefaultSize props from form controls (WordPress/gutenberg#80540)
- GitHub workflows: Fix changelog checks for forked PRs (WordPress/gutenberg#80538)
- Redirect editing events to extension handlers under editableRoot (WordPress/gutenberg#80287)
- Writing flow: fully select the items when a selection extends down into a nested item (WordPress/gutenberg#80492)
- Global Styles panels: fix wrong preset committed and shown when two color presets share a hex (WordPress/gutenberg#80497)
- Replaces the `title` attributes used by revision inline diff annotations with `aria-describedby` (WordPress/gutenberg#80440)
- Account for non-lowercase VIDEO tag in render_block filter (WordPress/gutenberg#80537)
- Components: migrate FormTokenField to SCSS module (WordPress/gutenberg#80472)
- Revisions: Specify block level diff status via aria-label (WordPress/gutenberg#77779)
- Notes: Remove "Add note" from the inline styles dropdown (WordPress/gutenberg#80531)
- Global Styles: Resolve per-level heading element styles in block inspector controls (WordPress/gutenberg#80495)
- Notes: Render @ mentions as span chips and narrow the kses class allowance (WordPress/gutenberg#80528)
- Backport from Core: improve icon name unit tests (WordPress/gutenberg#80552)
- Read the contentEditable attribute in ownsSelection, not isContentEditable (WordPress/gutenberg#80549)
- Device type preview: fix collapsing to content height (WordPress/gutenberg#80553)
- Wrap notices in ThemeProvider with 0 corner radius (WordPress/gutenberg#79523)
- Perf Tests: Fix 'Selecting blocks' metric reporting 0 ms (WordPress/gutenberg#80524)
- Global Styles: Limit the inherited value treatment to the Gutenberg plugin (WordPress/gutenberg#80555)
- RTC: Use array_any() for newer-compaction check in polling sync server (WordPress/gutenberg#80522)
- Fix: Update webpack-dev-server to ^5.2.1 to help with dep alerts (WordPress/gutenberg#80347)
- Notes: align floating threads with their inline marker (WordPress/gutenberg#79877)
- WP Build: avoid infinite worker build loop (WordPress/gutenberg#80361)
- Update view config API versioning (WordPress/gutenberg#80319)
- Docs: Update plugin release docs for GitHub's Release label UI (WordPress/gutenberg#80567)
- Release: Require a working GitHub CLI for cherry-picking (WordPress/gutenberg#80568)
- Improve the various Alignment controls props handling (WordPress/gutenberg#63696)
- Reduce duplicated preset utility implementations (WordPress/gutenberg#80245)
- Dashboard Widgets: harden action `href` sanitization (WordPress/gutenberg#80510)
- Notes: Register the inline note format at import time (WordPress/gutenberg#80576)
- Fix preset round-trip test imports after preset utils consolidation (WordPress/gutenberg#80589)
- ExternalLink: Use shared focus ring mixin (WordPress/gutenberg#80573)
- Combobox, Select, SelectControl: Add Group and GroupLabel (WordPress/gutenberg#80574)
- Query Loop: Add translation context to the 'Offset' setting label (WordPress/gutenberg#80582)
- Media: Stop forcing crossorigin on IMG tags in media templates (WordPress/gutenberg#80532)
- GradientPicker: select by slug so two presets sharing a gradient keep their identity (WordPress/gutenberg#80554)
- Media Editor: Show a loading state while the cropped file loads (WordPress/gutenberg#80460)
- Remove default paragraph from tab-panel template (WordPress/gutenberg#80565)
- Global Styles: Resolve link element styles in block inspector controls for blocks that are links (WordPress/gutenberg#80607)
- Math: Use ValidatedTextareaControl for LaTeX input (WordPress/gutenberg#80500)
- Navigation: Fixes `aria-expanded` not updating on hover submenu inside overlay (WordPress/gutenberg#77563)
- Core Data: Move EntitiesSavedState component out of editor (rebase of WordPress/gutenberg#71948) (WordPress/gutenberg#80485)
- Fix: Pullquote custom line height in the editor. (WordPress/gutenberg#80586)
- Block Tools: Fix empty block appender position inside blocks that capture toolbars (WordPress/gutenberg#80592)
- Editor: Avoid unnecessary term re-fetches in FlatTermSelector (WordPress/gutenberg#80623)
- DependencyExtractionWebpackPlugin: Include extracted styles in the asset version hash (WordPress/gutenberg#80601)
- Base styles: Allow overriding focus ring color in outset-ring__focus (WordPress/gutenberg#80587)
- UI: Add Autocomplete.Row primitive (WordPress/gutenberg#80490)
- Site Editor: Add E2E coverage for view config extensibility (WordPress/gutenberg#80577)
- View config: reject shape-mismatched merges, define empty-array semantics, strip nulls from appended members (WordPress/gutenberg#80571)
- Theme: Update Storybook admin color scheme examples (WordPress/gutenberg#80569)
- Detach core's note mention kses filter in the baseline strip test (WordPress/gutenberg#80656)
- Media REST API: Backport sideload from url path upload size check (WordPress/gutenberg#80659)
- Rich text: remove tabIndex from editable elements again to fix shift+click selection (WordPress/gutenberg#80651)
- Storybook: Remove Emotion as JSX import source (WordPress/gutenberg#80647)
- Gallery: make dynamic mode conversion a single undo level (WordPress/gutenberg#80665)
- Docs: Update iframe guidance for Gutenberg 23.6 (WordPress/gutenberg#80629)
- Background image control: Remove duplicated focus ring (WordPress/gutenberg#80671)
- DataViewsPicker: Add Shift+Click range selection to the `picker-table`, `picker-grid`, and `picker-activity` layouts (WordPress/gutenberg#80413)
- Docs: Require view config filter callbacks to return the container (WordPress/gutenberg#80642)
- Duotone: Dedupe duotone utils into global-styles-engine (WordPress/gutenberg#80598)
- Input: Hide native spin controls for `type="number"` (WordPress/gutenberg#80646)
- Make `useSelectionProps` hook layout agnostic (WordPress/gutenberg#80677)
- Remove redundant @jest-environment jsdom pragma and lint against it (WordPress/gutenberg#80676)
- Base Styles: Remove accent color parameter from input-control (WordPress/gutenberg#80595)
- wp-build: sync the page template preload field list with core-data (WordPress/gutenberg#80648)
- Add progressive-discovery pattern for agent instructions and skills and general guidelines (WordPress/gutenberg#80650)
- Writing flow: extend block selections with shift+arrow when there is no native selection (WordPress/gutenberg#80687)
- Fix cursor position during forward delete of empty blocks (WordPress/gutenberg#77525)
- Global Styles: Extract shared preset management from shadows and font sizes (WordPress/gutenberg#79810)
- Notes: Capture the target block before saving a block-level note (WordPress/gutenberg#80690)
- Rename unit tests, removing `spec.js` to match the convention. (WordPress/gutenberg#80711)
- Used @link for url in inline documentation (WordPress/gutenberg#80716)
- Block Library: Guards against error throwing attribute values (WordPress/gutenberg#80558)
- Theme JSON: Level block-level preset class specificity with :where() (WordPress/gutenberg#80657)
- Notes: Sync the sidebar selection to the inline marker under the caret (WordPress/gutenberg#80610)
- Page List: Use null coalescing operator for parentPageID attribute (WordPress/gutenberg#80728)
- Fix font library navigation page select font size to match DataViews. (WordPress/gutenberg#80617)
- Meta boxes: Match heading styles with Gutenberg panels (WordPress/gutenberg#80670)
- Edit Site: Replace Theme usage in canvas loader with CSS (WordPress/gutenberg#80688)
- Jest: Fix ignore patterns with dots (WordPress/gutenberg#80737)
- Components: Migrate Disabled to SCSS module (WordPress/gutenberg#80643)
- Enhance sandbox component to accept sandbox prop (WordPress/gutenberg#69617)
- Docs: Expand the back-porting to WP Core guide (WordPress/gutenberg#80593)
- Add nvm use instructions to AGENTS.md (WordPress/gutenberg#80755)
- Docs: Clarify agent guidance discovery (WordPress/gutenberg#80753)
- Block Editor: Fix floated blocks overlapping sticky blocks (WordPress/gutenberg#80749)
- Shorten playlist track toolbar button label (WordPress/gutenberg#80759)
- Block supports: Return from layout support before resolving global settings (WordPress/gutenberg#80771)
- Notes: Report save success consistently from note actions (WordPress/gutenberg#80748)
- Dynamic Gallery: Rename toolbar button to Detach and add a modal explaining what will happen (WordPress/gutenberg#80727)
- Docs: Clarify getBlock behavior with inner block controllers (WordPress/gutenberg#80773)
- Update docs for server-side view config filters (WordPress/gutenberg#80744)
- createInterpolateElement: handle unmatched closing tags gracefully (WordPress/gutenberg#80618)
- Components: Remove private Theme component (WordPress/gutenberg#80691)
- Block Editor: Refactor 'URLInput' to function component (WordPress/gutenberg#80721)
- UI: add Dialog vs Drawer design guidance (WordPress/gutenberg#80783)
- Packages: Update date-fns to 4.4.0 (WordPress/gutenberg#80763)
- Theme: Update Color.js to 0.7.1 (WordPress/gutenberg#80762)
- ESLint: Add missing not-recommended components to denylist (WordPress/gutenberg#80754)
- Jest: Update to v30 (breaking) (WordPress/gutenberg#80767)
- Packages: Update memize to 2.1.1 (WordPress/gutenberg#80764)
- ToolsPanel: Migrate styles to an SCSS Module (WordPress/gutenberg#80445)
- RTC: Prevent controlled block synchronization from intercepting undo (WordPress/gutenberg#80503)
- Build Plugin ZIP: don't abort when changelog can't be generated (WordPress/gutenberg#80791)
- RTC: Compact during serialization (WordPress/gutenberg#80707)
- DataForm: Stop card and details validation from hijacking focus (WordPress/gutenberg#80685)
- Only use Flakiness.io in canonical Gutenberg repo. (WordPress/gutenberg#80816)
- Global Styles: Put the inheritance UI behind a Gutenberg experiment (WordPress/gutenberg#80815)
- Add a responsiveEditingEnabled editor setting to hide the Responsive styles option (WordPress/gutenberg#80814)
- iOS: remove jumping hack, add typewriter (WordPress/gutenberg#74596)
- Writing flow: stop the page scrolling on caret moves within blocks taller than the viewport (WordPress/gutenberg#80708)
- List Block: Preserve ordered type on indent (WordPress/gutenberg#75353)
- Block Editor: Try to fix typing performance regression (WordPress/gutenberg#80507)
- Notes: Cancel in-flight hover highlight when focus leaves a note thread (WordPress/gutenberg#80752)
- Make editableRoot a private block setting Symbol, not a public support (WordPress/gutenberg#80820)
- Editor: leave undo to the browser in fields that handle their own undo (WordPress/gutenberg#80768)
- Improve pre-flight npm access checks (WordPress/gutenberg#80334)

Fixes #66065.
Built from https://develop.svn.wordpress.org/trunk@63533


git-svn-id: http://core.svn.wordpress.org/trunk@62709 1a063a9b-81f0-0310-95a4-ce76da25c4cd
@one-sz

one-sz commented Oct 3, 2026

Copy link
Copy Markdown

I'm not sure if this issue is back again.

When editing a post/page using the WordPress Block Editor, the global keyboard shortcut handling in @wordpress/compose prevents the native Ctrl+Z / Ctrl+Y behavior in textarea and text input elements that are not part of the Block Editor.

This also affects ACF fields rendered as <textarea>, but the issue can be reproduced without ACF or any third-party plugin.

Steps to reproduce

  1. Open a post/page in the WordPress Block Editor.
  2. Open the browser console.
  3. Create a regular textarea:
const test = document.createElement('textarea');
test.style.position = 'fixed';
test.style.top = '20px';
test.style.left = '20px';
test.style.zIndex = '99999';
document.body.appendChild(test);
test.focus();
  1. Type some text into the textarea.
  2. Press Ctrl+Z.

Expected result:
The native browser undo operation should undo the last change in the textarea.

Actual result:
Nothing happens.

However, right-clicking inside the textarea and selecting "Undo" works correctly.

The same happens with Ctrl+Y for redo.

Additional information

The issue is not caused by preventDefault() being called directly by the test listener. The relevant keyboard handler comes from:

/wp-includes/js/dist/compose.min.js

The registered document keydown handler contains:

function ze(v){
    typeof v.which!="number"&&(v.which=v.keyCode);
    var E=m(v);
    if(E){
        if(v.type=="keyup"&&M===E){
            M=!1;
            return
        }
        c.handleKey(E,S(v),v)
    }
}

The handler intercepts Ctrl+Z even when the event target is a normal textarea outside the Block Editor.

Interestingly, Ctrl+Z works normally inside native Gutenberg blocks, e.g. a standard Paragraph block, because Gutenberg handles the undo operation itself.

Workaround

The following capture-phase listener restores native undo/redo behavior for textareas and text inputs:

document.addEventListener('keydown', function (event) {
    if (!event.ctrlKey) {
        return;
    }
    if (!['z', 'y'].includes(event.key.toLowerCase())) {
        return;
    }
    const target = event.target;
    if (
        target instanceof HTMLTextAreaElement ||
        (
            target instanceof HTMLInputElement &&
            !['checkbox', 'radio', 'button', 'submit', 'reset'].includes(target.type)
        )
    ) {
        event.stopImmediatePropagation();
    }
}, true);

This allows the browser's native Ctrl+Z/Ctrl+Y behavior to work again in textarea/input elements while leaving Gutenberg's undo shortcuts working normally inside Gutenberg blocks.

Expected behavior

The global Block Editor keyboard shortcut handler should not prevent native Ctrl+Z/Ctrl+Y behavior for standard textarea and text input elements that are outside the Gutenberg editing surface.

Environment

WordPress: 7.1.2
Browser: Google Chrome 154
OS: Windows

The issue was reproduced in a WordPress development environment with all plugins disabled, and also using a dynamically-created plain textarea, so it does not appear to be specific to ACF or another third-party plugin.

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 [Package] Block editor /packages/block-editor [Package] Block library /packages/block-library [Package] Edit Post /packages/edit-post [Package] Edit Widgets /packages/edit-widgets [Package] Editor /packages/editor [Type] Bug An existing feature does not function as intended

Projects

None yet

5 participants