turbolinks_render 0.9.1 → 0.9.9

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: c45620397713bf0e33c196b245c7e37c9afd54aca8f9eee9a7fd3bbf36dee141
4
- data.tar.gz: d6272756f224fa2ebe50364886eff3832613f12d6848e628c9c4bf50e76538ca
3
+ metadata.gz: e280f90e434bbda7fac2a73678441b6d1549bcd26a34b36a02e7bc430268a323
4
+ data.tar.gz: 2f234433939c2dee28c31d6aacc3a4c178dfcd048d1af868ae4e32c7dae21df7
5
5
  SHA512:
6
- metadata.gz: b7f5293cf867a102c07d7de67853edc8441248b96b48bb0e667350a7d2e5b89903a48ae6aee1e3de7c2e452affc86187775102061fae69ccd0e5d795d52cba83
7
- data.tar.gz: 6f0204ce2d3995f80a5591d1de1be57a20050fdbb703c9df1e0eece0e193c80113e5a4888ecf0672e2bac2b534efdd1631822ea6b4ef6a450e40672db44b59bc
6
+ metadata.gz: a1660d462adac9c80204cb3d34fa832ded9c3ab6c29c3e28269cb5d1f9a17513595033b15045aa0be07c10e52e30e62a43dbad745e4d43f546ab651dca0e5a96
7
+ data.tar.gz: 80d496e2d359a3230388e31c39bdb17bc2e2da1dc9646959ae531d8d90e0cf914b8bc9dee99ade1ebb85c00927c1dda763a292054971d491205150a1f339d03f
data/README.md CHANGED
@@ -1,14 +1,18 @@
1
1
  # turbolinks_render
2
2
 
