turbograft 0.4.1 → 0.4.2

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: 908ca189eb5f9c51f6e061d844528bde62953db6
4
- data.tar.gz: 2b6f48a3f32d885e7d23ce33cd1f5fbdb2d2a6a2
3
+ metadata.gz: 1e699e8c4097b50cf1a8530b545dc15b0a285a5b
4
+ data.tar.gz: 60db5ecf8f5dc92ba320b3c88cfc97485255a953
5
5
  SHA512:
6
- metadata.gz: 5bc193a959af440b4af8312deea19d8356ac11a640d2d8189e7f9cb6fe10debb5f245033f6eff715287b85f4d665ea989eb6118e583e91e6111052ac3b03ba28
7
- data.tar.gz: 922997e629e3d77b3c6a2024273524149d8d5fceedb3d01d6c00d559eda8e8cf6ac3adacaa8bb49ac6b03180676d6a65650d5ceba61abf1ad4dd5761342678f7
6
+ metadata.gz: 9fd21cae920d11a5a6d755ed19e39fd50c6b0185e4bdbfcfb6e34485b90d810d15cc8a0f3a74b1eda351658f2b1983ebc3de5b1c986d89411c916cd02309c5ed
7
+ data.tar.gz: c0795f45590c5cea04be07a6aa0f91715fa22f3b3c0f19196e96c4179be0e89eb10e0cc33ffecc10288de3341f1d438d5542880112240fde4ab0da700d0d269a
data/README.md CHANGED
@@ -28,6 +28,9 @@ Turbograft was built with simplicity in mind. It intends to offer the smallest a
28
28
  * Replace `//= require turbolinks` with `//= require turbograft` in _app/assets/javascripts/application.js_
29
29
  * Run `bundle install`
30
30
 
