@@ -169,6 +169,7 @@ export default class MutationBuffer {
169
169
private addedSet = new Set < Node > ( ) ;
170
170
private movedSet = new Set < Node > ( ) ;
171
171
private droppedSet = new Set < Node > ( ) ;
172
+ private removesSubTreeCache = new Set < Node > ( ) ;
172
173
173
174
private mutationCb : observerParam [ 'mutationCb' ] ;
174
175
private blockClass : observerParam [ 'blockClass' ] ;
@@ -367,7 +368,7 @@ export default class MutationBuffer {
367
368
368
369
for ( const n of this . movedSet ) {
369
370
if (
370
- isParentRemoved ( this . removes , n , this . mirror ) &&
371
+ isParentRemoved ( this . removesSubTreeCache , n , this . mirror ) &&
371
372
! this . movedSet . has ( dom . parentNode ( n ) ! )
372
373
) {
373
374
continue ;
@@ -378,7 +379,7 @@ export default class MutationBuffer {
378
379
for ( const n of this . addedSet ) {
379
380
if (
380
381
! isAncestorInSet ( this . droppedSet , n ) &&
381
- ! isParentRemoved ( this . removes , n , this . mirror )
382
+ ! isParentRemoved ( this . removesSubTreeCache , n , this . mirror )
382
383
) {
383
384
pushAdd ( n ) ;
384
385
} else if ( isAncestorInSet ( this . movedSet , n ) ) {
@@ -514,6 +515,7 @@ export default class MutationBuffer {
514
515
this . addedSet = new Set < Node > ( ) ;
515
516
this . movedSet = new Set < Node > ( ) ;
516
517
this . droppedSet = new Set < Node > ( ) ;
518
+ this . removesSubTreeCache = new Set < Node > ( ) ;
517
519
this . movedMap = { } ;
518
520
519
521
this . mutationCb ( payload ) ;
@@ -740,6 +742,7 @@ export default class MutationBuffer {
740
742
? true
741
743
: undefined ,
742
744
} ) ;
745
+ processRemoves ( n , this . removesSubTreeCache ) ;
743
746
}
744
747
this . mapRemoves . push ( n ) ;
745
748
} ) ;
@@ -803,29 +806,33 @@ function deepDelete(addsSet: Set<Node>, n: Node) {
803
806
dom . childNodes ( n ) . forEach ( ( childN ) => deepDelete ( addsSet , childN ) ) ;
804
807
}
805
808
806
- function isParentRemoved (
807
- removes : removedNodeMutation [ ] ,
808
- n : Node ,
809
- mirror : Mirror ,
810
- ) : boolean {
811
- if ( removes . length === 0 ) return false ;
809
+ function processRemoves ( n : Node , cache : Set < Node > ) {
810
+ const queue = [ n ] ;
811
+
812
+ while ( queue . length ) {
813
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
814
+ const next = queue . pop ( ) ! ;
815
+ if ( cache . has ( next ) ) continue ;
816
+ cache . add ( next ) ;
817
+ dom . childNodes ( next ) . forEach ( ( n ) => queue . push ( n ) ) ;
818
+ }
819
+
820
+ return ;
821
+ }
822
+
823
+ function isParentRemoved ( removes : Set < Node > , n : Node , mirror : Mirror ) : boolean {
824
+ if ( removes . size === 0 ) return false ;
812
825
return _isParentRemoved ( removes , n , mirror ) ;
813
826
}
814
827
815
828
function _isParentRemoved (
816
- removes : removedNodeMutation [ ] ,
829
+ removes : Set < Node > ,
817
830
n : Node ,
818
- mirror : Mirror ,
831
+ _mirror : Mirror ,
819
832
) : boolean {
820
- let node : ParentNode | null = dom . parentNode ( n ) ;
821
- while ( node ) {
822
- const parentId = mirror . getId ( node ) ;
823
- if ( removes . some ( ( r ) => r . id === parentId ) ) {
824
- return true ;
825
- }
826
- node = dom . parentNode ( node ) ;
827
- }
828
- return false ;
833
+ const node : ParentNode | null = dom . parentNode ( n ) ;
834
+ if ( ! node ) return false ;
835
+ return removes . has ( node ) ;
829
836
}
830
837
831
838
function isAncestorInSet ( set : Set < Node > , n : Node ) : boolean {
0 commit comments