turbo-rails 1.3.0 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|