@hotwired/turbo 7.0.0-rc.2 → 7.0.0
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.
- package/dist/turbo.es2017-esm.js +71 -32
- package/dist/turbo.es2017-esm.js.map +1 -1
- package/dist/turbo.es2017-umd.js +71 -32
- package/dist/turbo.es2017-umd.js.map +1 -1
- package/dist/turbo.es5-umd.js +167 -422
- package/dist/turbo.es5-umd.js.map +1 -1
- package/dist/types/core/native/browser_adapter.d.ts +6 -3
- package/dist/types/http/fetch_request.d.ts +3 -1
- package/dist/types/tests/functional/form_submission_tests.d.ts +8 -1
- package/dist/types/tests/functional/frame_navigation_tests.d.ts +1 -0
- package/dist/types/tests/functional/frame_tests.d.ts +8 -1
- package/dist/types/tests/functional/rendering_tests.d.ts +1 -0
- package/dist/types/tests/functional/visit_tests.d.ts +1 -0
- package/package.json +2 -2
package/dist/turbo.es2017-esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Turbo 7.0.0
|
|
2
|
+
Turbo 7.0.0
|
|
3
3
|
Copyright © 2021 Basecamp, LLC
|
|
4
4
|
*/
|
|
5
5
|
(function () {
|
|
@@ -35,6 +35,8 @@ function clickCaptured(event) {
|
|
|
35
35
|
(function () {
|
|
36
36
|
if ("SubmitEvent" in window)
|
|
37
37
|
return;
|
|
38
|
+
if ("submitter" in Event.prototype)
|
|
39
|
+
return;
|
|
38
40
|
addEventListener("click", clickCaptured, true);
|
|
39
41
|
Object.defineProperty(Event.prototype, "submitter", {
|
|
40
42
|
get() {
|
|
@@ -222,11 +224,11 @@ class FetchResponse {
|
|
|
222
224
|
return this.header("Content-Type");
|
|
223
225
|
}
|
|
224
226
|
get responseText() {
|
|
225
|
-
return this.response.text();
|
|
227
|
+
return this.response.clone().text();
|
|
226
228
|
}
|
|
227
229
|
get responseHTML() {
|
|
228
230
|
if (this.isHTML) {
|
|
229
|
-
return this.response.text();
|
|
231
|
+
return this.response.clone().text();
|
|
230
232
|
}
|
|
231
233
|
else {
|
|
232
234
|
return Promise.resolve(undefined);
|
|
@@ -239,7 +241,12 @@ class FetchResponse {
|
|
|
239
241
|
|
|
240
242
|
function dispatch(eventName, { target, cancelable, detail } = {}) {
|
|
241
243
|
const event = new CustomEvent(eventName, { cancelable, bubbles: true, detail });
|
|
242
|
-
|
|
244
|
+
if (target && target.isConnected) {
|
|
245
|
+
target.dispatchEvent(event);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
document.documentElement.dispatchEvent(event);
|
|
249
|
+
}
|
|
243
250
|
return event;
|
|
244
251
|
}
|
|
245
252
|
function nextAnimationFrame() {
|
|
@@ -301,7 +308,7 @@ function fetchMethodFromString(method) {
|
|
|
301
308
|
}
|
|
302
309
|
}
|
|
303
310
|
class FetchRequest {
|
|
304
|
-
constructor(delegate, method, location, body = new URLSearchParams) {
|
|
311
|
+
constructor(delegate, method, location, body = new URLSearchParams, target = null) {
|
|
305
312
|
this.abortController = new AbortController;
|
|
306
313
|
this.resolveRequestPromise = (value) => { };
|
|
307
314
|
this.delegate = delegate;
|
|
@@ -314,6 +321,7 @@ class FetchRequest {
|
|
|
314
321
|
this.body = body;
|
|
315
322
|
this.url = location;
|
|
316
323
|
}
|
|
324
|
+
this.target = target;
|
|
317
325
|
}
|
|
318
326
|
get location() {
|
|
319
327
|
return this.url;
|
|
@@ -349,7 +357,7 @@ class FetchRequest {
|
|
|
349
357
|
}
|
|
350
358
|
async receive(response) {
|
|
351
359
|
const fetchResponse = new FetchResponse(response);
|
|
352
|
-
const event = dispatch("turbo:before-fetch-response", { cancelable: true, detail: { fetchResponse } });
|
|
360
|
+
const event = dispatch("turbo:before-fetch-response", { cancelable: true, detail: { fetchResponse }, target: this.target });
|
|
353
361
|
if (event.defaultPrevented) {
|
|
354
362
|
this.delegate.requestPreventedHandlingResponse(this, fetchResponse);
|
|
355
363
|
}
|
|
@@ -386,7 +394,15 @@ class FetchRequest {
|
|
|
386
394
|
}
|
|
387
395
|
async allowRequestToBeIntercepted(fetchOptions) {
|
|
388
396
|
const requestInterception = new Promise(resolve => this.resolveRequestPromise = resolve);
|
|
389
|
-
const event = dispatch("turbo:before-fetch-request", {
|
|
397
|
+
const event = dispatch("turbo:before-fetch-request", {
|
|
398
|
+
cancelable: true,
|
|
399
|
+
detail: {
|
|
400
|
+
fetchOptions,
|
|
401
|
+
url: this.url.href,
|
|
402
|
+
resume: this.resolveRequestPromise
|
|
403
|
+
},
|
|
404
|
+
target: this.target
|
|
405
|
+
});
|
|
390
406
|
if (event.defaultPrevented)
|
|
391
407
|
await requestInterception;
|
|
392
408
|
}
|
|
@@ -499,7 +515,7 @@ class FormSubmission {
|
|
|
499
515
|
this.formElement = formElement;
|
|
500
516
|
this.submitter = submitter;
|
|
501
517
|
this.formData = buildFormData(formElement, submitter);
|
|
502
|
-
this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body);
|
|
518
|
+
this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body, this.formElement);
|
|
503
519
|
this.mustRedirect = mustRedirect;
|
|
504
520
|
}
|
|
505
521
|
get method() {
|
|
@@ -1112,6 +1128,7 @@ class HeadSnapshot extends Snapshot {
|
|
|
1112
1128
|
super(...arguments);
|
|
1113
1129
|
this.detailsByOuterHTML = this.children
|
|
1114
1130
|
.filter((element) => !elementIsNoscript(element))
|
|
1131
|
+
.map((element) => elementWithoutNonce(element))
|
|
1115
1132
|
.reduce((result, element) => {
|
|
1116
1133
|
const { outerHTML } = element;
|
|
1117
1134
|
const details = outerHTML in result
|
|
@@ -1196,6 +1213,12 @@ function elementIsMetaElementWithName(element, name) {
|
|
|
1196
1213
|
const tagName = element.tagName.toLowerCase();
|
|
1197
1214
|
return tagName == "meta" && element.getAttribute("name") == name;
|
|
1198
1215
|
}
|
|
1216
|
+
function elementWithoutNonce(element) {
|
|
1217
|
+
if (element.hasAttribute("nonce")) {
|
|
1218
|
+
element.setAttribute("nonce", "");
|
|
1219
|
+
}
|
|
1220
|
+
return element;
|
|
1221
|
+
}
|
|
1199
1222
|
|
|
1200
1223
|
class PageSnapshot extends Snapshot {
|
|
1201
1224
|
constructor(element, headSnapshot) {
|
|
@@ -1581,7 +1604,7 @@ class BrowserAdapter {
|
|
|
1581
1604
|
visitRequestStarted(visit) {
|
|
1582
1605
|
this.progressBar.setValue(0);
|
|
1583
1606
|
if (visit.hasCachedSnapshot() || visit.action != "restore") {
|
|
1584
|
-
this.
|
|
1607
|
+
this.showVisitProgressBarAfterDelay();
|
|
1585
1608
|
}
|
|
1586
1609
|
else {
|
|
1587
1610
|
this.showProgressBar();
|
|
@@ -1602,7 +1625,7 @@ class BrowserAdapter {
|
|
|
1602
1625
|
}
|
|
1603
1626
|
visitRequestFinished(visit) {
|
|
1604
1627
|
this.progressBar.setValue(1);
|
|
1605
|
-
this.
|
|
1628
|
+
this.hideVisitProgressBar();
|
|
1606
1629
|
}
|
|
1607
1630
|
visitCompleted(visit) {
|
|
1608
1631
|
}
|
|
@@ -1615,20 +1638,32 @@ class BrowserAdapter {
|
|
|
1615
1638
|
}
|
|
1616
1639
|
formSubmissionStarted(formSubmission) {
|
|
1617
1640
|
this.progressBar.setValue(0);
|
|
1618
|
-
this.
|
|
1641
|
+
this.showFormProgressBarAfterDelay();
|
|
1619
1642
|
}
|
|
1620
1643
|
formSubmissionFinished(formSubmission) {
|
|
1621
1644
|
this.progressBar.setValue(1);
|
|
1622
|
-
this.
|
|
1645
|
+
this.hideFormProgressBar();
|
|
1646
|
+
}
|
|
1647
|
+
showVisitProgressBarAfterDelay() {
|
|
1648
|
+
this.visitProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);
|
|
1649
|
+
}
|
|
1650
|
+
hideVisitProgressBar() {
|
|
1651
|
+
this.progressBar.hide();
|
|
1652
|
+
if (this.visitProgressBarTimeout != null) {
|
|
1653
|
+
window.clearTimeout(this.visitProgressBarTimeout);
|
|
1654
|
+
delete this.visitProgressBarTimeout;
|
|
1655
|
+
}
|
|
1623
1656
|
}
|
|
1624
|
-
|
|
1625
|
-
|
|
1657
|
+
showFormProgressBarAfterDelay() {
|
|
1658
|
+
if (this.formProgressBarTimeout == null) {
|
|
1659
|
+
this.formProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);
|
|
1660
|
+
}
|
|
1626
1661
|
}
|
|
1627
|
-
|
|
1662
|
+
hideFormProgressBar() {
|
|
1628
1663
|
this.progressBar.hide();
|
|
1629
|
-
if (this.
|
|
1630
|
-
window.clearTimeout(this.
|
|
1631
|
-
delete this.
|
|
1664
|
+
if (this.formProgressBarTimeout != null) {
|
|
1665
|
+
window.clearTimeout(this.formProgressBarTimeout);
|
|
1666
|
+
delete this.formProgressBarTimeout;
|
|
1632
1667
|
}
|
|
1633
1668
|
}
|
|
1634
1669
|
reload() {
|
|
@@ -1719,6 +1754,7 @@ class FrameRedirector {
|
|
|
1719
1754
|
linkClickIntercepted(element, url) {
|
|
1720
1755
|
const frame = this.findFrameElement(element);
|
|
1721
1756
|
if (frame) {
|
|
1757
|
+
frame.setAttribute("reloadable", "");
|
|
1722
1758
|
frame.src = url;
|
|
1723
1759
|
}
|
|
1724
1760
|
}
|
|
@@ -1726,17 +1762,18 @@ class FrameRedirector {
|
|
|
1726
1762
|
return this.shouldRedirect(element, submitter);
|
|
1727
1763
|
}
|
|
1728
1764
|
formSubmissionIntercepted(element, submitter) {
|
|
1729
|
-
const frame = this.findFrameElement(element);
|
|
1765
|
+
const frame = this.findFrameElement(element, submitter);
|
|
1730
1766
|
if (frame) {
|
|
1767
|
+
frame.removeAttribute("reloadable");
|
|
1731
1768
|
frame.delegate.formSubmissionIntercepted(element, submitter);
|
|
1732
1769
|
}
|
|
1733
1770
|
}
|
|
1734
1771
|
shouldRedirect(element, submitter) {
|
|
1735
|
-
const frame = this.findFrameElement(element);
|
|
1772
|
+
const frame = this.findFrameElement(element, submitter);
|
|
1736
1773
|
return frame ? frame != element.closest("turbo-frame") : false;
|
|
1737
1774
|
}
|
|
1738
|
-
findFrameElement(element) {
|
|
1739
|
-
const id = element.getAttribute("data-turbo-frame");
|
|
1775
|
+
findFrameElement(element, submitter) {
|
|
1776
|
+
const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("data-turbo-frame")) || element.getAttribute("data-turbo-frame");
|
|
1740
1777
|
if (id && id != "_top") {
|
|
1741
1778
|
const frame = this.element.querySelector(`#${id}:not([disabled])`);
|
|
1742
1779
|
if (frame instanceof FrameElement) {
|
|
@@ -2448,12 +2485,14 @@ class Session {
|
|
|
2448
2485
|
this.convertLinkWithMethodClickToFormSubmission(link) || this.visit(location.href, { action });
|
|
2449
2486
|
}
|
|
2450
2487
|
convertLinkWithMethodClickToFormSubmission(link) {
|
|
2488
|
+
var _a;
|
|
2451
2489
|
const linkMethod = link.getAttribute("data-turbo-method");
|
|
2452
2490
|
if (linkMethod) {
|
|
2453
2491
|
const form = document.createElement("form");
|
|
2454
2492
|
form.method = linkMethod;
|
|
2455
2493
|
form.action = link.getAttribute("href") || "undefined";
|
|
2456
|
-
|
|
2494
|
+
form.hidden = true;
|
|
2495
|
+
(_a = link.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(form, link);
|
|
2457
2496
|
return dispatch("submit", { cancelable: true, target: form });
|
|
2458
2497
|
}
|
|
2459
2498
|
else {
|
|
@@ -2762,7 +2801,7 @@ class FrameController {
|
|
|
2762
2801
|
this.reloadable = false;
|
|
2763
2802
|
this.formSubmission = new FormSubmission(this, element, submitter);
|
|
2764
2803
|
if (this.formSubmission.fetchRequest.isIdempotent) {
|
|
2765
|
-
this.navigateFrame(element, this.formSubmission.fetchRequest.url.href);
|
|
2804
|
+
this.navigateFrame(element, this.formSubmission.fetchRequest.url.href, submitter);
|
|
2766
2805
|
}
|
|
2767
2806
|
else {
|
|
2768
2807
|
const { fetchRequest } = this.formSubmission;
|
|
@@ -2799,7 +2838,7 @@ class FrameController {
|
|
|
2799
2838
|
frame.setAttribute("busy", "");
|
|
2800
2839
|
}
|
|
2801
2840
|
formSubmissionSucceededWithResponse(formSubmission, response) {
|
|
2802
|
-
const frame = this.findFrameElement(formSubmission.formElement);
|
|
2841
|
+
const frame = this.findFrameElement(formSubmission.formElement, formSubmission.submitter);
|
|
2803
2842
|
frame.delegate.loadResponse(response);
|
|
2804
2843
|
}
|
|
2805
2844
|
formSubmissionFailedWithResponse(formSubmission, fetchResponse) {
|
|
@@ -2820,7 +2859,7 @@ class FrameController {
|
|
|
2820
2859
|
viewInvalidated() {
|
|
2821
2860
|
}
|
|
2822
2861
|
async visit(url) {
|
|
2823
|
-
const request = new FetchRequest(this, FetchMethod.get, expandURL(url));
|
|
2862
|
+
const request = new FetchRequest(this, FetchMethod.get, expandURL(url), undefined, this.element);
|
|
2824
2863
|
return new Promise(resolve => {
|
|
2825
2864
|
this.resolveVisitPromise = () => {
|
|
2826
2865
|
this.resolveVisitPromise = () => { };
|
|
@@ -2829,13 +2868,14 @@ class FrameController {
|
|
|
2829
2868
|
request.perform();
|
|
2830
2869
|
});
|
|
2831
2870
|
}
|
|
2832
|
-
navigateFrame(element, url) {
|
|
2833
|
-
const frame = this.findFrameElement(element);
|
|
2871
|
+
navigateFrame(element, url, submitter) {
|
|
2872
|
+
const frame = this.findFrameElement(element, submitter);
|
|
2873
|
+
frame.setAttribute("reloadable", "");
|
|
2834
2874
|
frame.src = url;
|
|
2835
2875
|
}
|
|
2836
|
-
findFrameElement(element) {
|
|
2876
|
+
findFrameElement(element, submitter) {
|
|
2837
2877
|
var _a;
|
|
2838
|
-
const id = element.getAttribute("data-turbo-frame") || this.element.getAttribute("target");
|
|
2878
|
+
const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("data-turbo-frame")) || element.getAttribute("data-turbo-frame") || this.element.getAttribute("target");
|
|
2839
2879
|
return (_a = getFrameElementById(id)) !== null && _a !== void 0 ? _a : this.element;
|
|
2840
2880
|
}
|
|
2841
2881
|
async extractForeignFrameElement(container) {
|
|
@@ -2857,7 +2897,7 @@ class FrameController {
|
|
|
2857
2897
|
return new FrameElement();
|
|
2858
2898
|
}
|
|
2859
2899
|
shouldInterceptNavigation(element, submitter) {
|
|
2860
|
-
const id = element.getAttribute("data-turbo-frame") || this.element.getAttribute("target");
|
|
2900
|
+
const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("data-turbo-frame")) || element.getAttribute("data-turbo-frame") || this.element.getAttribute("target");
|
|
2861
2901
|
if (!this.enabled || id == "_top") {
|
|
2862
2902
|
return false;
|
|
2863
2903
|
}
|
|
@@ -3105,4 +3145,3 @@ window.Turbo = Turbo;
|
|
|
3105
3145
|
start();
|
|
3106
3146
|
|
|
3107
3147
|
export { PageRenderer, PageSnapshot, clearCache, connectStreamSource, disconnectStreamSource, navigator, registerAdapter, renderStreamMessage, session, setProgressBarDelay, start, visit };
|
|
3108
|
-
//# sourceMappingURL=turbo.es2017-esm.js.map
|