twine-rails 1.0.0 → 1.0.1

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: 4386189c38efbea2da170dd03b7d30d11c69d0e7
4
- data.tar.gz: 90f46d3522191a2e65f21f9bc0accef50accc453
3
+ metadata.gz: 538a0c1b2f074d00d9402091cd8903e88a8c89f8
4
+ data.tar.gz: b966ba3ac32c35b34ab8cde4a05677e7d3b2ccfc
5
5
  SHA512:
6
- metadata.gz: a841a7bc1f7a30ddd0dd06dbb317f4aef580ae384865bf6a7f3df2c1789c36ef22df1bc4a4ece8501f4b6349100994bc0d6bb48f1cb5d79bf5172f58ed41c09c
7
- data.tar.gz: f66a43f275158666c7012acd90ca5a634c379ef8545c6255a6efb920f9cb82109c42ef7c7a98b492880949ea92af60eaab5f736acf5edffa490f247a44ea6194
6
+ metadata.gz: e272cf342cddbff047c8f3cff87f81a50631ab71559d3b17d7d12255689aa7fe72f1ed1b885060f04f1cb88f355a31efddf77ef5ae148a31977ce9c25438f099
7
+ data.tar.gz: 6d792404c98c19676b3d1f16b38d1e48874d4c691f8fe9c1a78e1b0a489c1475193ea1cf3181d994f018a3b6de1e90b83e4cd53d9ff75b31dfc40c98babe46f0
@@ -56,6 +56,7 @@
56
56
 
57
57
  bind = (context, node, indexes, forceSaveContext) ->
58
58
  currentBindingCallbacks = []
59
+ element = null
59
60
  if node.bindingId
60
61
  Twine.unbind(node)
61
62
 
@@ -69,13 +70,29 @@
69
70
  element = findOrCreateElementForNode(node)
70
71
  element.indexes = indexes
71
72
 
72
- for type, binding of Twine.bindingTypes when definition = Twine.getAttribute(node, type)
73
- element = findOrCreateElementForNode(node)
73
+ bindingConstructors = null
74
+ for attribute in node.attributes
75
+ type = attribute.name
76
+ type = type.slice(5) if isDataAttribute(type)
77
+
78
+ constructor = Twine.bindingTypes[type]
79
+ continue unless constructor
80
+
81
+ bindingConstructors ?= []
82
+ definition = attribute.value
83
+ if type == 'bind'
84
+ bindingConstructors.unshift([constructor, definition])
85
+ else
86
+ bindingConstructors.push([constructor, definition])
87
+
88
+ if bindingConstructors
89
+ element ?= findOrCreateElementForNode(node)
74
90
  element.bindings ?= []
75
91
  element.indexes ?= indexes
76
92
 
77
- fn = binding(node, context, definition, element)
78
- element.bindings.push(fn) if fn
93
+ for [constructor, definition] in bindingConstructors
94
+ binding = constructor(node, context, definition, element)
95
+ element.bindings.push(binding) if binding
79
96
 
80
97
  if newContextKey = Twine.getAttribute(node, 'context')
81
98
  keypath = keypathForKey(node, newContextKey)
@@ -85,7 +102,7 @@
85
102
  context = getValue(context, keypath) || setValue(context, keypath, {})
86
103
 
87
104
  if element || newContextKey || forceSaveContext
88
- element = findOrCreateElementForNode(node)
105
+ element ?= findOrCreateElementForNode(node)
89
106
  element.childContext = context
90
107
  element.indexes ?= indexes if indexes?
91
108
 
@@ -108,7 +125,6 @@
108
125
  findOrCreateElementForNode = (node) ->
109
126
  node.bindingId ?= ++nodeCount
110
127
  elements[node.bindingId] ?= {}
111
- elements[node.bindingId]
112
128
 
113
129
  # Queues a refresh of the DOM, batching up calls for the current synchronous block.
114
130
  Twine.refresh = ->
