turbograft 0.0.8 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de6aed257f2451693856924987ff6238f3b86f6f
4
- data.tar.gz: 020bf3757da79669cca06b78dc237f7f0f423bd2
3
+ metadata.gz: 1adee05ec0b9f2e394fd907aa38f75574715bcd1
4
+ data.tar.gz: 4d7a8bcaf0016e552e684b38dd0323a7f455b71f
5
5
  SHA512:
6
- metadata.gz: 950bfd3d8f0f12ccc9089a66383c6197f9288e4ea8f3fdd5122168102fdcfa9a4e3627077f4bbc31fb7a48293378195f91afc4135a192c72e3c53f3ed21bdf7f
7
- data.tar.gz: 19a95050d2a3d94fdb4ba20a804b94e1edba12f1afa83a0ba1b1d36df0ef37797fd8769899aeefac92d81afc2cf0c6b727da776cc8eba6b80d2a4bc4966881fc
6
+ metadata.gz: 41bfd3ae74adb0c3f62c7cefb2ee566ea1193cb2398a37b11186fd9a57289a6772b16b58de58c6237989e1196f65544a6ee931aacebabebfd663648b4075e744
7
+ data.tar.gz: 1cd3bc34fd7021780ae31120991cd16bba9cafc8e6f10ea0812f272ebb0816fb0e6a200001810bd16b82f909af901755af953ae42f2843b7a5dd7e21e0579452
data/README.md CHANGED
@@ -12,17 +12,9 @@ In botony, one can take parts of a tree and splice it onto another tree. The DO
12
12
 
13
13
  ## Installation
14
14
 
15
- Add this line to your application's Gemfile:
16
-
17
- gem 'turbograft'
18
-
19
- And then execute:
20
-
21
- $ bundle
22
-
23
- Or install it yourself as:
24
-
25
- $ gem install turbograft
15
+ * Add `gem "turbograft"` to your Gemfile
16
+ * Run `bundle install`
17
+ * Add `#= require turbograft` to _app/assets/javascripts/application.js_
26
18
 
27
19
  ## Usage
28
20
 
@@ -15,12 +15,9 @@ class window.Click
15
15
  return if @event.defaultPrevented
16
16
  @_extractLink()
17
17
  if @_validForTurbolinks()
18
- Turbolinks.visit @link.href unless @_pageChangePrevented()
18
+ Turbolinks.visit @link.href
19
19
  @event.preventDefault()
20
20
 
21
- _pageChangePrevented: ->
22
- !triggerEvent 'page:before-change' # TODO: fix this global
23
-
24
21
  _extractLink: ->
25
22
  link = @event.target
26
23
  link = link.parentNode until !link.parentNode or link.nodeName is 'A'
@@ -38,8 +38,9 @@ TurboGraft.handlers.remoteMethodHandler = (ev) ->
38
38
  fullRefresh: target.getAttribute('full-refresh')?
39
39
  refreshOnSuccess: target.getAttribute('refresh-on-success')
40
40
  refreshOnError: target.getAttribute('refresh-on-error')
41
+ refreshOnErrorExcept: target.getAttribute('full-refresh-on-error-except')
41
42
 
42
- if !options.refreshOnSuccess && !options.refreshOnError
43
+ if !options.refreshOnSuccess && !options.refreshOnError && !options.refreshOnErrorExcept
43
44
  options.fullRefresh = true
44
45
 
45
46
  remote = new TurboGraft.Remote(options, null, target)
@@ -60,8 +61,9 @@ TurboGraft.handlers.remoteFormHandler = (ev) ->
60
61
  fullRefresh: target.getAttribute('full-refresh')?
61
62
  refreshOnSuccess: target.getAttribute('refresh-on-success')
62
63
  refreshOnError: target.getAttribute('refresh-on-error')
64
+ refreshOnErrorExcept: target.getAttribute('full-refresh-on-error-except')
63
65
 
64
- if !options.refreshOnSuccess && !options.refreshOnError
66
+ if !options.refreshOnSuccess && !options.refreshOnError && !options.refreshOnErrorExcept
65
67
  options.fullRefresh = true
66
68
 
67
69
  remote = new TurboGraft.Remote(options, target, target)
@@ -17,7 +17,9 @@ Page.refresh = (options = {}, callback) ->
17
17
  location.href
