turbograft 0.0.8 → 0.0.10

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
  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