Skip to content

Worker threads: reject pending RPC calls on worker failure or termination - #79955

Merged
adamsilverstein merged 7 commits into
trunkfrom
fix/79953-worker-rpc-reject-pending
Jul 15, 2026
Merged

Worker threads: reject pending RPC calls on worker failure or termination#79955
adamsilverstein merged 7 commits into
trunkfrom
fix/79953-worker-rpc-reject-pending

Conversation

@adamsilverstein

@adamsilverstein adamsilverstein commented Jul 7, 2026

Copy link
Copy Markdown
Member

Fixes #79953

What?

Makes worker RPC promises in @wordpress/worker-threads settle when the underlying Web Worker fails or is terminated, instead of hanging forever.

Why?

comctx (the RPC layer used by wrap()) only settles a call promise when a response message arrives from the worker, and wrap() runs with heartbeatCheck: false. If the vips worker dies, fails to initialize, or is terminated while an operation is in flight, the promise for that operation never settles. The upload queue item then stays in its current operation forever:

  • The image block shows the blob: placeholder and a progress spinner indefinitely.
  • No error is surfaced to the user (the onError path never runs).
  • isUploading() stays true, so the editor's upload save lock keeps the post unsaveable.

The worker is terminated and recreated frequently (removeItem terminates it whenever the queue empties, and it is recycled every 50 operations), so failure windows occur many times per editing session. See #79953 for the full analysis.

How?

In packages/worker-threads/src/main-thread.ts, wrap() now tracks the rejecter of every in-flight call:

  • terminate() rejects all pending calls, as its docblock already promised ("any pending calls will be rejected") but the implementation never did.
  • error / messageerror listeners on the worker reject all pending calls when the worker crashes, fails script load/WASM instantiation, or delivers an undeserializable message.
  • Once a worker has failed or been terminated, subsequent calls on that remote reject immediately instead of hanging.

This closes the failure loop with the existing queue logic: a rejected vips call cancels the queue item and surfaces onError, the queue drains, the empty-queue cleanup terminates the dead worker, and the next upload lazily creates a fresh one (getWorkerAPI() in @wordpress/vips). Both the vips and video-conversion workers benefit.

Per review feedback, cancelItem in @wordpress/upload-media also needed a change: it awaits vipsCancelOperations() / cancelGifToVideoOperations(), and with a dead worker those cancel calls themselves now reject, which previously aborted the cancellation flow before onError fired and the item was removed. Those calls are now best-effort (.catch( () => {} )), which keeps the recovery loop intact end to end.

The remaining hardening ideas from #79953 (per-call timeout for a wedged-but-alive worker, debounced empty-queue termination, awaiting mediaDelete in cancelItem) are intentionally left as follow-ups to keep this focused.

Testing Instructions

Test in WordPress Playground

  1. npm run test:unit packages/worker-threads

The 5 new test cases hang (5s timeout each) without the fix and pass with it: worker error event rejects pending calls, messageerror rejects pending calls, calls after a worker error reject immediately, terminate() rejects pending calls, and calls after termination reject immediately.

  1. npm run test:unit packages/upload-media — includes two new tests asserting cancelItem still fires onError and removes the item when the worker cancel calls reject (both fail without the best-effort change).

  2. npm run test:e2e -- test/e2e/specs/editor/various/client-side-media-processing.spec.js — includes a new test that crashes the vips worker mid-upload and asserts the error snackbar appears, the queue empties, the save lock releases, and a follow-up upload succeeds with a fresh worker.

