From 79bbfde4444f366d6132b3c87b52d1ee44f43aef Mon Sep 17 00:00:00 2001 From: Eoghan Murray Date: Tue, 12 Jan 2021 16:55:11 +0000 Subject: [PATCH] Discovered that the common case of mouse movement or scrolling happening during `takeFullSnapshot` was causing mutations to be immediately emitted, contrary to the goal of https://github.com/rrweb-io/rrweb/pull/385 --- src/record/index.ts | 9 ++------- src/record/mutation.ts | 19 ++++++++++++++++--- typings/record/mutation.d.ts | 2 ++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/record/index.ts b/src/record/index.ts index 164d1e1933..11ead12958 100644 --- a/src/record/index.ts +++ b/src/record/index.ts @@ -116,7 +116,6 @@ function record( ) { // we've got a user initiated event so first we need to apply // all DOM changes that have been buffering during paused state - mutationBuffer.emit(); mutationBuffer.unfreeze(); } @@ -153,8 +152,7 @@ function record( isCheckout, ); - let wasFrozen = mutationBuffer.isFrozen(); - mutationBuffer.freeze(); // don't allow any mirror modifications during snapshotting + mutationBuffer.lock(); // don't allow any mirror modifications during snapshotting const [node, idNodeMap] = snapshot( tdoc, blockClass, @@ -193,10 +191,7 @@ function record( }, }), ); - if (!wasFrozen) { - mutationBuffer.emit(); // emit anything queued up now - mutationBuffer.unfreeze(); - } + mutationBuffer.unlock(); // generate & emit any mutations that happened during snapshotting, as can now apply against the newly built mirror } try { diff --git a/src/record/mutation.ts b/src/record/mutation.ts index 89b6ee8781..e4ca92b77c 100644 --- a/src/record/mutation.ts +++ b/src/record/mutation.ts @@ -170,20 +170,33 @@ export default class MutationBuffer { public unfreeze() { this.frozen = false; + this.emit(); } public isFrozen() { return this.frozen; } + public lock() { + this.locked = true; + } + + public unlock() { + this.locked = false; + this.emit(); + } + public processMutations = (mutations: mutationRecord[]) => { mutations.forEach(this.processMutation); - if (!this.frozen) { - this.emit(); - } + this.emit(); }; public emit = () => { + + if (this.frozen || this.locked) { + return; + } + // delay any modification of the mirror until this function // so that the mirror for takeFullSnapshot doesn't get mutated while it's event is being processed diff --git a/typings/record/mutation.d.ts b/typings/record/mutation.d.ts index f57d7b8e54..97e18cf179 100644 --- a/typings/record/mutation.d.ts +++ b/typings/record/mutation.d.ts @@ -19,6 +19,8 @@ export default class MutationBuffer { freeze(): void; unfreeze(): void; isFrozen(): boolean; + lock(): void; + unlock(): void; processMutations: (mutations: mutationRecord[]) => void; emit: () => void; private processMutation;