add option to pass in bindings delimiters
BUG= https://github.com/dart-lang/polymer-dart/issues/35
R=sigmund@google.com
Review URL: https://codereview.chromium.org//1014423002
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 59705c9..8c0c07b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+#### 0.10.6
+ * Add `bindingStartDelimiters` option to the `ImportInlinerTransformer`. Any
+ urls which contain any of the supplied delimiters before the first `/` will
+ be left alone since they can't be reasoned about. If you want these urls to
+ be treated as relative to the current path you should add a `./` in front.
+
#### 0.10.5+3
* Fix normalization of relative paths inside of deep relative imports,
https://github.com/dart-lang/polymer-dart/issues/30.
diff --git a/lib/build/import_inliner.dart b/lib/build/import_inliner.dart
index 4336587..0339ca6 100644
--- a/lib/build/import_inliner.dart
+++ b/lib/build/import_inliner.dart
@@ -22,8 +22,10 @@
/// in html imports.
class ImportInlinerTransformer extends Transformer {
final List<String> entryPoints;
+ final List<String> bindingStartDelimiters;
- ImportInlinerTransformer([this.entryPoints]);
+ ImportInlinerTransformer(
+ [this.entryPoints, this.bindingStartDelimiters = const []]);
bool isPrimary(AssetId id) {
if (entryPoints != null) return entryPoints.contains(id.path);
@@ -35,8 +37,8 @@
apply(Transform transform) {
var logger = new BuildLogger(transform, convertErrorsToWarnings: true);
- return new ImportInliner(transform, transform.primaryInput.id, logger)
- .run();
+ return new ImportInliner(transform, transform.primaryInput.id, logger,
+ bindingStartDelimiters: bindingStartDelimiters).run();
}
}
@@ -49,8 +51,11 @@
final AssetId primaryInput;
// The logger to use.
final BuildLogger logger;
+ // The start delimiters for template bindings, such as '{{' or '[['.
+ final List<String> bindingStartDelimiters;
- ImportInliner(this.transform, this.primaryInput, this.logger);
+ ImportInliner(this.transform, this.primaryInput, this.logger,
+ {this.bindingStartDelimiters: const []});
Future run() {
var crawler = new ImportCrawler(transform, primaryInput, logger);
@@ -58,7 +63,8 @@
var primaryDocument = imports[primaryInput].document;
// Normalize urls in the entry point.
- var changed = new _UrlNormalizer(primaryInput, primaryInput, logger)
+ var changed = new _UrlNormalizer(
+ primaryInput, primaryInput, logger, bindingStartDelimiters)
.visit(primaryDocument);
// Inline things if needed, always have at least one (the entry point).
@@ -104,7 +110,8 @@
.querySelectorAll('script[type="$dartType"]')
.forEach((script) => script.remove());
// Normalize urls in attributes and inline css.
- new _UrlNormalizer(data.fromId, asset, logger).visit(document);
+ new _UrlNormalizer(data.fromId, asset, logger, bindingStartDelimiters)
+ .visit(document);
// Replace the import with its contents by appending the nodes
// immediately before the import one at a time, and then removing the
// import from the document.
@@ -173,9 +180,15 @@
/// Whether or not the normalizer has changed something in the tree.
bool changed = false;
+ // The start delimiters for template bindings, such as '{{' or '[['. If these
+ // are found before the first `/` in a url, then the url will not be
+ // normalized.
+ final List<String> bindingStartDelimiters;
+
final BuildLogger logger;
- _UrlNormalizer(AssetId primaryInput, this.sourceId, this.logger)
+ _UrlNormalizer(AssetId primaryInput, this.sourceId, this.logger,
+ this.bindingStartDelimiters)
: primaryInput = primaryInput,
topLevelPath = '../' * (path.url.split(primaryInput.path).length - 2);
@@ -249,6 +262,10 @@
hrefToParse = '${href.substring(0, firstFolder + 1)}';
}
+ // If we found a binding before the first `/`, then just return the original
+ // href, we can't determine anything about it.
+ if (bindingStartDelimiters.any((d) => hrefToParse.contains(d))) return href;
+
Uri uri;
// Various template systems introduce invalid characters to uris which would
// be typically replaced at runtime. Parse errors are assumed to be caused
diff --git a/pubspec.yaml b/pubspec.yaml
index 1274e1d..ce70bc0 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: web_components
-version: 0.10.5+3
+version: 0.10.6
author: Polymer.dart Authors <web-ui-dev@dartlang.org>
homepage: https://www.dartlang.org/polymer-dart/
description: >
diff --git a/test/build/import_inliner_test.dart b/test/build/import_inliner_test.dart
index 7e060a2..f0dbef6 100644
--- a/test/build/import_inliner_test.dart
+++ b/test/build/import_inliner_test.dart
@@ -9,7 +9,7 @@
import 'package:unittest/compact_vm_config.dart';
import 'package:unittest/unittest.dart';
-var transformer = new ImportInlinerTransformer();
+var transformer = new ImportInlinerTransformer(null, ['{{', '[[']);
var phases = [[transformer]];
main() {
@@ -710,6 +710,24 @@
</body></html>''',
}, [], StringFormatter.noNewlinesOrSurroundingWhitespace);
+ testPhases('paths starting with a binding are treated as absolute', phases, {
+ 'a|web/test.html': '''
+ <!DOCTYPE html><html><head>
+ <link rel="import" href="packages/a/foo.html">
+ </head></html>''',
+ 'a|lib/foo.html': '''
+ <img _src="{{bar}}">
+ <img _src="[[bar]]">''',
+ }, {
+ 'a|web/test.html': '''
+ <!DOCTYPE html><html><head></head><body>
+ <div hidden="">
+ <img _src="{{bar}}">
+ <img _src="[[bar]]">
+ </div>
+ </body></html>''',
+ }, [], StringFormatter.noNewlinesOrSurroundingWhitespace);
+
testPhases('arbitrary bindings can exist in paths', phases, {
'a|web/test.html': '''
<!DOCTYPE html><html><head></head><body>