Manual verification of the end-to-end behavior:

  1. Open the post editor and start uploading a large image.
  2. Tip: use network throttling to slow down the upload and give more time to kill the worker.
  3. While the upload spinner is showing, kill the vips worker: in DevTools, go to Sources → Threads (or chrome://inspect/#workers) and terminate the blob worker, or simulate a crash.
  4. Without this PR the block is stuck on the blob: placeholder forever and the post can't be saved. With this PR the upload fails with an error notice and the save lock releases.

…tion

comctx only settles a call promise when a response message arrives from
the worker, so a worker that crashed, failed to initialize, or was
terminated mid-call left its promises pending forever. In the upload
queue this surfaced as an image stuck on its blob: placeholder with the
progress spinner, no error surfaced, and the editor save lock never
released.

Track pending call rejecters per wrapped worker so that:

- terminate() rejects pending calls, as its docblock already promised.
- The worker's error/messageerror events reject pending calls.
- Calls made after a failure/termination reject immediately instead of
  hanging, until the consumer recreates the worker.

Fixes #79953
@adamsilverstein adamsilverstein added [Type] Bug An existing feature does not function as intended [Feature] Client Side Media Media processing in the browser with WASM labels Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 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: adamsilverstein <adamsilverstein@git.wordpress.org>
Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>

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

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Size Change: +667 B (+0.01%)

Total Size: 7.72 MB

📦 View Changed
Filename Size Change
build/modules/video-conversion/worker.min.js 83.2 kB +269 B (+0.32%)
build/modules/vips/worker.min.js 3.69 MB +398 B (+0.01%)

compressed-size-action

@adamsilverstein adamsilverstein self-assigned this Jul 7, 2026
@adamsilverstein
adamsilverstein requested a review from ramonjd July 7, 2026 17:32
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Flaky tests detected in 3e63024.
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/28952781567
📝 Reported issues:

If the underlying remote call threw synchronously or returned a
non-thenable, the rejecter would stay in pendingRejects until the next
worker failure. Route the call through Promise.resolve() so cleanup
always runs.
Comment thread packages/worker-threads/src/main-thread.ts
…celItem

When the vips or video-conversion worker has crashed, every call on its
remote rejects - including the cancellation issued by cancelItem itself.
That rejection escaped cancelItem before onError fired and before the
item was removed, so a worker crash mid-transcode left the upload stuck
in the queue, the save lock held, and the dead worker never recycled.

Catch rejections from vipsCancelOperations and
cancelGifToVideoOperations so the cancellation flow always completes:
the error surfaces to the user, the item leaves the queue, and emptying
the queue tears down the dead worker so the next upload gets a fresh
one.

Adds unit tests for both rejecting cancel calls and an e2e test that
crashes the vips worker mid-upload and asserts the editor surfaces the
error, releases the save lock, and recovers on the next upload.
@adamsilverstein
adamsilverstein requested a review from ramonjd July 13, 2026 00:20

@andrewserong andrewserong left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I also wasn't able to manually test this one for some reason (I could pause workers, but Chrome didn't let me terminate any 🤷)

But, smoke testing uploading works as expected, and I didn't run into any issues looking over the code, and everything I got from passing this through Claude seemed minor/like nits. E.g.

  • That the failWorker state means subsequent calls for a failed worker are rejected even if the worker is still running (i.e. it'll run until it's terminated). That seems like the intention of this PR, so doesn't sound like an issue?
  • removeListeners() is only called when terminating the worker. Is that expected?
  • And "Wrapping the delegate in Promise.resolve().then( () => value( ...args ) )" adds a microtask of latency. This also sounds like a non-issue to me

Given we're close to the feature freeze, I'll give this a tentative approval. But let me know if you wanted someone to be able to manually reproduce the testing steps, since it seems neither Ramon or I have been able to yet.

@adamsilverstein

Copy link
Copy Markdown
Member Author

Some findings from the #80259 investigation (fix in #80260) that are relevant here:

The hang in #80259 turned out to be a wasm deadlock, not a crash: a libjpeg failure killed a libvips worker pthread without unwinding, and the coordinating thread blocked forever in Atomics.wait. The worker never fired error or messageerror and never terminated - so the event-based rejection in this PR wouldn't have caught that class of hang. Not a flaw in this PR (it correctly covers crashes, failed script loads, and termination), but probably worth a sentence in the description so it isn't assumed to be complete hang-proofing.

One concrete gap in the upload-media change: await vipsCancelOperations( id ).catch( () => {} ) handles a rejecting cancel, but against a deadlocked worker the promise never settles, so .catch never runs and cancelItem itself hangs at the await - cancelling a stuck upload still wouldn't unwind. A timeout race would cover it:

