c390f392 by Michael Richards

Merge branch 'text-node-binding'

2 parents b547428b 7124ab5f
...@@ -24,7 +24,7 @@ class Rivets.Binding ...@@ -24,7 +24,7 @@ class Rivets.Binding
24 # containing view, the DOM node, the type of binding, the model object and the 24 # containing view, the DOM node, the type of binding, the model object and the
25 # keypath at which to listen for changes. 25 # keypath at which to listen for changes.
26 constructor: (@view, @el, @type, @key, @keypath, @options = {}) -> 26 constructor: (@view, @el, @type, @key, @keypath, @options = {}) ->
27 unless @binder = Rivets.internalBinders[@type] or @view.binders[type] 27 unless @binder = @view.binders[type]
28 for identifier, value of @view.binders 28 for identifier, value of @view.binders
29 if identifier isnt '*' and identifier.indexOf('*') isnt -1 29 if identifier isnt '*' and identifier.indexOf('*') isnt -1
30 regexp = new RegExp "^#{identifier.replace('*', '.+')}$" 30 regexp = new RegExp "^#{identifier.replace('*', '.+')}$"
...@@ -174,8 +174,8 @@ class Rivets.ComponentBinding extends Rivets.Binding ...@@ -174,8 +174,8 @@ class Rivets.ComponentBinding extends Rivets.Binding
174 else 174 else
175 @inflections[attribute.name] = attribute.value 175 @inflections[attribute.name] = attribute.value
176 176
177 # Intercepts `Rivets.Binding::sync` since component bindings are not bound to a 177 # Intercepts `Rivets.Binding::sync` since component bindings are not bound to
178 # particular model to update it's value. 178 # a particular model to update it's value.
179 sync: -> 179 sync: ->
180 180
181 # Returns an object map using the component's scope inflections. 181 # Returns an object map using the component's scope inflections.
...@@ -207,6 +207,26 @@ class Rivets.ComponentBinding extends Rivets.Binding ...@@ -207,6 +207,26 @@ class Rivets.ComponentBinding extends Rivets.Binding
207 unbind: => 207 unbind: =>
208 @componentView?.unbind() 208 @componentView?.unbind()
209 209
210 # Rivets.TextBinding
211 # -----------------------
212
213 # A text node binding, defined internally to deal with text and element node
214 # differences while avoiding it being overwritten.
215 class Rivets.TextBinding extends Rivets.Binding
216 # Initializes a text binding for the specified view and text node.
217 constructor: (@view, @el, @type, @key, @keypath, @options = {}) ->
218 @formatters = @options.formatters || []
219 @model = if @key then @view.models[@key] else @view.models
220
221 # A standard routine binder used for text node bindings.
222 binder:
223 routine: (node, value) ->
224 node.data = value ? ''
225
226 # Wrap the call to `sync` in fat-arrow to avoid function context issues.
227 sync: =>
228 super
229
210 # Rivets.View 230 # Rivets.View
211 # ----------- 231 # -----------
212 232
...@@ -243,7 +263,7 @@ class Rivets.View ...@@ -243,7 +263,7 @@ class Rivets.View
243 componentRegExp = @componentRegExp() 263 componentRegExp = @componentRegExp()
244 264
245 265
246 buildBinding = (node, type, declaration) => 266 buildBinding = (binding, node, type, declaration) =>
247 options = {} 267 options = {}
248 268
249 pipes = (pipe.trim() for pipe in declaration.split '|') 269 pipes = (pipe.trim() for pipe in declaration.split '|')
...@@ -264,7 +284,7 @@ class Rivets.View ...@@ -264,7 +284,7 @@ class Rivets.View
264 if dependencies = context.shift() 284 if dependencies = context.shift()
265 options.dependencies = dependencies.split /\s+/ 285 options.dependencies = dependencies.split /\s+/
266 286
267 @bindings.push new Rivets.Binding @, node, type, key, keypath, options 287 @bindings.push new Rivets[binding] @, node, type, key, keypath, options
268 288
269 parse = (node) => 289 parse = (node) =>
270 unless node in skipNodes 290 unless node in skipNodes
...@@ -277,13 +297,17 @@ class Rivets.View ...@@ -277,13 +297,17 @@ class Rivets.View
277 [startToken, restTokens...] = tokens 297 [startToken, restTokens...] = tokens
278 node.data = startToken.value 298 node.data = startToken.value
279 299
280 switch startToken.type 300 if startToken.type is 0
281 when 0 then node.data = startToken.value 301 node.data = startToken.value
282 when 1 then buildBinding node, 'textNode', startToken.value 302 else
303 buildBinding 'TextBinding', node, null, startToken.value
283 304
284 for token in restTokens 305 for token in restTokens
285 node.parentNode.appendChild (text = document.createTextNode token.value) 306 text = document.createTextNode token.value
286 buildBinding text, 'textNode', token.value if token.type is 1 307 node.parentNode.appendChild text
308
309 if token.type is 1
310 buildBinding 'TextBinding', text, null, token.value
287 else if componentRegExp.test node.tagName 311 else if componentRegExp.test node.tagName
288 type = node.tagName.replace(componentRegExp, '').toLowerCase() 312 type = node.tagName.replace(componentRegExp, '').toLowerCase()
289 @bindings.push new Rivets.ComponentBinding @, node, type 313 @bindings.push new Rivets.ComponentBinding @, node, type
...@@ -308,7 +332,7 @@ class Rivets.View ...@@ -308,7 +332,7 @@ class Rivets.View
308 for attribute in attributes or node.attributes 332 for attribute in attributes or node.attributes
309 if bindingRegExp.test attribute.name 333 if bindingRegExp.test attribute.name
310 type = attribute.name.replace bindingRegExp, '' 334 type = attribute.name.replace bindingRegExp, ''
311 buildBinding node, type, attribute.value 335 buildBinding 'Binding', node, type, attribute.value
312 336
313 parse childNode for childNode in node.childNodes 337 parse childNode for childNode in node.childNodes
314 338
...@@ -642,15 +666,6 @@ Rivets.binders = ...@@ -642,15 +666,6 @@ Rivets.binders =
642 else 666 else
643 el.removeAttribute @type 667 el.removeAttribute @type
644 668
645 # Rivets.internalBinders
646 # ----------------------
647
648 # Contextually sensitive binders that are used outside of the standard attribute
649 # bindings. Put here for fast lookups and to prevent them from being overridden.
650 Rivets.internalBinders =
651 textNode: (node, value) ->
652 node.data = value ? ''
653
654 # Rivets.components 669 # Rivets.components
655 # ----------------- 670 # -----------------
656 671
......