turbo-rails 2.0.0.pre.beta.4 → 2.0.0.pre.rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db9fabf188a1b8db9d4a2f15742cbd342293368ba0bb3d23692fa2f1e922e79d
|
4
|
+
data.tar.gz: 3080cea594ecd3f05d1d80f515c919992f5e1d8afcbc921b656879ddcda76433
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdb2fcb4ed4f3d9b63ff6d965b8fa17a0e3b9e004546289f7a4f10b14da66f5c94ba3d5d6ca4c0e9bcbad7253d2250c47034bd4540d5bc1a962a333591892137
|
7
|
+
data.tar.gz: 37c771f8632419220a3a017c007867926adf12185cd6de833da527990bf8198a383eea645b53cee3ce38ffefc6ac4a25267b215272957e23aac07948d050e1d0
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
Turbo 8.0.0-
|
2
|
+
Turbo 8.0.0-rc.2
|
3
3
|
Copyright © 2024 37signals LLC
|
4
4
|
*/
|
5
5
|
(function(prototype) {
|
@@ -1228,7 +1228,8 @@ class View {
|
|
1228
1228
|
return window;
|
1229
1229
|
}
|
1230
1230
|
async render(renderer) {
|
1231
|
-
const {isPreview: isPreview, shouldRender: shouldRender, newSnapshot: snapshot} = renderer;
|
1231
|
+
const {isPreview: isPreview, shouldRender: shouldRender, willRender: willRender, newSnapshot: snapshot} = renderer;
|
1232
|
+
const shouldInvalidate = willRender;
|
1232
1233
|
if (shouldRender) {
|
1233
1234
|
try {
|
1234
1235
|
this.renderPromise = new Promise((resolve => this.#resolveRenderPromise = resolve));
|
@@ -1237,7 +1238,8 @@ class View {
|
|
1237
1238
|
const renderInterception = new Promise((resolve => this.#resolveInterceptionPromise = resolve));
|
1238
1239
|
const options = {
|
1239
1240
|
resume: this.#resolveInterceptionPromise,
|
1240
|
-
render: this.renderer.renderElement
|
1241
|
+
render: this.renderer.renderElement,
|
1242
|
+
renderMethod: this.renderer.renderMethod
|
1241
1243
|
};
|
1242
1244
|
const immediateRender = this.delegate.allowsImmediateRender(snapshot, options);
|
1243
1245
|
if (!immediateRender) await renderInterception;
|
@@ -1250,7 +1252,7 @@ class View {
|
|
1250
1252
|
this.#resolveRenderPromise(undefined);
|
1251
1253
|
delete this.renderPromise;
|
1252
1254
|
}
|
1253
|
-
} else {
|
1255
|
+
} else if (shouldInvalidate) {
|
1254
1256
|
this.invalidate(renderer.reloadReason);
|
1255
1257
|
}
|
1256
1258
|
}
|
@@ -1965,6 +1967,7 @@ class Visit {
|
|
1965
1967
|
this.snapshotHTML = snapshotHTML;
|
1966
1968
|
this.response = response;
|
1967
1969
|
this.isSamePage = this.delegate.locationWithActionIsSamePage(this.location, this.action);
|
1970
|
+
this.isPageRefresh = this.view.isPageRefresh(this);
|
1968
1971
|
this.visitCachedSnapshot = visitCachedSnapshot;
|
1969
1972
|
this.willRender = willRender;
|
1970
1973
|
this.updateHistory = updateHistory;
|
@@ -2106,7 +2109,7 @@ class Visit {
|
|
2106
2109
|
const isPreview = this.shouldIssueRequest();
|
2107
2110
|
this.render((async () => {
|
2108
2111
|
this.cacheSnapshot();
|
2109
|
-
if (this.isSamePage) {
|
2112
|
+
if (this.isSamePage || this.isPageRefresh) {
|
2110
2113
|
this.adapter.visitRendered(this);
|
2111
2114
|
} else {
|
2112
2115
|
if (this.view.renderPromise) await this.view.renderPromise;
|
@@ -2634,14 +2637,14 @@ class LinkPrefetchObserver {
|
|
2634
2637
|
};
|
2635
2638
|
prepareRequest(request) {
|
2636
2639
|
const link = request.target;
|
2637
|
-
request.headers["Sec-Purpose"] = "prefetch";
|
2640
|
+
request.headers["X-Sec-Purpose"] = "prefetch";
|
2638
2641
|
const turboFrame = link.closest("turbo-frame");
|
2639
2642
|
const turboFrameTarget = link.getAttribute("data-turbo-frame") || turboFrame?.getAttribute("target") || turboFrame?.id;
|
2640
2643
|
if (turboFrameTarget && turboFrameTarget !== "_top") {
|
2641
2644
|
request.headers["Turbo-Frame"] = turboFrameTarget;
|
2642
2645
|
}
|
2643
2646
|
if (link.hasAttribute("data-turbo-stream")) {
|
2644
|
-
request.acceptResponseType(
|
2647
|
+
request.acceptResponseType(StreamMessage.contentType);
|
2645
2648
|
}
|
2646
2649
|
}
|
2647
2650
|
requestSucceededWithResponse() {}
|
@@ -2655,7 +2658,7 @@ class LinkPrefetchObserver {
|
|
2655
2658
|
}
|
2656
2659
|
#isPrefetchable(link) {
|
2657
2660
|
const href = link.getAttribute("href");
|
2658
|
-
if (!href || href === "#" || link.
|
2661
|
+
if (!href || href === "#" || link.getAttribute("data-turbo") === "false" || link.getAttribute("data-turbo-prefetch") === "false") {
|
2659
2662
|
return false;
|
2660
2663
|
}
|
2661
2664
|
if (link.origin !== document.location.origin) {
|
@@ -2667,17 +2670,15 @@ class LinkPrefetchObserver {
|
|
2667
2670
|
if (link.pathname + link.search === document.location.pathname + document.location.search) {
|
2668
2671
|
return false;
|
2669
2672
|
}
|
2670
|
-
|
2673
|
+
const turboMethod = link.getAttribute("data-turbo-method");
|
2674
|
+
if (turboMethod && turboMethod !== "get") {
|
2671
2675
|
return false;
|
2672
2676
|
}
|
2673
2677
|
if (targetsIframe(link)) {
|
2674
2678
|
return false;
|
2675
2679
|
}
|
2676
|
-
if (link.pathname + link.search === document.location.pathname + document.location.search) {
|
2677
|
-
return false;
|
2678
|
-
}
|
2679
2680
|
const turboPrefetchParent = findClosestRecursively(link, "[data-turbo-prefetch]");
|
2680
|
-
if (turboPrefetchParent && turboPrefetchParent.
|
2681
|
+
if (turboPrefetchParent && turboPrefetchParent.getAttribute("data-turbo-prefetch") === "false") {
|
2681
2682
|
return false;
|
2682
2683
|
}
|
2683
2684
|
return true;
|
@@ -3147,7 +3148,7 @@ var Idiomorph = function() {
|
|
3147
3148
|
}
|
3148
3149
|
}
|
3149
3150
|
function ignoreValueOfActiveElement(possibleActiveElement, ctx) {
|
3150
|
-
return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement;
|
3151
|
+
return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;
|
3151
3152
|
}
|
3152
3153
|
function morphOldNodeTo(oldNode, newContent, ctx) {
|
3153
3154
|
if (ctx.ignoreActive && oldNode === document.activeElement) ; else if (newContent == null) {
|
@@ -3616,76 +3617,6 @@ var Idiomorph = function() {
|
|
3616
3617
|
};
|
3617
3618
|
}();
|
3618
3619
|
|
3619
|
-
class MorphRenderer extends Renderer {
|
3620
|
-
async render() {
|
3621
|
-
if (this.willRender) await this.#morphBody();
|
3622
|
-
}
|
3623
|
-
get renderMethod() {
|
3624
|
-
return "morph";
|
3625
|
-
}
|
3626
|
-
async #morphBody() {
|
3627
|
-
this.#morphElements(this.currentElement, this.newElement);
|
3628
|
-
this.#reloadRemoteFrames();
|
3629
|
-
dispatch("turbo:morph", {
|
3630
|
-
detail: {
|
3631
|
-
currentElement: this.currentElement,
|
3632
|
-
newElement: this.newElement
|
3633
|
-
}
|
3634
|
-
});
|
3635
|
-
}
|
3636
|
-
#morphElements(currentElement, newElement, morphStyle = "outerHTML") {
|
3637
|
-
this.isMorphingTurboFrame = this.#isFrameReloadedWithMorph(currentElement);
|
3638
|
-
Idiomorph.morph(currentElement, newElement, {
|
3639
|
-
morphStyle: morphStyle,
|
3640
|
-
callbacks: {
|
3641
|
-
beforeNodeAdded: this.#shouldAddElement,
|
3642
|
-
beforeNodeMorphed: this.#shouldMorphElement,
|
3643
|
-
beforeNodeRemoved: this.#shouldRemoveElement
|
3644
|
-
}
|
3645
|
-
});
|
3646
|
-
}
|
3647
|
-
#shouldAddElement=node => !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id));
|
3648
|
-
#shouldMorphElement=(oldNode, newNode) => {
|
3649
|
-
if (oldNode instanceof HTMLElement) {
|
3650
|
-
return !oldNode.hasAttribute("data-turbo-permanent") && (this.isMorphingTurboFrame || !this.#isFrameReloadedWithMorph(oldNode));
|
3651
|
-
} else {
|
3652
|
-
return true;
|
3653
|
-
}
|
3654
|
-
};
|
3655
|
-
#shouldRemoveElement=node => this.#shouldMorphElement(node);
|
3656
|
-
#reloadRemoteFrames() {
|
3657
|
-
this.#remoteFrames().forEach((frame => {
|
3658
|
-
if (this.#isFrameReloadedWithMorph(frame)) {
|
3659
|
-
this.#renderFrameWithMorph(frame);
|
3660
|
-
frame.reload();
|
3661
|
-
}
|
3662
|
-
}));
|
3663
|
-
}
|
3664
|
-
#renderFrameWithMorph(frame) {
|
3665
|
-
frame.addEventListener("turbo:before-frame-render", (event => {
|
3666
|
-
event.detail.render = this.#morphFrameUpdate;
|
3667
|
-
}), {
|
3668
|
-
once: true
|
3669
|
-
});
|
3670
|
-
}
|
3671
|
-
#morphFrameUpdate=(currentElement, newElement) => {
|
3672
|
-
dispatch("turbo:before-frame-morph", {
|
3673
|
-
target: currentElement,
|
3674
|
-
detail: {
|
3675
|
-
currentElement: currentElement,
|
3676
|
-
newElement: newElement
|
3677
|
-
}
|
3678
|
-
});
|
3679
|
-
this.#morphElements(currentElement, newElement.children, "innerHTML");
|
3680
|
-
};
|
3681
|
-
#isFrameReloadedWithMorph(element) {
|
3682
|
-
return element.src && element.refresh === "morph";
|
3683
|
-
}
|
3684
|
-
#remoteFrames() {
|
3685
|
-
return Array.from(document.querySelectorAll("turbo-frame[src]")).filter((frame => !frame.closest("[data-turbo-permanent]")));
|
3686
|
-
}
|
3687
|
-
}
|
3688
|
-
|
3689
3620
|
class PageRenderer extends Renderer {
|
3690
3621
|
static renderElement(currentElement, newElement) {
|
3691
3622
|
if (document.body && newElement instanceof HTMLBodyElement) {
|
@@ -3854,6 +3785,109 @@ class PageRenderer extends Renderer {
|
|
3854
3785
|
}
|
3855
3786
|
}
|
3856
3787
|
|
3788
|
+
class MorphRenderer extends PageRenderer {
|
3789
|
+
async render() {
|
3790
|
+
if (this.willRender) await this.#morphBody();
|
3791
|
+
}
|
3792
|
+
get renderMethod() {
|
3793
|
+
return "morph";
|
3794
|
+
}
|
3795
|
+
async #morphBody() {
|
3796
|
+
this.#morphElements(this.currentElement, this.newElement);
|
3797
|
+
this.#reloadRemoteFrames();
|
3798
|
+
dispatch("turbo:morph", {
|
3799
|
+
detail: {
|
3800
|
+
currentElement: this.currentElement,
|
3801
|
+
newElement: this.newElement
|
3802
|
+
}
|
3803
|
+
});
|
3804
|
+
}
|
3805
|
+
#morphElements(currentElement, newElement, morphStyle = "outerHTML") {
|
3806
|
+
this.isMorphingTurboFrame = this.#isFrameReloadedWithMorph(currentElement);
|
3807
|
+
Idiomorph.morph(currentElement, newElement, {
|
3808
|
+
ignoreActiveValue: true,
|
3809
|
+
morphStyle: morphStyle,
|
3810
|
+
callbacks: {
|
3811
|
+
beforeNodeAdded: this.#shouldAddElement,
|
3812
|
+
beforeNodeMorphed: this.#shouldMorphElement,
|
3813
|
+
beforeAttributeUpdated: this.#shouldUpdateAttribute,
|
3814
|
+
beforeNodeRemoved: this.#shouldRemoveElement,
|
3815
|
+
afterNodeMorphed: this.#didMorphElement
|
3816
|
+
}
|
3817
|
+
});
|
3818
|
+
}
|
3819
|
+
#shouldAddElement=node => !(node.id && node.hasAttribute("data-turbo-permanent") && document.getElementById(node.id));
|
3820
|
+
#shouldMorphElement=(oldNode, newNode) => {
|
3821
|
+
if (oldNode instanceof HTMLElement) {
|
3822
|
+
if (!oldNode.hasAttribute("data-turbo-permanent") && (this.isMorphingTurboFrame || !this.#isFrameReloadedWithMorph(oldNode))) {
|
3823
|
+
const event = dispatch("turbo:before-morph-element", {
|
3824
|
+
cancelable: true,
|
3825
|
+
target: oldNode,
|
3826
|
+
detail: {
|
3827
|
+
newElement: newNode
|
3828
|
+
}
|
3829
|
+
});
|
3830
|
+
return !event.defaultPrevented;
|
3831
|
+
} else {
|
3832
|
+
return false;
|
3833
|
+
}
|
3834
|
+
}
|
3835
|
+
};
|
3836
|
+
#shouldUpdateAttribute=(attributeName, target, mutationType) => {
|
3837
|
+
const event = dispatch("turbo:before-morph-attribute", {
|
3838
|
+
cancelable: true,
|
3839
|
+
target: target,
|
3840
|
+
detail: {
|
3841
|
+
attributeName: attributeName,
|
3842
|
+
mutationType: mutationType
|
3843
|
+
}
|
3844
|
+
});
|
3845
|
+
return !event.defaultPrevented;
|
3846
|
+
};
|
3847
|
+
#didMorphElement=(oldNode, newNode) => {
|
3848
|
+
if (newNode instanceof HTMLElement) {
|
3849
|
+
dispatch("turbo:morph-element", {
|
3850
|
+
target: oldNode,
|
3851
|
+
detail: {
|
3852
|
+
newElement: newNode
|
3853
|
+
}
|
3854
|
+
});
|
3855
|
+
}
|
3856
|
+
};
|
3857
|
+
#shouldRemoveElement=node => this.#shouldMorphElement(node);
|
3858
|
+
#reloadRemoteFrames() {
|
3859
|
+
this.#remoteFrames().forEach((frame => {
|
3860
|
+
if (this.#isFrameReloadedWithMorph(frame)) {
|
3861
|
+
this.#renderFrameWithMorph(frame);
|
3862
|
+
frame.reload();
|
3863
|
+
}
|
3864
|
+
}));
|
3865
|
+
}
|
3866
|
+
#renderFrameWithMorph(frame) {
|
3867
|
+
frame.addEventListener("turbo:before-frame-render", (event => {
|
3868
|
+
event.detail.render = this.#morphFrameUpdate;
|
3869
|
+
}), {
|
3870
|
+
once: true
|
3871
|
+
});
|
3872
|
+
}
|
3873
|
+
#morphFrameUpdate=(currentElement, newElement) => {
|
3874
|
+
dispatch("turbo:before-frame-morph", {
|
3875
|
+
target: currentElement,
|
3876
|
+
detail: {
|
3877
|
+
currentElement: currentElement,
|
3878
|
+
newElement: newElement
|
3879
|
+
}
|
3880
|
+
});
|
3881
|
+
this.#morphElements(currentElement, newElement.children, "innerHTML");
|
3882
|
+
};
|
3883
|
+
#isFrameReloadedWithMorph(element) {
|
3884
|
+
return element.src && element.refresh === "morph";
|
3885
|
+
}
|
3886
|
+
#remoteFrames() {
|
3887
|
+
return Array.from(document.querySelectorAll("turbo-frame[src]")).filter((frame => !frame.closest("[data-turbo-permanent]")));
|
3888
|
+
}
|
3889
|
+
}
|
3890
|
+
|
3857
3891
|
class SnapshotCache {
|
3858
3892
|
keys=[];
|
3859
3893
|
snapshots={};
|
@@ -3980,7 +4014,7 @@ class Preloader {
|
|
3980
4014
|
await fetchRequest.perform();
|
3981
4015
|
}
|
3982
4016
|
prepareRequest(fetchRequest) {
|
3983
|
-
fetchRequest.headers["Sec-Purpose"] = "prefetch";
|
4017
|
+
fetchRequest.headers["X-Sec-Purpose"] = "prefetch";
|
3984
4018
|
}
|
3985
4019
|
async requestSucceededWithResponse(fetchRequest, fetchResponse) {
|
3986
4020
|
try {
|
@@ -4090,8 +4124,9 @@ class Session {
|
|
4090
4124
|
visit(location, options = {}) {
|
4091
4125
|
const frameElement = options.frame ? document.getElementById(options.frame) : null;
|
4092
4126
|
if (frameElement instanceof FrameElement) {
|
4127
|
+
const action = options.action || getVisitAction(frameElement);
|
4128
|
+
frameElement.delegate.proposeVisitIfNavigatedWithAction(frameElement, action);
|
4093
4129
|
frameElement.src = location.toString();
|
4094
|
-
frameElement.loaded;
|
4095
4130
|
} else {
|
4096
4131
|
this.navigator.proposeVisit(expandURL(location), options);
|
4097
4132
|
}
|
@@ -4561,7 +4596,7 @@ class FrameController {
|
|
4561
4596
|
}
|
4562
4597
|
}
|
4563
4598
|
elementAppearedInViewport(element) {
|
4564
|
-
this.proposeVisitIfNavigatedWithAction(element, element);
|
4599
|
+
this.proposeVisitIfNavigatedWithAction(element, getVisitAction(element));
|
4565
4600
|
this.#loadSourceURL();
|
4566
4601
|
}
|
4567
4602
|
willSubmitFormLinkToLocation(link) {
|
@@ -4621,7 +4656,7 @@ class FrameController {
|
|
4621
4656
|
}
|
4622
4657
|
formSubmissionSucceededWithResponse(formSubmission, response) {
|
4623
4658
|
const frame = this.#findFrameElement(formSubmission.formElement, formSubmission.submitter);
|
4624
|
-
frame.delegate.proposeVisitIfNavigatedWithAction(frame, formSubmission.
|
4659
|
+
frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(formSubmission.submitter, formSubmission.formElement, frame));
|
4625
4660
|
frame.delegate.loadResponse(response);
|
4626
4661
|
if (!formSubmission.isSafe) {
|
4627
4662
|
session.clearCache();
|
@@ -4698,13 +4733,13 @@ class FrameController {
|
|
4698
4733
|
}
|
4699
4734
|
#navigateFrame(element, url, submitter) {
|
4700
4735
|
const frame = this.#findFrameElement(element, submitter);
|
4701
|
-
frame.delegate.proposeVisitIfNavigatedWithAction(frame, element,
|
4736
|
+
frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(submitter, element, frame));
|
4702
4737
|
this.#withCurrentNavigationElement(element, (() => {
|
4703
4738
|
frame.src = url;
|
4704
4739
|
}));
|
4705
4740
|
}
|
4706
|
-
proposeVisitIfNavigatedWithAction(frame,
|
4707
|
-
this.action =
|
4741
|
+
proposeVisitIfNavigatedWithAction(frame, action = null) {
|
4742
|
+
this.action = action;
|
4708
4743
|
if (this.action) {
|
4709
4744
|
const pageSnapshot = PageSnapshot.fromElement(frame).clone();
|
4710
4745
|
const {visitCachedSnapshot: visitCachedSnapshot} = frame.delegate;
|