turbograft 0.4.3 → 0.4.8

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
- SHA1:
3
- metadata.gz: 9334d30bbf9e86dd7baae353ac711bc9688f70ff
4
- data.tar.gz: 92bc6bf6eb003c707d82b1b28d7b71bd67e59ada
2
+ SHA256:
3
+ metadata.gz: fba255993ff4ba3b193a70109a4635ebe5c672b2baa82e788f9e94f8d1d79fe5
4
+ data.tar.gz: 024e4089a512cfcaf3f3c1233eb58a44535f67be2a99257f7575c7880861fac5
5
5
  SHA512:
6
- metadata.gz: 6625a059b2940513077f90ab4e11645e807cd57a62074815ed36f89710d28c3702a0277a90c62f243a079a0cc042011f8845cacd077f7881db43e576d478e5dd
7
- data.tar.gz: 02850cbe00f2c90a16a34fd2932fb458fe542f578b766e7b1709ff9c938a75d706c5b439639a6338d93be44c6e86a0d4d3a80af20ce0e9a8760b2b7544fc9f24
6
+ metadata.gz: e638743501bff1821d16afca2ee426081e85ff70d69b15647568c6fe2a766b089ee85f43d7138a60afe1cad2a235cdfeb25afb04c7d6dac92a42767bc125eb35
7
+ data.tar.gz: f6a539ce14d10aefb28f500a2e9834a8a888851762ffa143667a6c1bc54a22948609c6498a7f611ab3208065e3e7680370de41f9ad79e038177f4a54de1a0c8b
@@ -16,18 +16,18 @@ Page.refresh = (options = {}, callback) ->
16
16
  else
17
17
  location.href
18
18
 
19
- if options.response
20
- options.partialReplace = true
21
- options.onLoadFunction = callback
19
+ turboOptions = {
20
+ partialReplace: true,
21
+ exceptKeys: options.exceptKeys,
22
+ onlyKeys: options.onlyKeys,
23
+ updatePushState: options.updatePushState,
24
+ callback: callback
25
+ }
22
26
 
23
- xhr = options.response
24
- delete options.response
25
- Turbolinks.loadPage null, xhr, options
27
+ if xhr = options.response
28
+ Turbolinks.loadPage null, xhr, turboOptions
26
29
  else
27
- options.partialReplace = true
28
- options.callback = callback if callback
29
-
30
- Turbolinks.visit newUrl, options
30
+ Turbolinks.visit newUrl, turboOptions
31
31
 
32
32
  Page.open = ->
33
33
  window.open(arguments...)
@@ -134,16 +134,19 @@ class TurboGraft.Remote
134
134
  else if @opts.fullRefresh
135
135
  Page.refresh()
136
136
  else if @refreshOnSuccess
137
- Page.refresh
137
+ Page.refresh(
138
138
  response: xhr
139
139
  onlyKeys: @refreshOnSuccess
140
+ )
140
141
  else if @refreshOnSuccessExcept
141
- Page.refresh
142
+ Page.refresh(
142
143
  response: xhr
143
144
  exceptKeys: @refreshOnSuccessExcept
145
+ )
144
146
  else
145
- Page.refresh
147
+ Page.refresh(
146
148
  response: xhr
149
+ )
147
150
 
148
151
  onError: (ev) =>
149
152
  @opts.fail?()
@@ -162,13 +165,15 @@ class TurboGraft.Remote
162
165
  else if @opts.fullRefresh
163
166
  Page.refresh()
164
167
  else if @refreshOnError
165
- Page.refresh
168
+ Page.refresh(
166
169
  response: xhr
167
170
  onlyKeys: @refreshOnError
171
+ )
168
172
  else if @refreshOnErrorExcept
169
- Page.refresh
173
+ Page.refresh(
170
174
  response: xhr
171
175
  exceptKeys: @refreshOnErrorExcept
176
+ )
172
177
  else
173
178
  triggerEventFor 'turbograft:remote:fail:unhandled', @initiator,
174
179
  xhr: xhr
@@ -1,5 +1,11 @@
1
1
  class TurboGraft.Response
2
- constructor: (@xhr) ->
2
+ constructor: (@xhr, intendedURL) ->
3
+ if intendedURL && intendedURL.withoutHash() != @xhr.responseURL
4
+ redirectedTo = @xhr.responseURL
5
+ else
6
+ redirectedTo = @xhr.getResponseHeader('X-XHR-Redirected-To')
7
+
8
+ @finalURL = redirectedTo || intendedURL
3
9
 
4
10
  valid: -> @hasRenderableHttpStatus() && @hasValidContent()
