diff --git a/web/frontend/src/hooks/use-highlight-theme.ts b/web/frontend/src/hooks/use-highlight-theme.ts index 47b782679..1e4517c3f 100644 --- a/web/frontend/src/hooks/use-highlight-theme.ts +++ b/web/frontend/src/hooks/use-highlight-theme.ts @@ -4,14 +4,39 @@ import githubDarkCss from "highlight.js/styles/github-dark.css?inline" import githubLightCss from "highlight.js/styles/github.css?inline" const THEME_STYLE_ID = "hljs-theme-style" +const THEME_STYLE_OWNER_ATTR = "data-picoclaw-highlight-theme" +const THEME_STYLE_OWNER_VALUE = "true" +const MANAGED_THEME_STYLE_SELECTOR = `style[${THEME_STYLE_OWNER_ATTR}="${THEME_STYLE_OWNER_VALUE}"]` +const ID_THEME_STYLE_SELECTOR = `style#${THEME_STYLE_ID}` -function getOrCreateThemeStyleElement() { - let styleElement = document.getElementById(THEME_STYLE_ID) - if (!styleElement) { - styleElement = document.createElement("style") - styleElement.id = THEME_STYLE_ID - document.head.appendChild(styleElement) +function getOrCreateThemeStyleElement(): HTMLStyleElement { + const managedStyleElement = document.head.querySelector( + MANAGED_THEME_STYLE_SELECTOR, + ) + if (managedStyleElement) { + return managedStyleElement } + + const existingStyleElement = + document.querySelector(ID_THEME_STYLE_SELECTOR) + if (existingStyleElement) { + existingStyleElement.setAttribute( + THEME_STYLE_OWNER_ATTR, + THEME_STYLE_OWNER_VALUE, + ) + return existingStyleElement + } + + const conflictingElement = document.getElementById(THEME_STYLE_ID) + const styleElement = document.createElement("style") + if (!conflictingElement) { + styleElement.id = THEME_STYLE_ID + } + + // Leave conflicting non-style nodes untouched and track the injected style explicitly. + styleElement.setAttribute(THEME_STYLE_OWNER_ATTR, THEME_STYLE_OWNER_VALUE) + document.head.appendChild(styleElement) + return styleElement }