3
+ [![Build Status](https://travis-ci.org/jorgemanrubia/turbolinks_render.svg?branch=master)](https://travis-ci.org/jorgemanrubia/turbolinks_render)
4
+
3
5
  Use `render` in your Rails controllers and handle the response with Turbolinks.
4
6
 
5
7
  Turbolinks supports [`redirect_to`](https://github.com/turbolinks/turbolinks/blob/master/README.md#redirecting-after-a-form-submission) out of the box. But `render` is not supported and you have to use [workarounds for common things like dealing with forms](https://github.com/turbolinks/turbolinks/issues/85). This gem aims to fix that.
6
8
 
9
+ I think Turbolinks/Rails should handle this officially. If you agree [you can vote for this idea](https://github.com/turbolinks/turbolinks-rails/issues/40).
10
+
7
11
  ## Installation
8
12
  Add this line to your application's Gemfile:
9
13
 
10
14
  ```ruby
11
- gem 'turboilnks_render'
15
+ gem 'turbolinks_render'
12
16
  ```
13
17
 
14
18
  And then execute:
@@ -24,6 +28,11 @@ By default, `render` will be handled by Turbolinks if these conditions are met:
24
28
  - It's not a `get` request
25
29
  - It's not rendering json
26
30
 
31
+ When these conditions are met and `render` is used:
32
+
33
+ - The body of the page is replaced with the rendered content with Javascript
34
+ - An event `turbolinks:load` is dispatched
35
+
27
36
  You can disable turbolinks on a given request with:
28
37
 
29
38
  ```ruby
@@ -44,6 +53,10 @@ In this case, to use turbolinks you should write:
44
53
  render turbolinks: true
45
54
  ```
46
55
 
56
+ ## Example
57
+
58
+ An [example](https://github.com/jorgemanrubia/rails-form-validations-example) and an [explanatory blog post](https://www.jorgemanrubia.com/2019/02/16/form-validations-with-html5-and-modern-rails/) are also available.
59
+
47
60
  ## Credits
48
61
 
49
62
  - [Implementation based on this idea by @nerdcave](https://github.com/turbolinks/turbolinks/issues/85#issuecomment-298347900).
@@ -1,15 +1,33 @@
1
1
  require 'turbolinks_render/version'
2
2
  require 'turbolinks_render/rendering'
3
+ require 'turbolinks_render/middleware'
4
+ require 'turbolinks_render/debug_exceptions_patch'
3
5
 
4
6
  module TurbolinksRender
7
+ class TurbolinksRenderMiddleware
8
+ def initialize(app)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ @status, @headers, @response = @app.call(env)
14
+ end
15
+ end
16
+
5
17
  class Engine < ::Rails::Railtie
6
18
  config.turbolinks_render = ActiveSupport::OrderedOptions.new
7
19
  config.turbolinks_render.render_with_turbolinks_by_default = true
8
20
 
9
21
  initializer :turbolinks_render do |app|
22
+ app.config.app_middleware.insert_before ActionDispatch::ShowExceptions, TurbolinksRender::Middleware
23
+
10
24
  ActiveSupport.on_load(:action_controller) do
11
25
  include Rendering
12
26
  end
27
+
28
+ class ActionDispatch::DebugExceptions
29
+ prepend DebugExceptionsPatch
30
+ end
13
31
  end
14
32
  end
15
33
  end
@@ -0,0 +1,18 @@
1
+ module TurbolinksRender
2
+ # Patch for ActionDispatch::DebugExceptions middleware
3
+ module DebugExceptionsPatch
4
+ def render_for_browser_request(request, wrapper)
5
+ template = create_template(request, wrapper)
6
+ file = "rescues/#{wrapper.rescue_template}"
7
+
8
+ if request.xhr? && !request.get_header('X-Turbolinks-Render-Candidate')
9
+ body = template.render(template: file, layout: false, formats: [:text])
10
+ format = "text/plain"
11
+ else
12
+ body = template.render(template: file, layout: "rescues/layout")
13
+ format = "text/html"
14
+ end
15
+ render(wrapper.status_code, body, format)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,70 @@
1
+ module TurbolinksRender
2
+ class Middleware
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ @request = Rack::Request.new(env)
9
+ @request.set_header('X-Turbolinks-Render-Candidate', turbolinks_response_candidate?)
10
+
11
+ @status, @headers, @response = @app.call(env)
12
+
13
+ return [@status, @headers, @response] if file? || (!@response.respond_to?(:body) && !@response.respond_to?(:[]))
14
+
15
+ body = @response.respond_to?(:body) ? @response.body : @response[0]
16
+ body = render_body_with_turbolinks(body) if render_with_turbolinks?
17
+ [@status, @headers, [body]]
18
+ end
19
+
20
+ private
21
+
22
+ def render_body_with_turbolinks(body)
23
+ @headers["Content-Type"] = 'text/javascript'
24
+ build_turbolinks_response_to_render(body).tap do |turbolinks_body|
25
+ @headers["Content-Length"] = turbolinks_body.length
26
+ end
27
+ end
28
+
29
+ def file?
30
+ @headers["Content-Transfer-Encoding"] == "binary"
31
+ end
32
+
33
+ def render_with_turbolinks?
34
+ turbolinks_response_candidate? && html_response? && (turbolinks_render_option ||
35
+ (render_with_turbolinks_by_default? && turbolinks_render_option != false))
36
+ end
37
+
38
+ def turbolinks_render_option
39
+ @request.get_header('X-Turbolinks-Render-Option')
40
+ end
41
+
42
+ def turbolinks_response_candidate?
43
+ @request.xhr? && !@request.get?
44
+ end
45
+
46
+ def html_response?
47
+ @headers['Content-Type'] =~ /text\/html/
48
+ end
49
+
50
+ def build_turbolinks_response_to_render(html)
51
+ escaped_html = ActionController::Base.helpers.j(html)
52
+
53
+ <<-JS
54
+ (function(){
55
+ Turbolinks.clearCache();
56
+ document.open();
57
+ document.write("#{escaped_html}");
58
+ document.close();
59
+ Turbolinks.dispatch('turbolinks:load');
60
+ window.scroll(0, 0);
61
+ })();
62
+ JS
63
+ end
64
+
65
+ def render_with_turbolinks_by_default?
66
+ Rails.application.config.turbolinks_render.render_with_turbolinks_by_default
67
+ end
68
+
69
+ end
70
+ end
@@ -4,53 +4,14 @@ module TurbolinksRender
4
4
 
5
5
  def render(*args, &block)
6
6
  options = args.dup.extract_options!
7
- if render_with_turbolinks?(options)
8
- render_with_turbolinks(*args, &block)
9
- else
10
- super
11
- end
7
+ capture_turbolinks_option_to_make_it_accessible_by_middleware(options)
8
+ super
12
9
  end
13
10
 
14
11
  private
15
12
 
16
- def render_with_turbolinks?(options)
17
- request_candidate_for_turbolinks? && !json_response?(options) &&
18
- (options[:turbolinks] || (render_with_turbolinks_by_default? && options[:turbolinks] != false))
19
- end
20
-
21
- def request_candidate_for_turbolinks?
22
- request.xhr? && !request.get?
23
- end
24
-
25
- def render_with_turbolinks_by_default?
26
- Rails.application.config.turbolinks_render.render_with_turbolinks_by_default
27
- end
28
-
29
- def json_response?(options)
30
- options[:json]
31
- end
32
-
33
- def render_with_turbolinks(*args, &block)
34
- html = render_to_string(*args, &block)
35
- self.response_body = build_turbolinks_response_to_render(html)
36
- self.status = 200
37
- response.content_type = 'text/javascript'
38
- end
39
-
40
- def build_turbolinks_response_to_render(html)
41
- escaped_html = ActionController::Base.helpers.j(html)
42
-
43
- <<-JS
44
- (function(){
45
- Turbolinks.clearCache();
46
- var parser = new DOMParser();
47
- var newDocument = parser.parseFromString("#{escaped_html}", "text/html");
48
-
49
- document.documentElement.replaceChild(newDocument.body, document.body);
50
- Turbolinks.dispatch('turbolinks:load');
51
- window.scroll(0, 0);
52
- })();
53
- JS
13
+ def capture_turbolinks_option_to_make_it_accessible_by_middleware(options)
14
+ request.set_header('X-Turbolinks-Render-Option', options[:turbolinks])
54
15
  end
55
16
  end
56
17
  end
@@ -1,3 +1,3 @@
1
1
  module TurbolinksRender
2
- VERSION = '0.9.1'
2
+ VERSION = '0.9.9'
3
3
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbolinks_render
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jorge Manrubia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-19 00:00:00.000000000 Z
11
+ date: 2019-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 5.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 5.2.0
27
27
  - !ruby/object:Gem::Dependency
@@ -133,6 +133,8 @@ files:
133
133
  - README.md
134
134
  - Rakefile
135
135
  - lib/turbolinks_render.rb
136
+ - lib/turbolinks_render/debug_exceptions_patch.rb
137
+ - lib/turbolinks_render/middleware.rb
136
138
  - lib/turbolinks_render/rendering.rb
137
139
  - lib/turbolinks_render/version.rb
138
140
  homepage: https://github.com/jorgemanrubia/turbolinks_render
@@ -155,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
157
  version: '0'
156
158
  requirements: []
157
159
  rubyforge_project:
158
- rubygems_version: 2.7.3
160
+ rubygems_version: 2.7.6
159
161
  signing_key:
160
162
  specification_version: 4
161
163
  summary: Use Rails render with Turbolinks