| 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 /** | 5 /** |
| 6 * Part of the template compilation that concerns with extracting information | 6 * Part of the template compilation that concerns with extracting information |
| 7 * from the HTML parse tree. | 7 * from the HTML parse tree. |
| 8 */ | 8 */ |
| 9 library analyzer; | 9 library analyzer; |
| 10 | 10 |
| 11 import 'package:html5lib/dom.dart'; | 11 import 'package:html5lib/dom.dart'; |
| 12 import 'package:html5lib/dom_parsing.dart'; | 12 import 'package:html5lib/dom_parsing.dart'; |
| 13 import 'package:source_maps/span.dart' hide SourceFile; | 13 import 'package:source_maps/span.dart' hide SourceFile; |
| 14 | 14 |
| 15 import 'custom_tag_name.dart'; | 15 import 'custom_tag_name.dart'; |
| 16 import 'dart_parser.dart' show parseDartCode; | 16 import 'dart_parser.dart' show parseDartCode; |
| 17 import 'files.dart'; | 17 import 'files.dart'; |
| 18 import 'info.dart'; | 18 import 'info.dart'; |
| 19 import 'messages.dart'; | 19 import 'messages.dart'; |
| 20 import 'summary.dart'; | 20 import 'summary.dart'; |
| 21 | 21 |
| 22 /** | 22 /** |
| 23 * Finds custom elements in this file and the list of referenced files with | 23 * Finds custom elements in this file and the list of referenced files with |
| 24 * component declarations. This is the first pass of analysis on a file. | 24 * component declarations. This is the first pass of analysis on a file. |
| 25 * | 25 * |
| 26 * Adds emitted error/warning messages to [messages], if [messages] is | 26 * Adds emitted error/warning messages to [messages], if [messages] is |
| 27 * supplied. | 27 * supplied. |
| 28 */ | 28 */ |
| 29 FileInfo analyzeDefinitions(GlobalInfo global, UrlInfo inputUrl, | 29 FileInfo analyzeDefinitions(GlobalInfo global, UrlInfo inputUrl, |
| 30 Document document, String packageRoot, | 30 Document document, Messages messages, {bool isEntryPoint: false}) { |
| 31 Messages messages, {bool isEntryPoint: false}) { | |
| 32 var result = new FileInfo(inputUrl, isEntryPoint); | 31 var result = new FileInfo(inputUrl, isEntryPoint); |
| 33 var loader = new _ElementLoader(global, result, packageRoot, messages); | 32 var loader = new _ElementLoader(global, result, messages); |
| 34 loader.visit(document); | 33 loader.visit(document); |
| 35 return result; | 34 return result; |
| 36 } | 35 } |
| 37 | 36 |
| 38 /** | 37 /** |
| 39 * Extract relevant information from all files found from the root document. | 38 * Extract relevant information from all files found from the root document. |
| 40 * | 39 * |
| 41 * Adds emitted error/warning messages to [messages], if [messages] is | 40 * Adds emitted error/warning messages to [messages], if [messages] is |
| 42 * supplied. | 41 * supplied. |
| 43 */ | 42 */ |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 fileInfo.components[component.tagName] = component; | 339 fileInfo.components[component.tagName] = component; |
| 341 } | 340 } |
| 342 } | 341 } |
| 343 } | 342 } |
| 344 | 343 |
| 345 /** A visitor that finds `<link rel="import">` and `<element>` tags. */ | 344 /** A visitor that finds `<link rel="import">` and `<element>` tags. */ |
| 346 class _ElementLoader extends TreeVisitor { | 345 class _ElementLoader extends TreeVisitor { |
| 347 final GlobalInfo _global; | 346 final GlobalInfo _global; |
| 348 final FileInfo _fileInfo; | 347 final FileInfo _fileInfo; |
| 349 LibraryInfo _currentInfo; | 348 LibraryInfo _currentInfo; |
| 350 String _packageRoot; | |
| 351 bool _inHead = false; | 349 bool _inHead = false; |
| 352 Messages _messages; | 350 Messages _messages; |
| 353 | 351 |
| 354 /** | 352 /** |
| 355 * Adds emitted warning/error messages to [_messages]. [_messages] | 353 * Adds emitted warning/error messages to [_messages]. [_messages] |
| 356 * must not be null. | 354 * must not be null. |
| 357 */ | 355 */ |
| 358 _ElementLoader(this._global, this._fileInfo, this._packageRoot, | 356 _ElementLoader(this._global, this._fileInfo, this._messages) { |
| 359 this._messages) { | |
| 360 _currentInfo = _fileInfo; | 357 _currentInfo = _fileInfo; |
| 361 } | 358 } |
| 362 | 359 |
| 363 void visitElement(Element node) { | 360 void visitElement(Element node) { |
| 364 switch (node.tagName) { | 361 switch (node.tagName) { |
| 365 case 'link': visitLinkElement(node); break; | 362 case 'link': visitLinkElement(node); break; |
| 366 case 'element': | 363 case 'element': |
| 367 _messages.warning('<element> elements are not supported, use' | 364 _messages.warning('<element> elements are not supported, use' |
| 368 ' <polymer-element> instead', node.sourceSpan); | 365 ' <polymer-element> instead', node.sourceSpan); |
| 369 break; | 366 break; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 | 400 |
| 404 var href = node.attributes['href']; | 401 var href = node.attributes['href']; |
| 405 if (href == null || href == '') { | 402 if (href == null || href == '') { |
| 406 _messages.warning('link rel="$rel" missing href.', | 403 _messages.warning('link rel="$rel" missing href.', |
| 407 node.sourceSpan); | 404 node.sourceSpan); |
| 408 return; | 405 return; |
| 409 } | 406 } |
| 410 | 407 |
| 411 bool isStyleSheet = rel == 'stylesheet'; | 408 bool isStyleSheet = rel == 'stylesheet'; |
| 412 var urlInfo = UrlInfo.resolve(href, _fileInfo.inputUrl, node.sourceSpan, | 409 var urlInfo = UrlInfo.resolve(href, _fileInfo.inputUrl, node.sourceSpan, |
| 413 _packageRoot, _messages, ignoreAbsolute: isStyleSheet); | 410 _messages, ignoreAbsolute: isStyleSheet); |
| 414 if (urlInfo == null) return; | 411 if (urlInfo == null) return; |
| 415 if (isStyleSheet) { | 412 if (isStyleSheet) { |
| 416 _fileInfo.styleSheetHrefs.add(urlInfo); | 413 _fileInfo.styleSheetHrefs.add(urlInfo); |
| 417 } else { | 414 } else { |
| 418 _fileInfo.componentLinks.add(urlInfo); | 415 _fileInfo.componentLinks.add(urlInfo); |
| 419 } | 416 } |
| 420 } | 417 } |
| 421 | 418 |
| 422 void visitElementElement(Element node) { | 419 void visitElementElement(Element node) { |
| 423 // TODO(jmesserly): what do we do in this case? It seems like an <element> | 420 // TODO(jmesserly): what do we do in this case? It seems like an <element> |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 | 517 |
| 521 if (node.innerHtml.trim() != '') { | 518 if (node.innerHtml.trim() != '') { |
| 522 _messages.error('script tag has "src" attribute and also has script ' | 519 _messages.error('script tag has "src" attribute and also has script ' |
| 523 'text.', node.sourceSpan); | 520 'text.', node.sourceSpan); |
| 524 } | 521 } |
| 525 | 522 |
| 526 if (_currentInfo.codeAttached) { | 523 if (_currentInfo.codeAttached) { |
| 527 _tooManyScriptsError(node); | 524 _tooManyScriptsError(node); |
| 528 } else { | 525 } else { |
| 529 _currentInfo.externalFile = UrlInfo.resolve(src, _fileInfo.inputUrl, | 526 _currentInfo.externalFile = UrlInfo.resolve(src, _fileInfo.inputUrl, |
| 530 node.sourceSpan, _packageRoot, _messages); | 527 node.sourceSpan, _messages); |
| 531 } | 528 } |
| 532 return; | 529 return; |
| 533 } | 530 } |
| 534 | 531 |
| 535 if (node.nodes.length == 0) return; | 532 if (node.nodes.length == 0) return; |
| 536 | 533 |
| 537 // I don't think the html5 parser will emit a tree with more than | 534 // I don't think the html5 parser will emit a tree with more than |
| 538 // one child of <script> | 535 // one child of <script> |
| 539 assert(node.nodes.length == 1); | 536 assert(node.nodes.length == 1); |
| 540 Text text = node.nodes[0]; | 537 Text text = node.nodes[0]; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 557 } | 554 } |
| 558 | 555 |
| 559 void _tooManyScriptsError(Node node) { | 556 void _tooManyScriptsError(Node node) { |
| 560 var location = _currentInfo is ComponentInfo ? | 557 var location = _currentInfo is ComponentInfo ? |
| 561 'a custom element declaration' : 'the top-level HTML page'; | 558 'a custom element declaration' : 'the top-level HTML page'; |
| 562 | 559 |
| 563 _messages.error('there should be only one dart script tag in $location.', | 560 _messages.error('there should be only one dart script tag in $location.', |
| 564 node.sourceSpan); | 561 node.sourceSpan); |
| 565 } | 562 } |
| 566 } | 563 } |
| OLD | NEW |