@hotwired/turbo 7.2.0-beta.1 → 7.2.0-beta.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.
- package/dist/turbo.es2017-esm.js +388 -321
- package/dist/turbo.es2017-umd.js +388 -321
- package/dist/types/core/drive/error_renderer.d.ts +1 -1
- package/dist/types/core/drive/head_snapshot.d.ts +3 -3
- package/dist/types/core/drive/navigator.d.ts +3 -3
- package/dist/types/core/drive/page_renderer.d.ts +5 -5
- package/dist/types/core/drive/visit.d.ts +12 -1
- package/dist/types/core/frames/frame_controller.d.ts +26 -16
- package/dist/types/core/frames/frame_redirector.d.ts +12 -10
- package/dist/types/core/frames/frame_renderer.d.ts +1 -1
- package/dist/types/core/index.d.ts +5 -4
- package/dist/types/core/native/adapter.d.ts +1 -1
- package/dist/types/core/native/browser_adapter.d.ts +1 -1
- package/dist/types/core/renderer.d.ts +0 -2
- package/dist/types/core/session.d.ts +18 -11
- package/dist/types/core/streams/stream_message.d.ts +2 -6
- package/dist/types/core/types.d.ts +4 -0
- package/dist/types/core/view.d.ts +1 -1
- package/dist/types/elements/frame_element.d.ts +5 -5
- package/dist/types/elements/stream_element.d.ts +3 -1
- package/dist/types/http/fetch_request.d.ts +1 -0
- package/dist/types/observers/form_link_click_observer.d.ts +14 -0
- package/dist/types/observers/form_submit_observer.d.ts +2 -1
- package/dist/types/observers/link_click_observer.d.ts +3 -2
- package/dist/types/tests/functional/form_mode_tests.d.ts +1 -0
- package/dist/types/tests/unit/deprecated_adapter_support_test.d.ts +1 -1
- package/dist/types/util.d.ts +6 -0
- package/package.json +1 -1
- package/dist/types/core/frames/form_interceptor.d.ts +0 -12
- package/dist/types/core/frames/link_interceptor.d.ts +0 -16
- package/dist/types/observers/form_link_interceptor.d.ts +0 -14
package/dist/turbo.es2017-umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Turbo 7.2.0-beta.
|
|
2
|
+
Turbo 7.2.0-beta.2
|
|
3
3
|
Copyright © 2022 Basecamp, LLC
|
|
4
4
|
*/
|
|
5
5
|
(function (global, factory) {
|
|
@@ -138,6 +138,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
138
138
|
this.removeAttribute("complete");
|
|
139
139
|
this.src = null;
|
|
140
140
|
this.src = src;
|
|
141
|
+
return this.loaded;
|
|
141
142
|
}
|
|
142
143
|
attributeChangedCallback(name) {
|
|
143
144
|
if (name == "loading") {
|
|
@@ -316,6 +317,36 @@ Copyright © 2022 Basecamp, LLC
|
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
319
|
|
|
320
|
+
function isAction(action) {
|
|
321
|
+
return action == "advance" || action == "replace" || action == "restore";
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function activateScriptElement(element) {
|
|
325
|
+
if (element.getAttribute("data-turbo-eval") == "false") {
|
|
326
|
+
return element;
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
const createdScriptElement = document.createElement("script");
|
|
330
|
+
const cspNonce = getMetaContent("csp-nonce");
|
|
331
|
+
if (cspNonce) {
|
|
332
|
+
createdScriptElement.nonce = cspNonce;
|
|
333
|
+
}
|
|
334
|
+
createdScriptElement.textContent = element.textContent;
|
|
335
|
+
createdScriptElement.async = false;
|
|
336
|
+
copyElementAttributes(createdScriptElement, element);
|
|
337
|
+
return createdScriptElement;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function copyElementAttributes(destinationElement, sourceElement) {
|
|
341
|
+
for (const { name, value } of sourceElement.attributes) {
|
|
342
|
+
destinationElement.setAttribute(name, value);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function createDocumentFragment(html) {
|
|
346
|
+
const template = document.createElement("template");
|
|
347
|
+
template.innerHTML = html;
|
|
348
|
+
return template.content;
|
|
349
|
+
}
|
|
319
350
|
function dispatch(eventName, { target, cancelable, detail } = {}) {
|
|
320
351
|
const event = new CustomEvent(eventName, {
|
|
321
352
|
cancelable,
|
|
@@ -395,6 +426,31 @@ Copyright © 2022 Basecamp, LLC
|
|
|
395
426
|
element.removeAttribute("aria-busy");
|
|
396
427
|
}
|
|
397
428
|
}
|
|
429
|
+
function waitForLoad(element, timeoutInMilliseconds = 2000) {
|
|
430
|
+
return new Promise((resolve) => {
|
|
431
|
+
const onComplete = () => {
|
|
432
|
+
element.removeEventListener("error", onComplete);
|
|
433
|
+
element.removeEventListener("load", onComplete);
|
|
434
|
+
resolve();
|
|
435
|
+
};
|
|
436
|
+
element.addEventListener("load", onComplete, { once: true });
|
|
437
|
+
element.addEventListener("error", onComplete, { once: true });
|
|
438
|
+
setTimeout(resolve, timeoutInMilliseconds);
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
function getHistoryMethodForAction(action) {
|
|
442
|
+
switch (action) {
|
|
443
|
+
case "replace":
|
|
444
|
+
return history.replaceState;
|
|
445
|
+
case "advance":
|
|
446
|
+
case "restore":
|
|
447
|
+
return history.pushState;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
function getVisitAction(...elements) {
|
|
451
|
+
const action = getAttribute("data-turbo-action", ...elements);
|
|
452
|
+
return isAction(action) ? action : null;
|
|
453
|
+
}
|
|
398
454
|
function getMetaElement(name) {
|
|
399
455
|
return document.querySelector(`meta[name="${name}"]`);
|
|
400
456
|
}
|
|
@@ -519,6 +575,9 @@ Copyright © 2022 Basecamp, LLC
|
|
|
519
575
|
get abortSignal() {
|
|
520
576
|
return this.abortController.signal;
|
|
521
577
|
}
|
|
578
|
+
acceptResponseType(mimeType) {
|
|
579
|
+
this.headers["Accept"] = [mimeType, this.headers["Accept"]].join(", ");
|
|
580
|
+
}
|
|
522
581
|
async allowRequestToBeIntercepted(fetchOptions) {
|
|
523
582
|
const requestInterception = new Promise((resolve) => (this.resolveRequestPromise = resolve));
|
|
524
583
|
const event = dispatch("turbo:before-fetch-request", {
|
|
@@ -563,40 +622,29 @@ Copyright © 2022 Basecamp, LLC
|
|
|
563
622
|
}
|
|
564
623
|
|
|
565
624
|
class StreamMessage {
|
|
566
|
-
constructor(
|
|
567
|
-
this.
|
|
568
|
-
this.templateElement.innerHTML = html;
|
|
625
|
+
constructor(fragment) {
|
|
626
|
+
this.fragment = importStreamElements(fragment);
|
|
569
627
|
}
|
|
570
628
|
static wrap(message) {
|
|
571
629
|
if (typeof message == "string") {
|
|
572
|
-
return new this(message);
|
|
630
|
+
return new this(createDocumentFragment(message));
|
|
573
631
|
}
|
|
574
632
|
else {
|
|
575
633
|
return message;
|
|
576
634
|
}
|
|
577
635
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
636
|
+
}
|
|
637
|
+
StreamMessage.contentType = "text/vnd.turbo-stream.html";
|
|
638
|
+
function importStreamElements(fragment) {
|
|
639
|
+
for (const element of fragment.querySelectorAll("turbo-stream")) {
|
|
640
|
+
const streamElement = document.importNode(element, true);
|
|
641
|
+
for (const inertScriptElement of streamElement.templateElement.content.querySelectorAll("script")) {
|
|
642
|
+
inertScriptElement.replaceWith(activateScriptElement(inertScriptElement));
|
|
582
643
|
}
|
|
583
|
-
|
|
584
|
-
}
|
|
585
|
-
get foreignElements() {
|
|
586
|
-
return this.templateChildren.reduce((streamElements, child) => {
|
|
587
|
-
if (child.tagName.toLowerCase() == "turbo-stream") {
|
|
588
|
-
return [...streamElements, child];
|
|
589
|
-
}
|
|
590
|
-
else {
|
|
591
|
-
return streamElements;
|
|
592
|
-
}
|
|
593
|
-
}, []);
|
|
594
|
-
}
|
|
595
|
-
get templateChildren() {
|
|
596
|
-
return Array.from(this.templateElement.content.children);
|
|
644
|
+
element.replaceWith(streamElement);
|
|
597
645
|
}
|
|
646
|
+
return fragment;
|
|
598
647
|
}
|
|
599
|
-
StreamMessage.contentType = "text/vnd.turbo-stream.html";
|
|
600
648
|
|
|
601
649
|
var FormSubmissionState;
|
|
602
650
|
(function (FormSubmissionState) {
|
|
@@ -711,7 +759,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
711
759
|
}
|
|
712
760
|
}
|
|
713
761
|
if (this.requestAcceptsTurboStreamResponse(request)) {
|
|
714
|
-
|
|
762
|
+
request.acceptResponseType(StreamMessage.contentType);
|
|
715
763
|
}
|
|
716
764
|
}
|
|
717
765
|
requestStarted(_request) {
|
|
@@ -747,6 +795,10 @@ Copyright © 2022 Basecamp, LLC
|
|
|
747
795
|
}
|
|
748
796
|
requestErrored(request, error) {
|
|
749
797
|
this.result = { success: false, error };
|
|
798
|
+
dispatch("turbo:fetch-request-error", {
|
|
799
|
+
target: this.formElement,
|
|
800
|
+
detail: { request, error },
|
|
801
|
+
});
|
|
750
802
|
this.delegate.formSubmissionErrored(this, error);
|
|
751
803
|
}
|
|
752
804
|
requestFinished(_request) {
|
|
@@ -770,8 +822,8 @@ Copyright © 2022 Basecamp, LLC
|
|
|
770
822
|
const formData = new FormData(formElement);
|
|
771
823
|
const name = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("name");
|
|
772
824
|
const value = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("value");
|
|
773
|
-
if (name
|
|
774
|
-
formData.append(name, value);
|
|
825
|
+
if (name) {
|
|
826
|
+
formData.append(name, value || "");
|
|
775
827
|
}
|
|
776
828
|
return formData;
|
|
777
829
|
}
|
|
@@ -819,7 +871,14 @@ Copyright © 2022 Basecamp, LLC
|
|
|
819
871
|
return this.element.isConnected;
|
|
820
872
|
}
|
|
821
873
|
get firstAutofocusableElement() {
|
|
822
|
-
|
|
874
|
+
const inertDisabledOrHidden = "[inert], :disabled, [hidden], details:not([open]), dialog:not([open])";
|
|
875
|
+
for (const element of this.element.querySelectorAll("[autofocus]")) {
|
|
876
|
+
if (element.closest(inertDisabledOrHidden) == null)
|
|
877
|
+
return element;
|
|
878
|
+
else
|
|
879
|
+
continue;
|
|
880
|
+
}
|
|
881
|
+
return null;
|
|
823
882
|
}
|
|
824
883
|
get permanentElements() {
|
|
825
884
|
return [...this.element.querySelectorAll("[id][data-turbo-permanent]")];
|
|
@@ -840,32 +899,54 @@ Copyright © 2022 Basecamp, LLC
|
|
|
840
899
|
}
|
|
841
900
|
}
|
|
842
901
|
|
|
843
|
-
class
|
|
844
|
-
constructor(delegate,
|
|
902
|
+
class FormSubmitObserver {
|
|
903
|
+
constructor(delegate, eventTarget) {
|
|
904
|
+
this.started = false;
|
|
905
|
+
this.submitCaptured = () => {
|
|
906
|
+
this.eventTarget.removeEventListener("submit", this.submitBubbled, false);
|
|
907
|
+
this.eventTarget.addEventListener("submit", this.submitBubbled, false);
|
|
908
|
+
};
|
|
845
909
|
this.submitBubbled = ((event) => {
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
form instanceof HTMLFormElement &&
|
|
849
|
-
form.closest("turbo-frame, html") == this.element) {
|
|
910
|
+
if (!event.defaultPrevented) {
|
|
911
|
+
const form = event.target instanceof HTMLFormElement ? event.target : undefined;
|
|
850
912
|
const submitter = event.submitter || undefined;
|
|
851
|
-
|
|
852
|
-
|
|
913
|
+
if (form &&
|
|
914
|
+
submissionDoesNotDismissDialog(form, submitter) &&
|
|
915
|
+
submissionDoesNotTargetIFrame(form, submitter) &&
|
|
916
|
+
this.delegate.willSubmitForm(form, submitter)) {
|
|
853
917
|
event.preventDefault();
|
|
854
|
-
|
|
855
|
-
this.delegate.formSubmissionIntercepted(form, submitter);
|
|
918
|
+
this.delegate.formSubmitted(form, submitter);
|
|
856
919
|
}
|
|
857
920
|
}
|
|
858
921
|
});
|
|
859
922
|
this.delegate = delegate;
|
|
860
|
-
this.
|
|
923
|
+
this.eventTarget = eventTarget;
|
|
861
924
|
}
|
|
862
925
|
start() {
|
|
863
|
-
|
|
926
|
+
if (!this.started) {
|
|
927
|
+
this.eventTarget.addEventListener("submit", this.submitCaptured, true);
|
|
928
|
+
this.started = true;
|
|
929
|
+
}
|
|
864
930
|
}
|
|
865
931
|
stop() {
|
|
866
|
-
|
|
932
|
+
if (this.started) {
|
|
933
|
+
this.eventTarget.removeEventListener("submit", this.submitCaptured, true);
|
|
934
|
+
this.started = false;
|
|
935
|
+
}
|
|
867
936
|
}
|
|
868
937
|
}
|
|
938
|
+
function submissionDoesNotDismissDialog(form, submitter) {
|
|
939
|
+
const method = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formmethod")) || form.getAttribute("method");
|
|
940
|
+
return method != "dialog";
|
|
941
|
+
}
|
|
942
|
+
function submissionDoesNotTargetIFrame(form, submitter) {
|
|
943
|
+
const target = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formtarget")) || form.target;
|
|
944
|
+
for (const element of document.getElementsByName(target)) {
|
|
945
|
+
if (element instanceof HTMLIFrameElement)
|
|
946
|
+
return false;
|
|
947
|
+
}
|
|
948
|
+
return true;
|
|
949
|
+
}
|
|
869
950
|
|
|
870
951
|
class View {
|
|
871
952
|
constructor(delegate, element) {
|
|
@@ -917,7 +998,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
917
998
|
try {
|
|
918
999
|
this.renderPromise = new Promise((resolve) => (this.resolveRenderPromise = resolve));
|
|
919
1000
|
this.renderer = renderer;
|
|
920
|
-
this.prepareToRenderSnapshot(renderer);
|
|
1001
|
+
await this.prepareToRenderSnapshot(renderer);
|
|
921
1002
|
const renderInterception = new Promise((resolve) => (this.resolveInterceptionPromise = resolve));
|
|
922
1003
|
const options = { resume: this.resolveInterceptionPromise, render: this.renderer.renderElement };
|
|
923
1004
|
const immediateRender = this.delegate.allowsImmediateRender(snapshot, options);
|
|
@@ -941,9 +1022,9 @@ Copyright © 2022 Basecamp, LLC
|
|
|
941
1022
|
invalidate(reason) {
|
|
942
1023
|
this.delegate.viewInvalidated(reason);
|
|
943
1024
|
}
|
|
944
|
-
prepareToRenderSnapshot(renderer) {
|
|
1025
|
+
async prepareToRenderSnapshot(renderer) {
|
|
945
1026
|
this.markAsPreview(renderer.isPreview);
|
|
946
|
-
renderer.prepareToRender();
|
|
1027
|
+
await renderer.prepareToRender();
|
|
947
1028
|
}
|
|
948
1029
|
markAsPreview(isPreview) {
|
|
949
1030
|
if (isPreview) {
|
|
@@ -970,64 +1051,84 @@ Copyright © 2022 Basecamp, LLC
|
|
|
970
1051
|
}
|
|
971
1052
|
}
|
|
972
1053
|
|
|
973
|
-
class
|
|
974
|
-
constructor(delegate,
|
|
975
|
-
this.
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
else {
|
|
980
|
-
delete this.clickEvent;
|
|
981
|
-
}
|
|
1054
|
+
class LinkClickObserver {
|
|
1055
|
+
constructor(delegate, eventTarget) {
|
|
1056
|
+
this.started = false;
|
|
1057
|
+
this.clickCaptured = () => {
|
|
1058
|
+
this.eventTarget.removeEventListener("click", this.clickBubbled, false);
|
|
1059
|
+
this.eventTarget.addEventListener("click", this.clickBubbled, false);
|
|
982
1060
|
};
|
|
983
|
-
this.
|
|
984
|
-
if (
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
this.
|
|
1061
|
+
this.clickBubbled = (event) => {
|
|
1062
|
+
if (event instanceof MouseEvent && this.clickEventIsSignificant(event)) {
|
|
1063
|
+
const target = (event.composedPath && event.composedPath()[0]) || event.target;
|
|
1064
|
+
const link = this.findLinkFromClickTarget(target);
|
|
1065
|
+
if (link && doesNotTargetIFrame(link)) {
|
|
1066
|
+
const location = this.getLocationForLink(link);
|
|
1067
|
+
if (this.delegate.willFollowLinkToLocation(link, location, event)) {
|
|
1068
|
+
event.preventDefault();
|
|
1069
|
+
this.delegate.followedLinkToLocation(link, location);
|
|
1070
|
+
}
|
|
989
1071
|
}
|
|
990
1072
|
}
|
|
991
|
-
|
|
992
|
-
});
|
|
993
|
-
this.willVisit = ((_event) => {
|
|
994
|
-
delete this.clickEvent;
|
|
995
|
-
});
|
|
1073
|
+
};
|
|
996
1074
|
this.delegate = delegate;
|
|
997
|
-
this.
|
|
1075
|
+
this.eventTarget = eventTarget;
|
|
998
1076
|
}
|
|
999
1077
|
start() {
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1078
|
+
if (!this.started) {
|
|
1079
|
+
this.eventTarget.addEventListener("click", this.clickCaptured, true);
|
|
1080
|
+
this.started = true;
|
|
1081
|
+
}
|
|
1003
1082
|
}
|
|
1004
1083
|
stop() {
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1084
|
+
if (this.started) {
|
|
1085
|
+
this.eventTarget.removeEventListener("click", this.clickCaptured, true);
|
|
1086
|
+
this.started = false;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
clickEventIsSignificant(event) {
|
|
1090
|
+
return !((event.target && event.target.isContentEditable) ||
|
|
1091
|
+
event.defaultPrevented ||
|
|
1092
|
+
event.which > 1 ||
|
|
1093
|
+
event.altKey ||
|
|
1094
|
+
event.ctrlKey ||
|
|
1095
|
+
event.metaKey ||
|
|
1096
|
+
event.shiftKey);
|
|
1097
|
+
}
|
|
1098
|
+
findLinkFromClickTarget(target) {
|
|
1099
|
+
if (target instanceof Element) {
|
|
1100
|
+
return target.closest("a[href]:not([target^=_]):not([download])");
|
|
1101
|
+
}
|
|
1008
1102
|
}
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
return element && element.closest("turbo-frame, html") == this.element;
|
|
1103
|
+
getLocationForLink(link) {
|
|
1104
|
+
return expandURL(link.getAttribute("href") || "");
|
|
1012
1105
|
}
|
|
1013
1106
|
}
|
|
1107
|
+
function doesNotTargetIFrame(anchor) {
|
|
1108
|
+
for (const element of document.getElementsByName(anchor.target)) {
|
|
1109
|
+
if (element instanceof HTMLIFrameElement)
|
|
1110
|
+
return false;
|
|
1111
|
+
}
|
|
1112
|
+
return true;
|
|
1113
|
+
}
|
|
1014
1114
|
|
|
1015
|
-
class
|
|
1115
|
+
class FormLinkClickObserver {
|
|
1016
1116
|
constructor(delegate, element) {
|
|
1017
1117
|
this.delegate = delegate;
|
|
1018
|
-
this.
|
|
1118
|
+
this.linkClickObserver = new LinkClickObserver(this, element);
|
|
1019
1119
|
}
|
|
1020
1120
|
start() {
|
|
1021
|
-
this.
|
|
1121
|
+
this.linkClickObserver.start();
|
|
1022
1122
|
}
|
|
1023
1123
|
stop() {
|
|
1024
|
-
this.
|
|
1124
|
+
this.linkClickObserver.stop();
|
|
1025
1125
|
}
|
|
1026
|
-
|
|
1027
|
-
return (this.delegate.
|
|
1028
|
-
|
|
1126
|
+
willFollowLinkToLocation(link, location, originalEvent) {
|
|
1127
|
+
return (this.delegate.willSubmitFormLinkToLocation(link, location, originalEvent) &&
|
|
1128
|
+
link.hasAttribute("data-turbo-method"));
|
|
1029
1129
|
}
|
|
1030
|
-
|
|
1130
|
+
followedLinkToLocation(link, location) {
|
|
1131
|
+
const action = location.href;
|
|
1031
1132
|
const form = document.createElement("form");
|
|
1032
1133
|
form.setAttribute("data-turbo", "true");
|
|
1033
1134
|
form.setAttribute("action", action);
|
|
@@ -1044,7 +1145,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1044
1145
|
const turboStream = link.hasAttribute("data-turbo-stream");
|
|
1045
1146
|
if (turboStream)
|
|
1046
1147
|
form.setAttribute("data-turbo-stream", "");
|
|
1047
|
-
this.delegate.
|
|
1148
|
+
this.delegate.submittedFormLinkToLocation(link, location, form);
|
|
1048
1149
|
document.body.appendChild(form);
|
|
1049
1150
|
form.requestSubmit();
|
|
1050
1151
|
form.remove();
|
|
@@ -1128,21 +1229,6 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1128
1229
|
delete this.resolvingFunctions;
|
|
1129
1230
|
}
|
|
1130
1231
|
}
|
|
1131
|
-
createScriptElement(element) {
|
|
1132
|
-
if (element.getAttribute("data-turbo-eval") == "false") {
|
|
1133
|
-
return element;
|
|
1134
|
-
}
|
|
1135
|
-
else {
|
|
1136
|
-
const createdScriptElement = document.createElement("script");
|
|
1137
|
-
if (this.cspNonce) {
|
|
1138
|
-
createdScriptElement.nonce = this.cspNonce;
|
|
1139
|
-
}
|
|
1140
|
-
createdScriptElement.textContent = element.textContent;
|
|
1141
|
-
createdScriptElement.async = false;
|
|
1142
|
-
copyElementAttributes(createdScriptElement, element);
|
|
1143
|
-
return createdScriptElement;
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
1232
|
preservingPermanentElements(callback) {
|
|
1147
1233
|
Bardo.preservingPermanentElements(this, this.permanentElementMap, callback);
|
|
1148
1234
|
}
|
|
@@ -1177,14 +1263,6 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1177
1263
|
get permanentElementMap() {
|
|
1178
1264
|
return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot);
|
|
1179
1265
|
}
|
|
1180
|
-
get cspNonce() {
|
|
1181
|
-
return getMetaContent("csp-nonce");
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
function copyElementAttributes(destinationElement, sourceElement) {
|
|
1185
|
-
for (const { name, value } of [...sourceElement.attributes]) {
|
|
1186
|
-
destinationElement.setAttribute(name, value);
|
|
1187
|
-
}
|
|
1188
1266
|
}
|
|
1189
1267
|
function elementIsFocusable(element) {
|
|
1190
1268
|
return element && typeof element.focus == "function";
|
|
@@ -1222,7 +1300,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1222
1300
|
this.activateScriptElements();
|
|
1223
1301
|
}
|
|
1224
1302
|
loadFrameElement() {
|
|
1225
|
-
this.delegate.
|
|
1303
|
+
this.delegate.willRenderFrame(this.currentElement, this.newElement);
|
|
1226
1304
|
this.renderElement(this.currentElement, this.newElement);
|
|
1227
1305
|
}
|
|
1228
1306
|
scrollFrameIntoView() {
|
|
@@ -1239,7 +1317,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1239
1317
|
}
|
|
1240
1318
|
activateScriptElements() {
|
|
1241
1319
|
for (const inertScriptElement of this.newScriptElements) {
|
|
1242
|
-
const activatedScriptElement =
|
|
1320
|
+
const activatedScriptElement = activateScriptElement(inertScriptElement);
|
|
1243
1321
|
inertScriptElement.replaceWith(activatedScriptElement);
|
|
1244
1322
|
}
|
|
1245
1323
|
}
|
|
@@ -1525,6 +1603,9 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1525
1603
|
historyChanged: false,
|
|
1526
1604
|
visitCachedSnapshot: () => { },
|
|
1527
1605
|
willRender: true,
|
|
1606
|
+
updateHistory: true,
|
|
1607
|
+
shouldCacheSnapshot: true,
|
|
1608
|
+
acceptsStreamResponse: false,
|
|
1528
1609
|
};
|
|
1529
1610
|
var SystemStatusCode;
|
|
1530
1611
|
(function (SystemStatusCode) {
|
|
@@ -1539,12 +1620,15 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1539
1620
|
this.followedRedirect = false;
|
|
1540
1621
|
this.historyChanged = false;
|
|
1541
1622
|
this.scrolled = false;
|
|
1623
|
+
this.shouldCacheSnapshot = true;
|
|
1624
|
+
this.acceptsStreamResponse = false;
|
|
1542
1625
|
this.snapshotCached = false;
|
|
1543
1626
|
this.state = VisitState.initialized;
|
|
1544
1627
|
this.delegate = delegate;
|
|
1545
1628
|
this.location = location;
|
|
1546
1629
|
this.restorationIdentifier = restorationIdentifier || uuid();
|
|
1547
|
-
|
|
1630
|
+
this.promise = new Promise((resolve, reject) => (this.resolvingFunctions = { resolve, reject }));
|
|
1631
|
+
const { action, historyChanged, referrer, snapshotHTML, response, visitCachedSnapshot, willRender, updateHistory, shouldCacheSnapshot, acceptsStreamResponse, } = Object.assign(Object.assign({}, defaultOptions), options);
|
|
1548
1632
|
this.action = action;
|
|
1549
1633
|
this.historyChanged = historyChanged;
|
|
1550
1634
|
this.referrer = referrer;
|
|
@@ -1553,7 +1637,10 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1553
1637
|
this.isSamePage = this.delegate.locationWithActionIsSamePage(this.location, this.action);
|
|
1554
1638
|
this.visitCachedSnapshot = visitCachedSnapshot;
|
|
1555
1639
|
this.willRender = willRender;
|
|
1640
|
+
this.updateHistory = updateHistory;
|
|
1556
1641
|
this.scrolled = !willRender;
|
|
1642
|
+
this.shouldCacheSnapshot = shouldCacheSnapshot;
|
|
1643
|
+
this.acceptsStreamResponse = acceptsStreamResponse;
|
|
1557
1644
|
}
|
|
1558
1645
|
get adapter() {
|
|
1559
1646
|
return this.delegate.adapter;
|
|
@@ -1585,6 +1672,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1585
1672
|
}
|
|
1586
1673
|
this.cancelRender();
|
|
1587
1674
|
this.state = VisitState.canceled;
|
|
1675
|
+
this.resolvingFunctions.reject();
|
|
1588
1676
|
}
|
|
1589
1677
|
}
|
|
1590
1678
|
complete() {
|
|
@@ -1596,19 +1684,21 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1596
1684
|
this.adapter.visitCompleted(this);
|
|
1597
1685
|
this.delegate.visitCompleted(this);
|
|
1598
1686
|
}
|
|
1687
|
+
this.resolvingFunctions.resolve();
|
|
1599
1688
|
}
|
|
1600
1689
|
}
|
|
1601
1690
|
fail() {
|
|
1602
1691
|
if (this.state == VisitState.started) {
|
|
1603
1692
|
this.state = VisitState.failed;
|
|
1604
1693
|
this.adapter.visitFailed(this);
|
|
1694
|
+
this.resolvingFunctions.reject();
|
|
1605
1695
|
}
|
|
1606
1696
|
}
|
|
1607
1697
|
changeHistory() {
|
|
1608
1698
|
var _a;
|
|
1609
|
-
if (!this.historyChanged) {
|
|
1699
|
+
if (!this.historyChanged && this.updateHistory) {
|
|
1610
1700
|
const actionForHistory = this.location.href === ((_a = this.referrer) === null || _a === void 0 ? void 0 : _a.href) ? "replace" : this.action;
|
|
1611
|
-
const method =
|
|
1701
|
+
const method = getHistoryMethodForAction(actionForHistory);
|
|
1612
1702
|
this.history.update(method, this.location, this.restorationIdentifier);
|
|
1613
1703
|
this.historyChanged = true;
|
|
1614
1704
|
}
|
|
@@ -1653,11 +1743,13 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1653
1743
|
if (this.response) {
|
|
1654
1744
|
const { statusCode, responseHTML } = this.response;
|
|
1655
1745
|
this.render(async () => {
|
|
1656
|
-
this.
|
|
1746
|
+
if (this.shouldCacheSnapshot)
|
|
1747
|
+
this.cacheSnapshot();
|
|
1657
1748
|
if (this.view.renderPromise)
|
|
1658
1749
|
await this.view.renderPromise;
|
|
1659
1750
|
if (isSuccessful(statusCode) && responseHTML != null) {
|
|
1660
1751
|
await this.view.renderPage(PageSnapshot.fromHTMLString(responseHTML), false, this.willRender, this);
|
|
1752
|
+
this.performScroll();
|
|
1661
1753
|
this.adapter.visitRendered(this);
|
|
1662
1754
|
this.complete();
|
|
1663
1755
|
}
|
|
@@ -1698,6 +1790,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1698
1790
|
if (this.view.renderPromise)
|
|
1699
1791
|
await this.view.renderPromise;
|
|
1700
1792
|
await this.view.renderPage(snapshot, isPreview, this.willRender, this);
|
|
1793
|
+
this.performScroll();
|
|
1701
1794
|
this.adapter.visitRendered(this);
|
|
1702
1795
|
if (!isPreview) {
|
|
1703
1796
|
this.complete();
|
|
@@ -1721,10 +1814,16 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1721
1814
|
if (this.isSamePage) {
|
|
1722
1815
|
this.render(async () => {
|
|
1723
1816
|
this.cacheSnapshot();
|
|
1817
|
+
this.performScroll();
|
|
1724
1818
|
this.adapter.visitRendered(this);
|
|
1725
1819
|
});
|
|
1726
1820
|
}
|
|
1727
1821
|
}
|
|
1822
|
+
prepareHeadersForRequest(headers, request) {
|
|
1823
|
+
if (this.acceptsStreamResponse) {
|
|
1824
|
+
request.acceptResponseType(StreamMessage.contentType);
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1728
1827
|
requestStarted() {
|
|
1729
1828
|
this.startRequest();
|
|
1730
1829
|
}
|
|
@@ -1766,7 +1865,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1766
1865
|
this.finishRequest();
|
|
1767
1866
|
}
|
|
1768
1867
|
performScroll() {
|
|
1769
|
-
if (!this.scrolled) {
|
|
1868
|
+
if (!this.scrolled && !this.view.forceReloaded) {
|
|
1770
1869
|
if (this.action == "restore") {
|
|
1771
1870
|
this.scrollToRestoredPosition() || this.scrollToAnchor() || this.view.scrollToTop();
|
|
1772
1871
|
}
|
|
@@ -1835,9 +1934,6 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1835
1934
|
});
|
|
1836
1935
|
await callback();
|
|
1837
1936
|
delete this.frame;
|
|
1838
|
-
if (!this.view.forceReloaded) {
|
|
1839
|
-
this.performScroll();
|
|
1840
|
-
}
|
|
1841
1937
|
}
|
|
1842
1938
|
cancelRender() {
|
|
1843
1939
|
if (this.frame) {
|
|
@@ -1859,7 +1955,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1859
1955
|
this.session = session;
|
|
1860
1956
|
}
|
|
1861
1957
|
visitProposedToLocation(location, options) {
|
|
1862
|
-
this.navigator.startVisit(location, uuid(), options);
|
|
1958
|
+
return this.navigator.startVisit(location, (options === null || options === void 0 ? void 0 : options.restorationIdentifier) || uuid(), options);
|
|
1863
1959
|
}
|
|
1864
1960
|
visitStarted(visit) {
|
|
1865
1961
|
this.location = visit.location;
|
|
@@ -1969,84 +2065,39 @@ Copyright © 2022 Basecamp, LLC
|
|
|
1969
2065
|
}
|
|
1970
2066
|
}
|
|
1971
2067
|
|
|
1972
|
-
class FormSubmitObserver {
|
|
1973
|
-
constructor(delegate) {
|
|
1974
|
-
this.started = false;
|
|
1975
|
-
this.submitCaptured = () => {
|
|
1976
|
-
removeEventListener("submit", this.submitBubbled, false);
|
|
1977
|
-
addEventListener("submit", this.submitBubbled, false);
|
|
1978
|
-
};
|
|
1979
|
-
this.submitBubbled = ((event) => {
|
|
1980
|
-
if (!event.defaultPrevented) {
|
|
1981
|
-
const form = event.target instanceof HTMLFormElement ? event.target : undefined;
|
|
1982
|
-
const submitter = event.submitter || undefined;
|
|
1983
|
-
if (form &&
|
|
1984
|
-
submissionDoesNotDismissDialog(form, submitter) &&
|
|
1985
|
-
submissionDoesNotTargetIFrame(form, submitter) &&
|
|
1986
|
-
this.delegate.willSubmitForm(form, submitter)) {
|
|
1987
|
-
event.preventDefault();
|
|
1988
|
-
this.delegate.formSubmitted(form, submitter);
|
|
1989
|
-
}
|
|
1990
|
-
}
|
|
1991
|
-
});
|
|
1992
|
-
this.delegate = delegate;
|
|
1993
|
-
}
|
|
1994
|
-
start() {
|
|
1995
|
-
if (!this.started) {
|
|
1996
|
-
addEventListener("submit", this.submitCaptured, true);
|
|
1997
|
-
this.started = true;
|
|
1998
|
-
}
|
|
1999
|
-
}
|
|
2000
|
-
stop() {
|
|
2001
|
-
if (this.started) {
|
|
2002
|
-
removeEventListener("submit", this.submitCaptured, true);
|
|
2003
|
-
this.started = false;
|
|
2004
|
-
}
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
|
-
function submissionDoesNotDismissDialog(form, submitter) {
|
|
2008
|
-
const method = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formmethod")) || form.getAttribute("method");
|
|
2009
|
-
return method != "dialog";
|
|
2010
|
-
}
|
|
2011
|
-
function submissionDoesNotTargetIFrame(form, submitter) {
|
|
2012
|
-
const target = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formtarget")) || form.target;
|
|
2013
|
-
for (const element of document.getElementsByName(target)) {
|
|
2014
|
-
if (element instanceof HTMLIFrameElement)
|
|
2015
|
-
return false;
|
|
2016
|
-
}
|
|
2017
|
-
return true;
|
|
2018
|
-
}
|
|
2019
|
-
|
|
2020
2068
|
class FrameRedirector {
|
|
2021
|
-
constructor(element) {
|
|
2069
|
+
constructor(session, element) {
|
|
2070
|
+
this.session = session;
|
|
2022
2071
|
this.element = element;
|
|
2023
|
-
this.
|
|
2024
|
-
this.
|
|
2072
|
+
this.linkClickObserver = new LinkClickObserver(this, element);
|
|
2073
|
+
this.formSubmitObserver = new FormSubmitObserver(this, element);
|
|
2025
2074
|
}
|
|
2026
2075
|
start() {
|
|
2027
|
-
this.
|
|
2028
|
-
this.
|
|
2076
|
+
this.linkClickObserver.start();
|
|
2077
|
+
this.formSubmitObserver.start();
|
|
2029
2078
|
}
|
|
2030
2079
|
stop() {
|
|
2031
|
-
this.
|
|
2032
|
-
this.
|
|
2080
|
+
this.linkClickObserver.stop();
|
|
2081
|
+
this.formSubmitObserver.stop();
|
|
2033
2082
|
}
|
|
2034
|
-
|
|
2083
|
+
willFollowLinkToLocation(element) {
|
|
2035
2084
|
return this.shouldRedirect(element);
|
|
2036
2085
|
}
|
|
2037
|
-
|
|
2086
|
+
followedLinkToLocation(element, url) {
|
|
2038
2087
|
const frame = this.findFrameElement(element);
|
|
2039
2088
|
if (frame) {
|
|
2040
|
-
frame.delegate.
|
|
2089
|
+
frame.delegate.followedLinkToLocation(element, url);
|
|
2041
2090
|
}
|
|
2042
2091
|
}
|
|
2043
|
-
|
|
2044
|
-
return
|
|
2092
|
+
willSubmitForm(element, submitter) {
|
|
2093
|
+
return (element.closest("turbo-frame") == null &&
|
|
2094
|
+
this.shouldSubmit(element, submitter) &&
|
|
2095
|
+
this.shouldRedirect(element, submitter));
|
|
2045
2096
|
}
|
|
2046
|
-
|
|
2097
|
+
formSubmitted(element, submitter) {
|
|
2047
2098
|
const frame = this.findFrameElement(element, submitter);
|
|
2048
2099
|
if (frame) {
|
|
2049
|
-
frame.delegate.
|
|
2100
|
+
frame.delegate.formSubmitted(element, submitter);
|
|
2050
2101
|
}
|
|
2051
2102
|
}
|
|
2052
2103
|
shouldSubmit(form, submitter) {
|
|
@@ -2057,8 +2108,16 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2057
2108
|
return this.shouldRedirect(form, submitter) && locationIsVisitable(action, rootLocation);
|
|
2058
2109
|
}
|
|
2059
2110
|
shouldRedirect(element, submitter) {
|
|
2060
|
-
const
|
|
2061
|
-
|
|
2111
|
+
const isNavigatable = element instanceof HTMLFormElement
|
|
2112
|
+
? this.session.submissionIsNavigatable(element, submitter)
|
|
2113
|
+
: this.session.elementIsNavigatable(element);
|
|
2114
|
+
if (isNavigatable) {
|
|
2115
|
+
const frame = this.findFrameElement(element, submitter);
|
|
2116
|
+
return frame ? frame != element.closest("turbo-frame") : false;
|
|
2117
|
+
}
|
|
2118
|
+
else {
|
|
2119
|
+
return false;
|
|
2120
|
+
}
|
|
2062
2121
|
}
|
|
2063
2122
|
findFrameElement(element, submitter) {
|
|
2064
2123
|
const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("data-turbo-frame")) || element.getAttribute("data-turbo-frame");
|
|
@@ -2150,70 +2209,6 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2150
2209
|
}
|
|
2151
2210
|
}
|
|
2152
2211
|
|
|
2153
|
-
class LinkClickObserver {
|
|
2154
|
-
constructor(delegate) {
|
|
2155
|
-
this.started = false;
|
|
2156
|
-
this.clickCaptured = () => {
|
|
2157
|
-
removeEventListener("click", this.clickBubbled, false);
|
|
2158
|
-
addEventListener("click", this.clickBubbled, false);
|
|
2159
|
-
};
|
|
2160
|
-
this.clickBubbled = (event) => {
|
|
2161
|
-
if (this.clickEventIsSignificant(event)) {
|
|
2162
|
-
const target = (event.composedPath && event.composedPath()[0]) || event.target;
|
|
2163
|
-
const link = this.findLinkFromClickTarget(target);
|
|
2164
|
-
if (link && doesNotTargetIFrame(link)) {
|
|
2165
|
-
const location = this.getLocationForLink(link);
|
|
2166
|
-
if (this.delegate.willFollowLinkToLocation(link, location, event)) {
|
|
2167
|
-
event.preventDefault();
|
|
2168
|
-
this.delegate.followedLinkToLocation(link, location);
|
|
2169
|
-
}
|
|
2170
|
-
}
|
|
2171
|
-
}
|
|
2172
|
-
};
|
|
2173
|
-
this.delegate = delegate;
|
|
2174
|
-
}
|
|
2175
|
-
start() {
|
|
2176
|
-
if (!this.started) {
|
|
2177
|
-
addEventListener("click", this.clickCaptured, true);
|
|
2178
|
-
this.started = true;
|
|
2179
|
-
}
|
|
2180
|
-
}
|
|
2181
|
-
stop() {
|
|
2182
|
-
if (this.started) {
|
|
2183
|
-
removeEventListener("click", this.clickCaptured, true);
|
|
2184
|
-
this.started = false;
|
|
2185
|
-
}
|
|
2186
|
-
}
|
|
2187
|
-
clickEventIsSignificant(event) {
|
|
2188
|
-
return !((event.target && event.target.isContentEditable) ||
|
|
2189
|
-
event.defaultPrevented ||
|
|
2190
|
-
event.which > 1 ||
|
|
2191
|
-
event.altKey ||
|
|
2192
|
-
event.ctrlKey ||
|
|
2193
|
-
event.metaKey ||
|
|
2194
|
-
event.shiftKey);
|
|
2195
|
-
}
|
|
2196
|
-
findLinkFromClickTarget(target) {
|
|
2197
|
-
if (target instanceof Element) {
|
|
2198
|
-
return target.closest("a[href]:not([target^=_]):not([download])");
|
|
2199
|
-
}
|
|
2200
|
-
}
|
|
2201
|
-
getLocationForLink(link) {
|
|
2202
|
-
return expandURL(link.getAttribute("href") || "");
|
|
2203
|
-
}
|
|
2204
|
-
}
|
|
2205
|
-
function doesNotTargetIFrame(anchor) {
|
|
2206
|
-
for (const element of document.getElementsByName(anchor.target)) {
|
|
2207
|
-
if (element instanceof HTMLIFrameElement)
|
|
2208
|
-
return false;
|
|
2209
|
-
}
|
|
2210
|
-
return true;
|
|
2211
|
-
}
|
|
2212
|
-
|
|
2213
|
-
function isAction(action) {
|
|
2214
|
-
return action == "advance" || action == "replace" || action == "restore";
|
|
2215
|
-
}
|
|
2216
|
-
|
|
2217
2212
|
class Navigator {
|
|
2218
2213
|
constructor(delegate) {
|
|
2219
2214
|
this.delegate = delegate;
|
|
@@ -2221,18 +2216,23 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2221
2216
|
proposeVisit(location, options = {}) {
|
|
2222
2217
|
if (this.delegate.allowsVisitingLocationWithAction(location, options.action)) {
|
|
2223
2218
|
if (locationIsVisitable(location, this.view.snapshot.rootLocation)) {
|
|
2224
|
-
this.delegate.visitProposedToLocation(location, options);
|
|
2219
|
+
return this.delegate.visitProposedToLocation(location, options);
|
|
2225
2220
|
}
|
|
2226
2221
|
else {
|
|
2227
2222
|
window.location.href = location.toString();
|
|
2223
|
+
return Promise.resolve();
|
|
2228
2224
|
}
|
|
2229
2225
|
}
|
|
2226
|
+
else {
|
|
2227
|
+
return Promise.reject();
|
|
2228
|
+
}
|
|
2230
2229
|
}
|
|
2231
2230
|
startVisit(locatable, restorationIdentifier, options = {}) {
|
|
2232
2231
|
this.lastVisit = this.currentVisit;
|
|
2233
2232
|
this.stop();
|
|
2234
2233
|
this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, Object.assign({ referrer: this.location }, options));
|
|
2235
2234
|
this.currentVisit.start();
|
|
2235
|
+
return this.currentVisit.promise;
|
|
2236
2236
|
}
|
|
2237
2237
|
submitForm(form, submitter) {
|
|
2238
2238
|
this.stop();
|
|
@@ -2267,13 +2267,15 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2267
2267
|
if (formSubmission == this.formSubmission) {
|
|
2268
2268
|
const responseHTML = await fetchResponse.responseHTML;
|
|
2269
2269
|
if (responseHTML) {
|
|
2270
|
-
|
|
2270
|
+
const shouldCacheSnapshot = formSubmission.method == FetchMethod.get;
|
|
2271
|
+
if (!shouldCacheSnapshot) {
|
|
2271
2272
|
this.view.clearSnapshotCache();
|
|
2272
2273
|
}
|
|
2273
2274
|
const { statusCode, redirected } = fetchResponse;
|
|
2274
2275
|
const action = this.getActionForFormSubmission(formSubmission);
|
|
2275
2276
|
const visitOptions = {
|
|
2276
2277
|
action,
|
|
2278
|
+
shouldCacheSnapshot,
|
|
2277
2279
|
response: { statusCode, responseHTML, redirected },
|
|
2278
2280
|
};
|
|
2279
2281
|
this.proposeVisit(fetchResponse.location, visitOptions);
|
|
@@ -2472,7 +2474,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2472
2474
|
}
|
|
2473
2475
|
}
|
|
2474
2476
|
receiveMessageHTML(html) {
|
|
2475
|
-
this.delegate.receivedMessageFromStream(
|
|
2477
|
+
this.delegate.receivedMessageFromStream(StreamMessage.wrap(html));
|
|
2476
2478
|
}
|
|
2477
2479
|
}
|
|
2478
2480
|
function fetchResponseFromEvent(event) {
|
|
@@ -2506,7 +2508,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2506
2508
|
for (const replaceableElement of this.scriptElements) {
|
|
2507
2509
|
const parentNode = replaceableElement.parentNode;
|
|
2508
2510
|
if (parentNode) {
|
|
2509
|
-
const element =
|
|
2511
|
+
const element = activateScriptElement(replaceableElement);
|
|
2510
2512
|
parentNode.replaceChild(element, replaceableElement);
|
|
2511
2513
|
}
|
|
2512
2514
|
}
|
|
@@ -2515,7 +2517,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2515
2517
|
return this.newSnapshot.headSnapshot.element;
|
|
2516
2518
|
}
|
|
2517
2519
|
get scriptElements() {
|
|
2518
|
-
return
|
|
2520
|
+
return document.documentElement.querySelectorAll("script");
|
|
2519
2521
|
}
|
|
2520
2522
|
}
|
|
2521
2523
|
|
|
@@ -2543,8 +2545,8 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2543
2545
|
};
|
|
2544
2546
|
}
|
|
2545
2547
|
}
|
|
2546
|
-
prepareToRender() {
|
|
2547
|
-
this.mergeHead();
|
|
2548
|
+
async prepareToRender() {
|
|
2549
|
+
await this.mergeHead();
|
|
2548
2550
|
}
|
|
2549
2551
|
async render() {
|
|
2550
2552
|
if (this.willRender) {
|
|
@@ -2566,11 +2568,12 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2566
2568
|
get newElement() {
|
|
2567
2569
|
return this.newSnapshot.element;
|
|
2568
2570
|
}
|
|
2569
|
-
mergeHead() {
|
|
2570
|
-
this.copyNewHeadStylesheetElements();
|
|
2571
|
+
async mergeHead() {
|
|
2572
|
+
const newStylesheetElements = this.copyNewHeadStylesheetElements();
|
|
2571
2573
|
this.copyNewHeadScriptElements();
|
|
2572
2574
|
this.removeCurrentHeadProvisionalElements();
|
|
2573
2575
|
this.copyNewHeadProvisionalElements();
|
|
2576
|
+
await newStylesheetElements;
|
|
2574
2577
|
}
|
|
2575
2578
|
replaceBody() {
|
|
2576
2579
|
this.preservingPermanentElements(() => {
|
|
@@ -2581,14 +2584,17 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2581
2584
|
get trackedElementsAreIdentical() {
|
|
2582
2585
|
return this.currentHeadSnapshot.trackedElementSignature == this.newHeadSnapshot.trackedElementSignature;
|
|
2583
2586
|
}
|
|
2584
|
-
copyNewHeadStylesheetElements() {
|
|
2587
|
+
async copyNewHeadStylesheetElements() {
|
|
2588
|
+
const loadingElements = [];
|
|
2585
2589
|
for (const element of this.newHeadStylesheetElements) {
|
|
2590
|
+
loadingElements.push(waitForLoad(element));
|
|
2586
2591
|
document.head.appendChild(element);
|
|
2587
2592
|
}
|
|
2593
|
+
await Promise.all(loadingElements);
|
|
2588
2594
|
}
|
|
2589
2595
|
copyNewHeadScriptElements() {
|
|
2590
2596
|
for (const element of this.newHeadScriptElements) {
|
|
2591
|
-
document.head.appendChild(
|
|
2597
|
+
document.head.appendChild(activateScriptElement(element));
|
|
2592
2598
|
}
|
|
2593
2599
|
}
|
|
2594
2600
|
removeCurrentHeadProvisionalElements() {
|
|
@@ -2607,7 +2613,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2607
2613
|
}
|
|
2608
2614
|
activateNewBodyScriptElements() {
|
|
2609
2615
|
for (const inertScriptElement of this.newBodyScriptElements) {
|
|
2610
|
-
const activatedScriptElement =
|
|
2616
|
+
const activatedScriptElement = activateScriptElement(inertScriptElement);
|
|
2611
2617
|
inertScriptElement.replaceWith(activatedScriptElement);
|
|
2612
2618
|
}
|
|
2613
2619
|
}
|
|
@@ -2770,12 +2776,12 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2770
2776
|
this.adapter = new BrowserAdapter(this);
|
|
2771
2777
|
this.pageObserver = new PageObserver(this);
|
|
2772
2778
|
this.cacheObserver = new CacheObserver();
|
|
2773
|
-
this.linkClickObserver = new LinkClickObserver(this);
|
|
2774
|
-
this.formSubmitObserver = new FormSubmitObserver(this);
|
|
2779
|
+
this.linkClickObserver = new LinkClickObserver(this, window);
|
|
2780
|
+
this.formSubmitObserver = new FormSubmitObserver(this, document);
|
|
2775
2781
|
this.scrollObserver = new ScrollObserver(this);
|
|
2776
2782
|
this.streamObserver = new StreamObserver(this);
|
|
2777
|
-
this.
|
|
2778
|
-
this.frameRedirector = new FrameRedirector(document.documentElement);
|
|
2783
|
+
this.formLinkClickObserver = new FormLinkClickObserver(this, document.documentElement);
|
|
2784
|
+
this.frameRedirector = new FrameRedirector(this, document.documentElement);
|
|
2779
2785
|
this.drive = true;
|
|
2780
2786
|
this.enabled = true;
|
|
2781
2787
|
this.progressBarDelay = 500;
|
|
@@ -2786,7 +2792,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2786
2792
|
if (!this.started) {
|
|
2787
2793
|
this.pageObserver.start();
|
|
2788
2794
|
this.cacheObserver.start();
|
|
2789
|
-
this.
|
|
2795
|
+
this.formLinkClickObserver.start();
|
|
2790
2796
|
this.linkClickObserver.start();
|
|
2791
2797
|
this.formSubmitObserver.start();
|
|
2792
2798
|
this.scrollObserver.start();
|
|
@@ -2805,7 +2811,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2805
2811
|
if (this.started) {
|
|
2806
2812
|
this.pageObserver.stop();
|
|
2807
2813
|
this.cacheObserver.stop();
|
|
2808
|
-
this.
|
|
2814
|
+
this.formLinkClickObserver.stop();
|
|
2809
2815
|
this.linkClickObserver.stop();
|
|
2810
2816
|
this.formSubmitObserver.stop();
|
|
2811
2817
|
this.scrollObserver.stop();
|
|
@@ -2819,7 +2825,14 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2819
2825
|
this.adapter = adapter;
|
|
2820
2826
|
}
|
|
2821
2827
|
visit(location, options = {}) {
|
|
2822
|
-
|
|
2828
|
+
const frameElement = document.getElementById(options.frame || "");
|
|
2829
|
+
if (frameElement instanceof FrameElement) {
|
|
2830
|
+
frameElement.src = location.toString();
|
|
2831
|
+
return frameElement.loaded;
|
|
2832
|
+
}
|
|
2833
|
+
else {
|
|
2834
|
+
return this.navigator.proposeVisit(expandURL(location), options);
|
|
2835
|
+
}
|
|
2823
2836
|
}
|
|
2824
2837
|
connectStreamSource(source) {
|
|
2825
2838
|
this.streamObserver.connectStreamSource(source);
|
|
@@ -2861,25 +2874,26 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2861
2874
|
scrollPositionChanged(position) {
|
|
2862
2875
|
this.history.updateRestorationData({ scrollPosition: position });
|
|
2863
2876
|
}
|
|
2864
|
-
|
|
2865
|
-
return
|
|
2877
|
+
willSubmitFormLinkToLocation(link, location) {
|
|
2878
|
+
return this.elementIsNavigatable(link) && locationIsVisitable(location, this.snapshot.rootLocation);
|
|
2866
2879
|
}
|
|
2867
|
-
|
|
2880
|
+
submittedFormLinkToLocation() { }
|
|
2868
2881
|
willFollowLinkToLocation(link, location, event) {
|
|
2869
|
-
return (this.
|
|
2882
|
+
return (this.elementIsNavigatable(link) &&
|
|
2870
2883
|
locationIsVisitable(location, this.snapshot.rootLocation) &&
|
|
2871
2884
|
this.applicationAllowsFollowingLinkToLocation(link, location, event));
|
|
2872
2885
|
}
|
|
2873
2886
|
followedLinkToLocation(link, location) {
|
|
2874
2887
|
const action = this.getActionForLink(link);
|
|
2875
|
-
|
|
2888
|
+
const acceptsStreamResponse = link.hasAttribute("data-turbo-stream");
|
|
2889
|
+
this.visit(location.href, { action, acceptsStreamResponse });
|
|
2876
2890
|
}
|
|
2877
2891
|
allowsVisitingLocationWithAction(location, action) {
|
|
2878
2892
|
return this.locationWithActionIsSamePage(location, action) || this.applicationAllowsVisitingLocation(location);
|
|
2879
2893
|
}
|
|
2880
2894
|
visitProposedToLocation(location, options) {
|
|
2881
2895
|
extendURLWithDeprecatedProperties(location);
|
|
2882
|
-
this.adapter.visitProposedToLocation(location, options);
|
|
2896
|
+
return this.adapter.visitProposedToLocation(location, options);
|
|
2883
2897
|
}
|
|
2884
2898
|
visitStarted(visit) {
|
|
2885
2899
|
extendURLWithDeprecatedProperties(visit.location);
|
|
@@ -2898,8 +2912,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2898
2912
|
}
|
|
2899
2913
|
willSubmitForm(form, submitter) {
|
|
2900
2914
|
const action = getAction(form, submitter);
|
|
2901
|
-
return (this.
|
|
2902
|
-
(!submitter || this.formElementDriveEnabled(submitter)) &&
|
|
2915
|
+
return (this.submissionIsNavigatable(form, submitter) &&
|
|
2903
2916
|
locationIsVisitable(expandURL(action), this.snapshot.rootLocation));
|
|
2904
2917
|
}
|
|
2905
2918
|
formSubmitted(form, submitter) {
|
|
@@ -2948,6 +2961,10 @@ Copyright © 2022 Basecamp, LLC
|
|
|
2948
2961
|
frameRendered(fetchResponse, frame) {
|
|
2949
2962
|
this.notifyApplicationAfterFrameRender(fetchResponse, frame);
|
|
2950
2963
|
}
|
|
2964
|
+
frameMissing(frame, fetchResponse) {
|
|
2965
|
+
console.warn(`Completing full-page visit as matching frame for #${frame.id} was missing from the response`);
|
|
2966
|
+
return this.visit(fetchResponse.location);
|
|
2967
|
+
}
|
|
2951
2968
|
applicationAllowsFollowingLinkToLocation(link, location, ev) {
|
|
2952
2969
|
const event = this.notifyApplicationAfterClickingLinkToLocation(link, location, ev);
|
|
2953
2970
|
return !event.defaultPrevented;
|
|
@@ -3007,19 +3024,24 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3007
3024
|
cancelable: true,
|
|
3008
3025
|
});
|
|
3009
3026
|
}
|
|
3010
|
-
|
|
3027
|
+
submissionIsNavigatable(form, submitter) {
|
|
3011
3028
|
if (this.formMode == "off") {
|
|
3012
3029
|
return false;
|
|
3013
3030
|
}
|
|
3014
|
-
|
|
3015
|
-
const
|
|
3016
|
-
|
|
3031
|
+
else {
|
|
3032
|
+
const submitterIsNavigatable = submitter ? this.elementIsNavigatable(submitter) : true;
|
|
3033
|
+
if (this.formMode == "optin") {
|
|
3034
|
+
return submitterIsNavigatable && form.closest('[data-turbo="true"]') != null;
|
|
3035
|
+
}
|
|
3036
|
+
else {
|
|
3037
|
+
return submitterIsNavigatable && this.elementIsNavigatable(form);
|
|
3038
|
+
}
|
|
3017
3039
|
}
|
|
3018
|
-
return this.elementDriveEnabled(element);
|
|
3019
3040
|
}
|
|
3020
|
-
|
|
3021
|
-
const container = element
|
|
3022
|
-
|
|
3041
|
+
elementIsNavigatable(element) {
|
|
3042
|
+
const container = element.closest("[data-turbo]");
|
|
3043
|
+
const withinFrame = element.closest("turbo-frame");
|
|
3044
|
+
if (this.drive || withinFrame) {
|
|
3023
3045
|
if (container) {
|
|
3024
3046
|
return container.getAttribute("data-turbo") != "false";
|
|
3025
3047
|
}
|
|
@@ -3112,7 +3134,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3112
3134
|
session.registerAdapter(adapter);
|
|
3113
3135
|
}
|
|
3114
3136
|
function visit(location, options) {
|
|
3115
|
-
session.visit(location, options);
|
|
3137
|
+
return session.visit(location, options);
|
|
3116
3138
|
}
|
|
3117
3139
|
function connectStreamSource(source) {
|
|
3118
3140
|
session.connectStreamSource(source);
|
|
@@ -3166,6 +3188,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3166
3188
|
this.connected = false;
|
|
3167
3189
|
this.hasBeenLoaded = false;
|
|
3168
3190
|
this.ignoredAttributes = new Set();
|
|
3191
|
+
this.action = null;
|
|
3169
3192
|
this.visitCachedSnapshot = ({ element }) => {
|
|
3170
3193
|
const frame = element.querySelector("#" + this.element.id);
|
|
3171
3194
|
if (frame && this.previousFrameElement) {
|
|
@@ -3176,9 +3199,10 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3176
3199
|
this.element = element;
|
|
3177
3200
|
this.view = new FrameView(this, this.element);
|
|
3178
3201
|
this.appearanceObserver = new AppearanceObserver(this, this.element);
|
|
3179
|
-
this.
|
|
3180
|
-
this.
|
|
3181
|
-
this.
|
|
3202
|
+
this.formLinkClickObserver = new FormLinkClickObserver(this, this.element);
|
|
3203
|
+
this.linkClickObserver = new LinkClickObserver(this, this.element);
|
|
3204
|
+
this.restorationIdentifier = uuid();
|
|
3205
|
+
this.formSubmitObserver = new FormSubmitObserver(this, this.element);
|
|
3182
3206
|
}
|
|
3183
3207
|
connect() {
|
|
3184
3208
|
if (!this.connected) {
|
|
@@ -3189,18 +3213,18 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3189
3213
|
else {
|
|
3190
3214
|
this.loadSourceURL();
|
|
3191
3215
|
}
|
|
3192
|
-
this.
|
|
3193
|
-
this.
|
|
3194
|
-
this.
|
|
3216
|
+
this.formLinkClickObserver.start();
|
|
3217
|
+
this.linkClickObserver.start();
|
|
3218
|
+
this.formSubmitObserver.start();
|
|
3195
3219
|
}
|
|
3196
3220
|
}
|
|
3197
3221
|
disconnect() {
|
|
3198
3222
|
if (this.connected) {
|
|
3199
3223
|
this.connected = false;
|
|
3200
3224
|
this.appearanceObserver.stop();
|
|
3201
|
-
this.
|
|
3202
|
-
this.
|
|
3203
|
-
this.
|
|
3225
|
+
this.formLinkClickObserver.stop();
|
|
3226
|
+
this.linkClickObserver.stop();
|
|
3227
|
+
this.formSubmitObserver.stop();
|
|
3204
3228
|
}
|
|
3205
3229
|
}
|
|
3206
3230
|
disabledChanged() {
|
|
@@ -3248,15 +3272,22 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3248
3272
|
const html = await fetchResponse.responseHTML;
|
|
3249
3273
|
if (html) {
|
|
3250
3274
|
const { body } = parseHTMLDocument(html);
|
|
3251
|
-
const
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3275
|
+
const newFrameElement = await this.extractForeignFrameElement(body);
|
|
3276
|
+
if (newFrameElement) {
|
|
3277
|
+
const snapshot = new Snapshot(newFrameElement);
|
|
3278
|
+
const renderer = new FrameRenderer(this, this.view.snapshot, snapshot, FrameRenderer.renderElement, false, false);
|
|
3279
|
+
if (this.view.renderPromise)
|
|
3280
|
+
await this.view.renderPromise;
|
|
3281
|
+
this.changeHistory();
|
|
3282
|
+
await this.view.render(renderer);
|
|
3283
|
+
this.complete = true;
|
|
3284
|
+
session.frameRendered(fetchResponse, this.element);
|
|
3285
|
+
session.frameLoaded(this.element);
|
|
3286
|
+
this.fetchResponseLoaded(fetchResponse);
|
|
3287
|
+
}
|
|
3288
|
+
else if (this.sessionWillHandleMissingFrame(fetchResponse)) {
|
|
3289
|
+
await session.frameMissing(this.element, fetchResponse);
|
|
3290
|
+
}
|
|
3260
3291
|
}
|
|
3261
3292
|
}
|
|
3262
3293
|
catch (error) {
|
|
@@ -3270,24 +3301,24 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3270
3301
|
elementAppearedInViewport(_element) {
|
|
3271
3302
|
this.loadSourceURL();
|
|
3272
3303
|
}
|
|
3273
|
-
|
|
3274
|
-
return this.shouldInterceptNavigation(link);
|
|
3304
|
+
willSubmitFormLinkToLocation(link) {
|
|
3305
|
+
return link.closest("turbo-frame") == this.element && this.shouldInterceptNavigation(link);
|
|
3275
3306
|
}
|
|
3276
|
-
|
|
3307
|
+
submittedFormLinkToLocation(link, _location, form) {
|
|
3277
3308
|
const frame = this.findFrameElement(link);
|
|
3278
3309
|
if (frame)
|
|
3279
3310
|
form.setAttribute("data-turbo-frame", frame.id);
|
|
3280
3311
|
}
|
|
3281
|
-
|
|
3312
|
+
willFollowLinkToLocation(element) {
|
|
3282
3313
|
return this.shouldInterceptNavigation(element);
|
|
3283
3314
|
}
|
|
3284
|
-
|
|
3285
|
-
this.navigateFrame(element,
|
|
3315
|
+
followedLinkToLocation(element, location) {
|
|
3316
|
+
this.navigateFrame(element, location.href);
|
|
3286
3317
|
}
|
|
3287
|
-
|
|
3288
|
-
return this.shouldInterceptNavigation(element, submitter);
|
|
3318
|
+
willSubmitForm(element, submitter) {
|
|
3319
|
+
return element.closest("turbo-frame") == this.element && this.shouldInterceptNavigation(element, submitter);
|
|
3289
3320
|
}
|
|
3290
|
-
|
|
3321
|
+
formSubmitted(element, submitter) {
|
|
3291
3322
|
if (this.formSubmission) {
|
|
3292
3323
|
this.formSubmission.stop();
|
|
3293
3324
|
}
|
|
@@ -3296,8 +3327,12 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3296
3327
|
this.prepareHeadersForRequest(fetchRequest.headers, fetchRequest);
|
|
3297
3328
|
this.formSubmission.start();
|
|
3298
3329
|
}
|
|
3299
|
-
prepareHeadersForRequest(headers,
|
|
3330
|
+
prepareHeadersForRequest(headers, request) {
|
|
3331
|
+
var _a;
|
|
3300
3332
|
headers["Turbo-Frame"] = this.id;
|
|
3333
|
+
if ((_a = this.currentNavigationElement) === null || _a === void 0 ? void 0 : _a.hasAttribute("data-turbo-stream")) {
|
|
3334
|
+
request.acceptResponseType(StreamMessage.contentType);
|
|
3335
|
+
}
|
|
3301
3336
|
}
|
|
3302
3337
|
requestStarted(_request) {
|
|
3303
3338
|
markAsBusy(this.element);
|
|
@@ -3315,6 +3350,10 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3315
3350
|
}
|
|
3316
3351
|
requestErrored(request, error) {
|
|
3317
3352
|
console.error(error);
|
|
3353
|
+
dispatch("turbo:fetch-request-error", {
|
|
3354
|
+
target: this.element,
|
|
3355
|
+
detail: { request, error },
|
|
3356
|
+
});
|
|
3318
3357
|
this.resolveVisitPromise();
|
|
3319
3358
|
}
|
|
3320
3359
|
requestFinished(_request) {
|
|
@@ -3354,8 +3393,8 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3354
3393
|
session.preloadOnLoadLinksForView(element);
|
|
3355
3394
|
}
|
|
3356
3395
|
viewInvalidated() { }
|
|
3357
|
-
|
|
3358
|
-
this.previousFrameElement =
|
|
3396
|
+
willRenderFrame(currentElement, _newElement) {
|
|
3397
|
+
this.previousFrameElement = currentElement.cloneNode(true);
|
|
3359
3398
|
}
|
|
3360
3399
|
async visit(url) {
|
|
3361
3400
|
var _a;
|
|
@@ -3374,27 +3413,49 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3374
3413
|
navigateFrame(element, url, submitter) {
|
|
3375
3414
|
const frame = this.findFrameElement(element, submitter);
|
|
3376
3415
|
this.proposeVisitIfNavigatedWithAction(frame, element, submitter);
|
|
3377
|
-
|
|
3416
|
+
this.withCurrentNavigationElement(element, () => {
|
|
3417
|
+
frame.src = url;
|
|
3418
|
+
});
|
|
3378
3419
|
}
|
|
3379
3420
|
proposeVisitIfNavigatedWithAction(frame, element, submitter) {
|
|
3380
|
-
|
|
3381
|
-
|
|
3421
|
+
this.action = getVisitAction(submitter, element, frame);
|
|
3422
|
+
this.frame = frame;
|
|
3423
|
+
if (isAction(this.action)) {
|
|
3382
3424
|
const { visitCachedSnapshot } = frame.delegate;
|
|
3383
3425
|
frame.delegate.fetchResponseLoaded = (fetchResponse) => {
|
|
3384
3426
|
if (frame.src) {
|
|
3385
3427
|
const { statusCode, redirected } = fetchResponse;
|
|
3386
3428
|
const responseHTML = frame.ownerDocument.documentElement.outerHTML;
|
|
3387
3429
|
const response = { statusCode, redirected, responseHTML };
|
|
3388
|
-
|
|
3389
|
-
action,
|
|
3430
|
+
const options = {
|
|
3390
3431
|
response,
|
|
3391
3432
|
visitCachedSnapshot,
|
|
3392
3433
|
willRender: false,
|
|
3393
|
-
|
|
3434
|
+
updateHistory: false,
|
|
3435
|
+
restorationIdentifier: this.restorationIdentifier,
|
|
3436
|
+
};
|
|
3437
|
+
if (this.action)
|
|
3438
|
+
options.action = this.action;
|
|
3439
|
+
session.visit(frame.src, options);
|
|
3394
3440
|
}
|
|
3395
3441
|
};
|
|
3396
3442
|
}
|
|
3397
3443
|
}
|
|
3444
|
+
changeHistory() {
|
|
3445
|
+
if (this.action && this.frame) {
|
|
3446
|
+
const method = getHistoryMethodForAction(this.action);
|
|
3447
|
+
session.history.update(method, expandURL(this.frame.src || ""), this.restorationIdentifier);
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
sessionWillHandleMissingFrame(fetchResponse) {
|
|
3451
|
+
this.element.setAttribute("complete", "");
|
|
3452
|
+
const event = dispatch("turbo:frame-missing", {
|
|
3453
|
+
target: this.element,
|
|
3454
|
+
detail: { fetchResponse },
|
|
3455
|
+
cancelable: true,
|
|
3456
|
+
});
|
|
3457
|
+
return !event.defaultPrevented;
|
|
3458
|
+
}
|
|
3398
3459
|
findFrameElement(element, submitter) {
|
|
3399
3460
|
var _a;
|
|
3400
3461
|
const id = getAttribute("data-turbo-frame", submitter, element) || this.element.getAttribute("target");
|
|
@@ -3413,12 +3474,12 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3413
3474
|
await element.loaded;
|
|
3414
3475
|
return await this.extractForeignFrameElement(element);
|
|
3415
3476
|
}
|
|
3416
|
-
console.error(`Response has no matching <turbo-frame id="${id}"> element`);
|
|
3417
3477
|
}
|
|
3418
3478
|
catch (error) {
|
|
3419
3479
|
console.error(error);
|
|
3480
|
+
return new FrameElement();
|
|
3420
3481
|
}
|
|
3421
|
-
return
|
|
3482
|
+
return null;
|
|
3422
3483
|
}
|
|
3423
3484
|
formActionIsVisitable(form, submitter) {
|
|
3424
3485
|
const action = getAction(form, submitter);
|
|
@@ -3438,10 +3499,10 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3438
3499
|
return !frameElement.disabled;
|
|
3439
3500
|
}
|
|
3440
3501
|
}
|
|
3441
|
-
if (!session.
|
|
3502
|
+
if (!session.elementIsNavigatable(element)) {
|
|
3442
3503
|
return false;
|
|
3443
3504
|
}
|
|
3444
|
-
if (submitter && !session.
|
|
3505
|
+
if (submitter && !session.elementIsNavigatable(submitter)) {
|
|
3445
3506
|
return false;
|
|
3446
3507
|
}
|
|
3447
3508
|
return true;
|
|
@@ -3498,6 +3559,11 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3498
3559
|
callback();
|
|
3499
3560
|
this.ignoredAttributes.delete(attributeName);
|
|
3500
3561
|
}
|
|
3562
|
+
withCurrentNavigationElement(element, callback) {
|
|
3563
|
+
this.currentNavigationElement = element;
|
|
3564
|
+
callback();
|
|
3565
|
+
delete this.currentNavigationElement;
|
|
3566
|
+
}
|
|
3501
3567
|
}
|
|
3502
3568
|
function getFrameElementById(id) {
|
|
3503
3569
|
if (id != null) {
|
|
@@ -3610,6 +3676,7 @@ Copyright © 2022 Basecamp, LLC
|
|
|
3610
3676
|
return new CustomEvent("turbo:before-stream-render", {
|
|
3611
3677
|
bubbles: true,
|
|
3612
3678
|
cancelable: true,
|
|
3679
|
+
detail: { newStream: this },
|
|
3613
3680
|
});
|
|
3614
3681
|
}
|
|
3615
3682
|
get targetElementsById() {
|