Merge branch 'text-node-binding'
Showing
1 changed file
with
35 additions
and
20 deletions
... | @@ -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 | ... | ... |
-
Please register or sign in to post a comment