| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // WARNING: Do not edit - generated code. | 5 // WARNING: Do not edit - generated code. |
| 6 | 6 |
| 7 part of $LIBRARYNAME; | 7 part of $LIBRARYNAME; |
| 8 | 8 |
| 9 | 9 |
| 10 /** | 10 /** |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 * invoked. | 134 * invoked. |
| 135 * | 135 * |
| 136 * Returns true if this template was just decorated, or false if it was | 136 * Returns true if this template was just decorated, or false if it was |
| 137 * already decorated. | 137 * already decorated. |
| 138 */ | 138 */ |
| 139 @Experimental | 139 @Experimental |
| 140 static bool decorate(Element template, [Element instanceRef]) { | 140 static bool decorate(Element template, [Element instanceRef]) { |
| 141 // == true check because it starts as a null field. | 141 // == true check because it starts as a null field. |
| 142 if (template._templateIsDecorated == true) return false; | 142 if (template._templateIsDecorated == true) return false; |
| 143 | 143 |
| 144 template._templateIsDecorated = true; | |
| 145 | |
| 146 _injectStylesheet(); | 144 _injectStylesheet(); |
| 147 | 145 |
| 148 // Create content | 146 var templateElement = template; |
| 149 if (template is! TemplateElement) { | 147 var isNative = templateElement is TemplateElement; |
| 150 var doc = _getTemplateContentsOwner(template.document); | 148 var bootstrapContents = isNative; |
| 151 template._templateContent = doc.createDocumentFragment(); | 149 var liftContents = !isNative; |
| 150 var liftRoot = false; |
| 151 |
| 152 if (!isNative && templateElement._isAttributeTemplate) { |
| 153 if (instanceRef != null) { |
| 154 // TODO(jmesserly): this is just an assert in MDV. |
| 155 throw new ArgumentError('instanceRef should not be supplied for ' |
| 156 'attribute templates.'); |
| 157 } |
| 158 templateElement = _extractTemplateFromAttributeTemplate(template); |
| 159 isNative = templateElement is TemplateElement; |
| 160 liftRoot = true; |
| 161 } |
| 162 |
| 163 templateElement._templateIsDecorated = true; |
| 164 |
| 165 if (!isNative) { |
| 166 var doc = _getTemplateContentsOwner(templateElement.document); |
| 167 templateElement._templateContent = doc.createDocumentFragment(); |
| 152 } | 168 } |
| 153 | 169 |
| 154 if (instanceRef != null) { | 170 if (instanceRef != null) { |
| 155 template._templateInstanceRef = instanceRef; | 171 // template is contained within an instance, its direct content must be |
| 156 return true; // content is empty. | 172 // empty |
| 157 } | 173 templateElement._templateInstanceRef = instanceRef; |
| 158 | 174 } else if (liftContents) { |
| 159 if (template is TemplateElement) { | 175 _liftNonNativeChildrenIntoContent(templateElement, template, liftRoot); |
| 160 bootstrap(template.content); | 176 } else if (bootstrapContents) { |
| 161 } else { | 177 bootstrap(templateElement.content); |
| 162 _liftNonNativeChildrenIntoContent(template); | |
| 163 } | 178 } |
| 164 | 179 |
| 165 return true; | 180 return true; |
| 166 } | 181 } |
| 167 | 182 |
| 168 // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#
dfn-template-contents-owner | 183 // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#
dfn-template-contents-owner |
| 169 static Document _getTemplateContentsOwner(HtmlDocument doc) { | 184 static Document _getTemplateContentsOwner(HtmlDocument doc) { |
| 170 if (doc.window == null) { | 185 if (doc.window == null) { |
| 171 return doc; | 186 return doc; |
| 172 } | 187 } |
| 173 var d = doc._templateContentsOwner; | 188 var d = doc._templateContentsOwner; |
| 174 if (d == null) { | 189 if (d == null) { |
| 175 // TODO(arv): This should either be a Document or HTMLDocument depending | 190 // TODO(arv): This should either be a Document or HTMLDocument depending |
| 176 // on doc. | 191 // on doc. |
| 177 d = doc.implementation.createHtmlDocument(''); | 192 d = doc.implementation.createHtmlDocument(''); |
| 178 while (d.lastChild != null) { | 193 while (d.lastChild != null) { |
| 179 d.lastChild.remove(); | 194 d.lastChild.remove(); |
| 180 } | 195 } |
| 181 doc._templateContentsOwner = d; | 196 doc._templateContentsOwner = d; |
| 182 } | 197 } |
| 183 return d; | 198 return d; |
| 184 } | 199 } |
| 185 | 200 |
| 186 static Element _cloneAndSeperateAttributeTemplate(Element templateElement) { | 201 // For non-template browsers, the parser will disallow <template> in certain |
| 187 var clone = templateElement.clone(false); | 202 // locations, so we allow "attribute templates" which combine the template |
| 188 var attributes = templateElement.attributes; | 203 // element with the top-level container node of the content, e.g. |
| 189 for (var name in attributes.keys.toList()) { | 204 // |
| 205 // <tr template repeat="{{ foo }}"" class="bar"><td>Bar</td></tr> |
| 206 // |
| 207 // becomes |
| 208 // |
| 209 // <template repeat="{{ foo }}"> |
| 210 // + #document-fragment |
| 211 // + <tr class="bar"> |
| 212 // + <td>Bar</td> |
| 213 // |
| 214 static Element _extractTemplateFromAttributeTemplate(Element el) { |
| 215 var template = el.document.$dom_createElement('template'); |
| 216 el.parentNode.insertBefore(template, el); |
| 217 |
| 218 for (var name in el.attributes.keys.toList()) { |
| 190 switch (name) { | 219 switch (name) { |
| 191 case 'template': | 220 case 'template': |
| 221 el.attributes.remove(name); |
| 222 break; |
| 192 case 'repeat': | 223 case 'repeat': |
| 193 case 'bind': | 224 case 'bind': |
| 194 case 'ref': | 225 case 'ref': |
| 195 clone.attributes.remove(name); | 226 template.attributes[name] = el.attributes.remove(name); |
| 196 break; | |
| 197 default: | |
| 198 attributes.remove(name); | |
| 199 break; | 227 break; |
| 200 } | 228 } |
| 201 } | 229 } |
| 202 | 230 |
| 203 return clone; | 231 return template; |
| 204 } | 232 } |
| 205 | 233 |
| 206 static void _liftNonNativeChildrenIntoContent(Element templateElement) { | 234 static void _liftNonNativeChildrenIntoContent(Element template, Element el, |
| 207 var content = templateElement.content; | 235 bool useRoot) { |
| 208 | 236 |
| 209 if (!templateElement._isAttributeTemplate) { | 237 var content = template.content; |
| 210 var child; | 238 if (useRoot) { |
| 211 while ((child = templateElement.firstChild) != null) { | 239 content.append(el); |
| 212 content.append(child); | |
| 213 } | |
| 214 return; | 240 return; |
| 215 } | 241 } |
| 216 | 242 |
| 217 // For attribute templates we copy the whole thing into the content and | |
| 218 // we move the non template attributes into the content. | |
| 219 // | |
| 220 // <tr foo template> | |
| 221 // | |
| 222 // becomes | |
| 223 // | |
| 224 // <tr template> | |
| 225 // + #document-fragment | |
| 226 // + <tr foo> | |
| 227 // | |
| 228 var newRoot = _cloneAndSeperateAttributeTemplate(templateElement); | |
| 229 var child; | 243 var child; |
| 230 while ((child = templateElement.firstChild) != null) { | 244 while ((child = el.firstChild) != null) { |
| 231 newRoot.append(child); | 245 content.append(child); |
| 232 } | 246 } |
| 233 content.append(newRoot); | |
| 234 } | 247 } |
| 235 | 248 |
| 236 /** | 249 /** |
| 237 * This used to decorate recursively all templates from a given node. | 250 * This used to decorate recursively all templates from a given node. |
| 238 * | 251 * |
| 239 * By default [decorate] will be called on templates lazily when certain | 252 * By default [decorate] will be called on templates lazily when certain |
| 240 * properties such as [model] are accessed, but it can be run eagerly to | 253 * properties such as [model] are accessed, but it can be run eagerly to |
| 241 * decorate an entire tree recursively. | 254 * decorate an entire tree recursively. |
| 242 */ | 255 */ |
| 243 // TODO(rafaelw): Review whether this is the right public API. | 256 // TODO(rafaelw): Review whether this is the right public API. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 document.head.append(style); | 300 document.head.append(style); |
| 288 } | 301 } |
| 289 | 302 |
| 290 /** | 303 /** |
| 291 * A mapping of names to Custom Syntax objects. See [CustomBindingSyntax] for | 304 * A mapping of names to Custom Syntax objects. See [CustomBindingSyntax] for |
| 292 * more information. | 305 * more information. |
| 293 */ | 306 */ |
| 294 @Experimental | 307 @Experimental |
| 295 static Map<String, CustomBindingSyntax> syntax = {}; | 308 static Map<String, CustomBindingSyntax> syntax = {}; |
| 296 } | 309 } |
| OLD | NEW |