| Index: lib/src/mirror_initializer.dart
|
| diff --git a/lib/src/mirror_initializer.dart b/lib/src/mirror_initializer.dart
|
| index 5f874f8858382435f2a4e483aa028b671f1b5637..0d7ebb26eed22b524acfaaaf02e8afa51441ba47 100644
|
| --- a/lib/src/mirror_initializer.dart
|
| +++ b/lib/src/mirror_initializer.dart
|
| @@ -14,17 +14,20 @@ import 'dart:collection' show LinkedHashMap;
|
| import 'dart:mirrors';
|
| import 'dart:html';
|
| import 'package:initialize/initialize.dart' as init;
|
| +import 'package:path/path.dart' show url;
|
|
|
| const bool deployMode = false;
|
|
|
| Future run({List<Type> typeFilter, init.InitializerFilter customFilter}) async {
|
| - var libraryUris = _discoverLibrariesToLoad(document, window.location.href)
|
| - .map(Uri.parse);
|
| + var libraryUris =
|
| + _discoverLibrariesToLoad(document, window.location.href).map(Uri.parse);
|
|
|
| for (var uri in libraryUris) {
|
| await init.run(
|
| typeFilter: typeFilter, customFilter: customFilter, from: uri);
|
| }
|
| +
|
| + _validatePackageImports(document);
|
| return null;
|
| }
|
|
|
| @@ -33,8 +36,8 @@ Future run({List<Type> typeFilter, init.InitializerFilter customFilter}) async {
|
| /// called after all HTML imports are resolved. Polymer ensures this by asking
|
| /// users to put their Dart script tags after all HTML imports (this is checked
|
| /// by the linter, and Dartium will otherwise show an error message).
|
| -Iterable<_ScriptInfo> _discoverScripts(
|
| - Document doc, String baseUri, [_State state]) {
|
| +Iterable<_ScriptInfo> _discoverScripts(Document doc, String baseUri,
|
| + [_State state]) {
|
| if (state == null) state = new _State();
|
| if (doc == null) {
|
| print('warning: $baseUri not found.');
|
| @@ -82,7 +85,6 @@ class _ScriptInfo {
|
| _ScriptInfo(this.resolvedUrl, {this.packageUrl});
|
| }
|
|
|
| -
|
| // TODO(sigmund): explore other (cheaper) ways to resolve URIs relative to the
|
| // root library (see dartbug.com/12612)
|
| final _rootUri = currentMirrorSystem().isolate.rootLibrary.uri;
|
| @@ -100,8 +102,8 @@ _ScriptInfo _scriptInfoFor(script, baseUri) {
|
| // to the packages folder. If users don't create symlinks in the source
|
| // tree, then Dartium will also complain because it won't find the file seen
|
| // in an HTML import.
|
| - var packagePath = uri.path.substring(
|
| - uri.path.lastIndexOf('packages/') + 'packages/'.length);
|
| + var packagePath = uri.path
|
| + .substring(uri.path.lastIndexOf('packages/') + 'packages/'.length);
|
| return new _ScriptInfo('$uri', packageUrl: 'package:$packagePath');
|
| }
|
|
|
| @@ -130,3 +132,66 @@ final _libs = currentMirrorSystem().libraries;
|
|
|
| bool _packageUrlExists(_ScriptInfo info) =>
|
| info.isPackage && _libs[Uri.parse(info.packageUrl)] != null;
|
| +
|
| +/// All the imports that we have checked for package path validation.
|
| +final _importsSeen = new Set<LinkElement>();
|
| +
|
| +/// All the documents that we have crawled for import validation.
|
| +final _documentsSeen = new Set<Document>();
|
| +
|
| +/// Validates that all html imports to packages urls point to the right packages
|
| +/// symlink (the one next to the entry point).
|
| +void _validatePackageImports(Document doc) {
|
| + var imports = doc.querySelectorAll('link[rel="import"]');
|
| + for (LinkElement import in imports) {
|
| + // Don't re-validate imports.
|
| + if (!_importsSeen.add(import)) continue;
|
| +
|
| + // Check that the href points to the right packages path. If it doesn't we
|
| + // don't continue checking as it will print extraneous errors.
|
| + if (import.href.contains('packages/') && !_checkPackagePath(import)) {
|
| + continue;
|
| + }
|
| +
|
| + // Validate any imports contained in this import, if the document hasn't yet
|
| + // been seen.
|
| + var importDoc = import.import;
|
| + if (!_documentsSeen.add(importDoc)) continue;
|
| + _validatePackageImports(importDoc);
|
| + }
|
| +}
|
| +
|
| +/// The path to the entry document.
|
| +final entryPath = document.baseUri;
|
| +
|
| +/// Checks that the relative path from the entry point to all packages imports
|
| +/// starts with `packages/`.
|
| +bool _checkPackagePath(LinkElement import) {
|
| + var pathFromEntryPoint =
|
| + url.relative(import.href, from: url.dirname(entryPath));
|
| + if (pathFromEntryPoint.startsWith('packages/')) return true;
|
| +
|
| + LinkElement correctedImport = import.clone(false);
|
| +
|
| + var relativeUriParts = url.split(
|
| + url.relative(import.ownerDocument.baseUri, from: url.dirname(entryPath)));
|
| + var pathToEntryPoint = '../' * (relativeUriParts.length - 1);
|
| + var packagePath = import.href.substring(import.href.indexOf('packages/'));
|
| + correctedImport.href = '$pathToEntryPoint$packagePath';
|
| +
|
| + // TODO(jakemac): Throw an exception here at the next breaking change, and add
|
| + // a test at that point (no easy way to test console.error).
|
| + window.console.error('''
|
| +Found bad packages uri in html import. All packages uris should point to the
|
| +packages symlink in the same folder as the entry point.
|
| +
|
| +Entry point: $entryPath
|
| +Owner document: ${import.ownerDocument.baseUri}
|
| +Current import: ${import.outerHtml}
|
| +Corrected import: ${correctedImport.outerHtml}
|
| +
|
| +For more information, please see:
|
| +https://www.dartlang.org/polymer/app-directories.html#into-a-non-dart-non-entry-point
|
| +''');
|
| + return false;
|
| +}
|
|
|