@hotwired/turbo 7.2.4 → 7.3.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 +238 -128
- package/dist/turbo.es2017-umd.js +238 -128
- package/dist/types/core/bardo.d.ts +1 -1
- package/dist/types/core/drive/form_submission.d.ts +10 -6
- package/dist/types/core/drive/head_snapshot.d.ts +3 -3
- package/dist/types/core/drive/history.d.ts +3 -3
- package/dist/types/core/drive/navigator.d.ts +2 -2
- package/dist/types/core/drive/page_renderer.d.ts +4 -2
- package/dist/types/core/drive/page_view.d.ts +2 -2
- package/dist/types/core/drive/visit.d.ts +5 -5
- package/dist/types/core/errors.d.ts +2 -0
- package/dist/types/core/frames/frame_controller.d.ts +11 -9
- package/dist/types/core/frames/frame_view.d.ts +2 -2
- package/dist/types/core/index.d.ts +5 -4
- package/dist/types/core/native/browser_adapter.d.ts +1 -1
- package/dist/types/core/renderer.d.ts +2 -2
- package/dist/types/core/session.d.ts +12 -12
- package/dist/types/core/snapshot.d.ts +1 -1
- package/dist/types/core/streams/stream_actions.d.ts +2 -2
- package/dist/types/core/types.d.ts +3 -4
- package/dist/types/core/url.d.ts +1 -1
- package/dist/types/core/view.d.ts +1 -1
- package/dist/types/elements/frame_element.d.ts +1 -1
- package/dist/types/elements/stream_element.d.ts +2 -2
- package/dist/types/http/fetch_request.d.ts +8 -8
- package/dist/types/http/index.d.ts +1 -1
- package/dist/types/observers/appearance_observer.d.ts +6 -6
- package/dist/types/observers/cache_observer.d.ts +5 -1
- package/dist/types/observers/form_link_click_observer.d.ts +1 -1
- package/dist/types/observers/link_click_observer.d.ts +1 -1
- package/dist/types/polyfills/custom-elements-native-shim.d.ts +1 -0
- package/dist/types/tests/functional/frame_tests.d.ts +7 -0
- package/dist/types/tests/helpers/dom_test_case.d.ts +1 -2
- package/dist/types/tests/helpers/page.d.ts +15 -8
- package/dist/types/tests/unit/deprecated_adapter_support_tests.d.ts +1 -0
- package/dist/types/tests/unit/export_tests.d.ts +1 -5
- package/dist/types/tests/unit/stream_element_tests.d.ts +0 -10
- package/dist/types/util.d.ts +3 -1
- package/package.json +17 -11
- package/dist/types/tests/helpers/intern_test_case.d.ts +0 -20
- package/dist/types/tests/unit/deprecated_adapter_support_test.d.ts +0 -24
- package/dist/types/tests/unit/index.d.ts +0 -3
- /package/dist/types/tests/{functional → integration}/ujs_tests.d.ts +0 -0
package/dist/turbo.es2017-umd.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Turbo 7.
|
|
3
|
-
Copyright ©
|
|
2
|
+
Turbo 7.3.0
|
|
3
|
+
Copyright © 2023 37signals LLC
|
|
4
4
|
*/
|
|
5
5
|
(function (global, factory) {
|
|
6
6
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
@@ -93,16 +93,13 @@ Copyright © 2022 37signals LLC
|
|
|
93
93
|
(function () {
|
|
94
94
|
if ("submitter" in Event.prototype)
|
|
95
95
|
return;
|
|
96
|
-
let prototype;
|
|
96
|
+
let prototype = window.Event.prototype;
|
|
97
97
|
if ("SubmitEvent" in window && /Apple Computer/.test(navigator.vendor)) {
|
|
98
98
|
prototype = window.SubmitEvent.prototype;
|
|
99
99
|
}
|
|
100
100
|
else if ("SubmitEvent" in window) {
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
|
-
else {
|
|
104
|
-
prototype = window.Event.prototype;
|
|
105
|
-
}
|
|
106
103
|
addEventListener("click", clickCaptured, true);
|
|
107
104
|
Object.defineProperty(prototype, "submitter", {
|
|
108
105
|
get() {
|
|
@@ -119,14 +116,14 @@ Copyright © 2022 37signals LLC
|
|
|
119
116
|
FrameLoadingStyle["lazy"] = "lazy";
|
|
120
117
|
})(exports.FrameLoadingStyle || (exports.FrameLoadingStyle = {}));
|
|
121
118
|
class FrameElement extends HTMLElement {
|
|
119
|
+
static get observedAttributes() {
|
|
120
|
+
return ["disabled", "complete", "loading", "src"];
|
|
121
|
+
}
|
|
122
122
|
constructor() {
|
|
123
123
|
super();
|
|
124
124
|
this.loaded = Promise.resolve();
|
|
125
125
|
this.delegate = new FrameElement.delegateConstructor(this);
|
|
126
126
|
}
|
|
127
|
-
static get observedAttributes() {
|
|
128
|
-
return ["disabled", "complete", "loading", "src"];
|
|
129
|
-
}
|
|
130
127
|
connectedCallback() {
|
|
131
128
|
this.delegate.connect();
|
|
132
129
|
}
|
|
@@ -313,10 +310,6 @@ Copyright © 2022 37signals LLC
|
|
|
313
310
|
}
|
|
314
311
|
}
|
|
315
312
|
|
|
316
|
-
function isAction(action) {
|
|
317
|
-
return action == "advance" || action == "replace" || action == "restore";
|
|
318
|
-
}
|
|
319
|
-
|
|
320
313
|
function activateScriptElement(element) {
|
|
321
314
|
if (element.getAttribute("data-turbo-eval") == "false") {
|
|
322
315
|
return element;
|
|
@@ -347,6 +340,7 @@ Copyright © 2022 37signals LLC
|
|
|
347
340
|
const event = new CustomEvent(eventName, {
|
|
348
341
|
cancelable,
|
|
349
342
|
bubbles: true,
|
|
343
|
+
composed: true,
|
|
350
344
|
detail,
|
|
351
345
|
});
|
|
352
346
|
if (target && target.isConnected) {
|
|
@@ -446,6 +440,9 @@ Copyright © 2022 37signals LLC
|
|
|
446
440
|
return history.pushState;
|
|
447
441
|
}
|
|
448
442
|
}
|
|
443
|
+
function isAction(action) {
|
|
444
|
+
return action == "advance" || action == "replace" || action == "restore";
|
|
445
|
+
}
|
|
449
446
|
function getVisitAction(...elements) {
|
|
450
447
|
const action = getAttribute("data-turbo-action", ...elements);
|
|
451
448
|
return isAction(action) ? action : null;
|
|
@@ -467,6 +464,13 @@ Copyright © 2022 37signals LLC
|
|
|
467
464
|
element.setAttribute("content", content);
|
|
468
465
|
return element;
|
|
469
466
|
}
|
|
467
|
+
function findClosestRecursively(element, selector) {
|
|
468
|
+
var _a;
|
|
469
|
+
if (element instanceof Element) {
|
|
470
|
+
return (element.closest(selector) ||
|
|
471
|
+
findClosestRecursively(element.assignedSlot || ((_a = element.getRootNode()) === null || _a === void 0 ? void 0 : _a.host), selector));
|
|
472
|
+
}
|
|
473
|
+
}
|
|
470
474
|
|
|
471
475
|
var FetchMethod;
|
|
472
476
|
(function (FetchMethod) {
|
|
@@ -514,9 +518,8 @@ Copyright © 2022 37signals LLC
|
|
|
514
518
|
this.abortController.abort();
|
|
515
519
|
}
|
|
516
520
|
async perform() {
|
|
517
|
-
var _a, _b;
|
|
518
521
|
const { fetchOptions } = this;
|
|
519
|
-
|
|
522
|
+
this.delegate.prepareRequest(this);
|
|
520
523
|
await this.allowRequestToBeIntercepted(fetchOptions);
|
|
521
524
|
try {
|
|
522
525
|
this.delegate.requestStarted(this);
|
|
@@ -560,7 +563,7 @@ Copyright © 2022 37signals LLC
|
|
|
560
563
|
credentials: "same-origin",
|
|
561
564
|
headers: this.headers,
|
|
562
565
|
redirect: "follow",
|
|
563
|
-
body: this.
|
|
566
|
+
body: this.isSafe ? null : this.body,
|
|
564
567
|
signal: this.abortSignal,
|
|
565
568
|
referrer: (_a = this.delegate.referrer) === null || _a === void 0 ? void 0 : _a.href,
|
|
566
569
|
};
|
|
@@ -570,8 +573,8 @@ Copyright © 2022 37signals LLC
|
|
|
570
573
|
Accept: "text/html, application/xhtml+xml",
|
|
571
574
|
};
|
|
572
575
|
}
|
|
573
|
-
get
|
|
574
|
-
return this.method
|
|
576
|
+
get isSafe() {
|
|
577
|
+
return this.method === FetchMethod.get;
|
|
575
578
|
}
|
|
576
579
|
get abortSignal() {
|
|
577
580
|
return this.abortController.signal;
|
|
@@ -631,9 +634,6 @@ Copyright © 2022 37signals LLC
|
|
|
631
634
|
}
|
|
632
635
|
|
|
633
636
|
class StreamMessage {
|
|
634
|
-
constructor(fragment) {
|
|
635
|
-
this.fragment = importStreamElements(fragment);
|
|
636
|
-
}
|
|
637
637
|
static wrap(message) {
|
|
638
638
|
if (typeof message == "string") {
|
|
639
639
|
return new this(createDocumentFragment(message));
|
|
@@ -642,6 +642,9 @@ Copyright © 2022 37signals LLC
|
|
|
642
642
|
return message;
|
|
643
643
|
}
|
|
644
644
|
}
|
|
645
|
+
constructor(fragment) {
|
|
646
|
+
this.fragment = importStreamElements(fragment);
|
|
647
|
+
}
|
|
645
648
|
}
|
|
646
649
|
StreamMessage.contentType = "text/vnd.turbo-stream.html";
|
|
647
650
|
function importStreamElements(fragment) {
|
|
@@ -681,6 +684,9 @@ Copyright © 2022 37signals LLC
|
|
|
681
684
|
}
|
|
682
685
|
}
|
|
683
686
|
class FormSubmission {
|
|
687
|
+
static confirmMethod(message, _element, _submitter) {
|
|
688
|
+
return Promise.resolve(confirm(message));
|
|
689
|
+
}
|
|
684
690
|
constructor(delegate, formElement, submitter, mustRedirect = false) {
|
|
685
691
|
this.state = FormSubmissionState.initialized;
|
|
686
692
|
this.delegate = delegate;
|
|
@@ -694,9 +700,6 @@ Copyright © 2022 37signals LLC
|
|
|
694
700
|
this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body, this.formElement);
|
|
695
701
|
this.mustRedirect = mustRedirect;
|
|
696
702
|
}
|
|
697
|
-
static confirmMethod(message, _element, _submitter) {
|
|
698
|
-
return Promise.resolve(confirm(message));
|
|
699
|
-
}
|
|
700
703
|
get method() {
|
|
701
704
|
var _a;
|
|
702
705
|
const method = ((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("formmethod")) || this.formElement.getAttribute("method") || "";
|
|
@@ -724,8 +727,8 @@ Copyright © 2022 37signals LLC
|
|
|
724
727
|
var _a;
|
|
725
728
|
return formEnctypeFromString(((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("formenctype")) || this.formElement.enctype);
|
|
726
729
|
}
|
|
727
|
-
get
|
|
728
|
-
return this.fetchRequest.
|
|
730
|
+
get isSafe() {
|
|
731
|
+
return this.fetchRequest.isSafe;
|
|
729
732
|
}
|
|
730
733
|
get stringFormData() {
|
|
731
734
|
return [...this.formData].reduce((entries, [name, value]) => {
|
|
@@ -754,11 +757,11 @@ Copyright © 2022 37signals LLC
|
|
|
754
757
|
return true;
|
|
755
758
|
}
|
|
756
759
|
}
|
|
757
|
-
|
|
758
|
-
if (!request.
|
|
760
|
+
prepareRequest(request) {
|
|
761
|
+
if (!request.isSafe) {
|
|
759
762
|
const token = getCookieValue(getMetaContent("csrf-param")) || getMetaContent("csrf-token");
|
|
760
763
|
if (token) {
|
|
761
|
-
headers["X-CSRF-Token"] = token;
|
|
764
|
+
request.headers["X-CSRF-Token"] = token;
|
|
762
765
|
}
|
|
763
766
|
}
|
|
764
767
|
if (this.requestAcceptsTurboStreamResponse(request)) {
|
|
@@ -769,6 +772,7 @@ Copyright © 2022 37signals LLC
|
|
|
769
772
|
var _a;
|
|
770
773
|
this.state = FormSubmissionState.waiting;
|
|
771
774
|
(_a = this.submitter) === null || _a === void 0 ? void 0 : _a.setAttribute("disabled", "");
|
|
775
|
+
this.setSubmitsWith();
|
|
772
776
|
dispatch("turbo:submit-start", {
|
|
773
777
|
target: this.formElement,
|
|
774
778
|
detail: { formSubmission: this },
|
|
@@ -804,17 +808,46 @@ Copyright © 2022 37signals LLC
|
|
|
804
808
|
var _a;
|
|
805
809
|
this.state = FormSubmissionState.stopped;
|
|
806
810
|
(_a = this.submitter) === null || _a === void 0 ? void 0 : _a.removeAttribute("disabled");
|
|
811
|
+
this.resetSubmitterText();
|
|
807
812
|
dispatch("turbo:submit-end", {
|
|
808
813
|
target: this.formElement,
|
|
809
814
|
detail: Object.assign({ formSubmission: this }, this.result),
|
|
810
815
|
});
|
|
811
816
|
this.delegate.formSubmissionFinished(this);
|
|
812
817
|
}
|
|
818
|
+
setSubmitsWith() {
|
|
819
|
+
if (!this.submitter || !this.submitsWith)
|
|
820
|
+
return;
|
|
821
|
+
if (this.submitter.matches("button")) {
|
|
822
|
+
this.originalSubmitText = this.submitter.innerHTML;
|
|
823
|
+
this.submitter.innerHTML = this.submitsWith;
|
|
824
|
+
}
|
|
825
|
+
else if (this.submitter.matches("input")) {
|
|
826
|
+
const input = this.submitter;
|
|
827
|
+
this.originalSubmitText = input.value;
|
|
828
|
+
input.value = this.submitsWith;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
resetSubmitterText() {
|
|
832
|
+
if (!this.submitter || !this.originalSubmitText)
|
|
833
|
+
return;
|
|
834
|
+
if (this.submitter.matches("button")) {
|
|
835
|
+
this.submitter.innerHTML = this.originalSubmitText;
|
|
836
|
+
}
|
|
837
|
+
else if (this.submitter.matches("input")) {
|
|
838
|
+
const input = this.submitter;
|
|
839
|
+
input.value = this.originalSubmitText;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
813
842
|
requestMustRedirect(request) {
|
|
814
|
-
return !request.
|
|
843
|
+
return !request.isSafe && this.mustRedirect;
|
|
815
844
|
}
|
|
816
845
|
requestAcceptsTurboStreamResponse(request) {
|
|
817
|
-
return !request.
|
|
846
|
+
return !request.isSafe || hasAttribute("data-turbo-stream", this.submitter, this.formElement);
|
|
847
|
+
}
|
|
848
|
+
get submitsWith() {
|
|
849
|
+
var _a;
|
|
850
|
+
return (_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("data-turbo-submits-with");
|
|
818
851
|
}
|
|
819
852
|
}
|
|
820
853
|
function buildFormData(formElement, submitter) {
|
|
@@ -946,12 +979,17 @@ Copyright © 2022 37signals LLC
|
|
|
946
979
|
return method != "dialog";
|
|
947
980
|
}
|
|
948
981
|
function submissionDoesNotTargetIFrame(form, submitter) {
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
982
|
+
if ((submitter === null || submitter === void 0 ? void 0 : submitter.hasAttribute("formtarget")) || form.hasAttribute("target")) {
|
|
983
|
+
const target = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formtarget")) || form.target;
|
|
984
|
+
for (const element of document.getElementsByName(target)) {
|
|
985
|
+
if (element instanceof HTMLIFrameElement)
|
|
986
|
+
return false;
|
|
987
|
+
}
|
|
988
|
+
return true;
|
|
989
|
+
}
|
|
990
|
+
else {
|
|
991
|
+
return true;
|
|
953
992
|
}
|
|
954
|
-
return true;
|
|
955
993
|
}
|
|
956
994
|
|
|
957
995
|
class View {
|
|
@@ -1049,8 +1087,8 @@ Copyright © 2022 37signals LLC
|
|
|
1049
1087
|
}
|
|
1050
1088
|
|
|
1051
1089
|
class FrameView extends View {
|
|
1052
|
-
|
|
1053
|
-
this.element.innerHTML = ""
|
|
1090
|
+
missing() {
|
|
1091
|
+
this.element.innerHTML = `<strong class="turbo-frame-error">Content missing</strong>`;
|
|
1054
1092
|
}
|
|
1055
1093
|
get snapshot() {
|
|
1056
1094
|
return new Snapshot(this.element);
|
|
@@ -1144,20 +1182,23 @@ Copyright © 2022 37signals LLC
|
|
|
1144
1182
|
event.shiftKey);
|
|
1145
1183
|
}
|
|
1146
1184
|
findLinkFromClickTarget(target) {
|
|
1147
|
-
|
|
1148
|
-
return target.closest("a[href]:not([target^=_]):not([download])");
|
|
1149
|
-
}
|
|
1185
|
+
return findClosestRecursively(target, "a[href]:not([target^=_]):not([download])");
|
|
1150
1186
|
}
|
|
1151
1187
|
getLocationForLink(link) {
|
|
1152
1188
|
return expandURL(link.getAttribute("href") || "");
|
|
1153
1189
|
}
|
|
1154
1190
|
}
|
|
1155
1191
|
function doesNotTargetIFrame(anchor) {
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1192
|
+
if (anchor.hasAttribute("target")) {
|
|
1193
|
+
for (const element of document.getElementsByName(anchor.target)) {
|
|
1194
|
+
if (element instanceof HTMLIFrameElement)
|
|
1195
|
+
return false;
|
|
1196
|
+
}
|
|
1197
|
+
return true;
|
|
1198
|
+
}
|
|
1199
|
+
else {
|
|
1200
|
+
return true;
|
|
1159
1201
|
}
|
|
1160
|
-
return true;
|
|
1161
1202
|
}
|
|
1162
1203
|
|
|
1163
1204
|
class FormLinkClickObserver {
|
|
@@ -1176,10 +1217,14 @@ Copyright © 2022 37signals LLC
|
|
|
1176
1217
|
link.hasAttribute("data-turbo-method"));
|
|
1177
1218
|
}
|
|
1178
1219
|
followedLinkToLocation(link, location) {
|
|
1179
|
-
const action = location.href;
|
|
1180
1220
|
const form = document.createElement("form");
|
|
1221
|
+
const type = "hidden";
|
|
1222
|
+
for (const [name, value] of location.searchParams) {
|
|
1223
|
+
form.append(Object.assign(document.createElement("input"), { type, name, value }));
|
|
1224
|
+
}
|
|
1225
|
+
const action = Object.assign(location, { search: "" });
|
|
1181
1226
|
form.setAttribute("data-turbo", "true");
|
|
1182
|
-
form.setAttribute("action", action);
|
|
1227
|
+
form.setAttribute("action", action.href);
|
|
1183
1228
|
form.setAttribute("hidden", "");
|
|
1184
1229
|
const method = link.getAttribute("data-turbo-method");
|
|
1185
1230
|
if (method)
|
|
@@ -1187,7 +1232,7 @@ Copyright © 2022 37signals LLC
|
|
|
1187
1232
|
const turboFrame = link.getAttribute("data-turbo-frame");
|
|
1188
1233
|
if (turboFrame)
|
|
1189
1234
|
form.setAttribute("data-turbo-frame", turboFrame);
|
|
1190
|
-
const turboAction = link
|
|
1235
|
+
const turboAction = getVisitAction(link);
|
|
1191
1236
|
if (turboAction)
|
|
1192
1237
|
form.setAttribute("data-turbo-action", turboAction);
|
|
1193
1238
|
const turboConfirm = link.getAttribute("data-turbo-confirm");
|
|
@@ -1204,16 +1249,16 @@ Copyright © 2022 37signals LLC
|
|
|
1204
1249
|
}
|
|
1205
1250
|
|
|
1206
1251
|
class Bardo {
|
|
1207
|
-
|
|
1208
|
-
this.delegate = delegate;
|
|
1209
|
-
this.permanentElementMap = permanentElementMap;
|
|
1210
|
-
}
|
|
1211
|
-
static preservingPermanentElements(delegate, permanentElementMap, callback) {
|
|
1252
|
+
static async preservingPermanentElements(delegate, permanentElementMap, callback) {
|
|
1212
1253
|
const bardo = new this(delegate, permanentElementMap);
|
|
1213
1254
|
bardo.enter();
|
|
1214
|
-
callback();
|
|
1255
|
+
await callback();
|
|
1215
1256
|
bardo.leave();
|
|
1216
1257
|
}
|
|
1258
|
+
constructor(delegate, permanentElementMap) {
|
|
1259
|
+
this.delegate = delegate;
|
|
1260
|
+
this.permanentElementMap = permanentElementMap;
|
|
1261
|
+
}
|
|
1217
1262
|
enter() {
|
|
1218
1263
|
for (const id in this.permanentElementMap) {
|
|
1219
1264
|
const [currentPermanentElement, newPermanentElement] = this.permanentElementMap[id];
|
|
@@ -1280,8 +1325,8 @@ Copyright © 2022 37signals LLC
|
|
|
1280
1325
|
delete this.resolvingFunctions;
|
|
1281
1326
|
}
|
|
1282
1327
|
}
|
|
1283
|
-
preservingPermanentElements(callback) {
|
|
1284
|
-
Bardo.preservingPermanentElements(this, this.permanentElementMap, callback);
|
|
1328
|
+
async preservingPermanentElements(callback) {
|
|
1329
|
+
await Bardo.preservingPermanentElements(this, this.permanentElementMap, callback);
|
|
1285
1330
|
}
|
|
1286
1331
|
focusFirstAutofocusableElement() {
|
|
1287
1332
|
const element = this.connectedSnapshot.firstAutofocusableElement;
|
|
@@ -1320,10 +1365,6 @@ Copyright © 2022 37signals LLC
|
|
|
1320
1365
|
}
|
|
1321
1366
|
|
|
1322
1367
|
class FrameRenderer extends Renderer {
|
|
1323
|
-
constructor(delegate, currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {
|
|
1324
|
-
super(currentSnapshot, newSnapshot, renderElement, isPreview, willRender);
|
|
1325
|
-
this.delegate = delegate;
|
|
1326
|
-
}
|
|
1327
1368
|
static renderElement(currentElement, newElement) {
|
|
1328
1369
|
var _a;
|
|
1329
1370
|
const destinationRange = document.createRange();
|
|
@@ -1336,6 +1377,10 @@ Copyright © 2022 37signals LLC
|
|
|
1336
1377
|
currentElement.appendChild(sourceRange.extractContents());
|
|
1337
1378
|
}
|
|
1338
1379
|
}
|
|
1380
|
+
constructor(delegate, currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {
|
|
1381
|
+
super(currentSnapshot, newSnapshot, renderElement, isPreview, willRender);
|
|
1382
|
+
this.delegate = delegate;
|
|
1383
|
+
}
|
|
1339
1384
|
get shouldRender() {
|
|
1340
1385
|
return true;
|
|
1341
1386
|
}
|
|
@@ -1394,18 +1439,6 @@ Copyright © 2022 37signals LLC
|
|
|
1394
1439
|
}
|
|
1395
1440
|
|
|
1396
1441
|
class ProgressBar {
|
|
1397
|
-
constructor() {
|
|
1398
|
-
this.hiding = false;
|
|
1399
|
-
this.value = 0;
|
|
1400
|
-
this.visible = false;
|
|
1401
|
-
this.trickle = () => {
|
|
1402
|
-
this.setValue(this.value + Math.random() / 100);
|
|
1403
|
-
};
|
|
1404
|
-
this.stylesheetElement = this.createStylesheetElement();
|
|
1405
|
-
this.progressElement = this.createProgressElement();
|
|
1406
|
-
this.installStylesheetElement();
|
|
1407
|
-
this.setValue(0);
|
|
1408
|
-
}
|
|
1409
1442
|
static get defaultCSS() {
|
|
1410
1443
|
return unindent `
|
|
1411
1444
|
.turbo-progress-bar {
|
|
@@ -1423,6 +1456,18 @@ Copyright © 2022 37signals LLC
|
|
|
1423
1456
|
}
|
|
1424
1457
|
`;
|
|
1425
1458
|
}
|
|
1459
|
+
constructor() {
|
|
1460
|
+
this.hiding = false;
|
|
1461
|
+
this.value = 0;
|
|
1462
|
+
this.visible = false;
|
|
1463
|
+
this.trickle = () => {
|
|
1464
|
+
this.setValue(this.value + Math.random() / 100);
|
|
1465
|
+
};
|
|
1466
|
+
this.stylesheetElement = this.createStylesheetElement();
|
|
1467
|
+
this.progressElement = this.createProgressElement();
|
|
1468
|
+
this.installStylesheetElement();
|
|
1469
|
+
this.setValue(0);
|
|
1470
|
+
}
|
|
1426
1471
|
show() {
|
|
1427
1472
|
if (!this.visible) {
|
|
1428
1473
|
this.visible = true;
|
|
@@ -1593,10 +1638,6 @@ Copyright © 2022 37signals LLC
|
|
|
1593
1638
|
}
|
|
1594
1639
|
|
|
1595
1640
|
class PageSnapshot extends Snapshot {
|
|
1596
|
-
constructor(element, headSnapshot) {
|
|
1597
|
-
super(element);
|
|
1598
|
-
this.headSnapshot = headSnapshot;
|
|
1599
|
-
}
|
|
1600
1641
|
static fromHTMLString(html = "") {
|
|
1601
1642
|
return this.fromDocument(parseHTMLDocument(html));
|
|
1602
1643
|
}
|
|
@@ -1606,6 +1647,10 @@ Copyright © 2022 37signals LLC
|
|
|
1606
1647
|
static fromDocument({ head, body }) {
|
|
1607
1648
|
return new this(body, new HeadSnapshot(head));
|
|
1608
1649
|
}
|
|
1650
|
+
constructor(element, headSnapshot) {
|
|
1651
|
+
super(element);
|
|
1652
|
+
this.headSnapshot = headSnapshot;
|
|
1653
|
+
}
|
|
1609
1654
|
clone() {
|
|
1610
1655
|
const clonedElement = this.element.cloneNode(true);
|
|
1611
1656
|
const selectElements = this.element.querySelectorAll("select");
|
|
@@ -1866,6 +1911,8 @@ Copyright © 2022 37signals LLC
|
|
|
1866
1911
|
this.adapter.visitProposedToLocation(this.redirectedToLocation, {
|
|
1867
1912
|
action: "replace",
|
|
1868
1913
|
response: this.response,
|
|
1914
|
+
shouldCacheSnapshot: false,
|
|
1915
|
+
willRender: false,
|
|
1869
1916
|
});
|
|
1870
1917
|
this.followedRedirect = true;
|
|
1871
1918
|
}
|
|
@@ -1880,7 +1927,7 @@ Copyright © 2022 37signals LLC
|
|
|
1880
1927
|
});
|
|
1881
1928
|
}
|
|
1882
1929
|
}
|
|
1883
|
-
|
|
1930
|
+
prepareRequest(request) {
|
|
1884
1931
|
if (this.acceptsStreamResponse) {
|
|
1885
1932
|
request.acceptResponseType(StreamMessage.contentType);
|
|
1886
1933
|
}
|
|
@@ -2103,10 +2150,11 @@ Copyright © 2022 37signals LLC
|
|
|
2103
2150
|
|
|
2104
2151
|
class CacheObserver {
|
|
2105
2152
|
constructor() {
|
|
2153
|
+
this.selector = "[data-turbo-temporary]";
|
|
2154
|
+
this.deprecatedSelector = "[data-turbo-cache=false]";
|
|
2106
2155
|
this.started = false;
|
|
2107
|
-
this.
|
|
2108
|
-
const
|
|
2109
|
-
for (const element of staleElements) {
|
|
2156
|
+
this.removeTemporaryElements = ((_event) => {
|
|
2157
|
+
for (const element of this.temporaryElements) {
|
|
2110
2158
|
element.remove();
|
|
2111
2159
|
}
|
|
2112
2160
|
});
|
|
@@ -2114,15 +2162,25 @@ Copyright © 2022 37signals LLC
|
|
|
2114
2162
|
start() {
|
|
2115
2163
|
if (!this.started) {
|
|
2116
2164
|
this.started = true;
|
|
2117
|
-
addEventListener("turbo:before-cache", this.
|
|
2165
|
+
addEventListener("turbo:before-cache", this.removeTemporaryElements, false);
|
|
2118
2166
|
}
|
|
2119
2167
|
}
|
|
2120
2168
|
stop() {
|
|
2121
2169
|
if (this.started) {
|
|
2122
2170
|
this.started = false;
|
|
2123
|
-
removeEventListener("turbo:before-cache", this.
|
|
2171
|
+
removeEventListener("turbo:before-cache", this.removeTemporaryElements, false);
|
|
2124
2172
|
}
|
|
2125
2173
|
}
|
|
2174
|
+
get temporaryElements() {
|
|
2175
|
+
return [...document.querySelectorAll(this.selector), ...this.temporaryElementsWithDeprecation];
|
|
2176
|
+
}
|
|
2177
|
+
get temporaryElementsWithDeprecation() {
|
|
2178
|
+
const elements = document.querySelectorAll(this.deprecatedSelector);
|
|
2179
|
+
if (elements.length) {
|
|
2180
|
+
console.warn(`The ${this.deprecatedSelector} selector is deprecated and will be removed in a future version. Use ${this.selector} instead.`);
|
|
2181
|
+
}
|
|
2182
|
+
return [...elements];
|
|
2183
|
+
}
|
|
2126
2184
|
}
|
|
2127
2185
|
|
|
2128
2186
|
class FrameRedirector {
|
|
@@ -2321,7 +2379,7 @@ Copyright © 2022 37signals LLC
|
|
|
2321
2379
|
if (formSubmission == this.formSubmission) {
|
|
2322
2380
|
const responseHTML = await fetchResponse.responseHTML;
|
|
2323
2381
|
if (responseHTML) {
|
|
2324
|
-
const shouldCacheSnapshot = formSubmission.
|
|
2382
|
+
const shouldCacheSnapshot = formSubmission.isSafe;
|
|
2325
2383
|
if (!shouldCacheSnapshot) {
|
|
2326
2384
|
this.view.clearSnapshotCache();
|
|
2327
2385
|
}
|
|
@@ -2381,10 +2439,8 @@ Copyright © 2022 37signals LLC
|
|
|
2381
2439
|
get restorationIdentifier() {
|
|
2382
2440
|
return this.history.restorationIdentifier;
|
|
2383
2441
|
}
|
|
2384
|
-
getActionForFormSubmission(
|
|
2385
|
-
|
|
2386
|
-
const action = getAttribute("data-turbo-action", submitter, formElement);
|
|
2387
|
-
return isAction(action) ? action : "advance";
|
|
2442
|
+
getActionForFormSubmission({ submitter, formElement }) {
|
|
2443
|
+
return getVisitAction(submitter, formElement) || "advance";
|
|
2388
2444
|
}
|
|
2389
2445
|
}
|
|
2390
2446
|
|
|
@@ -2626,7 +2682,7 @@ Copyright © 2022 37signals LLC
|
|
|
2626
2682
|
}
|
|
2627
2683
|
async render() {
|
|
2628
2684
|
if (this.willRender) {
|
|
2629
|
-
this.replaceBody();
|
|
2685
|
+
await this.replaceBody();
|
|
2630
2686
|
}
|
|
2631
2687
|
}
|
|
2632
2688
|
finishRendering() {
|
|
@@ -2645,16 +2701,16 @@ Copyright © 2022 37signals LLC
|
|
|
2645
2701
|
return this.newSnapshot.element;
|
|
2646
2702
|
}
|
|
2647
2703
|
async mergeHead() {
|
|
2704
|
+
const mergedHeadElements = this.mergeProvisionalElements();
|
|
2648
2705
|
const newStylesheetElements = this.copyNewHeadStylesheetElements();
|
|
2649
2706
|
this.copyNewHeadScriptElements();
|
|
2650
|
-
|
|
2651
|
-
this.copyNewHeadProvisionalElements();
|
|
2707
|
+
await mergedHeadElements;
|
|
2652
2708
|
await newStylesheetElements;
|
|
2653
2709
|
}
|
|
2654
|
-
replaceBody() {
|
|
2655
|
-
this.preservingPermanentElements(() => {
|
|
2710
|
+
async replaceBody() {
|
|
2711
|
+
await this.preservingPermanentElements(async () => {
|
|
2656
2712
|
this.activateNewBody();
|
|
2657
|
-
this.assignNewBody();
|
|
2713
|
+
await this.assignNewBody();
|
|
2658
2714
|
});
|
|
2659
2715
|
}
|
|
2660
2716
|
get trackedElementsAreIdentical() {
|
|
@@ -2673,6 +2729,35 @@ Copyright © 2022 37signals LLC
|
|
|
2673
2729
|
document.head.appendChild(activateScriptElement(element));
|
|
2674
2730
|
}
|
|
2675
2731
|
}
|
|
2732
|
+
async mergeProvisionalElements() {
|
|
2733
|
+
const newHeadElements = [...this.newHeadProvisionalElements];
|
|
2734
|
+
for (const element of this.currentHeadProvisionalElements) {
|
|
2735
|
+
if (!this.isCurrentElementInElementList(element, newHeadElements)) {
|
|
2736
|
+
document.head.removeChild(element);
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
for (const element of newHeadElements) {
|
|
2740
|
+
document.head.appendChild(element);
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
isCurrentElementInElementList(element, elementList) {
|
|
2744
|
+
for (const [index, newElement] of elementList.entries()) {
|
|
2745
|
+
if (element.tagName == "TITLE") {
|
|
2746
|
+
if (newElement.tagName != "TITLE") {
|
|
2747
|
+
continue;
|
|
2748
|
+
}
|
|
2749
|
+
if (element.innerHTML == newElement.innerHTML) {
|
|
2750
|
+
elementList.splice(index, 1);
|
|
2751
|
+
return true;
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2754
|
+
if (newElement.isEqualNode(element)) {
|
|
2755
|
+
elementList.splice(index, 1);
|
|
2756
|
+
return true;
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
return false;
|
|
2760
|
+
}
|
|
2676
2761
|
removeCurrentHeadProvisionalElements() {
|
|
2677
2762
|
for (const element of this.currentHeadProvisionalElements) {
|
|
2678
2763
|
document.head.removeChild(element);
|
|
@@ -2693,8 +2778,8 @@ Copyright © 2022 37signals LLC
|
|
|
2693
2778
|
inertScriptElement.replaceWith(activatedScriptElement);
|
|
2694
2779
|
}
|
|
2695
2780
|
}
|
|
2696
|
-
assignNewBody() {
|
|
2697
|
-
this.renderElement(this.currentElement, this.newElement);
|
|
2781
|
+
async assignNewBody() {
|
|
2782
|
+
await this.renderElement(this.currentElement, this.newElement);
|
|
2698
2783
|
}
|
|
2699
2784
|
get newHeadStylesheetElements() {
|
|
2700
2785
|
return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot);
|
|
@@ -3111,8 +3196,8 @@ Copyright © 2022 37signals LLC
|
|
|
3111
3196
|
}
|
|
3112
3197
|
}
|
|
3113
3198
|
elementIsNavigatable(element) {
|
|
3114
|
-
const container = element
|
|
3115
|
-
const withinFrame = element
|
|
3199
|
+
const container = findClosestRecursively(element, "[data-turbo]");
|
|
3200
|
+
const withinFrame = findClosestRecursively(element, "turbo-frame");
|
|
3116
3201
|
if (this.drive || withinFrame) {
|
|
3117
3202
|
if (container) {
|
|
3118
3203
|
return container.getAttribute("data-turbo") != "false";
|
|
@@ -3131,8 +3216,7 @@ Copyright © 2022 37signals LLC
|
|
|
3131
3216
|
}
|
|
3132
3217
|
}
|
|
3133
3218
|
getActionForLink(link) {
|
|
3134
|
-
|
|
3135
|
-
return isAction(action) ? action : "advance";
|
|
3219
|
+
return getVisitAction(link) || "advance";
|
|
3136
3220
|
}
|
|
3137
3221
|
get snapshot() {
|
|
3138
3222
|
return this.view.snapshot;
|
|
@@ -3192,7 +3276,10 @@ Copyright © 2022 37signals LLC
|
|
|
3192
3276
|
this.targetElements.forEach((e) => e.replaceWith(this.templateContent));
|
|
3193
3277
|
},
|
|
3194
3278
|
update() {
|
|
3195
|
-
this.targetElements.forEach((
|
|
3279
|
+
this.targetElements.forEach((targetElement) => {
|
|
3280
|
+
targetElement.innerHTML = "";
|
|
3281
|
+
targetElement.append(this.templateContent);
|
|
3282
|
+
});
|
|
3196
3283
|
},
|
|
3197
3284
|
};
|
|
3198
3285
|
|
|
@@ -3252,6 +3339,9 @@ Copyright © 2022 37signals LLC
|
|
|
3252
3339
|
StreamActions: StreamActions
|
|
3253
3340
|
});
|
|
3254
3341
|
|
|
3342
|
+
class TurboFrameMissingError extends Error {
|
|
3343
|
+
}
|
|
3344
|
+
|
|
3255
3345
|
class FrameController {
|
|
3256
3346
|
constructor(element) {
|
|
3257
3347
|
this.fetchResponseLoaded = (_fetchResponse) => { };
|
|
@@ -3352,35 +3442,22 @@ Copyright © 2022 37signals LLC
|
|
|
3352
3442
|
try {
|
|
3353
3443
|
const html = await fetchResponse.responseHTML;
|
|
3354
3444
|
if (html) {
|
|
3355
|
-
const
|
|
3356
|
-
const
|
|
3357
|
-
if (
|
|
3358
|
-
|
|
3359
|
-
const renderer = new FrameRenderer(this, this.view.snapshot, snapshot, FrameRenderer.renderElement, false, false);
|
|
3360
|
-
if (this.view.renderPromise)
|
|
3361
|
-
await this.view.renderPromise;
|
|
3362
|
-
this.changeHistory();
|
|
3363
|
-
await this.view.render(renderer);
|
|
3364
|
-
this.complete = true;
|
|
3365
|
-
session.frameRendered(fetchResponse, this.element);
|
|
3366
|
-
session.frameLoaded(this.element);
|
|
3367
|
-
this.fetchResponseLoaded(fetchResponse);
|
|
3445
|
+
const document = parseHTMLDocument(html);
|
|
3446
|
+
const pageSnapshot = PageSnapshot.fromDocument(document);
|
|
3447
|
+
if (pageSnapshot.isVisitable) {
|
|
3448
|
+
await this.loadFrameResponse(fetchResponse, document);
|
|
3368
3449
|
}
|
|
3369
|
-
else
|
|
3370
|
-
|
|
3371
|
-
this.visitResponse(fetchResponse.response);
|
|
3450
|
+
else {
|
|
3451
|
+
await this.handleUnvisitableFrameResponse(fetchResponse);
|
|
3372
3452
|
}
|
|
3373
3453
|
}
|
|
3374
3454
|
}
|
|
3375
|
-
catch (error) {
|
|
3376
|
-
console.error(error);
|
|
3377
|
-
this.view.invalidate();
|
|
3378
|
-
}
|
|
3379
3455
|
finally {
|
|
3380
3456
|
this.fetchResponseLoaded = () => { };
|
|
3381
3457
|
}
|
|
3382
3458
|
}
|
|
3383
|
-
elementAppearedInViewport(
|
|
3459
|
+
elementAppearedInViewport(element) {
|
|
3460
|
+
this.proposeVisitIfNavigatedWithAction(element, element);
|
|
3384
3461
|
this.loadSourceURL();
|
|
3385
3462
|
}
|
|
3386
3463
|
willSubmitFormLinkToLocation(link) {
|
|
@@ -3406,12 +3483,12 @@ Copyright © 2022 37signals LLC
|
|
|
3406
3483
|
}
|
|
3407
3484
|
this.formSubmission = new FormSubmission(this, element, submitter);
|
|
3408
3485
|
const { fetchRequest } = this.formSubmission;
|
|
3409
|
-
this.
|
|
3486
|
+
this.prepareRequest(fetchRequest);
|
|
3410
3487
|
this.formSubmission.start();
|
|
3411
3488
|
}
|
|
3412
|
-
|
|
3489
|
+
prepareRequest(request) {
|
|
3413
3490
|
var _a;
|
|
3414
|
-
headers["Turbo-Frame"] = this.id;
|
|
3491
|
+
request.headers["Turbo-Frame"] = this.id;
|
|
3415
3492
|
if ((_a = this.currentNavigationElement) === null || _a === void 0 ? void 0 : _a.hasAttribute("data-turbo-stream")) {
|
|
3416
3493
|
request.acceptResponseType(StreamMessage.contentType);
|
|
3417
3494
|
}
|
|
@@ -3427,7 +3504,6 @@ Copyright © 2022 37signals LLC
|
|
|
3427
3504
|
this.resolveVisitPromise();
|
|
3428
3505
|
}
|
|
3429
3506
|
async requestFailedWithResponse(request, response) {
|
|
3430
|
-
console.error(response);
|
|
3431
3507
|
await this.loadResponse(response);
|
|
3432
3508
|
this.resolveVisitPromise();
|
|
3433
3509
|
}
|
|
@@ -3445,9 +3521,13 @@ Copyright © 2022 37signals LLC
|
|
|
3445
3521
|
const frame = this.findFrameElement(formSubmission.formElement, formSubmission.submitter);
|
|
3446
3522
|
frame.delegate.proposeVisitIfNavigatedWithAction(frame, formSubmission.formElement, formSubmission.submitter);
|
|
3447
3523
|
frame.delegate.loadResponse(response);
|
|
3524
|
+
if (!formSubmission.isSafe) {
|
|
3525
|
+
session.clearCache();
|
|
3526
|
+
}
|
|
3448
3527
|
}
|
|
3449
3528
|
formSubmissionFailedWithResponse(formSubmission, fetchResponse) {
|
|
3450
3529
|
this.element.delegate.loadResponse(fetchResponse);
|
|
3530
|
+
session.clearCache();
|
|
3451
3531
|
}
|
|
3452
3532
|
formSubmissionErrored(formSubmission, error) {
|
|
3453
3533
|
console.error(error);
|
|
@@ -3475,6 +3555,24 @@ Copyright © 2022 37signals LLC
|
|
|
3475
3555
|
willRenderFrame(currentElement, _newElement) {
|
|
3476
3556
|
this.previousFrameElement = currentElement.cloneNode(true);
|
|
3477
3557
|
}
|
|
3558
|
+
async loadFrameResponse(fetchResponse, document) {
|
|
3559
|
+
const newFrameElement = await this.extractForeignFrameElement(document.body);
|
|
3560
|
+
if (newFrameElement) {
|
|
3561
|
+
const snapshot = new Snapshot(newFrameElement);
|
|
3562
|
+
const renderer = new FrameRenderer(this, this.view.snapshot, snapshot, FrameRenderer.renderElement, false, false);
|
|
3563
|
+
if (this.view.renderPromise)
|
|
3564
|
+
await this.view.renderPromise;
|
|
3565
|
+
this.changeHistory();
|
|
3566
|
+
await this.view.render(renderer);
|
|
3567
|
+
this.complete = true;
|
|
3568
|
+
session.frameRendered(fetchResponse, this.element);
|
|
3569
|
+
session.frameLoaded(this.element);
|
|
3570
|
+
this.fetchResponseLoaded(fetchResponse);
|
|
3571
|
+
}
|
|
3572
|
+
else if (this.willHandleFrameMissingFromResponse(fetchResponse)) {
|
|
3573
|
+
this.handleFrameMissingFromResponse(fetchResponse);
|
|
3574
|
+
}
|
|
3575
|
+
}
|
|
3478
3576
|
async visit(url) {
|
|
3479
3577
|
var _a;
|
|
3480
3578
|
const request = new FetchRequest(this, FetchMethod.get, url, new URLSearchParams(), this.element);
|
|
@@ -3491,7 +3589,6 @@ Copyright © 2022 37signals LLC
|
|
|
3491
3589
|
}
|
|
3492
3590
|
navigateFrame(element, url, submitter) {
|
|
3493
3591
|
const frame = this.findFrameElement(element, submitter);
|
|
3494
|
-
this.pageSnapshot = PageSnapshot.fromElement(frame).clone();
|
|
3495
3592
|
frame.delegate.proposeVisitIfNavigatedWithAction(frame, element, submitter);
|
|
3496
3593
|
this.withCurrentNavigationElement(element, () => {
|
|
3497
3594
|
frame.src = url;
|
|
@@ -3499,7 +3596,8 @@ Copyright © 2022 37signals LLC
|
|
|
3499
3596
|
}
|
|
3500
3597
|
proposeVisitIfNavigatedWithAction(frame, element, submitter) {
|
|
3501
3598
|
this.action = getVisitAction(submitter, element, frame);
|
|
3502
|
-
if (
|
|
3599
|
+
if (this.action) {
|
|
3600
|
+
const pageSnapshot = PageSnapshot.fromElement(frame).clone();
|
|
3503
3601
|
const { visitCachedSnapshot } = frame.delegate;
|
|
3504
3602
|
frame.delegate.fetchResponseLoaded = (fetchResponse) => {
|
|
3505
3603
|
if (frame.src) {
|
|
@@ -3512,7 +3610,7 @@ Copyright © 2022 37signals LLC
|
|
|
3512
3610
|
willRender: false,
|
|
3513
3611
|
updateHistory: false,
|
|
3514
3612
|
restorationIdentifier: this.restorationIdentifier,
|
|
3515
|
-
snapshot:
|
|
3613
|
+
snapshot: pageSnapshot,
|
|
3516
3614
|
};
|
|
3517
3615
|
if (this.action)
|
|
3518
3616
|
options.action = this.action;
|
|
@@ -3527,6 +3625,10 @@ Copyright © 2022 37signals LLC
|
|
|
3527
3625
|
session.history.update(method, expandURL(this.element.src || ""), this.restorationIdentifier);
|
|
3528
3626
|
}
|
|
3529
3627
|
}
|
|
3628
|
+
async handleUnvisitableFrameResponse(fetchResponse) {
|
|
3629
|
+
console.warn(`The response (${fetchResponse.statusCode}) from <turbo-frame id="${this.element.id}"> is performing a full page visit due to turbo-visit-control.`);
|
|
3630
|
+
await this.visitResponse(fetchResponse.response);
|
|
3631
|
+
}
|
|
3530
3632
|
willHandleFrameMissingFromResponse(fetchResponse) {
|
|
3531
3633
|
this.element.setAttribute("complete", "");
|
|
3532
3634
|
const response = fetchResponse.response;
|
|
@@ -3545,6 +3647,14 @@ Copyright © 2022 37signals LLC
|
|
|
3545
3647
|
});
|
|
3546
3648
|
return !event.defaultPrevented;
|
|
3547
3649
|
}
|
|
3650
|
+
handleFrameMissingFromResponse(fetchResponse) {
|
|
3651
|
+
this.view.missing();
|
|
3652
|
+
this.throwFrameMissingError(fetchResponse);
|
|
3653
|
+
}
|
|
3654
|
+
throwFrameMissingError(fetchResponse) {
|
|
3655
|
+
const message = `The response (${fetchResponse.statusCode}) did not contain the expected <turbo-frame id="${this.element.id}"> and will be ignored. To perform a full page visit instead, set turbo-visit-control to reload.`;
|
|
3656
|
+
throw new TurboFrameMissingError(message);
|
|
3657
|
+
}
|
|
3548
3658
|
async visitResponse(response) {
|
|
3549
3659
|
const wrapped = new FetchResponse(response);
|
|
3550
3660
|
const responseHTML = await wrapped.responseHTML;
|