18
18
 
19
19
  if options.response
20
- Turbolinks.loadPage null, options.response, true, callback, options.onlyKeys || []
20
+ onlyKeys = options.onlyKeys || []
21
+ exceptKeys = options.exceptKeys || []
22
+ Turbolinks.loadPage null, options.response, true, callback, onlyKeys, exceptKeys
21
23
  else
22
24
  Turbolinks.visit newUrl, true, options.onlyKeys || [], -> callback?()
23
25
 
@@ -1,24 +1,24 @@
1
1
  class TurboGraft.Remote
2
2
  constructor: (@opts, form, target) ->
3
- formData = if form then new FormData(form) else new FormData()
4
-
5
- @initiator = target
3
+ formData = if form then new FormData(form) else new FormData()
4
+ @initiator = target || form
6
5
 
7
6
  actualRequestType = if @opts.httpRequestType.toLowerCase() == 'get' then 'GET' else 'POST'
8
7
 
9
8
  formData.append("_method", @opts.httpRequestType)
10
9
 
11
- @refreshOnSuccess = @opts.refreshOnSuccess.split(" ") if @opts.refreshOnSuccess
12
- @refreshOnError = @opts.refreshOnError.split(" ") if @opts.refreshOnError
10
+ @refreshOnSuccess = @opts.refreshOnSuccess.split(" ") if @opts.refreshOnSuccess
11
+ @refreshOnError = @opts.refreshOnError.split(" ") if @opts.refreshOnError
12
+ @refreshOnErrorExcept = @opts.refreshOnErrorExcept.split(" ") if @opts.refreshOnErrorExcept
13
13
 
14
14
  xhr = new XMLHttpRequest
15
15
  xhr.open(actualRequestType, @opts.httpUrl, true)
16
16
  xhr.setRequestHeader('Accept', 'text/html, application/xhtml+xml, application/xml')
17
+ triggerEventFor('turbograft:remote:init', @initiator, xhr: xhr)
17
18
 
18
19
  xhr.addEventListener 'loadstart', =>
19
- triggerEvent 'turbograft:remote:start',
20
- xhr: xhr,
21
- initiator: @initiator
20
+ triggerEventFor 'turbograft:remote:start', @initiator,
21
+ xhr: xhr
22
22
 
23
23
  xhr.addEventListener 'error', @onError
24
24
  xhr.addEventListener 'load', (event) =>
@@ -28,18 +28,16 @@ class TurboGraft.Remote
28
28
  @onError(event)
29
29
 
30
30
  xhr.addEventListener 'loadend', =>
31
- triggerEvent 'turbograft:remote:always',
32
- xhr: xhr,
33
- initiator: @initiator
31
+ triggerEventFor 'turbograft:remote:always', @initiator,
32
+ xhr: xhr
34
33
 
35
34
  xhr.send(formData)
36
35
  xhr
37
36
 
38
37
  onSuccess: (ev) ->
39
38
  xhr = ev.target
40
- triggerEvent 'turbograft:remote:success',
41
- xhr: xhr,
42
- initiator: @initiator
39
+ triggerEventFor 'turbograft:remote:success', @initiator,
40
+ xhr: xhr
43
41
 
44
42
  if redirect = xhr.getResponseHeader('X-Next-Redirect')
45
43
  Page.visit(redirect, reload: true)
@@ -56,15 +54,14 @@ class TurboGraft.Remote
56
54
 
57
55
  onError: (ev) ->
58
56
  xhr = ev.target
59
- triggerEvent 'turbograft:remote:fail',
60
- xhr: xhr,
61
- initiator: @initiator
57
+ triggerEventFor 'turbograft:remote:fail', @initiator,
58
+ xhr: xhr
62
59
 
63
- if @refreshOnError
60
+ if @refreshOnError || @refreshOnErrorExcept
64
61
  Page.refresh
65
62
  response: xhr
66
63
  onlyKeys: @refreshOnError
64
+ exceptKeys: @refreshOnErrorExcept
67
65
  else
68
- triggerEvent 'turbograft:remote:fail:unhandled',
69
- xhr: xhr,
70
- initiator: @initiator
66
+ triggerEventFor 'turbograft:remote:fail:unhandled', @initiator,
67
+ xhr: xhr
@@ -1,4 +1,4 @@
1
- xhr = null
1
+ xhr = null
2
2
 