5
11
 
@@ -21,3 +27,5 @@ class TurboGraft.Response
21
27
  "URL: #{@xhr.responseURL}, " +
22
28
  "ReadyState: #{@xhr.readyState}, " +
23
29
  "Headers: #{@xhr.getAllResponseHeaders()}"
30
+
31
+ TurboGraft.location = () -> location.href
@@ -44,6 +44,9 @@ class TurboGraft.TurboHead
44
44
  noMatchingSrc(node) || noMatchingHref(node)
45
45
  )
46
46
 
47
+ movingFromTrackedToUntracked: () ->
48
+ @upstreamAssets.length == 0 && @activeAssets.length > 0
49
+
47
50
  hasNamedAssetConflicts: () ->
48
51
  @newScripts
49
52
  .concat(@newLinks)
@@ -51,7 +54,9 @@ class TurboGraft.TurboHead
51
54
  .some(datasetMatchesIn(TRACKED_ATTRIBUTE_NAME, @activeAssets))
52
55
 
53
56
  hasAssetConflicts: () ->
54
- @hasNamedAssetConflicts() || @hasChangedAnonymousAssets()
57
+ @movingFromTrackedToUntracked() ||
58
+ @hasNamedAssetConflicts() ||
59
+ @hasChangedAnonymousAssets()
55
60
 
56
61
  waitForAssets: () ->
57
62
  resolvePreviousRequest?(isCanceled: true)
@@ -1,3 +1,7 @@
1
+ Response = TurboGraft.Response
2
+ TurboHead = TurboGraft.TurboHead
3
+ jQuery = window.jQuery
4
+
1
5
  xhr = null
2
6
  activeDocument = document
3
7
 
@@ -67,17 +71,18 @@ class window.Turbolinks
67
71
 
68
72
  fetch = (url, options = {}) ->
69
73
  return if pageChangePrevented(url)
70
- url = new ComponentUrl url
74
+ url = new ComponentUrl(url)
71
75
 
72
76
  rememberReferer()
73
77
 
74
- options.partialReplace ?= false
75
- options.onlyKeys ?= []
76
- options.onLoadFunction = ->
77
- resetScrollPosition() unless options.onlyKeys.length
78
- options.callback?()
78
+ fetchReplacement(url, options)
79
79
 
80
- fetchReplacement url, options
80
+ isPartialReplace = (response, options) ->
81
+ Boolean(
82
+ options.partialReplace ||
83
+ options.onlyKeys?.length ||
84
+ options.exceptKeys?.length
85
+ )
81
86
 
82
87
  @fullPageNavigate: (url) ->
83
88
  if url?
@@ -136,24 +141,28 @@ class window.Turbolinks
136
141
 
137
142
  @loadPage: (url, xhr, options = {}) ->
138
143
  triggerEvent 'page:receive'
144
+ response = new Response(xhr, url)
139
145
  options.updatePushState ?= true
140
- if upstreamDocument = new TurboGraft.Response(xhr).document()
141
- if options.partialReplace
142
- reflectNewUrl url if options.updatePushState
143
- updateBody(upstreamDocument, xhr, options)
144
- else
145
- turbohead = new TurboGraft.TurboHead(activeDocument, upstreamDocument)
146
- if turbohead.hasAssetConflicts()
147
- return Turbolinks.fullPageNavigate(url)
148
- reflectNewUrl url if options.updatePushState
149
- turbohead.waitForAssets().then((result) ->
150
- updateBody(upstreamDocument, xhr, options) unless result?.isCanceled
151
- )
152
- else
146
+ options.partialReplace = isPartialReplace(response, options)
147
+
148
+ unless upstreamDocument = response.document()
153
149
  triggerEvent 'page:error', xhr
154
- Turbolinks.fullPageNavigate(url)
150
+ Turbolinks.fullPageNavigate(response.finalURL)
151
+ return
152
+
153
+ if options.partialReplace
154
+ updateBody(upstreamDocument, response, options)
155
+ return
156
+
157
+ turbohead = new TurboHead(activeDocument, upstreamDocument)
158
+ if turbohead.hasAssetConflicts()
159
+ return Turbolinks.fullPageNavigate(response.finalURL)
155
160
 
156
- updateBody = (upstreamDocument, xhr, options) ->
161
+ turbohead.waitForAssets().then((result) ->
162
+ updateBody(upstreamDocument, response, options) unless result?.isCanceled
163
+ )
164
+
165
+ updateBody = (upstreamDocument, response, options) ->
157
166
  nodes = changePage(
158
167
  upstreamDocument.querySelector('title')?.textContent,
159
168
  removeNoscriptTags(upstreamDocument.querySelector('body')),
@@ -161,16 +170,17 @@ class window.Turbolinks
161
170
  'runScripts',
162
171
  options
163
172
  )
