turbograft 0.4.2 → 0.4.3

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: 1e699e8c4097b50cf1a8530b545dc15b0a285a5b
4
- data.tar.gz: 60db5ecf8f5dc92ba320b3c88cfc97485255a953
3
+ metadata.gz: 9334d30bbf9e86dd7baae353ac711bc9688f70ff
4
+ data.tar.gz: 92bc6bf6eb003c707d82b1b28d7b71bd67e59ada
5
5
  SHA512:
6
- metadata.gz: 9fd21cae920d11a5a6d755ed19e39fd50c6b0185e4bdbfcfb6e34485b90d810d15cc8a0f3a74b1eda351658f2b1983ebc3de5b1c986d89411c916cd02309c5ed
7
- data.tar.gz: c0795f45590c5cea04be07a6aa0f91715fa22f3b3c0f19196e96c4179be0e89eb10e0cc33ffecc10288de3341f1d438d5542880112240fde4ab0da700d0d269a
6
+ metadata.gz: 6625a059b2940513077f90ab4e11645e807cd57a62074815ed36f89710d28c3702a0277a90c62f243a079a0cc042011f8845cacd077f7881db43e576d478e5dd
7
+ data.tar.gz: 02850cbe00f2c90a16a34fd2932fb458fe542f578b766e7b1709ff9c938a75d706c5b439639a6338d93be44c6e86a0d4d3a80af20ce0e9a8760b2b7544fc9f24
@@ -0,0 +1,11 @@
1
+ TurboGraft.Document =
2
+ create: (html) ->
3
+ if /<(html|body)/i.test(html)
4
+ doc = document.documentElement.cloneNode()
5
+ doc.innerHTML = html
6
+ else
7
+ doc = document.documentElement.cloneNode(true)
8
+ doc.querySelector('body').innerHTML = html
9
+ doc.head = doc.querySelector('head')
10
+ doc.body = doc.querySelector('body')
11
+ doc
@@ -0,0 +1,23 @@
1
+ class TurboGraft.Response
2
+ constructor: (@xhr) ->
3
+
4
+ valid: -> @hasRenderableHttpStatus() && @hasValidContent()
5
+
6
+ document: ->
7
+ if @valid()
8
+ TurboGraft.Document.create(@xhr.responseText)
9
+
10
+ hasRenderableHttpStatus: ->
11
+ return true if @xhr.status == 422 # we want to render form validations
12
+ !(400 <= @xhr.status < 600)
13
+
14
+ hasValidContent: ->
15
+ if contentType = @xhr.getResponseHeader('Content-Type')
16
+ contentType.match(/^(?:text\/html|application\/xhtml\+xml|application\/xml)(?:;|$)/)
17
+ else
18
+ throw new Error("Error encountered for XHR Response: #{this}")
19
+
20
+ toString: () ->
21
+ "URL: #{@xhr.responseURL}, " +
22
+ "ReadyState: #{@xhr.readyState}, " +
23
+ "Headers: #{@xhr.getAllResponseHeaders()}"
@@ -10,7 +10,7 @@ waitForCompleteDownloads = ->
10
10
  scriptPromises[url]
11
11
  Promise.all(loadingPromises)
12
12
 
13
- class window.TurboHead
13
+ class TurboGraft.TurboHead
14
14
  constructor: (@activeDocument, @upstreamDocument) ->
15
15
  @activeAssets = extractTrackedAssets(@activeDocument)
16
16
  @upstreamAssets = extractTrackedAssets(@upstreamDocument)
@@ -1,14 +1,15 @@
1
1
  xhr = null
2
+ activeDocument = document
2
3
 
3
4
  installDocumentReadyPageEventTriggers = ->
