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 +4 -4
- data/app/assets/javascripts/turbo.js +75 -34
- data/app/assets/javascripts/turbo.min.js +4 -4
- data/app/assets/javascripts/turbo.min.js.map +1 -1
- data/lib/turbo/version.rb +1 -1
- metadata +1 -1
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
|
|
@@ -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) {
|
|
@@ -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
|
-
|
|
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(
|
|
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
|
|
1770
|
-
const
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
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 (
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
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 &&
|
|
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) {
|