@@ -187,7 +203,7 @@
187
203
  addKey(rootContext) if node == rootNode
188
204
  keys.join('.')
189
205
 
190
- valueAttributeForNode = (node) ->
206
+ valuePropertyForNode = (node) ->
191
207
  name = node.nodeName.toLowerCase()
192
208
  if name in ['input', 'textarea', 'select']
193
209
  if node.getAttribute('type') in ['checkbox', 'radio'] then 'checked' else 'value'
@@ -232,14 +248,7 @@
232
248
  object[lastKey] = value
233
249
 
234
250
  stringifyNodeAttributes = (node) ->
235
- nAttributes = node.attributes.length
236
- i = 0
237
- result = ""
238
- while i < nAttributes
239
- attr = node.attributes.item(i)
240
- result += "#{attr.nodeName}='#{attr.textContent}'"
241
- i+=1
242
- result
251
+ [].map.call(node.attributes, (attr) -> "#{attr.name}=#{JSON.stringify(attr.value)}").join(' ')
243
252
 
244
253
  wrapFunctionString = (code, args, node) ->
245
254
  if isKeypath(code) && keypath = keypathForKey(node, code)
@@ -249,7 +258,7 @@
249
258
  ($context, $root) -> getValue($context, keypath)
250
259
  else
251
260
  code = "return #{code}"
252
- code = "with($arrayPointers) { #{code} }" if nodeHasArrayIndexes(node)
261
+ code = "with($arrayPointers) { #{code} }" if nodeArrayIndexes(node)
253
262
  code = "with($registry) { #{code} }" if requiresRegistry(args)
254
263
  try
255
264
  new Function(args, "with($context) { #{code} }")
@@ -258,14 +267,12 @@
258
267
 
259
268
  requiresRegistry = (args) -> /\$registry/.test(args)
260
269
 
261
- nodeHasArrayIndexes = (node) ->
262
- return unless node.bindingId?
263
- !!elements[node.bindingId]?.indexes?
270
+ nodeArrayIndexes = (node) ->
271
+ node.bindingId? && elements[node.bindingId]?.indexes
264
272
 
265
273
  arrayPointersForNode = (node, context) ->
266
- return {} unless node.bindingId?
267
- indexes = elements[node.bindingId]?.indexes
268
- return {} unless indexes?
274
+ indexes = nodeArrayIndexes(node)
275
+ return {} unless indexes
269
276
 
270
277
  result = {}
271
278
  for key, index of indexes
@@ -273,7 +280,14 @@
273
280
  result
274
281
 
275
282
  isKeypath = (value) ->
276
- value not in ['true', 'false', 'null', 'undefined'] and keypathRegex.test(value)
283
+ value not in ['true', 'false', 'null', 'undefined'] && keypathRegex.test(value)
284
+
285
+ isDataAttribute = (value) ->
286
+ value[0] == 'd' &&
287
+ value[1] == 'a' &&
288
+ value[2] == 't' &&
289
+ value[3] == 'a' &&
290
+ value[4] == '-'
277
291
 
278
292
  fireCustomChangeEvent = (node) ->
279
293
  event = document.createEvent('CustomEvent')
@@ -282,8 +296,8 @@
282
296
 
283
297
  Twine.bindingTypes =
284
298
  bind: (node, context, definition) ->
285
- valueAttribute = valueAttributeForNode(node)
286
- value = node[valueAttribute]
299
+ valueProp = valuePropertyForNode(node)
300
+ value = node[valueProp]
287
301
  lastValue = undefined
288
302
  teardown = undefined
289
303
 
@@ -296,9 +310,9 @@
296
310
  return if newValue == lastValue # return if we can and avoid a DOM operation
297
311
 
298
312
  lastValue = newValue
299
- return if newValue == node[valueAttribute]
313
+ return if newValue == node[valueProp]
300
314
 
301
- node[valueAttribute] = if checkedValueType then newValue == node.value else newValue
315
+ node[valueProp] = if checkedValueType then newValue == node.value else newValue
302
316
  fireCustomChangeEvent(node)
