turbo-rails 1.3.3 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,19 +1,27 @@
1
1
  # Turbo frame requests are requests made from within a turbo frame with the intention of replacing the content of just
2
2
  # that frame, not the whole page. They are automatically tagged as such by the Turbo Frame JavaScript, which adds a
3
- # <tt>Turbo-Frame</tt> header to the request. When that header is detected by the controller, we ensure that any
4
- # template layout is skipped (since we're only working on an in-page frame, thus can skip the weight of the layout), and
5
- # that the etag for the page is changed (such that a cache for a layout-less request isn't served on a normal request
6
- # and vice versa).
3
+ # <tt>Turbo-Frame</tt> header to the request.
7
4
  #
8
- # This is merely a rendering optimization. Everything would still work just fine if we rendered everything including the layout.
9
- # Turbo Frames knows how to fish out the relevant frame regardless.
5
+ # When that header is detected by the controller, we substitute our own minimal layout in place of the
6
+ # application-supplied layout (since we're only working on an in-page frame, thus can skip the weight of the layout). We
7
+ # use a minimal layout, rather than avoid the layout entirely, so that it's still possible to render content into the
8
+ # <tt>head<tt>.
9
+ #
10
+ # Accordingly, we ensure that the etag for the page is changed, such that a cache for a minimal-layout request isn't
11
+ # served on a normal request and vice versa.
12
+ #
13
+ # This is merely a rendering optimization. Everything would still work just fine if we rendered everything including the
14
+ # full layout. Turbo Frames knows how to fish out the relevant frame regardless.
15
+ #
16
+ # The layout used is <tt>turbo_rails/frame.html.erb</tt>. If there's a need to customize this layout, an application can
17
+ # supply its own (such as <tt>app/views/layouts/turbo_rails/frame.html.erb</tt>) which will be used instead.
10
18
  #
11
19
  # This module is automatically included in <tt>ActionController::Base</tt>.
12
20
  module Turbo::Frames::FrameRequest
13
21
  extend ActiveSupport::Concern
14
22
 
15
23
  included do
16
- layout -> { false if turbo_frame_request? }
24
+ layout -> { "turbo_rails/frame" if turbo_frame_request? }
17
25
  etag { :frame if turbo_frame_request? }
18
26
  end
19
27
 
@@ -5,7 +5,11 @@ import snakeize from "./snakeize"
5
5
  class TurboCableStreamSourceElement extends HTMLElement {
6
6
  async connectedCallback() {
7
7
  connectStreamSource(this)
8
- this.subscription = await subscribeTo(this.channel, { received: this.dispatchMessageEvent.bind(this) })
8
+ this.subscription = await subscribeTo(this.channel, {
9
+ received: this.dispatchMessageEvent.bind(this),
10
+ connected: this.subscriptionConnected.bind(this),
11
+ disconnected: this.subscriptionDisconnected.bind(this)
12
+ })
9
13
  }
10
14
 
11
15
  disconnectedCallback() {
@@ -18,6 +22,14 @@ class TurboCableStreamSourceElement extends HTMLElement {
18
22
  return this.dispatchEvent(event)
19
23
  }
20
24
 
25
+ subscriptionConnected() {
26
+ this.setAttribute("connected", "")
27
+ }
28
+
29
+ subscriptionDisconnected() {
30
+ this.removeAttribute("connected")
31
+ }
32
+
21
33
  get channel() {
22
34
  const channel = this.getAttribute("channel")
23
35
  const signed_stream_name = this.getAttribute("signed-stream-name")
@@ -27,7 +27,7 @@
27
27
  # (which is derived by default from the plural model name of the model, but can be overwritten).
28
28
  #
29
29
  # You can also choose to render html instead of a partial inside of a broadcast
30
- # you do this by passing the html: option to any broadcast method that accepts the **rendering argument
30
+ # you do this by passing the `html:` option to any broadcast method that accepts the **rendering argument. Example:
31
31
  #
32
32
  # class Message < ApplicationRecord
33
33
  # belongs_to :user
@@ -40,6 +40,20 @@
40
40
  # end
41
41
  # end
42
42
  #
43
+ # If you want to render a template instead of a partial, e.g. ('messages/index' or 'messages/show'), you can use the `template:` option.
44
+ # Again, only to any broadcast method that accepts the `**rendering` argument. Example:
45
+ #
46
+ # class Message < ApplicationRecord
47
+ # belongs_to :user
48
+ #
49
+ # after_create_commit :update_message
50
+ #
51
+ # private
52
+ # def update_message
53
+ # broadcast_replace_to(user, :message, target: "message", template: "messages/show", locals: { message: self })
54
+ # end
55
+ # end
56
+ #
43
57
  # There are four basic actions you can broadcast: <tt>remove</tt>, <tt>replace</tt>, <tt>append</tt>, and
44
58
  # <tt>prepend</tt>. As a rule, you should use the <tt>_later</tt> versions of everything except for remove when broadcasting
45
59
  # within a real-time path, like a controller or model, since all those updates require a rendering step, which can slow down
@@ -335,8 +349,13 @@ module Turbo::Broadcastable
335
349
  # Add the current instance into the locals with the element name (which is the un-namespaced name)
336
350
  # as the key. This parallels how the ActionView::ObjectRenderer would create a local variable.
337
351
  o[:locals] = (o[:locals] || {}).reverse_merge!(model_name.element.to_sym => self)
338
- # if the html option is passed in it will skip setting a partial from #to_partial_path
339
- unless o.include?(:html)
352
+
353
+ if o[:html] || o[:partial]
354
+ return o
355
+ elsif o[:template]
356
+ o[:layout] = false
357
+ else
358
+ # if none of these options are passed in, it will set a partial from #to_partial_path
340
359
  o[:partial] ||= to_partial_path
341
360
  end
342
361
  end
@@ -227,6 +227,8 @@ class Turbo::Streams::TagBuilder
227
227
  private
228
228
  def render_template(target, content = nil, allow_inferred_rendering: true, **rendering, &block)
229
229
  case
230
+ when content.respond_to?(:render_in)
231
+ content.render_in(@view_context, &block)
230
232
  when content
231
233
  allow_inferred_rendering ? (render_record(content) || content) : content
232
234
  when block_given?
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <head>
3
+ <%= yield :head %>
4
+ </head>
5
+ <body>
6
+ <%= yield %>
7
+ </body>
8
+ </html>
data/lib/turbo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Turbo
2
- VERSION = "1.3.3"
2
+ VERSION = "1.4.0"
3
3
  end
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: 1.3.3
4
+ version: 1.4.0
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: 2023-01-31 00:00:00.000000000 Z
13
+ date: 2023-03-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activejob
@@ -87,6 +87,7 @@ files:
87
87
  - app/jobs/turbo/streams/broadcast_job.rb
88
88
  - app/models/concerns/turbo/broadcastable.rb
89
89
  - app/models/turbo/streams/tag_builder.rb
90
+ - app/views/layouts/turbo_rails/frame.html.erb
90
91
  - config/routes.rb
91
92
  - lib/install/turbo_needs_redis.rb
92
93
  - lib/install/turbo_with_importmap.rb
@@ -115,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
116
  - !ruby/object:Gem::Version
116
117
  version: '0'
117
118
  requirements: []
118
- rubygems_version: 3.4.5
119
+ rubygems_version: 3.4.6
119
120
  signing_key:
120
121
  specification_version: 4
121
122
  summary: The speed of a single-page web application without having to write any JavaScript.