From ac3c93ccfadfff8119305992156f18e346d58397 Mon Sep 17 00:00:00 2001 From: Juan Abimael Santos Castillo <41840076+Abimael10@users.noreply.github.com> Date: Sun, 14 Jun 2026 07:34:36 -0400 Subject: [PATCH] fix(editor): render strikethrough on links (#15109) **Issue** Strikethrough on a link doesn't render. The toolbar button highlights but no line appears (#15106). **Solution** affine-link hardcoded text-decoration: none in the override it passes to affineTextStyles, which clobbered the decoration computed from strike/underline. Removing it fixes the render; plain links still show no underline because affineTextStyles returns none by default. **Result** Strikethrough and underline render on links again. Added an e2e test: a plain link stays undecorated, a struck link renders line-through, red before the fix and green after. fix #15106 ## Summary by CodeRabbit * **Bug Fixes** * Fixed link text-decoration styling to properly support strikethrough and other text formatting when applied to links. --- .../inlines/link/src/link-node/affine-link.ts | 1 - tests/blocksuite/e2e/link.spec.ts | 33 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/blocksuite/affine/inlines/link/src/link-node/affine-link.ts b/blocksuite/affine/inlines/link/src/link-node/affine-link.ts index 5c707e6e90..51957ed91e 100644 --- a/blocksuite/affine/inlines/link/src/link-node/affine-link.ts +++ b/blocksuite/affine/inlines/link/src/link-node/affine-link.ts @@ -160,7 +160,6 @@ export class AffineLink extends WithDisposable(ShadowlessElement) { const linkStyle = { color: 'var(--affine-link-color)', fill: 'var(--affine-link-color)', - 'text-decoration': 'none', cursor: 'pointer', }; diff --git a/tests/blocksuite/e2e/link.spec.ts b/tests/blocksuite/e2e/link.spec.ts index 348344d9ee..f211b1afbb 100644 --- a/tests/blocksuite/e2e/link.spec.ts +++ b/tests/blocksuite/e2e/link.spec.ts @@ -16,6 +16,7 @@ import { selectAllByKeyboard, setSelection, SHORT_KEY, + strikethrough, switchReadonly, type, waitNextFrame, @@ -421,3 +422,35 @@ test('convert link to embed', async ({ page }, testInfo) => { await waitNextFrame(page); await expect(toolbar).toBeVisible(); }); + +test('strikethrough applies to a link', async ({ page }) => { + const linkText = 'linkText'; + const link = 'http://example.com'; + await enterPlaygroundRoom(page); + await initEmptyParagraphState(page); + await focusRichText(page); + await type(page, linkText); + + // turn the selected text into a link + await dragBetweenIndices(page, [0, 0], [0, 8]); + await pressCreateLinkShortCut(page); + await page.mouse.move(0, 0); + const linkPopoverInput = page.locator('.affine-link-popover-input'); + await expect(linkPopoverInput).toBeVisible(); + await type(page, link); + await pressEnter(page); + + const linkLocator = page.locator('affine-link a'); + await expect(linkLocator).toHaveAttribute('href', link); + + // a plain link keeps no text-decoration (preserve the default of no underline) + await expect(linkLocator).toHaveCSS('text-decoration-line', 'none'); + + // re-select the link text and strike it through + await dragBetweenIndices(page, [0, 0], [0, 8]); + await strikethrough(page); + await page.mouse.move(0, 0); + + // regression for #15106: the strike must actually render on the link + await expect(linkLocator).toHaveCSS('text-decoration-line', 'line-through'); +});