upgrade to rrweb-snapshot v1.0

This commit is contained in:
Yanzhen Yu
2020-11-29 13:54:37 +08:00
parent f9d8fb7844
commit 7d817be155
7 changed files with 53 additions and 48 deletions

View File

@@ -62,6 +62,6 @@
"@xstate/fsm": "^1.4.0", "@xstate/fsm": "^1.4.0",
"mitt": "^1.1.3", "mitt": "^1.1.3",
"pako": "^1.0.11", "pako": "^1.0.11",
"rrweb-snapshot": "^0.8.4" "rrweb-snapshot": "^1.0.0"
} }
} }

View File

@@ -86,8 +86,8 @@ function record<T = eventWithTime>(
mutationBuffer.isFrozen() && mutationBuffer.isFrozen() &&
e.type !== EventType.FullSnapshot && e.type !== EventType.FullSnapshot &&
!( !(
e.type == EventType.IncrementalSnapshot && e.type === EventType.IncrementalSnapshot &&
e.data.source == IncrementalSource.Mutation e.data.source === IncrementalSource.Mutation
) )
) { ) {
// we've got a user initiated event so first we need to apply // we've got a user initiated event so first we need to apply
@@ -128,15 +128,12 @@ function record<T = eventWithTime>(
let wasFrozen = mutationBuffer.isFrozen(); let wasFrozen = mutationBuffer.isFrozen();
mutationBuffer.freeze(); // don't allow any mirror modifications during snapshotting mutationBuffer.freeze(); // don't allow any mirror modifications during snapshotting
const [node, idNodeMap] = snapshot( const [node, idNodeMap] = snapshot(document, {
document,
blockClass, blockClass,
inlineStylesheet, inlineStylesheet,
maskInputOptions, maskAllInputs: maskInputOptions,
// TODO: bypass slim DOM options
false,
recordCanvas, recordCanvas,
); });
if (!node) { if (!node) {
return console.warn('Failed to snapshot the document'); return console.warn('Failed to snapshot the document');

View File

@@ -209,18 +209,17 @@ export default class MutationBuffer {
adds.push({ adds.push({
parentId, parentId,
nextId, nextId,
node: serializeNodeWithId( node: serializeNodeWithId(n, {
n, doc: document,
document, map: mirror.map,
mirror.map, blockClass: this.blockClass,
this.blockClass, blockSelector: null,
null, skipChild: true,
true, inlineStylesheet: this.inlineStylesheet,
this.inlineStylesheet, maskInputOptions: this.maskInputOptions,
this.maskInputOptions, slimDOMOptions: {},
undefined, recordCanvas: this.recordCanvas,
this.recordCanvas, })!,
)!,
}); });
}; };
@@ -305,7 +304,7 @@ export default class MutationBuffer {
// attribute mutation's id was not in the mirror map means the target node has been removed // attribute mutation's id was not in the mirror map means the target node has been removed
.filter((attribute) => mirror.has(attribute.id)), .filter((attribute) => mirror.has(attribute.id)),
removes: this.removes, removes: this.removes,
adds: adds, adds,
}; };
// payload may be empty if the mutations happened in some blocked elements // payload may be empty if the mutations happened in some blocked elements
if ( if (

View File

@@ -57,7 +57,7 @@ function initMutationObserver(
recordCanvas, recordCanvas,
); );
const observer = new MutationObserver( const observer = new MutationObserver(
mutationBuffer.processMutations.bind(mutationBuffer) mutationBuffer.processMutations.bind(mutationBuffer),
); );
observer.observe(document, { observer.observe(document, {
attributes: true, attributes: true,
@@ -254,8 +254,8 @@ function initInputObserver(
] || ] ||
maskInputOptions[type as keyof MaskInputOptions] maskInputOptions[type as keyof MaskInputOptions]
) { ) {
if(maskInputFn) { if (maskInputFn) {
text = maskInputFn(text) text = maskInputFn(text);
} else { } else {
text = '*'.repeat(text.length); text = '*'.repeat(text.length);
} }

View File

@@ -232,7 +232,9 @@ export class Replayer {
} }
if (typeof config.mouseTail !== 'undefined') { if (typeof config.mouseTail !== 'undefined') {
if (config.mouseTail === false) { if (config.mouseTail === false) {
this.mouseTail && (this.mouseTail.style.display = 'none'); if (this.mouseTail) {
this.mouseTail.style.display = 'none';
}
} else { } else {
if (!this.mouseTail) { if (!this.mouseTail) {
this.mouseTail = document.createElement('canvas'); this.mouseTail = document.createElement('canvas');
@@ -498,17 +500,20 @@ export class Replayer {
); );
} }
this.legacy_missingNodeRetryMap = {}; this.legacy_missingNodeRetryMap = {};
mirror.map = rebuild(event.data.node, this.iframe.contentDocument)[1]; mirror.map = rebuild(event.data.node, {
doc: this.iframe.contentDocument,
})[1];
const styleEl = document.createElement('style'); const styleEl = document.createElement('style');
const { documentElement, head } = this.iframe.contentDocument; const { documentElement, head } = this.iframe.contentDocument;
documentElement!.insertBefore(styleEl, head); documentElement!.insertBefore(styleEl, head);
const injectStylesRules = getInjectStyleRules( const injectStylesRules = getInjectStyleRules(
this.config.blockClass, this.config.blockClass,
).concat(this.config.insertStyleRules); ).concat(this.config.insertStyleRules);
if (this.config.pauseAnimation) if (this.config.pauseAnimation) {
injectStylesRules.push( injectStylesRules.push(
'html.rrweb-paused * { animation-play-state: paused !important; }', 'html.rrweb-paused * { animation-play-state: paused !important; }',
); );
}
if (!this.service.state.matches('playing')) { if (!this.service.state.matches('playing')) {
this.iframe.contentDocument this.iframe.contentDocument
.getElementsByTagName('html')[0] .getElementsByTagName('html')[0]
@@ -809,7 +814,7 @@ export class Replayer {
domParent!.appendChild(target); domParent!.appendChild(target);
} }
const styleSheet = <CSSStyleSheet>styleEl.sheet; const styleSheet: CSSStyleSheet = styleEl.sheet!;
if (d.adds) { if (d.adds) {
d.adds.forEach(({ rule, index }) => { d.adds.forEach(({ rule, index }) => {
@@ -920,10 +925,10 @@ export class Replayer {
if (realParent && realParent.contains(target)) { if (realParent && realParent.contains(target)) {
realParent.removeChild(target); realParent.removeChild(target);
} else if (this.fragmentParentMap.has(target)) { } else if (this.fragmentParentMap.has(target)) {
/** /**
* the target itself is a fragment document and it's not in the dom * the target itself is a fragment document and it's not in the dom
* so we should remove the real target from its parent * so we should remove the real target from its parent
*/ */
const realTarget = this.fragmentParentMap.get(target)!; const realTarget = this.fragmentParentMap.get(target)!;
parent.removeChild(realTarget); parent.removeChild(realTarget);
this.fragmentParentMap.delete(target); this.fragmentParentMap.delete(target);
@@ -933,6 +938,7 @@ export class Replayer {
} }
}); });
// tslint:disable-next-line: variable-name
const legacy_missingNodeMap: missingNodeMap = { const legacy_missingNodeMap: missingNodeMap = {
...this.legacy_missingNodeRetryMap, ...this.legacy_missingNodeRetryMap,
}; };
@@ -1000,12 +1006,12 @@ export class Replayer {
return queue.push(mutation); return queue.push(mutation);
} }
const target = buildNodeWithSN( const target = buildNodeWithSN(mutation.node, {
mutation.node, doc: this.iframe.contentDocument,
this.iframe.contentDocument, map: mirror.map,
mirror.map, skipChild: true,
true, hackCss: true,
) as Node; }) as Node;
// legacy data, we should not have -1 siblings any more // legacy data, we should not have -1 siblings any more
if (mutation.previousId === -1 || mutation.nextId === -1) { if (mutation.previousId === -1 || mutation.nextId === -1) {
@@ -1282,8 +1288,9 @@ export class Replayer {
}); });
} }
const children = parentElement.children; const children = parentElement.children;
for (let i = 0; i < children.length; i++) for (const child of Array.from(children)) {
this.storeState((children[i] as unknown) as INode); this.storeState((child as unknown) as INode);
}
} }
} }
} }
@@ -1305,8 +1312,8 @@ export class Replayer {
this.elementStateMap.delete(parent); this.elementStateMap.delete(parent);
} }
const children = parentElement.children; const children = parentElement.children;
for (let i = 0; i < children.length; i++) { for (const child of Array.from(children)) {
this.restoreState((children[i] as unknown) as INode); this.restoreState((child as unknown) as INode);
} }
} }
} }

