| 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 /// Transfomer that inlines polymer-element definitions from html imports. | 5 /// Transfomer that inlines polymer-element definitions from html imports. |
| 6 library polymer.src.build.import_inliner; | 6 library polymer.src.build.import_inliner; |
| 7 | 7 |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:convert'; | 9 import 'dart:convert'; |
| 10 | 10 |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 } | 410 } |
| 411 | 411 |
| 412 if (!output.hasEdits) return code; | 412 if (!output.hasEdits) return code; |
| 413 | 413 |
| 414 // TODO(sigmund): emit source maps when barback supports it (see | 414 // TODO(sigmund): emit source maps when barback supports it (see |
| 415 // dartbug.com/12340) | 415 // dartbug.com/12340) |
| 416 return (output.commit()..build(file.url)).text; | 416 return (output.commit()..build(file.url)).text; |
| 417 } | 417 } |
| 418 | 418 |
| 419 String _newUrl(String href, Span span) { | 419 String _newUrl(String href, Span span) { |
| 420 // Uri.parse blows up on invalid characters (like {{). Encoding the uri | 420 // Take all bindings out of the path and replace with [BINDING_PLACEHOLDER] |
| 421 // allows it to be parsed, which does the correct thing in the general case. | 421 // so [Uri.parse] will not fail. |
| 422 // This uri not used to build the new uri, so it never needs to be decoded. | 422 var bindingMatches = BINDING_REGEX.allMatches(href).map((m) => m.group(0)); |
| 423 var uri = Uri.parse(Uri.encodeFull(href)); | 423 href = href.replaceAll(BINDING_REGEX, BINDING_PLACEHOLDER); |
| 424 |
| 425 var uri = Uri.parse(href); |
| 424 if (uri.isAbsolute) return href; | 426 if (uri.isAbsolute) return href; |
| 425 if (!uri.scheme.isEmpty) return href; | 427 if (!uri.scheme.isEmpty) return href; |
| 426 if (!uri.host.isEmpty) return href; | 428 if (!uri.host.isEmpty) return href; |
| 427 if (uri.path.isEmpty) return href; // Implies standalone ? or # in URI. | 429 if (uri.path.isEmpty) return href; // Implies standalone ? or # in URI. |
| 428 if (path.isAbsolute(href)) return href; | 430 if (path.isAbsolute(href)) return href; |
| 429 | 431 |
| 430 var id = uriToAssetId(sourceId, href, transform.logger, span); | 432 var id = uriToAssetId(sourceId, href, transform.logger, span); |
| 431 if (id == null) return href; | 433 if (id == null) return href; |
| 432 var primaryId = transform.primaryInput.id; | 434 var primaryId = transform.primaryInput.id; |
| 433 | 435 |
| 434 if (id.path.startsWith('lib/')) { | 436 // Put the original bindings back into the path now that we have parsed it. |
| 435 return '${topLevelPath}packages/${id.package}/${id.path.substring(4)}'; | 437 var newPath = id.path; |
| 438 for (var bindingMatch in bindingMatches) { |
| 439 newPath = newPath.replaceFirst(BINDING_PLACEHOLDER, bindingMatch); |
| 436 } | 440 } |
| 437 | 441 |
| 438 if (id.path.startsWith('asset/')) { | 442 if (newPath.startsWith('lib/')) { |
| 439 return '${topLevelPath}assets/${id.package}/${id.path.substring(6)}'; | 443 return '${topLevelPath}packages/${id.package}/${newPath.substring(4)}'; |
| 444 } |
| 445 |
| 446 if (newPath.startsWith('asset/')) { |
| 447 return '${topLevelPath}assets/${id.package}/${newPath.substring(6)}'; |
| 440 } | 448 } |
| 441 | 449 |
| 442 if (primaryId.package != id.package) { | 450 if (primaryId.package != id.package) { |
| 443 // Techincally we shouldn't get there | 451 // Techincally we shouldn't get there |
| 444 transform.logger.error("don't know how to include $id from $primaryId", | 452 transform.logger.error("don't know how to include $id from $primaryId", |
| 445 span: span); | 453 span: span); |
| 446 return href; | 454 return href; |
| 447 } | 455 } |
| 448 | 456 |
| 449 var builder = path.url; | 457 var builder = path.url; |
| 450 return builder.relative(builder.join('/', id.path), | 458 return builder.relative(builder.join('/', newPath), |
| 451 from: builder.join('/', builder.dirname(primaryId.path))); | 459 from: builder.join('/', builder.dirname(primaryId.path))); |
| 452 } | 460 } |
| 453 } | 461 } |
| 454 | 462 |
| 455 /// HTML attributes that expect a URL value. | 463 /// HTML attributes that expect a URL value. |
| 456 /// <http://dev.w3.org/html5/spec/section-index.html#attributes-1> | 464 /// <http://dev.w3.org/html5/spec/section-index.html#attributes-1> |
| 457 /// | 465 /// |
| 458 /// Every one of these attributes is a URL in every context where it is used in | 466 /// Every one of these attributes is a URL in every context where it is used in |
| 459 /// the DOM. The comments show every DOM element where an attribute can be used. | 467 /// the DOM. The comments show every DOM element where an attribute can be used. |
| 460 const _urlAttributes = const [ | 468 const _urlAttributes = const [ |
| 461 'action', // in form | 469 'action', // in form |
| 462 'background', // in body | 470 'background', // in body |
| 463 'cite', // in blockquote, del, ins, q | 471 'cite', // in blockquote, del, ins, q |
| 464 'data', // in object | 472 'data', // in object |
| 465 'formaction', // in button, input | 473 'formaction', // in button, input |
| 466 'href', // in a, area, link, base, command | 474 'href', // in a, area, link, base, command |
| 467 'icon', // in command | 475 'icon', // in command |
| 468 'manifest', // in html | 476 'manifest', // in html |
| 469 'poster', // in video | 477 'poster', // in video |
| 470 'src', // in audio, embed, iframe, img, input, script, source, track, | 478 'src', // in audio, embed, iframe, img, input, script, source, track, |
| 471 // video | 479 // video |
| 472 ]; | 480 ]; |
| 473 | 481 |
| 474 /// When inlining <link rel="stylesheet"> tags copy over all attributes to the | 482 /// When inlining <link rel="stylesheet"> tags copy over all attributes to the |
| 475 /// style tag except these ones. | 483 /// style tag except these ones. |
| 476 const IGNORED_LINKED_STYLE_ATTRS = | 484 const IGNORED_LINKED_STYLE_ATTRS = |
| 477 const ['charset', 'href', 'href-lang', 'rel', 'rev']; | 485 const ['charset', 'href', 'href-lang', 'rel', 'rev']; |
| 478 | 486 |
| 479 /// Global RegExp objects for validating generated library names. | 487 /// Global RegExp objects. |
| 480 final INVALID_LIB_CHARS_REGEX = new RegExp('[^a-z0-9_]'); | 488 final INVALID_LIB_CHARS_REGEX = new RegExp('[^a-z0-9_]'); |
| 481 final NUM_REGEX = new RegExp('[0-9]'); | 489 final NUM_REGEX = new RegExp('[0-9]'); |
| 490 final BINDING_REGEX = new RegExp(r'({{.*}})'); |
| 491 |
| 492 /// Placeholder for bindings in urls for [Uri.parse]. |
| 493 final BINDING_PLACEHOLDER = '%BINDING%'; |
| 482 | 494 |
| 483 _getSpan(SourceFile file, AstNode node) => file.span(node.offset, node.end); | 495 _getSpan(SourceFile file, AstNode node) => file.span(node.offset, node.end); |
| OLD | NEW |