Skip to content

[WC-3647] Combine seven rich text fixes - #2495

Open
samuelreichert wants to merge 8 commits into
mainfrom
fix/rich-text-combined-fixes
Open

samuelreichert wants to merge 8 commits into
mainfrom
fix/rich-text-combined-fixes

Conversation

@samuelreichert

Copy link
Copy Markdown
Contributor

Pull request type

Bug fix (non-breaking change which fixes an issue)


Description

This PR combines seven Rich Text bug fixes into one branch, based on the latest main, so they can be reviewed, tested and released together. Each fix stays a separate commit.

Included PRs (this PR supersedes them):

PR Fix
#2454 Keep text color, font family and font size in class style mode
#2456 Run On change on leave only after an edit
#2458 Discard the typed value when pressing Escape in a configuration dropdown
#2459 Ignore trailing line breaks in the character count
#2460 Build a valid Google Maps embed URL
#2465 Apply the "Enable spell checking" setting
#2466 Apply the "Default font family" and "Default font size" settings

1. Class style mode loses text color, font family and size (#2454)

With Style data format = Class, these marks are saved as <span data-text-color|data-font-family|data-font-size class="has-…"> with no style attribute. Tiptap's TextStyle mark only parses a <span> that has a style attribute, so the formatting was dropped when the content was loaded again.

A new TextStyleClass extension extends TextStyle and, in class mode only, adds a parse rule for spans with these data attributes. Inline mode is unchanged.

2. On change runs on every blur (#2456)

With On change type = When user leaves input field, On change ran on every blur, even without an edit. A dirty flag is now set by a real edit (onUpdate) and cleared on blur. External value syncs use emitUpdate: false, so they never set it. On leave still runs on every blur.

Out of scope: clicking a toolbar button also blurs the editor, so editing and then clicking the toolbar still runs On change.

3. Escape saves the typed value in configuration dropdowns (#2458)

Escape called clearDraft() and then blur() straight away, so onBlur committed the draft before the state update applied. A ref set around the Escape-triggered blur now makes onBlur skip the commit.

4. Character count includes trailing line breaks (#2459)

getCharCount now returns text.trimEnd().length, as described in the 4.12.0 changelog. Word count and HTML character count are unchanged.

5. Invalid Google Maps embed URL (#2460)

The template in videoUrlPattern.ts used msid=$2 instead of $3 and ended with a stray ". It is now maps.google.com/maps/ms?msid=$3&output=embed.

The test-only commits of #2460 are already on main, so only the fix commit is included here.

6. "Enable spell checking" has no effect (#2465)

The setting was lost in the move from Quill to Tiptap. EditorWrapper now passes spellCheck to Editor, which sets spellcheck on the editable area, as 4.x did. role: "textbox" is set explicitly in the same attributes, because useEditor replaces them on re-render. Existing snapshots only gain spellcheck="true".

7. "Default font family" and "Default font size" have no effect (#2466)

These settings were also lost in the move to Tiptap. As in 4.x, they do not apply a font to the content. They set the initial value of the font family and font size toolbar dropdowns when the selection has no font of its own.

  • Font family matches an option's value or name, ignoring case. Custom fonts work.
  • Font size normalizes a bare number such as 14 to 14px.
  • A default that matches no option, including unsafe values, is ignored.
  • With no default configured, the dropdowns keep the current placeholders ("Font Family" / "14px").

Notes on combining

  • The CHANGELOG entries are merged into one ### Fixed list under [Unreleased].
  • The snapshot for "renders with both word and character count" was dropped from the spell-check commit, because that test no longer exists on main.
  • EditorWrapper passes both spellCheck and the default font props to Editor.

All fixes were written test-first. In rich-text-web: 41 test suites and 640 tests pass, tsc --noEmit is clean, and lint has 0 errors. The lint warnings are the same as on main.

What should be covered while testing?

  1. Class style mode: set Style data format to Class. Apply a text color, a font family and a font size, then save and reload the page. The formatting is still there and the saved HTML has no inline style. Repeat with Inline: nothing changed.
  2. On change on leave: configure On change (type: when user leaves input field) to show a message. Tab in and out without typing: no message. Type, then leave: the message appears once. Enter and leave again without typing: no message.
  3. Escape in a configuration dropdown: open a table configuration dropdown and type a new value in a number field. Press Escape: the value goes back and the table is unchanged. Type a value and press Enter: it is applied.
  4. Character count: enable the status bar with Character count. Type abc and press Enter twice. The count stays at 3.
  5. Google Maps embed: paste a https://maps.google.com/maps/ms?…&msid=<id> link in the video dialog. The embed URL is well-formed.
  6. Spell checking: set Enable spell checking to Yes and type a misspelled word: the browser underlines it. Set it to No: misspellings are not underlined.
  7. Default font: set Default font family (for example Arial) and Default font size (for example 18px). Place the cursor in unformatted text: the dropdowns show Arial and 18px, and the text does not change. Apply another font to some text and place the cursor there: the dropdowns show that font. Clear both settings: the dropdowns show "Font Family" and 14px.

🤖 Generated with Claude Code

@samuelreichert
samuelreichert requested a review from a team as a code owner October 28, 2026 09:23
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

gjulivan
gjulivan previously approved these changes Oct 30, 2026
@samuelreichert
samuelreichert force-pushed the fix/rich-text-combined-fixes branch from 16d3bfa to 123a395 Compare October 30, 2026 10:21
@github-actions

This comment has been minimized.

samuelreichert and others added 7 commits October 30, 2026 14:42
…yle mode

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@samuelreichert
samuelreichert force-pushed the fix/rich-text-combined-fixes branch from 123a395 to 0228fe2 Compare October 30, 2026 13:42
@github-actions

This comment has been minimized.

Text colors stored in class style mode are now kept when content loads,
so the editor and the View/Edit Code dialog show them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

AI Code Review

✅ Approved — no issues found


What was reviewed

File Change
rich-text-web/src/components/Editor.tsx Dirty flag so On change on leave runs only after an edit. spellcheck and role editor attributes. Uses TextStyleClass.
rich-text-web/src/components/EditorWrapper.tsx Passes spellCheck and the default font props through to Editor.
rich-text-web/src/components/toolbars/** (Toolbar, ToolbarConfig, fontHelpers, ConfigurationDropdown) Default font family and size shown in the toolbar dropdowns. Escape now skips the commit on blur.
rich-text-web/src/components/StatusBar.tsx The character count ignores trailing whitespace.
rich-text-web/src/extensions/TextStyleClass.ts New extension that parses class-mode text style spans.
rich-text-web/src/utils/videoUrlPattern.ts Google Maps embed URL fixed.
Tests, snapshots, e2e baseline PNGs Test coverage for each fix.
rich-text-web/CHANGELOG.md Seven user-facing Fixed entries under [Unreleased].

Skipped (out of scope): lockfiles and generated files. I did not read the test files line by line.

CI: pending: Run code quality check, sigridci · unrelated failures: security/snyk (external scanner), Run automated end-to-end tests and Run ${{ matrix.target }} task on ${{ matrix.os }} (both failed after 0s, so likely infrastructure or workflows awaiting approval)


Positives

  • Each fix has its own tests and its own changelog entry, and the entries are phrased for app developers.
  • TextStyleClass leaves inline mode untouched and skips spans that already carry a style attribute, so there is no double-parsing.
  • The dirty flag is set only in onUpdate, and external value syncs use emitUpdate: false, so they never set it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants