turbo-rails 2.0.16 → 2.0.20
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 +136 -57
 - data/app/assets/javascripts/turbo.min.js +6 -6
 - data/app/assets/javascripts/turbo.min.js.map +1 -1
 - data/app/models/concerns/turbo/broadcastable.rb +1 -1
 - data/lib/turbo/version.rb +1 -1
 - metadata +3 -7
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 06430d7095a020ded9bf6f76888c703184a7ffdd0c99e91f5461644c7fbdd062
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: b8b15ac1f37352d7a75782fe095c621340bb648eb24b5e36009634441efe098f
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: e4d105df336ab191ba9c3673bec4d47d7b4aa561cc3a865ada719ea5c478f70587a55bdd0b97a55b5846ab39afd6b18d863e50f74ec0c40657a407b00ad2cb2a
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 9b293373d747dbe2964328636a3c5d4eae68fbf522a2f704948c0ea53b671c90ad8b13c8049e1a327a25127691e3cc9c3814634ae5cb9d174f94d9ff54c4f3b0
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -206,7 +206,7 @@ Turbo can coexist with Rails UJS, but you need to take a series of upgrade steps 
     | 
|
| 
       206 
206 
     | 
    
         | 
| 
       207 
207 
     | 
    
         
             
            ## Testing
         
     | 
| 
       208 
208 
     | 
    
         | 
| 
       209 
     | 
    
         
            -
            The [`Turbo::TestAssertions`](./lib/turbo/test_assertions.rb) concern provides Turbo Stream test helpers that assert the presence or absence  
     | 
