Skip to content

Commit cefd57e

Browse files
committed
test
1 parent e369663 commit cefd57e

File tree

3 files changed

+151
-28
lines changed

3 files changed

+151
-28
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/**
2+
* Fix for 1Password and other browser extensions that bundle Prism.js
3+
*
4+
* Problem: Extensions with bundled Prism.js (especially 1Password beta/nightly)
5+
* run Prism.highlightAll() on page load, which strips our syntax highlighting
6+
* by removing .token spans and even <pre> wrappers.
7+
*
8+
* Solution: Detect when highlighting is stripped and re-apply it.
9+
* Only targets code BLOCKS (pre>code), not inline code elements.
10+
*/
11+
12+
// Extend Window interface to include Prism
13+
declare global {
14+
interface Window {
15+
Prism?: {
16+
highlightAll: () => void
17+
}
18+
}
19+
}
20+
21+
let isFixing = false
22+
let retryCount = 0
23+
const MAX_RETRIES = 3
24+
25+
/**
26+
* Check if Prism highlighting has been compromised
27+
* Returns true if we find code blocks that should be highlighted but aren't
28+
*/
29+
function isPrismCompromised(): boolean {
30+
// Look for code elements with language-* class but no token spans inside
31+
const codeBlocks = document.querySelectorAll('pre code[class*="language-"]')
32+
33+
for (const block of Array.from(codeBlocks)) {
34+
const hasTokens = block.querySelector('[class*="token"]')
35+
if (!hasTokens && block.textContent && block.textContent.trim().length > 0) {
36+
// Found a code block that should be highlighted but isn't
37+
return true
38+
}
39+
}
40+
41+
return false
42+
}
43+
44+
/**
45+
* Re-highlight all code blocks using Prism
46+
*/
47+
function reHighlightCode() {
48+
if (isFixing) return
49+
50+
isFixing = true
51+
retryCount++
52+
53+
try {
54+
// Check if Prism is available
55+
if (typeof window.Prism !== "undefined") {
56+
// Re-run Prism highlighting on all code blocks
57+
window.Prism.highlightAll()
58+
console.log("[Prism Fix] Re-applied syntax highlighting (retry", retryCount, ")")
59+
}
60+
} catch (error) {
61+
console.error("[Prism Fix] Error re-highlighting:", error)
62+
} finally {
63+
isFixing = false
64+
}
65+
}
66+
67+
/**
68+
* Check and fix Prism highlighting after a delay
69+
*/
70+
function checkAndFix(delay = 100) {
71+
setTimeout(() => {
72+
if (isPrismCompromised() && retryCount < MAX_RETRIES) {
73+
reHighlightCode()
74+
}
75+
}, delay)
76+
}
77+
78+
/**
79+
* Initialize the fix
80+
*/
81+
function init() {
82+
// Check immediately after DOM is ready
83+
if (document.readyState === "loading") {
84+
document.addEventListener("DOMContentLoaded", () => checkAndFix(50))
85+
} else {
86+
checkAndFix(50)
87+
}
88+
89+
// Check again after a short delay (in case extension runs after us)
90+
checkAndFix(200)
91+
checkAndFix(500)
92+
93+
// Set up a MutationObserver to detect if extension modifies code blocks
94+
const observer = new MutationObserver((mutations) => {
95+
// Check if any mutation affected code blocks
96+
for (const mutation of mutations) {
97+
if (mutation.type === "childList" || mutation.type === "characterData") {
98+
const target = mutation.target as HTMLElement
99+
100+
// Check if the mutation is inside a code block
101+
const codeBlock = target.closest('pre code[class*="language-"]')
102+
if (codeBlock) {
103+
checkAndFix(100)
104+
break
105+
}
106+
}
107+
}
108+
})
109+
110+
// Start observing
111+
observer.observe(document.body, {
112+
childList: true,
113+
subtree: true,
114+
characterData: true,
115+
})
116+
}
117+
118+
// Only run in browser
119+
if (typeof window !== "undefined") {
120+
init()
121+
}

src/scripts/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ import "./fix-remix-urls"
22
import "./fix-external-links"
33
import "./copyToClipboard/copyToClipboard"
44
import "./scroll-to-search"
5+
import "./fix-prism-extension-conflict"

src/styles/index.css

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,22 @@ strong {
9090
}
9191

9292
/* Override browser extensions (1Password, etc.) that inject dark themes into INLINE code elements ONLY */
93-
/* Specifically exclude pre>code blocks to preserve syntax highlighting */
93+
/* Specifically target ONLY inline code, never code inside pre tags or with token classes */
9494
/* Target: inline code in paragraphs, tables, and CopyText components */
95-
body p code:not([class*="token"]),
96-
body li code:not([class*="token"]),
97-
body td code:not([class*="token"]),
98-
body th code:not([class*="token"]),
95+
body p > code:not([class*="token"]),
96+
body li > code:not([class*="token"]),
97+
body td > code:not([class*="token"]),
98+
body th > code:not([class*="token"]),
9999
body .copyContainer > code:not([class*="token"]),
100-
body h1 code:not([class*="token"]),
101-
body h2 code:not([class*="token"]),
102-
body h3 code:not([class*="token"]),
103-
body h4 code:not([class*="token"]),
104-
body h5 code:not([class*="token"]),
105-
body h6 code:not([class*="token"]) {
100+
body h1 > code:not([class*="token"]),
101+
body h2 > code:not([class*="token"]),
102+
body h3 > code:not([class*="token"]),
103+
body h4 > code:not([class*="token"]),
104+
body h5 > code:not([class*="token"]),
105+
body h6 > code:not([class*="token"]),
106+
body blockquote > code:not([class*="token"]),
107+
body a > code:not([class*="token"]),
108+
body span > code:not([class*="token"]) {
106109
background: var(--theme-code-inline-bg) !important;
107110
background-color: var(--theme-code-inline-bg) !important;
108111
color: var(--theme-code-inline-text) !important;
@@ -116,24 +119,22 @@ body h6 code:not([class*="token"]) {
116119
font-weight: bold !important;
117120
}
118121

119-
/* Override even if extensions add language-* classes to inline code */
120-
/* Still exclude token classes to preserve Prism syntax highlighting */
121-
body p code[class*="language-"]:not([class*="token"]),
122-
body li code[class*="language-"]:not([class*="token"]),
123-
body td code[class*="language-"]:not([class*="token"]),
124-
body th code[class*="language-"]:not([class*="token"]),
125-
body .copyContainer > code[class*="language-"]:not([class*="token"]) {
126-
background: var(--theme-code-inline-bg) !important;
127-
background-color: var(--theme-code-inline-bg) !important;
128-
color: var(--theme-code-inline-text) !important;
129-
font-family: var(--font-mono) !important;
130-
padding: var(--padding-block) var(--padding-inline) !important;
131-
border-radius: var(--border-radius) !important;
132-
white-space: normal !important;
133-
word-break: break-word !important;
122+
/* Make absolutely sure we NEVER style code blocks */
123+
pre code,
124+
pre > code,
125+
.code-block-container code,
126+
[class*="code-block"] code {
127+
background: none !important;
128+
background-color: transparent !important;
129+
color: inherit !important;
130+
font-family: inherit !important;
131+
padding: 0 !important;
132+
border-radius: 0 !important;
133+
white-space: pre !important;
134+
word-break: normal !important;
134135
line-height: inherit !important;
135-
font-size: 0.85em !important;
136-
font-weight: bold !important;
136+
font-size: inherit !important;
137+
font-weight: inherit !important;
137138
}
138139

139140
/* Inline code in headings should inherit heading font size and weight */

0 commit comments

Comments
 (0)