f7c291b5 by Michael Richards

Rewrite the DOM template parser in Rivets.View#build to include text template parsing. [#181]

1 parent 6cb9af1e
...@@ -173,8 +173,47 @@ class Rivets.View ...@@ -173,8 +173,47 @@ class Rivets.View
173 skipNodes = [] 173 skipNodes = []
174 bindingRegExp = @bindingRegExp() 174 bindingRegExp = @bindingRegExp()
175 175
176 buildBinding = (node, type, declaration) =>
177 options = {}
178
179 pipes = (pipe.trim() for pipe in declaration.split '|')
180 context = (ctx.trim() for ctx in pipes.shift().split '<')
181 path = context.shift()
182 splitPath = path.split /\.|:/
183 options.formatters = pipes
184 options.bypass = path.indexOf(':') != -1
185
186 if splitPath[0]
187 key = splitPath.shift()
188 else
189 key = null
190 splitPath.shift()
191
192 keypath = splitPath.join '.'
193
194 if dependencies = context.shift()
195 options.dependencies = dependencies.split /\s+/
196
197 @bindings.push new Rivets.Binding @, node, type, key, keypath, options
198
176 parse = (node) => 199 parse = (node) =>
177 unless node in skipNodes 200 unless node in skipNodes
201 if node.nodeType is Node.TEXT_NODE
202 if (tokens = Rivets.TextTemplateParser.parse node.data).length
203 unless tokens.length is 1 and tokens[0].type is 0
204 [startToken, restTokens...] = tokens
205
206 node.data = startToken.value
207
208 switch startToken.type
209 when 0 then node.data = startToken.value
210 when 1 then buildBinding node, 'textNode', startToken.value
211
212 for token in restTokens
213 node.parentNode.appendChild (text = document.createTextNode token.value)
214 buildBinding text, 'textNode', token.value if token.type is 1
215
216 else if node.attributes?
178 for attribute in node.attributes 217 for attribute in node.attributes
179 if bindingRegExp.test attribute.name 218 if bindingRegExp.test attribute.name
180 type = attribute.name.replace bindingRegExp, '' 219 type = attribute.name.replace bindingRegExp, ''
...@@ -188,39 +227,17 @@ class Rivets.View ...@@ -188,39 +227,17 @@ class Rivets.View
188 binder or= @binders['*'] 227 binder or= @binders['*']
189 228
190 if binder.block 229 if binder.block
191 skipNodes.push n for n in node.getElementsByTagName '*' 230 skipNodes.push n for n in node.childNodes
192 attributes = [attribute] 231 attributes = [attribute]
193 232
194 for attribute in attributes or node.attributes 233 for attribute in attributes or node.attributes
195 if bindingRegExp.test attribute.name 234 if bindingRegExp.test attribute.name
196 options = {}
197 type = attribute.name.replace bindingRegExp, '' 235 type = attribute.name.replace bindingRegExp, ''
198 pipes = (pipe.trim() for pipe in attribute.value.split '|') 236 buildBinding node, type, attribute.value
199 context = (ctx.trim() for ctx in pipes.shift().split '<')
200 path = context.shift()
201 splitPath = path.split /\.|:/
202 options.formatters = pipes
203 options.bypass = path.indexOf(':') != -1
204 if splitPath[0]
205 key = splitPath.shift()
206 else
207 key = null
208 splitPath.shift()
209 keypath = splitPath.join '.'
210 237
211 if not key or @models[key]? 238 parse childNode for childNode in node.childNodes
212 if dependencies = context.shift()
213 options.dependencies = dependencies.split /\s+/
214
215 @bindings.push new Rivets.Binding @, node, type, key, keypath, options
216
217 attributes = null if attributes
218
219 return
220 239
221 for el in @els 240 parse el for el in @els
222 parse el
223 parse node for node in el.getElementsByTagName '*' when node.attributes?
224 241
225 return 242 return
226 243
......