| 
      
 209 
     | 
    
         
            +
            The [`Turbo::TestAssertions`](./lib/turbo/test_assertions.rb) concern provides Turbo Stream test helpers that assert the presence or absence of `<turbo-stream>` elements in a rendered fragment of HTML. `Turbo::TestAssertions` are automatically included in [`ActiveSupport::TestCase`](https://edgeapi.rubyonrails.org/classes/ActiveSupport/TestCase.html) and depend on the presence of [`rails-dom-testing`](https://github.com/rails/rails-dom-testing/) assertions.
         
     | 
| 
       210 
210 
     | 
    
         | 
| 
       211 
211 
     | 
    
         
             
            The [`Turbo::TestAssertions::IntegrationTestAssertions`](./lib/turbo/test_assertions/integration_test_assertions.rb) are built on top of `Turbo::TestAssertions`, and add support for passing a `status:` keyword. They are automatically included in [`ActionDispatch::IntegrationTest`](https://edgeguides.rubyonrails.org/testing.html#integration-testing).
         
     | 
| 
       212 
212 
     | 
    
         | 
| 
         @@ -1,5 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            /*!
         
     | 
| 
       2 
     | 
    
         
            -
            Turbo 8.0. 
     | 
| 
      
 2 
     | 
    
         
            +
            Turbo 8.0.19
         
     | 
| 
       3 
3 
     | 
    
         
             
            Copyright © 2025 37signals LLC
         
     | 
| 
       4 
4 
     | 
    
         
             
             */
         
     | 
| 
       5 
5 
     | 
    
         
             
            (function(prototype) {
         
     | 
| 
         @@ -409,7 +409,11 @@ function doesNotTargetIFrame(name) { 
     | 
|
| 
       409 
409 
     | 
    
         
             
            }
         
     | 
| 
       410 
410 
     | 
    
         | 
| 
       411 
411 
     | 
    
         
             
            function findLinkFromClickTarget(target) {
         
     | 
| 
       412 
     | 
    
         
            -
               
     | 
| 
      
 412 
     | 
    
         
            +
              const link = findClosestRecursively(target, "a[href], a[xlink\\:href]");
         
     | 
| 
      
 413 
     | 
    
         
            +
              if (!link) return null;
         
     | 
| 
      
 414 
     | 
    
         
            +
              if (link.hasAttribute("download")) return null;
         
     | 
| 
      
 415 
     | 
    
         
            +
              if (link.hasAttribute("target") && link.target !== "_self") return null;
         
     | 
| 
      
 416 
     | 
    
         
            +
              return link;
         
     | 
| 
       413 
417 
     | 
    
         
             
            }
         
     | 
| 
       414 
418 
     | 
    
         | 
| 
       415 
419 
     | 
    
         
             
            function getLocationForLink(link) {
         
     | 
| 
         @@ -488,8 +492,8 @@ function getExtension(url) { 
     | 
|
| 
       488 
492 
     | 
    
         
             
            }
         
     | 
| 
       489 
493 
     | 
    
         | 
| 
       490 
494 
     | 
    
         
             
            function isPrefixedBy(baseURL, url) {
         
     | 
| 
       491 
     | 
    
         
            -
              const prefix =  
     | 
| 
       492 
     | 
    
         
            -
              return baseURL.href ===  
     | 
| 
      
 495 
     | 
    
         
            +
              const prefix = addTrailingSlash(url.origin + url.pathname);
         
     | 
| 
      
 496 
     | 
    
         
            +
              return addTrailingSlash(baseURL.href) === prefix || baseURL.href.startsWith(prefix);
         
     | 
| 
       493 
497 
     | 
    
         
             
            }
         
     | 
| 
       494 
498 
     | 
    
         | 
| 
       495 
499 
     | 
    
         
             
            function locationIsVisitable(location, rootLocation) {
         
     | 
| 
         @@ -517,10 +521,6 @@ function getLastPathComponent(url) { 
     | 
|
| 
       517 
521 
     | 
    
         
             
              return getPathComponents(url).slice(-1)[0];
         
     | 
| 
       518 
522 
     | 
    
         
             
            }
         
     | 
| 
       519 
523 
     | 
    
         | 
| 
       520 
     | 
    
         
            -
            function getPrefix(url) {
         
     | 
| 
       521 
     | 
    
         
            -
              return addTrailingSlash(url.origin + url.pathname);
         
     | 
| 
       522 
     | 
    
         
            -
            }
         
     | 
| 
       523 
     | 
    
         
            -
             
     | 
| 
       524 
524 
     | 
    
         
             
            function addTrailingSlash(value) {
         
     | 
| 
       525 
525 
     | 
    
         
             
              return value.endsWith("/") ? value : value + "/";
         
     | 
| 
       526 
526 
     | 
    
         
             
            }
         
     | 
| 
         @@ -588,14 +588,12 @@ class LimitedSet extends Set { 
     | 
|
| 
       588 
588 
     | 
    
         | 
| 
       589 
589 
     | 
    
         
             
            const recentRequests = new LimitedSet(20);
         
     | 
| 
       590 
590 
     | 
    
         | 
| 
       591 
     | 
    
         
            -
            const nativeFetch = window.fetch;
         
     | 
| 
       592 
     | 
    
         
            -
             
     | 
| 
       593 
591 
     | 
    
         
             
            function fetchWithTurboHeaders(url, options = {}) {
         
     | 
| 
       594 
592 
     | 
    
         
             
              const modifiedHeaders = new Headers(options.headers || {});
         
     | 
| 
       595 
593 
     | 
    
         
             
              const requestUID = uuid();
         
     | 
| 
       596 
594 
     | 
    
         
             
              recentRequests.add(requestUID);
         
     | 
| 
       597 
595 
     | 
    
         
             
              modifiedHeaders.append("X-Turbo-Request-Id", requestUID);
         
     | 
| 
       598 
     | 
    
         
            -
              return  
     | 
| 
      
 596 
     | 
    
         
            +
              return window.fetch(url, {
         
     | 
| 
       599 
597 
     | 
    
         
             
                ...options,
         
     | 
| 
       600 
598 
     | 
    
         
             
                headers: modifiedHeaders
         
     | 
| 
       601 
599 
     | 
    
         
             
              });
         
     | 
| 
         @@ -1243,8 +1241,8 @@ class View { 
     | 
|
| 
       1243 
1241 
     | 
    
         
             
              scrollToAnchor(anchor) {
         
     | 
| 
       1244 
1242 
     | 
    
         
             
                const element = this.snapshot.getElementForAnchor(anchor);
         
     | 
| 
       1245 
1243 
     | 
    
         
             
                if (element) {
         
     | 
| 
       1246 
     | 
    
         
            -
                  this.scrollToElement(element);
         
     | 
| 
       1247 
1244 
     | 
    
         
             
                  this.focusElement(element);
         
     | 
| 
      
 1245 
     | 
    
         
            +
                  this.scrollToElement(element);
         
     | 
| 
       1248 
1246 
     | 
    
         
             
                } else {
         
     | 
| 
       1249 
1247 
     | 
    
         
             
                  this.scrollToPosition({
         
     | 
| 
       1250 
1248 
     | 
    
         
             
                    x: 0,
         
     | 
| 
         @@ -1725,12 +1723,8 @@ var Idiomorph = function() { 
     | 
|
| 
       1725 
1723 
     | 
    
         
             
              }
         
     | 
| 
       1726 
1724 
     | 
    
         
             
              function morphOuterHTML(ctx, oldNode, newNode) {
         
     | 
| 
       1727 
1725 
     | 
    
         
             
                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 
1726 
     | 
    
         
             
                morphChildren(ctx, oldParent, newNode, oldNode, oldNode.nextSibling);
         
     | 
| 
       1732 
     | 
    
         
            -
                 
     | 
| 
       1733 
     | 
    
         
            -
                return childNodes.slice(index, childNodes.length - rightMargin);
         
     | 
| 
      
 1727 
     | 
    
         
            +
                return Array.from(oldParent.childNodes);
         
     | 
| 
       1734 
1728 
     | 
    
         
             
              }
         
     | 
| 
       1735 
1729 
     | 
    
         
             
              function saveAndRestoreFocus(ctx, fn) {
         
     | 
| 
       1736 
1730 
     | 
    
         
             
                if (!ctx.config.restoreFocus) return fn();
         
     | 
| 
         @@ -1740,8 +1734,8 @@ var Idiomorph = function() { 
     | 
|
| 
       1740 
1734 
     | 
    
         
             
                }
         
     | 
| 
       1741 
1735 
     | 
    
         
             
                const {id: activeElementId, selectionStart: selectionStart, selectionEnd: selectionEnd} = activeElement;
         
     | 
| 
       1742 
1736 
     | 
    
         
             
                const results = fn();
         
     | 
| 
       1743 
     | 
    
         
            -
                if (activeElementId && activeElementId !== document.activeElement?.id) {
         
     | 
| 
       1744 
     | 
    
         
            -
                  activeElement = ctx.target.querySelector( 
     | 
| 
      
 1737 
     | 
    
         
            +
                if (activeElementId && activeElementId !== document.activeElement?.getAttribute("id")) {
         
     | 
| 
      
 1738 
     | 
    
         
            +
                  activeElement = ctx.target.querySelector(`[id="${activeElementId}"]`);
         
     | 
| 
       1745 
1739 
     | 
    
         
             
                  activeElement?.focus();
         
     | 
| 
       1746 
1740 
     | 
    
         
             
                }
         
     | 
| 
       1747 
1741 
     | 
    
         
             
                if (activeElement && !activeElement.selectionEnd && selectionEnd) {
         
     | 
| 
         @@ -1768,11 +1762,14 @@ var Idiomorph = function() { 
     | 
|
| 
       1768 
1762 
     | 
    
         
             
                        continue;
         
     | 
| 
       1769 
1763 
     | 
    
         
             
                      }
         
     | 
| 
       1770 
1764 
     | 
    
         
             
                    }
         
     | 
| 
       1771 
     | 
    
         
            -
                    if (newChild instanceof Element 
     | 
| 
       1772 
     | 
    
         
            -
                      const  
     | 
| 
       1773 
     | 
    
         
            -
                       
     | 
| 
       1774 
     | 
    
         
            -
             
     | 
| 
       1775 
     | 
    
         
            -
             
     | 
| 
      
 1765 
     | 
    
         
            +
                    if (newChild instanceof Element) {
         
     | 
| 
      
 1766 
     | 
    
         
            +
                      const newChildId = newChild.getAttribute("id");
         
     | 
| 
      
 1767 
     | 
    
         
            +
                      if (ctx.persistentIds.has(newChildId)) {
         
     | 
| 
      
 1768 
     | 
    
         
            +
                        const movedChild = moveBeforeById(oldParent, newChildId, insertionPoint, ctx);
         
     | 
| 
      
 1769 
     | 
    
         
            +
                        morphNode(movedChild, newChild, ctx);
         
     | 
| 
      
 1770 
     | 
    
         
            +
                        insertionPoint = movedChild.nextSibling;
         
     | 
| 
      
 1771 
     | 
    
         
            +
                        continue;
         
     | 
| 
      
 1772 
     | 
    
         
            +
                      }
         
     | 
| 
       1776 
1773 
     | 
    
         
             
                    }
         
     | 
| 
       1777 
1774 
     | 
    
         
             
                    const insertedNode = createNode(oldParent, newChild, insertionPoint, ctx);
         
     | 
| 
       1778 
1775 
     | 
    
         
             
                    if (insertedNode) {
         
     | 
| 
         @@ -1824,7 +1821,7 @@ var Idiomorph = function() { 
     | 
|
| 
       1824 
1821 
     | 
    
         
             
                          softMatch = undefined;
         
     | 
| 
       1825 
1822 
     | 
    
         
             
                        }
         
     | 
| 
       1826 
1823 
     | 
    
         
             
                      }
         
     | 
| 
       1827 
     | 
    
         
            -
                      if ( 
     | 
| 
      
 1824 
     | 
    
         
            +
                      if (ctx.activeElementAndParents.includes(cursor)) break;
         
     | 
| 
       1828 
1825 
     | 
    
         
             
                      cursor = cursor.nextSibling;
         
     | 
| 
       1829 
1826 
     | 
    
         
             
                    }
         
     | 
| 
       1830 
1827 
     | 
    
         
             
                    return softMatch || null;
         
     | 
| 
         @@ -1843,7 +1840,7 @@ var Idiomorph = function() { 
     | 
|
| 
       1843 
1840 
     | 
    
         
             
                  function isSoftMatch(oldNode, newNode) {
         
     | 
| 
       1844 
1841 
     | 
    
         
             
                    const oldElt = oldNode;
         
     | 
| 
       1845 
1842 
     | 
    
         
             
                    const newElt = newNode;
         
     | 
| 
       1846 
     | 
    
         
            -
                    return oldElt.nodeType === newElt.nodeType && oldElt.tagName === newElt.tagName && (!oldElt.id || oldElt.id === newElt.id);
         
     | 
| 
      
 1843 
     | 
    
         
            +
                    return oldElt.nodeType === newElt.nodeType && oldElt.tagName === newElt.tagName && (!oldElt.getAttribute?.("id") || oldElt.getAttribute?.("id") === newElt.getAttribute?.("id"));
         
     | 
| 
       1847 
1844 
     | 
    
         
             
                  }
         
     | 
| 
       1848 
1845 
     | 
    
         
             
                  return findBestMatch;
         
     | 
| 
       1849 
1846 
     | 
    
         
             
                }();
         
     | 
| 
         @@ -1866,13 +1863,13 @@ var Idiomorph = function() { 
     | 
|
| 
       1866 
1863 
     | 
    
         
             
                  return cursor;
         
     | 
| 
       1867 
1864 
     | 
    
         
             
                }
         
     | 
| 
       1868 
1865 
     | 
    
         
             
                function moveBeforeById(parentNode, id, after, ctx) {
         
     | 
| 
       1869 
     | 
    
         
            -
                  const target = ctx.target.querySelector( 
     | 
| 
      
 1866 
     | 
    
         
            +
                  const target = ctx.target.getAttribute?.("id") === id && ctx.target || ctx.target.querySelector(`[id="${id}"]`) || ctx.pantry.querySelector(`[id="${id}"]`);
         
     | 
| 
       1870 
1867 
     | 
    
         
             
                  removeElementFromAncestorsIdMaps(target, ctx);
         
     | 
| 
       1871 
1868 
     | 
    
         
             
                  moveBefore(parentNode, target, after);
         
     | 
| 
       1872 
1869 
     | 
    
         
             
                  return target;
         
     | 
| 
       1873 
1870 
     | 
    
         
             
                }
         
     | 
| 
       1874 
1871 
     | 
    
         
             
                function removeElementFromAncestorsIdMaps(element, ctx) {
         
     | 
| 
       1875 
     | 
    
         
            -
                  const id = element.id;
         
     | 
| 
      
 1872 
     | 
    
         
            +
                  const id = element.getAttribute("id");
         
     | 
| 
       1876 
1873 
     | 
    
         
             
                  while (element = element.parentNode) {
         
     | 
| 
       1877 
1874 
     | 
    
         
             
                    let idSet = ctx.idMap.get(element);
         
     | 
| 
       1878 
1875 
     | 
    
         
             
                    if (idSet) {
         
     | 
| 
         @@ -2116,6 +2113,7 @@ var Idiomorph = function() { 
     | 
|
| 
       2116 
2113 
     | 
    
         
             
                    idMap: idMap,
         
     | 
| 
       2117 
2114 
     | 
    
         
             
                    persistentIds: persistentIds,
         
     | 
| 
       2118 
2115 
     | 
    
         
             
                    pantry: createPantry(),
         
     | 
| 
      
 2116 
     | 
    
         
            +
                    activeElementAndParents: createActiveElementAndParents(oldNode),
         
     | 
| 
       2119 
2117 
     | 
    
         
             
                    callbacks: mergedConfig.callbacks,
         
     | 
| 
       2120 
2118 
     | 
    
         
             
                    head: mergedConfig.head
         
     | 
| 
       2121 
2119 
     | 
    
         
             
                  };
         
     | 
| 
         @@ -2133,16 +2131,29 @@ var Idiomorph = function() { 
     | 
|
| 
       2133 
2131 
     | 
    
         
             
                  document.body.insertAdjacentElement("afterend", pantry);
         
     | 
| 
       2134 
2132 
     | 
    
         
             
                  return pantry;
         
     | 
| 
       2135 
2133 
     | 
    
         
             
                }
         
     | 
| 
      
 2134 
     | 
    
         
            +
                function createActiveElementAndParents(oldNode) {
         
     | 
| 
      
 2135 
     | 
    
         
            +
                  let activeElementAndParents = [];
         
     | 
| 
      
 2136 
     | 
    
         
            +
                  let elt = document.activeElement;
         
     | 
| 
      
 2137 
     | 
    
         
            +
                  if (elt?.tagName !== "BODY" && oldNode.contains(elt)) {
         
     | 
| 
      
 2138 
     | 
    
         
            +
                    while (elt) {
         
     | 
| 
      
 2139 
     | 
    
         
            +
                      activeElementAndParents.push(elt);
         
     | 
| 
      
 2140 
     | 
    
         
            +
                      if (elt === oldNode) break;
         
     | 
| 
      
 2141 
     | 
    
         
            +
                      elt = elt.parentElement;
         
     | 
| 
      
 2142 
     | 
    
         
            +
                    }
         
     | 
| 
      
 2143 
     | 
    
         
            +
                  }
         
     | 
| 
      
 2144 
     | 
    
         
            +
                  return activeElementAndParents;
         
     | 
| 
      
 2145 
     | 
    
         
            +
                }
         
     | 
| 
       2136 
2146 
     | 
    
         
             
                function findIdElements(root) {
         
     | 
| 
       2137 
2147 
     | 
    
         
             
                  let elements = Array.from(root.querySelectorAll("[id]"));
         
     | 
| 
       2138 
     | 
    
         
            -
                  if (root.id) {
         
     | 
| 
      
 2148 
     | 
    
         
            +
                  if (root.getAttribute?.("id")) {
         
     | 
| 
       2139 
2149 
     | 
    
         
             
                    elements.push(root);
         
     | 
| 
       2140 
2150 
     | 
    
         
             
                  }
         
     | 
| 
       2141 
2151 
     | 
    
         
             
                  return elements;
         
     | 
| 
       2142 
2152 
     | 
    
         
             
                }
         
     | 
| 
       2143 
2153 
     | 
    
         
             
                function populateIdMapWithTree(idMap, persistentIds, root, elements) {
         
     | 
| 
       2144 
2154 
     | 
    
         
             
                  for (const elt of elements) {
         
     | 
| 
       2145 
     | 
    
         
            -
                     
     | 
| 
      
 2155 
     | 
    
         
            +
                    const id = elt.getAttribute("id");
         
     | 
| 
      
 2156 
     | 
    
         
            +
                    if (persistentIds.has(id)) {
         
     | 
| 
       2146 
2157 
     | 
    
         
             
                      let current = elt;
         
     | 
| 
       2147 
2158 
     | 
    
         
             
                      while (current) {
         
     | 
| 
       2148 
2159 
     | 
    
         
             
                        let idSet = idMap.get(current);
         
     | 
| 
         @@ -2150,7 +2161,7 @@ var Idiomorph = function() { 
     | 
|
| 
       2150 
2161 
     | 
    
         
             
                          idSet = new Set;
         
     | 
| 
       2151 
2162 
     | 
    
         
             
                          idMap.set(current, idSet);
         
     | 
| 
       2152 
2163 
     | 
    
         
             
                        }
         
     | 
| 
       2153 
     | 
    
         
            -
                        idSet.add( 
     | 
| 
      
 2164 
     | 
    
         
            +
                        idSet.add(id);
         
     | 
| 
       2154 
2165 
     | 
    
         
             
                        if (current === root) break;
         
     | 
| 
       2155 
2166 
     | 
    
         
             
                        current = current.parentElement;
         
     | 
| 
       2156 
2167 
     | 
    
         
             
                      }
         
     | 
| 
         @@ -2213,7 +2224,7 @@ var Idiomorph = function() { 
     | 
|
| 
       2213 
2224 
     | 
    
         
             
                    return newContent;
         
     | 
| 
       2214 
2225 
     | 
    
         
             
                  } else if (newContent instanceof Node) {
         
     | 
| 
       2215 
2226 
     | 
    
         
             
                    if (newContent.parentNode) {
         
     | 
| 
       2216 
     | 
    
         
            -
                      return  
     | 
| 
      
 2227 
     | 
    
         
            +
                      return new SlicedParentNode(newContent);
         
     | 
| 
       2217 
2228 
     | 
    
         
             
                    } else {
         
     | 
| 
       2218 
2229 
     | 
    
         
             
                      const dummyParent = document.createElement("div");
         
     | 
| 
       2219 
2230 
     | 
    
         
             
                      dummyParent.append(newContent);
         
     | 
| 
         @@ -2227,19 +2238,43 @@ var Idiomorph = function() { 
     | 
|
| 
       2227 
2238 
     | 
    
         
             
                    return dummyParent;
         
     | 
| 
       2228 
2239 
     | 
    
         
             
                  }
         
     | 
| 
       2229 
2240 
     | 
    
         
             
                }
         
     | 
| 
       2230 
     | 
    
         
            -
                 
     | 
| 
       2231 
     | 
    
         
            -
                   
     | 
| 
       2232 
     | 
    
         
            -
                     
     | 
| 
       2233 
     | 
    
         
            -
                     
     | 
| 
       2234 
     | 
    
         
            -
             
     | 
| 
       2235 
     | 
    
         
            -
             
     | 
| 
       2236 
     | 
    
         
            -
             
     | 
| 
       2237 
     | 
    
         
            -
             
     | 
| 
       2238 
     | 
    
         
            -
                     
     | 
| 
       2239 
     | 
    
         
            -
                     
     | 
| 
       2240 
     | 
    
         
            -
             
     | 
| 
      
 2241 
     | 
    
         
            +
                class SlicedParentNode {
         
     | 
| 
      
 2242 
     | 
    
         
            +
                  constructor(node) {
         
     | 
| 
      
 2243 
     | 
    
         
            +
                    this.originalNode = node;
         
     | 
| 
      
 2244 
     | 
    
         
            +
                    this.realParentNode = node.parentNode;
         
     | 
| 
      
 2245 
     | 
    
         
            +
                    this.previousSibling = node.previousSibling;
         
     | 
| 
      
 2246 
     | 
    
         
            +
                    this.nextSibling = node.nextSibling;
         
     | 
| 
      
 2247 
     | 
    
         
            +
                  }
         
     | 
| 
      
 2248 
     | 
    
         
            +
                  get childNodes() {
         
     | 
| 
      
 2249 
     | 
    
         
            +
                    const nodes = [];
         
     | 
| 
      
 2250 
     | 
    
         
            +
                    let cursor = this.previousSibling ? this.previousSibling.nextSibling : this.realParentNode.firstChild;
         
     | 
| 
      
 2251 
     | 
    
         
            +
                    while (cursor && cursor != this.nextSibling) {
         
     | 
| 
      
 2252 
     | 
    
         
            +
                      nodes.push(cursor);
         
     | 
| 
      
 2253 
     | 
    
         
            +
                      cursor = cursor.nextSibling;
         
     | 
| 
       2241 
2254 
     | 
    
         
             
                    }
         
     | 
| 
       2242 
     | 
    
         
            -
             
     | 
| 
      
 2255 
     | 
    
         
            +
                    return nodes;
         
     | 
| 
      
 2256 
     | 
    
         
            +
                  }
         
     | 
| 
      
 2257 
     | 
    
         
            +
                  querySelectorAll(selector) {
         
     | 
| 
      
 2258 
     | 
    
         
            +
                    return this.childNodes.reduce(((results, node) => {
         
     | 
| 
      
 2259 
     | 
    
         
            +
                      if (node instanceof Element) {
         
     | 
| 
      
 2260 
     | 
    
         
            +
                        if (node.matches(selector)) results.push(node);
         
     | 
| 
      
 2261 
     | 
    
         
            +
                        const nodeList = node.querySelectorAll(selector);
         
     | 
| 
      
 2262 
     | 
    
         
            +
                        for (let i = 0; i < nodeList.length; i++) {
         
     | 
| 
      
 2263 
     | 
    
         
            +
                          results.push(nodeList[i]);
         
     | 
| 
      
 2264 
     | 
    
         
            +
                        }
         
     | 
| 
      
 2265 
     | 
    
         
            +
                      }
         
     | 
| 
      
 2266 
     | 
    
         
            +
                      return results;
         
     | 
| 
      
 2267 
     | 
    
         
            +
                    }), []);
         
     | 
| 
      
 2268 
     | 
    
         
            +
                  }
         
     | 
| 
      
 2269 
     | 
    
         
            +
                  insertBefore(node, referenceNode) {
         
     | 
| 
      
 2270 
     | 
    
         
            +
                    return this.realParentNode.insertBefore(node, referenceNode);
         
     | 
| 
      
 2271 
     | 
    
         
            +
                  }
         
     | 
| 
      
 2272 
     | 
    
         
            +
                  moveBefore(node, referenceNode) {
         
     | 
| 
      
 2273 
     | 
    
         
            +
                    return this.realParentNode.moveBefore(node, referenceNode);
         
     | 
| 
      
 2274 
     | 
    
         
            +
                  }
         
     | 
| 
      
 2275 
     | 
    
         
            +
                  get __idiomorphRoot() {
         
     | 
| 
      
 2276 
     | 
    
         
            +
                    return this.originalNode;
         
     | 
| 
      
 2277 
     | 
    
         
            +
                  }
         
     | 
| 
       2243 
2278 
     | 
    
         
             
                }
         
     | 
| 
       2244 
2279 
     | 
    
         
             
                function parseContent(newContent) {
         
     | 
| 
       2245 
2280 
     | 
    
         
             
                  let parser = new DOMParser;
         
     | 
| 
         @@ -2281,12 +2316,25 @@ function morphElements(currentElement, newElement, {callbacks: callbacks, ...opt 
     | 
|
| 
       2281 
2316 
     | 
    
         
             
              });
         
     | 
| 
       2282 
2317 
     | 
    
         
             
            }
         
     | 
| 
       2283 
2318 
     | 
    
         | 
| 
       2284 
     | 
    
         
            -
            function morphChildren(currentElement, newElement) {
         
     | 
| 
      
 2319 
     | 
    
         
            +
            function morphChildren(currentElement, newElement, options = {}) {
         
     | 
| 
       2285 
2320 
     | 
    
         
             
              morphElements(currentElement, newElement.childNodes, {
         
     | 
| 
      
 2321 
     | 
    
         
            +
                ...options,
         
     | 
| 
       2286 
2322 
     | 
    
         
             
                morphStyle: "innerHTML"
         
     | 
| 
       2287 
2323 
     | 
    
         
             
              });
         
     | 
| 
       2288 
2324 
     | 
    
         
             
            }
         
     | 
| 
       2289 
2325 
     | 
    
         | 
| 
      
 2326 
     | 
    
         
            +
            function shouldRefreshFrameWithMorphing(currentFrame, newFrame) {
         
     | 
| 
      
 2327 
     | 
    
         
            +
              return currentFrame instanceof FrameElement && currentFrame.shouldReloadWithMorph && (!newFrame || areFramesCompatibleForRefreshing(currentFrame, newFrame)) && !currentFrame.closest("[data-turbo-permanent]");
         
     | 
| 
      
 2328 
     | 
    
         
            +
            }
         
     | 
| 
      
 2329 
     | 
    
         
            +
             
     | 
| 
      
 2330 
     | 
    
         
            +
            function areFramesCompatibleForRefreshing(currentFrame, newFrame) {
         
     | 
| 
      
 2331 
     | 
    
         
            +
              return newFrame instanceof Element && newFrame.nodeName === "TURBO-FRAME" && currentFrame.id === newFrame.id && (!newFrame.getAttribute("src") || urlsAreEqual(currentFrame.src, newFrame.getAttribute("src")));
         
     | 
| 
      
 2332 
     | 
    
         
            +
            }
         
     | 
| 
      
 2333 
     | 
    
         
            +
             
     | 
| 
      
 2334 
     | 
    
         
            +
            function closestFrameReloadableWithMorphing(node) {
         
     | 
| 
      
 2335 
     | 
    
         
            +
              return node.parentElement.closest("turbo-frame[src][refresh=morph]");
         
     | 
| 
      
 2336 
     | 
    
         
            +
            }
         
     | 
| 
      
 2337 
     | 
    
         
            +
             
     | 
| 
       2290 
2338 
     | 
    
         
             
            class DefaultIdiomorphCallbacks {
         
     | 
| 
       2291 
2339 
     | 
    
         
             
              #beforeNodeMorphed;
         
     | 
| 
       2292 
2340 
     | 
    
         
             
              constructor({beforeNodeMorphed: beforeNodeMorphed} = {}) {
         
     | 
| 
         @@ -2344,7 +2392,17 @@ class MorphingFrameRenderer extends FrameRenderer { 
     | 
|
| 
       2344 
2392 
     | 
    
         
             
                    newElement: newElement
         
     | 
| 
       2345 
2393 
     | 
    
         
             
                  }
         
     | 
| 
       2346 
2394 
     | 
    
         
             
                });
         
     | 
| 
       2347 
     | 
    
         
            -
                morphChildren(currentElement, newElement 
     | 
| 
      
 2395 
     | 
    
         
            +
                morphChildren(currentElement, newElement, {
         
     | 
| 
      
 2396 
     | 
    
         
            +
                  callbacks: {
         
     | 
| 
      
 2397 
     | 
    
         
            +
                    beforeNodeMorphed: (node, newNode) => {
         
     | 
| 
      
 2398 
     | 
    
         
            +
                      if (shouldRefreshFrameWithMorphing(node, newNode) && closestFrameReloadableWithMorphing(node) === currentElement) {
         
     | 
| 
      
 2399 
     | 
    
         
            +
                        node.reload();
         
     | 
| 
      
 2400 
     | 
    
         
            +
                        return false;
         
     | 
| 
      
 2401 
     | 
    
         
            +
                      }
         
     | 
| 
      
 2402 
     | 
    
         
            +
                      return true;
         
     | 
| 
      
 2403 
     | 
    
         
            +
                    }
         
     | 
| 
      
 2404 
     | 
    
         
            +
                  }
         
     | 
| 
      
 2405 
     | 
    
         
            +
                });
         
     | 
| 
       2348 
2406 
     | 
    
         
             
              }
         
     | 
| 
       2349 
2407 
     | 
    
         
             
              async preservingPermanentElements(callback) {
         
     | 
| 
       2350 
2408 
     | 
    
         
             
                return await callback();
         
     | 
| 
         @@ -2596,7 +2654,8 @@ class PageSnapshot extends Snapshot { 
     | 
|
| 
       2596 
2654 
     | 
    
         
             
                return this.getSetting("visit-control") != "reload";
         
     | 
| 
       2597 
2655 
     | 
    
         
             
              }
         
     | 
| 
       2598 
2656 
     | 
    
         
             
              get prefersViewTransitions() {
         
     | 
| 
       2599 
     | 
    
         
            -
                 
     | 
| 
      
 2657 
     | 
    
         
            +
                const viewTransitionEnabled = this.getSetting("view-transition") === "true" || this.headSnapshot.getMetaValue("view-transition") === "same-origin";
         
     | 
| 
      
 2658 
     | 
    
         
            +
                return viewTransitionEnabled && !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
         
     | 
| 
       2600 
2659 
     | 
    
         
             
              }
         
     | 
| 
       2601 
2660 
     | 
    
         
             
              get shouldMorphPage() {
         
     | 
| 
       2602 
2661 
     | 
    
         
             
                return this.getSetting("refresh-method") === "morph";
         
     | 
| 
         @@ -3011,6 +3070,7 @@ class BrowserAdapter { 
     | 
|
| 
       3011 
3070 
     | 
    
         
             
              }
         
     | 
| 
       3012 
3071 
     | 
    
         
             
              visitStarted(visit) {
         
     | 
| 
       3013 
3072 
     | 
    
         
             
                this.location = visit.location;
         
     | 
| 
      
 3073 
     | 
    
         
            +
                this.redirectedToLocation = null;
         
     | 
| 
       3014 
3074 
     | 
    
         
             
                visit.loadCachedSnapshot();
         
     | 
| 
       3015 
3075 
     | 
    
         
             
                visit.issueRequest();
         
     | 
| 
       3016 
3076 
     | 
    
         
             
                visit.goToSamePageAnchor();
         
     | 
| 
         @@ -3025,6 +3085,9 @@ class BrowserAdapter { 
     | 
|
| 
       3025 
3085 
     | 
    
         
             
              }
         
     | 
| 
       3026 
3086 
     | 
    
         
             
              visitRequestCompleted(visit) {
         
     | 
| 
       3027 
3087 
     | 
    
         
             
                visit.loadResponse();
         
     | 
| 
      
 3088 
     | 
    
         
            +
                if (visit.response.redirected) {
         
     | 
| 
      
 3089 
     | 
    
         
            +
                  this.redirectedToLocation = visit.redirectedToLocation;
         
     | 
| 
      
 3090 
     | 
    
         
            +
                }
         
     | 
| 
       3028 
3091 
     | 
    
         
             
              }
         
     | 
| 
       3029 
3092 
     | 
    
         
             
              visitRequestFailedWithStatusCode(visit, statusCode) {
         
     | 
| 
       3030 
3093 
     | 
    
         
             
                switch (statusCode) {
         
     | 
| 
         @@ -3095,7 +3158,7 @@ class BrowserAdapter { 
     | 
|
| 
       3095 
3158 
     | 
    
         
             
                dispatch("turbo:reload", {
         
     | 
| 
       3096 
3159 
     | 
    
         
             
                  detail: reason
         
     | 
| 
       3097 
3160 
     | 
    
         
             
                });
         
     | 
| 
       3098 
     | 
    
         
            -
                window.location.href = this.location?.toString() || window.location.href;
         
     | 
| 
      
 3161 
     | 
    
         
            +
                window.location.href = (this.redirectedToLocation || this.location)?.toString() || window.location.href;
         
     | 
| 
       3099 
3162 
     | 
    
         
             
              }
         
     | 
| 
       3100 
3163 
     | 
    
         
             
              get navigator() {
         
     | 
| 
       3101 
3164 
     | 
    
         
             
                return this.session.navigator;
         
     | 
| 
         @@ -3338,6 +3401,7 @@ class LinkPrefetchObserver { 
     | 
|
| 
       3338 
3401 
     | 
    
         
             
                  if (this.delegate.canPrefetchRequestToLocation(link, location)) {
         
     | 
| 
       3339 
3402 
     | 
    
         
             
                    this.#prefetchedLink = link;
         
     | 
| 
       3340 
3403 
     | 
    
         
             
                    const fetchRequest = new FetchRequest(this, FetchMethod.get, location, new URLSearchParams, target);
         
     | 
| 
      
 3404 
     | 
    
         
            +
                    fetchRequest.fetchOptions.priority = "low";
         
     | 
| 
       3341 
3405 
     | 
    
         
             
                    prefetchCache.setLater(location.toString(), fetchRequest, this.#cacheTtl);
         
     | 
| 
       3342 
3406 
     | 
    
         
             
                  }
         
     | 
| 
       3343 
3407 
     | 
    
         
             
                }
         
     | 
| 
         @@ -3988,12 +4052,15 @@ class MorphingPageRenderer extends PageRenderer { 
     | 
|
| 
       3988 
4052 
     | 
    
         
             
              static renderElement(currentElement, newElement) {
         
     | 
| 
       3989 
4053 
     | 
    
         
             
                morphElements(currentElement, newElement, {
         
     | 
| 
       3990 
4054 
     | 
    
         
             
                  callbacks: {
         
     | 
| 
       3991 
     | 
    
         
            -
                    beforeNodeMorphed:  
     | 
| 
      
 4055 
     | 
    
         
            +
                    beforeNodeMorphed: (node, newNode) => {
         
     | 
| 
      
 4056 
     | 
    
         
            +
                      if (shouldRefreshFrameWithMorphing(node, newNode) && !closestFrameReloadableWithMorphing(node)) {
         
     | 
| 
      
 4057 
     | 
    
         
            +
                        node.reload();
         
     | 
| 
      
 4058 
     | 
    
         
            +
                        return false;
         
     | 
| 
      
 4059 
     | 
    
         
            +
                      }
         
     | 
| 
      
 4060 
     | 
    
         
            +
                      return true;
         
     | 
| 
      
 4061 
     | 
    
         
            +
                    }
         
     | 
| 
       3992 
4062 
     | 
    
         
             
                  }
         
     | 
| 
       3993 
4063 
     | 
    
         
             
                });
         
     | 
| 
       3994 
     | 
    
         
            -
                for (const frame of currentElement.querySelectorAll("turbo-frame")) {
         
     | 
| 
       3995 
     | 
    
         
            -
                  if (canRefreshFrame(frame)) frame.reload();
         
     | 
| 
       3996 
     | 
    
         
            -
                }
         
     | 
| 
       3997 
4064 
     | 
    
         
             
                dispatch("turbo:morph", {
         
     | 
| 
       3998 
4065 
     | 
    
         
             
                  detail: {
         
     | 
| 
       3999 
4066 
     | 
    
         
             
                    currentElement: currentElement,
         
     | 
| 
         @@ -4012,10 +4079,6 @@ class MorphingPageRenderer extends PageRenderer { 
     | 
|
| 
       4012 
4079 
     | 
    
         
             
              }
         
     | 
| 
       4013 
4080 
     | 
    
         
             
            }
         
     | 
| 
       4014 
4081 
     | 
    
         | 
| 
       4015 
     | 
    
         
            -
            function canRefreshFrame(frame) {
         
     | 
| 
       4016 
     | 
    
         
            -
              return frame instanceof FrameElement && frame.src && frame.refresh === "morph" && !frame.closest("[data-turbo-permanent]");
         
     | 
| 
       4017 
     | 
    
         
            -
            }
         
     | 
| 
       4018 
     | 
    
         
            -
             
     | 
| 
       4019 
4082 
     | 
    
         
             
            class SnapshotCache {
         
     | 
| 
       4020 
4083 
     | 
    
         
             
              keys=[];
         
     | 
| 
       4021 
4084 
     | 
    
         
             
              snapshots={};
         
     | 
| 
         @@ -4616,6 +4679,14 @@ function setFormMode(mode) { 
     | 
|
| 
       4616 
4679 
     | 
    
         
             
              config.forms.mode = mode;
         
     | 
| 
       4617 
4680 
     | 
    
         
             
            }
         
     | 
| 
       4618 
4681 
     | 
    
         | 
| 
      
 4682 
     | 
    
         
            +
            function morphBodyElements(currentBody, newBody) {
         
     | 
| 
      
 4683 
     | 
    
         
            +
              MorphingPageRenderer.renderElement(currentBody, newBody);
         
     | 
| 
      
 4684 
     | 
    
         
            +
            }
         
     | 
| 
      
 4685 
     | 
    
         
            +
             
     | 
| 
      
 4686 
     | 
    
         
            +
            function morphTurboFrameElements(currentFrame, newFrame) {
         
     | 
| 
      
 4687 
     | 
    
         
            +
              MorphingFrameRenderer.renderElement(currentFrame, newFrame);
         
     | 
| 
      
 4688 
     | 
    
         
            +
            }
         
     | 
| 
      
 4689 
     | 
    
         
            +
             
     | 
| 
       4619 
4690 
     | 
    
         
             
            var Turbo = Object.freeze({
         
     | 
| 
       4620 
4691 
     | 
    
         
             
              __proto__: null,
         
     | 
| 
       4621 
4692 
     | 
    
         
             
              navigator: navigator$1,
         
     | 
| 
         @@ -4635,7 +4706,11 @@ var Turbo = Object.freeze({ 
     | 
|
| 
       4635 
4706 
     | 
    
         
             
              clearCache: clearCache,
         
     | 
| 
       4636 
4707 
     | 
    
         
             
              setProgressBarDelay: setProgressBarDelay,
         
     | 
| 
       4637 
4708 
     | 
    
         
             
              setConfirmMethod: setConfirmMethod,
         
     | 
| 
       4638 
     | 
    
         
            -
              setFormMode: setFormMode
         
     | 
| 
      
 4709 
     | 
    
         
            +
              setFormMode: setFormMode,
         
     | 
| 
      
 4710 
     | 
    
         
            +
              morphBodyElements: morphBodyElements,
         
     | 
| 
      
 4711 
     | 
    
         
            +
              morphTurboFrameElements: morphTurboFrameElements,
         
     | 
| 
      
 4712 
     | 
    
         
            +
              morphChildren: morphChildren,
         
     | 
| 
      
 4713 
     | 
    
         
            +
              morphElements: morphElements
         
     | 
| 
       4639 
4714 
     | 
    
         
             
            });
         
     | 
| 
       4640 
4715 
     | 
    
         | 
| 
       4641 
4716 
     | 
    
         
             
            class TurboFrameMissingError extends Error {}
         
     | 
| 
         @@ -5330,6 +5405,10 @@ var Turbo$1 = Object.freeze({ 
     | 
|
| 
       5330 
5405 
     | 
    
         
             
              fetchEnctypeFromString: fetchEnctypeFromString,
         
     | 
| 
       5331 
5406 
     | 
    
         
             
              fetchMethodFromString: fetchMethodFromString,
         
     | 
| 
       5332 
5407 
     | 
    
         
             
              isSafe: isSafe,
         
     | 
| 
      
 5408 
     | 
    
         
            +
              morphBodyElements: morphBodyElements,
         
     | 
| 
      
 5409 
     | 
    
         
            +
              morphChildren: morphChildren,
         
     | 
| 
      
 5410 
     | 
    
         
            +
              morphElements: morphElements,
         
     | 
| 
      
 5411 
     | 
    
         
            +
              morphTurboFrameElements: morphTurboFrameElements,
         
     | 
| 
       5333 
5412 
     | 
    
         
             
              navigator: navigator$1,
         
     | 
| 
       5334 
5413 
     | 
    
         
             
              registerAdapter: registerAdapter,
         
     | 
| 
       5335 
5414 
     | 
    
         
             
              renderStreamMessage: renderStreamMessage,
         
     |