View File

@@ -19,7 +19,9 @@
"only-arrow-functions": false, "only-arrow-functions": false,
"max-line-length": false, "max-line-length": false,
"no-empty": false, "no-empty": false,
"max-classes-per-file": false "max-classes-per-file": false,
"semicolon": false,
"trailing-comma": false
}, },
"rulesDirectory": [] "rulesDirectory": []
} }

View File

@@ -2749,10 +2749,10 @@ rollup@^2.3.3:
optionalDependencies: optionalDependencies:
fsevents "~2.1.2" fsevents "~2.1.2"
rrweb-snapshot@^0.8.4: rrweb-snapshot@^1.0.0:
version "0.8.4" version "1.0.0"
resolved "https://registry.yarnpkg.com/rrweb-snapshot/-/rrweb-snapshot-0.8.4.tgz#3f8bf1270975f9dfad60321a29067d2ea39e3c39" resolved "https://registry.npmjs.org/rrweb-snapshot/-/rrweb-snapshot-1.0.0.tgz#5736e0f14f3bfa5c9cad462e8178ae9b0ca9ce53"
integrity sha512-6zY4lEUpA6qEd/ArAo1crWefxsmiXMuK/fTToGmsW+ehR8/pglxTsqpMPEkgQO9uBUIWIUE9I3CyIQkigmt4ug== integrity sha512-9mzEqbFE2OCe5aTzFFA1gKTqwvx2o2X2bMARpOWm7ST4cA1/xBbq4+wHia35CIn6EmMougaBVgUmah7QDJHXlQ==
run-async@^2.2.0: run-async@^2.2.0:
version "2.4.1" version "2.4.1"