4
- document.addEventListener 'DOMContentLoaded', ( ->
5
+ activeDocument.addEventListener 'DOMContentLoaded', ( ->
5
6
  triggerEvent 'page:change'
6
7
  triggerEvent 'page:update'
7
8
  ), true
8
9
 
9
10
  installJqueryAjaxSuccessPageUpdateTrigger = ->
10
11
  if typeof jQuery isnt 'undefined'
11
- jQuery(document).on 'ajaxSuccess', (event, xhr, settings) ->
12
+ jQuery(activeDocument).on 'ajaxSuccess', (event, xhr, settings) ->
12
13
  return unless jQuery.trim xhr.responseText
13
14
  triggerEvent 'page:update'
14
15
 
@@ -20,20 +21,20 @@ browserSupportsPushState =
20
21
  window.history and window.history.pushState and window.history.replaceState and historyStateIsDefined
21
22
 
22
23
  window.triggerEvent = (name, data) ->
23
- event = document.createEvent 'Events'
24
+ event = activeDocument.createEvent 'Events'
24
25
  event.data = data if data
25
26
  event.initEvent name, true, true
26
- document.dispatchEvent event
27
+ activeDocument.dispatchEvent event
27
28
 
28
29
  window.triggerEventFor = (name, node, data) ->
29
- event = document.createEvent 'Events'
30
+ event = activeDocument.createEvent 'Events'
30
31
  event.data = data if data
31
32
  event.initEvent name, true, true
32
33
  node.dispatchEvent event
33
34
 
34
35
  popCookie = (name) ->
35
- value = document.cookie.match(new RegExp(name+"=(\\w+)"))?[1].toUpperCase() or ''
36
- document.cookie = name + '=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/'
36
+ value = activeDocument.cookie.match(new RegExp(name+"=(\\w+)"))?[1].toUpperCase() or ''
37
+ activeDocument.cookie = name + '=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/'
37
38
  value
38
39
 
39
40
  requestMethodIsSafe =
@@ -42,7 +43,7 @@ requestMethodIsSafe =
42
43
  browserSupportsTurbolinks = browserSupportsPushState and requestMethodIsSafe
43
44
 
44
45
  browserSupportsCustomEvents =
45
- document.addEventListener and document.createEvent
46
+ activeDocument.addEventListener and activeDocument.createEvent
46
47
 
47
48
  if browserSupportsCustomEvents
48
49
  installDocumentReadyPageEventTriggers()
@@ -61,7 +62,6 @@ removeNode = (node) ->
61
62
  # TODO: clean up everything above me ^
62
63
  # TODO: decide on the public API
63
64
  class window.Turbolinks
64
- createDocument = null
65
65
  currentState = null
66
66
  referer = null
67
67
 
@@ -80,8 +80,11 @@ class window.Turbolinks
80
80
  fetchReplacement url, options
81
81
 
82
82
  @fullPageNavigate: (url) ->
83
- triggerEvent('page:before-full-refresh', url: url)
84
- document.location.href = url
83
+ if url?
84
+ url = (new ComponentUrl(url)).absolute
85
+ triggerEvent('page:before-full-refresh', url: url)
86
+ activeDocument.location.href = url
87
+ return
85
88
 
86
89
  @pushState: (state, title, url) ->
87
90
  window.history.pushState(state, title, url)
@@ -89,6 +92,10 @@ class window.Turbolinks
89
92
  @replaceState: (state, title, url) ->
90
93
  window.history.replaceState(state, title, url)
91
94
 
95
+ @document: (documentToUse) ->
96
+ activeDocument = documentToUse if documentToUse
97
+ activeDocument
98
+
92
99
  fetchReplacement = (url, options) ->
93
100
  triggerEvent 'page:fetch', url: url.absolute
94
101
 
@@ -111,7 +118,7 @@ class window.Turbolinks
111
118
 
112
119
  xhr.onload = ->
113
120
  if xhr.status >= 500
114
- Turbolinks.fullPageNavigate(url.absolute)
121
+ Turbolinks.fullPageNavigate(url)
115
122
  else
116
123
  Turbolinks.loadPage(url, xhr, options)
117
124
  xhr = null
@@ -121,7 +128,7 @@ class window.Turbolinks
121
128
  if xhr.statusText == "abort"
122
129
  xhr = null
123
130
  return
124
- Turbolinks.fullPageNavigate(url.absolute)
131
+ Turbolinks.fullPageNavigate(url)
125
132
 
126
133
  xhr.send()
127
134
 
@@ -130,21 +137,21 @@ class window.Turbolinks
130
137
  @loadPage: (url, xhr, options = {}) ->
131
138
  triggerEvent 'page:receive'
132
139
  options.updatePushState ?= true
133
- if upstreamDocument = processResponse(xhr)
140
+ if upstreamDocument = new TurboGraft.Response(xhr).document()
134
141
  if options.partialReplace
135
142
  reflectNewUrl url if options.updatePushState
136
143
  updateBody(upstreamDocument, xhr, options)
137
144
  else
138
- turbohead = new TurboHead(document, upstreamDocument)
145
+ turbohead = new TurboGraft.TurboHead(activeDocument, upstreamDocument)
139
146
  if turbohead.hasAssetConflicts()
140
- return Turbolinks.fullPageNavigate(url.absolute)
147
+ return Turbolinks.fullPageNavigate(url)
141
148
  reflectNewUrl url if options.updatePushState
142
149
  turbohead.waitForAssets().then((result) ->
143
150
  updateBody(upstreamDocument, xhr, options) unless result?.isCanceled
144
151
  )
145
152
  else
146
153
  triggerEvent 'page:error', xhr
147
- Turbolinks.fullPageNavigate(url.absolute) if url?
154
+ Turbolinks.fullPageNavigate(url)
148
155
 
149
156
  updateBody = (upstreamDocument, xhr, options) ->
150
157
  nodes = changePage(
@@ -159,7 +166,7 @@ class window.Turbolinks
159
166
  triggerEvent 'page:load', nodes
160
167
 
161
168
  changePage = (title, body, csrfToken, runScripts, options = {}) ->
162
- document.title = title if title
169
+ activeDocument.title = title if title
163
170
  options.onlyKeys ?= []
164
171
  options.exceptKeys ?= []
165
172
 
@@ -177,7 +184,7 @@ class window.Turbolinks
177
184
  deleteRefreshNeverNodes(body)
178
185
 
179
186
  triggerEvent 'page:before-replace'
180
- replaceNode(body, document.body)
187
+ replaceNode(body, activeDocument.body)
181
188
  CSRFToken.update csrfToken if csrfToken?
182
189
  setAutofocusElement()
183
190
  executeScriptTags() if runScripts
@@ -190,14 +197,14 @@ class window.Turbolinks
190
197
  getNodesMatchingRefreshKeys = (keys) ->
191
198
  matchingNodes = []
192
199
  for key in keys
193
- for node in TurboGraft.querySelectorAllTGAttribute(document, 'refresh', key)
200
+ for node in TurboGraft.querySelectorAllTGAttribute(activeDocument, 'refresh', key)
194
201
  matchingNodes.push(node)
195
202
 
196
203
  return matchingNodes
197
204
 
198
205
  getNodesWithRefreshAlways = ->
199
206
  matchingNodes = []
200
- for node in TurboGraft.querySelectorAllTGAttribute(document, 'refresh-always')
207
+ for node in TurboGraft.querySelectorAllTGAttribute(activeDocument, 'refresh-always')
201
208
  matchingNodes.push(node)
202
209
 
203
210
  return matchingNodes
@@ -210,8 +217,8 @@ class window.Turbolinks
210
217
  false
211
218
 
212
219
  setAutofocusElement = ->
213
- autofocusElement = (list = document.querySelectorAll 'input[autofocus], textarea[autofocus]')[list.length - 1]
214
- if autofocusElement and document.activeElement isnt autofocusElement
220
+ autofocusElement = (list = activeDocument.querySelectorAll 'input[autofocus], textarea[autofocus]')[list.length - 1]
221
+ if autofocusElement and activeDocument.activeElement isnt autofocusElement
215
222
  autofocusElement.focus()
216
223
 
217
224
  deleteRefreshNeverNodes = (body) ->
@@ -260,7 +267,7 @@ class window.Turbolinks
260
267
  persistStaticElements = (body) ->
261
268
  allNodesToKeep = []
262
269
 
263
- nodes = TurboGraft.querySelectorAllTGAttribute(document, 'tg-static')
270
+ nodes = TurboGraft.querySelectorAllTGAttribute(activeDocument, 'tg-static')
264
271
  allNodesToKeep.push(node) for node in nodes
265
272
 
266
273
  keepNodes(body, allNodesToKeep)
@@ -270,22 +277,22 @@ class window.Turbolinks
270
277
  allNodesToKeep = []
271
278
 
272
279
  for key in keys
273
- for node in TurboGraft.querySelectorAllTGAttribute(document, 'refresh', key)
280
+ for node in TurboGraft.querySelectorAllTGAttribute(activeDocument, 'refresh', key)
274
281
  allNodesToKeep.push(node)
275
282
 
276
283
  keepNodes(body, allNodesToKeep)
277
284
  return
278
285
 
279
286
  executeScriptTags = ->
280
- scripts = Array::slice.call document.body.querySelectorAll 'script:not([data-turbolinks-eval="false"])'
287
+ scripts = Array::slice.call activeDocument.body.querySelectorAll 'script:not([data-turbolinks-eval="false"])'
281
288
  for script in scripts when script.type in ['', 'text/javascript']
282
289
  executeScriptTag(script)
283
290
  return
284
291
 
285
292
  executeScriptTag = (script) ->
286
- copy = document.createElement 'script'
293
+ copy = activeDocument.createElement 'script'
287
294
  copy.setAttribute attr.name, attr.value for attr in script.attributes
288
- copy.appendChild document.createTextNode script.innerHTML
295
+ copy.appendChild activeDocument.createTextNode script.innerHTML
289
296
  { parentNode, nextSibling } = script
290
297
  parentNode.removeChild script
291
298
  parentNode.insertBefore copy, nextSibling
@@ -303,16 +310,16 @@ class window.Turbolinks
303
310
  reflectRedirectedUrl = (xhr) ->
304
311
  if location = xhr.getResponseHeader 'X-XHR-Redirected-To'
305
312
  location = new ComponentUrl location
306
- preservedHash = if location.hasNoHash() then document.location.hash else ''
313
+ preservedHash = if location.hasNoHash() then activeDocument.location.hash else ''
307
314
  Turbolinks.replaceState currentState, '', location.href + preservedHash
308
315
 
309
316
  return
310
317
 
311
318
  rememberReferer = ->
312
- referer = document.location.href
319
+ referer = activeDocument.location.href
313
320
 
314
321
  @rememberCurrentUrl: ->
315
- Turbolinks.replaceState { turbolinks: true, url: document.location.href }, '', document.location.href
322
+ Turbolinks.replaceState { turbolinks: true, url: activeDocument.location.href }, '', activeDocument.location.href
316
323
 
317
324
  @rememberCurrentState: ->
318
325
  currentState = window.history.state
@@ -321,26 +328,14 @@ class window.Turbolinks
321
328
  window.scrollTo page.positionX, page.positionY
322
329
 
323
330
  resetScrollPosition = ->
324
- if document.location.hash
325
- document.location.href = document.location.href
331
+ if activeDocument.location.hash
332
+ activeDocument.location.href = activeDocument.location.href
326
333
  else
327
334
  window.scrollTo 0, 0
328
335
 
329
336
  pageChangePrevented = (url) ->
330
337
  !triggerEvent('page:before-change', url)
331
338
 
332
- processResponse = (xhr) ->
333
- clientOrServerError = ->
334
- return false if xhr.status == 422 # we want to render form validations
335
- 400 <= xhr.status < 600
336
-
337
- validContent = ->
338
- xhr.getResponseHeader('Content-Type').match /^(?:text\/html|application\/xhtml\+xml|application\/xml)(?:;|$)/
339
-
340
- if !clientOrServerError() && validContent()
341
- upstreamDocument = createDocument(xhr.responseText)
342
- return upstreamDocument
343
-
344
339
  installHistoryChangeHandler = (event) ->
345
340
  if event.state?.turbolinks
346
341
  Turbolinks.visit event.target.location.href
@@ -350,26 +345,15 @@ class window.Turbolinks
350
345
  bypassOnLoadPopstate = (fn) ->
351
346
  setTimeout fn, 500
352
347
 
353
- createDocument = (html) ->
354
- if /<(html|body)/i.test(html)
355
- doc = document.documentElement.cloneNode()
356
- doc.innerHTML = html
357
- else
358
- doc = document.documentElement.cloneNode(true)
359
- doc.querySelector('body').innerHTML = html
360
- doc.head = doc.querySelector('head')
361
- doc.body = doc.querySelector('body')
362
- doc
363
-
364
348
  if browserSupportsTurbolinks
365
349
  @visit = fetch
366
350
  @rememberCurrentUrl()
367
351
  @rememberCurrentState()
368
352
 
369
- document.addEventListener 'click', Click.installHandlerLast, true
353
+ activeDocument.addEventListener 'click', Click.installHandlerLast, true
370
354
 
371
355
  bypassOnLoadPopstate ->
372
356
  window.addEventListener 'popstate', installHistoryChangeHandler, false
373
357
 
374
358
  else
375
- @visit = (url) -> document.location.href = url
359
+ @visit = (url) -> activeDocument.location.href = url
data/lib/turbograft.rb CHANGED
@@ -35,10 +35,8 @@ module TurboGraft
35
35
  end
36
36
 
37
37
  ActiveSupport.on_load(:action_view) do
38
- (ActionView::RoutingUrlFor rescue ActionView::Helpers::UrlHelper).module_eval do
39
- prepend XHRUrlFor
40
- end
41
- end unless RUBY_VERSION =~ /^1\.8/
38
+ (ActionView::RoutingUrlFor rescue ActionView::Helpers::UrlHelper).prepend(XHRUrlFor)
39
+ end
42
40
  end
43
41
  end
44
42
  end
@@ -1,3 +1,3 @@
1
1
  module TurboGraft
2
- VERSION = '0.4.2'
2
+ VERSION = '0.4.3'
3
3
  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.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristian Plettenberg-Dussault
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2016-09-22 00:00:00.000000000 Z
16
+ date: 2016-10-05 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: coffee-rails
@@ -224,10 +224,12 @@ files:
224
224
  - lib/assets/javascripts/turbograft/click.coffee
225
225
  - lib/assets/javascripts/turbograft/component_url.coffee
226
226
  - lib/assets/javascripts/turbograft/csrf_token.coffee
227
+ - lib/assets/javascripts/turbograft/document.coffee
227
228
  - lib/assets/javascripts/turbograft/initializers.coffee
228
229
  - lib/assets/javascripts/turbograft/link.coffee
229
230
  - lib/assets/javascripts/turbograft/page.coffee
230
231
  - lib/assets/javascripts/turbograft/remote.coffee
232
+ - lib/assets/javascripts/turbograft/response.coffee
231
233
  - lib/assets/javascripts/turbograft/turbohead.coffee
232
234
  - lib/assets/javascripts/turbograft/turbolinks.coffee
233
235
  - lib/turbograft.rb
@@ -247,9 +249,9 @@ require_paths:
247
249
  - lib
248
250
  required_ruby_version: !ruby/object:Gem::Requirement
249
251
  requirements:
250
- - - ">="
252
+ - - "~>"
251
253
  - !ruby/object:Gem::Version
252
- version: '0'
254
+ version: '2.1'
253
255
  required_rubygems_version: !ruby/object:Gem::Requirement
254
256
  requirements:
255
257
  - - ">="