| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 /// Logic to validate that developers are correctly using Polymer constructs. | 5 /// Logic to validate that developers are correctly using Polymer constructs. |
| 6 /// This is mainly used to produce warnings for feedback in the editor. | 6 /// This is mainly used to produce warnings for feedback in the editor. |
| 7 library polymer.src.build.linter; | 7 library polymer.src.build.linter; |
| 8 | 8 |
| 9 import 'dart:async'; | 9 import 'dart:async'; |
| 10 | 10 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 return; | 207 return; |
| 208 } | 208 } |
| 209 | 209 |
| 210 var tagName = node.attributes['name']; | 210 var tagName = node.attributes['name']; |
| 211 var extendsTag = node.attributes['extends']; | 211 var extendsTag = node.attributes['extends']; |
| 212 | 212 |
| 213 if (tagName == null) { | 213 if (tagName == null) { |
| 214 _logger.error('Missing tag name of the custom element. Please include an ' | 214 _logger.error('Missing tag name of the custom element. Please include an ' |
| 215 'attribute like \'name="your-tag-name"\'.', | 215 'attribute like \'name="your-tag-name"\'.', |
| 216 span: node.sourceSpan); | 216 span: node.sourceSpan); |
| 217 } else if (!_isCustomTag(tagName)) { | 217 } else if (!isCustomTagName(tagName)) { |
| 218 _logger.error('Invalid name "$tagName". Custom element names must have ' | 218 _logger.error('Invalid name "$tagName". Custom element names must have ' |
| 219 'at least one dash and can\'t be any of the following names: ' | 219 'at least one dash and can\'t be any of the following names: ' |
| 220 '${_invalidTagNames.keys.join(", ")}.', | 220 '${invalidTagNames.keys.join(", ")}.', |
| 221 span: node.sourceSpan); | 221 span: node.sourceSpan); |
| 222 } | 222 } |
| 223 | 223 |
| 224 if (_elements[extendsTag] == null && _isCustomTag(extendsTag)) { | 224 if (_elements[extendsTag] == null && isCustomTagName(extendsTag)) { |
| 225 _logger.warning('custom element with name "$extendsTag" not found.', | 225 _logger.warning('custom element with name "$extendsTag" not found.', |
| 226 span: node.sourceSpan); | 226 span: node.sourceSpan); |
| 227 } | 227 } |
| 228 | 228 |
| 229 var attrs = node.attributes['attributes']; | 229 var attrs = node.attributes['attributes']; |
| 230 if (attrs != null) { | 230 if (attrs != null) { |
| 231 var attrsSpan = node.attributeSpans['attributes']; | 231 var attrsSpan = node.attributeSpans['attributes']; |
| 232 | 232 |
| 233 // names='a b c' or names='a,b,c' | 233 // names='a b c' or names='a,b,c' |
| 234 // record each name for publishing | 234 // record each name for publishing |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 node.attributes.forEach((name, value) { | 292 node.attributes.forEach((name, value) { |
| 293 if (name is String && name.startsWith('on')) { | 293 if (name is String && name.startsWith('on')) { |
| 294 _validateEventHandler(node, name, value); | 294 _validateEventHandler(node, name, value); |
| 295 } | 295 } |
| 296 }); | 296 }); |
| 297 | 297 |
| 298 // Validate uses of custom-tags | 298 // Validate uses of custom-tags |
| 299 var nodeTag = node.localName; | 299 var nodeTag = node.localName; |
| 300 var hasIsAttribute; | 300 var hasIsAttribute; |
| 301 var customTagName; | 301 var customTagName; |
| 302 if (_isCustomTag(nodeTag)) { | 302 if (isCustomTagName(nodeTag)) { |
| 303 // <fancy-button> | 303 // <fancy-button> |
| 304 customTagName = nodeTag; | 304 customTagName = nodeTag; |
| 305 hasIsAttribute = false; | 305 hasIsAttribute = false; |
| 306 } else { | 306 } else { |
| 307 // <button is="fancy-button"> | 307 // <button is="fancy-button"> |
| 308 customTagName = node.attributes['is']; | 308 customTagName = node.attributes['is']; |
| 309 hasIsAttribute = true; | 309 hasIsAttribute = true; |
| 310 } | 310 } |
| 311 | 311 |
| 312 if (customTagName == null || customTagName == 'polymer-element') return; | 312 if (customTagName == null || customTagName == 'polymer-element') return; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 | 380 |
| 381 if (value.contains('(')) { | 381 if (value.contains('(')) { |
| 382 _logger.warning('Invalid event handler body "$value". Declare a method ' | 382 _logger.warning('Invalid event handler body "$value". Declare a method ' |
| 383 'in your custom element "void handlerName(event, detail, target)" ' | 383 'in your custom element "void handlerName(event, detail, target)" ' |
| 384 'and use the form $name="handlerName".', | 384 'and use the form $name="handlerName".', |
| 385 span: node.attributeSpans[name]); | 385 span: node.attributeSpans[name]); |
| 386 } | 386 } |
| 387 } | 387 } |
| 388 } | 388 } |
| 389 | 389 |
| 390 | |
| 391 // These names have meaning in SVG or MathML, so they aren't allowed as custom | |
| 392 // tags. | |
| 393 var _invalidTagNames = const { | |
| 394 'annotation-xml': '', | |
| 395 'color-profile': '', | |
| 396 'font-face': '', | |
| 397 'font-face-src': '', | |
| 398 'font-face-uri': '', | |
| 399 'font-face-format': '', | |
| 400 'font-face-name': '', | |
| 401 'missing-glyph': '', | |
| 402 }; | |
| 403 | |
| 404 /// Returns true if this is a valid custom element name. See: | |
| 405 /// <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#df
n-custom-element-name> | |
| 406 bool _isCustomTag(String name) { | |
| 407 if (name == null || !name.contains('-')) return false; | |
| 408 return !_invalidTagNames.containsKey(name); | |
| 409 } | |
| 410 | |
| 411 const String USE_INIT_DART = | 390 const String USE_INIT_DART = |
| 412 'To run a polymer application, you need to call "initPolymer". You can ' | 391 'To run a polymer application, you need to call "initPolymer". You can ' |
| 413 'either include a generic script tag that does this for you:' | 392 'either include a generic script tag that does this for you:' |
| 414 '\'<script type="application/dart">export "package:polymer/init.dart";' | 393 '\'<script type="application/dart">export "package:polymer/init.dart";' |
| 415 '</script>\' or add your own script tag and call that function. ' | 394 '</script>\' or add your own script tag and call that function. ' |
| 416 'Make sure the script tag is placed after all HTML imports.'; | 395 'Make sure the script tag is placed after all HTML imports.'; |
| 417 | 396 |
| 418 const String BOOT_JS_DEPRECATED = | 397 const String BOOT_JS_DEPRECATED = |
| 419 '"boot.js" is now deprecated. Instead, you can initialize your polymer ' | 398 '"boot.js" is now deprecated. Instead, you can initialize your polymer ' |
| 420 'application by calling "initPolymer()" in your main. If you don\'t have a ' | 399 'application by calling "initPolymer()" in your main. If you don\'t have a ' |
| 421 'main, then you can include our generic main by adding the following ' | 400 'main, then you can include our generic main by adding the following ' |
| 422 'script tag to your page: \'<script type="application/dart">export ' | 401 'script tag to your page: \'<script type="application/dart">export ' |
| 423 '"package:polymer/init.dart";</script>\'. Additionally you need to ' | 402 '"package:polymer/init.dart";</script>\'. Additionally you need to ' |
| 424 'include: \'<script src="packages/browser/dart.js"></script>\' in the page ' | 403 'include: \'<script src="packages/browser/dart.js"></script>\' in the page ' |
| 425 'too. Make sure these script tags come after all HTML imports.'; | 404 'too. Make sure these script tags come after all HTML imports.'; |
| OLD | NEW |