@@ -473,12 +473,18 @@ class Morph {
473473 const seq : Array < number > = [ ]
474474 const matches : Array < number > = [ ]
475475 const op : Array < Operation > = [ ]
476+ const nodeTypeMap : Array < number > = [ ]
477+ const candidateNodeTypeMap : Array < number > = [ ]
478+ const localNameMap : Array < string > = [ ]
479+ const candidateLocalNameMap : Array < string > = [ ]
476480
477481 for ( let i = 0 ; i < fromChildNodes . length ; i ++ ) {
478482 const candidate = fromChildNodes [ i ] !
479483 const nodeType = candidate . nodeType
484+ candidateNodeTypeMap [ i ] = nodeType
480485
481486 if ( nodeType === ELEMENT_NODE_TYPE ) {
487+ candidateLocalNameMap [ i ] = ( candidate as Element ) . localName
482488 candidateElements . add ( i )
483489 } else if ( nodeType === TEXT_NODE_TYPE && candidate . textContent ?. trim ( ) === "" ) {
484490 whitespaceNodes . add ( i )
@@ -490,8 +496,10 @@ class Morph {
490496 for ( let i = 0 ; i < toChildNodes . length ; i ++ ) {
491497 const node = toChildNodes [ i ] !
492498 const nodeType = node . nodeType
499+ nodeTypeMap [ i ] = nodeType
493500
494501 if ( nodeType === ELEMENT_NODE_TYPE ) {
502+ localNameMap [ i ] = ( node as Element ) . localName
495503 unmatchedElements . add ( i )
496504 } else if ( nodeType === TEXT_NODE_TYPE && node . textContent ?. trim ( ) === "" ) {
497505 continue
@@ -502,9 +510,11 @@ class Morph {
502510
503511 // Match elements by isEqualNode
504512 for ( const unmatchedIndex of unmatchedElements ) {
513+ const localName = localNameMap [ unmatchedIndex ]
505514 const element = toChildNodes [ unmatchedIndex ] as Element
506515
507516 for ( const candidateIndex of candidateElements ) {
517+ if ( localName !== candidateLocalNameMap [ candidateIndex ] ) continue
508518 const candidate = fromChildNodes [ candidateIndex ] as Element
509519
510520 if ( candidate . isEqualNode ( element ) ) {
@@ -530,7 +540,7 @@ class Morph {
530540 candidateLoop: for ( const candidateIndex of candidateElements ) {
531541 const candidate = fromChildNodes [ candidateIndex ] as Element
532542
533- if ( element . localName === candidate . localName ) {
543+ if ( localNameMap [ unmatchedIndex ] === candidateLocalNameMap [ candidateIndex ] ) {
534544 // Match by exact id
535545 if ( id !== "" && id === candidate . id ) {
536546 matches [ unmatchedIndex ] = candidateIndex
@@ -573,7 +583,7 @@ class Morph {
573583 for ( const candidateIndex of candidateElements ) {
574584 const candidate = fromChildNodes [ candidateIndex ] as Element
575585 if (
576- element . localName === candidate . localName &&
586+ localNameMap [ unmatchedIndex ] === candidateLocalNameMap [ candidateIndex ] &&
577587 ( ( name && name === candidate . getAttribute ( "name" ) ) ||
578588 ( href && href === candidate . getAttribute ( "href" ) ) ||
579589 ( src && src === candidate . getAttribute ( "src" ) ) )
@@ -592,12 +602,14 @@ class Morph {
592602 for ( const unmatchedIndex of unmatchedElements ) {
593603 const element = toChildNodes [ unmatchedIndex ] as Element
594604
595- const localName = element . localName
605+ const localName = localNameMap [ unmatchedIndex ]
596606
597607 for ( const candidateIndex of candidateElements ) {
598608 const candidate = fromChildNodes [ candidateIndex ] as Element
599- if ( localName === candidate . localName ) {
600- if ( isInputElement ( candidate ) && isInputElement ( element ) && candidate . type !== element . type ) {
609+ const candidateLocalName = candidateLocalNameMap [ candidateIndex ]
610+
611+ if ( localName === candidateLocalName ) {
612+ if ( localName === "input" && ( candidate as HTMLInputElement ) . type !== ( element as HTMLInputElement ) . type ) {
601613 // Treat inputs with different type as though they are different tags.
602614 continue
603615 }
@@ -630,13 +642,10 @@ class Morph {
630642
631643 // Match by nodeType
632644 for ( const unmatchedIndex of unmatchedNodes ) {
633- const node = toChildNodes [ unmatchedIndex ] !
634-
635- const nodeType = node . nodeType
645+ const nodeType = nodeTypeMap [ unmatchedIndex ]
636646
637647 for ( const candidateIndex of candidateNodes ) {
638- const candidate = fromChildNodes [ candidateIndex ] !
639- if ( nodeType === candidate . nodeType ) {
648+ if ( nodeType === candidateNodeTypeMap [ candidateIndex ] ) {
640649 matches [ unmatchedIndex ] = candidateIndex
641650 op [ unmatchedIndex ] = Operation . SameNode
642651 seq [ candidateIndex ] = unmatchedIndex
0 commit comments