Rewrite the DOM template parser in Rivets.View#build to include text template parsing. [#181]
Showing
1 changed file
with
63 additions
and
46 deletions
... | @@ -173,54 +173,71 @@ class Rivets.View | ... | @@ -173,54 +173,71 @@ 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 |
178 | for attribute in node.attributes | 201 | if node.nodeType is Node.TEXT_NODE |
179 | if bindingRegExp.test attribute.name | 202 | if (tokens = Rivets.TextTemplateParser.parse node.data).length |
180 | type = attribute.name.replace bindingRegExp, '' | 203 | unless tokens.length is 1 and tokens[0].type is 0 |
181 | unless binder = @binders[type] | 204 | [startToken, restTokens...] = tokens |
182 | for identifier, value of @binders | 205 | |
183 | if identifier isnt '*' and identifier.indexOf('*') isnt -1 | 206 | node.data = startToken.value |
184 | regexp = new RegExp "^#{identifier.replace('*', '.+')}$" | 207 | |
185 | if regexp.test type | 208 | switch startToken.type |
186 | binder = value | 209 | when 0 then node.data = startToken.value |
187 | 210 | when 1 then buildBinding node, 'textNode', startToken.value | |
188 | binder or= @binders['*'] | 211 | |
189 | 212 | for token in restTokens | |
190 | if binder.block | 213 | node.parentNode.appendChild (text = document.createTextNode token.value) |
191 | skipNodes.push n for n in node.getElementsByTagName '*' | 214 | buildBinding text, 'textNode', token.value if token.type is 1 |
192 | attributes = [attribute] | 215 | |
193 | 216 | else if node.attributes? | |
194 | for attribute in attributes or node.attributes | 217 | for attribute in node.attributes |
195 | if bindingRegExp.test attribute.name | 218 | if bindingRegExp.test attribute.name |
196 | options = {} | 219 | type = attribute.name.replace bindingRegExp, '' |
197 | type = attribute.name.replace bindingRegExp, '' | 220 | unless binder = @binders[type] |
198 | pipes = (pipe.trim() for pipe in attribute.value.split '|') | 221 | for identifier, value of @binders |
199 | context = (ctx.trim() for ctx in pipes.shift().split '<') | 222 | if identifier isnt '*' and identifier.indexOf('*') isnt -1 |
200 | path = context.shift() | 223 | regexp = new RegExp "^#{identifier.replace('*', '.+')}$" |
201 | splitPath = path.split /\.|:/ | 224 | if regexp.test type |
202 | options.formatters = pipes | 225 | binder = value |
203 | options.bypass = path.indexOf(':') != -1 | 226 | |
204 | if splitPath[0] | 227 | binder or= @binders['*'] |
205 | key = splitPath.shift() | 228 | |
206 | else | 229 | if binder.block |
207 | key = null | 230 | skipNodes.push n for n in node.childNodes |
208 | splitPath.shift() | 231 | attributes = [attribute] |
209 | keypath = splitPath.join '.' | 232 | |
210 | 233 | for attribute in attributes or node.attributes | |
211 | if not key or @models[key]? | 234 | if bindingRegExp.test attribute.name |
212 | if dependencies = context.shift() | 235 | type = attribute.name.replace bindingRegExp, '' |
213 | options.dependencies = dependencies.split /\s+/ | 236 | buildBinding node, type, attribute.value |
214 | 237 | ||
215 | @bindings.push new Rivets.Binding @, node, type, key, keypath, options | 238 | parse childNode for childNode in node.childNodes |
216 | 239 | ||
217 | attributes = null if attributes | 240 | parse el for el in @els |
218 | |||
219 | return | ||
220 | |||
221 | 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 | ... | ... |
-
Please register or sign in to post a comment