await Promise.race( [
	vipsCancelOperations( id ).catch( () => {} ),
	new Promise( ( resolve ) => setTimeout( resolve, 3000 ) ),
] );

Silver lining: the terminate()-rejects-pending behavior added here is exactly the primitive a real watchdog needs. A natural follow-up once this lands: when a vips call exceeds a generous deadline (or cancellation times out as above), call terminateVipsWorker() - pending calls then reject immediately and the queue's existing error handling unwinds. Today maybeRecycleVipsWorker only recycles on op-count, which never triggers for a stuck worker.

Also FYI: #80260 touches the worker side of this package (expose() now normalizes non-Error throwables so in-worker failures reject instead of resolving undefined) - complementary to this PR, only overlap is a trivial CHANGELOG.md conflict for whichever merges second.

@andrewserong

Copy link
Copy Markdown
Contributor

So, sounds like we merge this PR now(ish) and then follow-up in #80260?

@adamsilverstein adamsilverstein added the Backport to Gutenberg RC Pull request that needs to be backported to a Gutenberg release candidate (RC) label Jul 15, 2026
@adamsilverstein
adamsilverstein merged commit 70f9a95 into trunk Jul 15, 2026
47 checks passed
@adamsilverstein
adamsilverstein deleted the fix/79953-worker-rpc-reject-pending branch July 15, 2026 16:41
@github-actions github-actions Bot added this to the Gutenberg 23.7 milestone Jul 15, 2026
@adamsilverstein adamsilverstein added the Backport to WP 7.1 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Jul 17, 2026
@github-actions

Copy link
Copy Markdown

There was a conflict while trying to cherry-pick the commit to the wp/7.1 branch. Please resolve the conflict manually and create a PR to the wp/7.1 branch.

PRs to wp/7.1 are similar to PRs to trunk, but you should base your PR on the wp/7.1 branch instead of trunk.

# Checkout the wp/7.1 branch instead of trunk.
git checkout wp/7.1

# Create a new branch for your PR.
git checkout -b my-branch

# Cherry-pick the commit.
git cherry-pick 70f9a9594d6532301fa31c3313f38275c60d26b9

# Check which files have conflicts.
git status

# Resolve the conflict...
# Add the resolved files to the staging area.
git status
git add .
git cherry-pick --continue

# Push the branch to the repository
git push origin my-branch

# Create a PR and set the base to the wp/7.1 branch.
# See https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-base-branch-of-a-pull-request.

@adamsilverstein

Copy link
Copy Markdown
Member Author

It looks like this was missing the 7.1 backport label and was never added to the 7.1 branch.

@adamsilverstein

Copy link
Copy Markdown
Member Author

It looks like this was missing the 7.1 backport label and was never added to the 7.1 branch.

Going to stack the PR on #80420 which touches the same files. cc: @t-hamano

@t-hamano

Copy link
Copy Markdown
Contributor

Removing the Backport to Gutenberg RC label from this PR and add it to #80421 instead. This is because cherry-picking the manual backport PR created for wp/7.1 is less likely to cause conflicts than cherry-picking the PR that caused the conflict.

