Precise DOM morphing
morphing typescript dom
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add nodeType and localName maps

+19 -10
+19 -10
src/morphlex.ts
··· 473 473 const seq: Array<number> = [] 474 474 const matches: Array<number> = [] 475 475 const op: Array<Operation> = [] 476 + const nodeTypeMap: Array<number> = [] 477 + const candidateNodeTypeMap: Array<number> = [] 478 + const localNameMap: Array<string> = [] 479 + const candidateLocalNameMap: Array<string> = [] 476 480 477 481 for (let i = 0; i < fromChildNodes.length; i++) { 478 482 const candidate = fromChildNodes[i]! 479 483 const nodeType = candidate.nodeType 484 + candidateNodeTypeMap[i] = nodeType 480 485 481 486 if (nodeType === ELEMENT_NODE_TYPE) { 487 + candidateLocalNameMap[i] = (candidate as Element).localName 482 488 candidateElements.add(i) 483 489 } else if (nodeType === TEXT_NODE_TYPE && candidate.textContent?.trim() === "") { 484 490 whitespaceNodes.add(i) ··· 490 496 for (let i = 0; i < toChildNodes.length; i++) { 491 497 const node = toChildNodes[i]! 492 498 const nodeType = node.nodeType 499 + nodeTypeMap[i] = nodeType 493 500 494 501 if (nodeType === ELEMENT_NODE_TYPE) { 502 + localNameMap[i] = (node as Element).localName 495 503 unmatchedElements.add(i) 496 504 } else if (nodeType === TEXT_NODE_TYPE && node.textContent?.trim() === "") { 497 505 continue ··· 502 510 503 511 // Match elements by isEqualNode 504 512 for (const unmatchedIndex of unmatchedElements) { 513 + const localName = localNameMap[unmatchedIndex] 505 514 const element = toChildNodes[unmatchedIndex] as Element 506 515 507 516 for (const candidateIndex of candidateElements) { 517 + if (localName !== candidateLocalNameMap[candidateIndex]) continue 508 518 const candidate = fromChildNodes[candidateIndex] as Element 509 519 510 520 if (candidate.isEqualNode(element)) { ··· 530 540 candidateLoop: for (const candidateIndex of candidateElements) { 531 541 const candidate = fromChildNodes[candidateIndex] as Element 532 542 533 - if (element.localName === candidate.localName) { 543 + if (localNameMap[unmatchedIndex] === candidateLocalNameMap[candidateIndex]) { 534 544 // Match by exact id 535 545 if (id !== "" && id === candidate.id) { 536 546 matches[unmatchedIndex] = candidateIndex ··· 573 583 for (const candidateIndex of candidateElements) { 574 584 const candidate = fromChildNodes[candidateIndex] as Element 575 585 if ( 576 - element.localName === candidate.localName && 586 + localNameMap[unmatchedIndex] === candidateLocalNameMap[candidateIndex] && 577 587 ((name && name === candidate.getAttribute("name")) || 578 588 (href && href === candidate.getAttribute("href")) || 579 589 (src && src === candidate.getAttribute("src"))) ··· 592 602 for (const unmatchedIndex of unmatchedElements) { 593 603 const element = toChildNodes[unmatchedIndex] as Element 594 604 595 - const localName = element.localName 605 + const localName = localNameMap[unmatchedIndex] 596 606 597 607 for (const candidateIndex of candidateElements) { 598 608 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) { 601 613 // Treat inputs with different type as though they are different tags. 602 614 continue 603 615 } ··· 630 642 631 643 // Match by nodeType 632 644 for (const unmatchedIndex of unmatchedNodes) { 633 - const node = toChildNodes[unmatchedIndex]! 634 - 635 - const nodeType = node.nodeType 645 + const nodeType = nodeTypeMap[unmatchedIndex] 636 646 637 647 for (const candidateIndex of candidateNodes) { 638 - const candidate = fromChildNodes[candidateIndex]! 639 - if (nodeType === candidate.nodeType) { 648 + if (nodeType === candidateNodeTypeMap[candidateIndex]) { 640 649 matches[unmatchedIndex] = candidateIndex 641 650 op[unmatchedIndex] = Operation.SameNode 642 651 seq[candidateIndex] = unmatchedIndex