|
|
@@ -10,6 +10,19 @@ type CopyButtonProps = {
|
|
|
className?: string
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Strips only history highlight spans from text while preserving other HTML
|
|
|
+ * Targets: <span class="history-item-highlight">content</span>
|
|
|
+ * @param text - Text that may contain highlight spans
|
|
|
+ * @returns Text with highlight spans removed but content preserved
|
|
|
+ */
|
|
|
+const stripHistoryHighlightSpans = (text: string): string => {
|
|
|
+ // Match opening tag, capture content until closing tag
|
|
|
+ // The [\s\S]*? pattern matches any character (including newlines) non-greedily,
|
|
|
+ // which properly handles content with < characters
|
|
|
+ return text.replace(/<span\s+class="history-item-highlight">([\s\S]*?)<\/span>/g, "$1")
|
|
|
+}
|
|
|
+
|
|
|
export const CopyButton = ({ itemTask, className }: CopyButtonProps) => {
|
|
|
const { isCopied, copy } = useClipboard()
|
|
|
const { t } = useAppTranslation()
|
|
|
@@ -17,12 +30,10 @@ export const CopyButton = ({ itemTask, className }: CopyButtonProps) => {
|
|
|
const onCopy = useCallback(
|
|
|
(e: React.MouseEvent) => {
|
|
|
e.stopPropagation()
|
|
|
- const tempDiv = document.createElement("div")
|
|
|
- tempDiv.innerHTML = itemTask
|
|
|
- const text = tempDiv.textContent || tempDiv.innerText || ""
|
|
|
-
|
|
|
if (!isCopied) {
|
|
|
- copy(text)
|
|
|
+ // Strip only history highlight spans before copying to clipboard
|
|
|
+ const cleanText = stripHistoryHighlightSpans(itemTask)
|
|
|
+ copy(cleanText)
|
|
|
}
|
|
|
},
|
|
|
[isCopied, copy, itemTask],
|