@t-hamano t-hamano removed the Backport to Gutenberg RC Pull request that needs to be backported to a Gutenberg release candidate (RC) label Jul 18, 2026
adamsilverstein added a commit that referenced this pull request Jul 20, 2026
…tion (#79955) (#80421)

Co-authored-by: adamsilverstein <adamsilverstein@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
@t-hamano

Copy link
Copy Markdown
Contributor

This PR was manually backported by #80421.

@t-hamano t-hamano added Backported to WP Core Pull request that has been successfully merged into WP Core and removed Backport to WP 7.1 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta labels Jul 20, 2026
t-hamano added a commit that referenced this pull request Jul 21, 2026
…tion (#79955) (#80421)

Co-authored-by: adamsilverstein <adamsilverstein@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
pento pushed a commit to WordPress/wordpress-develop that referenced this pull request Jul 22, 2026
This updates the pinned commit hash of the Gutenberg repository from `e73c3c481db0650183f092af157f6e42efe9ee2d` to `4997026b75c922d8a6f77a03d72ed7cad04c7073`.

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

- Notes: Replace blur-deselect bookkeeping with useFocusOutside (WordPress/gutenberg#80222)
- Playlist: Update @SInCE tags to 7.1.0 (WordPress/gutenberg#80317)
- fix playlist block Dimensions Design (WordPress/gutenberg#80312)
- UI: Backport compat overlay fixes to WordPress 7.1 (WordPress/gutenberg#80322)
- Editor: allow selecting which block styles to apply globally (WordPress/gutenberg#79839)
- Global Styles: Reject non-string custom CSS in the REST controller (WordPress/gutenberg#80338)
- Open inspector sidebar when toggling responsive editing (WordPress/gutenberg#80307)
- Client Side Media: Honor image_strip_meta and image_max_bit_depth on the client upload path (WordPress/gutenberg#80218)
- Hide block style variations when state is enabled in global styles (WordPress/gutenberg#80341)
- Media REST API: Fix sideload and finalize for EXIF rotated images (WordPress/gutenberg#80295)
- Fix upload snackbar stuck in uploading state on server-side uploads (WordPress/gutenberg#80345)
- Try fixing responsive layout in Nav block (WordPress/gutenberg#80305)
- Responsive styles: Use viewport dropdown to control states for in-editor global styles sidebar (WordPress/gutenberg#80339)
- RichTextControl: Replace DOM focus tracking with a single React-tree focus boundary (WordPress/gutenberg#80324)
- Notes: Finish WPDS treatment for mention chips (WordPress/gutenberg#80300)
- Notes: Add placeholders to the RichText fields (WordPress/gutenberg#80296)
- Fix upload hang when converting long animated GIFs: decode only the first frame for still outputs (WordPress/gutenberg#80260) (WordPress/gutenberg#80342)
- Device preview dropdown: use active color for device icon when responsive styles are active (WordPress/gutenberg#80346)
- Fix default aspect ratio for lazy loaded Featured image (WordPress/gutenberg#80386)
- Vips/upload-media: consolidate optional params into options objects (WordPress/gutenberg#80330)
- Autocompleters: Don't pre-encode mention search terms (WordPress/gutenberg#80377)
- Animated GIF uploads: generate sub-sizes from the first frame, matching core (WordPress/gutenberg#80268)
- Custom CSS: Fix cascade order against block style variations (WordPress/gutenberg#80340)
- Rich Text: Restore the selection when focus returns to the editable (WordPress/gutenberg#80396)
- Notes: Arm the mention kses allowance on REST note creation (WordPress/gutenberg#80221)
- Fix upload snackbar double-counting a single HEIC upload in Safari (WordPress/gutenberg#80436)
- ContentEditableControl: fix invalid label association with contenteditable div (WordPress/gutenberg#80441)
- Editor: Disable canvas resizing while zoomed out (WordPress/gutenberg#80391)
- Fix Color Picker Cursor Shaking Issue (WordPress/gutenberg#80205) (WordPress/gutenberg#80435)
- Misc fixes for WordPress-Develop 7.0 merges (WordPress/gutenberg#80444)
- Style Book: Restore live global styles updates on the styles route (WordPress/gutenberg#80459)
- Worker threads: reject pending RPC calls on worker failure or termination (WordPress/gutenberg#79955) (WordPress/gutenberg#80421)
- Media: Add timeout and size guardrails to client-side GIF to video conversion (WordPress/gutenberg#80420)
- Post Content: Use the default block appender for empty content (WordPress/gutenberg#80026)
- Block Supports: Handle nested array block gap values properly (WordPress/gutenberg#80464)
- Editor: Restore fixed device preview height for mobile and tablet (WordPress/gutenberg#80466)
- Block Editor: Guard against non-string spacing preset values (WordPress/gutenberg#80467)
- Writing flow: fully select the ancestor when a text selection crosses a nesting boundary (WordPress/gutenberg#80462)
- Block Editor: Reflect inherited Global Styles values in block inspector controls (WordPress/gutenberg#80481)
- Autocomplete: Reference the suggestions list with `aria-controls` and `aria-haspopup` (WordPress/gutenberg#80403) (WordPress/gutenberg#80499)
- Media: Remove the redundant __heicUploadSupport flag (WordPress/gutenberg#80486)
- State control - avoid tertiary variant on toggle to match style of other dropdown toggles (WordPress/gutenberg#80505)
- Icons: Store the sanitized SVG content when registering an icon (WordPress/gutenberg#80508)
- Fix `useHomeEnd` on tabs in mac testing (WordPress/gutenberg#80374)
- Playlist: Fix playback of tracks served without CORS headers (WordPress/gutenberg#80533)
- Redirect editing events to extension handlers under editableRoot (WordPress/gutenberg#80287)
- Writing flow: fully select the items when a selection extends down into a nested item (WordPress/gutenberg#80492)
- Global Styles panels: fix wrong preset committed and shown when two color presets share a hex (WordPress/gutenberg#80497)
- Replaces the `title` attributes used by revision inline diff annotations with `aria-describedby` (WordPress/gutenberg#80440)
- Notes: Remove "Add note" from the inline styles dropdown (WordPress/gutenberg#80531)
- Global Styles: Resolve per-level heading element styles in block inspector controls (WordPress/gutenberg#80495)
- Notes: Render @ mentions as span chips and narrow the kses class allowance (WordPress/gutenberg#80528)
- Revisions: Specify block level diff status via aria-label (WordPress/gutenberg#77779)
- Backport from Core: improve icon name unit tests (WordPress/gutenberg#80552)
- Device type preview: fix collapsing to content height (WordPress/gutenberg#80553)
- Wrap notices in ThemeProvider with 0 corner radius (WordPress/gutenberg#80557)
- Global Styles: Limit the inherited value treatment to the Gutenberg plugin (WordPress/gutenberg#80555)
- Fix crashes when manipulating locked blocks (WordPress/gutenberg#80509)
- Notes: align floating threads with their inline marker (WordPress/gutenberg#79877)

Props wildworks.
See #65529.

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

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

- Notes: Replace blur-deselect bookkeeping with useFocusOutside (WordPress/gutenberg#80222)
- Playlist: Update @SInCE tags to 7.1.0 (WordPress/gutenberg#80317)
- fix playlist block Dimensions Design (WordPress/gutenberg#80312)
- UI: Backport compat overlay fixes to WordPress 7.1 (WordPress/gutenberg#80322)
- Editor: allow selecting which block styles to apply globally (WordPress/gutenberg#79839)
- Global Styles: Reject non-string custom CSS in the REST controller (WordPress/gutenberg#80338)
- Open inspector sidebar when toggling responsive editing (WordPress/gutenberg#80307)
- Client Side Media: Honor image_strip_meta and image_max_bit_depth on the client upload path (WordPress/gutenberg#80218)
- Hide block style variations when state is enabled in global styles (WordPress/gutenberg#80341)
- Media REST API: Fix sideload and finalize for EXIF rotated images (WordPress/gutenberg#80295)
- Fix upload snackbar stuck in uploading state on server-side uploads (WordPress/gutenberg#80345)
- Try fixing responsive layout in Nav block (WordPress/gutenberg#80305)
- Responsive styles: Use viewport dropdown to control states for in-editor global styles sidebar (WordPress/gutenberg#80339)
- RichTextControl: Replace DOM focus tracking with a single React-tree focus boundary (WordPress/gutenberg#80324)
- Notes: Finish WPDS treatment for mention chips (WordPress/gutenberg#80300)
- Notes: Add placeholders to the RichText fields (WordPress/gutenberg#80296)
- Fix upload hang when converting long animated GIFs: decode only the first frame for still outputs (WordPress/gutenberg#80260) (WordPress/gutenberg#80342)
- Device preview dropdown: use active color for device icon when responsive styles are active (WordPress/gutenberg#80346)
- Fix default aspect ratio for lazy loaded Featured image (WordPress/gutenberg#80386)
- Vips/upload-media: consolidate optional params into options objects (WordPress/gutenberg#80330)
- Autocompleters: Don't pre-encode mention search terms (WordPress/gutenberg#80377)
- Animated GIF uploads: generate sub-sizes from the first frame, matching core (WordPress/gutenberg#80268)
- Custom CSS: Fix cascade order against block style variations (WordPress/gutenberg#80340)
- Rich Text: Restore the selection when focus returns to the editable (WordPress/gutenberg#80396)
- Notes: Arm the mention kses allowance on REST note creation (WordPress/gutenberg#80221)
- Fix upload snackbar double-counting a single HEIC upload in Safari (WordPress/gutenberg#80436)
- ContentEditableControl: fix invalid label association with contenteditable div (WordPress/gutenberg#80441)
- Editor: Disable canvas resizing while zoomed out (WordPress/gutenberg#80391)
- Fix Color Picker Cursor Shaking Issue (WordPress/gutenberg#80205) (WordPress/gutenberg#80435)
- Misc fixes for WordPress-Develop 7.0 merges (WordPress/gutenberg#80444)
- Style Book: Restore live global styles updates on the styles route (WordPress/gutenberg#80459)
- Worker threads: reject pending RPC calls on worker failure or termination (WordPress/gutenberg#79955) (WordPress/gutenberg#80421)
- Media: Add timeout and size guardrails to client-side GIF to video conversion (WordPress/gutenberg#80420)
- Post Content: Use the default block appender for empty content (WordPress/gutenberg#80026)
- Block Supports: Handle nested array block gap values properly (WordPress/gutenberg#80464)
- Editor: Restore fixed device preview height for mobile and tablet (WordPress/gutenberg#80466)
- Block Editor: Guard against non-string spacing preset values (WordPress/gutenberg#80467)
- Writing flow: fully select the ancestor when a text selection crosses a nesting boundary (WordPress/gutenberg#80462)
- Block Editor: Reflect inherited Global Styles values in block inspector controls (WordPress/gutenberg#80481)
- Autocomplete: Reference the suggestions list with `aria-controls` and `aria-haspopup` (WordPress/gutenberg#80403) (WordPress/gutenberg#80499)
- Media: Remove the redundant __heicUploadSupport flag (WordPress/gutenberg#80486)
- State control - avoid tertiary variant on toggle to match style of other dropdown toggles (WordPress/gutenberg#80505)
- Icons: Store the sanitized SVG content when registering an icon (WordPress/gutenberg#80508)
- Fix `useHomeEnd` on tabs in mac testing (WordPress/gutenberg#80374)
- Playlist: Fix playback of tracks served without CORS headers (WordPress/gutenberg#80533)
- Redirect editing events to extension handlers under editableRoot (WordPress/gutenberg#80287)
- Writing flow: fully select the items when a selection extends down into a nested item (WordPress/gutenberg#80492)
- Global Styles panels: fix wrong preset committed and shown when two color presets share a hex (WordPress/gutenberg#80497)
- Replaces the `title` attributes used by revision inline diff annotations with `aria-describedby` (WordPress/gutenberg#80440)
- Notes: Remove "Add note" from the inline styles dropdown (WordPress/gutenberg#80531)
- Global Styles: Resolve per-level heading element styles in block inspector controls (WordPress/gutenberg#80495)
- Notes: Render @ mentions as span chips and narrow the kses class allowance (WordPress/gutenberg#80528)
- Revisions: Specify block level diff status via aria-label (WordPress/gutenberg#77779)
- Backport from Core: improve icon name unit tests (WordPress/gutenberg#80552)
- Device type preview: fix collapsing to content height (WordPress/gutenberg#80553)
- Wrap notices in ThemeProvider with 0 corner radius (WordPress/gutenberg#80557)
- Global Styles: Limit the inherited value treatment to the Gutenberg plugin (WordPress/gutenberg#80555)
- Fix crashes when manipulating locked blocks (WordPress/gutenberg#80509)
- Notes: align floating threads with their inline marker (WordPress/gutenberg#79877)

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


git-svn-id: http://core.svn.wordpress.org/trunk@62104 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backported to WP Core Pull request that has been successfully merged into WP Core [Feature] Client Side Media Media processing in the browser with WASM [Type] Bug An existing feature does not function as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upload queue: a vips worker failure leaves uploads hanging forever (worker RPC promises never settle)

4 participants