Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
fix: bug when inlined link elements
  • Loading branch information
YunFeng0817 committed Sep 29, 2022
commit 406a7fb48dcbc8aabe758600d78540b7aad3c045
7 changes: 6 additions & 1 deletion packages/rrdom/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,12 @@ export class Mirror implements IMirror<RRNode> {
}

replace(id: number, n: RRNode) {
this.idNodeMap.set(id, n);
const oldNode = this.getNode(id);
if (oldNode) {
const meta = this.nodeMetaMap.get(oldNode);
if (meta) this.nodeMetaMap.set(n, meta);
this.idNodeMap.set(id, n);
}
}

reset() {
Expand Down
1 change: 0 additions & 1 deletion packages/rrweb-snapshot/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1165,7 +1165,6 @@ export function serializeNodeWithId(
},
stylesheetLoadTimeout,
);
if (isStylesheetLoaded(n as HTMLLinkElement) === false) return null; // add stylesheet in later mutation
}

return serializedNode;
Expand Down
2 changes: 1 addition & 1 deletion packages/rrweb/src/record/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ function record<T = eventWithTime>(
shadowDomManager.observeAttachShadow(iframe);
},
onStylesheetLoad: (linkEl, childSn) => {
stylesheetManager.attachLinkElement(linkEl, childSn, mirror);
stylesheetManager.attachLinkElement(linkEl, childSn);
},
keepIframeSrcFn,
});
Expand Down
2 changes: 1 addition & 1 deletion packages/rrweb/src/record/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ export default class MutationBuffer {
this.shadowDomManager.observeAttachShadow(iframe);
},
onStylesheetLoad: (link, childSn) => {
this.stylesheetManager.attachLinkElement(link, childSn, this.mirror);
this.stylesheetManager.attachLinkElement(link, childSn);
},
});
if (sn) {
Expand Down
29 changes: 15 additions & 14 deletions packages/rrweb/src/record/stylesheet-manager.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { Mirror, serializedNodeWithId } from 'rrweb-snapshot';
import type { elementNode, serializedNodeWithId } from 'rrweb-snapshot';
import { getCssRuleString } from 'rrweb-snapshot';
import type {
adoptedStyleSheetCallback,
adoptedStyleSheetParam,
attributeMutation,
mutationCallBack,
} from '../types';
import { StyleSheetMirror } from '../utils';
Expand All @@ -24,20 +25,20 @@ export class StylesheetManager {
public attachLinkElement(
linkEl: HTMLLinkElement,
childSn: serializedNodeWithId,
mirror: Mirror,
) {
this.mutationCb({
adds: [
{
parentId: mirror.getId(linkEl),
nextId: null,
node: childSn,
},
],
removes: [],
texts: [],
attributes: [],
});
if ('_cssText' in (childSn as elementNode).attributes)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is _cssText always going to be set, also if a link element hasn't finished loading yet?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According the code below

if (stylesheet) {
cssText = getCssRulesString(stylesheet);
}
if (cssText) {
delete attributes.rel;
delete attributes.href;
attributes._cssText = absoluteToStylesheet(cssText, stylesheet!.href!);

I think it will set _cssText when the link has been loaded. Otherwise, recorder will only keep its original attributes.

this.mutationCb({
adds: [],
removes: [],
texts: [],
attributes: [
{
id: childSn.id,
attributes: (childSn as elementNode)
.attributes as attributeMutation['attributes'],
},
],
});

this.trackLinkElement(linkEl);
}
Expand Down
40 changes: 40 additions & 0 deletions packages/rrweb/src/replay/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
createCache,
Mirror,
createMirror,
attributes,
serializedElementNodeWithId,
} from 'rrweb-snapshot';
import {
RRDocument,
Expand Down Expand Up @@ -1643,6 +1645,44 @@ export class Replayer {
(target as Element | RRElement).removeAttribute(attributeName);
} else if (typeof value === 'string') {
try {
// When building snapshot, some link styles haven't loaded. Then they are loaded, they will be inlined as incremental mutation change of attribute. We need to replace the old elements whose styles aren't inlined.
if (
attributeName === '_cssText' &&
(target.nodeName === 'LINK' || target.nodeName === 'STYLE')
) {
try {
const newSn = mirror.getMeta(
target as Node & RRNode,
) as serializedElementNodeWithId;
newSn.attributes = mutation.attributes as attributes;
const newNode = buildNodeWithSN(newSn, {
doc: target.ownerDocument as Document, // can be Document or RRDocument
mirror: mirror as Mirror,
skipChild: true,
hackCss: true,
cache: this.cache,
afterAppend: (node: Node | RRNode, id: number) => {
for (const plugin of this.config.plugins || []) {
if (plugin.onBuild)
plugin.onBuild(node, { id, replayer: this });
}
},
});
const siblingNode = target.nextSibling;
const parentNode = target.parentNode;
if (newNode && parentNode) {
parentNode.removeChild(target as Node & RRNode);
parentNode.insertBefore(
newNode as Node & RRNode,
siblingNode as (Node & RRNode) | null,
);
mirror.replace(mutation.id, newNode as Node & RRNode);
break;
}
} catch (e) {
// for safe
}
}
(target as Element | RRElement).setAttribute(
attributeName,
value,
Expand Down