Skip to content

Commit 6145303

Browse files
committed
fix: prevent double processing and fix H1-H6 header detection
- Fix elements being processed multiple times by excluding generated elements - Fix H1-H6 headers incorrectly matching chemical patterns - Add proper exclusion for sup.ss-sup and sub.ss-sub elements - Centralize CSS_CLASSES constant for consistency
1 parent 9ed7ccd commit 6145303

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

src/runtime/smartscript/config.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@
44

55
import type { SuperscriptConfig } from './types'
66

7+
/**
8+
* CSS class names used by SmartScript (not configurable)
9+
*/
10+
export const CSS_CLASSES = {
11+
superscript: 'ss-sup',
12+
subscript: 'ss-sub',
13+
trademark: 'ss-tm',
14+
registered: 'ss-reg',
15+
ordinal: 'ss-ordinal',
16+
math: 'ss-math',
17+
} as const
18+
719
/**
820
* Default configuration values
921
*/
@@ -34,6 +46,9 @@ export const DEFAULT_CONFIG: SuperscriptConfig = {
3446
'style',
3547
'.no-superscript',
3648
'[data-no-superscript]',
49+
// Exclude our own generated elements
50+
'sup.ss-sup',
51+
'sub.ss-sub',
3752
],
3853
},
3954
performance: {

src/runtime/smartscript/dom.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import type { TextPart } from './types'
66
import { logger } from './logger'
7+
import { CSS_CLASSES } from './config'
78

89
// Pre-compiled regex patterns for performance
910
const DIGITS_ONLY = /^\d+$/
@@ -21,23 +22,23 @@ export function createSuperscriptElement(
2122

2223
switch (type) {
2324
case 'trademark':
24-
sup.className = 'ss-sup ss-tm'
25+
sup.className = `${CSS_CLASSES.superscript} ${CSS_CLASSES.trademark}`
2526
sup.setAttribute('aria-label', 'trademark')
2627
break
2728
case 'registered':
28-
sup.className = 'ss-sup ss-reg'
29+
sup.className = `${CSS_CLASSES.superscript} ${CSS_CLASSES.registered}`
2930
sup.setAttribute('aria-label', 'registered')
3031
break
3132
case 'ordinal':
32-
sup.className = 'ss-sup ss-ordinal'
33+
sup.className = `${CSS_CLASSES.superscript} ${CSS_CLASSES.ordinal}`
3334
sup.setAttribute('aria-label', content)
3435
break
3536
case 'math':
36-
sup.className = 'ss-sup ss-math'
37+
sup.className = `${CSS_CLASSES.superscript} ${CSS_CLASSES.math}`
3738
sup.setAttribute('aria-label', `superscript ${content}`)
3839
break
3940
default:
40-
sup.className = 'ss-sup'
41+
sup.className = CSS_CLASSES.superscript
4142
sup.setAttribute('aria-label', `superscript ${content}`)
4243
}
4344

@@ -53,7 +54,7 @@ export function createSubscriptElement(
5354
): HTMLElement {
5455
const sub = document.createElement('sub')
5556
sub.textContent = content
56-
sub.className = 'ss-sub'
57+
sub.className = CSS_CLASSES.subscript
5758

5859
switch (type) {
5960
case 'chemical':

src/runtime/smartscript/engine.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
markAsProcessed,
1313
resetProcessingFlags,
1414
} from './dom'
15+
import { CSS_CLASSES } from './config'
1516

1617
/**
1718
* Process a single text node
@@ -54,11 +55,11 @@ function createTextNodeFilter(
5455
): NodeFilter {
5556
// Pre-compile exclude check for better performance
5657
const excludeSelectors = config.selectors.exclude
57-
58+
5859
return {
5960
acceptNode: (node: Node): number => {
6061
const text = node.textContent
61-
62+
6263
// Fast early exit for empty nodes
6364
if (!text || !text.trim()) {
6465
return NodeFilter.FILTER_REJECT
@@ -70,6 +71,14 @@ function createTextNodeFilter(
7071
return NodeFilter.FILTER_REJECT
7172
}
7273

74+
// Skip if parent is one of our generated elements
75+
if (parent && (
76+
(parent.tagName === 'SUP' && parent.classList.contains(CSS_CLASSES.superscript))
77+
|| (parent.tagName === 'SUB' && parent.classList.contains(CSS_CLASSES.subscript))
78+
)) {
79+
return NodeFilter.FILTER_REJECT
80+
}
81+
7382
// Use cached pattern check
7483
return needsProcessing(text, combinedPattern)
7584
? NodeFilter.FILTER_ACCEPT
@@ -142,13 +151,13 @@ function batchProcessElements(
142151

143152
function processBatch() {
144153
const endIndex = Math.min(index + batchSize, elements.length)
145-
154+
146155
for (let i = index; i < endIndex; i++) {
147156
processElement(elements[i], config, patterns, combinedPattern)
148157
}
149-
158+
150159
index = endIndex
151-
160+
152161
if (index < elements.length) {
153162
// Process next batch in next frame
154163
requestAnimationFrame(processBatch)

0 commit comments

Comments
 (0)