31
+ ## Dependencies
32
+
33
+ Turbograft requires a browser that supports [`Promise`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise), or a polyfill (e.g., [core-js](https://github.com/zloirock/core-js).)
31
34
 
32
35
  ## Usage
33
36
 
@@ -2,6 +2,14 @@ TRACKED_ASSET_SELECTOR = '[data-turbolinks-track]'
2
2
  TRACKED_ATTRIBUTE_NAME = 'turbolinksTrack'
3
3
  ANONYMOUS_TRACK_VALUE = 'true'
4
4
 
5
+ scriptPromises = {}
6
+ resolvePreviousRequest = null
7
+
8
+ waitForCompleteDownloads = ->
9
+ loadingPromises = Object.keys(scriptPromises).map (url) ->
10
+ scriptPromises[url]
11
+ Promise.all(loadingPromises)
12
+
5
13
  class window.TurboHead
6
14
  constructor: (@activeDocument, @upstreamDocument) ->
7
15
  @activeAssets = extractTrackedAssets(@activeDocument)
@@ -14,6 +22,12 @@ class window.TurboHead
14
22
  .filter(attributeMatches('nodeName', 'LINK'))
15
23
  .filter(noAttributeMatchesIn('href', @activeAssets))
16
24
 
25
+ @_testAPI: {
26
+ reset: ->
27
+ scriptPromises = {}
28
+ resolvePreviousRequest = null
29
+ }
30
+
17
31
  hasChangedAnonymousAssets: () ->
18
32
  anonymousUpstreamAssets = @upstreamAssets
19
33
  .filter(datasetMatches(TRACKED_ATTRIBUTE_NAME, ANONYMOUS_TRACK_VALUE))
@@ -39,9 +53,20 @@ class window.TurboHead
39
53
  hasAssetConflicts: () ->
40
54
  @hasNamedAssetConflicts() || @hasChangedAnonymousAssets()
41
55
 
42
- insertNewAssets: (callback) ->
56
+ waitForAssets: () ->
57
+ resolvePreviousRequest?(isCanceled: true)
58
+
59
+ new Promise((resolve) =>
60
+ resolvePreviousRequest = resolve
61
+ waitForCompleteDownloads()
62
+ .then(@_insertNewAssets)
63
+ .then(waitForCompleteDownloads)
64
+ .then(resolve)
65
+ )
66
+
67
+ _insertNewAssets: () =>
43
68
  updateLinkTags(@activeDocument, @newLinks)
44
- updateScriptTags(@activeDocument, @newScripts, callback)
69
+ updateScriptTags(@activeDocument, @newScripts)
45
70
 
46
71
  extractTrackedAssets = (doc) ->
47
72
  [].slice.call(doc.querySelectorAll(TRACKED_ASSET_SELECTOR))
@@ -76,37 +101,37 @@ noDatasetMatchesIn = (attribute, collection) ->
76
101
  updateLinkTags = (activeDocument, newLinks) ->
77
102
  # style tag load events don't work in all browsers
78
103
  # as such we just hope they load ¯\_(ツ)_/¯
79
- newLinks.forEach((linkNode) -> insertLinkTask(activeDocument, linkNode)())
80
-
81
- updateScriptTags = (activeDocument, newScripts, callback) ->
82
- asyncSeries(
83
- newScripts.map((scriptNode) -> insertScriptTask(activeDocument, scriptNode)),
84
- callback
104
+ newLinks.forEach((linkNode) ->
105
+ newNode = linkNode.cloneNode()
106
+ activeDocument.head.appendChild(newNode)
107
+ triggerEvent("page:after-link-inserted", newNode)
85
108
  )
86
109
 
87
- asyncSeries = (tasks, callback) ->
88
- return callback() if tasks.length == 0
89
- task = tasks.shift()
90
- task(-> asyncSeries(tasks, callback))
110
+ updateScriptTags = (activeDocument, newScripts) ->
111
+ promise = Promise.resolve()
112
+ newScripts.forEach (scriptNode) ->
113
+ promise = promise.then(-> insertScript(activeDocument, scriptNode))
114
+ promise
115
+
116
+ insertScript = (activeDocument, scriptNode) ->
117
+ url = scriptNode.src
118
+ if scriptPromises[url]
119
+ return scriptPromises[url]
91
120
 
92
- insertScriptTask = (activeDocument, scriptNode) ->
93
- # We need to clone script tags in order to ensure that the browser executes them.
121
+ # Clone script tags to guarantee browser execution.
94
122
  newNode = activeDocument.createElement('SCRIPT')
95
123
  newNode.setAttribute(attr.name, attr.value) for attr in scriptNode.attributes
96
124
  newNode.appendChild(activeDocument.createTextNode(scriptNode.innerHTML))
97
- insertAssetTask(activeDocument, newNode, 'script')
98
125
 
99
- insertLinkTask = (activeDocument, node) ->
100
- insertAssetTask(activeDocument, node.cloneNode(), 'link')
101
-
102
- insertAssetTask = (activeDocument, newNode, name) ->
103
- (done) ->
126
+ scriptPromises[url] = new Promise((resolve) ->
104
127
  onAssetEvent = (event) ->
105
- triggerEvent("page:#{name}-error", event) if event.type == 'error'
128
+ triggerEvent("page:#script-error", event) if event.type == 'error'
106
129
  newNode.removeEventListener('load', onAssetEvent)
107
130
  newNode.removeEventListener('error', onAssetEvent)
108
- done() if typeof done == 'function'
131
+ resolve()
132
+
109
133
  newNode.addEventListener('load', onAssetEvent)
110
134
  newNode.addEventListener('error', onAssetEvent)
111
135
  activeDocument.head.appendChild(newNode)
112
- triggerEvent("page:after-#{name}-inserted", newNode)
136
+ triggerEvent("page:after-script-inserted", newNode)
137
+ )
@@ -139,7 +139,9 @@ class window.Turbolinks
139
139
  if turbohead.hasAssetConflicts()
140
140
  return Turbolinks.fullPageNavigate(url.absolute)
141
141
  reflectNewUrl url if options.updatePushState
142
- turbohead.insertNewAssets(-> updateBody(upstreamDocument, xhr, options))
142
+ turbohead.waitForAssets().then((result) ->
143
+ updateBody(upstreamDocument, xhr, options) unless result?.isCanceled
144
+ )
143
145
  else
144
146
  triggerEvent 'page:error', xhr
145
147
  Turbolinks.fullPageNavigate(url.absolute) if url?
@@ -303,6 +305,7 @@ class window.Turbolinks
303
305
  location = new ComponentUrl location
304
306
  preservedHash = if location.hasNoHash() then document.location.hash else ''
305
307
  Turbolinks.replaceState currentState, '', location.href + preservedHash
308
+
306
309
  return
307
310
 
308
311
  rememberReferer = ->
@@ -1,3 +1,3 @@
1
1
  module TurboGraft
2
- VERSION = '0.4.1'
2
+ VERSION = '0.4.2'
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.1
4
+ version: 0.4.2
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-06 00:00:00.000000000 Z
16
+ date: 2016-09-22 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: coffee-rails