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 +5 -5
- data/lib/assets/javascripts/turbograft/page.coffee +10 -10
- data/lib/assets/javascripts/turbograft/remote.coffee +10 -5
- data/lib/assets/javascripts/turbograft/response.coffee +9 -1
- data/lib/assets/javascripts/turbograft/turbohead.coffee +6 -1
- data/lib/assets/javascripts/turbograft/turbolinks.coffee +39 -37
- data/lib/turbograft.rb +10 -6
- data/lib/turbograft/redirection.rb +1 -2
- data/lib/turbograft/version.rb +1 -1
- data/lib/turbograft/x_domain_blocker.rb +2 -2
- data/lib/turbograft/xhr_headers.rb +24 -15
- metadata +12 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fba255993ff4ba3b193a70109a4635ebe5c672b2baa82e788f9e94f8d1d79fe5
|
4
|
+
data.tar.gz: 024e4089a512cfcaf3f3c1233eb58a44535f67be2a99257f7575c7880861fac5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
20
|
-
|
21
|
-
options.
|
19
|
+
turboOptions = {
|
20
|
+
partialReplace: true,
|
21
|
+
exceptKeys: options.exceptKeys,
|
22
|
+
onlyKeys: options.onlyKeys,
|
23
|
+
updatePushState: options.updatePushState,
|
24
|
+
callback: callback
|
25
|
+
}
|
22
26
|
|
23
|
-
|
24
|
-
|
25
|
-
Turbolinks.loadPage null, xhr, options
|
27
|
+
if xhr = options.response
|
28
|
+
Turbolinks.loadPage null, xhr, turboOptions
|
26
29
|
else
|
27
|
-
|
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
|
-
@
|
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
|
74
|
+
url = new ComponentUrl(url)
|
71
75
|
|
72
76
|
rememberReferer()
|
73
77
|
|
74
|
-
options
|
75
|
-
options.onlyKeys ?= []
|
76
|
-
options.onLoadFunction = ->
|
77
|
-
resetScrollPosition() unless options.onlyKeys.length
|
78
|
-
options.callback?()
|
78
|
+
fetchReplacement(url, options)
|
79
79
|
|
80
|
-
|
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
|
-
|
141
|
-
|
142
|
-
|
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(
|
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
|
-
|
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
|
-
|
165
|
-
|
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
|
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
|
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 |
|
22
|
-
|
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
|
12
|
+
response.content_type = Mime[:js]
|
14
13
|
end
|
15
14
|
end
|
16
15
|
end
|
data/lib/turbograft/version.rb
CHANGED
@@ -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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
40
|
-
|
41
|
-
|
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.
|
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:
|
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:
|
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.
|
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
|
-
|
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
|