turbo-rails 2.0.19 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 790d37e202689c18ac20fc957cedaec41552a3e801fc0dfad05bdb2929b6c5e6
4
- data.tar.gz: b1a177817fba749087ffe1787a8bf2fb325c9242fcd6044ac9445ec7e4376a9f
3
+ metadata.gz: 06430d7095a020ded9bf6f76888c703184a7ffdd0c99e91f5461644c7fbdd062
4
+ data.tar.gz: b8b15ac1f37352d7a75782fe095c621340bb648eb24b5e36009634441efe098f
5
5
  SHA512:
6
- metadata.gz: c0e0ff4bdee78636bad18c5f677d67e85593eb2ce8cc4496c684047a434827a7a3779a44d8426a61b35c52de8916dc4da1e30b0fcb7960543adf200db313ff55
7
- data.tar.gz: 0a78a27690cbaea16e56d991493eba75da6ef017c70304627dd9381aa4d56f09dc1efa7f176bb3cf69ec292ab22aeee05ba97d3cd43ee0363d80eaabe0aece05
6
+ metadata.gz: e4d105df336ab191ba9c3673bec4d47d7b4aa561cc3a865ada719ea5c478f70587a55bdd0b97a55b5846ab39afd6b18d863e50f74ec0c40657a407b00ad2cb2a
7
+ data.tar.gz: 9b293373d747dbe2964328636a3c5d4eae68fbf522a2f704948c0ea53b671c90ad8b13c8049e1a327a25127691e3cc9c3814634ae5cb9d174f94d9ff54c4f3b0
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Turbo 8.0.18
2
+ Turbo 8.0.19
3
3
  Copyright © 2025 37signals LLC
4
4
  */
