Permalink
Browse files

Add a proper data-bind-style binding.

Supports both CSS string bindings and Batman.Hashes. Note that
Batman.Objects are not supported since they don't have item
added/removed events.

Fixes #176.
  • Loading branch information...
Kamil Tusznio
Kamil Tusznio committed Oct 12, 2011
1 parent c9b2602 commit ca641670b2d663a211de9f7a741a2daafd6cbc48
Showing with 106 additions and 5 deletions.
  1. +37 −3 lib/batman.js
  2. +33 −2 src/batman.coffee
  3. +36 −0 tests/batman/view/simple_rendering_test.coffee
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -434,6 +434,7 @@ class Batman.Property
valueFromAccessor: -> @accessor().get?.call(@base, @key)
setValue: (val) ->
+ @cached = no
result = @accessor().set?.call(@base, @key, val)
@refresh()
result
@@ -867,7 +868,6 @@ class Batman.Hash extends Batman.Object
@accessor
get: Batman.SimpleHash::get
set: @mutation (key, value) ->
- old = @get(key)
result = Batman.SimpleHash::set.call(@, key, value)
@fire 'itemsWereAdded', key
result
@@ -3023,12 +3023,14 @@ Batman.DOM = {
context: context
key: key
- when 'value', 'style', 'href', 'src', 'size'
+ when 'value', 'href', 'src', 'size'
dataChange = (value) -> node[attr] = value
nodeChange = (node, subContext) -> subContext.set(key, Batman.DOM.attrReaders._parseAttribute(node[attr]))
when 'class'
dataChange = (value) -> node.className = value
nodeChange = (node, subContext) -> subContext.set key, node.className
+ when 'style'
+ return Batman.DOM.binders.style node, attr, key, context, renderer, only
else
dataChange = (value) -> node.setAttribute(attr, value)
nodeChange = (node, subContext) -> subContext.set(key, Batman.DOM.attrReaders._parseAttribute(node.getAttribute(attr)))
@@ -3146,6 +3148,35 @@ Batman.DOM = {
context.bind node, key, dataChange, nodeChange, only
true
+ style: (node, attr, key, context, renderer, only) ->
+ dataChange = (value) ->
+ return node.setAttribute('style', '') unless value
+ return node.setAttribute('style', value) if typeof value is 'string'
+
+ if value instanceof Batman.Hash
+ onItemsAdded = (newKey) ->
+ node.style[newKey] = value.get(newKey)
+ onItemsRemoved = (oldKey) ->
+ node.style[oldKey] = ''
+
+ # remove listeners from a previously bound hash
+ if oldHash
+ oldHash.forget 'itemsWereAdded', onItemsAdded
+ oldHash.forget 'itemsWereRemoved', onItemsRemoved
+ oldHash = value
+
+ # attach listeners
+ value.on 'itemsWereAdded', onItemsAdded
+ value.on 'itemsWereRemoved', onItemsRemoved
+
+ # initialize styles
+ value.keys().forEach onItemsAdded
+
+ nodeChange = (node, subContext) -> subContext.set(key, node.style.cssText)
+
+ context.bind(node, key, dataChange, nodeChange, only)
+ true
+
radio: (node, key, context, renderer, only) ->
dataChange = (value) ->
# don't overwrite `checked` attributes in the HTML unless a bound
@@ -486,6 +486,42 @@ asyncTest 'should bind to the value of radio buttons', ->
delay =>
equal context.get('ad.sale_type'), 'fixed'
+asyncTest 'data-bind-style should bind to a string', 4, ->
+ source = '<div data-bind-style="string"></div>'
+ context = Batman
+ string: 'background-color:blue; color:green;'
+
+ helpers.render source, context, (node) ->
+ equal node[0].style['background-color'], 'blue'
+ equal node[0].style['color'], 'green'
+ context.set 'string', 'background-color:green'
+ delay =>
+ equal node[0].style['background-color'], 'green'
+ equal node[0].style['color'], ''
+
+asyncTest 'data-bind-style should bind to a Batman object', 8, ->
+ source = '<div data-bind-style="object"></div>'
+ context = Batman
+ object: new Batman.Hash
+ 'background-color': 'blue'
+ color: 'green'
+
+ helpers.render source, context, (node) ->
+ equal node[0].style['background-color'], 'blue'
+ equal node[0].style['color'], 'green'
+ context.set 'object.color', 'blue'
+ delay =>
+ equal node[0].style['color'], 'blue'
+ equal node[0].style['background-color'], 'blue'
+ context.unset 'object.color'
+ delay =>
+ equal node[0].style['color'], ''
+ equal node[0].style['background-color'], 'blue'
+ context.set 'object', new Batman.Hash color: 'yellow'
+ delay =>
+ equal node[0].style['color'], 'yellow'
+ equal node[0].style['background-color'], 'blue'
+
QUnit.module "Memory safety"
test "addEventListener and removeEventListener store and remove callbacks using Batman.data", ->

0 comments on commit ca64167

Please sign in to comment.