provide a general visit function to modify rebuilt id node map

This commit is contained in:
Yanzhen Yu
2026-04-01 12:00:00 +08:00
parent cd601571ea
commit 29fcf03d4f

View File

@@ -62,7 +62,7 @@ export function addHoverClass(cssText: string): string {
if (!ast.stylesheet) { if (!ast.stylesheet) {
return cssText; return cssText;
} }
ast.stylesheet.rules.forEach(rule => { ast.stylesheet.rules.forEach((rule) => {
if ('selectors' in rule) { if ('selectors' in rule) {
(rule.selectors || []).forEach((selector: string) => { (rule.selectors || []).forEach((selector: string) => {
if (HOVER_SELECTOR.test(selector)) { if (HOVER_SELECTOR.test(selector)) {
@@ -102,7 +102,8 @@ function buildNode(
continue; continue;
} }
let value = n.attributes[name]; let value = n.attributes[name];
value = typeof value === 'boolean' || typeof value === 'number' ? '' : value; value =
typeof value === 'boolean' || typeof value === 'number' ? '' : value;
// attribute names start with rr_ are internal attributes added by rrweb // attribute names start with rr_ are internal attributes added by rrweb
if (!name.startsWith('rr_')) { if (!name.startsWith('rr_')) {
const isTextarea = tagName === 'textarea' && name === 'value'; const isTextarea = tagName === 'textarea' && name === 'value';
@@ -128,7 +129,11 @@ function buildNode(
try { try {
if (n.isSVG && name === 'xlink:href') { if (n.isSVG && name === 'xlink:href') {
node.setAttributeNS('http://www.w3.org/1999/xlink', name, value); node.setAttributeNS('http://www.w3.org/1999/xlink', name, value);
} else if (name == 'onload' || name == 'onclick' || name.substring(0, 7) == 'onmouse') { } else if (
name === 'onload' ||
name === 'onclick' ||
name.substring(0, 7) === 'onmouse'
) {
// Rename some of the more common atttributes from https://www.w3schools.com/tags/ref_eventattributes.asp // Rename some of the more common atttributes from https://www.w3schools.com/tags/ref_eventattributes.asp
// as setting them triggers a console.error (which shows up despite the try/catch) // as setting them triggers a console.error (which shows up despite the try/catch)
// Assumption: these attributes are not used to css // Assumption: these attributes are not used to css
@@ -220,15 +225,25 @@ export function buildNodeWithSN(
return node as INode; return node as INode;
} }
function sideEffects(idNodeMap: idNodeMap) { function visit(idNodeMap: idNodeMap, onVisit: (node: INode) => void) {
for(let id in idNodeMap) { function walk(node: INode) {
const node = idNodeMap[id]; onVisit(node);
}
for (const key in idNodeMap) {
if (idNodeMap[key]) {
walk(idNodeMap[key]);
}
}
}
function handleScroll(node: INode) {
const n = node.__sn; const n = node.__sn;
if (n.type !== NodeType.Element) { if (n.type !== NodeType.Element) {
continue; return;
} }
const el = node as Node as HTMLElement; const el = (node as Node) as HTMLElement;
for(const name in n.attributes) { for (const name in n.attributes) {
if (!(n.attributes.hasOwnProperty(name) && name.startsWith('rr_'))) { if (!(n.attributes.hasOwnProperty(name) && name.startsWith('rr_'))) {
continue; continue;
} }
@@ -240,12 +255,12 @@ function sideEffects(idNodeMap: idNodeMap) {
el.scrollTop = value as number; el.scrollTop = value as number;
} }
} }
}
} }
function rebuild( function rebuild(
n: serializedNodeWithId, n: serializedNodeWithId,
doc: Document, doc: Document,
onVisit?: (node: INode) => unknown,
/** /**
* This is not a public API yet, just for POC * This is not a public API yet, just for POC
*/ */
@@ -253,7 +268,12 @@ function rebuild(
): [Node | null, idNodeMap] { ): [Node | null, idNodeMap] {
const idNodeMap: idNodeMap = {}; const idNodeMap: idNodeMap = {};
const node = buildNodeWithSN(n, doc, idNodeMap, false, HACK_CSS); const node = buildNodeWithSN(n, doc, idNodeMap, false, HACK_CSS);
sideEffects(idNodeMap); visit(idNodeMap, (visitedNode) => {
if (onVisit) {
onVisit(visitedNode);
}
handleScroll(visitedNode);
});
return [node, idNodeMap]; return [node, idNodeMap];
} }