turbo-rails 2.0.10 → 2.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +1 -1
 - data/app/assets/javascripts/turbo.js +500 -445
 - data/app/assets/javascripts/turbo.min.js +7 -7
 - data/app/assets/javascripts/turbo.min.js.map +1 -1
 - data/app/channels/turbo/streams/broadcasts.rb +4 -2
 - data/app/controllers/turbo/frames/frame_request.rb +1 -0
 - data/app/controllers/turbo/native/navigation.rb +11 -8
 - data/app/helpers/turbo/streams/action_helper.rb +7 -2
 - data/app/models/concerns/turbo/broadcastable.rb +1 -1
 - data/app/models/turbo/streams/tag_builder.rb +2 -2
 - data/lib/turbo/engine.rb +1 -1
 - data/lib/turbo/system_test_helper.rb +4 -4
 - data/lib/turbo/version.rb +1 -1
 - metadata +3 -3
 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            /*!
         
     | 
| 
       2 
     | 
    
         
            -
            Turbo 8.0. 
     | 
| 
       3 
     | 
    
         
            -
            Copyright ©  
     | 
| 
      
 2 
     | 
    
         
            +
            Turbo 8.0.13
         
     | 
| 
      
 3 
     | 
    
         
            +
            Copyright © 2025 37signals LLC
         
     | 
| 
       4 
4 
     | 
    
         
             
             */
         
     | 
| 
       5 
