Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: pkg/polymer/lib/src/build/import_inliner.dart

Issue 433913002: Strip bindings before calling Uri.parse (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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);
OLDNEW
« no previous file with comments | « no previous file | pkg/polymer/test/build/import_inliner_test.dart » ('j') | pkg/polymer/test/build/import_inliner_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698