3
3
  installDocumentReadyPageEventTriggers = ->
4
4
  document.addEventListener 'DOMContentLoaded', ( ->
@@ -28,6 +28,12 @@ window.triggerEvent = (name, data) ->
28
28
  event.initEvent name, true, true
29
29
  document.dispatchEvent event
30
30
 
31
+ window.triggerEventFor = (name, node, data) ->
32
+ event = document.createEvent 'Events'
33
+ event.data = data if data
34
+ event.initEvent name, true, true
35
+ node.dispatchEvent event
36
+
31
37
  popCookie = (name) ->
32
38
  value = document.cookie.match(new RegExp(name+"=(\\w+)"))?[1].toUpperCase() or ''
33
39
  document.cookie = name + '=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/'
@@ -54,33 +60,17 @@ class window.Turbolinks
54
60
  currentState = null
55
61
  loadedAssets = null
56
62
  referer = null
57
- usePageCache = false
58
- @pageCache = pageCache = new PageCache()
59
63
 
60
64
  fetch = (url, partialReplace = false, replaceContents = [], callback) ->
65
+ return if pageChangePrevented(url)
61
66
  url = new ComponentUrl url
62
67
 
63
68
  rememberReferer()
64
- Turbolinks.cacheCurrentPage() if usePageCache
65
-
66
- if usePageCache and cachedPage = transitionCacheFor(url.absolute)
67
- fetchHistory cachedPage
68
- fetchReplacement url, partialReplace, null, replaceContents
69
- else
70
- fetchReplacement url, partialReplace, ->
71
- resetScrollPosition() unless replaceContents.length
72
- callback?()
73
- , replaceContents
74
-
75
- @pageCacheEnabled = ->
76
- usePageCache
77
69
 
78
- @usePageCache = (status) ->
79
- usePageCache = status
80
-
81
- transitionCacheFor = (url) ->
82
- cachedPage = pageCache.get(url)
83
- cachedPage if cachedPage and !cachedPage.transitionCacheDisabled
70
+ fetchReplacement url, partialReplace, ->
71
+ resetScrollPosition() unless replaceContents.length
72
+ callback?()
73
+ , replaceContents
84
74
 
85
75
  @pushState: (state, title, url) ->
86
76
  window.history.pushState(state, title, url)
@@ -111,12 +101,12 @@ class window.Turbolinks
111
101
 
112
102
  return
113
103
 
114
- @loadPage: (url, xhr, partialReplace = false, onLoadFunction = (->), replaceContents = []) ->
104
+ @loadPage: (url, xhr, partialReplace = false, onLoadFunction = (->), replaceContents = [], replaceAllExcept = []) ->
115
105
  triggerEvent 'page:receive'
116
106
 
117
107
  if doc = processResponse(xhr, partialReplace)
118
108
  reflectNewUrl url
119
- nodes = changePage(extractTitleAndBody(doc)..., partialReplace, replaceContents)
109
+ nodes = changePage(extractTitleAndBody(doc)..., partialReplace, replaceContents, replaceAllExcept)
120
110
  reflectRedirectedUrl(xhr)
121
111
  triggerEvent 'page:load', nodes
122
112
  onLoadFunction?()
@@ -125,32 +115,15 @@ class window.Turbolinks
125
115
 
126
116
  return
127
117
 
128
- fetchHistory = (cachedPage) ->
129
- xhr?.abort()
130
- changePage cachedPage.title, cachedPage.body, false
131
- recallScrollPosition cachedPage
132
- triggerEvent 'page:restore'
133
-
134
-
135
- @cacheCurrentPage: ->
136
- currentStateUrl = new ComponentUrl currentState.url
137
-
138
- pageCache.set currentStateUrl.absolute,
139
- url: currentStateUrl.relative,
140
- body: document.body,
141
- title: document.title,
142
- positionY: window.pageYOffset,
143
- positionX: window.pageXOffset,
144
- transitionCacheDisabled: document.querySelector('[data-no-transition-cache]')?
145
-
146
- return
147
-
148
- changePage = (title, body, csrfToken, runScripts, partialReplace, replaceContents = []) ->
118
+ changePage = (title, body, csrfToken, runScripts, partialReplace, replaceContents = [], replaceAllExcept = []) ->
149
119
  document.title = title if title
150
120
  if replaceContents.length
151
121
  return refreshNodesWithKeys(replaceContents, body)
152
122
  else
153
- deleteRefreshNeverNodes(body)
123
+ if replaceAllExcept.length
124
+ refreshAllExceptWithKeys(replaceAllExcept, body)
125
+ else
126
+ deleteRefreshNeverNodes(body)
154
127
 
155
128
  triggerEvent 'page:before-replace'
156
129
  document.documentElement.replaceChild body, document.body
@@ -204,6 +177,20 @@ class window.Turbolinks
204
177
 
205
178
  refreshedNodes
206
179
 
180
+ refreshAllExceptWithKeys = (keys, body) ->
181
+ allNodesToKeep = []
182
+
183
+ for key in keys
184
+ for node in document.querySelectorAll("[refresh=#{key}]")
185
+ allNodesToKeep.push(node)
186
+
187
+ for existingNode in allNodesToKeep
188
+ unless nodeId = existingNode.getAttribute('id')
189
+ throw new Error "Turbolinks refresh: Refresh key elements must have an id."
190
+
191
+ remoteNode = body.querySelector("##{ nodeId }")
192
+ remoteNode.parentNode.replaceChild(existingNode, remoteNode)
193
+
207
194
  executeScriptTags = ->
208
195
  scripts = Array::slice.call document.body.querySelectorAll 'script:not([data-turbolinks-eval="false"])'
209
196
  for script in scripts when script.type in ['', 'text/javascript']
@@ -253,8 +240,8 @@ class window.Turbolinks
253
240
  else
254
241
  window.scrollTo 0, 0
255
242
 
256
- pageChangePrevented = ->
257
- !triggerEvent 'page:before-change'
243
+ pageChangePrevented = (url) ->
244
+ !triggerEvent('page:before-change', url)
258
245
 
259
246
  processResponse = (xhr, partial = false) ->
260
247
  clientOrServerError = ->
@@ -290,11 +277,7 @@ class window.Turbolinks
290
277
 
291
278
  installHistoryChangeHandler = (event) ->
292
279
  if event.state?.turbolinks
293
- if cachedPage = pageCache.get((new ComponentUrl(event.state.url)).absolute)
294
- Turbolinks.cacheCurrentPage()
295
- fetchHistory cachedPage
296
- else
297
- Turbolinks.visit event.target.location.href
280
+ Turbolinks.visit event.target.location.href
298
281
 
299
282
  # Delay execution of function long enough to miss the popstate event
300
283
  # some browsers fire on the initial page load.
@@ -1,3 +1,3 @@
1
1
  module TurboGraft
2
- VERSION = '0.0.8'
2
+ VERSION = '0.0.10'
3
3
  end
@@ -16,6 +16,17 @@ module TurboGraft
16
16
  end
17
17
 
18
18
  private
19
+
20
+ if Rails::VERSION::MAJOR == 4 && Rails::VERSION::MINOR > 1
21
+ def _compute_redirect_to_location_with_xhr_referer(request, options)
22
+ session[:_turbolinks_redirect_to] =
23
+ if options == :back && request.headers["X-XHR-Referer"]
24
+ _compute_redirect_to_location_without_xhr_referer(request, request.headers["X-XHR-Referer"])
25
+ else
26
+ _compute_redirect_to_location_without_xhr_referer(request, options)
27
+ end
28
+ end
29
+ else
19
30
  def _compute_redirect_to_location_with_xhr_referer(options)
20
31
  session[:_turbolinks_redirect_to] =
21
32
  if options == :back && request.headers["X-XHR-Referer"]
@@ -24,12 +35,12 @@ module TurboGraft
24
35
  _compute_redirect_to_location_without_xhr_referer(options)
25
36
  end
26
37
  end
38
+ end
27
39
 
28
- def set_xhr_redirected_to
29
- if session[:_turbolinks_redirect_to]
30
- response.headers['X-XHR-Redirected-To'] = session.delete :_turbolinks_redirect_to
31
- end
40
+ def set_xhr_redirected_to
41
+ if session[:_turbolinks_redirect_to]
42
+ response.headers['X-XHR-Redirected-To'] = session.delete :_turbolinks_redirect_to
32
43
  end
44
+ end
33
45
  end
34
-
35
46
  end