5
5
  (function(prototype) {
@@ -1723,12 +1723,8 @@ var Idiomorph = function() {
1723
1723
  }
1724
1724
  function morphOuterHTML(ctx, oldNode, newNode) {
1725
1725
  const oldParent = normalizeParent(oldNode);
1726
- let childNodes = Array.from(oldParent.childNodes);
1727
- const index = childNodes.indexOf(oldNode);
1728
- const rightMargin = childNodes.length - (index + 1);
1729
1726
  morphChildren(ctx, oldParent, newNode, oldNode, oldNode.nextSibling);
1730
- childNodes = Array.from(oldParent.childNodes);
1731
- return childNodes.slice(index, childNodes.length - rightMargin);
1727
+ return Array.from(oldParent.childNodes);
1732
1728
  }
1733
1729
  function saveAndRestoreFocus(ctx, fn) {
1734
1730
  if (!ctx.config.restoreFocus) return fn();
@@ -1738,8 +1734,8 @@ var Idiomorph = function() {
1738
1734
  }
1739
1735
  const {id: activeElementId, selectionStart: selectionStart, selectionEnd: selectionEnd} = activeElement;
1740
1736
  const results = fn();
1741
- if (activeElementId && activeElementId !== document.activeElement?.id) {
1742
- activeElement = ctx.target.querySelector(`#${activeElementId}`);
1737
+ if (activeElementId && activeElementId !== document.activeElement?.getAttribute("id")) {
1738
+ activeElement = ctx.target.querySelector(`[id="${activeElementId}"]`);
1743
1739
  activeElement?.focus();
1744
1740
  }
1745
1741
  if (activeElement && !activeElement.selectionEnd && selectionEnd) {
@@ -1766,11 +1762,14 @@ var Idiomorph = function() {
1766
1762
  continue;
1767
1763
  }
1768
1764
  }
1769
- if (newChild instanceof Element && ctx.persistentIds.has(newChild.id)) {
1770
- const movedChild = moveBeforeById(oldParent, newChild.id, insertionPoint, ctx);
1771
- morphNode(movedChild, newChild, ctx);
1772
- insertionPoint = movedChild.nextSibling;
1773
- continue;
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
+ }
1774
1773
  }
1775
1774
  const insertedNode = createNode(oldParent, newChild, insertionPoint, ctx);
1776
1775
  if (insertedNode) {
@@ -1822,7 +1821,7 @@ var Idiomorph = function() {
1822
1821
  softMatch = undefined;
1823
1822
  }
1824
1823
  }
1825
- if (cursor.contains(document.activeElement)) break;
1824
+ if (ctx.activeElementAndParents.includes(cursor)) break;
1826
1825
  cursor = cursor.nextSibling;
1827
1826
  }
1828
1827
  return softMatch || null;
@@ -1841,7 +1840,7 @@ var Idiomorph = function() {
1841
1840
  function isSoftMatch(oldNode, newNode) {
1842
1841
  const oldElt = oldNode;
1843
1842
  const newElt = newNode;
1844
- 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"));
1845
1844
  }
1846
1845
  return findBestMatch;
1847
1846
  }();
@@ -1864,13 +1863,13 @@ var Idiomorph = function() {
1864
1863
  return cursor;
1865
1864
  }
1866
1865
  function moveBeforeById(parentNode, id, after, ctx) {
1867
- const target = ctx.target.querySelector(`#${id}`) || ctx.pantry.querySelector(`#${id}`);
1866
+ const target = ctx.target.getAttribute?.("id") === id && ctx.target || ctx.target.querySelector(`[id="${id}"]`) || ctx.pantry.querySelector(`[id="${id}"]`);
1868
1867
  removeElementFromAncestorsIdMaps(target, ctx);
1869
1868
  moveBefore(parentNode, target, after);
1870
1869
  return target;
1871
1870
  }
1872
1871
  function removeElementFromAncestorsIdMaps(element, ctx) {
1873
- const id = element.id;
1872
+ const id = element.getAttribute("id");
1874
1873
  while (element = element.parentNode) {
1875
1874
  let idSet = ctx.idMap.get(element);
1876
1875
  if (idSet) {
@@ -2114,6 +2113,7 @@ var Idiomorph = function() {
2114
2113
  idMap: idMap,
2115
2114
  persistentIds: persistentIds,
2116
2115
  pantry: createPantry(),
2116
+ activeElementAndParents: createActiveElementAndParents(oldNode),
2117
2117
  callbacks: mergedConfig.callbacks,
2118
2118
  head: mergedConfig.head
2119
2119
  };
@@ -2131,16 +2131,29 @@ var Idiomorph = function() {
2131
2131
  document.body.insertAdjacentElement("afterend", pantry);
2132
2132
  return pantry;
2133
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
+ }
2134
2146
  function findIdElements(root) {
2135
2147
  let elements = Array.from(root.querySelectorAll("[id]"));
2136
- if (root.id) {
2148
+ if (root.getAttribute?.("id")) {
2137
2149
  elements.push(root);
2138
2150
  }
2139
2151
  return elements;
2140
2152
  }
2141
2153
  function populateIdMapWithTree(idMap, persistentIds, root, elements) {
2142
2154
  for (const elt of elements) {
2143
- if (persistentIds.has(elt.id)) {
2155
+ const id = elt.getAttribute("id");
2156
+ if (persistentIds.has(id)) {
2144
2157
  let current = elt;
2145
2158
  while (current) {
2146
2159
  let idSet = idMap.get(current);
@@ -2148,7 +2161,7 @@ var Idiomorph = function() {
2148
2161
  idSet = new Set;
2149
2162
  idMap.set(current, idSet);
2150
2163
  }
2151
- idSet.add(elt.id);
2164
+ idSet.add(id);
2152
2165
  if (current === root) break;
2153
2166
  current = current.parentElement;
2154
2167
  }
@@ -2211,7 +2224,7 @@ var Idiomorph = function() {
2211
2224
  return newContent;
2212
2225
  } else if (newContent instanceof Node) {
2213
2226
  if (newContent.parentNode) {
2214
- return createDuckTypedParent(newContent);
2227
+ return new SlicedParentNode(newContent);
2215
2228
  } else {
2216
2229
  const dummyParent = document.createElement("div");
2217
2230
  dummyParent.append(newContent);
@@ -2225,19 +2238,43 @@ var Idiomorph = function() {
2225
2238
  return dummyParent;
2226
2239
  }
2227
2240
  }
2228
- function createDuckTypedParent(newContent) {
2229
- return {
2230
- childNodes: [ newContent ],
2231
- querySelectorAll: s => {
2232
- const elements = newContent.querySelectorAll(s);
2233
- return newContent.matches(s) ? [ newContent, ...elements ] : elements;
2234
- },
2235
- insertBefore: (n, r) => newContent.parentNode.insertBefore(n, r),
2236
- moveBefore: (n, r) => newContent.parentNode.moveBefore(n, r),
2237
- get __idiomorphRoot() {
2238
- return newContent;
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;
2239
2254
  }
2240
- };
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
+ }
2241
2278
  }
2242
2279
  function parseContent(newContent) {
2243
2280
  let parser = new DOMParser;
@@ -2287,7 +2324,11 @@ function morphChildren(currentElement, newElement, options = {}) {
2287
2324
  }
2288
2325
 
2289
2326
  function shouldRefreshFrameWithMorphing(currentFrame, newFrame) {
2290
- return currentFrame instanceof FrameElement && newFrame instanceof Element && newFrame.nodeName === "TURBO-FRAME" && currentFrame.shouldReloadWithMorph && currentFrame.id === newFrame.id && (!newFrame.getAttribute("src") || urlsAreEqual(currentFrame.src, newFrame.getAttribute("src"))) && !currentFrame.closest("[data-turbo-permanent]");
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")));
2291
2332
  }
2292
2333
 
2293
2334
  function closestFrameReloadableWithMorphing(node) {