turbo-rails 1.3.0 → 1.3.2
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 +88 -66
- data/app/assets/javascripts/turbo.min.js +5 -5
- data/app/assets/javascripts/turbo.min.js.map +1 -1
- data/lib/turbo/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d91b4f1416fb84779360c106d108b2ea6eae46788a9abec0316595ac7d050c5
|
4
|
+
data.tar.gz: 8a63eef6bae625fcc8260bf343f0e8184b46f84feb56722688ca3d1d5e6825bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a63be2834e1cb5253da4fdd3c8bb4d840c39dd277264fb4b9437107f0182b30cc5d3e41b0bead34dec5ad0d355fe84a6e6911ac3438c8aa3a5ad3ba94e919bd
|
7
|
+
data.tar.gz: a1ba1d13b8baa6a62bb67c22a1c9e5e386f2164ff072029b5821b857eae5e1d6197810c3c14c64f50e976452179bbe3cebb12a16a4b11114fa60d6bc25f480f3
|
@@ -97,11 +97,7 @@ class FrameElement extends HTMLElement {
|
|
97
97
|
this.delegate.disconnect();
|
98
98
|
}
|
99
99
|
reload() {
|
100
|
-
|
101
|
-
this.removeAttribute("complete");
|
102
|
-
this.src = null;
|
103
|
-
this.src = src;
|
104
|
-
return this.loaded;
|
100
|
+
return this.delegate.sourceURLReloaded();
|
105
101
|
}
|
106
102
|
attributeChangedCallback(name) {
|
107
103
|
if (name == "loading") {
|
@@ -936,6 +932,7 @@ class FormSubmitObserver {
|
|
936
932
|
const submitter = event.submitter || undefined;
|
937
933
|
if (form && submissionDoesNotDismissDialog(form, submitter) && submissionDoesNotTargetIFrame(form, submitter) && this.delegate.willSubmitForm(form, submitter)) {
|
938
934
|
event.preventDefault();
|
935
|
+
event.stopImmediatePropagation();
|
939
936
|
this.delegate.formSubmitted(form, submitter);
|
940
937
|
}
|
941
938
|
}
|
@@ -1076,6 +1073,47 @@ class FrameView extends View {
|
|
1076
1073
|
}
|
1077
1074
|
}
|
1078
1075
|
|
1076
|
+
class LinkInterceptor {
|
1077
|
+
constructor(delegate, element) {
|
1078
|
+
this.clickBubbled = event => {
|
1079
|
+
if (this.respondsToEventTarget(event.target)) {
|
1080
|
+
this.clickEvent = event;
|
1081
|
+
} else {
|
1082
|
+
delete this.clickEvent;
|
1083
|
+
}
|
1084
|
+
};
|
1085
|
+
this.linkClicked = event => {
|
1086
|
+
if (this.clickEvent && this.respondsToEventTarget(event.target) && event.target instanceof Element) {
|
1087
|
+
if (this.delegate.shouldInterceptLinkClick(event.target, event.detail.url, event.detail.originalEvent)) {
|
1088
|
+
this.clickEvent.preventDefault();
|
1089
|
+
event.preventDefault();
|
1090
|
+
this.delegate.linkClickIntercepted(event.target, event.detail.url, event.detail.originalEvent);
|
1091
|
+
}
|
1092
|
+
}
|
1093
|
+
delete this.clickEvent;
|
1094
|
+
};
|
1095
|
+
this.willVisit = _event => {
|
1096
|
+
delete this.clickEvent;
|
1097
|
+
};
|
1098
|
+
this.delegate = delegate;
|
1099
|
+
this.element = element;
|
1100
|
+
}
|
1101
|
+
start() {
|
1102
|
+
this.element.addEventListener("click", this.clickBubbled);
|
1103
|
+
document.addEventListener("turbo:click", this.linkClicked);
|
1104
|
+
document.addEventListener("turbo:before-visit", this.willVisit);
|
1105
|
+
}
|
1106
|
+
stop() {
|
1107
|
+
this.element.removeEventListener("click", this.clickBubbled);
|
1108
|
+
document.removeEventListener("turbo:click", this.linkClicked);
|
1109
|
+
document.removeEventListener("turbo:before-visit", this.willVisit);
|
1110
|
+
}
|
1111
|
+
respondsToEventTarget(target) {
|
1112
|
+
const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
|
1113
|
+
return element && element.closest("turbo-frame, html") == this.element;
|
1114
|
+
}
|
1115
|
+
}
|
1116
|
+
|
1079
1117
|
class LinkClickObserver {
|
1080
1118
|
constructor(delegate, eventTarget) {
|
1081
1119
|
this.started = false;
|
@@ -1134,13 +1172,13 @@ function doesNotTargetIFrame(anchor) {
|
|
1134
1172
|
class FormLinkClickObserver {
|
1135
1173
|
constructor(delegate, element) {
|
1136
1174
|
this.delegate = delegate;
|
1137
|
-
this.
|
1175
|
+
this.linkInterceptor = new LinkClickObserver(this, element);
|
1138
1176
|
}
|
1139
1177
|
start() {
|
1140
|
-
this.
|
1178
|
+
this.linkInterceptor.start();
|
1141
1179
|
}
|
1142
1180
|
stop() {
|
1143
|
-
this.
|
1181
|
+
this.linkInterceptor.stop();
|
1144
1182
|
}
|
1145
1183
|
willFollowLinkToLocation(link, location, originalEvent) {
|
1146
1184
|
return this.delegate.willSubmitFormLinkToLocation(link, location, originalEvent) && link.hasAttribute("data-turbo-method");
|
@@ -1668,10 +1706,11 @@ class Visit {
|
|
1668
1706
|
this.delegate = delegate;
|
1669
1707
|
this.location = location;
|
1670
1708
|
this.restorationIdentifier = restorationIdentifier || uuid();
|
1671
|
-
const {action: action, historyChanged: historyChanged, referrer: referrer, snapshotHTML: snapshotHTML, response: response, visitCachedSnapshot: visitCachedSnapshot, willRender: willRender, updateHistory: updateHistory, shouldCacheSnapshot: shouldCacheSnapshot, acceptsStreamResponse: acceptsStreamResponse} = Object.assign(Object.assign({}, defaultOptions), options);
|
1709
|
+
const {action: action, historyChanged: historyChanged, referrer: referrer, snapshot: snapshot, snapshotHTML: snapshotHTML, response: response, visitCachedSnapshot: visitCachedSnapshot, willRender: willRender, updateHistory: updateHistory, shouldCacheSnapshot: shouldCacheSnapshot, acceptsStreamResponse: acceptsStreamResponse} = Object.assign(Object.assign({}, defaultOptions), options);
|
1672
1710
|
this.action = action;
|
1673
1711
|
this.historyChanged = historyChanged;
|
1674
1712
|
this.referrer = referrer;
|
1713
|
+
this.snapshot = snapshot;
|
1675
1714
|
this.snapshotHTML = snapshotHTML;
|
1676
1715
|
this.response = response;
|
1677
1716
|
this.isSamePage = this.delegate.locationWithActionIsSamePage(this.location, this.action);
|
@@ -1844,6 +1883,7 @@ class Visit {
|
|
1844
1883
|
this.render((async () => {
|
1845
1884
|
this.cacheSnapshot();
|
1846
1885
|
this.performScroll();
|
1886
|
+
this.changeHistory();
|
1847
1887
|
this.adapter.visitRendered(this);
|
1848
1888
|
}));
|
1849
1889
|
}
|
@@ -1956,7 +1996,7 @@ class Visit {
|
|
1956
1996
|
}
|
1957
1997
|
cacheSnapshot() {
|
1958
1998
|
if (!this.snapshotCached) {
|
1959
|
-
this.view.cacheSnapshot().then((snapshot => snapshot && this.visitCachedSnapshot(snapshot)));
|
1999
|
+
this.view.cacheSnapshot(this.snapshot).then((snapshot => snapshot && this.visitCachedSnapshot(snapshot)));
|
1960
2000
|
this.snapshotCached = true;
|
1961
2001
|
}
|
1962
2002
|
}
|
@@ -2065,11 +2105,11 @@ class BrowserAdapter {
|
|
2065
2105
|
}
|
2066
2106
|
}
|
2067
2107
|
reload(reason) {
|
2108
|
+
var _a;
|
2068
2109
|
dispatch("turbo:reload", {
|
2069
2110
|
detail: reason
|
2070
2111
|
});
|
2071
|
-
|
2072
|
-
window.location.href = this.location.toString();
|
2112
|
+
window.location.href = ((_a = this.location) === null || _a === void 0 ? void 0 : _a.toString()) || window.location.href;
|
2073
2113
|
}
|
2074
2114
|
get navigator() {
|
2075
2115
|
return this.session.navigator;
|
@@ -2104,24 +2144,24 @@ class FrameRedirector {
|
|
2104
2144
|
constructor(session, element) {
|
2105
2145
|
this.session = session;
|
2106
2146
|
this.element = element;
|
2107
|
-
this.
|
2147
|
+
this.linkInterceptor = new LinkInterceptor(this, element);
|
2108
2148
|
this.formSubmitObserver = new FormSubmitObserver(this, element);
|
2109
2149
|
}
|
2110
2150
|
start() {
|
2111
|
-
this.
|
2151
|
+
this.linkInterceptor.start();
|
2112
2152
|
this.formSubmitObserver.start();
|
2113
2153
|
}
|
2114
2154
|
stop() {
|
2115
|
-
this.
|
2155
|
+
this.linkInterceptor.stop();
|
2116
2156
|
this.formSubmitObserver.stop();
|
2117
2157
|
}
|
2118
|
-
|
2119
|
-
return this.shouldRedirect(element)
|
2158
|
+
shouldInterceptLinkClick(element, _location, _event) {
|
2159
|
+
return this.shouldRedirect(element);
|
2120
2160
|
}
|
2121
|
-
|
2161
|
+
linkClickIntercepted(element, url, event) {
|
2122
2162
|
const frame = this.findFrameElement(element);
|
2123
2163
|
if (frame) {
|
2124
|
-
frame.delegate.
|
2164
|
+
frame.delegate.linkClickIntercepted(element, url, event);
|
2125
2165
|
}
|
2126
2166
|
}
|
2127
2167
|
willSubmitForm(element, submitter) {
|
@@ -2133,17 +2173,6 @@ class FrameRedirector {
|
|
2133
2173
|
frame.delegate.formSubmitted(element, submitter);
|
2134
2174
|
}
|
2135
2175
|
}
|
2136
|
-
frameAllowsVisitingLocation(target, {href: url}, originalEvent) {
|
2137
|
-
const event = dispatch("turbo:click", {
|
2138
|
-
target: target,
|
2139
|
-
detail: {
|
2140
|
-
url: url,
|
2141
|
-
originalEvent: originalEvent
|
2142
|
-
},
|
2143
|
-
cancelable: true
|
2144
|
-
});
|
2145
|
-
return !event.defaultPrevented;
|
2146
|
-
}
|
2147
2176
|
shouldSubmit(form, submitter) {
|
2148
2177
|
var _a;
|
2149
2178
|
const action = getAction(form, submitter);
|
@@ -2268,7 +2297,6 @@ class Navigator {
|
|
2268
2297
|
}
|
2269
2298
|
}
|
2270
2299
|
startVisit(locatable, restorationIdentifier, options = {}) {
|
2271
|
-
this.lastVisit = this.currentVisit;
|
2272
2300
|
this.stop();
|
2273
2301
|
this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, Object.assign({
|
2274
2302
|
referrer: this.location
|
@@ -2355,12 +2383,10 @@ class Navigator {
|
|
2355
2383
|
this.delegate.visitCompleted(visit);
|
2356
2384
|
}
|
2357
2385
|
locationWithActionIsSamePage(location, action) {
|
2358
|
-
var _a;
|
2359
2386
|
const anchor = getAnchor(location);
|
2360
|
-
const
|
2361
|
-
const currentAnchor = getAnchor(lastLocation);
|
2387
|
+
const currentAnchor = getAnchor(this.view.lastRenderedLocation);
|
2362
2388
|
const isRestorationToTop = action === "restore" && typeof anchor === "undefined";
|
2363
|
-
return action !== "replace" && getRequestURL(location) === getRequestURL(
|
2389
|
+
return action !== "replace" && getRequestURL(location) === getRequestURL(this.view.lastRenderedLocation) && (isRestorationToTop || anchor != null && anchor !== currentAnchor);
|
2364
2390
|
}
|
2365
2391
|
visitScrolledToSamePageLocation(oldURL, newURL) {
|
2366
2392
|
this.delegate.visitScrolledToSamePageLocation(oldURL, newURL);
|
@@ -2777,10 +2803,10 @@ class PageView extends View {
|
|
2777
2803
|
clearSnapshotCache() {
|
2778
2804
|
this.snapshotCache.clear();
|
2779
2805
|
}
|
2780
|
-
async cacheSnapshot() {
|
2781
|
-
if (
|
2806
|
+
async cacheSnapshot(snapshot = this.snapshot) {
|
2807
|
+
if (snapshot.isCacheable) {
|
2782
2808
|
this.delegate.viewWillCacheSnapshot();
|
2783
|
-
const {
|
2809
|
+
const {lastRenderedLocation: location} = this;
|
2784
2810
|
await nextEventLoopTick();
|
2785
2811
|
const cachedSnapshot = snapshot.clone();
|
2786
2812
|
this.snapshotCache.put(location, cachedSnapshot);
|
@@ -2793,9 +2819,6 @@ class PageView extends View {
|
|
2793
2819
|
get snapshot() {
|
2794
2820
|
return PageSnapshot.fromElement(this.element);
|
2795
2821
|
}
|
2796
|
-
get shouldCacheSnapshot() {
|
2797
|
-
return this.snapshot.isCacheable;
|
2798
|
-
}
|
2799
2822
|
}
|
2800
2823
|
|
2801
2824
|
class Preloader {
|
@@ -3305,7 +3328,7 @@ class FrameController {
|
|
3305
3328
|
this.view = new FrameView(this, this.element);
|
3306
3329
|
this.appearanceObserver = new AppearanceObserver(this, this.element);
|
3307
3330
|
this.formLinkClickObserver = new FormLinkClickObserver(this, this.element);
|
3308
|
-
this.
|
3331
|
+
this.linkInterceptor = new LinkInterceptor(this, this.element);
|
3309
3332
|
this.restorationIdentifier = uuid();
|
3310
3333
|
this.formSubmitObserver = new FormSubmitObserver(this, this.element);
|
3311
3334
|
}
|
@@ -3318,7 +3341,7 @@ class FrameController {
|
|
3318
3341
|
this.loadSourceURL();
|
3319
3342
|
}
|
3320
3343
|
this.formLinkClickObserver.start();
|
3321
|
-
this.
|
3344
|
+
this.linkInterceptor.start();
|
3322
3345
|
this.formSubmitObserver.start();
|
3323
3346
|
}
|
3324
3347
|
}
|
@@ -3327,7 +3350,7 @@ class FrameController {
|
|
3327
3350
|
this.connected = false;
|
3328
3351
|
this.appearanceObserver.stop();
|
3329
3352
|
this.formLinkClickObserver.stop();
|
3330
|
-
this.
|
3353
|
+
this.linkInterceptor.stop();
|
3331
3354
|
this.formSubmitObserver.stop();
|
3332
3355
|
}
|
3333
3356
|
}
|
@@ -3345,6 +3368,15 @@ class FrameController {
|
|
3345
3368
|
this.loadSourceURL();
|
3346
3369
|
}
|
3347
3370
|
}
|
3371
|
+
sourceURLReloaded() {
|
3372
|
+
const {src: src} = this.element;
|
3373
|
+
this.ignoringChangesToAttribute("complete", (() => {
|
3374
|
+
this.element.removeAttribute("complete");
|
3375
|
+
}));
|
3376
|
+
this.element.src = null;
|
3377
|
+
this.element.src = src;
|
3378
|
+
return this.element.loaded;
|
3379
|
+
}
|
3348
3380
|
completeChanged() {
|
3349
3381
|
if (this.isIgnoringChangesTo("complete")) return;
|
3350
3382
|
this.loadSourceURL();
|
@@ -3400,17 +3432,17 @@ class FrameController {
|
|
3400
3432
|
this.loadSourceURL();
|
3401
3433
|
}
|
3402
3434
|
willSubmitFormLinkToLocation(link) {
|
3403
|
-
return
|
3435
|
+
return this.shouldInterceptNavigation(link);
|
3404
3436
|
}
|
3405
3437
|
submittedFormLinkToLocation(link, _location, form) {
|
3406
3438
|
const frame = this.findFrameElement(link);
|
3407
3439
|
if (frame) form.setAttribute("data-turbo-frame", frame.id);
|
3408
3440
|
}
|
3409
|
-
|
3410
|
-
return this.shouldInterceptNavigation(element)
|
3441
|
+
shouldInterceptLinkClick(element, _location, _event) {
|
3442
|
+
return this.shouldInterceptNavigation(element);
|
3411
3443
|
}
|
3412
|
-
|
3413
|
-
this.navigateFrame(element, location
|
3444
|
+
linkClickIntercepted(element, location) {
|
3445
|
+
this.navigateFrame(element, location);
|
3414
3446
|
}
|
3415
3447
|
willSubmitForm(element, submitter) {
|
3416
3448
|
return element.closest("turbo-frame") == this.element && this.shouldInterceptNavigation(element, submitter);
|
@@ -3458,7 +3490,7 @@ class FrameController {
|
|
3458
3490
|
}
|
3459
3491
|
formSubmissionSucceededWithResponse(formSubmission, response) {
|
3460
3492
|
const frame = this.findFrameElement(formSubmission.formElement, formSubmission.submitter);
|
3461
|
-
|
3493
|
+
frame.delegate.proposeVisitIfNavigatedWithAction(frame, formSubmission.formElement, formSubmission.submitter);
|
3462
3494
|
frame.delegate.loadResponse(response);
|
3463
3495
|
}
|
3464
3496
|
formSubmissionFailedWithResponse(formSubmission, fetchResponse) {
|
@@ -3508,14 +3540,14 @@ class FrameController {
|
|
3508
3540
|
}
|
3509
3541
|
navigateFrame(element, url, submitter) {
|
3510
3542
|
const frame = this.findFrameElement(element, submitter);
|
3511
|
-
this.
|
3543
|
+
this.pageSnapshot = PageSnapshot.fromElement(frame).clone();
|
3544
|
+
frame.delegate.proposeVisitIfNavigatedWithAction(frame, element, submitter);
|
3512
3545
|
this.withCurrentNavigationElement(element, (() => {
|
3513
3546
|
frame.src = url;
|
3514
3547
|
}));
|
3515
3548
|
}
|
3516
3549
|
proposeVisitIfNavigatedWithAction(frame, element, submitter) {
|
3517
3550
|
this.action = getVisitAction(submitter, element, frame);
|
3518
|
-
this.frame = frame;
|
3519
3551
|
if (isAction(this.action)) {
|
3520
3552
|
const {visitCachedSnapshot: visitCachedSnapshot} = frame.delegate;
|
3521
3553
|
frame.delegate.fetchResponseLoaded = fetchResponse => {
|
@@ -3532,7 +3564,8 @@ class FrameController {
|
|
3532
3564
|
visitCachedSnapshot: visitCachedSnapshot,
|
3533
3565
|
willRender: false,
|
3534
3566
|
updateHistory: false,
|
3535
|
-
restorationIdentifier: this.restorationIdentifier
|
3567
|
+
restorationIdentifier: this.restorationIdentifier,
|
3568
|
+
snapshot: this.pageSnapshot
|
3536
3569
|
};
|
3537
3570
|
if (this.action) options.action = this.action;
|
3538
3571
|
session.visit(frame.src, options);
|
@@ -3541,9 +3574,9 @@ class FrameController {
|
|
3541
3574
|
}
|
3542
3575
|
}
|
3543
3576
|
changeHistory() {
|
3544
|
-
if (this.action
|
3577
|
+
if (this.action) {
|
3545
3578
|
const method = getHistoryMethodForAction(this.action);
|
3546
|
-
session.history.update(method, expandURL(this.
|
3579
|
+
session.history.update(method, expandURL(this.element.src || ""), this.restorationIdentifier);
|
3547
3580
|
}
|
3548
3581
|
}
|
3549
3582
|
willHandleFrameMissingFromResponse(fetchResponse) {
|
@@ -3671,17 +3704,6 @@ class FrameController {
|
|
3671
3704
|
const root = (_a = meta === null || meta === void 0 ? void 0 : meta.content) !== null && _a !== void 0 ? _a : "/";
|
3672
3705
|
return expandURL(root);
|
3673
3706
|
}
|
3674
|
-
frameAllowsVisitingLocation(target, {href: url}, originalEvent) {
|
3675
|
-
const event = dispatch("turbo:click", {
|
3676
|
-
target: target,
|
3677
|
-
detail: {
|
3678
|
-
url: url,
|
3679
|
-
originalEvent: originalEvent
|
3680
|
-
},
|
3681
|
-
cancelable: true
|
3682
|
-
});
|
3683
|
-
return !event.defaultPrevented;
|
3684
|
-
}
|
3685
3707
|
isIgnoringChangesTo(attributeName) {
|
3686
3708
|
return this.ignoredAttributes.has(attributeName);
|
3687
3709
|
}
|