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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a154de824445dd365a26b41da3b7ecf1699e12db6931ac23b516916093c85ab
4
- data.tar.gz: fbb86806c7dfc95d8703bb447bcfcdc9c3f3802442962b619f2d976a8f68fc57
3
+ metadata.gz: 6d91b4f1416fb84779360c106d108b2ea6eae46788a9abec0316595ac7d050c5
4
+ data.tar.gz: 8a63eef6bae625fcc8260bf343f0e8184b46f84feb56722688ca3d1d5e6825bc
5
5
  SHA512:
6
- metadata.gz: fa8e5b959bf8d751bef2a6e12abbc98165fea71db42a49f0302d3e8319d669e3476322017889cb26a3262588b9fb14d7a05ae313ac9bc16d29eb3547275a412a
7
- data.tar.gz: 1abca2f9add27efadb27e4d52aaa1185bb652309a31353ad909b74369af766a592279181a7a8aa970b9d6c720d92bbf54e3e19a5b42bec419de83e97be249e71
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
- const {src: src} = this;
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.linkClickObserver = new LinkClickObserver(this, element);
1175
+ this.linkInterceptor = new LinkClickObserver(this, element);
1138
1176
  }
1139
1177
  start() {
1140
- this.linkClickObserver.start();
1178
+ this.linkInterceptor.start();
1141
1179
  }
1142
1180
  stop() {
1143
- this.linkClickObserver.stop();
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
- if (!this.location) return;
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.linkClickObserver = new LinkClickObserver(this, element);
2147
+ this.linkInterceptor = new LinkInterceptor(this, element);
2108
2148
  this.formSubmitObserver = new FormSubmitObserver(this, element);
2109
2149
  }
2110
2150
  start() {
2111
- this.linkClickObserver.start();
2151
+ this.linkInterceptor.start();
2112
2152
  this.formSubmitObserver.start();
2113
2153
  }
2114
2154
  stop() {
2115
- this.linkClickObserver.stop();
2155
+ this.linkInterceptor.stop();
2116
2156
  this.formSubmitObserver.stop();
2117
2157
  }
2118
- willFollowLinkToLocation(element, location, event) {
2119
- return this.shouldRedirect(element) && this.frameAllowsVisitingLocation(element, location, event);
2158
+ shouldInterceptLinkClick(element, _location, _event) {
2159
+ return this.shouldRedirect(element);
2120
2160
  }
2121
- followedLinkToLocation(element, url) {
2161
+ linkClickIntercepted(element, url, event) {
2122
2162
  const frame = this.findFrameElement(element);
2123
2163
  if (frame) {
2124
- frame.delegate.followedLinkToLocation(element, url);
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 lastLocation = ((_a = this.lastVisit) === null || _a === void 0 ? void 0 : _a.location) || this.view.lastRenderedLocation;
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(lastLocation) && (isRestorationToTop || anchor != null && anchor !== currentAnchor);
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 (this.shouldCacheSnapshot) {
2806
+ async cacheSnapshot(snapshot = this.snapshot) {
2807
+ if (snapshot.isCacheable) {
2782
2808
  this.delegate.viewWillCacheSnapshot();
2783
- const {snapshot: snapshot, lastRenderedLocation: location} = this;
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.linkClickObserver = new LinkClickObserver(this, this.element);
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.linkClickObserver.start();
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.linkClickObserver.stop();
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 link.closest("turbo-frame") == this.element && this.shouldInterceptNavigation(link);
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
- willFollowLinkToLocation(element, location, event) {
3410
- return this.shouldInterceptNavigation(element) && this.frameAllowsVisitingLocation(element, location, event);
3441
+ shouldInterceptLinkClick(element, _location, _event) {
3442
+ return this.shouldInterceptNavigation(element);
3411
3443
  }
3412
- followedLinkToLocation(element, location) {
3413
- this.navigateFrame(element, location.href);
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
- this.proposeVisitIfNavigatedWithAction(frame, formSubmission.formElement, formSubmission.submitter);
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.proposeVisitIfNavigatedWithAction(frame, element, submitter);
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 && this.frame) {
3577
+ if (this.action) {
3545
3578
  const method = getHistoryMethodForAction(this.action);
3546
- session.history.update(method, expandURL(this.frame.src || ""), this.restorationIdentifier);
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
  }