Skip to content

Commit

Permalink
Avoid a build up of duplicate adds by delaying pushing to adds unti…
Browse files Browse the repository at this point in the history
…l emission time
  • Loading branch information
eoghanmurray committed Jun 9, 2020
1 parent e3b7425 commit 410756e
Showing 1 changed file with 65 additions and 63 deletions.
128 changes: 65 additions & 63 deletions src/record/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export default class MutationBuffer {
private texts: textCursor[] = [];
private attributes: attributeCursor[] = [];
private removes: removedNodeMutation[] = [];
private adds: addedNodeMutation[] = [];

private movedMap: Record<string, true> = {};

Expand Down Expand Up @@ -69,66 +68,6 @@ export default class MutationBuffer {
public processMutations = (mutations: mutationRecord[]) => {
mutations.forEach(this.processMutation);

/**
* Sometimes child node may be pushed before its newly added
* parent, so we init a queue to store these nodes.
*/
const addQueue: Node[] = [];
const pushAdd = (n: Node) => {
const parentId = mirror.getId((n.parentNode as Node) as INode);
const nextId =
n.nextSibling && mirror.getId((n.nextSibling as unknown) as INode);
if (parentId === -1 || nextId === -1) {
return addQueue.push(n);
}
this.adds.push({
parentId,
nextId,
node: serializeNodeWithId(
n,
document,
mirror.map,
this.blockClass,
true,
this.inlineStylesheet,
this.maskAllInputs,
)!,
});
};

for (const n of this.movedSet) {
pushAdd(n);
}

for (const n of this.addedSet) {
if (
!isAncestorInSet(this.droppedSet, n) &&
!isParentRemoved(this.removes, n)
) {
pushAdd(n);
} else if (isAncestorInSet(this.movedSet, n)) {
pushAdd(n);
} else {
this.droppedSet.add(n);
}
}

while (addQueue.length) {
if (
addQueue.every(
(n) => mirror.getId((n.parentNode as Node) as INode) === -1,
)
) {
/**
* If all nodes in queue could not find a serialized parent,
* it may be a bug or corner case. We need to escape the
* dead while loop at once.
*/
break;
}
pushAdd(addQueue.shift()!);
}

if (!this.paused) {
this.emit();
}
Expand Down Expand Up @@ -237,6 +176,70 @@ export default class MutationBuffer {
};

public emit = () => {

const adds: addedNodeMutation[] = [];

/**
* Sometimes child node may be pushed before its newly added
* parent, so we init a queue to store these nodes.
*/
const addQueue: Node[] = [];
const pushAdd = (n: Node) => {
const parentId = mirror.getId((n.parentNode as Node) as INode);
const nextId =
n.nextSibling && mirror.getId((n.nextSibling as unknown) as INode);
if (parentId === -1 || nextId === -1) {
return addQueue.push(n);
}
adds.push({
parentId,
nextId,
node: serializeNodeWithId(
n,
document,
mirror.map,
this.blockClass,
true,
this.inlineStylesheet,
this.maskAllInputs,
)!,
});
};

for (const n of this.movedSet) {
pushAdd(n);
}

for (const n of this.addedSet) {
if (
!isAncestorInSet(this.droppedSet, n) &&
!isParentRemoved(this.removes, n)
) {
pushAdd(n);
} else if (isAncestorInSet(this.movedSet, n)) {
pushAdd(n);
} else {
this.droppedSet.add(n);
}
}

while (addQueue.length) {
if (
addQueue.every(
(n) => mirror.getId((n.parentNode as Node) as INode) === -1,
)
) {
/**
* If all nodes in queue could not find a serialized parent,
* it may be a bug or corner case. We need to escape the
* dead while loop at once.
*/
break;
}
pushAdd(addQueue.shift()!);
}


const payload = {
texts: this.texts
.map((text) => ({
Expand All @@ -253,7 +256,7 @@ export default class MutationBuffer {
// attribute mutation's id was not in the mirror map means the target node has been removed
.filter((attribute) => mirror.has(attribute.id)),
removes: this.removes,
adds: this.adds,
adds: adds,
};
// payload may be empty if the mutations happened in some blocked elements
if (
Expand All @@ -270,7 +273,6 @@ export default class MutationBuffer {
this.texts = [];
this.attributes = [];
this.removes = [];
this.adds = [];
this.addedSet = new Set<Node>();
this.movedSet = new Set<Node>();
this.droppedSet = new Set<Node>();
Expand Down

0 comments on commit 410756e

Please sign in to comment.