Skip to content

Suggestions - show suggestions as inline previews#77869

Open
adamsilverstein wants to merge 20 commits into
add-suggestion-modefrom
try/suggest-mode-inline-formats
Open

Suggestions - show suggestions as inline previews#77869
adamsilverstein wants to merge 20 commits into
add-suggestion-modefrom
try/suggest-mode-inline-formats

Conversation

@adamsilverstein
Copy link
Copy Markdown
Member

@adamsilverstein adamsilverstein commented May 1, 2026

Summary

Similar to Google Docs, suggestion mode in Gutenberg now shows suggestions as inline previews:

  • A suggested text insertion is visible in the editor with a green underline + side-shadow indicating it is a suggested insertion.
  • A suggested text deletion is shown with a red strike-through and color treatment indicating it is a suggested deletion.
  • A suggested style change (e.g. bolding a word) renders with the new format AND the addition color treatment so the change is discoverable inline.

This screenshot shows a suggested attribute change (bold), addition and deletion:

image

Closes #77867.

Scope: phases A + B + C in one PR

The tracking issue originally split this work into four phases (A — register format types, B — edit-time interception, C — apply/reject transforms + schema v2 migration, D — edge cases). This PR folds A, B, and C into a single change because the chosen architecture makes B and C structurally smaller than the issue anticipated:

