turbograft 0.1.14 → 0.1.15

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: 1aff9e76ad586eab0a400892c5f596ffeac608b0
4
- data.tar.gz: 0e0c807cb3e2b1f6897de5977ae37850225b306c
3
+ metadata.gz: f0cae3c571903c38a3f4202abcf69b3be1759c79
4
+ data.tar.gz: 1763b567311c50e6a20348c2b68a8fdc2b872084
5
5
  SHA512:
6
- metadata.gz: 161fbc9a0d5312ce29364cabe5689aa8d25f9588b6504c1fde1f1a348c5daf9f47065a08e5533aa3e666d558469923ea9be4e9e26b677b1a80fcbaf5cc7aa238
7
- data.tar.gz: 9b2346f149f5ead38e386d5a8fbff973c70075bf33018b94c3125518bc3b39b282d0a86cacc3c68c60c2595a80f78bf62c6ba427b4d07d98eb81597cf3e66b5d
6
+ metadata.gz: 39adb2b25cb0414a2360850d35a82c418a96f884d6648b6f682f630127e13b2dcf79f9edaeea641ce46a58076107007a961c49329be397e09af83e81decc2d30
7
+ data.tar.gz: 115abe752d2a6e1c7300007dad6acb16c1cdc0878d78a16ad05bbfb4b620a13a8f422dc0307324d32f5eccfcafce96aa44c207520b574f472649cad61e975c24
data/README.md CHANGED
@@ -145,6 +145,15 @@ There is an example app that you can boot to play with TurboGraft. Open the con
145
145
  ./server