5 
     | 
    
         
             
            (function(prototype) {
         
     | 
| 
       6 
6 
     | 
    
         
             
              if (typeof prototype.requestSubmit == "function") return;
         
     | 
| 
         @@ -181,7 +181,7 @@ function activateScriptElement(element) { 
     | 
|
| 
       181 
181 
     | 
    
         
             
                return element;
         
     | 
| 
       182 
182 
     | 
    
         
             
              } else {
         
     | 
| 
       183 
183 
     | 
    
         
             
                const createdScriptElement = document.createElement("script");
         
     | 
| 
       184 
     | 
    
         
            -
                const cspNonce =  
     | 
| 
      
 184 
     | 
    
         
            +
                const cspNonce = getCspNonce();
         
     | 
| 
       185 
185 
     | 
    
         
             
                if (cspNonce) {
         
     | 
| 
       186 
186 
     | 
    
         
             
                  createdScriptElement.nonce = cspNonce;
         
     | 
| 
       187 
187 
     | 
    
         
             
                }
         
     | 
| 
         @@ -353,6 +353,14 @@ function getMetaContent(name) { 
     | 
|
| 
       353 
353 
     | 
    
         
             
              return element && element.content;
         
     | 
| 
       354 
354 
     | 
    
         
             
            }
         
     | 
| 
       355 
355 
     | 
    
         | 
| 
      
 356 
     | 
    
         
            +
            function getCspNonce() {
         
     | 
| 
      
 357 
     | 
    
         
            +
              const element = getMetaElement("csp-nonce");
         
     | 
| 
      
 358 
     | 
    
         
            +
              if (element) {
         
     | 
| 
      
 359 
     | 
    
         
            +
                const {nonce: nonce, content: content} = element;
         
     | 
| 
      
 360 
     | 
    
         
            +
                return nonce == "" ? content : nonce;
         
     | 
| 
      
 361 
     | 
    
         
            +
              }
         
     | 
| 
      
 362 
     | 
    
         
            +
            }
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
       356 
364 
     | 
    
         
             
            function setMetaContent(name, content) {
         
     | 
| 
       357 
365 
     | 
    
         
             
              let element = getMetaElement(name);
         
     | 
| 
       358 
366 
     | 
    
         
             
              if (!element) {
         
     | 
| 
         @@ -1531,12 +1539,13 @@ function createPlaceholderForPermanentElement(permanentElement) { 
     | 
|
| 
       1531 
1539 
     | 
    
         | 
| 
       1532 
1540 
     | 
    
         
             
            class Renderer {
         
     | 
| 
       1533 
1541 
     | 
    
         
             
              #activeElement=null;
         
     | 
| 
       1534 
     | 
    
         
            -
               
     | 
| 
      
 1542 
     | 
    
         
            +
              static renderElement(currentElement, newElement) {}
         
     | 
| 
      
 1543 
     | 
    
         
            +
              constructor(currentSnapshot, newSnapshot, isPreview, willRender = true) {
         
     | 
| 
       1535 
1544 
     | 
    
         
             
                this.currentSnapshot = currentSnapshot;
         
     | 
| 
       1536 
1545 
     | 
    
         
             
                this.newSnapshot = newSnapshot;
         
     | 
| 
       1537 
1546 
     | 
    
         
             
                this.isPreview = isPreview;
         
     | 
| 
       1538 
1547 
     | 
    
         
             
                this.willRender = willRender;
         
     | 
| 
       1539 
     | 
    
         
            -
                this.renderElement = renderElement;
         
     | 
| 
      
 1548 
     | 
    
         
            +
                this.renderElement = this.constructor.renderElement;
         
     | 
| 
       1540 
1549 
     | 
    
         
             
                this.promise = new Promise(((resolve, reject) => this.resolvingFunctions = {
         
     | 
| 
       1541 
1550 
     | 
    
         
             
                  resolve: resolve,
         
     | 
| 
       1542 
1551 
     | 
    
         
             
                  reject: reject
         
     | 
| 
         @@ -1678,8 +1687,8 @@ function readScrollBehavior(value, defaultValue) { 
     | 
|
| 
       1678 
1687 
     | 
    
         
             
            }
         
     | 
| 
       1679 
1688 
     | 
    
         | 
| 
       1680 
1689 
     | 
    
         
             
            var Idiomorph = function() {
         
     | 
| 
       1681 
     | 
    
         
            -
               
     | 
| 
       1682 
     | 
    
         
            -
               
     | 
| 
      
 1690 
     | 
    
         
            +
              const noOp = () => {};
         
     | 
| 
      
 1691 
     | 
    
         
            +
              const defaults = {
         
     | 
| 
       1683 
1692 
     | 
    
         
             
                morphStyle: "outerHTML",
         
     | 
| 
       1684 
1693 
     | 
    
         
             
                callbacks: {
         
     | 
| 
       1685 
1694 
     | 
    
         
             
                  beforeNodeAdded: noOp,
         
     | 
| 
         @@ -1692,235 +1701,346 @@ var Idiomorph = function() { 
     | 
|
| 
       1692 
1701 
     | 
    
         
             
                },
         
     | 
| 
       1693 
1702 
     | 
    
         
             
                head: {
         
     | 
| 
       1694 
1703 
     | 
    
         
             
                  style: "merge",
         
     | 
| 
       1695 
     | 
    
         
            -
                  shouldPreserve:  
     | 
| 
       1696 
     | 
    
         
            -
             
     | 
| 
       1697 
     | 
    
         
            -
                  },
         
     | 
| 
       1698 
     | 
    
         
            -
                  shouldReAppend: function(elt) {
         
     | 
| 
       1699 
     | 
    
         
            -
                    return elt.getAttribute("im-re-append") === "true";
         
     | 
| 
       1700 
     | 
    
         
            -
                  },
         
     | 
| 
      
 1704 
     | 
    
         
            +
                  shouldPreserve: elt => elt.getAttribute("im-preserve") === "true",
         
     | 
| 
      
 1705 
     | 
    
         
            +
                  shouldReAppend: elt => elt.getAttribute("im-re-append") === "true",
         
     | 
| 
       1701 
1706 
     | 
    
         
             
                  shouldRemove: noOp,
         
     | 
| 
       1702 
1707 
     | 
    
         
             
                  afterHeadMorphed: noOp
         
     | 
| 
       1703 
     | 
    
         
            -
                }
         
     | 
| 
      
 1708 
     | 
    
         
            +
                },
         
     | 
| 
      
 1709 
     | 
    
         
            +
                restoreFocus: true
         
     | 
| 
       1704 
1710 
     | 
    
         
             
              };
         
     | 
| 
       1705 
1711 
     | 
    
         
             
              function morph(oldNode, newContent, config = {}) {
         
     | 
| 
       1706 
     | 
    
         
            -
                 
     | 
| 
       1707 
     | 
    
         
            -
             
     | 
| 
      
 1712 
     | 
    
         
            +
                oldNode = normalizeElement(oldNode);
         
     | 
| 
      
 1713 
     | 
    
         
            +
                const newNode = normalizeParent(newContent);
         
     | 
| 
      
 1714 
     | 
    
         
            +
                const ctx = createMorphContext(oldNode, newNode, config);
         
     | 
| 
      
 1715 
     | 
    
         
            +
                const morphedNodes = saveAndRestoreFocus(ctx, (() => withHeadBlocking(ctx, oldNode, newNode, (ctx => {
         
     | 
| 
      
 1716 
     | 
    
         
            +
                  if (ctx.morphStyle === "innerHTML") {
         
     | 
| 
      
 1717 
     | 
    
         
            +
                    morphChildren(ctx, oldNode, newNode);
         
     | 
| 
      
 1718 
     | 
    
         
            +
                    return Array.from(oldNode.childNodes);
         
     | 
| 
      
 1719 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 1720 
     | 
    
         
            +
                    return morphOuterHTML(ctx, oldNode, newNode);
         
     | 
| 
      
 1721 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1722 
     | 
    
         
            +
                }))));
         
     | 
| 
      
 1723 
     | 
    
         
            +
                ctx.pantry.remove();
         
     | 
| 
      
 1724 
     | 
    
         
            +
                return morphedNodes;
         
     | 
| 
      
 1725 
     | 
    
         
            +
              }
         
     | 
| 
      
 1726 
     | 
    
         
            +
              function morphOuterHTML(ctx, oldNode, newNode) {
         
     | 
| 
      
 1727 
     | 
    
         
            +
                const oldParent = normalizeParent(oldNode);
         
     | 
| 
      
 1728 
     | 
    
         
            +
                let childNodes = Array.from(oldParent.childNodes);
         
     | 
| 
      
 1729 
     | 
    
         
            +
                const index = childNodes.indexOf(oldNode);
         
     | 
| 
      
 1730 
     | 
    
         
            +
                const rightMargin = childNodes.length - (index + 1);
         
     | 
| 
      
 1731 
     | 
    
         
            +
                morphChildren(ctx, oldParent, newNode, oldNode, oldNode.nextSibling);
         
     | 
| 
      
 1732 
     | 
    
         
            +
                childNodes = Array.from(oldParent.childNodes);
         
     | 
| 
      
 1733 
     | 
    
         
            +
                return childNodes.slice(index, childNodes.length - rightMargin);
         
     | 
| 
      
 1734 
     | 
    
         
            +
              }
         
     | 
| 
      
 1735 
     | 
    
         
            +
              function saveAndRestoreFocus(ctx, fn) {
         
     | 
| 
      
 1736 
     | 
    
         
            +
                if (!ctx.config.restoreFocus) return fn();
         
     | 
| 
      
 1737 
     | 
    
         
            +
                let activeElement = document.activeElement;
         
     | 
| 
      
 1738 
     | 
    
         
            +
                if (!(activeElement instanceof HTMLInputElement || activeElement instanceof HTMLTextAreaElement)) {
         
     | 
| 
      
 1739 
     | 
    
         
            +
                  return fn();
         
     | 
| 
      
 1740 
     | 
    
         
            +
                }
         
     | 
| 
      
 1741 
     | 
    
         
            +
                const {id: activeElementId, selectionStart: selectionStart, selectionEnd: selectionEnd} = activeElement;
         
     | 
| 
      
 1742 
     | 
    
         
            +
                const results = fn();
         
     | 
| 
      
 1743 
     | 
    
         
            +
                if (activeElementId && activeElementId !== document.activeElement?.id) {
         
     | 
| 
      
 1744 
     | 
    
         
            +
                  activeElement = ctx.target.querySelector(`#${activeElementId}`);
         
     | 
| 
      
 1745 
     | 
    
         
            +
                  activeElement?.focus();
         
     | 
| 
      
 1746 
     | 
    
         
            +
                }
         
     | 
| 
      
 1747 
     | 
    
         
            +
                if (activeElement && !activeElement.selectionEnd && selectionEnd) {
         
     | 
| 
      
 1748 
     | 
    
         
            +
                  activeElement.setSelectionRange(selectionStart, selectionEnd);
         
     | 
| 
      
 1749 
     | 
    
         
            +
                }
         
     | 
| 
      
 1750 
     | 
    
         
            +
                return results;
         
     | 
| 
      
 1751 
     | 
    
         
            +
              }
         
     | 
| 
      
 1752 
     | 
    
         
            +
              const morphChildren = function() {
         
     | 
| 
      
 1753 
     | 
    
         
            +
                function morphChildren(ctx, oldParent, newParent, insertionPoint = null, endPoint = null) {
         
     | 
| 
      
 1754 
     | 
    
         
            +
                  if (oldParent instanceof HTMLTemplateElement && newParent instanceof HTMLTemplateElement) {
         
     | 
| 
      
 1755 
     | 
    
         
            +
                    oldParent = oldParent.content;
         
     | 
| 
      
 1756 
     | 
    
         
            +
                    newParent = newParent.content;
         
     | 
| 
      
 1757 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1758 
     | 
    
         
            +
                  insertionPoint ||= oldParent.firstChild;
         
     | 
| 
      
 1759 
     | 
    
         
            +
                  for (const newChild of newParent.childNodes) {
         
     | 
| 
      
 1760 
     | 
    
         
            +
                    if (insertionPoint && insertionPoint != endPoint) {
         
     | 
| 
      
 1761 
     | 
    
         
            +
                      const bestMatch = findBestMatch(ctx, newChild, insertionPoint, endPoint);
         
     | 
| 
      
 1762 
     | 
    
         
            +
                      if (bestMatch) {
         
     | 
| 
      
 1763 
     | 
    
         
            +
                        if (bestMatch !== insertionPoint) {
         
     | 
| 
      
 1764 
     | 
    
         
            +
                          removeNodesBetween(ctx, insertionPoint, bestMatch);
         
     | 
| 
      
 1765 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1766 
     | 
    
         
            +
                        morphNode(bestMatch, newChild, ctx);
         
     | 
| 
      
 1767 
     | 
    
         
            +
                        insertionPoint = bestMatch.nextSibling;
         
     | 
| 
      
 1768 
     | 
    
         
            +
                        continue;
         
     | 
| 
      
 1769 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1770 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1771 
     | 
    
         
            +
                    if (newChild instanceof Element && ctx.persistentIds.has(newChild.id)) {
         
     | 
| 
      
 1772 
     | 
    
         
            +
                      const movedChild = moveBeforeById(oldParent, newChild.id, insertionPoint, ctx);
         
     | 
| 
      
 1773 
     | 
    
         
            +
                      morphNode(movedChild, newChild, ctx);
         
     | 
| 
      
 1774 
     | 
    
         
            +
                      insertionPoint = movedChild.nextSibling;
         
     | 
| 
      
 1775 
     | 
    
         
            +
                      continue;
         
     | 
| 
      
 1776 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1777 
     | 
    
         
            +
                    const insertedNode = createNode(oldParent, newChild, insertionPoint, ctx);
         
     | 
| 
      
 1778 
     | 
    
         
            +
                    if (insertedNode) {
         
     | 
| 
      
 1779 
     | 
    
         
            +
                      insertionPoint = insertedNode.nextSibling;
         
     | 
| 
      
 1780 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1781 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1782 
     | 
    
         
            +
                  while (insertionPoint && insertionPoint != endPoint) {
         
     | 
| 
      
 1783 
     | 
    
         
            +
                    const tempNode = insertionPoint;
         
     | 
| 
      
 1784 
     | 
    
         
            +
                    insertionPoint = insertionPoint.nextSibling;
         
     | 
| 
      
 1785 
     | 
    
         
            +
                    removeNode(ctx, tempNode);
         
     | 
| 
      
 1786 
     | 
    
         
            +
                  }
         
     | 
| 
       1708 
1787 
     | 
    
         
             
                }
         
     | 
| 
       1709 
     | 
    
         
            -
                 
     | 
| 
       1710 
     | 
    
         
            -
                   
     | 
| 
      
 1788 
     | 
    
         
            +
                function createNode(oldParent, newChild, insertionPoint, ctx) {
         
     | 
| 
      
 1789 
     | 
    
         
            +
                  if (ctx.callbacks.beforeNodeAdded(newChild) === false) return null;
         
     | 
| 
      
 1790 
     | 
    
         
            +
                  if (ctx.idMap.has(newChild)) {
         
     | 
| 
      
 1791 
     | 
    
         
            +
                    const newEmptyChild = document.createElement(newChild.tagName);
         
     | 
| 
      
 1792 
     | 
    
         
            +
                    oldParent.insertBefore(newEmptyChild, insertionPoint);
         
     | 
| 
      
 1793 
     | 
    
         
            +
                    morphNode(newEmptyChild, newChild, ctx);
         
     | 
| 
      
 1794 
     | 
    
         
            +
                    ctx.callbacks.afterNodeAdded(newEmptyChild);
         
     | 
| 
      
 1795 
     | 
    
         
            +
                    return newEmptyChild;
         
     | 
| 
      
 1796 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 1797 
     | 
    
         
            +
                    const newClonedChild = document.importNode(newChild, true);
         
     | 
| 
      
 1798 
     | 
    
         
            +
                    oldParent.insertBefore(newClonedChild, insertionPoint);
         
     | 
| 
      
 1799 
     | 
    
         
            +
                    ctx.callbacks.afterNodeAdded(newClonedChild);
         
     | 
| 
      
 1800 
     | 
    
         
            +
                    return newClonedChild;
         
     | 
| 
      
 1801 
     | 
    
         
            +
                  }
         
     | 
| 
       1711 
1802 
     | 
    
         
             
                }
         
     | 
| 
       1712 
     | 
    
         
            -
                 
     | 
| 
       1713 
     | 
    
         
            -
             
     | 
| 
       1714 
     | 
    
         
            -
             
     | 
| 
       1715 
     | 
    
         
            -
             
     | 
| 
       1716 
     | 
    
         
            -
             
     | 
| 
       1717 
     | 
    
         
            -
             
     | 
| 
       1718 
     | 
    
         
            -
             
     | 
| 
       1719 
     | 
    
         
            -
             
     | 
| 
       1720 
     | 
    
         
            -
             
     | 
| 
       1721 
     | 
    
         
            -
             
     | 
| 
       1722 
     | 
    
         
            -
                    Promise.all(promises).then((function() {
         
     | 
| 
       1723 
     | 
    
         
            -
                      morphNormalizedContent(oldNode, normalizedNewContent, Object.assign(ctx, {
         
     | 
| 
       1724 
     | 
    
         
            -
                        head: {
         
     | 
| 
       1725 
     | 
    
         
            -
                          block: false,
         
     | 
| 
       1726 
     | 
    
         
            -
                          ignore: true
         
     | 
| 
      
 1803 
     | 
    
         
            +
                const findBestMatch = function() {
         
     | 
| 
      
 1804 
     | 
    
         
            +
                  function findBestMatch(ctx, node, startPoint, endPoint) {
         
     | 
| 
      
 1805 
     | 
    
         
            +
                    let softMatch = null;
         
     | 
| 
      
 1806 
     | 
    
         
            +
                    let nextSibling = node.nextSibling;
         
     | 
| 
      
 1807 
     | 
    
         
            +
                    let siblingSoftMatchCount = 0;
         
     | 
| 
      
 1808 
     | 
    
         
            +
                    let cursor = startPoint;
         
     | 
| 
      
 1809 
     | 
    
         
            +
                    while (cursor && cursor != endPoint) {
         
     | 
| 
      
 1810 
     | 
    
         
            +
                      if (isSoftMatch(cursor, node)) {
         
     | 
| 
      
 1811 
     | 
    
         
            +
                        if (isIdSetMatch(ctx, cursor, node)) {
         
     | 
| 
      
 1812 
     | 
    
         
            +
                          return cursor;
         
     | 
| 
       1727 
1813 
     | 
    
         
             
                        }
         
     | 
| 
       1728 
     | 
    
         
            -
             
     | 
| 
       1729 
     | 
    
         
            -
             
     | 
| 
       1730 
     | 
    
         
            -
             
     | 
| 
      
 1814 
     | 
    
         
            +
                        if (softMatch === null) {
         
     | 
| 
      
 1815 
     | 
    
         
            +
                          if (!ctx.idMap.has(cursor)) {
         
     | 
| 
      
 1816 
     | 
    
         
            +
                            softMatch = cursor;
         
     | 
| 
      
 1817 
     | 
    
         
            +
                          }
         
     | 
| 
      
 1818 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1819 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1820 
     | 
    
         
            +
                      if (softMatch === null && nextSibling && isSoftMatch(cursor, nextSibling)) {
         
     | 
| 
      
 1821 
     | 
    
         
            +
                        siblingSoftMatchCount++;
         
     | 
| 
      
 1822 
     | 
    
         
            +
                        nextSibling = nextSibling.nextSibling;
         
     | 
| 
      
 1823 
     | 
    
         
            +
                        if (siblingSoftMatchCount >= 2) {
         
     | 
| 
      
 1824 
     | 
    
         
            +
                          softMatch = undefined;
         
     | 
| 
      
 1825 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1826 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1827 
     | 
    
         
            +
                      if (cursor.contains(document.activeElement)) break;
         
     | 
| 
      
 1828 
     | 
    
         
            +
                      cursor = cursor.nextSibling;
         
     | 
| 
      
 1829 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1830 
     | 
    
         
            +
                    return softMatch || null;
         
     | 
| 
      
 1831 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1832 
     | 
    
         
            +
                  function isIdSetMatch(ctx, oldNode, newNode) {
         
     | 
| 
      
 1833 
     | 
    
         
            +
                    let oldSet = ctx.idMap.get(oldNode);
         
     | 
| 
      
 1834 
     | 
    
         
            +
                    let newSet = ctx.idMap.get(newNode);
         
     | 
| 
      
 1835 
     | 
    
         
            +
                    if (!newSet || !oldSet) return false;
         
     | 
| 
      
 1836 
     | 
    
         
            +
                    for (const id of oldSet) {
         
     | 
| 
      
 1837 
     | 
    
         
            +
                      if (newSet.has(id)) {
         
     | 
| 
      
 1838 
     | 
    
         
            +
                        return true;
         
     | 
| 
      
 1839 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1840 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1841 
     | 
    
         
            +
                    return false;
         
     | 
| 
      
 1842 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1843 
     | 
    
         
            +
                  function isSoftMatch(oldNode, newNode) {
         
     | 
| 
      
 1844 
     | 
    
         
            +
                    const oldElt = oldNode;
         
     | 
| 
      
 1845 
     | 
    
         
            +
                    const newElt = newNode;
         
     | 
| 
      
 1846 
     | 
    
         
            +
                    return oldElt.nodeType === newElt.nodeType && oldElt.tagName === newElt.tagName && (!oldElt.id || oldElt.id === newElt.id);
         
     | 
| 
      
 1847 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1848 
     | 
    
         
            +
                  return findBestMatch;
         
     | 
| 
      
 1849 
     | 
    
         
            +
                }();
         
     | 
| 
      
 1850 
     | 
    
         
            +
                function removeNode(ctx, node) {
         
     | 
| 
      
 1851 
     | 
    
         
            +
                  if (ctx.idMap.has(node)) {
         
     | 
| 
      
 1852 
     | 
    
         
            +
                    moveBefore(ctx.pantry, node, null);
         
     | 
| 
      
 1853 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 1854 
     | 
    
         
            +
                    if (ctx.callbacks.beforeNodeRemoved(node) === false) return;
         
     | 
| 
      
 1855 
     | 
    
         
            +
                    node.parentNode?.removeChild(node);
         
     | 
| 
      
 1856 
     | 
    
         
            +
                    ctx.callbacks.afterNodeRemoved(node);
         
     | 
| 
       1731 
1857 
     | 
    
         
             
                  }
         
     | 
| 
       1732 
1858 
     | 
    
         
             
                }
         
     | 
| 
       1733 
     | 
    
         
            -
                 
     | 
| 
       1734 
     | 
    
         
            -
                   
     | 
| 
       1735 
     | 
    
         
            -
                   
     | 
| 
       1736 
     | 
    
         
            -
             
     | 
| 
       1737 
     | 
    
         
            -
             
     | 
| 
       1738 
     | 
    
         
            -
             
     | 
| 
       1739 
     | 
    
         
            -
                   
     | 
| 
       1740 
     | 
    
         
            -
                   
     | 
| 
       1741 
     | 
    
         
            -
             
     | 
| 
       1742 
     | 
    
         
            -
             
     | 
| 
      
 1859 
     | 
    
         
            +
                function removeNodesBetween(ctx, startInclusive, endExclusive) {
         
     | 
| 
      
 1860 
     | 
    
         
            +
                  let cursor = startInclusive;
         
     | 
| 
      
 1861 
     | 
    
         
            +
                  while (cursor && cursor !== endExclusive) {
         
     | 
| 
      
 1862 
     | 
    
         
            +
                    let tempNode = cursor;
         
     | 
| 
      
 1863 
     | 
    
         
            +
                    cursor = cursor.nextSibling;
         
     | 
| 
      
 1864 
     | 
    
         
            +
                    removeNode(ctx, tempNode);
         
     | 
| 
      
 1865 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1866 
     | 
    
         
            +
                  return cursor;
         
     | 
| 
      
 1867 
     | 
    
         
            +
                }
         
     | 
| 
      
 1868 
     | 
    
         
            +
                function moveBeforeById(parentNode, id, after, ctx) {
         
     | 
| 
      
 1869 
     | 
    
         
            +
                  const target = ctx.target.querySelector(`#${id}`) || ctx.pantry.querySelector(`#${id}`);
         
     | 
| 
      
 1870 
     | 
    
         
            +
                  removeElementFromAncestorsIdMaps(target, ctx);
         
     | 
| 
      
 1871 
     | 
    
         
            +
                  moveBefore(parentNode, target, after);
         
     | 
| 
      
 1872 
     | 
    
         
            +
                  return target;
         
     | 
| 
      
 1873 
     | 
    
         
            +
                }
         
     | 
| 
      
 1874 
     | 
    
         
            +
                function removeElementFromAncestorsIdMaps(element, ctx) {
         
     | 
| 
      
 1875 
     | 
    
         
            +
                  const id = element.id;
         
     | 
| 
      
 1876 
     | 
    
         
            +
                  while (element = element.parentNode) {
         
     | 
| 
      
 1877 
     | 
    
         
            +
                    let idSet = ctx.idMap.get(element);
         
     | 
| 
      
 1878 
     | 
    
         
            +
                    if (idSet) {
         
     | 
| 
      
 1879 
     | 
    
         
            +
                      idSet.delete(id);
         
     | 
| 
      
 1880 
     | 
    
         
            +
                      if (!idSet.size) {
         
     | 
| 
      
 1881 
     | 
    
         
            +
                        ctx.idMap.delete(element);
         
     | 
| 
      
 1882 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1883 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1884 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1885 
     | 
    
         
            +
                }
         
     | 
| 
      
 1886 
     | 
    
         
            +
                function moveBefore(parentNode, element, after) {
         
     | 
| 
      
 1887 
     | 
    
         
            +
                  if (parentNode.moveBefore) {
         
     | 
| 
      
 1888 
     | 
    
         
            +
                    try {
         
     | 
| 
      
 1889 
     | 
    
         
            +
                      parentNode.moveBefore(element, after);
         
     | 
| 
      
 1890 
     | 
    
         
            +
                    } catch (e) {
         
     | 
| 
      
 1891 
     | 
    
         
            +
                      parentNode.insertBefore(element, after);
         
     | 
| 
      
 1892 
     | 
    
         
            +
                    }
         
     | 
| 
       1743 
1893 
     | 
    
         
             
                  } else {
         
     | 
| 
       1744 
     | 
    
         
            -
                     
     | 
| 
      
 1894 
     | 
    
         
            +
                    parentNode.insertBefore(element, after);
         
     | 
| 
       1745 
1895 
     | 
    
         
             
                  }
         
     | 
| 
       1746 
     | 
    
         
            -
                } else {
         
     | 
| 
       1747 
     | 
    
         
            -
                  throw "Do not understand how to morph style " + ctx.morphStyle;
         
     | 
| 
       1748 
1896 
     | 
    
         
             
                }
         
     | 
| 
       1749 
     | 
    
         
            -
             
     | 
| 
       1750 
     | 
    
         
            -
               
     | 
| 
       1751 
     | 
    
         
            -
             
     | 
| 
       1752 
     | 
    
         
            -
             
     | 
| 
       1753 
     | 
    
         
            -
             
     | 
| 
       1754 
     | 
    
         
            -
             
     | 
| 
       1755 
     | 
    
         
            -
                   
     | 
| 
       1756 
     | 
    
         
            -
                   
     | 
| 
       1757 
     | 
    
         
            -
             
     | 
| 
       1758 
     | 
    
         
            -
                   
     | 
| 
       1759 
     | 
    
         
            -
                } else if (!isSoftMatch(oldNode, newContent)) {
         
     | 
| 
       1760 
     | 
    
         
            -
                  if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;
         
     | 
| 
       1761 
     | 
    
         
            -
                  if (ctx.callbacks.beforeNodeAdded(newContent) === false) return oldNode;
         
     | 
| 
       1762 
     | 
    
         
            -
                  oldNode.parentElement.replaceChild(newContent, oldNode);
         
     | 
| 
       1763 
     | 
    
         
            -
                  ctx.callbacks.afterNodeAdded(newContent);
         
     | 
| 
       1764 
     | 
    
         
            -
                  ctx.callbacks.afterNodeRemoved(oldNode);
         
     | 
| 
       1765 
     | 
    
         
            -
                  return newContent;
         
     | 
| 
       1766 
     | 
    
         
            -
                } else {
         
     | 
| 
       1767 
     | 
    
         
            -
                  if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) return oldNode;
         
     | 
| 
      
 1897 
     | 
    
         
            +
                return morphChildren;
         
     | 
| 
      
 1898 
     | 
    
         
            +
              }();
         
     | 
| 
      
 1899 
     | 
    
         
            +
              const morphNode = function() {
         
     | 
| 
      
 1900 
     | 
    
         
            +
                function morphNode(oldNode, newContent, ctx) {
         
     | 
| 
      
 1901 
     | 
    
         
            +
                  if (ctx.ignoreActive && oldNode === document.activeElement) {
         
     | 
| 
      
 1902 
     | 
    
         
            +
                    return null;
         
     | 
| 
      
 1903 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1904 
     | 
    
         
            +
                  if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) {
         
     | 
| 
      
 1905 
     | 
    
         
            +
                    return oldNode;
         
     | 
| 
      
 1906 
     | 
    
         
            +
                  }
         
     | 
| 
       1768 
1907 
     | 
    
         
             
                  if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) ; else if (oldNode instanceof HTMLHeadElement && ctx.head.style !== "morph") {
         
     | 
| 
       1769 
     | 
    
         
            -
                    handleHeadElement( 
     | 
| 
      
 1908 
     | 
    
         
            +
                    handleHeadElement(oldNode, newContent, ctx);
         
     | 
| 
       1770 
1909 
     | 
    
         
             
                  } else {
         
     | 
| 
       1771 
     | 
    
         
            -
                     
     | 
| 
      
 1910 
     | 
    
         
            +
                    morphAttributes(oldNode, newContent, ctx);
         
     | 
| 
       1772 
1911 
     | 
    
         
             
                    if (!ignoreValueOfActiveElement(oldNode, ctx)) {
         
     | 
| 
       1773 
     | 
    
         
            -
                      morphChildren( 
     | 
| 
      
 1912 
     | 
    
         
            +
                      morphChildren(ctx, oldNode, newContent);
         
     | 
| 
       1774 
1913 
     | 
    
         
             
                    }
         
     | 
| 
       1775 
1914 
     | 
    
         
             
                  }
         
     | 
| 
       1776 
1915 
     | 
    
         
             
                  ctx.callbacks.afterNodeMorphed(oldNode, newContent);
         
     | 
| 
       1777 
1916 
     | 
    
         
             
                  return oldNode;
         
     | 
| 
       1778 
1917 
     | 
    
         
             
                }
         
     | 
| 
       1779 
     | 
    
         
            -
             
     | 
| 
       1780 
     | 
    
         
            -
             
     | 
| 
       1781 
     | 
    
         
            -
             
     | 
| 
       1782 
     | 
    
         
            -
             
     | 
| 
       1783 
     | 
    
         
            -
             
     | 
| 
       1784 
     | 
    
         
            -
             
     | 
| 
       1785 
     | 
    
         
            -
             
     | 
| 
       1786 
     | 
    
         
            -
             
     | 
| 
       1787 
     | 
    
         
            -
             
     | 
| 
       1788 
     | 
    
         
            -
             
     | 
| 
       1789 
     | 
    
         
            -
             
     | 
| 
       1790 
     | 
    
         
            -
             
     | 
| 
       1791 
     | 
    
         
            -
             
     | 
| 
       1792 
     | 
    
         
            -
             
     | 
| 
       1793 
     | 
    
         
            -
             
     | 
| 
       1794 
     | 
    
         
            -
             
     | 
| 
       1795 
     | 
    
         
            -
             
     | 
| 
       1796 
     | 
    
         
            -
             
     | 
| 
       1797 
     | 
    
         
            -
             
     | 
| 
       1798 
     | 
    
         
            -
             
     | 
| 
       1799 
     | 
    
         
            -
             
     | 
| 
       1800 
     | 
    
         
            -
             
     | 
| 
       1801 
     | 
    
         
            -
             
     | 
| 
       1802 
     | 
    
         
            -
             
     | 
| 
       1803 
     | 
    
         
            -
                     
     | 
| 
       1804 
     | 
    
         
            -
                     
     | 
| 
       1805 
     | 
    
         
            -
             
     | 
| 
      
 1918 
     | 
    
         
            +
                function morphAttributes(oldNode, newNode, ctx) {
         
     | 
| 
      
 1919 
     | 
    
         
            +
                  let type = newNode.nodeType;
         
     | 
| 
      
 1920 
     | 
    
         
            +
                  if (type === 1) {
         
     | 
| 
      
 1921 
     | 
    
         
            +
                    const oldElt = oldNode;
         
     | 
| 
      
 1922 
     | 
    
         
            +
                    const newElt = newNode;
         
     | 
| 
      
 1923 
     | 
    
         
            +
                    const oldAttributes = oldElt.attributes;
         
     | 
| 
      
 1924 
     | 
    
         
            +
                    const newAttributes = newElt.attributes;
         
     | 
| 
      
 1925 
     | 
    
         
            +
                    for (const newAttribute of newAttributes) {
         
     | 
| 
      
 1926 
     | 
    
         
            +
                      if (ignoreAttribute(newAttribute.name, oldElt, "update", ctx)) {
         
     | 
| 
      
 1927 
     | 
    
         
            +
                        continue;
         
     | 
| 
      
 1928 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1929 
     | 
    
         
            +
                      if (oldElt.getAttribute(newAttribute.name) !== newAttribute.value) {
         
     | 
| 
      
 1930 
     | 
    
         
            +
                        oldElt.setAttribute(newAttribute.name, newAttribute.value);
         
     | 
| 
      
 1931 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1932 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1933 
     | 
    
         
            +
                    for (let i = oldAttributes.length - 1; 0 <= i; i--) {
         
     | 
| 
      
 1934 
     | 
    
         
            +
                      const oldAttribute = oldAttributes[i];
         
     | 
| 
      
 1935 
     | 
    
         
            +
                      if (!oldAttribute) continue;
         
     | 
| 
      
 1936 
     | 
    
         
            +
                      if (!newElt.hasAttribute(oldAttribute.name)) {
         
     | 
| 
      
 1937 
     | 
    
         
            +
                        if (ignoreAttribute(oldAttribute.name, oldElt, "remove", ctx)) {
         
     | 
| 
      
 1938 
     | 
    
         
            +
                          continue;
         
     | 
| 
      
 1939 
     | 
    
         
            +
                        }
         
     | 
| 
      
 1940 
     | 
    
         
            +
                        oldElt.removeAttribute(oldAttribute.name);
         
     | 
| 
      
 1941 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1942 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1943 
     | 
    
         
            +
                    if (!ignoreValueOfActiveElement(oldElt, ctx)) {
         
     | 
| 
      
 1944 
     | 
    
         
            +
                      syncInputValue(oldElt, newElt, ctx);
         
     | 
| 
      
 1945 
     | 
    
         
            +
                    }
         
     | 
| 
       1806 
1946 
     | 
    
         
             
                  }
         
     | 
| 
       1807 
     | 
    
         
            -
                   
     | 
| 
       1808 
     | 
    
         
            -
             
     | 
| 
       1809 
     | 
    
         
            -
             
     | 
| 
       1810 
     | 
    
         
            -
                     
     | 
| 
       1811 
     | 
    
         
            -
                    removeIdsFromConsideration(ctx, newChild);
         
     | 
| 
       1812 
     | 
    
         
            -
                    continue;
         
     | 
| 
      
 1947 
     | 
    
         
            +
                  if (type === 8 || type === 3) {
         
     | 
| 
      
 1948 
     | 
    
         
            +
                    if (oldNode.nodeValue !== newNode.nodeValue) {
         
     | 
| 
      
 1949 
     | 
    
         
            +
                      oldNode.nodeValue = newNode.nodeValue;
         
     | 
| 
      
 1950 
     | 
    
         
            +
                    }
         
     | 
| 
       1813 
1951 
     | 
    
         
             
                  }
         
     | 
| 
       1814 
     | 
    
         
            -
                  if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;
         
     | 
| 
       1815 
     | 
    
         
            -
                  oldParent.insertBefore(newChild, insertionPoint);
         
     | 
| 
       1816 
     | 
    
         
            -
                  ctx.callbacks.afterNodeAdded(newChild);
         
     | 
| 
       1817 
     | 
    
         
            -
                  removeIdsFromConsideration(ctx, newChild);
         
     | 
| 
       1818 
1952 
     | 
    
         
             
                }
         
     | 
| 
       1819 
     | 
    
         
            -
                 
     | 
| 
       1820 
     | 
    
         
            -
                   
     | 
| 
       1821 
     | 
    
         
            -
             
     | 
| 
       1822 
     | 
    
         
            -
             
     | 
| 
       1823 
     | 
    
         
            -
             
     | 
| 
       1824 
     | 
    
         
            -
             
     | 
| 
       1825 
     | 
    
         
            -
             
     | 
| 
       1826 
     | 
    
         
            -
             
     | 
| 
       1827 
     | 
    
         
            -
             
     | 
| 
       1828 
     | 
    
         
            -
             
     | 
| 
       1829 
     | 
    
         
            -
             
     | 
| 
       1830 
     | 
    
         
            -
             
     | 
| 
       1831 
     | 
    
         
            -
             
     | 
| 
       1832 
     | 
    
         
            -
             
     | 
| 
       1833 
     | 
    
         
            -
             
     | 
| 
       1834 
     | 
    
         
            -
             
     | 
| 
       1835 
     | 
    
         
            -
                  const toAttributes = to.attributes;
         
     | 
| 
       1836 
     | 
    
         
            -
                  for (const fromAttribute of fromAttributes) {
         
     | 
| 
       1837 
     | 
    
         
            -
                    if (ignoreAttribute(fromAttribute.name, to, "update", ctx)) {
         
     | 
| 
       1838 
     | 
    
         
            -
                      continue;
         
     | 
| 
      
 1953 
     | 
    
         
            +
                function syncInputValue(oldElement, newElement, ctx) {
         
     | 
| 
      
 1954 
     | 
    
         
            +
                  if (oldElement instanceof HTMLInputElement && newElement instanceof HTMLInputElement && newElement.type !== "file") {
         
     | 
| 
      
 1955 
     | 
    
         
            +
                    let newValue = newElement.value;
         
     | 
| 
      
 1956 
     | 
    
         
            +
                    let oldValue = oldElement.value;
         
     | 
| 
      
 1957 
     | 
    
         
            +
                    syncBooleanAttribute(oldElement, newElement, "checked", ctx);
         
     | 
| 
      
 1958 
     | 
    
         
            +
                    syncBooleanAttribute(oldElement, newElement, "disabled", ctx);
         
     | 
| 
      
 1959 
     | 
    
         
            +
                    if (!newElement.hasAttribute("value")) {
         
     | 
| 
      
 1960 
     | 
    
         
            +
                      if (!ignoreAttribute("value", oldElement, "remove", ctx)) {
         
     | 
| 
      
 1961 
     | 
    
         
            +
                        oldElement.value = "";
         
     | 
| 
      
 1962 
     | 
    
         
            +
                        oldElement.removeAttribute("value");
         
     | 
| 
      
 1963 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1964 
     | 
    
         
            +
                    } else if (oldValue !== newValue) {
         
     | 
| 
      
 1965 
     | 
    
         
            +
                      if (!ignoreAttribute("value", oldElement, "update", ctx)) {
         
     | 
| 
      
 1966 
     | 
    
         
            +
                        oldElement.setAttribute("value", newValue);
         
     | 
| 
      
 1967 
     | 
    
         
            +
                        oldElement.value = newValue;
         
     | 
| 
      
 1968 
     | 
    
         
            +
                      }
         
     | 
| 
       1839 
1969 
     | 
    
         
             
                    }
         
     | 
| 
       1840 
     | 
    
         
            -
             
     | 
| 
       1841 
     | 
    
         
            -
             
     | 
| 
      
 1970 
     | 
    
         
            +
                  } else if (oldElement instanceof HTMLOptionElement && newElement instanceof HTMLOptionElement) {
         
     | 
| 
      
 1971 
     | 
    
         
            +
                    syncBooleanAttribute(oldElement, newElement, "selected", ctx);
         
     | 
| 
      
 1972 
     | 
    
         
            +
                  } else if (oldElement instanceof HTMLTextAreaElement && newElement instanceof HTMLTextAreaElement) {
         
     | 
| 
      
 1973 
     | 
    
         
            +
                    let newValue = newElement.value;
         
     | 
| 
      
 1974 
     | 
    
         
            +
                    let oldValue = oldElement.value;
         
     | 
| 
      
 1975 
     | 
    
         
            +
                    if (ignoreAttribute("value", oldElement, "update", ctx)) {
         
     | 
| 
      
 1976 
     | 
    
         
            +
                      return;
         
     | 
| 
       1842 
1977 
     | 
    
         
             
                    }
         
     | 
| 
       1843 
     | 
    
         
            -
             
     | 
| 
       1844 
     | 
    
         
            -
             
     | 
| 
       1845 
     | 
    
         
            -
                    const toAttribute = toAttributes[i];
         
     | 
| 
       1846 
     | 
    
         
            -
                    if (ignoreAttribute(toAttribute.name, to, "remove", ctx)) {
         
     | 
| 
       1847 
     | 
    
         
            -
                      continue;
         
     | 
| 
      
 1978 
     | 
    
         
            +
                    if (newValue !== oldValue) {
         
     | 
| 
      
 1979 
     | 
    
         
            +
                      oldElement.value = newValue;
         
     | 
| 
       1848 
1980 
     | 
    
         
             
                    }
         
     | 
| 
       1849 
     | 
    
         
            -
                    if ( 
     | 
| 
       1850 
     | 
    
         
            -
                       
     | 
| 
      
 1981 
     | 
    
         
            +
                    if (oldElement.firstChild && oldElement.firstChild.nodeValue !== newValue) {
         
     | 
| 
      
 1982 
     | 
    
         
            +
                      oldElement.firstChild.nodeValue = newValue;
         
     | 
| 
       1851 
1983 
     | 
    
         
             
                    }
         
     | 
| 
       1852 
1984 
     | 
    
         
             
                  }
         
     | 
| 
       1853 
1985 
     | 
    
         
             
                }
         
     | 
| 
       1854 
     | 
    
         
            -
                 
     | 
| 
       1855 
     | 
    
         
            -
                   
     | 
| 
       1856 
     | 
    
         
            -
             
     | 
| 
       1857 
     | 
    
         
            -
             
     | 
| 
       1858 
     | 
    
         
            -
                }
         
     | 
| 
       1859 
     | 
    
         
            -
                if (!ignoreValueOfActiveElement(to, ctx)) {
         
     | 
| 
       1860 
     | 
    
         
            -
                  syncInputValue(from, to, ctx);
         
     | 
| 
       1861 
     | 
    
         
            -
                }
         
     | 
| 
       1862 
     | 
    
         
            -
              }
         
     | 
| 
       1863 
     | 
    
         
            -
              function syncBooleanAttribute(from, to, attributeName, ctx) {
         
     | 
| 
       1864 
     | 
    
         
            -
                if (from[attributeName] !== to[attributeName]) {
         
     | 
| 
       1865 
     | 
    
         
            -
                  let ignoreUpdate = ignoreAttribute(attributeName, to, "update", ctx);
         
     | 
| 
       1866 
     | 
    
         
            -
                  if (!ignoreUpdate) {
         
     | 
| 
       1867 
     | 
    
         
            -
                    to[attributeName] = from[attributeName];
         
     | 
| 
       1868 
     | 
    
         
            -
                  }
         
     | 
| 
       1869 
     | 
    
         
            -
                  if (from[attributeName]) {
         
     | 
| 
      
 1986 
     | 
    
         
            +
                function syncBooleanAttribute(oldElement, newElement, attributeName, ctx) {
         
     | 
| 
      
 1987 
     | 
    
         
            +
                  const newLiveValue = newElement[attributeName], oldLiveValue = oldElement[attributeName];
         
     | 
| 
      
 1988 
     | 
    
         
            +
                  if (newLiveValue !== oldLiveValue) {
         
     | 
| 
      
 1989 
     | 
    
         
            +
                    const ignoreUpdate = ignoreAttribute(attributeName, oldElement, "update", ctx);
         
     | 
| 
       1870 
1990 
     | 
    
         
             
                    if (!ignoreUpdate) {
         
     | 
| 
       1871 
     | 
    
         
            -
                       
     | 
| 
      
 1991 
     | 
    
         
            +
                      oldElement[attributeName] = newElement[attributeName];
         
     | 
| 
       1872 
1992 
     | 
    
         
             
                    }
         
     | 
| 
       1873 
     | 
    
         
            -
             
     | 
| 
       1874 
     | 
    
         
            -
             
     | 
| 
       1875 
     | 
    
         
            -
             
     | 
| 
      
 1993 
     | 
    
         
            +
                    if (newLiveValue) {
         
     | 
| 
      
 1994 
     | 
    
         
            +
                      if (!ignoreUpdate) {
         
     | 
| 
      
 1995 
     | 
    
         
            +
                        oldElement.setAttribute(attributeName, "");
         
     | 
| 
      
 1996 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1997 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 1998 
     | 
    
         
            +
                      if (!ignoreAttribute(attributeName, oldElement, "remove", ctx)) {
         
     | 
| 
      
 1999 
     | 
    
         
            +
                        oldElement.removeAttribute(attributeName);
         
     | 
| 
      
 2000 
     | 
    
         
            +
                      }
         
     | 
| 
       1876 
2001 
     | 
    
         
             
                    }
         
     | 
| 
       1877 
2002 
     | 
    
         
             
                  }
         
     | 
| 
       1878 
2003 
     | 
    
         
             
                }
         
     | 
| 
       1879 
     | 
    
         
            -
             
     | 
| 
       1880 
     | 
    
         
            -
             
     | 
| 
       1881 
     | 
    
         
            -
             
     | 
| 
       1882 
     | 
    
         
            -
                  let fromValue = from.value;
         
     | 
| 
       1883 
     | 
    
         
            -
                  let toValue = to.value;
         
     | 
| 
       1884 
     | 
    
         
            -
                  syncBooleanAttribute(from, to, "checked", ctx);
         
     | 
| 
       1885 
     | 
    
         
            -
                  syncBooleanAttribute(from, to, "disabled", ctx);
         
     | 
| 
       1886 
     | 
    
         
            -
                  if (!from.hasAttribute("value")) {
         
     | 
| 
       1887 
     | 
    
         
            -
                    if (!ignoreAttribute("value", to, "remove", ctx)) {
         
     | 
| 
       1888 
     | 
    
         
            -
                      to.value = "";
         
     | 
| 
       1889 
     | 
    
         
            -
                      to.removeAttribute("value");
         
     | 
| 
       1890 
     | 
    
         
            -
                    }
         
     | 
| 
       1891 
     | 
    
         
            -
                  } else if (fromValue !== toValue) {
         
     | 
| 
       1892 
     | 
    
         
            -
                    if (!ignoreAttribute("value", to, "update", ctx)) {
         
     | 
| 
       1893 
     | 
    
         
            -
                      to.setAttribute("value", fromValue);
         
     | 
| 
       1894 
     | 
    
         
            -
                      to.value = fromValue;
         
     | 
| 
       1895 
     | 
    
         
            -
                    }
         
     | 
| 
       1896 
     | 
    
         
            -
                  }
         
     | 
| 
       1897 
     | 
    
         
            -
                } else if (from instanceof HTMLOptionElement) {
         
     | 
| 
       1898 
     | 
    
         
            -
                  syncBooleanAttribute(from, to, "selected", ctx);
         
     | 
| 
       1899 
     | 
    
         
            -
                } else if (from instanceof HTMLTextAreaElement && to instanceof HTMLTextAreaElement) {
         
     | 
| 
       1900 
     | 
    
         
            -
                  let fromValue = from.value;
         
     | 
| 
       1901 
     | 
    
         
            -
                  let toValue = to.value;
         
     | 
| 
       1902 
     | 
    
         
            -
                  if (ignoreAttribute("value", to, "update", ctx)) {
         
     | 
| 
       1903 
     | 
    
         
            -
                    return;
         
     | 
| 
       1904 
     | 
    
         
            -
                  }
         
     | 
| 
       1905 
     | 
    
         
            -
                  if (fromValue !== toValue) {
         
     | 
| 
       1906 
     | 
    
         
            -
                    to.value = fromValue;
         
     | 
| 
      
 2004 
     | 
    
         
            +
                function ignoreAttribute(attr, element, updateType, ctx) {
         
     | 
| 
      
 2005 
     | 
    
         
            +
                  if (attr === "value" && ctx.ignoreActiveValue && element === document.activeElement) {
         
     | 
| 
      
 2006 
     | 
    
         
            +
                    return true;
         
     | 
| 
       1907 
2007 
     | 
    
         
             
                  }
         
     | 
| 
       1908 
     | 
    
         
            -
                   
     | 
| 
       1909 
     | 
    
         
            -
             
     | 
| 
      
 2008 
     | 
    
         
            +
                  return ctx.callbacks.beforeAttributeUpdated(attr, element, updateType) === false;
         
     | 
| 
      
 2009 
     | 
    
         
            +
                }
         
     | 
| 
      
 2010 
     | 
    
         
            +
                function ignoreValueOfActiveElement(possibleActiveElement, ctx) {
         
     | 
| 
      
 2011 
     | 
    
         
            +
                  return !!ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;
         
     | 
| 
      
 2012 
     | 
    
         
            +
                }
         
     | 
| 
      
 2013 
     | 
    
         
            +
                return morphNode;
         
     | 
| 
      
 2014 
     | 
    
         
            +
              }();
         
     | 
| 
      
 2015 
     | 
    
         
            +
              function withHeadBlocking(ctx, oldNode, newNode, callback) {
         
     | 
| 
      
 2016 
     | 
    
         
            +
                if (ctx.head.block) {
         
     | 
| 
      
 2017 
     | 
    
         
            +
                  const oldHead = oldNode.querySelector("head");
         
     | 
| 
      
 2018 
     | 
    
         
            +
                  const newHead = newNode.querySelector("head");
         
     | 
| 
      
 2019 
     | 
    
         
            +
                  if (oldHead && newHead) {
         
     | 
| 
      
 2020 
     | 
    
         
            +
                    const promises = handleHeadElement(oldHead, newHead, ctx);
         
     | 
| 
      
 2021 
     | 
    
         
            +
                    return Promise.all(promises).then((() => {
         
     | 
| 
      
 2022 
     | 
    
         
            +
                      const newCtx = Object.assign(ctx, {
         
     | 
| 
      
 2023 
     | 
    
         
            +
                        head: {
         
     | 
| 
      
 2024 
     | 
    
         
            +
                          block: false,
         
     | 
| 
      
 2025 
     | 
    
         
            +
                          ignore: true
         
     | 
| 
      
 2026 
     | 
    
         
            +
                        }
         
     | 
| 
      
 2027 
     | 
    
         
            +
                      });
         
     | 
| 
      
 2028 
     | 
    
         
            +
                      return callback(newCtx);
         
     | 
| 
      
 2029 
     | 
    
         
            +
                    }));
         
     | 
| 
       1910 
2030 
     | 
    
         
             
                  }
         
     | 
| 
       1911 
2031 
     | 
    
         
             
                }
         
     | 
| 
      
 2032 
     | 
    
         
            +
                return callback(ctx);
         
     | 
| 
       1912 
2033 
     | 
    
         
             
              }
         
     | 
| 
       1913 
     | 
    
         
            -
              function handleHeadElement( 
     | 
| 
      
 2034 
     | 
    
         
            +
              function handleHeadElement(oldHead, newHead, ctx) {
         
     | 
| 
       1914 
2035 
     | 
    
         
             
                let added = [];
         
     | 
| 
       1915 
2036 
     | 
    
         
             
                let removed = [];
         
     | 
| 
       1916 
2037 
     | 
    
         
             
                let preserved = [];
         
     | 
| 
       1917 
2038 
     | 
    
         
             
                let nodesToAppend = [];
         
     | 
| 
       1918 
     | 
    
         
            -
                let headMergeStyle = ctx.head.style;
         
     | 
| 
       1919 
2039 
     | 
    
         
             
                let srcToNewHeadNodes = new Map;
         
     | 
| 
       1920 
     | 
    
         
            -
                for (const newHeadChild of  
     | 
| 
      
 2040 
     | 
    
         
            +
                for (const newHeadChild of newHead.children) {
         
     | 
| 
       1921 
2041 
     | 
    
         
             
                  srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);
         
     | 
| 
       1922 
2042 
     | 
    
         
             
                }
         
     | 
| 
       1923 
     | 
    
         
            -
                for (const currentHeadElt of  
     | 
| 
      
 2043 
     | 
    
         
            +
                for (const currentHeadElt of oldHead.children) {
         
     | 
| 
       1924 
2044 
     | 
    
         
             
                  let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);
         
     | 
| 
       1925 
2045 
     | 
    
         
             
                  let isReAppended = ctx.head.shouldReAppend(currentHeadElt);
         
     | 
| 
       1926 
2046 
     | 
    
         
             
                  let isPreserved = ctx.head.shouldPreserve(currentHeadElt);
         
     | 
| 
         @@ -1932,7 +2052,7 @@ var Idiomorph = function() { 
     | 
|
| 
       1932 
2052 
     | 
    
         
             
                      preserved.push(currentHeadElt);
         
     | 
| 
       1933 
2053 
     | 
    
         
             
                    }
         
     | 
| 
       1934 
2054 
     | 
    
         
             
                  } else {
         
     | 
| 
       1935 
     | 
    
         
            -
                    if ( 
     | 
| 
      
 2055 
     | 
    
         
            +
                    if (ctx.head.style === "append") {
         
     | 
| 
       1936 
2056 
     | 
    
         
             
                      if (isReAppended) {
         
     | 
| 
       1937 
2057 
     | 
    
         
             
                        removed.push(currentHeadElt);
         
     | 
| 
       1938 
2058 
     | 
    
         
             
                        nodesToAppend.push(currentHeadElt);
         
     | 
| 
         @@ -1949,8 +2069,8 @@ var Idiomorph = function() { 
     | 
|
| 
       1949 
2069 
     | 
    
         
             
                for (const newNode of nodesToAppend) {
         
     | 
| 
       1950 
2070 
     | 
    
         
             
                  let newElt = document.createRange().createContextualFragment(newNode.outerHTML).firstChild;
         
     | 
| 
       1951 
2071 
     | 
    
         
             
                  if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {
         
     | 
| 
       1952 
     | 
    
         
            -
                    if (newElt.href || newElt.src) {
         
     | 
| 
       1953 
     | 
    
         
            -
                      let resolve 
     | 
| 
      
 2072 
     | 
    
         
            +
                    if ("href" in newElt && newElt.href || "src" in newElt && newElt.src) {
         
     | 
| 
      
 2073 
     | 
    
         
            +
                      let resolve;
         
     | 
| 
       1954 
2074 
     | 
    
         
             
                      let promise = new Promise((function(_resolve) {
         
     | 
| 
       1955 
2075 
     | 
    
         
             
                        resolve = _resolve;
         
     | 
| 
       1956 
2076 
     | 
    
         
             
                      }));
         
     | 
| 
         @@ -1959,258 +2079,195 @@ var Idiomorph = function() { 
     | 
|
| 
       1959 
2079 
     | 
    
         
             
                      }));
         
     | 
| 
       1960 
2080 
     | 
    
         
             
                      promises.push(promise);
         
     | 
| 
       1961 
2081 
     | 
    
         
             
                    }
         
     | 
| 
       1962 
     | 
    
         
            -
                     
     | 
| 
      
 2082 
     | 
    
         
            +
                    oldHead.appendChild(newElt);
         
     | 
| 
       1963 
2083 
     | 
    
         
             
                    ctx.callbacks.afterNodeAdded(newElt);
         
     | 
| 
       1964 
2084 
     | 
    
         
             
                    added.push(newElt);
         
     | 
| 
       1965 
2085 
     | 
    
         
             
                  }
         
     | 
| 
       1966 
2086 
     | 
    
         
             
                }
         
     | 
| 
       1967 
2087 
     | 
    
         
             
                for (const removedElement of removed) {
         
     | 
| 
       1968 
2088 
     | 
    
         
             
                  if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {
         
     | 
| 
       1969 
     | 
    
         
            -
                     
     | 
| 
      
 2089 
     | 
    
         
            +
                    oldHead.removeChild(removedElement);
         
     | 
| 
       1970 
2090 
     | 
    
         
             
                    ctx.callbacks.afterNodeRemoved(removedElement);
         
     | 
| 
       1971 
2091 
     | 
    
         
             
                  }
         
     | 
| 
       1972 
2092 
     | 
    
         
             
                }
         
     | 
| 
       1973 
     | 
    
         
            -
                ctx.head.afterHeadMorphed( 
     | 
| 
      
 2093 
     | 
    
         
            +
                ctx.head.afterHeadMorphed(oldHead, {
         
     | 
| 
       1974 
2094 
     | 
    
         
             
                  added: added,
         
     | 
| 
       1975 
2095 
     | 
    
         
             
                  kept: preserved,
         
     | 
| 
       1976 
2096 
     | 
    
         
             
                  removed: removed
         
     | 
| 
       1977 
2097 
     | 
    
         
             
                });
         
     | 
| 
       1978 
2098 
     | 
    
         
             
                return promises;
         
     | 
| 
       1979 
2099 
     | 
    
         
             
              }
         
     | 
| 
       1980 
     | 
    
         
            -
              function 
     | 
| 
       1981 
     | 
    
         
            -
             
     | 
| 
       1982 
     | 
    
         
            -
             
     | 
| 
       1983 
     | 
    
         
            -
             
     | 
| 
       1984 
     | 
    
         
            -
             
     | 
| 
       1985 
     | 
    
         
            -
             
     | 
| 
       1986 
     | 
    
         
            -
             
     | 
| 
       1987 
     | 
    
         
            -
             
     | 
| 
       1988 
     | 
    
         
            -
             
     | 
| 
       1989 
     | 
    
         
            -
             
     | 
| 
       1990 
     | 
    
         
            -
             
     | 
| 
       1991 
     | 
    
         
            -
             
     | 
| 
       1992 
     | 
    
         
            -
             
     | 
| 
       1993 
     | 
    
         
            -
             
     | 
| 
       1994 
     | 
    
         
            -
             
     | 
| 
       1995 
     | 
    
         
            -
             
     | 
| 
       1996 
     | 
    
         
            -
             
     | 
| 
       1997 
     | 
    
         
            -
             
     | 
| 
       1998 
     | 
    
         
            -
             
     | 
| 
       1999 
     | 
    
         
            -
             
     | 
| 
       2000 
     | 
    
         
            -
             
     | 
| 
       2001 
     | 
    
         
            -
                   
     | 
| 
       2002 
     | 
    
         
            -
                  idMap: createIdMap(oldNode, newContent),
         
     | 
| 
       2003 
     | 
    
         
            -
                  deadIds: new Set,
         
     | 
| 
       2004 
     | 
    
         
            -
                  callbacks: config.callbacks,
         
     | 
| 
       2005 
     | 
    
         
            -
                  head: config.head
         
     | 
| 
       2006 
     | 
    
         
            -
                };
         
     | 
| 
       2007 
     | 
    
         
            -
              }
         
     | 
| 
       2008 
     | 
    
         
            -
              function isIdSetMatch(node1, node2, ctx) {
         
     | 
| 
       2009 
     | 
    
         
            -
                if (node1 == null || node2 == null) {
         
     | 
| 
       2010 
     | 
    
         
            -
                  return false;
         
     | 
| 
      
 2100 
     | 
    
         
            +
              const createMorphContext = function() {
         
     | 
| 
      
 2101 
     | 
    
         
            +
                function createMorphContext(oldNode, newContent, config) {
         
     | 
| 
      
 2102 
     | 
    
         
            +
                  const {persistentIds: persistentIds, idMap: idMap} = createIdMaps(oldNode, newContent);
         
     | 
| 
      
 2103 
     | 
    
         
            +
                  const mergedConfig = mergeDefaults(config);
         
     | 
| 
      
 2104 
     | 
    
         
            +
                  const morphStyle = mergedConfig.morphStyle || "outerHTML";
         
     | 
| 
      
 2105 
     | 
    
         
            +
                  if (![ "innerHTML", "outerHTML" ].includes(morphStyle)) {
         
     | 
| 
      
 2106 
     | 
    
         
            +
                    throw `Do not understand how to morph style ${morphStyle}`;
         
     | 
| 
      
 2107 
     | 
    
         
            +
                  }
         
     | 
| 
      
 2108 
     | 
    
         
            +
                  return {
         
     | 
| 
      
 2109 
     | 
    
         
            +
                    target: oldNode,
         
     | 
| 
      
 2110 
     | 
    
         
            +
                    newContent: newContent,
         
     | 
| 
      
 2111 
     | 
    
         
            +
                    config: mergedConfig,
         
     | 
| 
      
 2112 
     | 
    
         
            +
                    morphStyle: morphStyle,
         
     | 
| 
      
 2113 
     | 
    
         
            +
                    ignoreActive: mergedConfig.ignoreActive,
         
     | 
| 
      
 2114 
     | 
    
         
            +
                    ignoreActiveValue: mergedConfig.ignoreActiveValue,
         
     | 
| 
      
 2115 
     | 
    
         
            +
                    restoreFocus: mergedConfig.restoreFocus,
         
     | 
| 
      
 2116 
     | 
    
         
            +
                    idMap: idMap,
         
     | 
| 
      
 2117 
     | 
    
         
            +
                    persistentIds: persistentIds,
         
     | 
| 
      
 2118 
     | 
    
         
            +
                    pantry: createPantry(),
         
     | 
| 
      
 2119 
     | 
    
         
            +
                    callbacks: mergedConfig.callbacks,
         
     | 
| 
      
 2120 
     | 
    
         
            +
                    head: mergedConfig.head
         
     | 
| 
      
 2121 
     | 
    
         
            +
                  };
         
     | 
| 
       2011 
2122 
     | 
    
         
             
                }
         
     | 
| 
       2012 
     | 
    
         
            -
                 
     | 
| 
       2013 
     | 
    
         
            -
                   
     | 
| 
       2014 
     | 
    
         
            -
             
     | 
| 
       2015 
     | 
    
         
            -
                  }  
     | 
| 
       2016 
     | 
    
         
            -
             
     | 
| 
      
 2123 
     | 
    
         
            +
                function mergeDefaults(config) {
         
     | 
| 
      
 2124 
     | 
    
         
            +
                  let finalConfig = Object.assign({}, defaults);
         
     | 
| 
      
 2125 
     | 
    
         
            +
                  Object.assign(finalConfig, config);
         
     | 
| 
      
 2126 
     | 
    
         
            +
                  finalConfig.callbacks = Object.assign({}, defaults.callbacks, config.callbacks);
         
     | 
| 
      
 2127 
     | 
    
         
            +
                  finalConfig.head = Object.assign({}, defaults.head, config.head);
         
     | 
| 
      
 2128 
     | 
    
         
            +
                  return finalConfig;
         
     | 
| 
      
 2129 
     | 
    
         
            +
                }
         
     | 
| 
      
 2130 
     | 
    
         
            +
                function createPantry() {
         
     | 
| 
      
 2131 
     | 
    
         
            +
                  const pantry = document.createElement("div");
         
     | 
| 
      
 2132 
     | 
    
         
            +
                  pantry.hidden = true;
         
     | 
| 
      
 2133 
     | 
    
         
            +
                  document.body.insertAdjacentElement("afterend", pantry);
         
     | 
| 
      
 2134 
     | 
    
         
            +
                  return pantry;
         
     | 
| 
      
 2135 
     | 
    
         
            +
                }
         
     | 
| 
      
 2136 
     | 
    
         
            +
                function findIdElements(root) {
         
     | 
| 
      
 2137 
     | 
    
         
            +
                  let elements = Array.from(root.querySelectorAll("[id]"));
         
     | 
| 
      
 2138 
     | 
    
         
            +
                  if (root.id) {
         
     | 
| 
      
 2139 
     | 
    
         
            +
                    elements.push(root);
         
     | 
| 
      
 2140 
     | 
    
         
            +
                  }
         
     | 
| 
      
 2141 
     | 
    
         
            +
                  return elements;
         
     | 
| 
      
 2142 
     | 
    
         
            +
                }
         
     | 
| 
      
 2143 
     | 
    
         
            +
                function populateIdMapWithTree(idMap, persistentIds, root, elements) {
         
     | 
| 
      
 2144 
     | 
    
         
            +
                  for (const elt of elements) {
         
     | 
| 
      
 2145 
     | 
    
         
            +
                    if (persistentIds.has(elt.id)) {
         
     | 
| 
      
 2146 
     | 
    
         
            +
                      let current = elt;
         
     | 
| 
      
 2147 
     | 
    
         
            +
                      while (current) {
         
     | 
| 
      
 2148 
     | 
    
         
            +
                        let idSet = idMap.get(current);
         
     | 
| 
      
 2149 
     | 
    
         
            +
                        if (idSet == null) {
         
     | 
| 
      
 2150 
     | 
    
         
            +
                          idSet = new Set;
         
     | 
| 
      
 2151 
     | 
    
         
            +
                          idMap.set(current, idSet);
         
     | 
| 
      
 2152 
     | 
    
         
            +
                        }
         
     | 
| 
      
 2153 
     | 
    
         
            +
                        idSet.add(elt.id);
         
     | 
| 
      
 2154 
     | 
    
         
            +
                        if (current === root) break;
         
     | 
| 
      
 2155 
     | 
    
         
            +
                        current = current.parentElement;
         
     | 
| 
      
 2156 
     | 
    
         
            +
                      }
         
     | 
| 
      
 2157 
     | 
    
         
            +
                    }
         
     | 
| 
       2017 
2158 
     | 
    
         
             
                  }
         
     | 
| 
       2018 
2159 
     | 
    
         
             
                }
         
     | 
| 
       2019 
     | 
    
         
            -
                 
     | 
| 
       2020 
     | 
    
         
            -
             
     | 
| 
       2021 
     | 
    
         
            -
             
     | 
| 
       2022 
     | 
    
         
            -
             
     | 
| 
       2023 
     | 
    
         
            -
                   
     | 
| 
      
 2160 
     | 
    
         
            +
                function createIdMaps(oldContent, newContent) {
         
     | 
| 
      
 2161 
     | 
    
         
            +
                  const oldIdElements = findIdElements(oldContent);
         
     | 
| 
      
 2162 
     | 
    
         
            +
                  const newIdElements = findIdElements(newContent);
         
     | 
| 
      
 2163 
     | 
    
         
            +
                  const persistentIds = createPersistentIds(oldIdElements, newIdElements);
         
     | 
| 
      
 2164 
     | 
    
         
            +
                  let idMap = new Map;
         
     | 
| 
      
 2165 
     | 
    
         
            +
                  populateIdMapWithTree(idMap, persistentIds, oldContent, oldIdElements);
         
     | 
| 
      
 2166 
     | 
    
         
            +
                  const newRoot = newContent.__idiomorphRoot || newContent;
         
     | 
| 
      
 2167 
     | 
    
         
            +
                  populateIdMapWithTree(idMap, persistentIds, newRoot, newIdElements);
         
     | 
| 
      
 2168 
     | 
    
         
            +
                  return {
         
     | 
| 
      
 2169 
     | 
    
         
            +
                    persistentIds: persistentIds,
         
     | 
| 
      
 2170 
     | 
    
         
            +
                    idMap: idMap
         
     | 
| 
      
 2171 
     | 
    
         
            +
                  };
         
     | 
| 
       2024 
2172 
     | 
    
         
             
                }
         
     | 
| 
       2025 
     | 
    
         
            -
                 
     | 
| 
       2026 
     | 
    
         
            -
             
     | 
| 
       2027 
     | 
    
         
            -
             
     | 
| 
       2028 
     | 
    
         
            -
             
     | 
| 
       2029 
     | 
    
         
            -
             
     | 
| 
       2030 
     | 
    
         
            -
             
     | 
| 
       2031 
     | 
    
         
            -
             
     | 
| 
       2032 
     | 
    
         
            -
             
     | 
| 
       2033 
     | 
    
         
            -
                removeIdsFromConsideration(ctx, endExclusive);
         
     | 
| 
       2034 
     | 
    
         
            -
                return endExclusive.nextSibling;
         
     | 
| 
       2035 
     | 
    
         
            -
              }
         
     | 
| 
       2036 
     | 
    
         
            -
              function findIdSetMatch(newContent, oldParent, newChild, insertionPoint, ctx) {
         
     | 
| 
       2037 
     | 
    
         
            -
                let newChildPotentialIdCount = getIdIntersectionCount(ctx, newChild, oldParent);
         
     | 
| 
       2038 
     | 
    
         
            -
                let potentialMatch = null;
         
     | 
| 
       2039 
     | 
    
         
            -
                if (newChildPotentialIdCount > 0) {
         
     | 
| 
       2040 
     | 
    
         
            -
                  let potentialMatch = insertionPoint;
         
     | 
| 
       2041 
     | 
    
         
            -
                  let otherMatchCount = 0;
         
     | 
| 
       2042 
     | 
    
         
            -
                  while (potentialMatch != null) {
         
     | 
| 
       2043 
     | 
    
         
            -
                    if (isIdSetMatch(newChild, potentialMatch, ctx)) {
         
     | 
| 
       2044 
     | 
    
         
            -
                      return potentialMatch;
         
     | 
| 
       2045 
     | 
    
         
            -
                    }
         
     | 
| 
       2046 
     | 
    
         
            -
                    otherMatchCount += getIdIntersectionCount(ctx, potentialMatch, newContent);
         
     | 
| 
       2047 
     | 
    
         
            -
                    if (otherMatchCount > newChildPotentialIdCount) {
         
     | 
| 
       2048 
     | 
    
         
            -
                      return null;
         
     | 
| 
      
 2173 
     | 
    
         
            +
                function createPersistentIds(oldIdElements, newIdElements) {
         
     | 
| 
      
 2174 
     | 
    
         
            +
                  let duplicateIds = new Set;
         
     | 
| 
      
 2175 
     | 
    
         
            +
                  let oldIdTagNameMap = new Map;
         
     | 
| 
      
 2176 
     | 
    
         
            +
                  for (const {id: id, tagName: tagName} of oldIdElements) {
         
     | 
| 
      
 2177 
     | 
    
         
            +
                    if (oldIdTagNameMap.has(id)) {
         
     | 
| 
      
 2178 
     | 
    
         
            +
                      duplicateIds.add(id);
         
     | 
| 
      
 2179 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 2180 
     | 
    
         
            +
                      oldIdTagNameMap.set(id, tagName);
         
     | 
| 
       2049 
2181 
     | 
    
         
             
                    }
         
     | 
| 
       2050 
     | 
    
         
            -
                    potentialMatch = potentialMatch.nextSibling;
         
     | 
| 
       2051 
2182 
     | 
    
         
             
                  }
         
     | 
| 
       2052 
     | 
    
         
            -
             
     | 
| 
       2053 
     | 
    
         
            -
             
     | 
| 
       2054 
     | 
    
         
            -
             
     | 
| 
       2055 
     | 
    
         
            -
             
     | 
| 
       2056 
     | 
    
         
            -
             
     | 
| 
       2057 
     | 
    
         
            -
             
     | 
| 
       2058 
     | 
    
         
            -
             
     | 
| 
       2059 
     | 
    
         
            -
                while (potentialSoftMatch != null) {
         
     | 
| 
       2060 
     | 
    
         
            -
                  if (getIdIntersectionCount(ctx, potentialSoftMatch, newContent) > 0) {
         
     | 
| 
       2061 
     | 
    
         
            -
                    return null;
         
     | 
| 
      
 2183 
     | 
    
         
            +
                  let persistentIds = new Set;
         
     | 
| 
      
 2184 
     | 
    
         
            +
                  for (const {id: id, tagName: tagName} of newIdElements) {
         
     | 
| 
      
 2185 
     | 
    
         
            +
                    if (persistentIds.has(id)) {
         
     | 
| 
      
 2186 
     | 
    
         
            +
                      duplicateIds.add(id);
         
     | 
| 
      
 2187 
     | 
    
         
            +
                    } else if (oldIdTagNameMap.get(id) === tagName) {
         
     | 
| 
      
 2188 
     | 
    
         
            +
                      persistentIds.add(id);
         
     | 
| 
      
 2189 
     | 
    
         
            +
                    }
         
     | 
| 
       2062 
2190 
     | 
    
         
             
                  }
         
     | 
| 
       2063 
     | 
    
         
            -
                   
     | 
| 
       2064 
     | 
    
         
            -
                     
     | 
| 
      
 2191 
     | 
    
         
            +
                  for (const id of duplicateIds) {
         
     | 
| 
      
 2192 
     | 
    
         
            +
                    persistentIds.delete(id);
         
     | 
| 
       2065 
2193 
     | 
    
         
             
                  }
         
     | 
| 
       2066 
     | 
    
         
            -
                   
     | 
| 
       2067 
     | 
    
         
            -
             
     | 
| 
       2068 
     | 
    
         
            -
             
     | 
| 
       2069 
     | 
    
         
            -
             
     | 
| 
       2070 
     | 
    
         
            -
             
     | 
| 
       2071 
     | 
    
         
            -
             
     | 
| 
      
 2194 
     | 
    
         
            +
                  return persistentIds;
         
     | 
| 
      
 2195 
     | 
    
         
            +
                }
         
     | 
| 
      
 2196 
     | 
    
         
            +
                return createMorphContext;
         
     | 
| 
      
 2197 
     | 
    
         
            +
              }();
         
     | 
| 
      
 2198 
     | 
    
         
            +
              const {normalizeElement: normalizeElement, normalizeParent: normalizeParent} = function() {
         
     | 
| 
      
 2199 
     | 
    
         
            +
                const generatedByIdiomorph = new WeakSet;
         
     | 
| 
      
 2200 
     | 
    
         
            +
                function normalizeElement(content) {
         
     | 
| 
      
 2201 
     | 
    
         
            +
                  if (content instanceof Document) {
         
     | 
| 
      
 2202 
     | 
    
         
            +
                    return content.documentElement;
         
     | 
| 
      
 2203 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 2204 
     | 
    
         
            +
                    return content;
         
     | 
| 
       2072 
2205 
     | 
    
         
             
                  }
         
     | 
| 
       2073 
     | 
    
         
            -
                  potentialSoftMatch = potentialSoftMatch.nextSibling;
         
     | 
| 
       2074 
2206 
     | 
    
         
             
                }
         
     | 
| 
       2075 
     | 
    
         
            -
                 
     | 
| 
       2076 
     | 
    
         
            -
             
     | 
| 
       2077 
     | 
    
         
            -
             
     | 
| 
       2078 
     | 
    
         
            -
             
     | 
| 
       2079 
     | 
    
         
            -
             
     | 
| 
       2080 
     | 
    
         
            -
             
     | 
| 
       2081 
     | 
    
         
            -
             
     | 
| 
       2082 
     | 
    
         
            -
                  if ( 
     | 
| 
       2083 
     | 
    
         
            -
                     
     | 
| 
       2084 
     | 
    
         
            -
             
     | 
| 
       2085 
     | 
    
         
            -
                  } else {
         
     | 
| 
       2086 
     | 
    
         
            -
                    let htmlElement = content.firstChild;
         
     | 
| 
       2087 
     | 
    
         
            -
                    if (htmlElement) {
         
     | 
| 
       2088 
     | 
    
         
            -
                      htmlElement.generatedByIdiomorph = true;
         
     | 
| 
       2089 
     | 
    
         
            -
                      return htmlElement;
         
     | 
| 
      
 2207 
     | 
    
         
            +
                function normalizeParent(newContent) {
         
     | 
| 
      
 2208 
     | 
    
         
            +
                  if (newContent == null) {
         
     | 
| 
      
 2209 
     | 
    
         
            +
                    return document.createElement("div");
         
     | 
| 
      
 2210 
     | 
    
         
            +
                  } else if (typeof newContent === "string") {
         
     | 
| 
      
 2211 
     | 
    
         
            +
                    return normalizeParent(parseContent(newContent));
         
     | 
| 
      
 2212 
     | 
    
         
            +
                  } else if (generatedByIdiomorph.has(newContent)) {
         
     | 
| 
      
 2213 
     | 
    
         
            +
                    return newContent;
         
     | 
| 
      
 2214 
     | 
    
         
            +
                  } else if (newContent instanceof Node) {
         
     | 
| 
      
 2215 
     | 
    
         
            +
                    if (newContent.parentNode) {
         
     | 
| 
      
 2216 
     | 
    
         
            +
                      return createDuckTypedParent(newContent);
         
     | 
| 
       2090 
2217 
     | 
    
         
             
                    } else {
         
     | 
| 
       2091 
     | 
    
         
            -
                       
     | 
| 
      
 2218 
     | 
    
         
            +
                      const dummyParent = document.createElement("div");
         
     | 
| 
      
 2219 
     | 
    
         
            +
                      dummyParent.append(newContent);
         
     | 
| 
      
 2220 
     | 
    
         
            +
                      return dummyParent;
         
     | 
| 
       2092 
2221 
     | 
    
         
             
                    }
         
     | 
| 
      
 2222 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 2223 
     | 
    
         
            +
                    const dummyParent = document.createElement("div");
         
     | 
| 
      
 2224 
     | 
    
         
            +
                    for (const elt of [ ...newContent ]) {
         
     | 
| 
      
 2225 
     | 
    
         
            +
                      dummyParent.append(elt);
         
     | 
| 
      
 2226 
     | 
    
         
            +
                    }
         
     | 
| 
      
 2227 
     | 
    
         
            +
                    return dummyParent;
         
     | 
| 
       2093 
2228 
     | 
    
         
             
                  }
         
     | 
| 
       2094 
     | 
    
         
            -
                } else {
         
     | 
| 
       2095 
     | 
    
         
            -
                  let responseDoc = parser.parseFromString("<body><template>" + newContent + "</template></body>", "text/html");
         
     | 
| 
       2096 
     | 
    
         
            -
                  let content = responseDoc.body.querySelector("template").content;
         
     | 
| 
       2097 
     | 
    
         
            -
                  content.generatedByIdiomorph = true;
         
     | 
| 
       2098 
     | 
    
         
            -
                  return content;
         
     | 
| 
       2099 
     | 
    
         
            -
                }
         
     | 
| 
       2100 
     | 
    
         
            -
              }
         
     | 
| 
       2101 
     | 
    
         
            -
              function normalizeContent(newContent) {
         
     | 
| 
       2102 
     | 
    
         
            -
                if (newContent == null) {
         
     | 
| 
       2103 
     | 
    
         
            -
                  const dummyParent = document.createElement("div");
         
     | 
| 
       2104 
     | 
    
         
            -
                  return dummyParent;
         
     | 
| 
       2105 
     | 
    
         
            -
                } else if (newContent.generatedByIdiomorph) {
         
     | 
| 
       2106 
     | 
    
         
            -
                  return newContent;
         
     | 
| 
       2107 
     | 
    
         
            -
                } else if (newContent instanceof Node) {
         
     | 
| 
       2108 
     | 
    
         
            -
                  const dummyParent = document.createElement("div");
         
     | 
| 
       2109 
     | 
    
         
            -
                  dummyParent.append(newContent);
         
     | 
| 
       2110 
     | 
    
         
            -
                  return dummyParent;
         
     | 
| 
       2111 
     | 
    
         
            -
                } else {
         
     | 
| 
       2112 
     | 
    
         
            -
                  const dummyParent = document.createElement("div");
         
     | 
| 
       2113 
     | 
    
         
            -
                  for (const elt of [ ...newContent ]) {
         
     | 
| 
       2114 
     | 
    
         
            -
                    dummyParent.append(elt);
         
     | 
| 
       2115 
     | 
    
         
            -
                  }
         
     | 
| 
       2116 
     | 
    
         
            -
                  return dummyParent;
         
     | 
| 
       2117 
     | 
    
         
            -
                }
         
     | 
| 
       2118 
     | 
    
         
            -
              }
         
     | 
| 
       2119 
     | 
    
         
            -
              function insertSiblings(previousSibling, morphedNode, nextSibling) {
         
     | 
| 
       2120 
     | 
    
         
            -
                let stack = [];
         
     | 
| 
       2121 
     | 
    
         
            -
                let added = [];
         
     | 
| 
       2122 
     | 
    
         
            -
                while (previousSibling != null) {
         
     | 
| 
       2123 
     | 
    
         
            -
                  stack.push(previousSibling);
         
     | 
| 
       2124 
     | 
    
         
            -
                  previousSibling = previousSibling.previousSibling;
         
     | 
| 
       2125 
     | 
    
         
            -
                }
         
     | 
| 
       2126 
     | 
    
         
            -
                while (stack.length > 0) {
         
     | 
| 
       2127 
     | 
    
         
            -
                  let node = stack.pop();
         
     | 
| 
       2128 
     | 
    
         
            -
                  added.push(node);
         
     | 
| 
       2129 
     | 
    
         
            -
                  morphedNode.parentElement.insertBefore(node, morphedNode);
         
     | 
| 
       2130 
     | 
    
         
            -
                }
         
     | 
| 
       2131 
     | 
    
         
            -
                added.push(morphedNode);
         
     | 
| 
       2132 
     | 
    
         
            -
                while (nextSibling != null) {
         
     | 
| 
       2133 
     | 
    
         
            -
                  stack.push(nextSibling);
         
     | 
| 
       2134 
     | 
    
         
            -
                  added.push(nextSibling);
         
     | 
| 
       2135 
     | 
    
         
            -
                  nextSibling = nextSibling.nextSibling;
         
     | 
| 
       2136 
     | 
    
         
            -
                }
         
     | 
| 
       2137 
     | 
    
         
            -
                while (stack.length > 0) {
         
     | 
| 
       2138 
     | 
    
         
            -
                  morphedNode.parentElement.insertBefore(stack.pop(), morphedNode.nextSibling);
         
     | 
| 
       2139 
     | 
    
         
            -
                }
         
     | 
| 
       2140 
     | 
    
         
            -
                return added;
         
     | 
| 
       2141 
     | 
    
         
            -
              }
         
     | 
| 
       2142 
     | 
    
         
            -
              function findBestNodeMatch(newContent, oldNode, ctx) {
         
     | 
| 
       2143 
     | 
    
         
            -
                let currentElement;
         
     | 
| 
       2144 
     | 
    
         
            -
                currentElement = newContent.firstChild;
         
     | 
| 
       2145 
     | 
    
         
            -
                let bestElement = currentElement;
         
     | 
| 
       2146 
     | 
    
         
            -
                let score = 0;
         
     | 
| 
       2147 
     | 
    
         
            -
                while (currentElement) {
         
     | 
| 
       2148 
     | 
    
         
            -
                  let newScore = scoreElement(currentElement, oldNode, ctx);
         
     | 
| 
       2149 
     | 
    
         
            -
                  if (newScore > score) {
         
     | 
| 
       2150 
     | 
    
         
            -
                    bestElement = currentElement;
         
     | 
| 
       2151 
     | 
    
         
            -
                    score = newScore;
         
     | 
| 
       2152 
     | 
    
         
            -
                  }
         
     | 
| 
       2153 
     | 
    
         
            -
                  currentElement = currentElement.nextSibling;
         
     | 
| 
       2154 
     | 
    
         
            -
                }
         
     | 
| 
       2155 
     | 
    
         
            -
                return bestElement;
         
     | 
| 
       2156 
     | 
    
         
            -
              }
         
     | 
| 
       2157 
     | 
    
         
            -
              function scoreElement(node1, node2, ctx) {
         
     | 
| 
       2158 
     | 
    
         
            -
                if (isSoftMatch(node1, node2)) {
         
     | 
| 
       2159 
     | 
    
         
            -
                  return .5 + getIdIntersectionCount(ctx, node1, node2);
         
     | 
| 
       2160 
2229 
     | 
    
         
             
                }
         
     | 
| 
       2161 
     | 
    
         
            -
                 
     | 
| 
       2162 
     | 
    
         
            -
             
     | 
| 
       2163 
     | 
    
         
            -
             
     | 
| 
       2164 
     | 
    
         
            -
             
     | 
| 
       2165 
     | 
    
         
            -
             
     | 
| 
       2166 
     | 
    
         
            -
             
     | 
| 
       2167 
     | 
    
         
            -
             
     | 
| 
       2168 
     | 
    
         
            -
             
     | 
| 
       2169 
     | 
    
         
            -
             
     | 
| 
       2170 
     | 
    
         
            -
             
     | 
| 
       2171 
     | 
    
         
            -
             
     | 
| 
       2172 
     | 
    
         
            -
             
     | 
| 
       2173 
     | 
    
         
            -
             
     | 
| 
       2174 
     | 
    
         
            -
                return idSet.has(id);
         
     | 
| 
       2175 
     | 
    
         
            -
              }
         
     | 
| 
       2176 
     | 
    
         
            -
              function removeIdsFromConsideration(ctx, node) {
         
     | 
| 
       2177 
     | 
    
         
            -
                let idSet = ctx.idMap.get(node) || EMPTY_SET;
         
     | 
| 
       2178 
     | 
    
         
            -
                for (const id of idSet) {
         
     | 
| 
       2179 
     | 
    
         
            -
                  ctx.deadIds.add(id);
         
     | 
| 
       2180 
     | 
    
         
            -
                }
         
     | 
| 
       2181 
     | 
    
         
            -
              }
         
     | 
| 
       2182 
     | 
    
         
            -
              function getIdIntersectionCount(ctx, node1, node2) {
         
     | 
| 
       2183 
     | 
    
         
            -
                let sourceSet = ctx.idMap.get(node1) || EMPTY_SET;
         
     | 
| 
       2184 
     | 
    
         
            -
                let matchCount = 0;
         
     | 
| 
       2185 
     | 
    
         
            -
                for (const id of sourceSet) {
         
     | 
| 
       2186 
     | 
    
         
            -
                  if (isIdInConsideration(ctx, id) && idIsWithinNode(ctx, id, node2)) {
         
     | 
| 
       2187 
     | 
    
         
            -
                    ++matchCount;
         
     | 
| 
       2188 
     | 
    
         
            -
                  }
         
     | 
| 
      
 2230 
     | 
    
         
            +
                function createDuckTypedParent(newContent) {
         
     | 
| 
      
 2231 
     | 
    
         
            +
                  return {
         
     | 
| 
      
 2232 
     | 
    
         
            +
                    childNodes: [ newContent ],
         
     | 
| 
      
 2233 
     | 
    
         
            +
                    querySelectorAll: s => {
         
     | 
| 
      
 2234 
     | 
    
         
            +
                      const elements = newContent.querySelectorAll(s);
         
     | 
| 
      
 2235 
     | 
    
         
            +
                      return newContent.matches(s) ? [ newContent, ...elements ] : elements;
         
     | 
| 
      
 2236 
     | 
    
         
            +
                    },
         
     | 
| 
      
 2237 
     | 
    
         
            +
                    insertBefore: (n, r) => newContent.parentNode.insertBefore(n, r),
         
     | 
| 
      
 2238 
     | 
    
         
            +
                    moveBefore: (n, r) => newContent.parentNode.moveBefore(n, r),
         
     | 
| 
      
 2239 
     | 
    
         
            +
                    get __idiomorphRoot() {
         
     | 
| 
      
 2240 
     | 
    
         
            +
                      return newContent;
         
     | 
| 
      
 2241 
     | 
    
         
            +
                    }
         
     | 
| 
      
 2242 
     | 
    
         
            +
                  };
         
     | 
| 
       2189 
2243 
     | 
    
         
             
                }
         
     | 
| 
       2190 
     | 
    
         
            -
                 
     | 
| 
       2191 
     | 
    
         
            -
             
     | 
| 
       2192 
     | 
    
         
            -
             
     | 
| 
       2193 
     | 
    
         
            -
             
     | 
| 
       2194 
     | 
    
         
            -
             
     | 
| 
       2195 
     | 
    
         
            -
             
     | 
| 
       2196 
     | 
    
         
            -
             
     | 
| 
       2197 
     | 
    
         
            -
             
     | 
| 
       2198 
     | 
    
         
            -
                     
     | 
| 
       2199 
     | 
    
         
            -
             
     | 
| 
       2200 
     | 
    
         
            -
                       
     | 
| 
       2201 
     | 
    
         
            -
             
     | 
| 
      
 2244 
     | 
    
         
            +
                function parseContent(newContent) {
         
     | 
| 
      
 2245 
     | 
    
         
            +
                  let parser = new DOMParser;
         
     | 
| 
      
 2246 
     | 
    
         
            +
                  let contentWithSvgsRemoved = newContent.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim, "");
         
     | 
| 
      
 2247 
     | 
    
         
            +
                  if (contentWithSvgsRemoved.match(/<\/html>/) || contentWithSvgsRemoved.match(/<\/head>/) || contentWithSvgsRemoved.match(/<\/body>/)) {
         
     | 
| 
      
 2248 
     | 
    
         
            +
                    let content = parser.parseFromString(newContent, "text/html");
         
     | 
| 
      
 2249 
     | 
    
         
            +
                    if (contentWithSvgsRemoved.match(/<\/html>/)) {
         
     | 
| 
      
 2250 
     | 
    
         
            +
                      generatedByIdiomorph.add(content);
         
     | 
| 
      
 2251 
     | 
    
         
            +
                      return content;
         
     | 
| 
      
 2252 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 2253 
     | 
    
         
            +
                      let htmlElement = content.firstChild;
         
     | 
| 
      
 2254 
     | 
    
         
            +
                      if (htmlElement) {
         
     | 
| 
      
 2255 
     | 
    
         
            +
                        generatedByIdiomorph.add(htmlElement);
         
     | 
| 
      
 2256 
     | 
    
         
            +
                      }
         
     | 
| 
      
 2257 
     | 
    
         
            +
                      return htmlElement;
         
     | 
| 
       2202 
2258 
     | 
    
         
             
                    }
         
     | 
| 
       2203 
     | 
    
         
            -
             
     | 
| 
       2204 
     | 
    
         
            -
                     
     | 
| 
      
 2259 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 2260 
     | 
    
         
            +
                    let responseDoc = parser.parseFromString("<body><template>" + newContent + "</template></body>", "text/html");
         
     | 
| 
      
 2261 
     | 
    
         
            +
                    let content = responseDoc.body.querySelector("template").content;
         
     | 
| 
      
 2262 
     | 
    
         
            +
                    generatedByIdiomorph.add(content);
         
     | 
| 
      
 2263 
     | 
    
         
            +
                    return content;
         
     | 
| 
       2205 
2264 
     | 
    
         
             
                  }
         
     | 
| 
       2206 
2265 
     | 
    
         
             
                }
         
     | 
| 
       2207 
     | 
    
         
            -
             
     | 
| 
       2208 
     | 
    
         
            -
             
     | 
| 
       2209 
     | 
    
         
            -
             
     | 
| 
       2210 
     | 
    
         
            -
                 
     | 
| 
       2211 
     | 
    
         
            -
             
     | 
| 
       2212 
     | 
    
         
            -
                return idMap;
         
     | 
| 
       2213 
     | 
    
         
            -
              }
         
     | 
| 
      
 2266 
     | 
    
         
            +
                return {
         
     | 
| 
      
 2267 
     | 
    
         
            +
                  normalizeElement: normalizeElement,
         
     | 
| 
      
 2268 
     | 
    
         
            +
                  normalizeParent: normalizeParent
         
     | 
| 
      
 2269 
     | 
    
         
            +
                };
         
     | 
| 
      
 2270 
     | 
    
         
            +
              }();
         
     | 
| 
       2214 
2271 
     | 
    
         
             
              return {
         
     | 
| 
       2215 
2272 
     | 
    
         
             
                morph: morph,
         
     | 
| 
       2216 
2273 
     | 
    
         
             
                defaults: defaults
         
     | 
| 
         @@ -2225,7 +2282,7 @@ function morphElements(currentElement, newElement, {callbacks: callbacks, ...opt 
     | 
|
| 
       2225 
2282 
     | 
    
         
             
            }
         
     | 
| 
       2226 
2283 
     | 
    
         | 
| 
       2227 
2284 
     | 
    
         
             
            function morphChildren(currentElement, newElement) {
         
     | 
| 
       2228 
     | 
    
         
            -
              morphElements(currentElement, newElement. 
     | 
| 
      
 2285 
     | 
    
         
            +
              morphElements(currentElement, newElement.childNodes, {
         
     | 
| 
       2229 
2286 
     | 
    
         
             
                morphStyle: "innerHTML"
         
     | 
| 
       2230 
2287 
     | 
    
         
             
              });
         
     | 
| 
       2231 
2288 
     | 
    
         
             
            }
         
     | 
| 
         @@ -2289,6 +2346,9 @@ class MorphingFrameRenderer extends FrameRenderer { 
     | 
|
| 
       2289 
2346 
     | 
    
         
             
                });
         
     | 
| 
       2290 
2347 
     | 
    
         
             
                morphChildren(currentElement, newElement);
         
     | 
| 
       2291 
2348 
     | 
    
         
             
              }
         
     | 
| 
      
 2349 
     | 
    
         
            +
              async preservingPermanentElements(callback) {
         
     | 
| 
      
 2350 
     | 
    
         
            +
                return await callback();
         
     | 
| 
      
 2351 
     | 
    
         
            +
              }
         
     | 
| 
       2292 
2352 
     | 
    
         
             
            }
         
     | 
| 
       2293 
2353 
     | 
    
         | 
| 
       2294 
2354 
     | 
    
         
             
            class ProgressBar {
         
     | 
| 
         @@ -2380,8 +2440,9 @@ class ProgressBar { 
     | 
|
| 
       2380 
2440 
     | 
    
         
             
                const element = document.createElement("style");
         
     | 
| 
       2381 
2441 
     | 
    
         
             
                element.type = "text/css";
         
     | 
| 
       2382 
2442 
     | 
    
         
             
                element.textContent = ProgressBar.defaultCSS;
         
     | 
| 
       2383 
     | 
    
         
            -
                 
     | 
| 
       2384 
     | 
    
         
            -
             
     | 
| 
      
 2443 
     | 
    
         
            +
                const cspNonce = getCspNonce();
         
     | 
| 
      
 2444 
     | 
    
         
            +
                if (cspNonce) {
         
     | 
| 
      
 2445 
     | 
    
         
            +
                  element.nonce = cspNonce;
         
     | 
| 
       2385 
2446 
     | 
    
         
             
                }
         
     | 
| 
       2386 
2447 
     | 
    
         
             
                return element;
         
     | 
| 
       2387 
2448 
     | 
    
         
             
              }
         
     | 
| 
         @@ -2390,9 +2451,6 @@ class ProgressBar { 
     | 
|
| 
       2390 
2451 
     | 
    
         
             
                element.className = "turbo-progress-bar";
         
     | 
| 
       2391 
2452 
     | 
    
         
             
                return element;
         
     | 
| 
       2392 
2453 
     | 
    
         
             
              }
         
     | 
| 
       2393 
     | 
    
         
            -
              get cspNonce() {
         
     | 
| 
       2394 
     | 
    
         
            -
                return getMetaContent("csp-nonce");
         
     | 
| 
       2395 
     | 
    
         
            -
              }
         
     | 
| 
       2396 
2454 
     | 
    
         
             
            }
         
     | 
| 
       2397 
2455 
     | 
    
         | 
| 
       2398 
2456 
     | 
    
         
             
            class HeadSnapshot extends Snapshot {
         
     | 
| 
         @@ -2895,16 +2953,6 @@ class Visit { 
     | 
|
| 
       2895 
2953 
     | 
    
         
             
                  ...this.timingMetrics
         
     | 
| 
       2896 
2954 
     | 
    
         
             
                };
         
     | 
| 
       2897 
2955 
     | 
    
         
             
              }
         
     | 
| 
       2898 
     | 
    
         
            -
              getHistoryMethodForAction(action) {
         
     | 
| 
       2899 
     | 
    
         
            -
                switch (action) {
         
     | 
| 
       2900 
     | 
    
         
            -
                 case "replace":
         
     | 
| 
       2901 
     | 
    
         
            -
                  return history.replaceState;
         
     | 
| 
       2902 
     | 
    
         
            -
             
     | 
| 
       2903 
     | 
    
         
            -
                 case "advance":
         
     | 
| 
       2904 
     | 
    
         
            -
                 case "restore":
         
     | 
| 
       2905 
     | 
    
         
            -
                  return history.pushState;
         
     | 
| 
       2906 
     | 
    
         
            -
                }
         
     | 
| 
       2907 
     | 
    
         
            -
              }
         
     | 
| 
       2908 
2956 
     | 
    
         
             
              hasPreloadedResponse() {
         
     | 
| 
       2909 
2957 
     | 
    
         
             
                return typeof this.response == "object";
         
     | 
| 
       2910 
2958 
     | 
    
         
             
              }
         
     | 
| 
         @@ -3007,6 +3055,9 @@ class BrowserAdapter { 
     | 
|
| 
       3007 
3055 
     | 
    
         
             
                this.hideVisitProgressBar();
         
     | 
| 
       3008 
3056 
     | 
    
         
             
              }
         
     | 
| 
       3009 
3057 
     | 
    
         
             
              visitRendered(_visit) {}
         
     | 
| 
      
 3058 
     | 
    
         
            +
              linkPrefetchingIsEnabledForLocation(location) {
         
     | 
| 
      
 3059 
     | 
    
         
            +
                return true;
         
     | 
| 
      
 3060 
     | 
    
         
            +
              }
         
     | 
| 
       3010 
3061 
     | 
    
         
             
              formSubmissionStarted(_formSubmission) {
         
     | 
| 
       3011 
3062 
     | 
    
         
             
                this.progressBar.setValue(0);
         
     | 
| 
       3012 
3063 
     | 
    
         
             
                this.showFormProgressBarAfterDelay();
         
     | 
| 
         @@ -3463,6 +3514,12 @@ class Navigator { 
     | 
|
| 
       3463 
3514 
     | 
    
         
             
                  this.adapter.formSubmissionFinished(formSubmission);
         
     | 
| 
       3464 
3515 
     | 
    
         
             
                }
         
     | 
| 
       3465 
3516 
     | 
    
         
             
              }
         
     | 
| 
      
 3517 
     | 
    
         
            +
              linkPrefetchingIsEnabledForLocation(location) {
         
     | 
| 
      
 3518 
     | 
    
         
            +
                if (typeof this.adapter.linkPrefetchingIsEnabledForLocation === "function") {
         
     | 
| 
      
 3519 
     | 
    
         
            +
                  return this.adapter.linkPrefetchingIsEnabledForLocation(location);
         
     | 
| 
      
 3520 
     | 
    
         
            +
                }
         
     | 
| 
      
 3521 
     | 
    
         
            +
                return true;
         
     | 
| 
      
 3522 
     | 
    
         
            +
              }
         
     | 
| 
       3466 
3523 
     | 
    
         
             
              visitStarted(visit) {
         
     | 
| 
       3467 
3524 
     | 
    
         
             
                this.delegate.visitStarted(visit);
         
     | 
| 
       3468 
3525 
     | 
    
         
             
              }
         
     | 
| 
         @@ -4013,7 +4070,7 @@ class PageView extends View { 
     | 
|
| 
       4013 
4070 
     | 
    
         
             
              renderPage(snapshot, isPreview = false, willRender = true, visit) {
         
     | 
| 
       4014 
4071 
     | 
    
         
             
                const shouldMorphPage = this.isPageRefresh(visit) && this.snapshot.shouldMorphPage;
         
     | 
| 
       4015 
4072 
     | 
    
         
             
                const rendererClass = shouldMorphPage ? MorphingPageRenderer : PageRenderer;
         
     | 
| 
       4016 
     | 
    
         
            -
                const renderer = new rendererClass(this.snapshot, snapshot,  
     | 
| 
      
 4073 
     | 
    
         
            +
                const renderer = new rendererClass(this.snapshot, snapshot, isPreview, willRender);
         
     | 
| 
       4017 
4074 
     | 
    
         
             
                if (!renderer.shouldRender) {
         
     | 
| 
       4018 
4075 
     | 
    
         
             
                  this.forceReloaded = true;
         
     | 
| 
       4019 
4076 
     | 
    
         
             
                } else {
         
     | 
| 
         @@ -4023,7 +4080,7 @@ class PageView extends View { 
     | 
|
| 
       4023 
4080 
     | 
    
         
             
              }
         
     | 
| 
       4024 
4081 
     | 
    
         
             
              renderError(snapshot, visit) {
         
     | 
| 
       4025 
4082 
     | 
    
         
             
                visit?.changeHistory();
         
     | 
| 
       4026 
     | 
    
         
            -
                const renderer = new ErrorRenderer(this.snapshot, snapshot,  
     | 
| 
      
 4083 
     | 
    
         
            +
                const renderer = new ErrorRenderer(this.snapshot, snapshot, false);
         
     | 
| 
       4027 
4084 
     | 
    
         
             
                return this.render(renderer);
         
     | 
| 
       4028 
4085 
     | 
    
         
             
              }
         
     | 
| 
       4029 
4086 
     | 
    
         
             
              clearSnapshotCache() {
         
     | 
| 
         @@ -4201,7 +4258,8 @@ class Session { 
     | 
|
| 
       4201 
4258 
     | 
    
         
             
              }
         
     | 
| 
       4202 
4259 
     | 
    
         
             
              refresh(url, requestId) {
         
     | 
| 
       4203 
4260 
     | 
    
         
             
                const isRecentRequest = requestId && this.recentRequests.has(requestId);
         
     | 
| 
       4204 
     | 
    
         
            -
                 
     | 
| 
      
 4261 
     | 
    
         
            +
                const isCurrentUrl = url === document.baseURI;
         
     | 
| 
      
 4262 
     | 
    
         
            +
                if (!isRecentRequest && !this.navigator.currentVisit && isCurrentUrl) {
         
     | 
| 
       4205 
4263 
     | 
    
         
             
                  this.visit(url, {
         
     | 
| 
       4206 
4264 
     | 
    
         
             
                    action: "replace",
         
     | 
| 
       4207 
4265 
     | 
    
         
             
                    shouldCacheSnapshot: false
         
     | 
| 
         @@ -4290,7 +4348,7 @@ class Session { 
     | 
|
| 
       4290 
4348 
     | 
    
         
             
              }
         
     | 
| 
       4291 
4349 
     | 
    
         
             
              submittedFormLinkToLocation() {}
         
     | 
| 
       4292 
4350 
     | 
    
         
             
              canPrefetchRequestToLocation(link, location) {
         
     | 
| 
       4293 
     | 
    
         
            -
                return this.elementIsNavigatable(link) && locationIsVisitable(location, this.snapshot.rootLocation);
         
     | 
| 
      
 4351 
     | 
    
         
            +
                return this.elementIsNavigatable(link) && locationIsVisitable(location, this.snapshot.rootLocation) && this.navigator.linkPrefetchingIsEnabledForLocation(location);
         
     | 
| 
       4294 
4352 
     | 
    
         
             
              }
         
     | 
| 
       4295 
4353 
     | 
    
         
             
              willFollowLinkToLocation(link, location, event) {
         
     | 
| 
       4296 
4354 
     | 
    
         
             
                return this.elementIsNavigatable(link) && locationIsVisitable(location, this.snapshot.rootLocation) && this.applicationAllowsFollowingLinkToLocation(link, location, event);
         
     | 
| 
         @@ -4589,6 +4647,7 @@ class FrameController { 
     | 
|
| 
       4589 
4647 
     | 
    
         
             
              #connected=false;
         
     | 
| 
       4590 
4648 
     | 
    
         
             
              #hasBeenLoaded=false;
         
     | 
| 
       4591 
4649 
     | 
    
         
             
              #ignoredAttributes=new Set;
         
     | 
| 
      
 4650 
     | 
    
         
            +
              #shouldMorphFrame=false;
         
     | 
| 
       4592 
4651 
     | 
    
         
             
              action=null;
         
     | 
| 
       4593 
4652 
     | 
    
         
             
              constructor(element) {
         
     | 
| 
       4594 
4653 
     | 
    
         
             
                this.element = element;
         
     | 
| 
         @@ -4636,14 +4695,8 @@ class FrameController { 
     | 
|
| 
       4636 
4695 
     | 
    
         
             
                }
         
     | 
| 
       4637 
4696 
     | 
    
         
             
              }
         
     | 
| 
       4638 
4697 
     | 
    
         
             
              sourceURLReloaded() {
         
     | 
| 
       4639 
     | 
    
         
            -
                 
     | 
| 
       4640 
     | 
    
         
            -
             
     | 
| 
       4641 
     | 
    
         
            -
                    detail.render = MorphingFrameRenderer.renderElement;
         
     | 
| 
       4642 
     | 
    
         
            -
                  }), {
         
     | 
| 
       4643 
     | 
    
         
            -
                    once: true
         
     | 
| 
       4644 
     | 
    
         
            -
                  });
         
     | 
| 
       4645 
     | 
    
         
            -
                }
         
     | 
| 
       4646 
     | 
    
         
            -
                const {src: src} = this.element;
         
     | 
| 
      
 4698 
     | 
    
         
            +
                const {refresh: refresh, src: src} = this.element;
         
     | 
| 
      
 4699 
     | 
    
         
            +
                this.#shouldMorphFrame = src && refresh === "morph";
         
     | 
| 
       4647 
4700 
     | 
    
         
             
                this.element.removeAttribute("complete");
         
     | 
| 
       4648 
4701 
     | 
    
         
             
                this.element.src = null;
         
     | 
| 
       4649 
4702 
     | 
    
         
             
                this.element.src = src;
         
     | 
| 
         @@ -4681,6 +4734,7 @@ class FrameController { 
     | 
|
| 
       4681 
4734 
     | 
    
         
             
                    }
         
     | 
| 
       4682 
4735 
     | 
    
         
             
                  }
         
     | 
| 
       4683 
4736 
     | 
    
         
             
                } finally {
         
     | 
| 
      
 4737 
     | 
    
         
            +
                  this.#shouldMorphFrame = false;
         
     | 
| 
       4684 
4738 
     | 
    
         
             
                  this.fetchResponseLoaded = () => Promise.resolve();
         
     | 
| 
       4685 
4739 
     | 
    
         
             
                }
         
     | 
| 
       4686 
4740 
     | 
    
         
             
              }
         
     | 
| 
         @@ -4793,9 +4847,10 @@ class FrameController { 
     | 
|
| 
       4793 
4847 
     | 
    
         
             
              };
         
     | 
| 
       4794 
4848 
     | 
    
         
             
              async #loadFrameResponse(fetchResponse, document) {
         
     | 
| 
       4795 
4849 
     | 
    
         
             
                const newFrameElement = await this.extractForeignFrameElement(document.body);
         
     | 
| 
      
 4850 
     | 
    
         
            +
                const rendererClass = this.#shouldMorphFrame ? MorphingFrameRenderer : FrameRenderer;
         
     | 
| 
       4796 
4851 
     | 
    
         
             
                if (newFrameElement) {
         
     | 
| 
       4797 
4852 
     | 
    
         
             
                  const snapshot = new Snapshot(newFrameElement);
         
     | 
| 
       4798 
     | 
    
         
            -
                  const renderer = new  
     | 
| 
      
 4853 
     | 
    
         
            +
                  const renderer = new rendererClass(this, this.view.snapshot, snapshot, false, false);
         
     | 
| 
       4799 
4854 
     | 
    
         
             
                  if (this.view.renderPromise) await this.view.renderPromise;
         
     | 
| 
       4800 
4855 
     | 
    
         
             
                  this.changeHistory();
         
     | 
| 
       4801 
4856 
     | 
    
         
             
                  await this.view.render(renderer);
         
     | 
| 
         @@ -5110,9 +5165,9 @@ class StreamElement extends HTMLElement { 
     | 
|
| 
       5110 
5165 
     | 
    
         
             
                this.duplicateChildren.forEach((c => c.remove()));
         
     | 
| 
       5111 
5166 
     | 
    
         
             
              }
         
     | 
| 
       5112 
5167 
     | 
    
         
             
              get duplicateChildren() {
         
     | 
| 
       5113 
     | 
    
         
            -
                const existingChildren = this.targetElements.flatMap((e => [ ...e.children ])).filter((c => !!c.id));
         
     | 
| 
       5114 
     | 
    
         
            -
                const newChildrenIds = [ ...this.templateContent?.children || [] ].filter((c => !!c.id)).map((c => c.id));
         
     | 
| 
       5115 
     | 
    
         
            -
                return existingChildren.filter((c => newChildrenIds.includes(c.id)));
         
     | 
| 
      
 5168 
     | 
    
         
            +
                const existingChildren = this.targetElements.flatMap((e => [ ...e.children ])).filter((c => !!c.getAttribute("id")));
         
     | 
| 
      
 5169 
     | 
    
         
            +
                const newChildrenIds = [ ...this.templateContent?.children || [] ].filter((c => !!c.getAttribute("id"))).map((c => c.getAttribute("id")));
         
     | 
| 
      
 5170 
     | 
    
         
            +
                return existingChildren.filter((c => newChildrenIds.includes(c.getAttribute("id"))));
         
     | 
| 
       5116 
5171 
     | 
    
         
             
              }
         
     | 
| 
       5117 
5172 
     | 
    
         
             
              get performAction() {
         
     | 
| 
       5118 
5173 
     | 
    
         
             
                if (this.action) {
         
     |