From 182178ba3c70cd9e73cecc74d8ffb96b82c78739 Mon Sep 17 00:00:00 2001 From: gjulivan Date: Mon, 16 Feb 2026 12:03:17 +0100 Subject: [PATCH 1/2] fix: hyperlink does not read attribute from clipboard --- packages/pluggableWidgets/rich-text-web/CHANGELOG.md | 4 ++++ .../rich-text-web/src/utils/modules/clipboard.ts | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/packages/pluggableWidgets/rich-text-web/CHANGELOG.md b/packages/pluggableWidgets/rich-text-web/CHANGELOG.md index 5be17ce3c5..9dbd139bb0 100644 --- a/packages/pluggableWidgets/rich-text-web/CHANGELOG.md +++ b/packages/pluggableWidgets/rich-text-web/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Fixed + +- We fixed an issue where hyperlink tag does not read target attribute when edited from code viewer. + ## [4.11.1] - 2026-01-27 ### Fixed diff --git a/packages/pluggableWidgets/rich-text-web/src/utils/modules/clipboard.ts b/packages/pluggableWidgets/rich-text-web/src/utils/modules/clipboard.ts index 0ef1317c3d..788914b0d5 100644 --- a/packages/pluggableWidgets/rich-text-web/src/utils/modules/clipboard.ts +++ b/packages/pluggableWidgets/rich-text-web/src/utils/modules/clipboard.ts @@ -22,6 +22,7 @@ export default class CustomClipboard extends Clipboard { this.matchers.unshift([Node.TEXT_NODE, customMatchText]); // add custom list matchers for ol and ul to allow custom list types (lower-alpha, lower-roman, etc.) this.addMatcher("ol, ul", matchList); + this.addMatcher("a", matchLink); } } @@ -116,6 +117,15 @@ function customMatchText(node: HTMLElement, delta: Delta, scroll: ScrollBlot): D return delta.insert(text); } +function matchLink(node: HTMLElement, _delta: Delta): Delta { + const href = node.getAttribute("href"); + const text = node.textContent || href || ""; + const title = node.getAttribute("title") || text; + const target = node.getAttribute("target") || "_blank"; + const value = { href, text, title, target }; + return new Delta().insert(text, { link: value }); +} + function matchList(node: HTMLElement, delta: Delta): Delta { const format = "list"; let list = "ordered"; From 92c663dcf5ea1d5b3059a5b2b9e82bbcade41c66 Mon Sep 17 00:00:00 2001 From: gjulivan Date: Fri, 20 Feb 2026 09:17:56 +0100 Subject: [PATCH 2/2] fix: remove default values for link target and title --- .../rich-text-web/src/utils/formats/link.ts | 8 ++++++-- .../rich-text-web/src/utils/modules/clipboard.ts | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/pluggableWidgets/rich-text-web/src/utils/formats/link.ts b/packages/pluggableWidgets/rich-text-web/src/utils/formats/link.ts index 0a20dba632..3d0fdca32d 100644 --- a/packages/pluggableWidgets/rich-text-web/src/utils/formats/link.ts +++ b/packages/pluggableWidgets/rich-text-web/src/utils/formats/link.ts @@ -25,9 +25,13 @@ export default class CustomLink extends Link { const linkConfig = value as linkConfigType; // @ts-expect-error the constructor is generic function, ts will consider sanitize not exist this.domNode.setAttribute("href", getLink(this.constructor.sanitize(linkConfig.href))); - this.domNode.setAttribute("target", linkConfig.target ?? "_blank"); - this.domNode.setAttribute("title", linkConfig.title ?? ""); this.domNode.textContent = linkConfig.text ?? linkConfig.href; + if (linkConfig.target) { + this.domNode.setAttribute("target", linkConfig.target); + } + if (linkConfig.title) { + this.domNode.setAttribute("title", linkConfig.title); + } } else { // @ts-expect-error the constructor is generic function, ts will consider sanitize not exist this.domNode.setAttribute("href", getLink(this.constructor.sanitize(value))); diff --git a/packages/pluggableWidgets/rich-text-web/src/utils/modules/clipboard.ts b/packages/pluggableWidgets/rich-text-web/src/utils/modules/clipboard.ts index 788914b0d5..0b98faa349 100644 --- a/packages/pluggableWidgets/rich-text-web/src/utils/modules/clipboard.ts +++ b/packages/pluggableWidgets/rich-text-web/src/utils/modules/clipboard.ts @@ -120,8 +120,8 @@ function customMatchText(node: HTMLElement, delta: Delta, scroll: ScrollBlot): D function matchLink(node: HTMLElement, _delta: Delta): Delta { const href = node.getAttribute("href"); const text = node.textContent || href || ""; - const title = node.getAttribute("title") || text; - const target = node.getAttribute("target") || "_blank"; + const title = node.getAttribute("title"); + const target = node.getAttribute("target"); const value = { href, text, title, target }; return new Delta().insert(text, { link: value }); }