164
- reflectRedirectedUrl(xhr) if options.updatePushState
165
- options.onLoadFunction?()
173
+ reflectNewUrl(response.finalURL) if options.updatePushState
174
+
175
+ Turbolinks.resetScrollPosition() unless options.partialReplace
176
+
177
+ options.callback?()
166
178
  triggerEvent 'page:load', nodes
167
179
 
168
180
  changePage = (title, body, csrfToken, runScripts, options = {}) ->
169
181
  activeDocument.title = title if title
170
- options.onlyKeys ?= []
171
- options.exceptKeys ?= []
172
182
 
173
- if options.onlyKeys.length
183
+ if options.onlyKeys?.length
174
184
  nodesToRefresh = [].concat(getNodesWithRefreshAlways(), getNodesMatchingRefreshKeys(options.onlyKeys))
175
185
  nodes = refreshNodes(nodesToRefresh, body)
176
186
  setAutofocusElement() if anyAutofocusElement(nodes)
@@ -178,7 +188,7 @@ class window.Turbolinks
178
188
  else
179
189
  refreshNodes(getNodesWithRefreshAlways(), body)
180
190
  persistStaticElements(body)
181
- if options.exceptKeys.length
191
+ if options.exceptKeys?.length
182
192
  refreshAllExceptWithKeys(options.exceptKeys, body)
183
193
  else
184
194
  deleteRefreshNeverNodes(body)
@@ -307,14 +317,6 @@ class window.Turbolinks
307
317
  Turbolinks.pushState { turbolinks: true, url: url.absolute }, '', url.absolute
308
318
  return
309
319
 
310
- reflectRedirectedUrl = (xhr) ->
311
- if location = xhr.getResponseHeader 'X-XHR-Redirected-To'
312
- location = new ComponentUrl location
313
- preservedHash = if location.hasNoHash() then activeDocument.location.hash else ''
314
- Turbolinks.replaceState currentState, '', location.href + preservedHash
315
-
316
- return
317
-
318
320
  rememberReferer = ->
319
321
  referer = activeDocument.location.href
320
322
 
@@ -327,7 +329,7 @@ class window.Turbolinks
327
329
  recallScrollPosition = (page) ->
328
330
  window.scrollTo page.positionX, page.positionY
329
331
 
330
- resetScrollPosition = ->
332
+ @resetScrollPosition: ->
331
333
  if activeDocument.location.hash
332
334
  activeDocument.location.href = activeDocument.location.href
333
335
  else
data/lib/turbograft.rb CHANGED
@@ -14,16 +14,20 @@ module TurboGraft
14
14
  self.controllers = ["ActionController::Base"]
15
15
  end
16
16
 
17
+ def self.included(controller)
18
+ controller.class_eval do
19
+ include XHRHeaders, Cookies, XDomainBlocker, Redirection
20
+ before_action :set_xhr_redirected_to, :set_request_method_cookie
21
+ after_action :abort_xdomain_redirect
22
+ end
23
+ end
24
+
17
25
  class Engine < ::Rails::Engine
18
26
 
19
27
  initializer :turbograft do |config|
20
28
  ActiveSupport.on_load(:action_controller) do
21
- Config.controllers.each do |klass|
22
- klass.constantize.class_eval do
23
- include XHRHeaders, Cookies, XDomainBlocker, Redirection
24
- before_action :set_xhr_redirected_to, :set_request_method_cookie
25
- after_action :abort_xdomain_redirect
26
- end
29
+ Config.controllers.each do |class_name|
30
+ class_name.constantize.include(::TurboGraft)
27
31
  end
28
32
 
29
33
  ActionDispatch::Request.class_eval do
@@ -7,10 +7,9 @@ module TurboGraft
7
7
  private
8
8
  def redirect_via_turbolinks_to(url = {}, response_status = {})
9
9
  redirect_to(url, response_status)
10
-
11
10
  self.status = 200
12
11
  self.response_body = "Turbolinks.visit('#{location}');"
13
- response.content_type = Mime::JS
12
+ response.content_type = Mime[:js]
14
13
  end
15
14
  end
16
15
  end
@@ -1,3 +1,3 @@
1
1
  module TurboGraft
2
- VERSION = '0.4.3'
2
+ VERSION = '0.4.8'
3
3
  end
@@ -5,8 +5,8 @@ module TurboGraft
5
5
  module XDomainBlocker
6
6
  private
