turbo-rails 0.7.11 → 0.7.15
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 +4 -4
- data/README.md +1 -4
- data/app/assets/javascripts/turbo.js +39 -21
- data/app/channels/turbo/streams/broadcasts.rb +16 -16
- data/app/helpers/turbo/streams/action_helper.rb +7 -3
- data/app/models/concerns/turbo/broadcastable.rb +12 -12
- data/lib/install/turbo_needs_redis.rb +11 -1
- data/lib/tasks/turbo_tasks.rake +2 -2
- data/lib/turbo/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab24210e4f0dd28243c220d5b586b69705e2b18b50251daa22e8cd6d861fc9f5
|
4
|
+
data.tar.gz: 7379f1f27936571fe482807459f18f773c041d36ae539cd0e1750dd5ade8489b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa92baea7d57b563f9c802e3a595a870f5c3fe38402c49720cd34908a6c396a3fcdb503fc8be035407ff3c8bdad8bcb81294fa83d81dc2e53d676de49da5cd50
|
7
|
+
data.tar.gz: b3a8d8bd0ff379e6dd40c8a41e53aa413c914c04cdf9cc2408fc1c670b3bafde13881bd4fc2a9b106e77c09ee770e61061cce8c8ddf69d0160b759995a93883e
|
data/README.md
CHANGED
@@ -71,10 +71,7 @@ Turbo can coexist with Rails UJS, but you need to take a series of upgrade steps
|
|
71
71
|
|
72
72
|
## Development
|
73
73
|
|
74
|
-
|
75
|
-
* To install dependencies: `bundle install`
|
76
|
-
* To prepare the test database: `cd test/dummy; RAILS_ENV=test ./bin/rails db:migrate`
|
77
|
-
* To compile the JavaScript for the asset pipeline: `yarn build`
|
74
|
+
Run the tests with `./bin/test`.
|
78
75
|
|
79
76
|
|
80
77
|
## License
|
@@ -31,6 +31,7 @@ function clickCaptured(event) {
|
|
31
31
|
|
32
32
|
(function() {
|
33
33
|
if ("SubmitEvent" in window) return;
|
34
|
+
if ("submitter" in Event.prototype) return;
|
34
35
|
addEventListener("click", clickCaptured, true);
|
35
36
|
Object.defineProperty(Event.prototype, "submitter", {
|
36
37
|
get() {
|
@@ -226,11 +227,11 @@ class FetchResponse {
|
|
226
227
|
return this.header("Content-Type");
|
227
228
|
}
|
228
229
|
get responseText() {
|
229
|
-
return this.response.text();
|
230
|
+
return this.response.clone().text();
|
230
231
|
}
|
231
232
|
get responseHTML() {
|
232
233
|
if (this.isHTML) {
|
233
|
-
return this.response.text();
|
234
|
+
return this.response.clone().text();
|
234
235
|
} else {
|
235
236
|
return Promise.resolve(undefined);
|
236
237
|
}
|
@@ -246,7 +247,11 @@ function dispatch(eventName, {target: target, cancelable: cancelable, detail: de
|
|
246
247
|
bubbles: true,
|
247
248
|
detail: detail
|
248
249
|
});
|
249
|
-
|
250
|
+
if (target && target.isConnected) {
|
251
|
+
target.dispatchEvent(event);
|
252
|
+
} else {
|
253
|
+
document.documentElement.dispatchEvent(event);
|
254
|
+
}
|
250
255
|
return event;
|
251
256
|
}
|
252
257
|
|
@@ -326,7 +331,7 @@ function fetchMethodFromString(method) {
|
|
326
331
|
}
|
327
332
|
|
328
333
|
class FetchRequest {
|
329
|
-
constructor(delegate, method, location, body = new URLSearchParams) {
|
334
|
+
constructor(delegate, method, location, body = new URLSearchParams, target = null) {
|
330
335
|
this.abortController = new AbortController;
|
331
336
|
this.resolveRequestPromise = value => {};
|
332
337
|
this.delegate = delegate;
|
@@ -338,6 +343,7 @@ class FetchRequest {
|
|
338
343
|
this.body = body;
|
339
344
|
this.url = location;
|
340
345
|
}
|
346
|
+
this.target = target;
|
341
347
|
}
|
342
348
|
get location() {
|
343
349
|
return this.url;
|
@@ -375,7 +381,8 @@ class FetchRequest {
|
|
375
381
|
cancelable: true,
|
376
382
|
detail: {
|
377
383
|
fetchResponse: fetchResponse
|
378
|
-
}
|
384
|
+
},
|
385
|
+
target: this.target
|
379
386
|
});
|
380
387
|
if (event.defaultPrevented) {
|
381
388
|
this.delegate.requestPreventedHandlingResponse(this, fetchResponse);
|
@@ -417,7 +424,8 @@ class FetchRequest {
|
|
417
424
|
fetchOptions: fetchOptions,
|
418
425
|
url: this.url.href,
|
419
426
|
resume: this.resolveRequestPromise
|
420
|
-
}
|
427
|
+
},
|
428
|
+
target: this.target
|
421
429
|
});
|
422
430
|
if (event.defaultPrevented) await requestInterception;
|
423
431
|
}
|
@@ -538,7 +546,7 @@ class FormSubmission {
|
|
538
546
|
this.formElement = formElement;
|
539
547
|
this.submitter = submitter;
|
540
548
|
this.formData = buildFormData(formElement, submitter);
|
541
|
-
this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body);
|
549
|
+
this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body, this.formElement);
|
542
550
|
this.mustRedirect = mustRedirect;
|
543
551
|
}
|
544
552
|
get method() {
|
@@ -1173,7 +1181,7 @@ ProgressBar.animationDuration = 300;
|
|
1173
1181
|
class HeadSnapshot extends Snapshot {
|
1174
1182
|
constructor() {
|
1175
1183
|
super(...arguments);
|
1176
|
-
this.detailsByOuterHTML = this.children.filter((element => !elementIsNoscript(element))).reduce(((result, element) => {
|
1184
|
+
this.detailsByOuterHTML = this.children.filter((element => !elementIsNoscript(element))).map((element => elementWithoutNonce(element))).reduce(((result, element) => {
|
1177
1185
|
const {outerHTML: outerHTML} = element;
|
1178
1186
|
const details = outerHTML in result ? result[outerHTML] : {
|
1179
1187
|
type: elementType(element),
|
@@ -1255,6 +1263,13 @@ function elementIsMetaElementWithName(element, name) {
|
|
1255
1263
|
return tagName == "meta" && element.getAttribute("name") == name;
|
1256
1264
|
}
|
1257
1265
|
|
1266
|
+
function elementWithoutNonce(element) {
|
1267
|
+
if (element.hasAttribute("nonce")) {
|
1268
|
+
element.setAttribute("nonce", "");
|
1269
|
+
}
|
1270
|
+
return element;
|
1271
|
+
}
|
1272
|
+
|
1258
1273
|
class PageSnapshot extends Snapshot {
|
1259
1274
|
constructor(element, headSnapshot) {
|
1260
1275
|
super(element);
|
@@ -1805,18 +1820,18 @@ class FrameRedirector {
|
|
1805
1820
|
return this.shouldRedirect(element, submitter);
|
1806
1821
|
}
|
1807
1822
|
formSubmissionIntercepted(element, submitter) {
|
1808
|
-
const frame = this.findFrameElement(element);
|
1823
|
+
const frame = this.findFrameElement(element, submitter);
|
1809
1824
|
if (frame) {
|
1810
1825
|
frame.removeAttribute("reloadable");
|
1811
1826
|
frame.delegate.formSubmissionIntercepted(element, submitter);
|
1812
1827
|
}
|
1813
1828
|
}
|
1814
1829
|
shouldRedirect(element, submitter) {
|
1815
|
-
const frame = this.findFrameElement(element);
|
1830
|
+
const frame = this.findFrameElement(element, submitter);
|
1816
1831
|
return frame ? frame != element.closest("turbo-frame") : false;
|
1817
1832
|
}
|
1818
|
-
findFrameElement(element) {
|
1819
|
-
const id = element.getAttribute("data-turbo-frame");
|
1833
|
+
findFrameElement(element, submitter) {
|
1834
|
+
const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("data-turbo-frame")) || element.getAttribute("data-turbo-frame");
|
1820
1835
|
if (id && id != "_top") {
|
1821
1836
|
const frame = this.element.querySelector(`#${id}:not([disabled])`);
|
1822
1837
|
if (frame instanceof FrameElement) {
|
@@ -2539,12 +2554,14 @@ class Session {
|
|
2539
2554
|
});
|
2540
2555
|
}
|
2541
2556
|
convertLinkWithMethodClickToFormSubmission(link) {
|
2557
|
+
var _a;
|
2542
2558
|
const linkMethod = link.getAttribute("data-turbo-method");
|
2543
2559
|
if (linkMethod) {
|
2544
2560
|
const form = document.createElement("form");
|
2545
2561
|
form.method = linkMethod;
|
2546
2562
|
form.action = link.getAttribute("href") || "undefined";
|
2547
|
-
|
2563
|
+
form.hidden = true;
|
2564
|
+
(_a = link.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(form, link);
|
2548
2565
|
return dispatch("submit", {
|
2549
2566
|
cancelable: true,
|
2550
2567
|
target: form
|
@@ -2896,7 +2913,7 @@ class FrameController {
|
|
2896
2913
|
this.reloadable = false;
|
2897
2914
|
this.formSubmission = new FormSubmission(this, element, submitter);
|
2898
2915
|
if (this.formSubmission.fetchRequest.isIdempotent) {
|
2899
|
-
this.navigateFrame(element, this.formSubmission.fetchRequest.url.href);
|
2916
|
+
this.navigateFrame(element, this.formSubmission.fetchRequest.url.href, submitter);
|
2900
2917
|
} else {
|
2901
2918
|
const {fetchRequest: fetchRequest} = this.formSubmission;
|
2902
2919
|
this.prepareHeadersForRequest(fetchRequest.headers, fetchRequest);
|
@@ -2932,7 +2949,7 @@ class FrameController {
|
|
2932
2949
|
frame.setAttribute("busy", "");
|
2933
2950
|
}
|
2934
2951
|
formSubmissionSucceededWithResponse(formSubmission, response) {
|
2935
|
-
const frame = this.findFrameElement(formSubmission.formElement);
|
2952
|
+
const frame = this.findFrameElement(formSubmission.formElement, formSubmission.submitter);
|
2936
2953
|
frame.delegate.loadResponse(response);
|
2937
2954
|
}
|
2938
2955
|
formSubmissionFailedWithResponse(formSubmission, fetchResponse) {
|
@@ -2951,7 +2968,7 @@ class FrameController {
|
|
2951
2968
|
viewRenderedSnapshot(snapshot, isPreview) {}
|
2952
2969
|
viewInvalidated() {}
|
2953
2970
|
async visit(url) {
|
2954
|
-
const request = new FetchRequest(this, FetchMethod.get, expandURL(url));
|
2971
|
+
const request = new FetchRequest(this, FetchMethod.get, expandURL(url), undefined, this.element);
|
2955
2972
|
return new Promise((resolve => {
|
2956
2973
|
this.resolveVisitPromise = () => {
|
2957
2974
|
this.resolveVisitPromise = () => {};
|
@@ -2960,13 +2977,14 @@ class FrameController {
|
|
2960
2977
|
request.perform();
|
2961
2978
|
}));
|
2962
2979
|
}
|
2963
|
-
navigateFrame(element, url) {
|
2964
|
-
const frame = this.findFrameElement(element);
|
2980
|
+
navigateFrame(element, url, submitter) {
|
2981
|
+
const frame = this.findFrameElement(element, submitter);
|
2982
|
+
frame.setAttribute("reloadable", "");
|
2965
2983
|
frame.src = url;
|
2966
2984
|
}
|
2967
|
-
findFrameElement(element) {
|
2985
|
+
findFrameElement(element, submitter) {
|
2968
2986
|
var _a;
|
2969
|
-
const id = element.getAttribute("data-turbo-frame") || this.element.getAttribute("target");
|
2987
|
+
const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("data-turbo-frame")) || element.getAttribute("data-turbo-frame") || this.element.getAttribute("target");
|
2970
2988
|
return (_a = getFrameElementById(id)) !== null && _a !== void 0 ? _a : this.element;
|
2971
2989
|
}
|
2972
2990
|
async extractForeignFrameElement(container) {
|
@@ -2987,7 +3005,7 @@ class FrameController {
|
|
2987
3005
|
return new FrameElement;
|
2988
3006
|
}
|
2989
3007
|
shouldInterceptNavigation(element, submitter) {
|
2990
|
-
const id = element.getAttribute("data-turbo-frame") || this.element.getAttribute("target");
|
3008
|
+
const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("data-turbo-frame")) || element.getAttribute("data-turbo-frame") || this.element.getAttribute("target");
|
2991
3009
|
if (!this.enabled || id == "_top") {
|
2992
3010
|
return false;
|
2993
3011
|
}
|
@@ -6,61 +6,61 @@ module Turbo::Streams::Broadcasts
|
|
6
6
|
include Turbo::Streams::ActionHelper
|
7
7
|
|
8
8
|
def broadcast_remove_to(*streamables, **opts)
|
9
|
-
broadcast_action_to
|
9
|
+
broadcast_action_to(*streamables, action: :remove, **opts)
|
10
10
|
end
|
11
11
|
|
12
12
|
def broadcast_replace_to(*streamables, **opts)
|
13
|
-
broadcast_action_to
|
13
|
+
broadcast_action_to(*streamables, action: :replace, **opts)
|
14
14
|
end
|
15
15
|
|
16
16
|
def broadcast_update_to(*streamables, **opts)
|
17
|
-
broadcast_action_to
|
17
|
+
broadcast_action_to(*streamables, action: :update, **opts)
|
18
18
|
end
|
19
19
|
|
20
20
|
def broadcast_before_to(*streamables, **opts)
|
21
|
-
broadcast_action_to
|
21
|
+
broadcast_action_to(*streamables, action: :before, **opts)
|
22
22
|
end
|
23
23
|
|
24
24
|
def broadcast_after_to(*streamables, **opts)
|
25
|
-
broadcast_action_to
|
25
|
+
broadcast_action_to(*streamables, action: :after, **opts)
|
26
26
|
end
|
27
27
|
|
28
28
|
def broadcast_append_to(*streamables, **opts)
|
29
|
-
broadcast_action_to
|
29
|
+
broadcast_action_to(*streamables, action: :append, **opts)
|
30
30
|
end
|
31
31
|
|
32
32
|
def broadcast_prepend_to(*streamables, **opts)
|
33
|
-
broadcast_action_to
|
33
|
+
broadcast_action_to(*streamables, action: :prepend, **opts)
|
34
34
|
end
|
35
35
|
|
36
36
|
def broadcast_action_to(*streamables, action:, target: nil, targets: nil, **rendering)
|
37
|
-
broadcast_stream_to
|
37
|
+
broadcast_stream_to(*streamables, content: turbo_stream_action_tag(action, target: target, targets: targets, template:
|
38
38
|
rendering.delete(:content) || (rendering.any? ? render_format(:html, **rendering) : nil)
|
39
|
-
)
|
39
|
+
))
|
40
40
|
end
|
41
41
|
|
42
42
|
def broadcast_replace_later_to(*streamables, **opts)
|
43
|
-
broadcast_action_later_to
|
43
|
+
broadcast_action_later_to(*streamables, action: :replace, **opts)
|
44
44
|
end
|
45
45
|
|
46
46
|
def broadcast_update_later_to(*streamables, **opts)
|
47
|
-
broadcast_action_later_to
|
47
|
+
broadcast_action_later_to(*streamables, action: :update, **opts)
|
48
48
|
end
|
49
49
|
|
50
50
|
def broadcast_before_later_to(*streamables, **opts)
|
51
|
-
broadcast_action_later_to
|
51
|
+
broadcast_action_later_to(*streamables, action: :before, **opts)
|
52
52
|
end
|
53
53
|
|
54
54
|
def broadcast_after_later_to(*streamables, **opts)
|
55
|
-
broadcast_action_later_to
|
55
|
+
broadcast_action_later_to(*streamables, action: :after, **opts)
|
56
56
|
end
|
57
57
|
|
58
58
|
def broadcast_append_later_to(*streamables, **opts)
|
59
|
-
broadcast_action_later_to
|
59
|
+
broadcast_action_later_to(*streamables, action: :append, **opts)
|
60
60
|
end
|
61
61
|
|
62
62
|
def broadcast_prepend_later_to(*streamables, **opts)
|
63
|
-
broadcast_action_later_to
|
63
|
+
broadcast_action_later_to(*streamables, action: :prepend, **opts)
|
64
64
|
end
|
65
65
|
|
66
66
|
def broadcast_action_later_to(*streamables, action:, target: nil, targets: nil, **rendering)
|
@@ -69,7 +69,7 @@ module Turbo::Streams::Broadcasts
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def broadcast_render_to(*streamables, **rendering)
|
72
|
-
broadcast_stream_to
|
72
|
+
broadcast_stream_to(*streamables, content: render_format(:turbo_stream, **rendering))
|
73
73
|
end
|
74
74
|
|
75
75
|
def broadcast_render_later_to(*streamables, **rendering)
|
@@ -14,7 +14,7 @@ module Turbo::Streams::ActionHelper
|
|
14
14
|
|
15
15
|
if target = convert_to_turbo_stream_dom_id(target)
|
16
16
|
%(<turbo-stream action="#{action}" target="#{target}">#{template}</turbo-stream>).html_safe
|
17
|
-
elsif targets = convert_to_turbo_stream_dom_id(targets)
|
17
|
+
elsif targets = convert_to_turbo_stream_dom_id(targets, include_selector: true)
|
18
18
|
%(<turbo-stream action="#{action}" targets="#{targets}">#{template}</turbo-stream>).html_safe
|
19
19
|
else
|
20
20
|
raise ArgumentError, "target or targets must be supplied"
|
@@ -22,7 +22,11 @@ module Turbo::Streams::ActionHelper
|
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
25
|
-
def convert_to_turbo_stream_dom_id(target)
|
26
|
-
target.respond_to?(:to_key)
|
25
|
+
def convert_to_turbo_stream_dom_id(target, include_selector: false)
|
26
|
+
if target.respond_to?(:to_key)
|
27
|
+
[ ("#" if include_selector), ActionView::RecordIdentifier.dom_id(target) ].compact.join
|
28
|
+
else
|
29
|
+
target
|
30
|
+
end
|
27
31
|
end
|
28
32
|
end
|
@@ -76,7 +76,7 @@ module Turbo::Broadcastable
|
|
76
76
|
# # Sends <turbo-stream action="remove" target="clearance_5"></turbo-stream> to the stream named "identity:2:clearances"
|
77
77
|
# clearance.broadcast_remove_to examiner.identity, :clearances
|
78
78
|
def broadcast_remove_to(*streamables, target: self)
|
79
|
-
Turbo::StreamsChannel.broadcast_remove_to
|
79
|
+
Turbo::StreamsChannel.broadcast_remove_to(*streamables, target: target)
|
80
80
|
end
|
81
81
|
|
82
82
|
# Same as <tt>#broadcast_remove_to</tt>, but the designated stream is automatically set to the current model.
|
@@ -95,7 +95,7 @@ module Turbo::Broadcastable
|
|
95
95
|
# # to the stream named "identity:2:clearances"
|
96
96
|
# clearance.broadcast_replace_to examiner.identity, :clearances, partial: "clearances/other_partial", locals: { a: 1 }
|
97
97
|
def broadcast_replace_to(*streamables, **rendering)
|
98
|
-
Turbo::StreamsChannel.broadcast_replace_to
|
98
|
+
Turbo::StreamsChannel.broadcast_replace_to(*streamables, target: self, **broadcast_rendering_with_defaults(rendering))
|
99
99
|
end
|
100
100
|
|
101
101
|
# Same as <tt>#broadcast_replace_to</tt>, but the designated stream is automatically set to the current model.
|
@@ -114,7 +114,7 @@ module Turbo::Broadcastable
|
|
114
114
|
# # to the stream named "identity:2:clearances"
|
115
115
|
# clearance.broadcast_update_to examiner.identity, :clearances, partial: "clearances/other_partial", locals: { a: 1 }
|
116
116
|
def broadcast_update_to(*streamables, **rendering)
|
117
|
-
Turbo::StreamsChannel.broadcast_update_to
|
117
|
+
Turbo::StreamsChannel.broadcast_update_to(*streamables, target: self, **broadcast_rendering_with_defaults(rendering))
|
118
118
|
end
|
119
119
|
|
120
120
|
# Same as <tt>#broadcast_update_to</tt>, but the designated stream is automatically set to the current model.
|
@@ -135,7 +135,7 @@ module Turbo::Broadcastable
|
|
135
135
|
# clearance.broadcast_before_to examiner.identity, :clearances, target: "clearance_5",
|
136
136
|
# partial: "clearances/other_partial", locals: { a: 1 }
|
137
137
|
def broadcast_before_to(*streamables, target:, **rendering)
|
138
|
-
Turbo::StreamsChannel.broadcast_before_to
|
138
|
+
Turbo::StreamsChannel.broadcast_before_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering))
|
139
139
|
end
|
140
140
|
|
141
141
|
# Insert a rendering of this broadcastable model after the target identified by it's dom id passed as <tt>target</tt>
|
@@ -151,7 +151,7 @@ module Turbo::Broadcastable
|
|
151
151
|
# clearance.broadcast_after_to examiner.identity, :clearances, target: "clearance_5",
|
152
152
|
# partial: "clearances/other_partial", locals: { a: 1 }
|
153
153
|
def broadcast_after_to(*streamables, target:, **rendering)
|
154
|
-
Turbo::StreamsChannel.broadcast_after_to
|
154
|
+
Turbo::StreamsChannel.broadcast_after_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering))
|
155
155
|
end
|
156
156
|
|
157
157
|
# Append a rendering of this broadcastable model to the target identified by it's dom id passed as <tt>target</tt>
|
@@ -167,7 +167,7 @@ module Turbo::Broadcastable
|
|
167
167
|
# clearance.broadcast_append_to examiner.identity, :clearances, target: "clearances",
|
168
168
|
# partial: "clearances/other_partial", locals: { a: 1 }
|
169
169
|
def broadcast_append_to(*streamables, target: broadcast_target_default, **rendering)
|
170
|
-
Turbo::StreamsChannel.broadcast_append_to
|
170
|
+
Turbo::StreamsChannel.broadcast_append_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering))
|
171
171
|
end
|
172
172
|
|
173
173
|
# Same as <tt>#broadcast_append_to</tt>, but the designated stream is automatically set to the current model.
|
@@ -188,7 +188,7 @@ module Turbo::Broadcastable
|
|
188
188
|
# clearance.broadcast_prepend_to examiner.identity, :clearances, target: "clearances",
|
189
189
|
# partial: "clearances/other_partial", locals: { a: 1 }
|
190
190
|
def broadcast_prepend_to(*streamables, target: broadcast_target_default, **rendering)
|
191
|
-
Turbo::StreamsChannel.broadcast_prepend_to
|
191
|
+
Turbo::StreamsChannel.broadcast_prepend_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering))
|
192
192
|
end
|
193
193
|
|
194
194
|
# Same as <tt>#broadcast_prepend_to</tt>, but the designated stream is automatically set to the current model.
|
@@ -213,7 +213,7 @@ module Turbo::Broadcastable
|
|
213
213
|
|
214
214
|
# Same as <tt>broadcast_replace_to</tt> but run asynchronously via a <tt>Turbo::Streams::BroadcastJob</tt>.
|
215
215
|
def broadcast_replace_later_to(*streamables, **rendering)
|
216
|
-
Turbo::StreamsChannel.broadcast_replace_later_to
|
216
|
+
Turbo::StreamsChannel.broadcast_replace_later_to(*streamables, target: self, **broadcast_rendering_with_defaults(rendering))
|
217
217
|
end
|
218
218
|
|
219
219
|
# Same as <tt>#broadcast_replace_later_to</tt>, but the designated stream is automatically set to the current model.
|
@@ -223,7 +223,7 @@ module Turbo::Broadcastable
|
|
223
223
|
|
224
224
|
# Same as <tt>broadcast_update_to</tt> but run asynchronously via a <tt>Turbo::Streams::BroadcastJob</tt>.
|
225
225
|
def broadcast_update_later_to(*streamables, **rendering)
|
226
|
-
Turbo::StreamsChannel.broadcast_update_later_to
|
226
|
+
Turbo::StreamsChannel.broadcast_update_later_to(*streamables, target: self, **broadcast_rendering_with_defaults(rendering))
|
227
227
|
end
|
228
228
|
|
229
229
|
# Same as <tt>#broadcast_update_later_to</tt>, but the designated stream is automatically set to the current model.
|
@@ -233,7 +233,7 @@ module Turbo::Broadcastable
|
|
233
233
|
|
234
234
|
# Same as <tt>broadcast_append_to</tt> but run asynchronously via a <tt>Turbo::Streams::BroadcastJob</tt>.
|
235
235
|
def broadcast_append_later_to(*streamables, target: broadcast_target_default, **rendering)
|
236
|
-
Turbo::StreamsChannel.broadcast_append_later_to
|
236
|
+
Turbo::StreamsChannel.broadcast_append_later_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering))
|
237
237
|
end
|
238
238
|
|
239
239
|
# Same as <tt>#broadcast_append_later_to</tt>, but the designated stream is automatically set to the current model.
|
@@ -243,7 +243,7 @@ module Turbo::Broadcastable
|
|
243
243
|
|
244
244
|
# Same as <tt>broadcast_prepend_to</tt> but run asynchronously via a <tt>Turbo::Streams::BroadcastJob</tt>.
|
245
245
|
def broadcast_prepend_later_to(*streamables, target: broadcast_target_default, **rendering)
|
246
|
-
Turbo::StreamsChannel.broadcast_prepend_later_to
|
246
|
+
Turbo::StreamsChannel.broadcast_prepend_later_to(*streamables, target: target, **broadcast_rendering_with_defaults(rendering))
|
247
247
|
end
|
248
248
|
|
249
249
|
# Same as <tt>#broadcast_prepend_later_to</tt>, but the designated stream is automatically set to the current model.
|
@@ -283,7 +283,7 @@ module Turbo::Broadcastable
|
|
283
283
|
# Same as <tt>broadcast_render_later</tt> but run with the added option of naming the stream using the passed
|
284
284
|
# <tt>streamables</tt>.
|
285
285
|
def broadcast_render_later_to(*streamables, **rendering)
|
286
|
-
Turbo::StreamsChannel.broadcast_render_later_to
|
286
|
+
Turbo::StreamsChannel.broadcast_render_later_to(*streamables, **broadcast_rendering_with_defaults(rendering))
|
287
287
|
end
|
288
288
|
|
289
289
|
|
@@ -1,6 +1,16 @@
|
|
1
1
|
if (cable_config_path = Rails.root.join("config/cable.yml")).exist?
|
2
2
|
say "Enable redis in bundle"
|
3
|
-
|
3
|
+
|
4
|
+
gemfile_content = File.read(Rails.root.join("Gemfile"))
|
5
|
+
pattern = /gem ['"]redis['"]/
|
6
|
+
|
7
|
+
if gemfile_content.match?(pattern)
|
8
|
+
uncomment_lines "Gemfile", pattern
|
9
|
+
else
|
10
|
+
gem 'redis', '~> 4.0', comment: "Use Redis as Action Cable adapter instead of default Async. The Async adapter\ndoes not support Turbo Stream broadcasting."
|
11
|
+
end
|
12
|
+
|
13
|
+
run_bundle
|
4
14
|
|
5
15
|
say "Switch development cable to use redis"
|
6
16
|
gsub_file cable_config_path.to_s, /development:\n\s+adapter: async/, "development:\n adapter: redis\n url: redis://localhost:6379/1"
|
data/lib/tasks/turbo_tasks.rake
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
def run_turbo_install_template(path)
|
2
|
-
system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/#{path}.rb",
|
2
|
+
system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/#{path}.rb", __dir__)}"
|
3
3
|
end
|
4
4
|
|
5
5
|
def redis_installed?
|
6
|
-
system('which redis-server')
|
6
|
+
system('which redis-server > /dev/null')
|
7
7
|
end
|
8
8
|
|
9
9
|
def switch_on_redis_if_available
|
data/lib/turbo/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbo-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Stephenson
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-09-
|
13
|
+
date: 2021-09-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|