Skip to content

Fix background color removal failing on second toggle when text formatting is present#4031

Draft
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-background-color-removal-issue
Draft

Fix background color removal failing on second toggle when text formatting is present#4031
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-background-color-removal-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 3, 2026

After applying background color + any text formatting (underline, bold, etc.), removing the background works once but silently fails on subsequent remove attempts.

Root Cause

The cleanup dispatch in formatSelection.ts reads from Redux state to identify background-color artifacts to strip. However, the state is stale at cleanup time — the Editable component throttles its state sync by 500ms, so the state still holds the previous custom color (e.g. red) rather than the colors.bg value that execCommand just wrote to the DOM.

On the first removal this is benign: the DOM visually looks correct after the throttled sync. But on re-apply, Chromium creates a nested structure because the dirty background-color: colors.bg artifact left in state causes execCommand to add the new color as an inner element rather than replacing the outer one:

<!-- State after first removal (dirty): -->
<font color="#000000" style="background-color: rgb(0,0,0);">
  <u><font style="background-color: rgba(255,87,61,1);">Hello</font></u>
</font>

<!-- After second removal attempt, cleanup removes the outer colors.bg but not the inner red: -->
<font color="#000000">
  <u><font style="background-color: rgba(255,87,61,1);">Hello</font></u>
</font>
<!-- ↑ Red background still visible -->

Fix

Read contentEditable.innerHTML (immediately reflects execCommand output) instead of the stale Redux state value when computing what to strip. The state value is still used as oldValue for editThought to keep lexeme updates correct.

// Before: reads stale Redux state — misses the inner custom color
const styleRemovedThought = value.replace(styleAttrPattern, ...)

// After: reads current DOM — all background-color: colors.bg artifacts are present and stripped
const currentHtml = contentEditable?.innerHTML ?? value
const styleRemovedThought = currentHtml.replace(styleAttrPattern, ...)

Changes

  • src/actions/formatSelection.ts: Use contentEditable?.innerHTML as the source for cleanup computation in the backColor/bg dispatch
  • src/e2e/puppeteer/__tests__/color.ts: Add test covering background + text formatting + remove + re-apply + remove cycle

Copilot AI and others added 2 commits April 3, 2026 20:11
Agent-Logs-Url: https://github.com/cybersemics/em/sessions/39f3d69e-bf4c-4817-ac82-467d06896a49

Co-authored-by: raineorshine <750276+raineorshine@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix unable to remove background color on text formatting Fix background color removal failing on second toggle when text formatting is present Apr 3, 2026
Copilot AI requested a review from raineorshine April 3, 2026 20:15
@raineorshine
Copy link
Copy Markdown
Contributor

Wait for #4048

@raineorshine raineorshine added the hold Pause development label Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hold Pause development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to remove Background Color on text with any Text Formatting

2 participants