7
7
  def same_origin?(a, b)
8
- a = URI.parse URI.escape(a)
9
- b = URI.parse URI.escape(b)
8
+ a = URI.parse URI::DEFAULT_PARSER.escape(a)
9
+ b = URI.parse URI::DEFAULT_PARSER.escape(b)
10
10
  [a.scheme, a.host, a.port] == [b.scheme, b.host, b.port]
11
11
  end
12
12
 
@@ -25,23 +25,32 @@ module TurboGraft
25
25
  end
26
26
 
27
27
  private
28
- def store_for_turbolinks(url)
29
- session[:_turbolinks_redirect_to] = url if session && request.headers["X-XHR-Referer"]
30
- url
31
- end
32
28
 
33
- def set_xhr_redirected_to
34
- if session && session[:_turbolinks_redirect_to]
35
- response.headers['X-XHR-Redirected-To'] = session.delete :_turbolinks_redirect_to
36
- end
37
- end
29
+ # Ensure backwards compatibility
30
+ # Rails < 4.2: _compute_redirect_to_location(options)
31
+ # Rails >= 4.2: _compute_redirect_to_location(request, options)
32
+ def _normalize_redirect_params(args)
33
+ options, req = args.reverse
34
+ [options, req || request]
35
+ end
36
+
37
+ def store_for_turbolinks(url)
38
+ session[:_turbolinks_redirect_to] = url if session && request.headers["X-XHR-Referer"]
39
+ url
40
+ end
38
41
 
39
- # Ensure backwards compatibility
40
- # Rails < 4.2: _compute_redirect_to_location(options)
41
- # Rails >= 4.2: _compute_redirect_to_location(request, options)
42
- def _normalize_redirect_params(args)
43
- options, req = args.reverse
44
- [options, req || request]
42
+ def set_xhr_redirected_to
43
+ if turbolinks_redirected? && request_matches_redirect?
44
+ response.headers['X-XHR-Redirected-To'] = session.delete(:_turbolinks_redirect_to)
45
45
  end
46
+ end
47
+
48
+ def turbolinks_redirected?
49
+ session && session[:_turbolinks_redirect_to]
50
+ end
51
+
52
+ def request_matches_redirect?
53
+ session[:_turbolinks_redirect_to] == request.original_url
54
+ end
46
55
  end
47
56
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbograft
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristian Plettenberg-Dussault
@@ -10,10 +10,12 @@ authors:
10
10
  - Tyler Mercier
11
11
  - Anthony Cameron
12
12
  - Patrick Donovan
13
+ - Mathew Allen
14
+ - Gord Pearson
13
15
  autorequire:
14
16
  bindir: bin
15
17
  cert_chain: []
16
- date: 2016-10-05 00:00:00.000000000 Z
18
+ date: 2021-03-19 00:00:00.000000000 Z
17
19
  dependencies:
18
20
  - !ruby/object:Gem::Dependency
19
21
  name: coffee-rails
@@ -211,9 +213,11 @@ dependencies:
211
213
  - - ">="
212
214
  - !ruby/object:Gem::Version
213
215
  version: '0'
214
- description: It's like turbolinks, but with partial page replacement and tests
216
+ description: Turbograft is a hard fork of Turbolinks, allowing you to perform partial
217
+ page refreshes and offering ajax form utilities.
215
218
  email:
216
219
  - tylermercier@gmail.com
220
+ - mathew.allen@shopify.com
217
221
  executables: []
218
222
  extensions: []
219
223
  extra_rdoc_files: []
@@ -242,24 +246,24 @@ files:
242
246
  homepage: https://github.com/Shopify/turbograft
243
247
  licenses:
244
248
  - MIT
245
- metadata: {}
249
+ metadata:
250
+ allowed_push_host: https://rubygems.org
246
251
  post_install_message:
247
252
  rdoc_options: []
248
253
  require_paths:
249
254
  - lib
250
255
  required_ruby_version: !ruby/object:Gem::Requirement
251
256
  requirements:
252
- - - "~>"
257
+ - - ">="
253
258
  - !ruby/object:Gem::Version
254
- version: '2.1'
259
+ version: '2.5'
255
260
  required_rubygems_version: !ruby/object:Gem::Requirement
256
261
  requirements:
257
262
  - - ">="
258
263
  - !ruby/object:Gem::Version
259
264
  version: '0'
260
265
  requirements: []
261
- rubyforge_project:
262
- rubygems_version: 2.5.1
266
+ rubygems_version: 3.0.3
263
267
  signing_key:
264
268
  specification_version: 4
265
269
  summary: turbolinks with partial page replacement