close
Skip to content

Post Revisions: Upgrade diff from v4 to v8#77992

Merged
manzoorwanijk merged 8 commits into
trunkfrom
upgrade/diff-to-v8
Jun 8, 2026
Merged

Post Revisions: Upgrade diff from v4 to v8#77992
manzoorwanijk merged 8 commits into
trunkfrom
upgrade/diff-to-v8

Conversation

@manzoorwanijk

@manzoorwanijk manzoorwanijk commented May 6, 2026

Copy link
Copy Markdown
Member

What?

Closes #77976

Upgrades the diff library from ^4.0.2 to ^8.0.3 in packages/editor and packages/block-editor, and updates the post-revisions consumer code so the four-major bump is invisible to users — the in-editor revisions UI keeps the same block pairing and inline word-level diff output it produced under v4.

Why?

The diff library was declared at ^4.0.2 in editor / block-editor and ^8.0.3 in sync, blocking the cross-workspace Syncpack alignment work (#77950, #77954). Bumping editor to ^8.0.3 is a four-major jump that, on its own, breaks four unit tests in block-diff.js and surfaces real UX regressions in the post-revisions feature. The failures fall into two unrelated upstream behaviour changes:

  1. LCS tie-breaker change (v6+). v6 added a "prefer deletions before insertions" tie-breaker, which selects a different LCS for inputs where multiple equal-length matches exist. The relevant case here is prev=[paragraph, whitespace, paragraph] versus curr=[paragraph_modified, whitespace, paragraph]: v8 picks the whitespace pseudo-block as the LCS anchor, so pairSimilarBlocks then sees two removed and two added paragraphs and similarity-matches dissimilar pairs — producing two confusing inline diffs instead of a clean modified+unchanged pair.
  2. diffWords semantics change (v6+). v6 stopped treating whitespace as a token, so adjacent word changes coalesce into one removed/added pair. Inline rich-text diffs lose precision: Visit <a><del>our</del><ins>the</ins> <del>site</del><ins>website</ins></a> today (per-word) becomes Visit <a><del>our site</del><ins>the website</ins></a> today (one coarser diff).

Both are real user-visible regressions, not snapshot drift.

How?

1. Bump the dependency

  • packages/editor/package.json and packages/block-editor/package.json: diff^8.0.3. (packages/sync was already on v8.)

2. Filter whitespace pseudo-blocks before LCS

packages/editor/src/components/post-revisions-preview/block-diff.jsdiffRawBlocks now strips freeform/whitespace pseudo-blocks (the \n\n between block markers) from both arrays before passing them to diffArrays. With those out of the picture, v8's tie-breaker selects the same content-block LCS anchor v4 did for every previously-failing case. Whitespace pseudo-blocks aren't rendered (parseRawBlock returns undefined for them), so dropping them before the diff has no user-visible effect.

pairSimilarBlocks's placement heuristic was extended to match: it previously decided where to anchor a paired modification by checking whether any added block sat between the removed and added positions. Now that whitespace pseudo-blocks are no longer in the result list, an unchanged content block between the two positions is the only "the modified block crosses current-revision content" signal — so the heuristic also fires on unchanged blocks (but still ignores removed blocks, which don't exist in the current revision and so don't count as crossing).

3. Switch rich-text and field diffs to diffWordsWithSpace

  • block-diff.js: applyRichTextDiff and applyDiffToBlock (sidebar changedAttributes) now call diffWordsWithSpace from the top-level diff import. v8's diffWordsWithSpace keeps whitespace as its own token, matching v4's diffWords semantics.
  • revision-fields-diff/index.js: meta field diffs likewise use diffWordsWithSpace.

4. Migrate remaining diff imports to top-level

preserve-client-ids.js and block-compare/index.js used deep paths like 'diff/lib/diff/array'. v8's package.json exports map only wildcards ./lib/*.js (with extension); the bare-folder ./lib/ mapping requires a trailing slash. The deep paths only resolve here because the bundler/Jest resolver fills in .js — a future tooling change could break them. v8 also declares sideEffects: false in its per-output sub-manifests (libcjs/package.json and libesm/package.json), which webpack 4+ honours, so the historical tree-shaking reason for the deep imports no longer applies. The "diff doesn't tree-shake correctly" comment in block-compare/index.js was true for v4 but is now stale and gets removed.

5. Relax one test assertion

The 'handles two blocks that swapped positions' test was asserting which block stayed unmarked vs. which became removed/added. For a pure swap, both LCS choices are equally valid — both v4 and v8 produce semantically-correct output, they just disagree on which block reads as "unchanged." The test now asserts the user-facing invariant (one unmarked + one removed/added pair with same content) instead of the implementation choice.

6. CHANGELOG entries

Added ### Internal entries to packages/editor/CHANGELOG.md and packages/block-editor/CHANGELOG.md recording the major dependency bump.

Testing Instructions

Automated:

npm run test:unit -- -- packages/editor/src/components/post-revisions-preview/ \
                       packages/editor/src/components/revision-fields-diff/ \
                       packages/editor/src/components/revision-diff-panel/ \
                       packages/block-editor/src/components/block-compare/

Expected: 42/42 pass. Full npm run test:unit is also green (32538/32545, 7 unrelated skips).

Manual (golden path for the revisions UI):

  1. Start wp-env (npm run wp-env start) and create a post with several paragraphs.
  2. Edit and save the post a few times to build up a revision history. Mix the kinds of changes:
    • Add a couple of new paragraphs above an existing one and slightly tweak its wording.
    • Swap two paragraphs.
    • Inside a paragraph, change one word inside a link (e.g. our sitethe website).
    • Add <strong> / <em> formatting to part of a paragraph.
  3. Open the post's revisions preview (Document → Revisions → click a prior revision).
  4. Verify the following render the same as on trunk before the bump:
    • The slightly-tweaked paragraph shows as a single modified block with a clean inline <del>…</del><ins>…</ins> diff, not two confusing pair-ups.
    • For a pure swap, exactly one block stays unmarked and the other shows as a removed+added pair with the same content (which side gets matched is implementation-defined — see below).
    • Inside-link word changes show per-word (our → the and site → website as two separate diffs), not coalesced into one.
    • Format-only changes (added bold, changed link URL) render as revision-diff-format-* spans on just the affected range.
  5. Open the Meta panel in the document sidebar during revision mode (if any meta keys differ) and confirm word-level diffs there are also per-word.

Testing Instructions for Keyboard

No UI changes; existing keyboard navigation through the revisions panel is unaffected.

Screenshots or screencast

Before (v8 with no consumer fix) After (this PR)
<del>First</del><ins>Second</ins> block content <ins>modified</ins> + a second confusing inline diff for the unchanged sibling Single modified block with Second block content<ins> modified</ins>; the unchanged sibling stays unmarked
Visit <a><del>our site</del><ins>the website</ins></a> today (one coarse diff) Visit <a><del>our</del><ins>the</ins> <del>site</del><ins>website</ins></a> today (per-word)

Use of AI Tools

This PR was authored with the assistance of Claude Code (Opus 4.7). All edits, the test results, and the manual testing steps were reviewed and verified by me.

@manzoorwanijk manzoorwanijk requested a review from ellatrix as a code owner May 6, 2026 04:53
@github-actions github-actions Bot added [Package] Editor /packages/editor [Package] Block editor /packages/block-editor labels May 6, 2026
@github-actions

github-actions Bot commented May 6, 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.

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: manzoorwanijk <manzoorwanijk@git.wordpress.org>
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: ciampo <mciampini@git.wordpress.org>
Co-authored-by: aduth <aduth@git.wordpress.org>

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

@manzoorwanijk manzoorwanijk self-assigned this May 6, 2026
@manzoorwanijk manzoorwanijk added the [Type] Task Issues or PRs that have been broken down into an individual action to take label May 6, 2026
@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown

Size Change: +1.35 kB (+0.02%)

Total Size: 8.44 MB

📦 View Changed
Filename Size Change
build/scripts/block-editor/index.min.js 380 kB +106 B (+0.03%)
build/scripts/editor/index.min.js 466 kB +1.24 kB (+0.27%)

compressed-size-action

@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown

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

@ciampo

ciampo commented May 6, 2026

Copy link
Copy Markdown
Contributor

This feels like something that @ellatrix should take a look at — I don't personally have much context to understand the full implications of changing / keeping the previous diff behavior.

In the meantime, I'm sharing some notes from an initial round of AI-assisted review

PR Review: #77992 — Post Revisions: Upgrade diff from v4 to v8

Summary

Bumps diff from ^4.0.2 to ^8.0.3 in packages/editor and packages/block-editor to align with packages/sync. Two unrelated upstream behaviour changes (LCS tie-breaker in v6, diffWords whitespace tokenization in v6) would regress the post-revisions UI; the PR addresses both: switches the per-word diffs to diffWordsWithSpace, and inlines a v4-compatible port of diffArrays (~150 LoC) to keep the LCS pivot stable for block-level matching.

The motivation (Syncpack alignment), the diagnosis (the two v6 changes), and the choice of diffWordsWithSpace as the v4-compatible word-diff replacement all check out against the upstream release notes. The main concern is the cost of vendoring the LCS algorithm vs. cheaper alternatives (subclassing v8's Diff class, or making the consumer logic LCS-pivot-insensitive). A few sibling consumers also weren't updated for consistency.

Findings Overview

  1. [major] Vendored ~150 LoC of upstream algorithm — consider subclassing v8's Diff class instead (packages/editor/src/components/post-revisions-preview/block-diff.js:48-193)
  2. [major] preserve-client-ids.js still uses a deep import that's risky under v8 (packages/editor/src/components/post-revisions-preview/preserve-client-ids.js:4)
  3. [major] Missing CHANGELOG entries for editor and block-editor (packages/editor/CHANGELOG.md:3, packages/block-editor/CHANGELOG.md:3)
  4. [minor] Stale tree-shaking comment in block-compare not migrated (packages/block-editor/src/components/block-compare/index.js:5-7)
  5. [minor] Local diffArrays shadows the upstream name — rename for clarity (packages/editor/src/components/post-revisions-preview/block-diff.js:48)
  6. [minor] JSDoc on local diffArrays overstates what the algorithm does (packages/editor/src/components/post-revisions-preview/block-diff.js:30-43)
  7. [minor] "Pure swap" test asserts an arbitrary LCS pivot rather than user-facing invariant (packages/editor/src/components/post-revisions-preview/test/block-diff.js:327-369)
  8. [minor] Helper diffArrays doubles the file's size; consider extracting to a sibling module (packages/editor/src/components/post-revisions-preview/block-diff.js:48-193)
  9. [nit] extractCommon( basePath, diagonalPath )diagonalPath is a number, not a path object (packages/editor/src/components/post-revisions-preview/block-diff.js:66)
  10. [nit] Inconsistent placement of the diffWordsWithSpace rationale comment (packages/editor/src/components/post-revisions-preview/block-diff.js:669-677 vs packages/editor/src/components/revision-fields-diff/index.js:4-9)

1. [major] Consider subclassing v8's Diff class instead of vendoring the algorithm

packages/editor/src/components/post-revisions-preview/block-diff.js:48-193

Inlining ~150 LoC of upstream LCS code is a real maintenance cost: it is now WordPress's responsibility forever, even though the only behaviour we actually want from it is the v4 tie-breaker. v8 explicitly documents class CustomDiff extends Diff as the supported customization API:

The Diff object is now a class. Custom extensions of Diff, as described in the "Defining custom diffing behaviors" section of the README, can therefore now be done by writing a class CustomDiff extends Diff and overriding methods.

A subclass that re-uses v8's algorithm and only overrides the tie-breaker (and keeps v4's (added, removed)(removed, added) post-swap, if still desired) should be ~20–30 LoC instead of ~150, and it inherits all future fixes and performance improvements upstream automatically.

It's also worth questioning whether we need v4-pivot fidelity at all. For both motivating cases:

  • Whitespace pivot ('pairs paragraphs in order when section is condensed'): the failure is real (confusing dual inline diffs). But pairSimilarBlocks is the thing that gets confused — it could likely be made LCS-pivot-insensitive (e.g. by allowing a removed/added pair in either order to feed back into the similarity matcher). That structural fix would survive any future diff change.
  • Pure swap (prev=[First, Second] / curr=[Second, First]): which block reads as "unchanged" vs "moved" is purely cosmetic — both v4 and v8 give equally-valid output here. This alone wouldn't justify vendoring an algorithm.

I'd suggest one of:

  • Subclass Diff and only override the tie-breaker (keep this PR's scope, much smaller surface), or
  • Make pairSimilarBlocks insensitive to LCS pivot choice (longer-term, no inlined algorithm needed).

Either feels preferable to maintaining a v4 reimplementation indefinitely. Happy to be convinced otherwise if you've already considered them — the PR description hints at the structural-fix option but doesn't say why it was ruled out.


2. [major] preserve-client-ids.js deep import is risky under diff v8

packages/editor/src/components/post-revisions-preview/preserve-client-ids.js:4

import { diffArrays } from 'diff/lib/diff/array';

Two concerns:

  1. No .js extension. v8's package.json exports only wildcards ./lib/*.js (with extension); the bare-folder ./lib/ mapping requires a trailing slash on the consumer side. A path like 'diff/lib/diff/array' (no extension) only resolves because the bundler/Jest resolver fills in .js. This worked under v4 because v4 had no exports field. v8's stricter exports map makes this fragile — a future tooling change (or stricter ESM resolver) could break it.
  2. sideEffects: false in v8. The historical reason for the deep import was tree-shaking; v8 marks the package sideEffects: false, so a top-level import { diffArrays } from 'diff' is now equivalent.

Suggest migrating to:

import { diffArrays } from 'diff';

The PR description says "its tests pass under v8 unmodified" — but the tests probably don't exercise the v6 LCS tie-breaker change (block-name signatures rarely produce equally-valid LCSes), so passing tests don't prove behaviour parity. Worth either (a) adding a test that does, or (b) explicitly noting in the file why this consumer is OK with v6 tie-breaker semantics.


3. [major] No CHANGELOG entries

packages/editor/CHANGELOG.md:3, packages/block-editor/CHANGELOG.md:3

Both packages get a major dependency bump but neither has an ## Unreleased > Internal entry. Even though the user-visible behaviour is unchanged by design, a major dep bump (and the inlining of a third-party algorithm port) is exactly the kind of thing that should be discoverable in the CHANGELOG when investigating future regressions.

Suggested entries:

Suggested CHANGELOG entries
### Internal

-   Updated `diff` dependency from `^4.0.2` to `^8.0.3`. ([#77992](https://github.com/WordPress/gutenberg/pull/77992))

(Same entry in packages/block-editor/CHANGELOG.md.)


4. [minor] Stale tree-shaking comment in block-compare; consider migrating its import too

packages/block-editor/src/components/block-compare/index.js:5-7

// diff doesn't tree-shake correctly, so we import from the individual
// module here, to avoid including too much of the library
import { diffChars } from 'diff/lib/diff/character';

This comment was true for v4 (no sideEffects declaration). It's no longer true for v8 (sideEffects: false, see release notes 8.0.2). Now that block-editor is also on v8, this is a good moment to:

  • Migrate the import to top-level (import { diffChars } from 'diff'), and
  • Remove the stale comment.

Same reasoning as #2. Keeping it within scope here makes the diff tooling consistent across the three consumers in the package.


5. [minor] Local diffArrays shadows the upstream name

packages/editor/src/components/post-revisions-preview/block-diff.js:48

function diffArrays( oldArr, newArr ) {

If a future contributor re-adds import { diffArrays } from 'diff' (e.g. for an unrelated diff in the same file), the import will silently shadow / collide with the local helper. Renaming the local one makes the v4-compatibility intent explicit and avoids the collision risk:

Suggested rename
function diffArraysV4Compatible( oldArr, newArr ) {
  // ...
}

6. [minor] JSDoc on diffArrays overstates what the algorithm does

packages/editor/src/components/post-revisions-preview/block-diff.js:30-43

/**
 * Compute an LCS-based array diff with the same tie-breaker semantics as
 * `diff` v4's `diffArrays`. The post-revisions UI relies on a specific LCS
 * choice when multiple equally-valid matches exist (e.g. preferring the
 * earlier occurrence in the previous revision over later ones, and
 * preferring content blocks over freeform/whitespace blocks). `diff` v6
 * changed the tie-breaker to "deletions before insertions", which produces
 * a different but equally-valid pairing — visible as confusing inline diffs
 * in the post-revisions feature. We reproduce v4's selection locally so
 * block-level matching stays stable across upgrades of the `diff` library.
 ...
 */

"Preferring content blocks over freeform/whitespace blocks" isn't something this function does — it's a downstream consequence of the LCS tie-breaker interacting with how pairSimilarBlocks then groups results. Stating it as a property of diffArrays is misleading; the function only tie-breaks on newPos. Suggest reworking to focus on the algorithmic invariant ("when multiple equal-length LCSes exist, prefer the one that advances newPos further") and leaving the downstream consequences in the comment on the consumer (pairSimilarBlocks).


7. [minor] "Pure swap" test asserts an arbitrary LCS pivot

packages/editor/src/components/post-revisions-preview/test/block-diff.js:327-369

The 'handles two blocks that swapped positions' test asserts the exact order [Second:added, First:unchanged, Second:removed] — meaning "First" stays put, "Second" moves. The opposite outcome ([Second:unchanged, ...]) would be equally valid LCS output. Asserting one over the other ties the test to the implementation choice rather than to user-facing value.

A more robust assertion would test the invariant — e.g. exactly one block is unmarked, the other is shown as removed+added with consistent content — without prescribing which one. That way the test would also pass on diff v8 directly (without the local diffArrays), letting the suite tell us which behaviour changes are user-visible vs. just LCS pivot drift.

Less critical than the items above, but worth considering since this test is one of the listed motivations for vendoring diffArrays.


8. [minor] Helper doubles the file's size; consider extracting

packages/editor/src/components/post-revisions-preview/block-diff.js:48-193

The local diffArrays adds ~150 LoC at the top of block-diff.js, which now mixes two unrelated concerns: (a) the LCS algorithm port and (b) the post-revisions diff orchestration. Extracting diffArrays to a sibling module (e.g. diff-arrays-v4.js) would:

  • Keep block-diff.js focused on revision-specific logic.
  • Make the algorithm port easier to delete in one shot if/when the consumer logic becomes pivot-insensitive (per TinyMCE formatting improvements #1).

Lower priority if you take #1 — subclassing would shrink it enough that extraction is unnecessary.


9. [nit] extractCommon( basePath, diagonalPath ) — parameter is a number

packages/editor/src/components/post-revisions-preview/block-diff.js:66

const extractCommon = ( basePath, diagonalPath ) => {

diagonalPath is the diagonal index (a number), not a path object — and the outer loop calls it diag. Renaming the parameter to diag for consistency would avoid the suggestion that it's another basePath-shaped value.


10. [nit] Inconsistent placement of the diffWordsWithSpace rationale comment

In block-diff.js, the rationale lives at the call site (inside applyRichTextDiff):

	/*
	 * Diff the plain text (words for cleaner output).
	 *
	 * `diffWordsWithSpace` keeps whitespace as its own token, the same
	 * behaviour `diffWords` had in `diff` v4. v6+ stopped treating
	 * whitespace as a token, which would otherwise coalesce adjacent word
	 * changes into one removed/added pair instead of reporting them
	 * separately — making the inline rich-text diff less precise.
	 */

But in revision-fields-diff/index.js, the same rationale lives at the import site:

/*
 * `diffWordsWithSpace` preserves the v4-style per-word output. v6+
 * stopped treating whitespace as a token in `diffWords`, which coalesces
 * adjacent word changes into a single removed/added pair.
 */

Minor inconsistency — pick one and apply uniformly. Since block-diff.js uses diffWordsWithSpace in two distinct call sites (applyRichTextDiff and applyDiffToBlock), the import-site comment is probably the cleaner pattern for both files.

manzoorwanijk added a commit that referenced this pull request May 6, 2026
Addresses review feedback on #77992 (findings 1, 5, 6, 7, 8, 9).

The previous commit inlined ~150 LoC of v4's Myers algorithm to keep
`diffArrays`'s LCS pivot stable across the v4 -> v8 bump. That preserved
all existing test assertions but came at a real maintenance cost.

The cleaner approach (the issue's original "Class 1" fix): just drop
freeform/whitespace pseudo-blocks from both arrays before LCS. Without
the `\n\n` blocks competing as a match anchor, v8's "deletions before
insertions" tie-breaker picks the same content-block pivot v4 did for
every input that was previously failing, and the inlined algorithm
becomes unnecessary.

Two follow-ups to make that approach work end-to-end:

1. Adjust `pairSimilarBlocks`'s placement heuristic. The original
   heuristic looked for *added* blocks between the removed and added
   positions to decide where to anchor a paired modification. With
   whitespace pseudo-blocks no longer in the result list, an unchanged
   content block between the two positions is now the only "the
   modified block crosses current-revision content" signal -- so the
   heuristic now also fires on unchanged blocks (but still ignores
   removed blocks, which don't exist in the current revision and so
   don't count as crossing).

2. Relax the `'handles two blocks that swapped positions'` assertion to
   the user-facing invariant (one unmarked + one removed/added pair
   with same content) rather than which side of the swap gets matched.
   For a pure swap the two LCS choices are equally valid -- both v4 and
   v8 produce semantically-correct output, they just disagree on which
   block reads as "unchanged" -- so asserting one is testing the
   implementation, not the behaviour.

Net: -191 +56 LoC in `block-diff.js`. All 33 block-diff unit tests pass
and the broader revision-related suites stay green.
manzoorwanijk added a commit that referenced this pull request May 6, 2026
Addresses review feedback on #77992 (findings 2, 3, 4, 10).

- `preserve-client-ids.js` and `block-compare/index.js` now import
  `diffArrays` / `diffChars` from the top-level `'diff'` package
  instead of the deep `'diff/lib/diff/<name>'` paths. v8's
  `package.json` `exports` map only wildcards `./lib/*.js` (with
  extension); the bare-folder `./lib/` mapping requires a trailing
  slash. The deep paths only resolve here because the bundler/Jest
  resolver fills in `.js` -- a future tooling change could break
  them. v8 also marks the package `sideEffects: false`, so the
  historical tree-shaking reason for the deep imports no longer
  applies. The "diff doesn't tree-shake correctly" comment in
  `block-compare/index.js` is now stale and gets removed.

- Add `### Internal` entries to `packages/editor/CHANGELOG.md` and
  `packages/block-editor/CHANGELOG.md` recording the major dependency
  bump.
manzoorwanijk added a commit that referenced this pull request May 6, 2026
Addresses review feedback on #77992 (findings 1, 5, 6, 7, 8, 9).

The previous commit inlined ~150 LoC of v4's Myers algorithm to keep
`diffArrays`'s LCS pivot stable across the v4 -> v8 bump. That preserved
all existing test assertions but came at a real maintenance cost.

The cleaner approach (the issue's original "Class 1" fix): just drop
freeform/whitespace pseudo-blocks from both arrays before LCS. Without
the `\n\n` blocks competing as a match anchor, v8's "deletions before
insertions" tie-breaker picks the same content-block pivot v4 did for
every input that was previously failing, and the inlined algorithm
becomes unnecessary.

Two follow-ups to make that approach work end-to-end:

1. Adjust `pairSimilarBlocks`'s placement heuristic. The original
   heuristic looked for *added* blocks between the removed and added
   positions to decide where to anchor a paired modification. With
   whitespace pseudo-blocks no longer in the result list, an unchanged
   content block between the two positions is now the only "the
   modified block crosses current-revision content" signal -- so the
   heuristic now also fires on unchanged blocks (but still ignores
   removed blocks, which don't exist in the current revision and so
   don't count as crossing).

2. Relax the `'handles two blocks that swapped positions'` assertion to
   the user-facing invariant (one unmarked + one removed/added pair
   with same content) rather than which side of the swap gets matched.
   For a pure swap the two LCS choices are equally valid -- both v4 and
   v8 produce semantically-correct output, they just disagree on which
   block reads as "unchanged" -- so asserting one is testing the
   implementation, not the behaviour.

Net: -191 +56 LoC in `block-diff.js`. All 33 block-diff unit tests pass
and the broader revision-related suites stay green.
manzoorwanijk added a commit that referenced this pull request May 6, 2026
Addresses review feedback on #77992 (findings 2, 3, 4, 10).

- `preserve-client-ids.js` and `block-compare/index.js` now import
  `diffArrays` / `diffChars` from the top-level `'diff'` package
  instead of the deep `'diff/lib/diff/<name>'` paths. v8's
  `package.json` `exports` map only wildcards `./lib/*.js` (with
  extension); the bare-folder `./lib/` mapping requires a trailing
  slash. The deep paths only resolve here because the bundler/Jest
  resolver fills in `.js` -- a future tooling change could break
  them. v8 also marks the package `sideEffects: false`, so the
  historical tree-shaking reason for the deep imports no longer
  applies. The "diff doesn't tree-shake correctly" comment in
  `block-compare/index.js` is now stale and gets removed.

- Add `### Internal` entries to `packages/editor/CHANGELOG.md` and
  `packages/block-editor/CHANGELOG.md` recording the major dependency
  bump.
manzoorwanijk added a commit that referenced this pull request May 8, 2026
Addresses review feedback on #77992 (findings 1, 5, 6, 7, 8, 9).

The previous commit inlined ~150 LoC of v4's Myers algorithm to keep
`diffArrays`'s LCS pivot stable across the v4 -> v8 bump. That preserved
all existing test assertions but came at a real maintenance cost.

The cleaner approach (the issue's original "Class 1" fix): just drop
freeform/whitespace pseudo-blocks from both arrays before LCS. Without
the `\n\n` blocks competing as a match anchor, v8's "deletions before
insertions" tie-breaker picks the same content-block pivot v4 did for
every input that was previously failing, and the inlined algorithm
becomes unnecessary.

Two follow-ups to make that approach work end-to-end:

1. Adjust `pairSimilarBlocks`'s placement heuristic. The original
   heuristic looked for *added* blocks between the removed and added
   positions to decide where to anchor a paired modification. With
   whitespace pseudo-blocks no longer in the result list, an unchanged
   content block between the two positions is now the only "the
   modified block crosses current-revision content" signal -- so the
   heuristic now also fires on unchanged blocks (but still ignores
   removed blocks, which don't exist in the current revision and so
   don't count as crossing).

2. Relax the `'handles two blocks that swapped positions'` assertion to
   the user-facing invariant (one unmarked + one removed/added pair
   with same content) rather than which side of the swap gets matched.
   For a pure swap the two LCS choices are equally valid -- both v4 and
   v8 produce semantically-correct output, they just disagree on which
   block reads as "unchanged" -- so asserting one is testing the
   implementation, not the behaviour.

Net: -191 +56 LoC in `block-diff.js`. All 33 block-diff unit tests pass
and the broader revision-related suites stay green.
manzoorwanijk added a commit that referenced this pull request May 8, 2026
Addresses review feedback on #77992 (findings 2, 3, 4, 10).

- `preserve-client-ids.js` and `block-compare/index.js` now import
  `diffArrays` / `diffChars` from the top-level `'diff'` package
  instead of the deep `'diff/lib/diff/<name>'` paths. v8's
  `package.json` `exports` map only wildcards `./lib/*.js` (with
  extension); the bare-folder `./lib/` mapping requires a trailing
  slash. The deep paths only resolve here because the bundler/Jest
  resolver fills in `.js` -- a future tooling change could break
  them. v8 also marks the package `sideEffects: false`, so the
  historical tree-shaking reason for the deep imports no longer
  applies. The "diff doesn't tree-shake correctly" comment in
  `block-compare/index.js` is now stale and gets removed.

- Add `### Internal` entries to `packages/editor/CHANGELOG.md` and
  `packages/block-editor/CHANGELOG.md` recording the major dependency
  bump.
@ciampo ciampo requested a review from Copilot May 8, 2026 15:52

Copilot AI 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.

Pull request overview

This PR upgrades the diff dependency used by the editor’s revisions/compare features from v4 to v8, and updates the revisions diffing logic to preserve the same user-facing pairing and word-level inline diff behavior despite upstream behavioral changes in diff.

Changes:

  • Upgrade diff to ^8.0.3 in @wordpress/editor and @wordpress/block-editor, and migrate remaining imports to the top-level diff entrypoint.
  • Stabilize block pairing under diffArrays by filtering whitespace-only freeform pseudo-blocks before LCS matching, and adjust the placement heuristic in pairSimilarBlocks.
  • Restore per-word inline diffs by switching from diffWords to diffWordsWithSpace for rich-text, sidebar changed-attribute diffs, and meta-field diffs; relax one swap test assertion to assert the UX invariant rather than a specific LCS tie-break.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/editor/src/components/revision-fields-diff/index.js Switch meta diffs to diffWordsWithSpace via top-level diff import to preserve per-word output.
packages/editor/src/components/post-revisions-preview/test/block-diff.js Update swap test to assert invariant output instead of a specific unchanged-anchor choice.
packages/editor/src/components/post-revisions-preview/preserve-client-ids.js Migrate diffArrays import to top-level diff.
packages/editor/src/components/post-revisions-preview/block-diff.js Filter whitespace pseudo-blocks pre-LCS; adjust pairing placement heuristic; use diffWordsWithSpace for inline and attribute diffs.
packages/editor/package.json Bump diff dependency to ^8.0.3.
packages/editor/CHANGELOG.md Record the diff major-version bump under Internal changes.
packages/block-editor/src/components/block-compare/index.js Migrate diffChars import to top-level diff and remove now-stale tree-shaking comment.
packages/block-editor/package.json Bump diff dependency to ^8.0.3.
packages/block-editor/CHANGELOG.md Record the diff major-version bump under Internal changes.
package-lock.json Lockfile updates reflecting diff v8 installs for the updated workspaces.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ciampo

ciampo commented May 8, 2026

Copy link
Copy Markdown
Contributor

@manzoorwanijk FWIW, sharing another round of AI-assisted review.

Click to expand

PR Review: #77992 — Post Revisions: Upgrade diff from v4 to v8 (round 2)

Summary

This round reviews the PR after the previous round of feedback was applied. The author replaced the ~150 LoC vendored LCS port with a much smaller, sturdier fix: filter whitespace pseudo-blocks out of the input arrays before LCS, and update pairSimilarBlocks's placement heuristic so the unchanged-content case is detected without relying on a specific diffArrays tie-breaker. All four "major" items from the prior round are addressed: deep-path imports are migrated to top-level (block-compare, preserve-client-ids, block-diff), CHANGELOG entries are present in both packages, and the stale tree-shaking comment is gone.

The new approach is sound and substantially less risky than vendoring. Remaining feedback is small and mostly clarifying.

Findings Overview

  1. [Possible issue] Asymmetric pairSimilarBlocks lookahead: 'modified' status is not treated as crossing current-revision content (packages/editor/src/components/post-revisions-preview/block-diff.js:271-282)
  2. [minor] No focused unit test for the whitespace-pseudo-block filter (packages/editor/src/components/post-revisions-preview/test/block-diff.js)
  3. [minor] isWhitespaceRawBlock only runs at the top of each diffRawBlocks invocation — consider asserting the invariant in the recursive call (packages/editor/src/components/post-revisions-preview/block-diff.js:322-330)
  4. [minor] Tree-shaking comment removed but tree-shaking guarantee is more nuanced than the PR description suggests (packages/block-editor/src/components/block-compare/index.js:5)
  5. [nit] Rationale comment placement is now inconsistent again (packages/editor/src/components/post-revisions-preview/block-diff.js:4-10 vs packages/editor/src/components/revision-fields-diff/index.js:4-9)
  6. [nit] crossesCurrentContent comment is slightly out of sync with the code (packages/editor/src/components/post-revisions-preview/block-diff.js:260-268)

1. [Possible issue] Asymmetric lookahead in pairSimilarBlocks ignores already-paired modifications

packages/editor/src/components/post-revisions-preview/block-diff.js:271-282

The new heuristic treats unchanged blocks (status === undefined) and unpaired added blocks as "crossing current-revision content," but ignores 'modified' blocks. In the loop, modifications produced by earlier iterations of the outer for ( const rem of removed ) are stored only in the modifications Map — blocks[ i ].__revisionDiffStatus.status for those indices still reads as 'added' or 'removed', so this works out for the current iteration. But once crossesCurrentContent is decided based on 'added' && ! pairedAdded.has( i ), an added block that has already been "absorbed" into a pairing at the removed position (i.e. is in pairedAdded) is treated as not crossing — which is what we want. However, the symmetric case (a removed block at the added position, i.e. in pairedRemoved) isn't checked at all, because the loop never breaks on 'removed'.

In practice the existing tests all pass, so this may be intentional (removed blocks don't exist in the current revision and so don't actually "cross" current-revision content). But the asymmetry is worth a one-line confirmation in the comment, e.g.:

// 'removed' blocks (and pairedRemoved blocks placed at an added
// position) are not in the current revision and so don't count as
// crossing it. 'added' blocks that have already been absorbed into a
// modification at a removed position (pairedAdded) similarly don't.

If you're confident the current behaviour is correct, ignore — just flagging because the semantic distinction "current-revision content" vs. "anything in the result list" is what the heuristic now hinges on, and the code reads as if it might be inadvertently asymmetric.


2. [minor] Add a focused test for whitespace-pseudo-block filtering

packages/editor/src/components/post-revisions-preview/test/block-diff.js

The whitespace-filter behaviour is the primary mechanism for keeping LCS output stable across diff major versions, but it's only exercised transitively via the 'pairs paragraphs in order when section is condensed' test (which doesn't fail on a regression of the filter; it would fail downstream in pairSimilarBlocks). A direct test would lock the contract:

Suggested test
it( 'ignores whitespace-only freeform pseudo-blocks between block markers', () => {
  // Two paragraphs separated by raw whitespace at the document level
  // (the grammar parser emits these as { blockName: null, innerHTML: '\n\n' }).
  // Swapping their order shouldn't latch onto the whitespace pseudo-block
  // as the LCS anchor.
  const previous =
    '<!-- wp:paragraph --><p>First</p><!-- /wp:paragraph -->\n\n' +
    '<!-- wp:paragraph --><p>Second</p><!-- /wp:paragraph -->';
  const current =
    '<!-- wp:paragraph --><p>Second</p><!-- /wp:paragraph -->\n\n' +
    '<!-- wp:paragraph --><p>First</p><!-- /wp:paragraph -->';
  const blocks = diffRevisionContent( current, previous );
  // … assert one unchanged + one removed/added pair (the swap invariant)
} );

That way, if a future diff upgrade or refactor breaks the filter (e.g. blockName === null semantics change), this test is the canary, instead of an unrelated paragraph-condensing test failing in a confusing way.


3. [minor] Defensive: assert the filter holds inside recursion

packages/editor/src/components/post-revisions-preview/block-diff.js:322-330

function diffRawBlocks( currentRaw, previousRaw ) {
  // Strip whitespace-only freeform pseudo-blocks before LCS — see
  // `isWhitespaceRawBlock` for why.
  const currentBlocks = currentRaw.filter(
    ( b ) => ! isWhitespaceRawBlock( b )
  );
  const previousBlocks = previousRaw.filter(
    ( b ) => ! isWhitespaceRawBlock( b )
  );

The filter now runs at the top of every recursive call, which is correct but does redundant work for inner recursive calls (their innerBlocks were already filtered when the parent was diffed and stored). Harmless, just worth either:

  • Documenting in the JSDoc that the filter is intentionally re-applied at every level (so the function is safe to call directly with raw grammar output, which is its public contract), or
  • Pulling the filter out so it only runs at the top-level entry (diffRevisionContent) and asserting the invariant inside diffRawBlocks.

The first option is probably the right one — it keeps the function self-contained and the duplicate work is negligible.


4. [minor] block-compare tree-shaking comment removal — verify the assumption

packages/block-editor/src/components/block-compare/index.js:5

The PR description says "v8 also marks the package sideEffects: false", which made the deep diff/lib/diff/character import unnecessary. That's almost accurate — v8's top-level package.json doesn't have sideEffects: false; the flag lives in the per-output sub-manifests at libcjs/package.json and libesm/package.json that kpdecker/jsdiff writes during its build. Webpack 4+ honors nested sideEffects declarations, so tree-shaking should still work, but it's not exactly the property the PR description implies.

The size-change report on this PR (+866 B total, +784 B in editor, +82 B in block-editor) is consistent with tree-shaking working correctly — the editor bump is the new pairSimilarBlocks heuristic plus the LCS work, not unused diff code. So this is mostly cosmetic / for the description, not the code.


5. [nit] Rationale comment placement inconsistent across files

packages/editor/src/components/post-revisions-preview/block-diff.js:4-10 vs. packages/editor/src/components/revision-fields-diff/index.js:4-9

The two files now use slightly different framings:

/*
 * `diffWordsWithSpace` keeps whitespace as its own token, matching the
 * behaviour `diffWords` had in `diff` v4. v6+ stopped treating whitespace
 * as a token, which would otherwise coalesce adjacent word changes into a
 * single removed/added pair instead of reporting them per-word.
 */
import { diffArrays, diffWordsWithSpace } from 'diff';
/*
 * `diffWordsWithSpace` preserves the v4-style per-word output. v6+
 * stopped treating whitespace as a token in `diffWords`, which coalesces
 * adjacent word changes into a single removed/added pair.
 */
import { diffWordsWithSpace } from 'diff';

These are saying the same thing in two different ways; using identical wording (or extracting to a shared comment block) makes future grep-ability easier. Take or leave.


6. [nit] crossesCurrentContent comment slightly out of sync with code

packages/editor/src/components/post-revisions-preview/block-diff.js:260-268

// Decide where to place the modified block by checking
// what's between the removed and added positions.
// If anything between them is part of the current revision
// (an unpaired added block, or an unchanged block),
// placing at the removed position would put the modified
// block before content that comes before it in the
// current revision — so use the added position.
// Otherwise, use the removed position to keep the
// previous revision's order intact.

The comment says "if anything between them is part of the current revision," but the code only checks two specific cases (unchanged via status === undefined, and unpaired added). Modifications previously produced by this same loop iteration aren't checked — which is fine in practice (see #1) but the comment overstates the generality. Suggest narrowing the wording, e.g.:

// If any block between the two positions is in the current
// revision (an unchanged block, or an unpaired added block),
// placing the modification at the removed position would put it
// before content that already comes before it in the current
// revision — so use the added position instead.

…and possibly add an inline note that "removed and pairedRemoved blocks aren't checked because they're not in the current revision."

Still, I think this PR should be reviewed by someone familiar with the WordPress/Gutenberg diffiing, too.

manzoorwanijk added a commit that referenced this pull request May 8, 2026
Addresses round-2 review feedback on #77992 (human #1, #3, #5, #6 + Codex
test gaps a, b).

- Add a `'filters whitespace-only freeform pseudo-blocks before LCS'`
  test that's a direct canary for the whitespace filter — without the
  filter, `pairSimilarBlocks` would mis-match two paragraphs across the
  whitespace pseudo-block as the LCS anchor and produce two confused
  modified blocks instead of one modified + one unchanged.
- Add a `'places paired modification at current-revision position when
  only unchanged blocks sit between'` test exercising the new
  `crossesCurrentContent` "unchanged between removed and added" branch
  in isolation. Previously only hit transitively through the
  `'handles block move with a tiny change'` test, which mixes that
  branch with the whitespace-filter path and other heuristics.
- Tighten the `crossesCurrentContent` comment so it matches what the
  code actually checks (unpaired-added + unchanged) and adds a one-line
  note that 'removed' / `pairedAdded` blocks aren't checked because
  they aren't in the current revision.
- Match the `diffWordsWithSpace` rationale comment between
  `block-diff.js` and `revision-fields-diff/index.js` for grep-ability.
- Document on `diffRawBlocks` that the whitespace filter is
  intentionally re-applied at every recursive level so the function
  stays self-contained when called directly with raw grammar output.

No logic changes. All 35 block-diff tests + the broader unit suite
(32598 tests) stay green.
@manzoorwanijk

Copy link
Copy Markdown
Member Author

@manzoorwanijk FWIW, sharing another round of AI-assisted review.

Thank you. I have addressed the feedback.

I think this PR should be reviewed by someone familiar with the WordPress/Gutenberg diffiing, too.

Yes, I agree. Let us see if @ellatrix finds some time to have a look at this.

@ciampo

ciampo commented May 11, 2026

Copy link
Copy Markdown
Contributor

cc'ing @aduth on this PR too, since he was partially involved in some npm / package.json / syncpack conversations

manzoorwanijk added a commit that referenced this pull request Jun 4, 2026
Addresses round-2 review feedback on #77992 (human #1, #3, #5, #6 + Codex
test gaps a, b).

- Add a `'filters whitespace-only freeform pseudo-blocks before LCS'`
  test that's a direct canary for the whitespace filter — without the
  filter, `pairSimilarBlocks` would mis-match two paragraphs across the
  whitespace pseudo-block as the LCS anchor and produce two confused
  modified blocks instead of one modified + one unchanged.
- Add a `'places paired modification at current-revision position when
  only unchanged blocks sit between'` test exercising the new
  `crossesCurrentContent` "unchanged between removed and added" branch
  in isolation. Previously only hit transitively through the
  `'handles block move with a tiny change'` test, which mixes that
  branch with the whitespace-filter path and other heuristics.
- Tighten the `crossesCurrentContent` comment so it matches what the
  code actually checks (unpaired-added + unchanged) and adds a one-line
  note that 'removed' / `pairedAdded` blocks aren't checked because
  they aren't in the current revision.
- Match the `diffWordsWithSpace` rationale comment between
  `block-diff.js` and `revision-fields-diff/index.js` for grep-ability.
- Document on `diffRawBlocks` that the whitespace filter is
  intentionally re-applied at every recursive level so the function
  stays self-contained when called directly with raw grammar output.

No logic changes. All 35 block-diff tests + the broader unit suite
(32598 tests) stay green.
@manzoorwanijk

Copy link
Copy Markdown
Member Author

Just a gentle reminder that this PR has been a blocker for other dependency improvements via #77950.

Aligns `packages/editor` and `packages/block-editor` with `packages/sync` on
`diff@^8.0.3` (needed for the Syncpack alignment work in #77950 / #77954).
The bump exposes two unrelated upstream changes that would regress the
post-revisions UI:

1. v6+ adds a "deletions before insertions" tie-breaker, so for inputs
   with multiple equal-length LCSes (whitespace-block pivots, paragraph
   swaps), `diffArrays` selects a different match than v4 did. The
   downstream `pairSimilarBlocks` step then mis-pairs blocks and shows
   two confusing inline diffs instead of a clean modified+unchanged pair.
2. v6+ stops treating whitespace as a token in `diffWords`, coalescing
   adjacent word changes into one removed/added pair and losing per-word
   precision in inline rich-text diffs.

Fix on the consumer side so existing tests pass without touching any
assertion:

- Replace the imported `diffArrays` in `block-diff.js` with a local
  v4-compatible port of `Diff.prototype.diff` (Myers, array+strict-eq),
  including v4's `(added, removed)` -> `(removed, added)` swap in
  `buildValues` so condensed sections still render in the right order.
- Switch `diffWords` -> `diffWordsWithSpace` for the inline rich-text
  diff, the `changedAttributes` panel diff, and the `Meta` field diff
  in `revision-fields-diff`.

`preserve-client-ids.js` and `block-compare` (uses `diffChars`) need no
changes -- neither hits the affected v6+ behaviours and their tests pass
unmodified under v8.

41/41 revision-related unit tests pass; full `npm run test:unit` is
green.

Closes #77976
Addresses review feedback on #77992 (findings 1, 5, 6, 7, 8, 9).

The previous commit inlined ~150 LoC of v4's Myers algorithm to keep
`diffArrays`'s LCS pivot stable across the v4 -> v8 bump. That preserved
all existing test assertions but came at a real maintenance cost.

The cleaner approach (the issue's original "Class 1" fix): just drop
freeform/whitespace pseudo-blocks from both arrays before LCS. Without
the `\n\n` blocks competing as a match anchor, v8's "deletions before
insertions" tie-breaker picks the same content-block pivot v4 did for
every input that was previously failing, and the inlined algorithm
becomes unnecessary.

Two follow-ups to make that approach work end-to-end:

1. Adjust `pairSimilarBlocks`'s placement heuristic. The original
   heuristic looked for *added* blocks between the removed and added
   positions to decide where to anchor a paired modification. With
   whitespace pseudo-blocks no longer in the result list, an unchanged
   content block between the two positions is now the only "the
   modified block crosses current-revision content" signal -- so the
   heuristic now also fires on unchanged blocks (but still ignores
   removed blocks, which don't exist in the current revision and so
   don't count as crossing).

2. Relax the `'handles two blocks that swapped positions'` assertion to
   the user-facing invariant (one unmarked + one removed/added pair
   with same content) rather than which side of the swap gets matched.
   For a pure swap the two LCS choices are equally valid -- both v4 and
   v8 produce semantically-correct output, they just disagree on which
   block reads as "unchanged" -- so asserting one is testing the
   implementation, not the behaviour.

Net: -191 +56 LoC in `block-diff.js`. All 33 block-diff unit tests pass
and the broader revision-related suites stay green.
Addresses review feedback on #77992 (findings 2, 3, 4, 10).

- `preserve-client-ids.js` and `block-compare/index.js` now import
  `diffArrays` / `diffChars` from the top-level `'diff'` package
  instead of the deep `'diff/lib/diff/<name>'` paths. v8's
  `package.json` `exports` map only wildcards `./lib/*.js` (with
  extension); the bare-folder `./lib/` mapping requires a trailing
  slash. The deep paths only resolve here because the bundler/Jest
  resolver fills in `.js` -- a future tooling change could break
  them. v8 also marks the package `sideEffects: false`, so the
  historical tree-shaking reason for the deep imports no longer
  applies. The "diff doesn't tree-shake correctly" comment in
  `block-compare/index.js` is now stale and gets removed.

- Add `### Internal` entries to `packages/editor/CHANGELOG.md` and
  `packages/block-editor/CHANGELOG.md` recording the major dependency
  bump.
Addresses round-2 review feedback on #77992 (human #1, #3, #5, #6 + Codex
test gaps a, b).

- Add a `'filters whitespace-only freeform pseudo-blocks before LCS'`
  test that's a direct canary for the whitespace filter — without the
  filter, `pairSimilarBlocks` would mis-match two paragraphs across the
  whitespace pseudo-block as the LCS anchor and produce two confused
  modified blocks instead of one modified + one unchanged.
- Add a `'places paired modification at current-revision position when
  only unchanged blocks sit between'` test exercising the new
  `crossesCurrentContent` "unchanged between removed and added" branch
  in isolation. Previously only hit transitively through the
  `'handles block move with a tiny change'` test, which mixes that
  branch with the whitespace-filter path and other heuristics.
- Tighten the `crossesCurrentContent` comment so it matches what the
  code actually checks (unpaired-added + unchanged) and adds a one-line
  note that 'removed' / `pairedAdded` blocks aren't checked because
  they aren't in the current revision.
- Match the `diffWordsWithSpace` rationale comment between
  `block-diff.js` and `revision-fields-diff/index.js` for grep-ability.
- Document on `diffRawBlocks` that the whitespace filter is
  intentionally re-applied at every recursive level so the function
  stays self-contained when called directly with raw grammar output.

No logic changes. All 35 block-diff tests + the broader unit suite
(32598 tests) stay green.
@ciampo

ciampo commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

@manzoorwanijk I suggest you look for who would be better suited to review this PR and ping them directly

@manzoorwanijk

Copy link
Copy Markdown
Member Author

@manzoorwanijk I suggest you look for who would be better suited to review this PR and ping them directly

From the history of this area of the code or its reviews, I can see @ellatrix, @Mamaduka, @ntsekouras, @t-hamano, @aduth

@aduth

aduth commented Jun 5, 2026

Copy link
Copy Markdown
Member

I'm happy to give my thumbs-up on the upgrade itself, but I don't personally feel confident enough to weigh in on the semantics of how diffs are reflected in post revisions, which feels like the more impactful change here.

Comment thread packages/editor/src/components/post-revisions-preview/test/block-diff.js Outdated
Comment thread packages/editor/src/components/post-revisions-preview/block-diff.js
Addresses review feedback on #77992: the relaxed invariant-style
assertion was harder to read than the surrounding tests. Revert to the
single `toMatchObject([...])` form, with the parenthetical updated to
reflect that v8's LCS tie-breaker now anchors on the second block
(prev[1] -> curr[0]) instead of the first (prev[0] -> curr[1]). The
rest of the comment is restored verbatim from trunk.

For a pure swap the two LCS choices are equally valid, so a future
`diff` major bump that flips the tie-breaker again would just require
updating this snapshot — no UX regression.
Comment thread packages/editor/src/components/post-revisions-preview/test/block-diff.js Outdated
Comment thread packages/editor/src/components/post-revisions-preview/block-diff.js

@ellatrix ellatrix left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would love to also use matchObject for the other test that was added, makes sense otherwise.

Addresses ellatrix's follow-up review comments on #77992:

- `test/block-diff.js`: Convert the new `'places paired modification at
  current-revision position when only unchanged blocks sit between'`
  test to a single `toMatchObject([...])` snapshot, matching the
  surrounding tests in this file. Also tighten the swap-test comment:
  drop the speculative "future major bump" note and keep just a single
  line acknowledging that pre-v8 LCS picked the other block.
- `block-diff.js`: Reassign the `currentRaw` / `previousRaw`
  parameters in place of introducing renamed `currentBlocks` /
  `previousBlocks` locals — the filtered entries are still raw
  grammar-parser output, just a subset, so dropping the "Raw"
  classifier was misleading. No-param-reassign is not enabled in the
  project's ESLint config.

No logic changes. All 35 block-diff tests + the broader unit suite
stay green.
@manzoorwanijk

Copy link
Copy Markdown
Member Author

Would love to also use matchObject for the other test that was added

Done in 5d8bdec. Thanks

@manzoorwanijk manzoorwanijk enabled auto-merge (squash) June 8, 2026 09:49
@manzoorwanijk manzoorwanijk merged commit c25cea9 into trunk Jun 8, 2026
40 checks passed
@manzoorwanijk manzoorwanijk deleted the upgrade/diff-to-v8 branch June 8, 2026 10:21
@github-actions github-actions Bot added this to the Gutenberg 23.4 milestone Jun 8, 2026
@ramonjd ramonjd added [Type] Code Quality Issues or PRs that relate to code quality and removed [Type] Task Issues or PRs that have been broken down into an individual action to take labels Jun 10, 2026
pento pushed a commit to WordPress/wordpress-develop that referenced this pull request Jun 30, 2026
This updates the pinned commit hash of the Gutenberg repository from `14db4ab9395a9e96430eed678e4288a59eecbd15 ` (version `23.3.0`) to `14db4ab9395a9e96430eed678e4288a59eecbd15` (version `23.4.0`).

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

The following commits are included:
- Hide image dimension tools when a state is selected (WordPress/gutenberg#78670)
- Changed labels to consistently use Patterns in favor of Block patterns (WordPress/gutenberg#56880)
- Fix: Restrict parent page API search to post titles only (WordPress/gutenberg#78683)
- Update AGENTS.md to mention additional pitfalls: (WordPress/gutenberg#78718)
- Docs: Fix big_image_size_threshold xref typo (WordPress/gutenberg#76299)
- Compose: Fully deprecate the 'pure' HoC (WordPress/gutenberg#78674)
- Common CSS: avoid false-positive border-style on custom properties (WordPress/gutenberg#77476)
- Compose: Fix SSR crash in useMediaQuery and useViewportMatch (WordPress/gutenberg#78725)
- CI: Skip plugin repo release when SVN tag already exists (WordPress/gutenberg#78476)
- Dashboard: Hello Dolly (WordPress/gutenberg#78648)
- UI: `Tooltip.Provider` — forward upstream `closeDelay` and `timeout` props (WordPress/gutenberg#78642)
- Compose: Support React 19 ref callback cleanups in `useMergeRefs` (WordPress/gutenberg#78685)
- Add copilot-instructions.md file (WordPress/gutenberg#78584)
- Dashboard: show ghost widgets visually & allow easy removal (WordPress/gutenberg#78502)
- Bump fast-xml-builder from 1.0.0 to 1.2.0 (WordPress/gutenberg#78272)
- Bump actions/stale (WordPress/gutenberg#78745)
- Bump fast-xml-parser from 4.5.0 to 4.5.6 (WordPress/gutenberg#77167)
- Bump actions/github-script from 8.0.0 to 9.0.0 in /.github/workflows (WordPress/gutenberg#78591)
- @wordpress/theme: deduplicate addFallbackToVar helper (WordPress/gutenberg#78666)
- Add Combobox primitives (WordPress/gutenberg#78399)
- Editor: Fix keyboard activation of the template actions preview (WordPress/gutenberg#78641)
- Theme: drop `density` support from `@wordpress/theme` (WordPress/gutenberg#78741)
- Tooltip migration: fields + media-editor + media-fields + global-styles-ui (4/5) (WordPress/gutenberg#78691)
- List View: Expose block visibility label to assistive technology (WordPress/gutenberg#78640)
- Hide paragraph Drop cap control when a state is selected (WordPress/gutenberg#78672)
- Image cropper: round zoom control values and display as percentages (WordPress/gutenberg#78757)
- Media Editor Modal: Try placing the save and cancel buttons in the footer (WordPress/gutenberg#78708)
- Unset grid span defaults with viewport states enabled (WordPress/gutenberg#78709)
- Media Editor: Remove resize handles toggle from crop panel (WordPress/gutenberg#78758)
- Image Editor: focus return after closing image crop modal (WordPress/gutenberg#78711)
- Add dashboard Events widget (WordPress/gutenberg#78553)
- Writing flow: Delete at end of nested list item should merge into next block (WordPress/gutenberg#78742)
- RTC: Re-render collaborators overlay when the block tree changes (WordPress/gutenberg#78636)
- Dashboard: rename `widget-types` to `widget-primitives` and consolidate the widget contract (WordPress/gutenberg#78749)
- Fix Gutenberg plugin assuming its directory is named "gutenberg" (WordPress/gutenberg#78705)
- Codemods: Remove one-shot Tooltip migration codemod (WordPress/gutenberg#78669)
- Dashboard: rename `WidgetChrome` to `DashboardWidgetChrome` (WordPress/gutenberg#78751)
- Paragraph: Strip stale block-support classes from className during align attribute migration (WordPress/gutenberg#78731)
- Global Styles: Fix CSS not applying to Custom CSS textarea in Advanced panel (WordPress/gutenberg#78773)
- scripts: Use require.resolve for SVG loaders to fix pnpm compat (WordPress/gutenberg#78777)
- Post list: Remove close button from Quick Edit drawer (WordPress/gutenberg#78730)
- Revert "Gate client-side media processing as plugin-only (WordPress/gutenberg#76700)" (WordPress/gutenberg#76751)
- Tooltip migration: boot consumers + shell-level Tooltip.Provider (5/5) (WordPress/gutenberg#78692)
- Dashboard: replace `surface` with `host` in widget contract docs (WordPress/gutenberg#78778)
- Shortcode block: Fix editor crash when selecting transform menu (WordPress/gutenberg#78770)
- Make `@wordpress/nux` a no-op compatibility package (WordPress/gutenberg#77773)
- Tests: Temporarily disable REST index output-format assertions (WordPress/gutenberg#78788)
- Hide Cover overlay controls for viewport states (WordPress/gutenberg#78763)
- Fix type of `$block_instance` parameter in `block_core_image_render_lightbox()` (WordPress/gutenberg#78790)
- TypeScript: Migrate server-side-render package to TS (WordPress/gutenberg#71383)
- feat: Migrate performance results to tools release (WordPress/gutenberg#78761)
- wp-build: Fix black flash on wp-admin pages before hydration (WordPress/gutenberg#78493)
- Icons: maintain absolute stroke-width regardless of icon-size (WordPress/gutenberg#78774)
- Dashboard: Use Howdy greeting for page title (WordPress/gutenberg#78740)
- Block Editor: Refactor Inserter to a function component (WordPress/gutenberg#78766)
- Dashboard: Move layout settings to customize toolbar (WordPress/gutenberg#78738)
- Build: update changelog (WordPress/gutenberg#78807)
- Icons: rename timeToRead to time (WordPress/gutenberg#78804)
- RTC: Prevent slower polling filters (WordPress/gutenberg#78811)
- Button.Icon: Fix clipped icons (WordPress/gutenberg#78614)
- Bump docker/login-action (WordPress/gutenberg#78819)
- RTC: Return forbidden rooms together (WordPress/gutenberg#78748)
- Update browserslist (WordPress/gutenberg#78840)
- Try allowing transforms to a variation of another block (WordPress/gutenberg#78713)
- Elements: Guard against non-string className in render filter (WordPress/gutenberg#78841)
- e2e-test-utils-playwright: add src to published NPM files (WordPress/gutenberg#78847)
- Editor: Refactor 'PostPublishButton' into function component (WordPress/gutenberg#78737)
- Dashboard: Promote WidgetRender into widget-primitives (WordPress/gutenberg#78821)
- Notes: Show default avatar in the indicator when user avatars are disabled (WordPress/gutenberg#78849)
- Revert "Icons: maintain absolute stroke-width regardless of icon-size (WordPress/gutenberg#78774)" (WordPress/gutenberg#78854)
- Media: Send Document-Isolation-Policy header on the site preview frame (WordPress/gutenberg#78404)
- Revert navigation morph & playlist commits pushed directly to trunk (WordPress/gutenberg#78857)
- Fix Update button staying active when changes are reverted. (WordPress/gutenberg#78567)
- Docs: Fix and improve documentation (WordPress/gutenberg#78686)
- Abilities: Add validation tests pinning behavior for WP-specific schema keywords (WordPress/gutenberg#78783)
- Tools: migrate docs/tool into tools/docs workspace (WordPress/gutenberg#78870)
- Dashboard: Fix Add widget error on non-secure HTTP origins (WordPress/gutenberg#78850)
- Docs: Fix @wordpress/data README fragment links (WordPress/gutenberg#78866)
- bin: Remove obsolete bin/setup-local-env.sh (WordPress/gutenberg#78871)
- Boot navigation: wrap items in a list role for valid listitem semantics (WordPress/gutenberg#78829)
- wp-build: Document generated page hooks per WordPress standards. (WordPress/gutenberg#78826)
- Update CODEOWNERS for tooling directories (WordPress/gutenberg#78874)
- Block Visibility: Keep hide-everywhere working after a block opts out of visibility support (WordPress/gutenberg#78780)
- Dashboard: Replace grid row height controls with size presets. (WordPress/gutenberg#78735)
- Prevent font-size propagation in Navigation items causing `em` compounding (WordPress/gutenberg#77419)
- Media Editor Modal: Reorder details fields so the editable regular layout fields appear at the top (WordPress/gutenberg#78792)
- Fix media editor sidebar close button label (WordPress/gutenberg#78895)
- Dashboard: event widget iteration (WordPress/gutenberg#78815)
- Playlist Block: Add visualization style selector (WordPress/gutenberg#76147)
- [Content Types]: Fix extra Page padding causing vertical scrollbar (WordPress/gutenberg#78661)
- Remove migrated dependencies from root package.json (WordPress/gutenberg#78813)
- Packages: Declare missing `@types/react` dependency (WordPress/gutenberg#78882)
- Fix collapsed experiment cards not stretching to full width (WordPress/gutenberg#78910)
- Element: add polyfills for render, hydrate, unmountComponentAtNode (WordPress/gutenberg#78899)
- Revert "wp-build: Replace getter-based exports with data properties" (WordPress/gutenberg#78917)
- React: add ReactCurrentOwner polyfill (WordPress/gutenberg#78923)
- Fix playlist metadata edits recreating player (WordPress/gutenberg#78876)
- Media Editor: Fix sidebar overflowing the modal between the small and medium breakpoints (WordPress/gutenberg#78931)
- Media: Move client-side media compat file to wordpress-7.1 directory (WordPress/gutenberg#78852)
- env: Replace extract-zip with adm-zip to fix hang on Node 24.16 (WordPress/gutenberg#78828)
- Media Editor: refactor modal layout (WordPress/gutenberg#78896)
- Optimize wp-env source downloads with Git partial clones (WordPress/gutenberg#78918)
- Fix: Escape URLs in block render functions using `esc_url()` (WordPress/gutenberg#78912)
- Blocks: Allow the Login/out block as an inner block in the Navigation Submenu block (WordPress/gutenberg#75497)
- Fix sprintf format specifiers in post-date and read-more blocks (WordPress/gutenberg#78933)
- Refactor: Remove jest/test deps from root package.json (WordPress/gutenberg#78801)
- Upload Media: Add retry with exponential backoff and network resilience (WordPress/gutenberg#76765)
- Build Scripts: Fix Windows path handling in dev script (WordPress/gutenberg#78939)
- Revert React 19 upgrade (WordPress/gutenberg#78940)
- Fix: block auto-complete for AI API Keys in Connectors (WordPress/gutenberg#78946)
- Dashboard: Opinionated grid columns with container breakpoints (WordPress/gutenberg#78732)
- Skip including inactive or experimental routes when building for WordPress Core (WordPress/gutenberg#76715)
- RTC: Fix Yjs undo manager to update UI state when undo stack changes (WordPress/gutenberg#78864)
- Storybook: Enhance Theme Provider example with admin-ui Page. (WordPress/gutenberg#78814)
- RTC: Fix CRDT deferred updates resulting in jumbled typing (WordPress/gutenberg#78756)
- Add playlist track length setting (WordPress/gutenberg#78954)
- Add aspect ratio control to media editor mobile toolbar (WordPress/gutenberg#78935)
- Media Editor: Replace the zoom slider with +/- buttons (WordPress/gutenberg#78928)
- Use omit-unchanged for compressed-size-action (WordPress/gutenberg#78976)
- DataViewsPicker: Add a new `pickerActivity` layout (WordPress/gutenberg#78941)
- refactor: move babel dependencies to workspace configuration (WordPress/gutenberg#78974)
- feat: Migrate the browserlintrc file to `packages/postcss-plugins-preset` (WordPress/gutenberg#78764)
- Storybook: Declare workspace dependencies for theme example story. (WordPress/gutenberg#78979)
- Refactor: Move React dependencies from root to workspaces (WordPress/gutenberg#78981)
- UI: Update `@base-ui/react` to `1.5.0` (WordPress/gutenberg#78448)
- ui/AlertDialog: Fix footer layout style override (WordPress/gutenberg#78953)
- Font Library: Fix focus issue when navigating (WordPress/gutenberg#78671)
- Docs: Auto-generate per-block API reference pages from block.json (WordPress/gutenberg#77612)
- Patterns: fix focus loss when dismissing Create pattern dialog (WordPress/gutenberg#78957)
- Show media upload progress in a snackbar (WordPress/gutenberg#77249)
- Upload Media: Gate very large images out of client-side processing (WordPress/gutenberg#78949)
- Media: Add UltraHDR (ISO 21496-1) gain map support (WordPress/gutenberg#74873)
- Site Editor: Apply the user's admin color scheme (WordPress/gutenberg#78397)
- Navigation Link: fix duplicate block html attributes in editor (WordPress/gutenberg#78973)
- Added Missing Global Documentation (WordPress/gutenberg#78997)
- Post Revisions: Upgrade `diff` from v4 to v8 (WordPress/gutenberg#77992)
- Theme: Increase stroke1 contrast target to 2.9 (WordPress/gutenberg#77599)
- Tooltip: Use md border radius for portaled popups. (WordPress/gutenberg#78983)
- Framework: Remove invalid stale nested npm package references (WordPress/gutenberg#79014)
- Theme package: Add element size design tokens (WordPress/gutenberg#76545)
- Inserter: use forwardRef for refs (WordPress/gutenberg#79006)
- RTC: Add separate doc persistence endpoint (WordPress/gutenberg#78891)
- DataViews: Add DataViews components to components manifest (WordPress/gutenberg#78960)
- Media Editor: Keep crop handles operable on large images (WordPress/gutenberg#79011)
- Media editor: tweak paddings and margins (WordPress/gutenberg#79009)
- Media Editor: Remove lag when toggling the sidebar (WordPress/gutenberg#79024)
- Elements: Align class name parsing with custom CSS implementation (WordPress/gutenberg#79023)
- CI: Suppress lint:js warnings on static checks (WordPress/gutenberg#79025)
- Remove React Native implementation, framework, and dependencies (WordPress/gutenberg#78747)
- e2e-test-utils-playwright: start transpiling again, but faster (WordPress/gutenberg#79026)
- CI: Remove Validate Gradle Wrapper workflow (WordPress/gutenberg#79030)
- Remove dead native code branches from Platform usages (WordPress/gutenberg#79031)
- Remove orphaned README files for deleted native-only components (WordPress/gutenberg#79035)
- Remove orphaned mobile bug report issue template (WordPress/gutenberg#79038)
- Inserter: Fix error being thrown for spoken message when inserting default/direct block (WordPress/gutenberg#79004)
- Editor: Remove dead native guard in block removal warnings (WordPress/gutenberg#79039)
- Preserve nested list when deleting a selection across sibling list items (WordPress/gutenberg#78776)
- Remove platform-docs Docusaurus site (WordPress/gutenberg#79034)
- Align dependency versions across workspaces (WordPress/gutenberg#77954)
- RichText: Remove dead native-only prop filtering (WordPress/gutenberg#79037)
- Navigable Container: Hoist getFocusableContext out of the component (WordPress/gutenberg#79029)
- Tools: Lint dependency version consistency with Syncpack (WordPress/gutenberg#77950)
- Extract entity view config into a filterable API (WordPress/gutenberg#78977)
- Rich text: use subscribeDelegatedListener for element event listeners (WordPress/gutenberg#79047)
- theme/ThemeProvider: rename `color.bg` prop to `color.background` (WordPress/gutenberg#79007)
- Format Library: Migrate to recommended `@wordpress/ui` components (WordPress/gutenberg#79059)
- Syncpack: ban `classnames` from being reintroduced (WordPress/gutenberg#79061)
- UI: Update CSS cascade layers to use nesting (WordPress/gutenberg#78959)
- Docs: Remove stale mobile references from tooling and primitives docs (WordPress/gutenberg#79041)
- Release: Drop mobile-specific changelog omit rules (WordPress/gutenberg#79042)
- Bump actions/checkout (WordPress/gutenberg#79033)
- `ColorPalette`: don't render when custom colors disabled and no colors passed (WordPress/gutenberg#72402)
- Bump minimatch and lerna (WordPress/gutenberg#76750)
- Image block: don't show crop icon while image is uploading (WordPress/gutenberg#79103)
- Add React 19 as an experimental flag (WordPress/gutenberg#79077)
- Media modal: small tweak to gutters (WordPress/gutenberg#79168)
- Add more React internals polyfills (WordPress/gutenberg#79142)
- Media editor modal: Fix keyboard resizing for locked aspect-ratio crops (WordPress/gutenberg#79207)
- Fix responsive element styles front end output (WordPress/gutenberg#79135) (WordPress/gutenberg#79215)

Props adamsilverstein, jorbin, westonruter, wildworks.
Fixes #65368.

git-svn-id: https://develop.svn.wordpress.org/trunk@62584 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Jun 30, 2026
This updates the pinned commit hash of the Gutenberg repository from `14db4ab9395a9e96430eed678e4288a59eecbd15 ` (version `23.3.0`) to `14db4ab9395a9e96430eed678e4288a59eecbd15` (version `23.4.0`).

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

The following commits are included:
- Hide image dimension tools when a state is selected (WordPress/gutenberg#78670)
- Changed labels to consistently use Patterns in favor of Block patterns (WordPress/gutenberg#56880)
- Fix: Restrict parent page API search to post titles only (WordPress/gutenberg#78683)
- Update AGENTS.md to mention additional pitfalls: (WordPress/gutenberg#78718)
- Docs: Fix big_image_size_threshold xref typo (WordPress/gutenberg#76299)
- Compose: Fully deprecate the 'pure' HoC (WordPress/gutenberg#78674)
- Common CSS: avoid false-positive border-style on custom properties (WordPress/gutenberg#77476)
- Compose: Fix SSR crash in useMediaQuery and useViewportMatch (WordPress/gutenberg#78725)
- CI: Skip plugin repo release when SVN tag already exists (WordPress/gutenberg#78476)
- Dashboard: Hello Dolly (WordPress/gutenberg#78648)
- UI: `Tooltip.Provider` — forward upstream `closeDelay` and `timeout` props (WordPress/gutenberg#78642)
- Compose: Support React 19 ref callback cleanups in `useMergeRefs` (WordPress/gutenberg#78685)
- Add copilot-instructions.md file (WordPress/gutenberg#78584)
- Dashboard: show ghost widgets visually & allow easy removal (WordPress/gutenberg#78502)
- Bump fast-xml-builder from 1.0.0 to 1.2.0 (WordPress/gutenberg#78272)
- Bump actions/stale (WordPress/gutenberg#78745)
- Bump fast-xml-parser from 4.5.0 to 4.5.6 (WordPress/gutenberg#77167)
- Bump actions/github-script from 8.0.0 to 9.0.0 in /.github/workflows (WordPress/gutenberg#78591)
- @wordpress/theme: deduplicate addFallbackToVar helper (WordPress/gutenberg#78666)
- Add Combobox primitives (WordPress/gutenberg#78399)
- Editor: Fix keyboard activation of the template actions preview (WordPress/gutenberg#78641)
- Theme: drop `density` support from `@wordpress/theme` (WordPress/gutenberg#78741)
- Tooltip migration: fields + media-editor + media-fields + global-styles-ui (4/5) (WordPress/gutenberg#78691)
- List View: Expose block visibility label to assistive technology (WordPress/gutenberg#78640)
- Hide paragraph Drop cap control when a state is selected (WordPress/gutenberg#78672)
- Image cropper: round zoom control values and display as percentages (WordPress/gutenberg#78757)
- Media Editor Modal: Try placing the save and cancel buttons in the footer (WordPress/gutenberg#78708)
- Unset grid span defaults with viewport states enabled (WordPress/gutenberg#78709)
- Media Editor: Remove resize handles toggle from crop panel (WordPress/gutenberg#78758)
- Image Editor: focus return after closing image crop modal (WordPress/gutenberg#78711)
- Add dashboard Events widget (WordPress/gutenberg#78553)
- Writing flow: Delete at end of nested list item should merge into next block (WordPress/gutenberg#78742)
- RTC: Re-render collaborators overlay when the block tree changes (WordPress/gutenberg#78636)
- Dashboard: rename `widget-types` to `widget-primitives` and consolidate the widget contract (WordPress/gutenberg#78749)
- Fix Gutenberg plugin assuming its directory is named "gutenberg" (WordPress/gutenberg#78705)
- Codemods: Remove one-shot Tooltip migration codemod (WordPress/gutenberg#78669)
- Dashboard: rename `WidgetChrome` to `DashboardWidgetChrome` (WordPress/gutenberg#78751)
- Paragraph: Strip stale block-support classes from className during align attribute migration (WordPress/gutenberg#78731)
- Global Styles: Fix CSS not applying to Custom CSS textarea in Advanced panel (WordPress/gutenberg#78773)
- scripts: Use require.resolve for SVG loaders to fix pnpm compat (WordPress/gutenberg#78777)
- Post list: Remove close button from Quick Edit drawer (WordPress/gutenberg#78730)
- Revert "Gate client-side media processing as plugin-only (WordPress/gutenberg#76700)" (WordPress/gutenberg#76751)
- Tooltip migration: boot consumers + shell-level Tooltip.Provider (5/5) (WordPress/gutenberg#78692)
- Dashboard: replace `surface` with `host` in widget contract docs (WordPress/gutenberg#78778)
- Shortcode block: Fix editor crash when selecting transform menu (WordPress/gutenberg#78770)
- Make `@wordpress/nux` a no-op compatibility package (WordPress/gutenberg#77773)
- Tests: Temporarily disable REST index output-format assertions (WordPress/gutenberg#78788)
- Hide Cover overlay controls for viewport states (WordPress/gutenberg#78763)
- Fix type of `$block_instance` parameter in `block_core_image_render_lightbox()` (WordPress/gutenberg#78790)
- TypeScript: Migrate server-side-render package to TS (WordPress/gutenberg#71383)
- feat: Migrate performance results to tools release (WordPress/gutenberg#78761)
- wp-build: Fix black flash on wp-admin pages before hydration (WordPress/gutenberg#78493)
- Icons: maintain absolute stroke-width regardless of icon-size (WordPress/gutenberg#78774)
- Dashboard: Use Howdy greeting for page title (WordPress/gutenberg#78740)
- Block Editor: Refactor Inserter to a function component (WordPress/gutenberg#78766)
- Dashboard: Move layout settings to customize toolbar (WordPress/gutenberg#78738)
- Build: update changelog (WordPress/gutenberg#78807)
- Icons: rename timeToRead to time (WordPress/gutenberg#78804)
- RTC: Prevent slower polling filters (WordPress/gutenberg#78811)
- Button.Icon: Fix clipped icons (WordPress/gutenberg#78614)
- Bump docker/login-action (WordPress/gutenberg#78819)
- RTC: Return forbidden rooms together (WordPress/gutenberg#78748)
- Update browserslist (WordPress/gutenberg#78840)
- Try allowing transforms to a variation of another block (WordPress/gutenberg#78713)
- Elements: Guard against non-string className in render filter (WordPress/gutenberg#78841)
- e2e-test-utils-playwright: add src to published NPM files (WordPress/gutenberg#78847)
- Editor: Refactor 'PostPublishButton' into function component (WordPress/gutenberg#78737)
- Dashboard: Promote WidgetRender into widget-primitives (WordPress/gutenberg#78821)
- Notes: Show default avatar in the indicator when user avatars are disabled (WordPress/gutenberg#78849)
- Revert "Icons: maintain absolute stroke-width regardless of icon-size (WordPress/gutenberg#78774)" (WordPress/gutenberg#78854)
- Media: Send Document-Isolation-Policy header on the site preview frame (WordPress/gutenberg#78404)
- Revert navigation morph & playlist commits pushed directly to trunk (WordPress/gutenberg#78857)
- Fix Update button staying active when changes are reverted. (WordPress/gutenberg#78567)
- Docs: Fix and improve documentation (WordPress/gutenberg#78686)
- Abilities: Add validation tests pinning behavior for WP-specific schema keywords (WordPress/gutenberg#78783)
- Tools: migrate docs/tool into tools/docs workspace (WordPress/gutenberg#78870)
- Dashboard: Fix Add widget error on non-secure HTTP origins (WordPress/gutenberg#78850)
- Docs: Fix @wordpress/data README fragment links (WordPress/gutenberg#78866)
- bin: Remove obsolete bin/setup-local-env.sh (WordPress/gutenberg#78871)
- Boot navigation: wrap items in a list role for valid listitem semantics (WordPress/gutenberg#78829)
- wp-build: Document generated page hooks per WordPress standards. (WordPress/gutenberg#78826)
- Update CODEOWNERS for tooling directories (WordPress/gutenberg#78874)
- Block Visibility: Keep hide-everywhere working after a block opts out of visibility support (WordPress/gutenberg#78780)
- Dashboard: Replace grid row height controls with size presets. (WordPress/gutenberg#78735)
- Prevent font-size propagation in Navigation items causing `em` compounding (WordPress/gutenberg#77419)
- Media Editor Modal: Reorder details fields so the editable regular layout fields appear at the top (WordPress/gutenberg#78792)
- Fix media editor sidebar close button label (WordPress/gutenberg#78895)
- Dashboard: event widget iteration (WordPress/gutenberg#78815)
- Playlist Block: Add visualization style selector (WordPress/gutenberg#76147)
- [Content Types]: Fix extra Page padding causing vertical scrollbar (WordPress/gutenberg#78661)
- Remove migrated dependencies from root package.json (WordPress/gutenberg#78813)
- Packages: Declare missing `@types/react` dependency (WordPress/gutenberg#78882)
- Fix collapsed experiment cards not stretching to full width (WordPress/gutenberg#78910)
- Element: add polyfills for render, hydrate, unmountComponentAtNode (WordPress/gutenberg#78899)
- Revert "wp-build: Replace getter-based exports with data properties" (WordPress/gutenberg#78917)
- React: add ReactCurrentOwner polyfill (WordPress/gutenberg#78923)
- Fix playlist metadata edits recreating player (WordPress/gutenberg#78876)
- Media Editor: Fix sidebar overflowing the modal between the small and medium breakpoints (WordPress/gutenberg#78931)
- Media: Move client-side media compat file to wordpress-7.1 directory (WordPress/gutenberg#78852)
- env: Replace extract-zip with adm-zip to fix hang on Node 24.16 (WordPress/gutenberg#78828)
- Media Editor: refactor modal layout (WordPress/gutenberg#78896)
- Optimize wp-env source downloads with Git partial clones (WordPress/gutenberg#78918)
- Fix: Escape URLs in block render functions using `esc_url()` (WordPress/gutenberg#78912)
- Blocks: Allow the Login/out block as an inner block in the Navigation Submenu block (WordPress/gutenberg#75497)
- Fix sprintf format specifiers in post-date and read-more blocks (WordPress/gutenberg#78933)
- Refactor: Remove jest/test deps from root package.json (WordPress/gutenberg#78801)
- Upload Media: Add retry with exponential backoff and network resilience (WordPress/gutenberg#76765)
- Build Scripts: Fix Windows path handling in dev script (WordPress/gutenberg#78939)
- Revert React 19 upgrade (WordPress/gutenberg#78940)
- Fix: block auto-complete for AI API Keys in Connectors (WordPress/gutenberg#78946)
- Dashboard: Opinionated grid columns with container breakpoints (WordPress/gutenberg#78732)
- Skip including inactive or experimental routes when building for WordPress Core (WordPress/gutenberg#76715)
- RTC: Fix Yjs undo manager to update UI state when undo stack changes (WordPress/gutenberg#78864)
- Storybook: Enhance Theme Provider example with admin-ui Page. (WordPress/gutenberg#78814)
- RTC: Fix CRDT deferred updates resulting in jumbled typing (WordPress/gutenberg#78756)
- Add playlist track length setting (WordPress/gutenberg#78954)
- Add aspect ratio control to media editor mobile toolbar (WordPress/gutenberg#78935)
- Media Editor: Replace the zoom slider with +/- buttons (WordPress/gutenberg#78928)
- Use omit-unchanged for compressed-size-action (WordPress/gutenberg#78976)
- DataViewsPicker: Add a new `pickerActivity` layout (WordPress/gutenberg#78941)
- refactor: move babel dependencies to workspace configuration (WordPress/gutenberg#78974)
- feat: Migrate the browserlintrc file to `packages/postcss-plugins-preset` (WordPress/gutenberg#78764)
- Storybook: Declare workspace dependencies for theme example story. (WordPress/gutenberg#78979)
- Refactor: Move React dependencies from root to workspaces (WordPress/gutenberg#78981)
- UI: Update `@base-ui/react` to `1.5.0` (WordPress/gutenberg#78448)
- ui/AlertDialog: Fix footer layout style override (WordPress/gutenberg#78953)
- Font Library: Fix focus issue when navigating (WordPress/gutenberg#78671)
- Docs: Auto-generate per-block API reference pages from block.json (WordPress/gutenberg#77612)
- Patterns: fix focus loss when dismissing Create pattern dialog (WordPress/gutenberg#78957)
- Show media upload progress in a snackbar (WordPress/gutenberg#77249)
- Upload Media: Gate very large images out of client-side processing (WordPress/gutenberg#78949)
- Media: Add UltraHDR (ISO 21496-1) gain map support (WordPress/gutenberg#74873)
- Site Editor: Apply the user's admin color scheme (WordPress/gutenberg#78397)
- Navigation Link: fix duplicate block html attributes in editor (WordPress/gutenberg#78973)
- Added Missing Global Documentation (WordPress/gutenberg#78997)
- Post Revisions: Upgrade `diff` from v4 to v8 (WordPress/gutenberg#77992)
- Theme: Increase stroke1 contrast target to 2.9 (WordPress/gutenberg#77599)
- Tooltip: Use md border radius for portaled popups. (WordPress/gutenberg#78983)
- Framework: Remove invalid stale nested npm package references (WordPress/gutenberg#79014)
- Theme package: Add element size design tokens (WordPress/gutenberg#76545)
- Inserter: use forwardRef for refs (WordPress/gutenberg#79006)
- RTC: Add separate doc persistence endpoint (WordPress/gutenberg#78891)
- DataViews: Add DataViews components to components manifest (WordPress/gutenberg#78960)
- Media Editor: Keep crop handles operable on large images (WordPress/gutenberg#79011)
- Media editor: tweak paddings and margins (WordPress/gutenberg#79009)
- Media Editor: Remove lag when toggling the sidebar (WordPress/gutenberg#79024)
- Elements: Align class name parsing with custom CSS implementation (WordPress/gutenberg#79023)
- CI: Suppress lint:js warnings on static checks (WordPress/gutenberg#79025)
- Remove React Native implementation, framework, and dependencies (WordPress/gutenberg#78747)
- e2e-test-utils-playwright: start transpiling again, but faster (WordPress/gutenberg#79026)
- CI: Remove Validate Gradle Wrapper workflow (WordPress/gutenberg#79030)
- Remove dead native code branches from Platform usages (WordPress/gutenberg#79031)
- Remove orphaned README files for deleted native-only components (WordPress/gutenberg#79035)
- Remove orphaned mobile bug report issue template (WordPress/gutenberg#79038)
- Inserter: Fix error being thrown for spoken message when inserting default/direct block (WordPress/gutenberg#79004)
- Editor: Remove dead native guard in block removal warnings (WordPress/gutenberg#79039)
- Preserve nested list when deleting a selection across sibling list items (WordPress/gutenberg#78776)
- Remove platform-docs Docusaurus site (WordPress/gutenberg#79034)
- Align dependency versions across workspaces (WordPress/gutenberg#77954)
- RichText: Remove dead native-only prop filtering (WordPress/gutenberg#79037)
- Navigable Container: Hoist getFocusableContext out of the component (WordPress/gutenberg#79029)
- Tools: Lint dependency version consistency with Syncpack (WordPress/gutenberg#77950)
- Extract entity view config into a filterable API (WordPress/gutenberg#78977)
- Rich text: use subscribeDelegatedListener for element event listeners (WordPress/gutenberg#79047)
- theme/ThemeProvider: rename `color.bg` prop to `color.background` (WordPress/gutenberg#79007)
- Format Library: Migrate to recommended `@wordpress/ui` components (WordPress/gutenberg#79059)
- Syncpack: ban `classnames` from being reintroduced (WordPress/gutenberg#79061)
- UI: Update CSS cascade layers to use nesting (WordPress/gutenberg#78959)
- Docs: Remove stale mobile references from tooling and primitives docs (WordPress/gutenberg#79041)
- Release: Drop mobile-specific changelog omit rules (WordPress/gutenberg#79042)
- Bump actions/checkout (WordPress/gutenberg#79033)
- `ColorPalette`: don't render when custom colors disabled and no colors passed (WordPress/gutenberg#72402)
- Bump minimatch and lerna (WordPress/gutenberg#76750)
- Image block: don't show crop icon while image is uploading (WordPress/gutenberg#79103)
- Add React 19 as an experimental flag (WordPress/gutenberg#79077)
- Media modal: small tweak to gutters (WordPress/gutenberg#79168)
- Add more React internals polyfills (WordPress/gutenberg#79142)
- Media editor modal: Fix keyboard resizing for locked aspect-ratio crops (WordPress/gutenberg#79207)
- Fix responsive element styles front end output (WordPress/gutenberg#79135) (WordPress/gutenberg#79215)

Props adamsilverstein, jorbin, westonruter, wildworks.
Fixes #65368.
Built from https://develop.svn.wordpress.org/trunk@62584


git-svn-id: http://core.svn.wordpress.org/trunk@61864 1a063a9b-81f0-0310-95a4-ce76da25c4cd
KhushalSainS pushed a commit to KhushalSainS/wordpress-develop that referenced this pull request Jul 1, 2026
This updates the pinned commit hash of the Gutenberg repository from `14db4ab9395a9e96430eed678e4288a59eecbd15 ` (version `23.3.0`) to `14db4ab9395a9e96430eed678e4288a59eecbd15` (version `23.4.0`).

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

The following commits are included:
- Hide image dimension tools when a state is selected (WordPress/gutenberg#78670)
- Changed labels to consistently use Patterns in favor of Block patterns (WordPress/gutenberg#56880)
- Fix: Restrict parent page API search to post titles only (WordPress/gutenberg#78683)
- Update AGENTS.md to mention additional pitfalls: (WordPress/gutenberg#78718)
- Docs: Fix big_image_size_threshold xref typo (WordPress/gutenberg#76299)
- Compose: Fully deprecate the 'pure' HoC (WordPress/gutenberg#78674)
- Common CSS: avoid false-positive border-style on custom properties (WordPress/gutenberg#77476)
- Compose: Fix SSR crash in useMediaQuery and useViewportMatch (WordPress/gutenberg#78725)
- CI: Skip plugin repo release when SVN tag already exists (WordPress/gutenberg#78476)
- Dashboard: Hello Dolly (WordPress/gutenberg#78648)
- UI: `Tooltip.Provider` — forward upstream `closeDelay` and `timeout` props (WordPress/gutenberg#78642)
- Compose: Support React 19 ref callback cleanups in `useMergeRefs` (WordPress/gutenberg#78685)
- Add copilot-instructions.md file (WordPress/gutenberg#78584)
- Dashboard: show ghost widgets visually & allow easy removal (WordPress/gutenberg#78502)
- Bump fast-xml-builder from 1.0.0 to 1.2.0 (WordPress/gutenberg#78272)
- Bump actions/stale (WordPress/gutenberg#78745)
- Bump fast-xml-parser from 4.5.0 to 4.5.6 (WordPress/gutenberg#77167)
- Bump actions/github-script from 8.0.0 to 9.0.0 in /.github/workflows (WordPress/gutenberg#78591)
- @wordpress/theme: deduplicate addFallbackToVar helper (WordPress/gutenberg#78666)
- Add Combobox primitives (WordPress/gutenberg#78399)
- Editor: Fix keyboard activation of the template actions preview (WordPress/gutenberg#78641)
- Theme: drop `density` support from `@wordpress/theme` (WordPress/gutenberg#78741)
- Tooltip migration: fields + media-editor + media-fields + global-styles-ui (4/5) (WordPress/gutenberg#78691)
- List View: Expose block visibility label to assistive technology (WordPress/gutenberg#78640)
- Hide paragraph Drop cap control when a state is selected (WordPress/gutenberg#78672)
- Image cropper: round zoom control values and display as percentages (WordPress/gutenberg#78757)
- Media Editor Modal: Try placing the save and cancel buttons in the footer (WordPress/gutenberg#78708)
- Unset grid span defaults with viewport states enabled (WordPress/gutenberg#78709)
- Media Editor: Remove resize handles toggle from crop panel (WordPress/gutenberg#78758)
- Image Editor: focus return after closing image crop modal (WordPress/gutenberg#78711)
- Add dashboard Events widget (WordPress/gutenberg#78553)
- Writing flow: Delete at end of nested list item should merge into next block (WordPress/gutenberg#78742)
- RTC: Re-render collaborators overlay when the block tree changes (WordPress/gutenberg#78636)
- Dashboard: rename `widget-types` to `widget-primitives` and consolidate the widget contract (WordPress/gutenberg#78749)
- Fix Gutenberg plugin assuming its directory is named "gutenberg" (WordPress/gutenberg#78705)
- Codemods: Remove one-shot Tooltip migration codemod (WordPress/gutenberg#78669)
- Dashboard: rename `WidgetChrome` to `DashboardWidgetChrome` (WordPress/gutenberg#78751)
- Paragraph: Strip stale block-support classes from className during align attribute migration (WordPress/gutenberg#78731)
- Global Styles: Fix CSS not applying to Custom CSS textarea in Advanced panel (WordPress/gutenberg#78773)
- scripts: Use require.resolve for SVG loaders to fix pnpm compat (WordPress/gutenberg#78777)
- Post list: Remove close button from Quick Edit drawer (WordPress/gutenberg#78730)
- Revert "Gate client-side media processing as plugin-only (WordPress/gutenberg#76700)" (WordPress/gutenberg#76751)
- Tooltip migration: boot consumers + shell-level Tooltip.Provider (5/5) (WordPress/gutenberg#78692)
- Dashboard: replace `surface` with `host` in widget contract docs (WordPress/gutenberg#78778)
- Shortcode block: Fix editor crash when selecting transform menu (WordPress/gutenberg#78770)
- Make `@wordpress/nux` a no-op compatibility package (WordPress/gutenberg#77773)
- Tests: Temporarily disable REST index output-format assertions (WordPress/gutenberg#78788)
- Hide Cover overlay controls for viewport states (WordPress/gutenberg#78763)
- Fix type of `$block_instance` parameter in `block_core_image_render_lightbox()` (WordPress/gutenberg#78790)
- TypeScript: Migrate server-side-render package to TS (WordPress/gutenberg#71383)
- feat: Migrate performance results to tools release (WordPress/gutenberg#78761)
- wp-build: Fix black flash on wp-admin pages before hydration (WordPress/gutenberg#78493)
- Icons: maintain absolute stroke-width regardless of icon-size (WordPress/gutenberg#78774)
- Dashboard: Use Howdy greeting for page title (WordPress/gutenberg#78740)
- Block Editor: Refactor Inserter to a function component (WordPress/gutenberg#78766)
- Dashboard: Move layout settings to customize toolbar (WordPress/gutenberg#78738)
- Build: update changelog (WordPress/gutenberg#78807)
- Icons: rename timeToRead to time (WordPress/gutenberg#78804)
- RTC: Prevent slower polling filters (WordPress/gutenberg#78811)
- Button.Icon: Fix clipped icons (WordPress/gutenberg#78614)
- Bump docker/login-action (WordPress/gutenberg#78819)
- RTC: Return forbidden rooms together (WordPress/gutenberg#78748)
- Update browserslist (WordPress/gutenberg#78840)
- Try allowing transforms to a variation of another block (WordPress/gutenberg#78713)
- Elements: Guard against non-string className in render filter (WordPress/gutenberg#78841)
- e2e-test-utils-playwright: add src to published NPM files (WordPress/gutenberg#78847)
- Editor: Refactor 'PostPublishButton' into function component (WordPress/gutenberg#78737)
- Dashboard: Promote WidgetRender into widget-primitives (WordPress/gutenberg#78821)
- Notes: Show default avatar in the indicator when user avatars are disabled (WordPress/gutenberg#78849)
- Revert "Icons: maintain absolute stroke-width regardless of icon-size (WordPress/gutenberg#78774)" (WordPress/gutenberg#78854)
- Media: Send Document-Isolation-Policy header on the site preview frame (WordPress/gutenberg#78404)
- Revert navigation morph & playlist commits pushed directly to trunk (WordPress/gutenberg#78857)
- Fix Update button staying active when changes are reverted. (WordPress/gutenberg#78567)
- Docs: Fix and improve documentation (WordPress/gutenberg#78686)
- Abilities: Add validation tests pinning behavior for WP-specific schema keywords (WordPress/gutenberg#78783)
- Tools: migrate docs/tool into tools/docs workspace (WordPress/gutenberg#78870)
- Dashboard: Fix Add widget error on non-secure HTTP origins (WordPress/gutenberg#78850)
- Docs: Fix @wordpress/data README fragment links (WordPress/gutenberg#78866)
- bin: Remove obsolete bin/setup-local-env.sh (WordPress/gutenberg#78871)
- Boot navigation: wrap items in a list role for valid listitem semantics (WordPress/gutenberg#78829)
- wp-build: Document generated page hooks per WordPress standards. (WordPress/gutenberg#78826)
- Update CODEOWNERS for tooling directories (WordPress/gutenberg#78874)
- Block Visibility: Keep hide-everywhere working after a block opts out of visibility support (WordPress/gutenberg#78780)
- Dashboard: Replace grid row height controls with size presets. (WordPress/gutenberg#78735)
- Prevent font-size propagation in Navigation items causing `em` compounding (WordPress/gutenberg#77419)
- Media Editor Modal: Reorder details fields so the editable regular layout fields appear at the top (WordPress/gutenberg#78792)
- Fix media editor sidebar close button label (WordPress/gutenberg#78895)
- Dashboard: event widget iteration (WordPress/gutenberg#78815)
- Playlist Block: Add visualization style selector (WordPress/gutenberg#76147)
- [Content Types]: Fix extra Page padding causing vertical scrollbar (WordPress/gutenberg#78661)
- Remove migrated dependencies from root package.json (WordPress/gutenberg#78813)
- Packages: Declare missing `@types/react` dependency (WordPress/gutenberg#78882)
- Fix collapsed experiment cards not stretching to full width (WordPress/gutenberg#78910)
- Element: add polyfills for render, hydrate, unmountComponentAtNode (WordPress/gutenberg#78899)
- Revert "wp-build: Replace getter-based exports with data properties" (WordPress/gutenberg#78917)
- React: add ReactCurrentOwner polyfill (WordPress/gutenberg#78923)
- Fix playlist metadata edits recreating player (WordPress/gutenberg#78876)
- Media Editor: Fix sidebar overflowing the modal between the small and medium breakpoints (WordPress/gutenberg#78931)
- Media: Move client-side media compat file to wordpress-7.1 directory (WordPress/gutenberg#78852)
- env: Replace extract-zip with adm-zip to fix hang on Node 24.16 (WordPress/gutenberg#78828)
- Media Editor: refactor modal layout (WordPress/gutenberg#78896)
- Optimize wp-env source downloads with Git partial clones (WordPress/gutenberg#78918)
- Fix: Escape URLs in block render functions using `esc_url()` (WordPress/gutenberg#78912)
- Blocks: Allow the Login/out block as an inner block in the Navigation Submenu block (WordPress/gutenberg#75497)
- Fix sprintf format specifiers in post-date and read-more blocks (WordPress/gutenberg#78933)
- Refactor: Remove jest/test deps from root package.json (WordPress/gutenberg#78801)
- Upload Media: Add retry with exponential backoff and network resilience (WordPress/gutenberg#76765)
- Build Scripts: Fix Windows path handling in dev script (WordPress/gutenberg#78939)
- Revert React 19 upgrade (WordPress/gutenberg#78940)
- Fix: block auto-complete for AI API Keys in Connectors (WordPress/gutenberg#78946)
- Dashboard: Opinionated grid columns with container breakpoints (WordPress/gutenberg#78732)
- Skip including inactive or experimental routes when building for WordPress Core (WordPress/gutenberg#76715)
- RTC: Fix Yjs undo manager to update UI state when undo stack changes (WordPress/gutenberg#78864)
- Storybook: Enhance Theme Provider example with admin-ui Page. (WordPress/gutenberg#78814)
- RTC: Fix CRDT deferred updates resulting in jumbled typing (WordPress/gutenberg#78756)
- Add playlist track length setting (WordPress/gutenberg#78954)
- Add aspect ratio control to media editor mobile toolbar (WordPress/gutenberg#78935)
- Media Editor: Replace the zoom slider with +/- buttons (WordPress/gutenberg#78928)
- Use omit-unchanged for compressed-size-action (WordPress/gutenberg#78976)
- DataViewsPicker: Add a new `pickerActivity` layout (WordPress/gutenberg#78941)
- refactor: move babel dependencies to workspace configuration (WordPress/gutenberg#78974)
- feat: Migrate the browserlintrc file to `packages/postcss-plugins-preset` (WordPress/gutenberg#78764)
- Storybook: Declare workspace dependencies for theme example story. (WordPress/gutenberg#78979)
- Refactor: Move React dependencies from root to workspaces (WordPress/gutenberg#78981)
- UI: Update `@base-ui/react` to `1.5.0` (WordPress/gutenberg#78448)
- ui/AlertDialog: Fix footer layout style override (WordPress/gutenberg#78953)
- Font Library: Fix focus issue when navigating (WordPress/gutenberg#78671)
- Docs: Auto-generate per-block API reference pages from block.json (WordPress/gutenberg#77612)
- Patterns: fix focus loss when dismissing Create pattern dialog (WordPress/gutenberg#78957)
- Show media upload progress in a snackbar (WordPress/gutenberg#77249)
- Upload Media: Gate very large images out of client-side processing (WordPress/gutenberg#78949)
- Media: Add UltraHDR (ISO 21496-1) gain map support (WordPress/gutenberg#74873)
- Site Editor: Apply the user's admin color scheme (WordPress/gutenberg#78397)
- Navigation Link: fix duplicate block html attributes in editor (WordPress/gutenberg#78973)
- Added Missing Global Documentation (WordPress/gutenberg#78997)
- Post Revisions: Upgrade `diff` from v4 to v8 (WordPress/gutenberg#77992)
- Theme: Increase stroke1 contrast target to 2.9 (WordPress/gutenberg#77599)
- Tooltip: Use md border radius for portaled popups. (WordPress/gutenberg#78983)
- Framework: Remove invalid stale nested npm package references (WordPress/gutenberg#79014)
- Theme package: Add element size design tokens (WordPress/gutenberg#76545)
- Inserter: use forwardRef for refs (WordPress/gutenberg#79006)
- RTC: Add separate doc persistence endpoint (WordPress/gutenberg#78891)
- DataViews: Add DataViews components to components manifest (WordPress/gutenberg#78960)
- Media Editor: Keep crop handles operable on large images (WordPress/gutenberg#79011)
- Media editor: tweak paddings and margins (WordPress/gutenberg#79009)
- Media Editor: Remove lag when toggling the sidebar (WordPress/gutenberg#79024)
- Elements: Align class name parsing with custom CSS implementation (WordPress/gutenberg#79023)
- CI: Suppress lint:js warnings on static checks (WordPress/gutenberg#79025)
- Remove React Native implementation, framework, and dependencies (WordPress/gutenberg#78747)
- e2e-test-utils-playwright: start transpiling again, but faster (WordPress/gutenberg#79026)
- CI: Remove Validate Gradle Wrapper workflow (WordPress/gutenberg#79030)
- Remove dead native code branches from Platform usages (WordPress/gutenberg#79031)
- Remove orphaned README files for deleted native-only components (WordPress/gutenberg#79035)
- Remove orphaned mobile bug report issue template (WordPress/gutenberg#79038)
- Inserter: Fix error being thrown for spoken message when inserting default/direct block (WordPress/gutenberg#79004)
- Editor: Remove dead native guard in block removal warnings (WordPress/gutenberg#79039)
- Preserve nested list when deleting a selection across sibling list items (WordPress/gutenberg#78776)
- Remove platform-docs Docusaurus site (WordPress/gutenberg#79034)
- Align dependency versions across workspaces (WordPress/gutenberg#77954)
- RichText: Remove dead native-only prop filtering (WordPress/gutenberg#79037)
- Navigable Container: Hoist getFocusableContext out of the component (WordPress/gutenberg#79029)
- Tools: Lint dependency version consistency with Syncpack (WordPress/gutenberg#77950)
- Extract entity view config into a filterable API (WordPress/gutenberg#78977)
- Rich text: use subscribeDelegatedListener for element event listeners (WordPress/gutenberg#79047)
- theme/ThemeProvider: rename `color.bg` prop to `color.background` (WordPress/gutenberg#79007)
- Format Library: Migrate to recommended `@wordpress/ui` components (WordPress/gutenberg#79059)
- Syncpack: ban `classnames` from being reintroduced (WordPress/gutenberg#79061)
- UI: Update CSS cascade layers to use nesting (WordPress/gutenberg#78959)
- Docs: Remove stale mobile references from tooling and primitives docs (WordPress/gutenberg#79041)
- Release: Drop mobile-specific changelog omit rules (WordPress/gutenberg#79042)
- Bump actions/checkout (WordPress/gutenberg#79033)
- `ColorPalette`: don't render when custom colors disabled and no colors passed (WordPress/gutenberg#72402)
- Bump minimatch and lerna (WordPress/gutenberg#76750)
- Image block: don't show crop icon while image is uploading (WordPress/gutenberg#79103)
- Add React 19 as an experimental flag (WordPress/gutenberg#79077)
- Media modal: small tweak to gutters (WordPress/gutenberg#79168)
- Add more React internals polyfills (WordPress/gutenberg#79142)
- Media editor modal: Fix keyboard resizing for locked aspect-ratio crops (WordPress/gutenberg#79207)
- Fix responsive element styles front end output (WordPress/gutenberg#79135) (WordPress/gutenberg#79215)

Props adamsilverstein, jorbin, westonruter, wildworks.
Fixes #65368.

git-svn-id: https://develop.svn.wordpress.org/trunk@62584 602fd350-edb4-49c9-b593-d223f7449a82
SteelWagstaff pushed a commit to SteelWagstaff/wordpress-develop that referenced this pull request Jul 2, 2026
This updates the pinned commit hash of the Gutenberg repository from `14db4ab9395a9e96430eed678e4288a59eecbd15 ` (version `23.3.0`) to `14db4ab9395a9e96430eed678e4288a59eecbd15` (version `23.4.0`).

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

The following commits are included:
- Hide image dimension tools when a state is selected (WordPress/gutenberg#78670)
- Changed labels to consistently use Patterns in favor of Block patterns (WordPress/gutenberg#56880)
- Fix: Restrict parent page API search to post titles only (WordPress/gutenberg#78683)
- Update AGENTS.md to mention additional pitfalls: (WordPress/gutenberg#78718)
- Docs: Fix big_image_size_threshold xref typo (WordPress/gutenberg#76299)
- Compose: Fully deprecate the 'pure' HoC (WordPress/gutenberg#78674)
- Common CSS: avoid false-positive border-style on custom properties (WordPress/gutenberg#77476)
- Compose: Fix SSR crash in useMediaQuery and useViewportMatch (WordPress/gutenberg#78725)
- CI: Skip plugin repo release when SVN tag already exists (WordPress/gutenberg#78476)
- Dashboard: Hello Dolly (WordPress/gutenberg#78648)
- UI: `Tooltip.Provider` — forward upstream `closeDelay` and `timeout` props (WordPress/gutenberg#78642)
- Compose: Support React 19 ref callback cleanups in `useMergeRefs` (WordPress/gutenberg#78685)
- Add copilot-instructions.md file (WordPress/gutenberg#78584)
- Dashboard: show ghost widgets visually & allow easy removal (WordPress/gutenberg#78502)
- Bump fast-xml-builder from 1.0.0 to 1.2.0 (WordPress/gutenberg#78272)
- Bump actions/stale (WordPress/gutenberg#78745)
- Bump fast-xml-parser from 4.5.0 to 4.5.6 (WordPress/gutenberg#77167)
- Bump actions/github-script from 8.0.0 to 9.0.0 in /.github/workflows (WordPress/gutenberg#78591)
- @wordpress/theme: deduplicate addFallbackToVar helper (WordPress/gutenberg#78666)
- Add Combobox primitives (WordPress/gutenberg#78399)
- Editor: Fix keyboard activation of the template actions preview (WordPress/gutenberg#78641)
- Theme: drop `density` support from `@wordpress/theme` (WordPress/gutenberg#78741)
- Tooltip migration: fields + media-editor + media-fields + global-styles-ui (4/5) (WordPress/gutenberg#78691)
- List View: Expose block visibility label to assistive technology (WordPress/gutenberg#78640)
- Hide paragraph Drop cap control when a state is selected (WordPress/gutenberg#78672)
- Image cropper: round zoom control values and display as percentages (WordPress/gutenberg#78757)
- Media Editor Modal: Try placing the save and cancel buttons in the footer (WordPress/gutenberg#78708)
- Unset grid span defaults with viewport states enabled (WordPress/gutenberg#78709)
- Media Editor: Remove resize handles toggle from crop panel (WordPress/gutenberg#78758)
- Image Editor: focus return after closing image crop modal (WordPress/gutenberg#78711)
- Add dashboard Events widget (WordPress/gutenberg#78553)
- Writing flow: Delete at end of nested list item should merge into next block (WordPress/gutenberg#78742)
- RTC: Re-render collaborators overlay when the block tree changes (WordPress/gutenberg#78636)
- Dashboard: rename `widget-types` to `widget-primitives` and consolidate the widget contract (WordPress/gutenberg#78749)
- Fix Gutenberg plugin assuming its directory is named "gutenberg" (WordPress/gutenberg#78705)
- Codemods: Remove one-shot Tooltip migration codemod (WordPress/gutenberg#78669)
- Dashboard: rename `WidgetChrome` to `DashboardWidgetChrome` (WordPress/gutenberg#78751)
- Paragraph: Strip stale block-support classes from className during align attribute migration (WordPress/gutenberg#78731)
- Global Styles: Fix CSS not applying to Custom CSS textarea in Advanced panel (WordPress/gutenberg#78773)
- scripts: Use require.resolve for SVG loaders to fix pnpm compat (WordPress/gutenberg#78777)
- Post list: Remove close button from Quick Edit drawer (WordPress/gutenberg#78730)
- Revert "Gate client-side media processing as plugin-only (WordPress/gutenberg#76700)" (WordPress/gutenberg#76751)
- Tooltip migration: boot consumers + shell-level Tooltip.Provider (5/5) (WordPress/gutenberg#78692)
- Dashboard: replace `surface` with `host` in widget contract docs (WordPress/gutenberg#78778)
- Shortcode block: Fix editor crash when selecting transform menu (WordPress/gutenberg#78770)
- Make `@wordpress/nux` a no-op compatibility package (WordPress/gutenberg#77773)
- Tests: Temporarily disable REST index output-format assertions (WordPress/gutenberg#78788)
- Hide Cover overlay controls for viewport states (WordPress/gutenberg#78763)
- Fix type of `$block_instance` parameter in `block_core_image_render_lightbox()` (WordPress/gutenberg#78790)
- TypeScript: Migrate server-side-render package to TS (WordPress/gutenberg#71383)
- feat: Migrate performance results to tools release (WordPress/gutenberg#78761)
- wp-build: Fix black flash on wp-admin pages before hydration (WordPress/gutenberg#78493)
- Icons: maintain absolute stroke-width regardless of icon-size (WordPress/gutenberg#78774)
- Dashboard: Use Howdy greeting for page title (WordPress/gutenberg#78740)
- Block Editor: Refactor Inserter to a function component (WordPress/gutenberg#78766)
- Dashboard: Move layout settings to customize toolbar (WordPress/gutenberg#78738)
- Build: update changelog (WordPress/gutenberg#78807)
- Icons: rename timeToRead to time (WordPress/gutenberg#78804)
- RTC: Prevent slower polling filters (WordPress/gutenberg#78811)
- Button.Icon: Fix clipped icons (WordPress/gutenberg#78614)
- Bump docker/login-action (WordPress/gutenberg#78819)
- RTC: Return forbidden rooms together (WordPress/gutenberg#78748)
- Update browserslist (WordPress/gutenberg#78840)
- Try allowing transforms to a variation of another block (WordPress/gutenberg#78713)
- Elements: Guard against non-string className in render filter (WordPress/gutenberg#78841)
- e2e-test-utils-playwright: add src to published NPM files (WordPress/gutenberg#78847)
- Editor: Refactor 'PostPublishButton' into function component (WordPress/gutenberg#78737)
- Dashboard: Promote WidgetRender into widget-primitives (WordPress/gutenberg#78821)
- Notes: Show default avatar in the indicator when user avatars are disabled (WordPress/gutenberg#78849)
- Revert "Icons: maintain absolute stroke-width regardless of icon-size (WordPress/gutenberg#78774)" (WordPress/gutenberg#78854)
- Media: Send Document-Isolation-Policy header on the site preview frame (WordPress/gutenberg#78404)
- Revert navigation morph & playlist commits pushed directly to trunk (WordPress/gutenberg#78857)
- Fix Update button staying active when changes are reverted. (WordPress/gutenberg#78567)
- Docs: Fix and improve documentation (WordPress/gutenberg#78686)
- Abilities: Add validation tests pinning behavior for WP-specific schema keywords (WordPress/gutenberg#78783)
- Tools: migrate docs/tool into tools/docs workspace (WordPress/gutenberg#78870)
- Dashboard: Fix Add widget error on non-secure HTTP origins (WordPress/gutenberg#78850)
- Docs: Fix @wordpress/data README fragment links (WordPress/gutenberg#78866)
- bin: Remove obsolete bin/setup-local-env.sh (WordPress/gutenberg#78871)
- Boot navigation: wrap items in a list role for valid listitem semantics (WordPress/gutenberg#78829)
- wp-build: Document generated page hooks per WordPress standards. (WordPress/gutenberg#78826)
- Update CODEOWNERS for tooling directories (WordPress/gutenberg#78874)
- Block Visibility: Keep hide-everywhere working after a block opts out of visibility support (WordPress/gutenberg#78780)
- Dashboard: Replace grid row height controls with size presets. (WordPress/gutenberg#78735)
- Prevent font-size propagation in Navigation items causing `em` compounding (WordPress/gutenberg#77419)
- Media Editor Modal: Reorder details fields so the editable regular layout fields appear at the top (WordPress/gutenberg#78792)
- Fix media editor sidebar close button label (WordPress/gutenberg#78895)
- Dashboard: event widget iteration (WordPress/gutenberg#78815)
- Playlist Block: Add visualization style selector (WordPress/gutenberg#76147)
- [Content Types]: Fix extra Page padding causing vertical scrollbar (WordPress/gutenberg#78661)
- Remove migrated dependencies from root package.json (WordPress/gutenberg#78813)
- Packages: Declare missing `@types/react` dependency (WordPress/gutenberg#78882)
- Fix collapsed experiment cards not stretching to full width (WordPress/gutenberg#78910)
- Element: add polyfills for render, hydrate, unmountComponentAtNode (WordPress/gutenberg#78899)
- Revert "wp-build: Replace getter-based exports with data properties" (WordPress/gutenberg#78917)
- React: add ReactCurrentOwner polyfill (WordPress/gutenberg#78923)
- Fix playlist metadata edits recreating player (WordPress/gutenberg#78876)
- Media Editor: Fix sidebar overflowing the modal between the small and medium breakpoints (WordPress/gutenberg#78931)
- Media: Move client-side media compat file to wordpress-7.1 directory (WordPress/gutenberg#78852)
- env: Replace extract-zip with adm-zip to fix hang on Node 24.16 (WordPress/gutenberg#78828)
- Media Editor: refactor modal layout (WordPress/gutenberg#78896)
- Optimize wp-env source downloads with Git partial clones (WordPress/gutenberg#78918)
- Fix: Escape URLs in block render functions using `esc_url()` (WordPress/gutenberg#78912)
- Blocks: Allow the Login/out block as an inner block in the Navigation Submenu block (WordPress/gutenberg#75497)
- Fix sprintf format specifiers in post-date and read-more blocks (WordPress/gutenberg#78933)
- Refactor: Remove jest/test deps from root package.json (WordPress/gutenberg#78801)
- Upload Media: Add retry with exponential backoff and network resilience (WordPress/gutenberg#76765)
- Build Scripts: Fix Windows path handling in dev script (WordPress/gutenberg#78939)
- Revert React 19 upgrade (WordPress/gutenberg#78940)
- Fix: block auto-complete for AI API Keys in Connectors (WordPress/gutenberg#78946)
- Dashboard: Opinionated grid columns with container breakpoints (WordPress/gutenberg#78732)
- Skip including inactive or experimental routes when building for WordPress Core (WordPress/gutenberg#76715)
- RTC: Fix Yjs undo manager to update UI state when undo stack changes (WordPress/gutenberg#78864)
- Storybook: Enhance Theme Provider example with admin-ui Page. (WordPress/gutenberg#78814)
- RTC: Fix CRDT deferred updates resulting in jumbled typing (WordPress/gutenberg#78756)
- Add playlist track length setting (WordPress/gutenberg#78954)
- Add aspect ratio control to media editor mobile toolbar (WordPress/gutenberg#78935)
- Media Editor: Replace the zoom slider with +/- buttons (WordPress/gutenberg#78928)
- Use omit-unchanged for compressed-size-action (WordPress/gutenberg#78976)
- DataViewsPicker: Add a new `pickerActivity` layout (WordPress/gutenberg#78941)
- refactor: move babel dependencies to workspace configuration (WordPress/gutenberg#78974)
- feat: Migrate the browserlintrc file to `packages/postcss-plugins-preset` (WordPress/gutenberg#78764)
- Storybook: Declare workspace dependencies for theme example story. (WordPress/gutenberg#78979)
- Refactor: Move React dependencies from root to workspaces (WordPress/gutenberg#78981)
- UI: Update `@base-ui/react` to `1.5.0` (WordPress/gutenberg#78448)
- ui/AlertDialog: Fix footer layout style override (WordPress/gutenberg#78953)
- Font Library: Fix focus issue when navigating (WordPress/gutenberg#78671)
- Docs: Auto-generate per-block API reference pages from block.json (WordPress/gutenberg#77612)
- Patterns: fix focus loss when dismissing Create pattern dialog (WordPress/gutenberg#78957)
- Show media upload progress in a snackbar (WordPress/gutenberg#77249)
- Upload Media: Gate very large images out of client-side processing (WordPress/gutenberg#78949)
- Media: Add UltraHDR (ISO 21496-1) gain map support (WordPress/gutenberg#74873)
- Site Editor: Apply the user's admin color scheme (WordPress/gutenberg#78397)
- Navigation Link: fix duplicate block html attributes in editor (WordPress/gutenberg#78973)
- Added Missing Global Documentation (WordPress/gutenberg#78997)
- Post Revisions: Upgrade `diff` from v4 to v8 (WordPress/gutenberg#77992)
- Theme: Increase stroke1 contrast target to 2.9 (WordPress/gutenberg#77599)
- Tooltip: Use md border radius for portaled popups. (WordPress/gutenberg#78983)
- Framework: Remove invalid stale nested npm package references (WordPress/gutenberg#79014)
- Theme package: Add element size design tokens (WordPress/gutenberg#76545)
- Inserter: use forwardRef for refs (WordPress/gutenberg#79006)
- RTC: Add separate doc persistence endpoint (WordPress/gutenberg#78891)
- DataViews: Add DataViews components to components manifest (WordPress/gutenberg#78960)
- Media Editor: Keep crop handles operable on large images (WordPress/gutenberg#79011)
- Media editor: tweak paddings and margins (WordPress/gutenberg#79009)
- Media Editor: Remove lag when toggling the sidebar (WordPress/gutenberg#79024)
- Elements: Align class name parsing with custom CSS implementation (WordPress/gutenberg#79023)
- CI: Suppress lint:js warnings on static checks (WordPress/gutenberg#79025)
- Remove React Native implementation, framework, and dependencies (WordPress/gutenberg#78747)
- e2e-test-utils-playwright: start transpiling again, but faster (WordPress/gutenberg#79026)
- CI: Remove Validate Gradle Wrapper workflow (WordPress/gutenberg#79030)
- Remove dead native code branches from Platform usages (WordPress/gutenberg#79031)
- Remove orphaned README files for deleted native-only components (WordPress/gutenberg#79035)
- Remove orphaned mobile bug report issue template (WordPress/gutenberg#79038)
- Inserter: Fix error being thrown for spoken message when inserting default/direct block (WordPress/gutenberg#79004)
- Editor: Remove dead native guard in block removal warnings (WordPress/gutenberg#79039)
- Preserve nested list when deleting a selection across sibling list items (WordPress/gutenberg#78776)
- Remove platform-docs Docusaurus site (WordPress/gutenberg#79034)
- Align dependency versions across workspaces (WordPress/gutenberg#77954)
- RichText: Remove dead native-only prop filtering (WordPress/gutenberg#79037)
- Navigable Container: Hoist getFocusableContext out of the component (WordPress/gutenberg#79029)
- Tools: Lint dependency version consistency with Syncpack (WordPress/gutenberg#77950)
- Extract entity view config into a filterable API (WordPress/gutenberg#78977)
- Rich text: use subscribeDelegatedListener for element event listeners (WordPress/gutenberg#79047)
- theme/ThemeProvider: rename `color.bg` prop to `color.background` (WordPress/gutenberg#79007)
- Format Library: Migrate to recommended `@wordpress/ui` components (WordPress/gutenberg#79059)
- Syncpack: ban `classnames` from being reintroduced (WordPress/gutenberg#79061)
- UI: Update CSS cascade layers to use nesting (WordPress/gutenberg#78959)
- Docs: Remove stale mobile references from tooling and primitives docs (WordPress/gutenberg#79041)
- Release: Drop mobile-specific changelog omit rules (WordPress/gutenberg#79042)
- Bump actions/checkout (WordPress/gutenberg#79033)
- `ColorPalette`: don't render when custom colors disabled and no colors passed (WordPress/gutenberg#72402)
- Bump minimatch and lerna (WordPress/gutenberg#76750)
- Image block: don't show crop icon while image is uploading (WordPress/gutenberg#79103)
- Add React 19 as an experimental flag (WordPress/gutenberg#79077)
- Media modal: small tweak to gutters (WordPress/gutenberg#79168)
- Add more React internals polyfills (WordPress/gutenberg#79142)
- Media editor modal: Fix keyboard resizing for locked aspect-ratio crops (WordPress/gutenberg#79207)
- Fix responsive element styles front end output (WordPress/gutenberg#79135) (WordPress/gutenberg#79215)

Props adamsilverstein, jorbin, westonruter, wildworks.
Fixes #65368.

git-svn-id: https://develop.svn.wordpress.org/trunk@62584 602fd350-edb4-49c9-b593-d223f7449a82
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Block editor /packages/block-editor [Package] Editor /packages/editor [Type] Code Quality Issues or PRs that relate to code quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Post Revisions: Upgrade diff from v4 to v8

6 participants