turbograft 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- 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 +15 -1
- data/lib/assets/javascripts/turbograft/turbohead.coffee +6 -1
- data/lib/assets/javascripts/turbograft/turbolinks.coffee +39 -37
- data/lib/turbograft/version.rb +1 -1
- data/lib/turbograft/xhr_headers.rb +24 -15
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 433d009a932180009262cbcd89d39cbff1d8410e
|
4
|
+
data.tar.gz: 89fbc6072f6b803015c9e817d0ff3f6d7938fbd5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 747bf89f153ced295b2ea0ab4e0fe69ecba0728a8ad7c5f8bc5b639d86b1d31c25f43ca7f180c7657d566ae3daffabe12e46b59cf53ac890ba9345b8efbee255
|
7
|
+
data.tar.gz: 19ac8dbfc36d19dcac93313b9e09ad0e87a9d1fadbe35ef13671fd00892f803578b69c01c708e26096b4c558200f9af054f8625d34c84f8e7ab4b5ea58f8d081
|
@@ -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
|
|
@@ -17,7 +23,15 @@ class TurboGraft.Response
|
|
17
23
|
else
|
18
24
|
throw new Error("Error encountered for XHR Response: #{this}")
|
19
25
|
|
26
|
+
redirectedToNewUrl: () ->
|
27
|
+
Boolean(
|
28
|
+
@redirectedTo &&
|
29
|
+
@redirectedTo != TurboGraft.location()
|
30
|
+
)
|
31
|
+
|
20
32
|
toString: () ->
|
21
33
|
"URL: #{@xhr.responseURL}, " +
|
22
34
|
"ReadyState: #{@xhr.readyState}, " +
|
23
35
|
"Headers: #{@xhr.getAllResponseHeaders()}"
|
36
|
+
|
37
|
+
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
|
+
) && !response.redirectedToNewUrl()
|
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/version.rb
CHANGED
@@ -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.4
|
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
|
18
|
+
date: 2016-11-10 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: []
|