146
146
  ```
147
147
 
148
+ ## jQuery and memory leaks
149
+
150
+ When turbograft replaces or removes a node it uses native DOM API to do so. If any objects use jQuery to listen to events on a node then these objects will leak when the node is replaced because jQuery will still have references to it. To clean these up you'll need to tell jQuery that they're removed. This can be done with something like:
151
+
152
+ ```coffeescript
153
+ document.addEventListener 'page:after-node-removed', (event) ->
154
+ $(event.data).remove()
155
+ ```
156
+
148
157
  ## Contributing
149
158
 
150
159
  1. Fork it ( http://github.com/Shopify/turbograft/fork )
@@ -4,13 +4,10 @@ hasClass = (node, search) ->
4
4
  nodeIsDisabled = (node) ->
5
5
  node.getAttribute('disabled') || hasClass(node, 'disabled')
6
6
 
7
- TurboGraft.handlers.remoteMethodHandler = (ev) ->
8
- target = ev.clickTarget
9
- httpRequestType = target.getAttribute('tg-remote')
10
- return unless httpRequestType
11
- ev.preventDefault()
12
- httpUrl = target.getAttribute('href')
13
- throw new Error("Turbograft developer error: You did not provide a URL ('href' attribute) for tg-remote") unless httpUrl
7
+ setupRemoteFromTarget = (target, httpRequestType, urlAttribute, form = null) ->
8
+ httpUrl = target.getAttribute(urlAttribute)
9
+
10
+ throw new Error("Turbograft developer error: You did not provide a URL ('#{urlAttribute}' attribute) for tg-remote") unless httpUrl
14
11
 
15
12
  if target.getAttribute("remote-once")
16
13
  target.removeAttribute("remote-once")
@@ -25,36 +22,35 @@ TurboGraft.handlers.remoteMethodHandler = (ev) ->
25
22
  refreshOnError: target.getAttribute('refresh-on-error')
26
23
  refreshOnErrorExcept: target.getAttribute('full-refresh-on-error-except')
27
24
 
28
- remote = new TurboGraft.Remote(options, null, target)
25
+ new TurboGraft.Remote(options, form, target)
26
+
27
+ TurboGraft.handlers.remoteMethodHandler = (ev) ->
28
+ target = ev.clickTarget
29
+ httpRequestType = target.getAttribute('tg-remote')
30
+
31
+ return unless httpRequestType
32
+ ev.preventDefault()
33
+
34
+ remote = setupRemoteFromTarget(target, httpRequestType, 'href')
29
35
  remote.submit()
30
36
  return
31
37
 
32
38
  TurboGraft.handlers.remoteFormHandler = (ev) ->
33
39
  target = ev.target
40
+ method = target.getAttribute('method')
41
+
34
42
  return unless target.getAttribute('tg-remote')?
35
43
  ev.preventDefault()
36
- httpUrl = target.getAttribute('action')
37
- throw new Error("Turbograft developer error: You did not provide a URL ('action' attribute) for tg-remote") unless httpUrl
38
-
39
- options =
40
- httpRequestType: target.getAttribute('method')
41
- httpUrl: httpUrl
42
- fullRefresh: target.getAttribute('full-refresh')?
43
- refreshOnSuccess: target.getAttribute('refresh-on-success')
44
- refreshOnSuccessExcept: target.getAttribute('full-refresh-on-success-except')
45
- refreshOnError: target.getAttribute('refresh-on-error')
46
- refreshOnErrorExcept: target.getAttribute('full-refresh-on-error-except')
47
44
 
48
- remote = new TurboGraft.Remote(options, target, target)
45
+ remote = setupRemoteFromTarget(target, method, 'action', target)
49
46
  remote.submit()
50
47
  return
51
48
 
52
49
  documentListenerForButtons = (eventType, handler, useCapture = false) ->
53
50
  document.addEventListener eventType, (ev) ->
54
51
  target = ev.target
55
- return if !target
56
52
 
57
- while target != document && (typeof target != "undefined")
53
+ while target != document && target?
58
54
  if target.nodeName == "A" || target.nodeName == "BUTTON"
59
55
  isNodeDisabled = nodeIsDisabled(target)
60
56
  ev.preventDefault() if isNodeDisabled
@@ -48,6 +48,14 @@ if browserSupportsCustomEvents
48
48
  installDocumentReadyPageEventTriggers()
49
49
  installJqueryAjaxSuccessPageUpdateTrigger()
50
50
 
51
+ replaceNode = (newNode, oldNode) ->
52
+ replacedNode = oldNode.parentNode.replaceChild(newNode, oldNode)
53
+ triggerEvent('page:after-node-removed', replacedNode)
54
+
55
+ removeNode = (node) ->
56
+ removedNode = node.parentNode.removeChild(node)
57
+ triggerEvent('page:after-node-removed', removedNode)
58
+
51
59
  # TODO: triggerEvent should be accessible to all these guys
52
60
  # on some kind of eventbus
53
61
  # TODO: clean up everything above me ^
@@ -129,7 +137,7 @@ class window.Turbolinks
129
137
  deleteRefreshNeverNodes(body)
130
138
 
131
139
  triggerEvent 'page:before-replace'
132
- document.documentElement.replaceChild body, document.body
140
+ replaceNode(body, document.body)
133
141
  CSRFToken.update csrfToken if csrfToken?
134
142
  setAutofocusElement()
135
143
  executeScriptTags() if runScripts
@@ -168,7 +176,7 @@ class window.Turbolinks
168
176
 
169
177
  deleteRefreshNeverNodes = (body) ->
170
178
  for node in body.querySelectorAll('[refresh-never]')
171
- node.parentNode.removeChild(node)
179
+ removeNode(node)
172
180
 
173
181
  return
174
182
 
@@ -189,7 +197,7 @@ class window.Turbolinks
189
197
 
190
198
  if newNode = body.querySelector("##{ nodeId }")
191
199
  newNode = newNode.cloneNode(true)
192
- existingNode.parentNode.replaceChild(newNode, existingNode)
200
+ replaceNode(newNode, existingNode)
193
201
 
194
202
  if newNode.nodeName == 'SCRIPT' && newNode.getAttribute("data-turbolinks-eval") != "false"
195
203
  executeScriptTag(newNode)
@@ -197,7 +205,7 @@ class window.Turbolinks
197
205
  refreshedNodes.push(newNode)
198
206
 
199
207
  else if existingNode.getAttribute("refresh-always") == null
200
- existingNode.parentNode.removeChild(existingNode)
208
+ removeNode(existingNode)
201
209
 
202
210
  refreshedNodes
203
211
 
@@ -207,7 +215,7 @@ class window.Turbolinks
207
215
  throw new Error("TurboGraft refresh: Kept nodes must have an id.")
208
216
 
209
217
  if remoteNode = body.querySelector("##{ nodeId }")
210
- remoteNode.parentNode.replaceChild(existingNode, remoteNode)
218
+ replaceNode(existingNode, remoteNode)
211
219
 
212
220
  persistStaticElements = (body) ->
213
221
  allNodesToKeep = []
@@ -1,3 +1,3 @@
1
1
  module TurboGraft
2
- VERSION = '0.1.14'
2
+ VERSION = '0.1.15'
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.1.14
4
+ version: 0.1.15
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: 2015-02-09 00:00:00.000000000 Z
16
+ date: 2015-03-06 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: coffee-rails