ecb605f6 by Adam Heath

Add support for constant-text expressions. This new advanced parser

activates when it detects {{}} in the attribute value.  This can be
useful when building up values with variables interspersed with
constants.  An example is
href="/path/to/images/{{order.orderId}}/{{order.overlay}}.png"

This correctly handles bind/unbind, and updates to the possibly many
internal variables.
1 parent c5f6d853
...@@ -117,7 +117,54 @@ loopDeps = (binder, callback) -> ...@@ -117,7 +117,54 @@ loopDeps = (binder, callback) ->
117 117
118 callback model, keypath 118 callback model, keypath
119 119
120 expressionRegex = /(.*?)\{\{([^{}]+)\}\}/
121
122 createSubExpressionBinder = (outerBinding, values, i) ->
123 values[i] = null
124 routine: (el, value) ->
125 values[i] = value
126 outerBinding.sync()
127
120 defaultExpressionParser = (view, node, type, models, value) -> 128 defaultExpressionParser = (view, node, type, models, value) ->
129 if expressionRegex.test value
130 binding = new Rivets.Binding node, type, models
131
132 values = []
133 subs = []
134 while value && expressionRegex.test value
135 matches = expressionRegex.exec value
136 value = value.substring matches[0].length
137 values[values.length] = matches[1] if matches[1]
138 subs[subs.length] = subBinding = defaultExpressionParser view, null, '*', models, matches[2]
139 subBinding.binder = createSubExpressionBinder binding, values, values.length
140 values[values.length] = value if value
141 bindMethod = binding.bind
142 unbindMethod = binding.unbind
143 binding.sync = ->
144 binding.set values.join ''
145
146 # Publishes the value currently set on the input element back to the model.
147 binding.publish = ->
148 # can't really do anything with this
149
150 # Subscribes to the model for changes at the specified keypath. Bi-directional
151 # routines will also listen for changes on the element to propagate them back
152 # to the model.
153 binding.bind = ->
154 bindMethod()
155
156 for sub in subs
157 sub.bind()
158
159 # Unsubscribes from the model and the element.
160 binding.unbind = ->
161 unbindMethod()
162
163 for sub in subs
164 sub.unbind()
165
166 return binding
167
121 pipes = (pipe.trim() for pipe in value.split '|') 168 pipes = (pipe.trim() for pipe in value.split '|')
122 context = (ctx.trim() for ctx in pipes.shift().split '<') 169 context = (ctx.trim() for ctx in pipes.shift().split '<')
123 path = context.shift() 170 path = context.shift()
......