303
317
 
304
318
  return {refresh} unless isKeypath(definition)
@@ -308,10 +322,10 @@
308
322
  return unless node.checked
309
323
  setValue(context, keypath, node.value)
310
324
  else
311
- setValue(context, keypath, node[valueAttribute])
325
+ setValue(context, keypath, node[valueProp])
312
326
 
313
327
  keypath = keypathForKey(node, definition)
314
- twoWayBinding = valueAttribute != 'textContent' && node.type != 'hidden'
328
+ twoWayBinding = valueProp != 'textContent' && node.type != 'hidden'
315
329
 
316
330
  if keypath[0] == '$root'
317
331
  context = rootContext
@@ -322,7 +336,7 @@
322
336
 
323
337
  if twoWayBinding
324
338
  changeHandler = ->
325
- return if getValue(context, keypath) == this[valueAttribute]
339
+ return if getValue(context, keypath) == this[valueProp]
326
340
  refreshContext()
327
341
  Twine.refreshImmediately()
328
342
  $(node).on 'input keyup change', changeHandler
@@ -383,24 +397,24 @@
383
397
 
384
398
  indexes
385
399
 
386
- setupAttributeBinding = (attributeName, bindingName) ->
387
- booleanAttribute = attributeName in ['checked', 'indeterminate', 'disabled', 'readOnly']
400
+ setupPropertyBinding = (attributeName, bindingName) ->
401
+ booleanProp = attributeName in ['checked', 'indeterminate', 'disabled', 'readOnly']
388
402
 
389
- Twine.bindingTypes["bind-#{bindingName}"] = (node, context, definition) ->
403
+ Twine.bindingTypes["bind-#{bindingName.toLowerCase()}"] = (node, context, definition) ->
390
404
  fn = wrapFunctionString(definition, '$context,$root,$arrayPointers', node)
391
405
  lastValue = undefined
392
406
  return refresh: ->
393
407
  newValue = fn.call(node, context, rootContext, arrayPointersForNode(node, context))
394
- newValue = !!newValue if booleanAttribute
408
+ newValue = !!newValue if booleanProp
395
409
  return if newValue == lastValue
396
410
  node[attributeName] = lastValue = newValue
397
411
 
398
412
  fireCustomChangeEvent(node) if attributeName == 'checked'
399
413
 
400
414
  for attribute in ['placeholder', 'checked', 'indeterminate', 'disabled', 'href', 'title', 'readOnly', 'src']
401
- setupAttributeBinding(attribute, attribute)
415
+ setupPropertyBinding(attribute, attribute)
402
416
 
403
- setupAttributeBinding('innerHTML', 'unsafe-html')
417
+ setupPropertyBinding('innerHTML', 'unsafe-html')
404
418
 
405
419
  preventDefaultForEvent = (event) ->
406
420
  (event.type == 'submit' || event.currentTarget.nodeName.toLowerCase() == 'a') &&
@@ -1,5 +1,4 @@
1
1
  require "rails"
2
- require "active_support"
3
2
 
4
3
  require "twine-rails/version"
5
4
 
@@ -1,3 +1,3 @@
1
1
  module TwineRails
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twine-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Li
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-06-23 00:00:00.000000000 Z
13
+ date: 2016-07-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: coffee-rails
@@ -26,6 +26,20 @@ dependencies:
26
26
  - - ">="
27
27
  - !ruby/object:Gem::Version
28
28
  version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: railties
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
29
43
  - !ruby/object:Gem::Dependency
30
44
  name: bundler
31
45
  requirement: !ruby/object:Gem::Requirement
@@ -86,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
100
  version: '0'
87
101
  requirements: []
88
102
  rubyforge_project:
89
- rubygems_version: 2.5.1
103
+ rubygems_version: 2.4.5.1
90
104
  signing_key:
91
105
  specification_version: 4
92
106
  summary: Minimalistic two-way bindings