fix(sidebar): highlights not rendering math in read-only text

This commit is contained in:
Elian Doran
2026-04-11 14:23:07 +03:00
parent 67a48bbec7
commit 03ff9c4b27
2 changed files with 57 additions and 5 deletions

View File

@@ -0,0 +1,32 @@
import { describe, expect, it } from "vitest";
import { extractHighlightsFromStaticHtml } from "./HighlightsList.js";
describe("extractHighlightsFromStaticHtml", () => {
it("extracts highlighted text with math equations", () => {
const container = document.createElement("div");
container.innerHTML = `<p>
<span style="background-color:hsl(30,75%,60%);">
Highlighted&nbsp;
<span class="math-tex">
\\(e=mc^2\\)
</span>
&nbsp;math
</span>
</p>`;
document.body.appendChild(container);
const highlights = extractHighlightsFromStaticHtml(container);
// Should extract 3 highlights: "Highlighted ", the math element, and " math"
expect(highlights.length).toBe(3);
// The math highlight should preserve the .math-tex wrapper
const mathHighlight = highlights.find(h => h.text.includes("math-tex"));
expect(mathHighlight).toBeDefined();
expect(mathHighlight?.text).toContain('class="math-tex"');
expect(mathHighlight?.text).toContain("e=mc^2");
expect(mathHighlight?.attrs.background).toBeTruthy();
document.body.removeChild(container);
});
});

View File

@@ -267,7 +267,7 @@ function ReadOnlyTextHighlightsList() {
/>;
}
function extractHighlightsFromStaticHtml(el: HTMLElement | null) {
export function extractHighlightsFromStaticHtml(el: HTMLElement | null) {
if (!el) return [];
const { color: defaultColor, backgroundColor: defaultBackgroundColor } = getComputedStyle(el);
@@ -279,6 +279,7 @@ function extractHighlightsFromStaticHtml(el: HTMLElement | null) {
);
const highlights: DomHighlight[] = [];
const processedMathElements = new Set<Element>();
let node: Node | null;
while ((node = walker.nextNode())) {
@@ -287,23 +288,42 @@ function extractHighlightsFromStaticHtml(el: HTMLElement | null) {
const style = getComputedStyle(el);
// For elements inside math-tex, get styles from the styled ancestor
const mathEl = el.closest(".math-tex");
// Skip if we've already processed this math element
if (mathEl && processedMathElements.has(mathEl)) continue;
const styledEl = mathEl?.parentElement ?? el;
const styledElStyle = styledEl !== el ? getComputedStyle(styledEl) : style;
if (
el.closest('strong, em, u') ||
style.color !== defaultColor ||
style.backgroundColor !== defaultBackgroundColor
style.backgroundColor !== defaultBackgroundColor ||
styledElStyle.color !== defaultColor ||
styledElStyle.backgroundColor !== defaultBackgroundColor
) {
const attrs: RawHighlight["attrs"] = {
bold: !!el.closest("strong"),
italic: !!el.closest("em"),
underline: !!el.closest("u"),
background: el.style.backgroundColor,
color: el.style.color
background: styledEl.style.backgroundColor,
color: styledEl.style.color
};
if (Object.values(attrs).some(Boolean)) {
const text = mathEl ? mathEl.outerHTML : node.textContent;
// Track processed math elements to avoid duplicates
if (mathEl) {
processedMathElements.add(mathEl);
}
highlights.push({
id: randomString(),
text: node.textContent,
text,
element: el,
attrs
});