Original plan (issue #77867) What this PR does
A — Register gutenberg/suggested-deletion / -addition formats and ship CSS Done as designed — see inline-formats.js, style.scss
B — Intercept Backspace/Delete and onChange to mark text as <del> / <ins> at edit time, persist a marked RichText value Replaced with a render-time diff: the overlay HOC compares baseline vs proposed content on every render and feeds marked HTML to BlockEdit
C — Add an applyMarkedValue / rejectMarkedValue transform path; introduce schema v2 with a rich-text-marked operation; migrate v1 payloads on read Not needed. Because the overlay stores the clean proposed value (not marked HTML), the existing attribute-set schema and apply/reject path keep working unchanged — no migration, no new op type
D — Edge cases (paste-into-mixed-selection, undo/redo across overlay boundaries, multi-block changes, partial-tag overlap) Out of scope here, lands as follow-up

Why the pivot

Edit-time interception (the original Phase B plan) requires hooking key handlers into every RichText that participates in suggest mode and then teaching the auto-save pipeline how to round-trip a marked value. Render-time diff achieves the same visible behavior by deriving the diff every render — markContentDiff(baseline, proposed) is small, deterministic, and never touches the persistence path. The result:

  • Persisted post (block content + _wp_suggestion meta) is byte-identical to phase-5 trunk; no schema migration to ship or reason about.
  • Apply / Reject continue to operate on the same attribute-set operations they always did — no "strip runs with format" helper, no two-pass clean-up.
  • Marks render after the user blurs the block (gated on ! isBlockSelected), which sidesteps RichText cursor-jumping that would otherwise come from value-prop reconciliation on every keystroke. Docs takes the same end-state route via a custom rendering pipeline; this PR matches the visible result without that pipeline.

The tradeoff is that we don't do live-mark-while-typing, and that whole-token format changes surface as a paired delete/insert rather than an in-place format swap. Both are acceptable for v1.

What lands here

  • packages/editor/src/components/suggestion-mode/inline-formats.js
    • gutenberg/suggested-deletion<del class="has-suggestion-deletion">
    • gutenberg/suggested-addition<ins class="has-suggestion-addition">
    • Both registered via registerSuggestionFormats() (idempotent), called once on module import so editor bootstrap and integration tests get the formats without a separate init step.
    • Both are interactive: false and have no edit UI so they never appear in the block toolbar — the formats are applied programmatically by the overlay HOC, not by users clicking a toolbar button.
    • markContentDiff(baseline, proposed) — produces marked HTML where deleted runs are wrapped in <del class="has-suggestion-deletion"> and added runs in <ins class="has-suggestion-addition">. Tokenization delegates to the existing wordDiff so the canvas marks share a definition of "what counts as a change" with the sidebar diff summary.
    • stripSuggestionMarks(marked) — reverses the wrap so RichText round-tripping the marked HTML through setAttributes doesn't double up the marks on the next render.
  • packages/editor/src/components/suggestion-mode/with-suggestion-overlay.js
    • mergedAttributes now passes content through markContentDiff before handing it to BlockEdit, so deletions render with the strikethrough and additions render with the underline + side-shadow.
    • wrappedSetAttributes strips suggestion marks from incoming payloads before storing them in the overlay, so the overlay stays "proposed clean" rather than "proposed marked".
    • Marking is gated on ! isBlockSelected( clientId ) so RichText's value-prop reconciliation doesn't fight the user's caret on every keystroke. Marks reappear as soon as focus moves elsewhere.
    • RICH_TEXT_ATTRIBUTE_KEYS is intentionally narrow (content only) so primitive attributes (align, level, fontSize) keep flowing through the existing block-level outline rather than leaking HTML into string slots.
  • CSS in style.scss
    • Strikethrough red on deletions, underline + faint green background + 1px side-shadow on additions, all using --wp-admin-theme-color with sensible fallbacks.
  • Unit tests covering format registration, serialization shape, side-by-side application, the diff/mark/strip round-trip, and the new HOC helpers (applyDiffMarks, stripMarksFromIncoming).
  • E2E tests covering the three golden-path scenarios in the editor canvas.

What does NOT land here (Phase D follow-up)

  • Always-on inline marks during typing — would require a custom RichText rendering pipeline; the marks-after-blur compromise sidesteps RichText cursor-jumping on value-prop reconciliation.
  • Edit-time interception of Backspace/Delete that preserves the original characters as <del> runs in real time.
  • Edge cases — paste-into-mixed-selection, drag-select spanning already-marked runs, undo / redo across overlay boundaries, cursor visual adjacent to a <del> run, multi-block changes, partial-tag overlap.
  • Marking on attributes other than content (button text, list items, etc.).

Stack base

This branch sits on top of #77407 (add-suggestion-mode). Merge order is #75147#77403#77407 → this PR → Phase D.

Test plan

# Unit tests (jest)
npm run test:unit -- packages/editor/src/components/suggestion-mode

# E2E tests (playwright; requires wp-env)
npm run test:e2e -- test/e2e/specs/editor/various/suggestion-mode.spec.js

Unit tests now cover:

  • gutenberg/suggested-deletion registers as a non-interactive <del> with the right class
  • gutenberg/suggested-addition registers as a non-interactive <ins> with the right class
  • A range with gutenberg/suggested-deletion serializes to <del class="has-suggestion-deletion">…</del>
  • A range with gutenberg/suggested-addition serializes to <ins class="has-suggestion-addition">…</ins>
  • Adjacent deletion + addition runs (the "Hello → Hi" diff) serialize as two separate elements without merging
  • markContentDiff handles identical inputs, pure additions, pure deletions, mid-string replacements, inline-format additions, and null/undefined coercion
  • stripSuggestionMarks is a no-op when no marks present, removes deletion runs, unwraps addition runs, round-trips, and passes null/undefined through
  • applyDiffMarks no-ops on missing baseline, no-ops on unchanged content, marks changed content, and skips primitive attributes
  • stripMarksFromIncoming short-circuits unchanged payloads and strips marks from content

E2E tests cover the three golden-path scenarios:

  • Add: typing at the end of a paragraph → after deselect, the new word renders as <ins class="has-suggestion-addition">
  • Delete: backspacing a selected trailing run → after deselect, the removed word renders as <del class="has-suggestion-deletion">
  • Style: Cmd/Ctrl+B on a selected word → after deselect, the bolded run renders as <ins class="has-suggestion-addition"><strong>word</strong></ins> AND its pre-bold version surfaces as a paired <del>

All 109 suggestion-mode unit tests pass; all 6 suggestion-mode e2e tests pass locally.

Linked

…and deletes

Phase A of #77867. Registers two display-oriented format types that
later phases will apply programmatically to the suggest-mode overlay
so reviewers and suggesters see proposed deletions struck through
and proposed additions highlighted inline within RichText, alongside
the existing sidebar diff summary.

- gutenberg/suggested-deletion (<del class="has-suggestion-deletion">)
- gutenberg/suggested-addition (<ins class="has-suggestion-addition">)

Both formats are non-interactive (no toolbar UI) and registered
idempotently so the editor bootstrap and integration tests can both
trigger registration safely. CSS uses --wp-admin-theme-color and a
faint background so the marks read on light and dark themes.

Phase B (input interception) and Phase C (apply/reject transforms)
follow in subsequent PRs.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

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: alecgeatches <alecgeatches@git.wordpress.org>

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

@github-actions github-actions Bot added the [Package] Editor /packages/editor label May 1, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

Size Change: +1.96 kB (+0.02%)

Total Size: 7.92 MB

📦 View Changed
Filename Size Change
build/scripts/editor/index.min.js 434 kB +1.63 kB (+0.38%)
build/styles/block-editor/content-rtl.css 5.52 kB +85 B (+1.56%)
build/styles/block-editor/content-rtl.min.css 4.09 kB +78 B (+1.94%)
build/styles/block-editor/content.css 5.53 kB +85 B (+1.56%)
build/styles/block-editor/content.min.css 4.09 kB +80 B (+2%)
ℹ️ View Unchanged
Filename Size
build/modules/a11y/index.min.js 355 B
build/modules/abilities/index.min.js 42.3 kB
build/modules/block-editor/utils/fit-text-frontend.min.js 617 B
build/modules/block-library/accordion/view.min.js 595 B
build/modules/block-library/file/view.min.js 346 B
build/modules/block-library/form/view.min.js 528 B
build/modules/block-library/image/view.min.js 2.64 kB
build/modules/block-library/navigation/view.min.js 1.14 kB
build/modules/block-library/playlist/view.min.js 10.9 kB
build/modules/block-library/query/view.min.js 518 B
build/modules/block-library/search/view.min.js 498 B
build/modules/block-library/tabs/view.min.js 946 B
build/modules/boot/index.min.js 18.6 kB
build/modules/connectors/index.min.js 2.05 kB
build/modules/core-abilities/index.min.js 907 B
build/modules/edit-site-init/index.min.js 1.4 kB
build/modules/interactivity-router/full-page.min.js 451 B
build/modules/interactivity-router/index.min.js 11.6 kB
build/modules/interactivity/index.min.js 15.1 kB
build/modules/latex-to-mathml/index.min.js 56.5 kB
build/modules/latex-to-mathml/loader.min.js 131 B
build/modules/lazy-editor/index.min.js 13.9 kB
build/modules/route/index.min.js 25.2 kB
build/modules/user-post-types/index.min.js 49 kB
build/modules/user-taxonomies/index.min.js 82.5 kB
build/modules/vips/loader.min.js 127 B
build/modules/vips/worker.min.js 4.56 MB
build/modules/workflow/index.min.js 19.9 kB
build/scripts/a11y/index.min.js 1.06 kB
build/scripts/annotations/index.min.js 2.49 kB
build/scripts/api-fetch/index.min.js 2.83 kB
build/scripts/autop/index.min.js 2.18 kB
build/scripts/base-styles/index.min.js 98 B
build/scripts/blob/index.min.js 631 B
build/scripts/block-directory/index.min.js 9.98 kB
build/scripts/block-editor/index.min.js 341 kB
build/scripts/block-library/index.min.js 319 kB
build/scripts/block-serialization-default-parser/index.min.js 1.16 kB
build/scripts/block-serialization-spec-parser/index.min.js 3.08 kB
build/scripts/blocks/index.min.js 56.9 kB
build/scripts/commands/index.min.js 21 kB
build/scripts/components/index.min.js 266 kB
build/scripts/compose/index.min.js 11.1 kB
build/scripts/core-commands/index.min.js 4.33 kB
build/scripts/core-data/index.min.js 30.8 kB
build/scripts/customize-widgets/index.min.js 14.3 kB
build/scripts/data-controls/index.min.js 795 B
build/scripts/data/index.min.js 9.66 kB
build/scripts/date/index.min.js 23.6 kB
build/scripts/deprecated/index.min.js 756 B
build/scripts/dom-ready/index.min.js 476 B
build/scripts/dom/index.min.js 5 kB
build/scripts/edit-post/index.min.js 18.4 kB
build/scripts/edit-site/index.min.js 264 kB
build/scripts/edit-widgets/index.min.js 21.9 kB
build/scripts/element/index.min.js 5.17 kB
build/scripts/escape-html/index.min.js 587 B
build/scripts/format-library/index.min.js 12.8 kB
build/scripts/hooks/index.min.js 1.83 kB
build/scripts/html-entities/index.min.js 494 B
build/scripts/i18n/index.min.js 2.47 kB
build/scripts/is-shallow-equal/index.min.js 572 B
build/scripts/keyboard-shortcuts/index.min.js 1.61 kB
build/scripts/keycodes/index.min.js 1.56 kB
build/scripts/list-reusable-blocks/index.min.js 2.49 kB
build/scripts/media-utils/index.min.js 79.5 kB
build/scripts/notices/index.min.js 1.85 kB
build/scripts/nux/index.min.js 1.89 kB
build/scripts/patterns/index.min.js 7.96 kB
build/scripts/plugins/index.min.js 2.15 kB
build/scripts/preferences-persistence/index.min.js 2.15 kB
build/scripts/preferences/index.min.js 3.3 kB
build/scripts/primitives/index.min.js 1.01 kB
build/scripts/priority-queue/index.min.js 1.62 kB
build/scripts/private-apis/index.min.js 1.1 kB
build/scripts/react-i18n/index.min.js 833 B
build/scripts/redux-routine/index.min.js 3.37 kB
build/scripts/reusable-blocks/index.min.js 3.1 kB
build/scripts/rich-text/index.min.js 14 kB
build/scripts/router/index.min.js 5.96 kB
build/scripts/server-side-render/index.min.js 1.91 kB
build/scripts/shortcode/index.min.js 1.59 kB
build/scripts/style-engine/index.min.js 2.42 kB
build/scripts/sync/index.min.js 38.8 kB
build/scripts/theme/index.min.js 22 kB
build/scripts/token-list/index.min.js 739 B
build/scripts/undo-manager/index.min.js 918 B
build/scripts/upload-media/index.min.js 11.2 kB
build/scripts/url/index.min.js 3.98 kB
build/scripts/vendors/react-dom.min.js 43.3 kB
build/scripts/vendors/react-jsx-runtime.min.js 667 B
build/scripts/vendors/react.min.js 2.77 kB
build/scripts/viewport/index.min.js 1.22 kB
build/scripts/warning/index.min.js 454 B
build/scripts/widgets/index.min.js 7.8 kB
build/scripts/wordcount/index.min.js 1.04 kB
build/styles/base-styles/admin-schemes-rtl.css 1.71 kB
build/styles/base-styles/admin-schemes-rtl.min.css 775 B
build/styles/base-styles/admin-schemes.css 1.71 kB
build/styles/base-styles/admin-schemes.min.css 775 B
build/styles/block-directory/style-rtl.css 1.97 kB
build/styles/block-directory/style-rtl.min.css 1.06 kB
build/styles/block-directory/style.css 1.98 kB
build/styles/block-directory/style.min.css 1.06 kB
build/styles/block-editor/default-editor-styles-rtl.css 697 B
build/styles/block-editor/default-editor-styles-rtl.min.css 224 B
build/styles/block-editor/default-editor-styles.css 697 B
build/styles/block-editor/default-editor-styles.min.css 224 B
build/styles/block-editor/style-rtl.css 18.6 kB
build/styles/block-editor/style-rtl.min.css 15.9 kB
build/styles/block-editor/style.css 18.6 kB
build/styles/block-editor/style.min.css 15.8 kB
build/styles/block-library/accordion-heading/style-rtl.css 346 B
build/styles/block-library/accordion-heading/style-rtl.min.css 325 B
build/styles/block-library/accordion-heading/style.css 346 B
build/styles/block-library/accordion-heading/style.min.css 325 B
build/styles/block-library/accordion-item/style-rtl.css 239 B
build/styles/block-library/accordion-item/style-rtl.min.css 180 B
build/styles/block-library/accordion-item/style.css 238 B
build/styles/block-library/accordion-item/style.min.css 180 B
build/styles/block-library/accordion-panel/style-rtl.css 110 B
build/styles/block-library/accordion-panel/style-rtl.min.css 99 B
build/styles/block-library/accordion-panel/style.css 110 B
build/styles/block-library/accordion-panel/style.min.css 99 B
build/styles/block-library/accordion/style-rtl.css 69 B
build/styles/block-library/accordion/style-rtl.min.css 62 B
build/styles/block-library/accordion/style.css 69 B
build/styles/block-library/accordion/style.min.css 62 B
build/styles/block-library/archives/style-rtl.css 101 B
build/styles/block-library/archives/style-rtl.min.css 90 B
build/styles/block-library/archives/style.css 101 B
build/styles/block-library/archives/style.min.css 90 B
build/styles/block-library/audio/editor-rtl.css 166 B
build/styles/block-library/audio/editor-rtl.min.css 149 B
build/styles/block-library/audio/editor.css 166 B
build/styles/block-library/audio/editor.min.css 151 B
build/styles/block-library/audio/style-rtl.css 945 B
build/styles/block-library/audio/style-rtl.min.css 132 B
build/styles/block-library/audio/style.css 945 B
build/styles/block-library/audio/style.min.css 132 B
build/styles/block-library/audio/theme-rtl.css 967 B
build/styles/block-library/audio/theme-rtl.min.css 134 B
build/styles/block-library/audio/theme.css 967 B
build/styles/block-library/audio/theme.min.css 134 B
build/styles/block-library/avatar/editor-rtl.css 127 B
build/styles/block-library/avatar/editor-rtl.min.css 115 B
build/styles/block-library/avatar/editor.css 127 B
build/styles/block-library/avatar/editor.min.css 115 B
build/styles/block-library/avatar/style-rtl.css 117 B
build/styles/block-library/avatar/style-rtl.min.css 104 B
build/styles/block-library/avatar/style.css 117 B
build/styles/block-library/avatar/style.min.css 104 B
build/styles/block-library/breadcrumbs/style-rtl.css 233 B
build/styles/block-library/breadcrumbs/style-rtl.min.css 203 B
build/styles/block-library/breadcrumbs/style.css 233 B
build/styles/block-library/breadcrumbs/style.min.css 203 B
build/styles/block-library/button/editor-rtl.css 306 B
build/styles/block-library/button/editor-rtl.min.css 265 B
build/styles/block-library/button/editor.css 317 B
build/styles/block-library/button/editor.min.css 265 B
build/styles/block-library/button/style-rtl.css 651 B
build/styles/block-library/button/style-rtl.min.css 596 B
build/styles/block-library/button/style.css 662 B
build/styles/block-library/button/style.min.css 596 B
build/styles/block-library/buttons/editor-rtl.css 391 B
build/styles/block-library/buttons/editor-rtl.min.css 291 B
build/styles/block-library/buttons/editor.css 391 B
build/styles/block-library/buttons/editor.min.css 291 B
build/styles/block-library/buttons/style-rtl.css 452 B
build/styles/block-library/buttons/style-rtl.min.css 349 B
build/styles/block-library/buttons/style.css 453 B
build/styles/block-library/buttons/style.min.css 349 B
build/styles/block-library/calendar/style-rtl.css 271 B
build/styles/block-library/calendar/style-rtl.min.css 239 B
build/styles/block-library/calendar/style.css 271 B
build/styles/block-library/calendar/style.min.css 239 B
build/styles/block-library/categories/editor-rtl.css 171 B
build/styles/block-library/categories/editor-rtl.min.css 132 B
build/styles/block-library/categories/editor.css 170 B
build/styles/block-library/categories/editor.min.css 131 B
build/styles/block-library/categories/style-rtl.css 226 B
build/styles/block-library/categories/style-rtl.min.css 169 B
build/styles/block-library/categories/style.css 235 B
build/styles/block-library/categories/style.min.css 169 B
build/styles/block-library/classic-rtl.css 402 B
build/styles/block-library/classic-rtl.min.css 358 B
build/styles/block-library/classic.css 402 B
build/styles/block-library/classic.min.css 358 B
build/styles/block-library/code/editor-rtl.css 59 B
build/styles/block-library/code/editor-rtl.min.css 53 B
build/styles/block-library/code/editor.css 59 B
build/styles/block-library/code/editor.min.css 53 B
build/styles/block-library/code/style-rtl.css 158 B
build/styles/block-library/code/style-rtl.min.css 140 B
build/styles/block-library/code/style.css 178 B
build/styles/block-library/code/style.min.css 140 B
build/styles/block-library/code/theme-rtl.css 135 B
build/styles/block-library/code/theme-rtl.min.css 122 B
build/styles/block-library/code/theme.css 135 B
build/styles/block-library/code/theme.min.css 122 B
build/styles/block-library/columns/editor-rtl.css 119 B
build/styles/block-library/columns/editor-rtl.min.css 108 B
build/styles/block-library/columns/editor.css 119 B
build/styles/block-library/columns/editor.min.css 108 B
build/styles/block-library/columns/style-rtl.css 1.3 kB
build/styles/block-library/columns/style-rtl.min.css 421 B
build/styles/block-library/columns/style.css 1.3 kB
build/styles/block-library/columns/style.min.css 421 B
build/styles/block-library/comment-author-avatar/editor-rtl.css 136 B
build/styles/block-library/comment-author-avatar/editor-rtl.min.css 124 B
build/styles/block-library/comment-author-avatar/editor.css 136 B
build/styles/block-library/comment-author-avatar/editor.min.css 124 B
build/styles/block-library/comment-author-name/style-rtl.css 79 B
build/styles/block-library/comment-author-name/style-rtl.min.css 72 B
build/styles/block-library/comment-author-name/style.css 79 B
build/styles/block-library/comment-author-name/style.min.css 72 B
build/styles/block-library/comment-content/style-rtl.css 137 B
build/styles/block-library/comment-content/style-rtl.min.css 120 B
build/styles/block-library/comment-content/style.css 137 B
build/styles/block-library/comment-content/style.min.css 120 B
build/styles/block-library/comment-date/style-rtl.css 72 B
build/styles/block-library/comment-date/style-rtl.min.css 65 B
build/styles/block-library/comment-date/style.css 72 B
build/styles/block-library/comment-date/style.min.css 65 B
build/styles/block-library/comment-edit-link/style-rtl.css 77 B
build/styles/block-library/comment-edit-link/style-rtl.min.css 70 B
build/styles/block-library/comment-edit-link/style.css 77 B
build/styles/block-library/comment-edit-link/style.min.css 70 B
build/styles/block-library/comment-reply-link/style-rtl.css 78 B
build/styles/block-library/comment-reply-link/style-rtl.min.css 71 B
build/styles/block-library/comment-reply-link/style.css 78 B
build/styles/block-library/comment-reply-link/style.min.css 71 B
build/styles/block-library/comment-template/style-rtl.css 213 B
build/styles/block-library/comment-template/style-rtl.min.css 191 B
build/styles/block-library/comment-template/style.css 213 B
build/styles/block-library/comment-template/style.min.css 191 B
build/styles/block-library/comments-pagination-numbers/editor-rtl.css 135 B
build/styles/block-library/comments-pagination-numbers/editor-rtl.min.css 122 B
build/styles/block-library/comments-pagination-numbers/editor.css 144 B
build/styles/block-library/comments-pagination-numbers/editor.min.css 121 B
build/styles/block-library/comments-pagination/editor-rtl.css 184 B
build/styles/block-library/comments-pagination/editor-rtl.min.css 168 B
build/styles/block-library/comments-pagination/editor.css 184 B
build/styles/block-library/comments-pagination/editor.min.css 168 B
build/styles/block-library/comments-pagination/style-rtl.css 224 B
build/styles/block-library/comments-pagination/style-rtl.min.css 201 B
build/styles/block-library/comments-pagination/style.css 236 B
build/styles/block-library/comments-pagination/style.min.css 201 B
build/styles/block-library/comments-title/editor-rtl.css 83 B
build/styles/block-library/comments-title/editor-rtl.min.css 75 B
build/styles/block-library/comments-title/editor.css 83 B
build/styles/block-library/comments-title/editor.min.css 75 B
build/styles/block-library/comments/editor-rtl.css 968 B
build/styles/block-library/comments/editor-rtl.min.css 842 B
build/styles/block-library/comments/editor.css 968 B
build/styles/block-library/comments/editor.min.css 842 B
build/styles/block-library/comments/style-rtl.css 754 B
build/styles/block-library/comments/style-rtl.min.css 637 B
build/styles/block-library/comments/style.css 752 B
build/styles/block-library/comments/style.min.css 637 B
build/styles/block-library/common-rtl.css 2.48 kB
build/styles/block-library/common-rtl.min.css 1.12 kB
build/styles/block-library/common.css 2.5 kB
build/styles/block-library/common.min.css 1.12 kB
build/styles/block-library/cover/editor-rtl.css 1.05 kB
build/styles/block-library/cover/editor-rtl.min.css 631 B
build/styles/block-library/cover/editor.css 1.05 kB
build/styles/block-library/cover/editor.min.css 631 B
build/styles/block-library/cover/style-rtl.css 2.5 kB
build/styles/block-library/cover/style-rtl.min.css 1.82 kB
build/styles/block-library/cover/style.css 2.51 kB
build/styles/block-library/cover/style.min.css 1.81 kB
build/styles/block-library/details/editor-rtl.css 72 B
build/styles/block-library/details/editor-rtl.min.css 65 B
build/styles/block-library/details/editor.css 72 B
build/styles/block-library/details/editor.min.css 65 B
build/styles/block-library/details/style-rtl.css 97 B
build/styles/block-library/details/style-rtl.min.css 86 B
build/styles/block-library/details/style.css 97 B
build/styles/block-library/details/style.min.css 86 B
build/styles/block-library/editor-elements-rtl.css 117 B
build/styles/block-library/editor-elements-rtl.min.css 75 B
build/styles/block-library/editor-elements.css 117 B
build/styles/block-library/editor-elements.min.css 75 B
build/styles/block-library/editor-rtl.css 12.5 kB
build/styles/block-library/editor-rtl.min.css 10.3 kB
build/styles/block-library/editor.css 12.5 kB
build/styles/block-library/editor.min.css 10.3 kB
build/styles/block-library/elements-rtl.css 84 B
build/styles/block-library/elements-rtl.min.css 54 B
build/styles/block-library/elements.css 84 B
build/styles/block-library/elements.min.css 54 B
build/styles/block-library/embed/editor-rtl.css 391 B
build/styles/block-library/embed/editor-rtl.min.css 331 B
build/styles/block-library/embed/editor.css 390 B
build/styles/block-library/embed/editor.min.css 331 B
build/styles/block-library/embed/style-rtl.css 1.29 kB
build/styles/block-library/embed/style-rtl.min.css 448 B
build/styles/block-library/embed/style.css 1.29 kB
build/styles/block-library/embed/style.min.css 448 B
build/styles/block-library/embed/theme-rtl.css 967 B
build/styles/block-library/embed/theme-rtl.min.css 133 B
build/styles/block-library/embed/theme.css 967 B
build/styles/block-library/embed/theme.min.css 133 B
build/styles/block-library/file/editor-rtl.css 352 B
build/styles/block-library/file/editor-rtl.min.css 324 B
build/styles/block-library/file/editor.css 353 B
build/styles/block-library/file/editor.min.css 324 B
build/styles/block-library/file/style-rtl.css 318 B
build/styles/block-library/file/style-rtl.min.css 278 B
build/styles/block-library/file/style.css 331 B
build/styles/block-library/file/style.min.css 278 B
build/styles/block-library/footnotes/style-rtl.css 220 B
build/styles/block-library/footnotes/style-rtl.min.css 198 B
build/styles/block-library/footnotes/style.css 219 B
build/styles/block-library/footnotes/style.min.css 197 B
build/styles/block-library/form-input/editor-rtl.css 286 B
build/styles/block-library/form-input/editor-rtl.min.css 265 B
build/styles/block-library/form-input/editor.css 285 B
build/styles/block-library/form-input/editor.min.css 264 B
build/styles/block-library/form-input/style-rtl.css 467 B
build/styles/block-library/form-input/style-rtl.min.css 366 B
build/styles/block-library/form-input/style.css 467 B
build/styles/block-library/form-input/style.min.css 366 B
build/styles/block-library/form-submission-notification/editor-rtl.css 368 B
build/styles/block-library/form-submission-notification/editor-rtl.min.css 344 B
build/styles/block-library/form-submission-notification/editor.css 368 B
build/styles/block-library/form-submission-notification/editor.min.css 341 B
build/styles/block-library/form-submit-button/style-rtl.css 77 B
build/styles/block-library/form-submit-button/style-rtl.min.css 69 B
build/styles/block-library/form-submit-button/style.css 77 B
build/styles/block-library/form-submit-button/style.min.css 69 B
build/styles/block-library/freeform/editor-rtl.css 1.12 kB
build/styles/block-library/freeform/editor-rtl.min.css 288 B
build/styles/block-library/freeform/editor.css 1.12 kB
build/styles/block-library/freeform/editor.min.css 288 B
build/styles/block-library/gallery/editor-rtl.css 1.52 kB
build/styles/block-library/gallery/editor-rtl.min.css 615 B
build/styles/block-library/gallery/editor.css 1.52 kB
build/styles/block-library/gallery/editor.min.css 616 B
build/styles/block-library/gallery/style-rtl.css 2.84 kB
build/styles/block-library/gallery/style-rtl.min.css 1.84 kB
build/styles/block-library/gallery/style.css 2.84 kB
build/styles/block-library/gallery/style.min.css 1.84 kB
build/styles/block-library/gallery/theme-rtl.css 941 B
build/styles/block-library/gallery/theme-rtl.min.css 108 B
build/styles/block-library/gallery/theme.css 941 B
build/styles/block-library/gallery/theme.min.css 108 B
build/styles/block-library/group/editor-rtl.css 772 B
build/styles/block-library/group/editor-rtl.min.css 335 B
build/styles/block-library/group/editor.css 772 B
build/styles/block-library/group/editor.min.css 335 B
build/styles/block-library/group/style-rtl.css 120 B
build/styles/block-library/group/style-rtl.min.css 103 B
build/styles/block-library/group/style.css 120 B
build/styles/block-library/group/style.min.css 103 B
build/styles/block-library/group/theme-rtl.css 468 B
build/styles/block-library/group/theme-rtl.min.css 79 B
build/styles/block-library/group/theme.css 468 B
build/styles/block-library/group/theme.min.css 79 B
build/styles/block-library/heading/style-rtl.css 604 B
build/styles/block-library/heading/style-rtl.min.css 205 B
build/styles/block-library/heading/style.css 604 B
build/styles/block-library/heading/style.min.css 205 B
build/styles/block-library/html/editor-rtl.css 1.29 kB
build/styles/block-library/html/editor-rtl.min.css 464 B
build/styles/block-library/html/editor.css 1.3 kB
build/styles/block-library/html/editor.min.css 464 B
build/styles/block-library/icon/editor-rtl.css 776 B
build/styles/block-library/icon/editor-rtl.min.css 377 B
build/styles/block-library/icon/editor.css 776 B
build/styles/block-library/icon/editor.min.css 377 B
build/styles/block-library/icon/style-rtl.css 218 B
build/styles/block-library/icon/style-rtl.min.css 154 B
build/styles/block-library/icon/style.css 218 B
build/styles/block-library/icon/style.min.css 154 B
build/styles/block-library/image/editor-rtl.css 1.64 kB
build/styles/block-library/image/editor-rtl.min.css 782 B
build/styles/block-library/image/editor.css 1.64 kB
build/styles/block-library/image/editor.min.css 780 B
build/styles/block-library/image/style-rtl.css 2.92 kB
build/styles/block-library/image/style-rtl.min.css 1.86 kB
build/styles/block-library/image/style.css 2.92 kB
build/styles/block-library/image/style.min.css 1.85 kB
build/styles/block-library/image/theme-rtl.css 971 B
build/styles/block-library/image/theme-rtl.min.css 137 B
build/styles/block-library/image/theme.css 971 B
build/styles/block-library/image/theme.min.css 137 B
build/styles/block-library/latest-comments/style-rtl.css 392 B
build/styles/block-library/latest-comments/style-rtl.min.css 352 B
build/styles/block-library/latest-comments/style.css 390 B
build/styles/block-library/latest-comments/style.min.css 352 B
build/styles/block-library/latest-posts/editor-rtl.css 154 B
build/styles/block-library/latest-posts/editor-rtl.min.css 139 B
build/styles/block-library/latest-posts/editor.css 153 B
build/styles/block-library/latest-posts/editor.min.css 138 B
build/styles/block-library/latest-posts/style-rtl.css 1.36 kB
build/styles/block-library/latest-posts/style-rtl.min.css 520 B
build/styles/block-library/latest-posts/style.css 1.37 kB
build/styles/block-library/latest-posts/style.min.css 520 B
build/styles/block-library/list/style-rtl.css 498 B
build/styles/block-library/list/style-rtl.min.css 107 B
build/styles/block-library/list/style.css 498 B
build/styles/block-library/list/style.min.css 107 B
build/styles/block-library/loginout/style-rtl.css 68 B
build/styles/block-library/loginout/style-rtl.min.css 61 B
build/styles/block-library/loginout/style.css 68 B
build/styles/block-library/loginout/style.min.css 61 B
build/styles/block-library/math/editor-rtl.css 491 B
build/styles/block-library/math/editor-rtl.min.css 105 B
build/styles/block-library/math/editor.css 502 B
build/styles/block-library/math/editor.min.css 105 B
build/styles/block-library/math/style-rtl.css 70 B
build/styles/block-library/math/style-rtl.min.css 61 B
build/styles/block-library/math/style.css 70 B
build/styles/block-library/math/style.min.css 61 B
build/styles/block-library/media-text/editor-rtl.css 389 B
build/styles/block-library/media-text/editor-rtl.min.css 321 B
build/styles/block-library/media-text/editor.css 389 B
build/styles/block-library/media-text/editor.min.css 320 B
build/styles/block-library/media-text/style-rtl.css 873 B
build/styles/block-library/media-text/style-rtl.min.css 552 B
build/styles/block-library/media-text/style.css 901 B
build/styles/block-library/media-text/style.min.css 550 B
build/styles/block-library/more/editor-rtl.css 796 B
build/styles/block-library/more/editor-rtl.min.css 393 B
build/styles/block-library/more/editor.css 798 B
build/styles/block-library/more/editor.min.css 393 B
build/styles/block-library/navigation-link/editor-rtl.css 1.28 kB
build/styles/block-library/navigation-link/editor-rtl.min.css 710 B
build/styles/block-library/navigation-link/editor.css 1.27 kB
build/styles/block-library/navigation-link/editor.min.css 713 B
build/styles/block-library/navigation-link/style-rtl.css 579 B
build/styles/block-library/navigation-link/style-rtl.min.css 190 B
build/styles/block-library/navigation-link/style.css 579 B
build/styles/block-library/navigation-link/style.min.css 188 B
build/styles/block-library/navigation-overlay-close/style-rtl.css 260 B
build/styles/block-library/navigation-overlay-close/style-rtl.min.css 237 B
build/styles/block-library/navigation-overlay-close/style.css 260 B
build/styles/block-library/navigation-overlay-close/style.min.css 237 B
build/styles/block-library/navigation-submenu/editor-rtl.css 1.12 kB
build/styles/block-library/navigation-submenu/editor-rtl.min.css 295 B
build/styles/block-library/navigation-submenu/editor.css 1.12 kB
build/styles/block-library/navigation-submenu/editor.min.css 294 B
build/styles/block-library/navigation/editor-rtl.css 3.28 kB
build/styles/block-library/navigation/editor-rtl.min.css 2.28 kB
build/styles/block-library/navigation/editor.css 3.29 kB
build/styles/block-library/navigation/editor.min.css 2.28 kB
build/styles/block-library/navigation/style-rtl.css 3.59 kB
build/styles/block-library/navigation/style-rtl.min.css 2.52 kB
build/styles/block-library/navigation/style.css 3.59 kB
build/styles/block-library/navigation/style.min.css 2.5 kB
build/styles/block-library/nextpage/editor-rtl.css 799 B
build/styles/block-library/nextpage/editor-rtl.min.css 392 B
build/styles/block-library/nextpage/editor.css 800 B
build/styles/block-library/nextpage/editor.min.css 392 B
build/styles/block-library/page-list/editor-rtl.css 1.18 kB
build/styles/block-library/page-list/editor-rtl.min.css 356 B
build/styles/block-library/page-list/editor.css 1.18 kB
build/styles/block-library/page-list/editor.min.css 356 B
build/styles/block-library/page-list/style-rtl.css 207 B
build/styles/block-library/page-list/style-rtl.min.css 192 B
build/styles/block-library/page-list/style.css 207 B
build/styles/block-library/page-list/style.min.css 192 B
build/styles/block-library/paragraph/editor-rtl.css 315 B
build/styles/block-library/paragraph/editor-rtl.min.css 292 B
build/styles/block-library/paragraph/editor.css 314 B
build/styles/block-library/paragraph/editor.min.css 292 B
build/styles/block-library/paragraph/style-rtl.css 746 B
build/styles/block-library/paragraph/style-rtl.min.css 341 B
build/styles/block-library/paragraph/style.css 752 B
build/styles/block-library/paragraph/style.min.css 340 B
build/styles/block-library/playlist-track/style-rtl.css 453 B
build/styles/block-library/playlist-track/style-rtl.min.css 420 B
build/styles/block-library/playlist-track/style.css 453 B
build/styles/block-library/playlist-track/style.min.css 420 B
build/styles/block-library/playlist/editor-rtl.css 120 B
build/styles/block-library/playlist/editor-rtl.min.css 112 B
build/styles/block-library/playlist/editor.css 120 B
build/styles/block-library/playlist/editor.min.css 112 B
build/styles/block-library/playlist/style-rtl.css 1.52 kB
build/styles/block-library/playlist/style-rtl.min.css 1.42 kB
build/styles/block-library/playlist/style.css 1.52 kB
build/styles/block-library/playlist/style.min.css 1.42 kB
build/styles/block-library/post-author-biography/style-rtl.css 96 B
build/styles/block-library/post-author-biography/style-rtl.min.css 86 B
build/styles/block-library/post-author-biography/style.css 96 B
build/styles/block-library/post-author-biography/style.min.css 86 B
build/styles/block-library/post-author-name/style-rtl.css 76 B
build/styles/block-library/post-author-name/style-rtl.min.css 69 B
build/styles/block-library/post-author-name/style.css 76 B
build/styles/block-library/post-author-name/style.min.css 69 B
build/styles/block-library/post-author/editor-rtl.css 490 B
build/styles/block-library/post-author/editor-rtl.min.css 104 B
build/styles/block-library/post-author/editor.css 490 B
build/styles/block-library/post-author/editor.min.css 104 B
build/styles/block-library/post-author/style-rtl.css 213 B
build/styles/block-library/post-author/style-rtl.min.css 188 B
build/styles/block-library/post-author/style.css 214 B
build/styles/block-library/post-author/style.min.css 189 B
build/styles/block-library/post-comments-count/style-rtl.css 79 B
build/styles/block-library/post-comments-count/style-rtl.min.css 72 B
build/styles/block-library/post-comments-count/style.css 79 B
build/styles/block-library/post-comments-count/style.min.css 72 B
build/styles/block-library/post-comments-form/editor-rtl.css 104 B
build/styles/block-library/post-comments-form/editor-rtl.min.css 96 B
build/styles/block-library/post-comments-form/editor.css 104 B
build/styles/block-library/post-comments-form/editor.min.css 96 B
build/styles/block-library/post-comments-form/style-rtl.css 585 B
build/styles/block-library/post-comments-form/style-rtl.min.css 525 B
build/styles/block-library/post-comments-form/style.css 584 B
build/styles/block-library/post-comments-form/style.min.css 525 B
build/styles/block-library/post-comments-link/style-rtl.css 78 B
build/styles/block-library/post-comments-link/style-rtl.min.css 71 B
build/styles/block-library/post-comments-link/style.css 78 B
build/styles/block-library/post-comments-link/style.min.css 71 B
build/styles/block-library/post-content/style-rtl.css 68 B
build/styles/block-library/post-content/style-rtl.min.css 61 B
build/styles/block-library/post-content/style.css 68 B
build/styles/block-library/post-content/style.min.css 61 B
build/styles/block-library/post-date/style-rtl.css 69 B
build/styles/block-library/post-date/style-rtl.min.css 62 B
build/styles/block-library/post-date/style.css 69 B
build/styles/block-library/post-date/style.min.css 62 B
build/styles/block-library/post-excerpt/editor-rtl.css 78 B
build/styles/block-library/post-excerpt/editor-rtl.min.css 71 B
build/styles/block-library/post-excerpt/editor.css 78 B
build/styles/block-library/post-excerpt/editor.min.css 71 B
build/styles/block-library/post-excerpt/style-rtl.css 171 B
build/styles/block-library/post-excerpt/style-rtl.min.css 155 B
build/styles/block-library/post-excerpt/style.css 171 B
build/styles/block-library/post-excerpt/style.min.css 155 B
build/styles/block-library/post-featured-image/editor-rtl.css 1.14 kB
build/styles/block-library/post-featured-image/editor-rtl.min.css 719 B
build/styles/block-library/post-featured-image/editor.css 1.14 kB
build/styles/block-library/post-featured-image/editor.min.css 717 B
build/styles/block-library/post-featured-image/style-rtl.css 392 B
build/styles/block-library/post-featured-image/style-rtl.min.css 347 B
build/styles/block-library/post-featured-image/style.css 392 B
build/styles/block-library/post-featured-image/style.min.css 347 B
build/styles/block-library/post-navigation-link/style-rtl.css 234 B
build/styles/block-library/post-navigation-link/style-rtl.min.css 215 B
build/styles/block-library/post-navigation-link/style.css 245 B
build/styles/block-library/post-navigation-link/style.min.css 214 B
build/styles/block-library/post-template/style-rtl.css 1.27 kB
build/styles/block-library/post-template/style-rtl.min.css 441 B
build/styles/block-library/post-template/style.css 1.27 kB
build/styles/block-library/post-template/style.min.css 441 B
build/styles/block-library/post-terms/style-rtl.css 108 B
build/styles/block-library/post-terms/style-rtl.min.css 96 B
build/styles/block-library/post-terms/style.css 108 B
build/styles/block-library/post-terms/style.min.css 96 B
build/styles/block-library/post-time-to-read/style-rtl.css 77 B
build/styles/block-library/post-time-to-read/style-rtl.min.css 70 B
build/styles/block-library/post-time-to-read/style.css 77 B
build/styles/block-library/post-time-to-read/style.min.css 70 B
build/styles/block-library/post-title/style-rtl.css 175 B
build/styles/block-library/post-title/style-rtl.min.css 162 B
build/styles/block-library/post-title/style.css 175 B
build/styles/block-library/post-title/style.min.css 162 B
build/styles/block-library/preformatted/style-rtl.css 511 B
build/styles/block-library/preformatted/style-rtl.min.css 125 B
build/styles/block-library/preformatted/style.css 511 B
build/styles/block-library/preformatted/style.min.css 125 B
build/styles/block-library/pullquote/editor-rtl.css 146 B
build/styles/block-library/pullquote/editor-rtl.min.css 133 B
build/styles/block-library/pullquote/editor.css 146 B
build/styles/block-library/pullquote/editor.min.css 133 B
build/styles/block-library/pullquote/style-rtl.css 765 B
build/styles/block-library/pullquote/style-rtl.min.css 365 B
build/styles/block-library/pullquote/style.css 764 B
build/styles/block-library/pullquote/style.min.css 365 B
build/styles/block-library/pullquote/theme-rtl.css 195 B
build/styles/block-library/pullquote/theme-rtl.min.css 176 B
build/styles/block-library/pullquote/theme.css 195 B
build/styles/block-library/pullquote/theme.min.css 176 B
build/styles/block-library/query-pagination-numbers/editor-rtl.css 134 B
build/styles/block-library/query-pagination-numbers/editor-rtl.min.css 121 B
build/styles/block-library/query-pagination-numbers/editor.css 144 B
build/styles/block-library/query-pagination-numbers/editor.min.css 118 B
build/styles/block-library/query-pagination/editor-rtl.css 168 B
build/styles/block-library/query-pagination/editor-rtl.min.css 154 B
build/styles/block-library/query-pagination/editor.css 168 B
build/styles/block-library/query-pagination/editor.min.css 154 B
build/styles/block-library/query-pagination/style-rtl.css 254 B
build/styles/block-library/query-pagination/style-rtl.min.css 237 B
build/styles/block-library/query-pagination/style.css 265 B
build/styles/block-library/query-pagination/style.min.css 237 B
build/styles/block-library/query-title/style-rtl.css 71 B
build/styles/block-library/query-title/style-rtl.min.css 64 B
build/styles/block-library/query-title/style.css 71 B
build/styles/block-library/query-title/style.min.css 64 B
build/styles/block-library/query-total/style-rtl.css 71 B
build/styles/block-library/query-total/style-rtl.min.css 64 B
build/styles/block-library/query-total/style.css 71 B
build/styles/block-library/query-total/style.min.css 64 B
build/styles/block-library/query/editor-rtl.css 1.28 kB
build/styles/block-library/query/editor-rtl.min.css 438 B
build/styles/block-library/query/editor.css 1.28 kB
build/styles/block-library/query/editor.min.css 438 B
build/styles/block-library/quote/style-rtl.css 255 B
build/styles/block-library/quote/style-rtl.min.css 238 B
build/styles/block-library/quote/style.css 256 B
build/styles/block-library/quote/style.min.css 238 B
build/styles/block-library/quote/theme-rtl.css 253 B
build/styles/block-library/quote/theme-rtl.min.css 233 B
build/styles/block-library/quote/theme.css 254 B
build/styles/block-library/quote/theme.min.css 236 B
build/styles/block-library/read-more/style-rtl.css 146 B
build/styles/block-library/read-more/style-rtl.min.css 131 B
build/styles/block-library/read-more/style.css 146 B
build/styles/block-library/read-more/style.min.css 131 B
build/styles/block-library/reset-rtl.css 936 B
build/styles/block-library/reset-rtl.min.css 467 B
build/styles/block-library/reset.css 936 B
build/styles/block-library/reset.min.css 467 B
build/styles/block-library/rss/editor-rtl.css 144 B
build/styles/block-library/rss/editor-rtl.min.css 126 B
build/styles/block-library/rss/editor.css 144 B
build/styles/block-library/rss/editor.min.css 126 B
build/styles/block-library/rss/style-rtl.css 1.11 kB
build/styles/block-library/rss/style-rtl.min.css 284 B
build/styles/block-library/rss/style.css 1.12 kB
build/styles/block-library/rss/style.min.css 283 B
build/styles/block-library/search/editor-rtl.css 217 B
build/styles/block-library/search/editor-rtl.min.css 199 B
build/styles/block-library/search/editor.css 217 B
build/styles/block-library/search/editor.min.css 199 B
build/styles/block-library/search/style-rtl.css 1.1 kB
build/styles/block-library/search/style-rtl.min.css 665 B
build/styles/block-library/search/style.css 1.1 kB
build/styles/block-library/search/style.min.css 666 B
build/styles/block-library/search/theme-rtl.css 130 B
build/styles/block-library/search/theme-rtl.min.css 113 B
build/styles/block-library/search/theme.css 130 B
build/styles/block-library/search/theme.min.css 113 B
build/styles/block-library/separator/editor-rtl.css 106 B
build/styles/block-library/separator/editor-rtl.min.css 100 B
build/styles/block-library/separator/editor.css 106 B
build/styles/block-library/separator/editor.min.css 100 B
build/styles/block-library/separator/style-rtl.css 284 B
build/styles/block-library/separator/style-rtl.min.css 248 B
build/styles/block-library/separator/style.css 297 B
build/styles/block-library/separator/style.min.css 248 B
build/styles/block-library/separator/theme-rtl.css 226 B
build/styles/block-library/separator/theme-rtl.min.css 195 B
build/styles/block-library/separator/theme.css 226 B
build/styles/block-library/separator/theme.min.css 195 B
build/styles/block-library/shortcode/editor-rtl.css 1.1 kB
build/styles/block-library/shortcode/editor-rtl.min.css 286 B
build/styles/block-library/shortcode/editor.css 1.1 kB
build/styles/block-library/shortcode/editor.min.css 286 B
build/styles/block-library/site-logo/editor-rtl.css 1.12 kB
build/styles/block-library/site-logo/editor-rtl.min.css 696 B
build/styles/block-library/site-logo/editor.css 1.12 kB
build/styles/block-library/site-logo/editor.min.css 692 B
build/styles/block-library/site-logo/style-rtl.css 239 B
build/styles/block-library/site-logo/style-rtl.min.css 218 B
build/styles/block-library/site-logo/style.css 238 B
build/styles/block-library/site-logo/style.min.css 218 B
build/styles/block-library/site-tagline/editor-rtl.css 94 B
build/styles/block-library/site-tagline/editor-rtl.min.css 87 B
build/styles/block-library/site-tagline/editor.css 94 B
build/styles/block-library/site-tagline/editor.min.css 87 B
build/styles/block-library/site-tagline/style-rtl.css 72 B
build/styles/block-library/site-tagline/style-rtl.min.css 65 B
build/styles/block-library/site-tagline/style.css 72 B
build/styles/block-library/site-tagline/style.min.css 65 B
build/styles/block-library/site-title/editor-rtl.css 93 B
build/styles/block-library/site-title/editor-rtl.min.css 85 B
build/styles/block-library/site-title/editor.css 93 B
build/styles/block-library/site-title/editor.min.css 85 B
build/styles/block-library/site-title/style-rtl.css 153 B
build/styles/block-library/site-title/style-rtl.min.css 143 B
build/styles/block-library/site-title/style.css 153 B
build/styles/block-library/site-title/style.min.css 143 B
build/styles/block-library/social-link/editor-rtl.css 346 B
build/styles/block-library/social-link/editor-rtl.min.css 314 B
build/styles/block-library/social-link/editor.css 348 B
build/styles/block-library/social-link/editor.min.css 314 B
build/styles/block-library/social-links/editor-rtl.css 737 B
build/styles/block-library/social-links/editor-rtl.min.css 339 B
build/styles/block-library/social-links/editor.css 738 B
build/styles/block-library/social-links/editor.min.css 338 B
build/styles/block-library/social-links/style-rtl.css 1.57 kB
build/styles/block-library/social-links/style-rtl.min.css 1.51 kB
build/styles/block-library/social-links/style.css 1.57 kB
build/styles/block-library/social-links/style.min.css 1.51 kB
build/styles/block-library/spacer/editor-rtl.css 774 B
build/styles/block-library/spacer/editor-rtl.min.css 346 B
build/styles/block-library/spacer/editor.css 774 B
build/styles/block-library/spacer/editor.min.css 346 B
build/styles/block-library/spacer/style-rtl.css 55 B
build/styles/block-library/spacer/style-rtl.min.css 48 B
build/styles/block-library/spacer/style.css 55 B
build/styles/block-library/spacer/style.min.css 48 B
build/styles/block-library/style-rtl.css 21.5 kB
build/styles/block-library/style-rtl.min.css 18 kB
build/styles/block-library/style.css 21.6 kB
build/styles/block-library/style.min.css 18 kB
build/styles/block-library/tab-list/editor-rtl.css 107 B
build/styles/block-library/tab-list/editor-rtl.min.css 97 B
build/styles/block-library/tab-list/editor.css 107 B
build/styles/block-library/tab-list/editor.min.css 97 B
build/styles/block-library/tab-panel/style-rtl.css 238 B
build/styles/block-library/tab-panel/style-rtl.min.css 215 B
build/styles/block-library/tab-panel/style.css 238 B
build/styles/block-library/tab-panel/style.min.css 215 B
build/styles/block-library/tab-panels/style-rtl.css 76 B
build/styles/block-library/tab-panels/style-rtl.min.css 65 B
build/styles/block-library/tab-panels/style.css 76 B
build/styles/block-library/tab-panels/style.min.css 65 B
build/styles/block-library/tab/editor-rtl.css 160 B
build/styles/block-library/tab/editor-rtl.min.css 148 B
build/styles/block-library/tab/editor.css 160 B
build/styles/block-library/tab/editor.min.css 148 B
build/styles/block-library/tab/style-rtl.css 397 B
build/styles/block-library/tab/style-rtl.min.css 352 B
build/styles/block-library/tab/style.css 398 B
build/styles/block-library/tab/style.min.css 356 B
build/styles/block-library/table-of-contents/style-rtl.css 89 B
build/styles/block-library/table-of-contents/style-rtl.min.css 83 B
build/styles/block-library/table-of-contents/style.css 89 B
build/styles/block-library/table-of-contents/style.min.css 83 B
build/styles/block-library/table/editor-rtl.css 1.25 kB
build/styles/block-library/table/editor-rtl.min.css 394 B
build/styles/block-library/table/editor.css 1.25 kB
build/styles/block-library/table/editor.min.css 394 B
build/styles/block-library/table/style-rtl.css 1.06 kB
build/styles/block-library/table/style-rtl.min.css 641 B
build/styles/block-library/table/style.css 1.06 kB
build/styles/block-library/table/style.min.css 640 B
build/styles/block-library/table/theme-rtl.css 985 B
build/styles/block-library/table/theme-rtl.min.css 152 B
build/styles/block-library/table/theme.css 985 B
build/styles/block-library/table/theme.min.css 152 B
build/styles/block-library/tabs/style-rtl.css 64 B
build/styles/block-library/tabs/style-rtl.min.css 57 B
build/styles/block-library/tabs/style.css 64 B
build/styles/block-library/tabs/style.min.css 57 B
build/styles/block-library/tag-cloud/style-rtl.css 283 B
build/styles/block-library/tag-cloud/style-rtl.min.css 248 B
build/styles/block-library/tag-cloud/style.css 283 B
build/styles/block-library/tag-cloud/style.min.css 248 B
build/styles/block-library/template-part/editor-rtl.css 1.2 kB
build/styles/block-library/template-part/editor-rtl.min.css 368 B
build/styles/block-library/template-part/editor.css 1.2 kB
build/styles/block-library/template-part/editor.min.css 368 B
build/styles/block-library/template-part/theme-rtl.css 492 B
build/styles/block-library/template-part/theme-rtl.min.css 113 B
build/styles/block-library/template-part/theme.css 492 B
build/styles/block-library/template-part/theme.min.css 113 B
build/styles/block-library/term-count/style-rtl.css 70 B
build/styles/block-library/term-count/style-rtl.min.css 63 B
build/styles/block-library/term-count/style.css 70 B
build/styles/block-library/term-count/style.min.css 63 B
build/styles/block-library/term-description/style-rtl.css 138 B
build/styles/block-library/term-description/style-rtl.min.css 126 B
build/styles/block-library/term-description/style.css 138 B
build/styles/block-library/term-description/style.min.css 126 B
build/styles/block-library/term-name/style-rtl.css 69 B
build/styles/block-library/term-name/style-rtl.min.css 62 B
build/styles/block-library/term-name/style.css 69 B
build/styles/block-library/term-name/style.min.css 62 B
build/styles/block-library/term-template/editor-rtl.css 267 B
build/styles/block-library/term-template/editor-rtl.min.css 225 B
build/styles/block-library/term-template/editor.css 267 B
build/styles/block-library/term-template/editor.min.css 225 B
build/styles/block-library/term-template/style-rtl.css 124 B
build/styles/block-library/term-template/style-rtl.min.css 114 B
build/styles/block-library/term-template/style.css 124 B
build/styles/block-library/term-template/style.min.css 114 B
build/styles/block-library/text-columns/editor-rtl.css 481 B
build/styles/block-library/text-columns/editor-rtl.min.css 95 B
build/styles/block-library/text-columns/editor.css 481 B
build/styles/block-library/text-columns/editor.min.css 95 B
build/styles/block-library/text-columns/style-rtl.css 177 B
build/styles/block-library/text-columns/style-rtl.min.css 165 B
build/styles/block-library/text-columns/style.css 177 B
build/styles/block-library/text-columns/style.min.css 165 B
build/styles/block-library/theme-rtl.css 1.59 kB
build/styles/block-library/theme-rtl.min.css 715 B
build/styles/block-library/theme.css 1.6 kB
build/styles/block-library/theme.min.css 719 B
build/styles/block-library/verse/style-rtl.css 155 B
build/styles/block-library/verse/style-rtl.min.css 137 B
build/styles/block-library/verse/style.css 155 B
build/styles/block-library/verse/style.min.css 137 B
build/styles/block-library/video/editor-rtl.css 839 B
build/styles/block-library/video/editor-rtl.min.css 428 B
build/styles/block-library/video/editor.css 840 B
build/styles/block-library/video/editor.min.css 428 B
build/styles/block-library/video/style-rtl.css 1.02 kB
build/styles/block-library/video/style-rtl.min.css 202 B
build/styles/block-library/video/style.css 1.02 kB
build/styles/block-library/video/style.min.css 202 B
build/styles/block-library/video/theme-rtl.css 967 B
build/styles/block-library/video/theme-rtl.min.css 134 B
build/styles/block-library/video/theme.css 967 B
build/styles/block-library/video/theme.min.css 134 B
build/styles/commands/style-rtl.css 2.07 kB
build/styles/commands/style-rtl.min.css 1.17 kB
build/styles/commands/style.css 2.06 kB
build/styles/commands/style.min.css 1.17 kB
build/styles/components/style-rtl.css 17.5 kB
build/styles/components/style-rtl.min.css 14.3 kB
build/styles/components/style.css 17.6 kB
build/styles/components/style.min.css 14.3 kB
build/styles/customize-widgets/style-rtl.css 2.35 kB
build/styles/customize-widgets/style-rtl.min.css 1.44 kB
build/styles/customize-widgets/style.css 2.35 kB
build/styles/customize-widgets/style.min.css 1.44 kB
build/styles/edit-post/classic-rtl.css 1.29 kB
build/styles/edit-post/classic-rtl.min.css 425 B
build/styles/edit-post/classic.css 1.31 kB
build/styles/edit-post/classic.min.css 428 B
build/styles/edit-post/style-rtl.css 3.51 kB
build/styles/edit-post/style-rtl.min.css 2.21 kB
build/styles/edit-post/style.css 3.51 kB
build/styles/edit-post/style.min.css 2.21 kB
build/styles/edit-site/style-rtl.css 20.3 kB
build/styles/edit-site/style-rtl.min.css 16.5 kB
build/styles/edit-site/style.css 20.3 kB
build/styles/edit-site/style.min.css 16.5 kB
build/styles/edit-widgets/style-rtl.css 4.85 kB
build/styles/edit-widgets/style-rtl.min.css 3.52 kB
build/styles/edit-widgets/style.css 4.85 kB
build/styles/edit-widgets/style.min.css 3.52 kB
build/styles/editor/style-rtl.css 27.6 kB
build/styles/editor/style-rtl.min.css 23.2 kB
build/styles/editor/style.css 27.7 kB
build/styles/editor/style.min.css 23.2 kB
build/styles/format-library/style-rtl.css 735 B
build/styles/format-library/style-rtl.min.css 326 B
build/styles/format-library/style.css 746 B
build/styles/format-library/style.min.css 326 B
build/styles/list-reusable-blocks/style-rtl.css 1.07 kB
build/styles/list-reusable-blocks/style-rtl.min.css 250 B
build/styles/list-reusable-blocks/style.css 1.07 kB
build/styles/list-reusable-blocks/style.min.css 249 B
build/styles/media-utils/style-rtl.css 2.08 kB
build/styles/media-utils/style-rtl.min.css 1.17 kB
build/styles/media-utils/style.css 2.08 kB
build/styles/media-utils/style.min.css 1.17 kB
build/styles/nux/style-rtl.css 1.48 kB
build/styles/nux/style-rtl.min.css 622 B
build/styles/nux/style.css 1.5 kB
build/styles/nux/style.min.css 618 B
build/styles/patterns/style-rtl.css 1.46 kB
build/styles/patterns/style-rtl.min.css 611 B
build/styles/patterns/style.css 1.46 kB
build/styles/patterns/style.min.css 611 B
build/styles/preferences/style-rtl.css 1.26 kB
build/styles/preferences/style-rtl.min.css 415 B
build/styles/preferences/style.css 1.26 kB
build/styles/preferences/style.min.css 415 B
build/styles/reusable-blocks/style-rtl.css 1.11 kB
build/styles/reusable-blocks/style-rtl.min.css 275 B
build/styles/reusable-blocks/style.css 1.11 kB
build/styles/reusable-blocks/style.min.css 275 B
build/styles/widgets/style-rtl.css 2.05 kB
build/styles/widgets/style-rtl.min.css 1.16 kB
build/styles/widgets/style.css 2.06 kB
build/styles/widgets/style.min.css 1.16 kB

compressed-size-action

@adamsilverstein adamsilverstein changed the title Suggestions: Phase A — Register inline RichText format types Suggestions - show suggestions as inline previews May 1, 2026
@adamsilverstein adamsilverstein added the [Feature] Notes Phase 3 of the Gutenberg roadmap around block commenting label May 1, 2026
@adamsilverstein adamsilverstein self-assigned this May 1, 2026
@adamsilverstein adamsilverstein added the [Status] In Progress Tracking issues with work in progress label May 1, 2026
Phase A wired up the inline format types but no code applied them. This
adds the two helpers the overlay HOC needs to render proposed changes
inline:

- markContentDiff(baseline, proposed) returns marked HTML where deleted
  runs are wrapped in <del class="has-suggestion-deletion"> and added
  runs in <ins class="has-suggestion-addition">. Tokenization is the
  existing word-level wordDiff so we share a definition of "what counts
  as a change" with the sidebar diff.
- stripSuggestionMarks(marked) reverses the wrap so the overlay can
  store the proposed value rather than the marked rendering — without
  this, a re-edit through RichText would feed marked HTML back into the
  overlay and the next render would double up the marks.

Eleven new unit tests cover the round-trip, the three golden-path
scenarios (text addition, text deletion, mid-string replacement), an
inline format change ("world" -> "<strong>world</strong>"), and the
null/undefined edge cases the overlay can pass when an attribute is
introduced for the first time.
Wires markContentDiff and stripSuggestionMarks into withSuggestionOverlay
so RichText attributes like `content` render with the suggestion marks
visible in the editor canvas, not just in the sidebar summary.

- mergedAttributes now passes the proposed content through markContentDiff
  before handing it to BlockEdit, so deleted runs render with the red
  strikethrough and added runs render with the green underline + side-
  shadow defined in the existing CSS.
- wrappedSetAttributes strips suggestion marks from incoming payloads so
  RichText round-tripping the marked HTML back through onChange doesn't
  pile additional marks onto the next render.
- Marks are skipped while the block is selected so the user's caret is
  not fighting the value-prop reconciliation on every keystroke. They
  reappear as soon as focus moves elsewhere — a Docs-like end state that
  trades live feedback for a cursor that doesn't jump mid-word.
- RICH_TEXT_ATTRIBUTE_KEYS is intentionally narrow (just `content`) so
  primitive attribute changes (align, level, fontSize) keep flowing
  through the existing block-level outline rather than leaking HTML into
  string slots.

Seven new unit tests exercise the helpers directly; the existing HOC
tests continue to pass because the marking is gated on a selected block
and the test harness leaves block-editor unregistered (the useSelect
fallback returns true, so marks are skipped).
Three new playwright tests exercise the golden-path scenarios the PR
description promises:

- A trailing text addition lands in the paragraph wrapped in
  <ins class="has-suggestion-addition"> after the block deselects, so
  reviewers see the new word with the addition color treatment.
- A trailing text deletion (selected range backspaced) survives in the
  paragraph wrapped in <del class="has-suggestion-deletion"> so the
  reviewer can read what the suggester wants removed.
- Bolding a word renders the suggestion as
  <ins class="has-suggestion-addition"><strong>word</strong></ins>,
  keeping both the new format AND the addition treatment, with the
  pre-bold version surfacing as a paired <del> so the reviewer can see
  what changed.

Each test deselects the block via clearSelectedBlock() before asserting,
because withSuggestionOverlay deliberately skips marking while a block
is selected (avoiding RichText caret jumps during typing). The marks
appear once focus moves elsewhere — Docs-like end state without the
custom rendering pipeline.
@t-hamano t-hamano added the [Type] Enhancement A suggestion for improvement. label May 4, 2026
Update the suggest-mode JSDoc and inline comments so reviewers can read the
files top-down without cross-referencing the tracking issue.

- inline-formats.js: rewrite the registration docblock to describe the
  overlay HOC consumer; update markContentDiff to drop the stale
  golden-path-of-this-PR phrasing in favor of the v1 scenarios in #77867.
- index.js: barrel comment now points at the actual consumer rather than
  promising a future phase.
- with-suggestion-overlay.js: add a top-of-file architecture note tracing
  data flow from BlockEdit through the overlay to markContentDiff and back;
  promote isStringLike's intent to JSDoc; document mergeOverlayAttributes
  explicitly; explain the capture-baseline-on-first-write pattern; surface
  the isSelected short-circuit at the call site.
- test files: add header comments listing the contracts each suite covers
  (HOC pass-through, merge semantics, diff/strip round-trip).
- e2e spec: add a header naming the three golden-path scenarios; rename
  the scenario tests to 'add | delete | style' so they map 1:1 to the PR
  description bullets.

No behavior change.
@adamsilverstein
Copy link
Copy Markdown
Member Author

Plan to bring this PR in line with the canvas-treatment fixes that just landed on the structural-marker stack (#77979 and friends). Two independent improvements; both should land on this branch.

1. Relocate inline-format CSS so it reaches the canvas iframe

Problem. packages/editor/src/components/suggestion-mode/style.scss is part of the editor-package chrome stylesheet (wp-edit-blocks). The canvas iframe loads wp-block-editor-content (compiled from packages/block-editor/src/content.scss) but does NOT load editor-package chrome stylesheets. So .has-suggestion-deletion / .has-suggestion-addition rules will hit the DOM but no rule matches inside the iframe and the marks render unstyled.

This is the same bug the structural stack hit with is-suggestion-pending-*. The fix mirrors what landed in a84e306b:

  • Move the .has-suggestion-deletion and .has-suggestion-addition rule blocks out of packages/editor/src/components/suggestion-mode/style.scss.
  • Append them to packages/block-editor/src/components/block-list/content-suggestion.scss (the partial that already houses the canvas-side block-level suggestion rules — already imported from packages/block-editor/src/content.scss).
  • Leave any chrome-only sibling rules (sidebar diff colors etc.) where they are.

The class names describe a text visual state, so block-editor styling them does not violate package layering: it doesn't need to know how the format arrived, just how to render it.

2. Tint inline marks by suggester avatar color

Problem. Right now the deletion strikethrough is hard-coded red and the addition underline is hard-coded green-ish (--wp-admin-theme-color). When two suggesters edit the same document the reviewer can't tell their marks apart. The structural stack just adopted the same per-author tinting Google Docs uses — block-level pending markers now read in the suggester's avatar color (the same palette getAvatarBorderColor produces for live cursors and the collab-sidebar dot).

The pattern that landed in f7d03128:

\$suggestion-author-color: var(--suggestion-author-color, #{\$suggestion-color});
.is-suggestion-pending-remove { color: \$suggestion-author-color; ... }

The HOC writes --suggestion-author-color onto the wrapper from the marker's authorId. To do the equivalent for inline formats, the author has to ride along on each <del> / <ins> run — there's no block-level wrapper to hang it on, since marks live inside RichText.

Implementation sketch:

  • markContentDiff(baseline, proposed, authorId) (in inline-formats.js) accepts the suggester's user id; when wrapping a deletion / addition run, it emits the inline style on the tag itself:
    <del class=\"has-suggestion-deletion\" style=\"--suggestion-author-color: #b26200\">deleted text</del>
  • with-suggestion-overlay.js resolves the suggester's authorId from the overlay entry and the suggester's user id (via coreStore.getCurrentUser for own-edits, or the pending-suggestion's stored author for foreign edits) and passes it into markContentDiff.
  • getAvatarBorderColor( authorId ) (already imported in the structural HOC at packages/editor/src/components/collab-sidebar/utils.js) maps the id to a 7-color palette; reuse it here.
  • stripSuggestionMarks already removes the wrapping <del> / <ins> so the inline style attribute disappears with them on round-trip — no schema impact.
  • CSS becomes:
    .has-suggestion-deletion {
      color: var(--suggestion-author-color, #cc1818);
      text-decoration: line-through;
      text-decoration-color: var(--suggestion-author-color, #cc1818);
    }
    .has-suggestion-addition {
      color: var(--suggestion-author-color, #188038);
      text-decoration: underline;
      text-decoration-color: var(--suggestion-author-color, #188038);
      box-shadow: -1px 0 0 0 var(--suggestion-author-color, #188038);
    }
    Falls through to the existing red / green defaults when authorId is missing (anonymous or pre-collab sessions), so nothing changes for the single-suggester case.

Order of operations

  1. Land the relocation first — it's a single-file move and the existing red/green colors keep working through the var fallback.
  2. Add the authorId parameter to markContentDiff and the per-tag style writer.
  3. Wire authorId resolution in with-suggestion-overlay.js.
  4. Update unit tests in test/inline-formats.js to assert the inline-style propagation; update test/with-suggestion-overlay.js to assert that an overlay with a non-null author id produces marked HTML carrying the author color.
  5. E2E: add a multi-suggester scenario to suggestion-mode.spec.js that opens two browser contexts, makes a deletion and an addition from each, and asserts the rendered marks paint different colors.

Happy to take this on as a follow-up commit on this branch once the relocation goes in — let me know if you'd like me to push the change directly.

…ndle

The .has-suggestion-deletion / .has-suggestion-addition rules target
RichText runs that render inside the editor canvas iframe. Previously
they lived in the editor-package stylesheet (wp-edit-blocks), which is
not loaded into the iframe — only wp-block-editor-content (compiled from
block-editor/src/content.scss) is. As a result the inline marks landed
on the DOM but no rule matched, so deletions/additions rendered
unstyled.

Move the inline-format rules to a new partial under
block-editor/src/components/block-list/content-suggestion.scss and
include it from block-editor/src/content.scss. The class names describe
a text visual state, so block-editor styling them does not violate
package layering: the partial only knows how to render the marks, not
how the format arrived. Sidebar/diff/header rules stay in the editor
package since they target chrome surrounding the iframe rather than
RichText runs within it.

Add `--suggestion-author-color` as an opt-in CSS custom property on the
inline rules with the prior red/green pair as the fallback, so the
follow-up commit that pipes the suggester's avatar color through
`markContentDiff` can light it up without re-touching this file.
@adamsilverstein adamsilverstein requested a review from ellatrix as a code owner May 6, 2026 17:49
@github-actions github-actions Bot added the [Package] Block editor /packages/block-editor label May 6, 2026
Hardcoded red / theme-green make every suggester's marks look the same,
so reviewers can't tell two authors apart in the canvas. Pipe an
optional `authorColor` through `markContentDiff` and emit it as an
inline `style="--suggestion-author-color: …"` on each <del> / <ins>
run. The block-editor CSS partial already consumes the variable with
the previous red/green pair as the fallback, so anonymous /
pre-collab edits stay visually unchanged — single-suggester sessions
see no diff on the wire.

The author color rides on the wrapper element rather than on a
parent (there is no block-level wrapper available — marks live inside
RichText). `stripSuggestionMarks` already removes the wrapper on
accept / round-trip, so the inline `style` attribute disappears with
it; no schema impact.

Add unit coverage for the new parameter (color propagation, null/
undefined fallthrough, and the strip round-trip) so future changes to
the wrapper format don't silently drop the per-author tinting.
Resolve the current user id from `coreStore.getCurrentUser` and map it
through `getAvatarBorderColor` (the same palette `editor-collab-sidebar`
uses for live cursors). Forward the resulting hex through
`applyDiffMarks` into `markContentDiff` so each <del>/<ins> emitted in
the canvas carries `style="--suggestion-author-color: …"`. The
block-editor CSS partial already consumes the variable with the
red/green pair as the fallback, so anonymous edits keep the existing
default.

Folded into the existing `useSelect` so the HOC stays at one extra
store-subscription per block in suggest mode. `authorColor` flows
through `useMemo`'s dep list so the marked HTML re-renders the moment
a suggester logs in (or out) without forcing the whole tree.

Add a unit test for the propagation through `applyDiffMarks` so the
contract is enforced at the helper boundary, independent of how the
HOC resolves the color.
@adamsilverstein
Copy link
Copy Markdown
Member Author

Pushed both items on this branch — single-file diffs each, ordered as proposed:

  1. CSS relocation (905841f7cb5) — moved .has-suggestion-deletion / .has-suggestion-addition out of packages/editor/src/components/suggestion-mode/style.scss into a new packages/block-editor/src/components/block-list/content-suggestion.scss partial and registered it from block-editor/src/content.scss. The chrome-only .editor-collab-sidebar-panel__suggestion-text-diff rules stay in the editor package. The new partial pre-declares --suggestion-author-color with the previous red/green pair as the fallback so step 2 can light it up without re-touching this file.

  2. Per-author tinting (ef72cfdd94e + b67ed11a501) — markContentDiff( baseline, proposed, authorColor? ) now emits an inline style="--suggestion-author-color: …" on each <del> / <ins>. with-suggestion-overlay.js resolves the suggester via coreStore.getCurrentUsergetAvatarBorderColor and threads the hex through applyDiffMarks. Anonymous / pre-collab edits pass null and fall through to the existing red/green default; stripSuggestionMarks already drops the wrapper element on round-trip so the inline style attribute never persists.

Coverage:

  • 4 new unit tests in test/inline-formats.js (color propagation on <del>/<ins>, null/undefined fallthrough, strip round-trip discards the inline style).
  • 1 new test in test/with-suggestion-overlay.js asserting applyDiffMarks forwards the color into each marked run.
  • Full suggestion-mode suite: 120/120 passing.
  • Stylelint clean on the three touched SCSS files.

Foreign-edit author resolution (passing the suggester's id rather than the current user's once stored on the pending suggestion) and the multi-suggester e2e are mentioned in the plan but not in these commits — happy to follow up once the structural stack lands the foreign-suggester id on the pending-suggestion record so both surfaces share one source of truth.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

Flaky tests detected in 42565cf.
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/25456853520
📝 Reported issues:

Co-authored-by: alecgeatches <alecgeatches@git.wordpress.org>
Co-authored-by: maxschmeling <maxschmeling@git.wordpress.org>
Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
* Keep overlapping compaction updates to avoid YDoc divergence

* Add backport file

---------

Co-authored-by: alecgeatches <alecgeatches@git.wordpress.org>
Co-authored-by: maxschmeling <maxschmeling@git.wordpress.org>
The named re-export of `SUGGESTED_DELETION_FORMAT`, `SUGGESTED_ADDITION_FORMAT`,
and `registerSuggestionFormats` already pulls the module in, evaluating its
top-level format registration. The companion `import './inline-formats';`
above it added nothing — and because the file is not listed in the editor
package's `sideEffects` allowlist, esbuild emits an `[ignored-bare-import]`
warning every dev build.

Removing the bare import keeps the registration behavior unchanged (the
named re-export still triggers it, as does `with-suggestion-overlay.js`
consuming `markContentDiff`/`stripSuggestionMarks`) and clears the warning.
`wordDiff` tokenizes on word/whitespace boundaries, so a multi-word
addition or deletion arrives as 2N-1 separate `insert`/`delete`
segments. The previous `markContentDiff` wrapped each segment in its
own `<ins>`/`<del>`, which combined with the per-element border CSS
painted a pipe around every word — the result looked like a bracket
grid rather than a single underlined addition.

Accumulate consecutive same-type segments into one run and emit a
single wrapper per run. Boundary CSS now only paints at the actual
edges of each change.

Updates two unit tests in `test/inline-formats.js` and two in
`test/with-suggestion-overlay.js` that pinned the pre-coalesce
per-segment shape.
The overlay HOC suppresses diff marks while the block is selected to
keep RichText's value-prop reconciliation from disrupting the caret
during continuous typing. But discrete edits — a range Delete, a
paste, a single Backspace — also stayed unmarked until focus moved
off the block, leaving suggesters with no immediate visual feedback
that the suggestion had been captured.

Replace the block-selected gate with a ~100 ms idle debounce on
`overlayAttributes` change. A single overlay write followed by
silence flips the gate within a frame, so marks render almost
immediately for discrete actions while continuous typing keeps the
timer reset and avoids the original caret-fight scenario.

Implemented as `setIsOverlayIdle(false)` during render keyed on a
ref change, so the new `false` value is consumed by the same render
that observed the overlay change — no one-frame flash of marked
output between the change and the timeout cleanup.

Adds two unit tests: marks render after the idle window, and stay
suppressed while overlay writes churn inside it.
The inline diff overlay lives in React state on `SuggestionOverlayProvider`,
seeded only by direct edits in Suggest intent. That left two gaps:
suggesters lost their pending marks on reload (auto-save persisted
the comment, but the overlay starts empty on mount), and reviewers
viewing the same post in any non-Suggest intent never saw the
inline strike-through/insertion at all — only the sidebar summary.

Add a `SuggestionOverlayHydrator` mounted alongside the existing
suggest-mode siblings (interceptor, autosave) inside the provider.
It re-uses the `useNoteThreads` query from the collab sidebar so
no extra REST traffic is needed, parses each unresolved comment's
`_wp_suggestion` payload via the existing `parseSuggestionPayload`,
turns each `attribute-set` op into a baseline/overlay pair, and
dispatches a new `SEED_FROM_COMMENT` reducer action.

The seeded entry is tagged with `hydratedFromCommentId` so the
HOC can tell a hydrator-sourced entry from a live edit. Two
behaviors follow from that:

  - The outer `withSuggestionOverlay` wrap now activates whenever
    `isSuggestMode || hasOverlayEntry`, so blocks with a hydrated
    entry render with marks even outside Suggest intent.
  - Inside `SuggestingBlockEdit`, `wrappedSetAttributes` falls
    through to the real `setAttributes` when not in Suggest intent.
    Reviewers' keystrokes therefore land on the real block instead
    of being trapped in the suggester's overlay.

The hydrator skips entries that already have live overlay writes
(`Object.keys(overlayAttributes).length > 0` and not flagged as
hydrator-sourced) so a refresh of the comment list mid-typing
doesn't clobber the suggester's unsaved state.

Adds three unit tests covering the reducer, the syncedOpsKey
preservation, and the reviewer write-through scenario.
The hydrator re-runs whenever the comment entity record list updates.
Without a value-level guard, re-seeding the same payload produced a new
overlay state reference on every render and the effect looped, pegging
the renderer. Short-circuit when both baseline and overlay attribute
shallow-compare equal to the existing entry's, and add unit tests
covering the seed paths.
In a real-time collaboration session, the hydrator seeds an overlay
entry on every connected client from each persisted suggestion comment.
Reviewers route their writes through to the real block, but the merge
step still let the suggester's recorded `after` win on overlapping
rich-text keys — so the reviewer's typing was masked in the canvas and
the diff marks made it look as if their edits had become part of the
suggester's proposal. Skip the merge for hydrated reviewer entries
once the real content diverges from the suggester's recorded
baseline; the existing accept-time conflict prompt covers the case
where someone tries to accept a now-stale suggestion.
The `.has-suggestion-addition` rule applied a 1px box-shadow on the
left and right of every inserted run, which rendered as visible
vertical bars around suggested text. The underline plus the author
color already carry the "inserted" treatment (matching the Google
Docs suggesting-mode style noted in the surrounding comments), so
the box-shadow was redundant and visually noisy.
Replace the 100 ms idle-debounce gate with a strict `isSelected`
guard so the overlay HOC never flips RichText's value prop between
the clean proposed value and the marked HTML while the caret is in
the block.

The idle gate ('Show inline diff marks once edits settle, not only
on blur') tried to surface marks within ~100 ms of a discrete edit
without leaving the block, but rendering `<del>`/`<ins>` wrappers
while the caret is live disrupts the cursor on the next keystroke.
A reproducible failure: typing 'page' after backspacing 'post.'
yields '.egappost' in the suggestion instead of 'page' — each typed
character lands at the boundary of a format element, gets stripped
into the deletion or prepended to the addition, and the result is
a reversed insertion mixed with surviving baseline text.

Marks reappear as soon as focus moves off the block. Reviewers (who
are not editing the suggester's block) continue to see marks on
hydrated entries without selecting anything.

Two unit tests that exercised the idle gate are replaced with one
that pins the new behavior: while `isBlockSelected` is true, the
rendered content stays unmarked. The hydrated-reviewer and
suggester-divergence tests now register the block in the editor
store so `isBlockSelected` returns false (no block selected), which
is the production state for those scenarios.
The hydrated-reviewer scenarios need `isBlockSelected` to return
false (no block is selected) so the HOC's selection gate lets the
diff marks render. The renderWithProviders helper previously
registered only the notices and editor stores; this adds an opt-in
`blocks` parameter that registers the block-editor + preferences
stores and seeds the live block tree.

The orphan-prune effect runs against the live tree on every overlay
mutation, so we only register the block-editor store when a test
asks for it — synthetic clientIds with no matching block would
otherwise be pruned the moment a baseline is captured.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Notes Phase 3 of the Gutenberg roadmap around block commenting [Package] Block editor /packages/block-editor [Package] Editor /packages/editor [Status] In Progress Tracking issues with work in progress [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Suggestion mode: render suggestions inline

3 participants