@@ -169,6 +169,7 @@ export default class MutationBuffer {
169169 private addedSet = new Set < Node > ( ) ;
170170 private movedSet = new Set < Node > ( ) ;
171171 private droppedSet = new Set < Node > ( ) ;
172+ private removesSubTreeCache = new Set < Node > ( ) ;
172173
173174 private mutationCb : observerParam [ 'mutationCb' ] ;
174175 private blockClass : observerParam [ 'blockClass' ] ;
@@ -367,7 +368,7 @@ export default class MutationBuffer {
367368
368369 for ( const n of this . movedSet ) {
369370 if (
370- isParentRemoved ( this . removes , n , this . mirror ) &&
371+ isParentRemoved ( this . removesSubTreeCache , n , this . mirror ) &&
371372 ! this . movedSet . has ( dom . parentNode ( n ) ! )
372373 ) {
373374 continue ;
@@ -378,7 +379,7 @@ export default class MutationBuffer {
378379 for ( const n of this . addedSet ) {
379380 if (
380381 ! isAncestorInSet ( this . droppedSet , n ) &&
381- ! isParentRemoved ( this . removes , n , this . mirror )
382+ ! isParentRemoved ( this . removesSubTreeCache , n , this . mirror )
382383 ) {
383384 pushAdd ( n ) ;
384385 } else if ( isAncestorInSet ( this . movedSet , n ) ) {
@@ -514,6 +515,7 @@ export default class MutationBuffer {
514515 this . addedSet = new Set < Node > ( ) ;
515516 this . movedSet = new Set < Node > ( ) ;
516517 this . droppedSet = new Set < Node > ( ) ;
518+ this . removesSubTreeCache = new Set < Node > ( ) ;
517519 this . movedMap = { } ;
518520
519521 this . mutationCb ( payload ) ;
@@ -740,6 +742,7 @@ export default class MutationBuffer {
740742 ? true
741743 : undefined ,
742744 } ) ;
745+ processRemoves ( n , this . removesSubTreeCache ) ;
743746 }
744747 this . mapRemoves . push ( n ) ;
745748 } ) ;
@@ -803,29 +806,33 @@ function deepDelete(addsSet: Set<Node>, n: Node) {
803806 dom . childNodes ( n ) . forEach ( ( childN ) => deepDelete ( addsSet , childN ) ) ;
804807}
805808
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 ;
812825 return _isParentRemoved ( removes , n , mirror ) ;
813826}
814827
815828function _isParentRemoved (
816- removes : removedNodeMutation [ ] ,
829+ removes : Set < Node > ,
817830 n : Node ,
818- mirror : Mirror ,
831+ _mirror : Mirror ,
819832) : 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 ) ;
829836}
830837
831838function isAncestorInSet ( set : Set < Node > , n : Node ) : boolean {
0 commit comments