| Index: web_components/lib/build/script_compactor.dart
|
| diff --git a/web_components/lib/build/script_compactor.dart b/web_components/lib/build/script_compactor.dart
|
| deleted file mode 100644
|
| index 12655b3e5870b6ec9fcc26b78fec78a129195ce1..0000000000000000000000000000000000000000
|
| --- a/web_components/lib/build/script_compactor.dart
|
| +++ /dev/null
|
| @@ -1,261 +0,0 @@
|
| -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -library web_components.build.script_compactor;
|
| -
|
| -import 'dart:async';
|
| -import 'package:analyzer/analyzer.dart';
|
| -import 'package:barback/barback.dart';
|
| -import 'package:code_transformers/assets.dart';
|
| -import 'package:code_transformers/messages/build_logger.dart';
|
| -import 'package:html/dom.dart' as dom;
|
| -import 'package:html/parser.dart' as parser;
|
| -import 'package:path/path.dart' as path;
|
| -import 'package:source_maps/refactor.dart' show TextEditTransaction;
|
| -import 'package:source_span/source_span.dart';
|
| -import 'common.dart';
|
| -import 'import_crawler.dart';
|
| -import 'messages.dart';
|
| -
|
| -/// Transformer which combines all dart scripts found in html imports into one
|
| -/// new bootstrap file, and replaces the old entry point script with that file.
|
| -///
|
| -/// Note: Does not delete the original script files (it can't because the
|
| -/// imports may live in other packages). The [ImportInlinerTransformer] will not
|
| -/// copy scripts when inlining imports into your entry point to compensate for
|
| -/// this.
|
| -class ScriptCompactorTransformer extends Transformer {
|
| - final List<String> entryPoints;
|
| -
|
| - ScriptCompactorTransformer([this.entryPoints]);
|
| -
|
| - bool isPrimary(AssetId id) {
|
| - if (entryPoints != null) return entryPoints.contains(id.path);
|
| - // If no entry point is supplied, then any html file under web/ or test/ is
|
| - // an entry point.
|
| - return (id.path.startsWith('web/') || id.path.startsWith('test/')) &&
|
| - id.path.endsWith('.html');
|
| - }
|
| -
|
| - apply(Transform transform) {
|
| - var logger = new BuildLogger(transform);
|
| - return new ScriptCompactor(transform, transform.primaryInput.id, logger)
|
| - .run()
|
| - .then((Asset bootstrap) {
|
| - if (bootstrap == null) return null;
|
| - return transform.primaryInput.readAsString().then((html) {
|
| - var doc = parser.parse(html);
|
| - var mainScriptTag = doc.querySelector('script[type="$dartType"]');
|
| - mainScriptTag.attributes['src'] =
|
| - _importPath(bootstrap.id, transform.primaryInput.id);
|
| - mainScriptTag.text = '';
|
| -
|
| - transform.addOutput(
|
| - new Asset.fromString(transform.primaryInput.id, doc.outerHtml));
|
| - });
|
| - });
|
| - }
|
| -}
|
| -
|
| -/// Helper class which does all the script compacting for a single entry point.
|
| -class ScriptCompactor {
|
| - /// Can be an AggregateTransform or Transform
|
| - final transform;
|
| -
|
| - /// The primary input to start from.
|
| - final AssetId primaryInput;
|
| -
|
| - /// The logger to use.
|
| - final BuildLogger logger;
|
| -
|
| - /// How many inline scripts were extracted.
|
| - int inlineScriptCounter = 0;
|
| -
|
| - /// Id representing the dart script which lives in the primaryInput.
|
| - AssetId mainScript;
|
| -
|
| - /// Ids of all the scripts found in html imports.
|
| - final Set<AssetId> importScripts = new Set<AssetId>();
|
| -
|
| - ScriptCompactor(this.transform, this.primaryInput, this.logger);
|
| -
|
| - Future<Asset> run() {
|
| - var crawler = new ImportCrawler(transform, primaryInput, logger);
|
| - return crawler.crawlImports().then((imports) {
|
| - Future extractScripts(id) =>
|
| - _extractInlineScripts(id, imports[id].document);
|
| -
|
| - return Future.forEach(imports.keys, extractScripts).then((_) {
|
| - if (mainScript == null) {
|
| - logger.error(
|
| - exactlyOneScriptPerEntryPoint.create({'url': primaryInput.path}));
|
| - return null;
|
| - }
|
| -
|
| - var primaryDocument = imports[primaryInput].document;
|
| - assert(primaryDocument != null);
|
| -
|
| - // Create the new bootstrap file and return its AssetId.
|
| - return _buildBootstrapFile(mainScript, importScripts);
|
| - });
|
| - });
|
| - }
|
| -
|
| - /// Builds the bootstrap file and returns the path to it relative to
|
| - /// [primaryInput].
|
| - Asset _buildBootstrapFile(AssetId mainScript, Set<AssetId> importScripts) {
|
| - var bootstrapId = new AssetId(primaryInput.package,
|
| - primaryInput.path.replaceFirst('.html', '.bootstrap.dart'));
|
| -
|
| - var buffer = new StringBuffer();
|
| - buffer.writeln('library ${_libraryNameFor(bootstrapId)};');
|
| - buffer.writeln();
|
| - var i = 0;
|
| - for (var script in importScripts) {
|
| - var path = _importPath(script, primaryInput);
|
| - buffer.writeln("import '$path' as i$i;");
|
| - i++;
|
| - }
|
| - var mainScriptPath = _importPath(mainScript, primaryInput);
|
| - buffer.writeln("import '$mainScriptPath' as i$i;");
|
| - buffer.writeln();
|
| - buffer.writeln('main() => i$i.main();');
|
| -
|
| - var bootstrap = new Asset.fromString(bootstrapId, '$buffer');
|
| - transform.addOutput(bootstrap);
|
| - return bootstrap;
|
| - }
|
| -
|
| - /// Split inline scripts into their own files. We need to do this for dart2js
|
| - /// to be able to compile them.
|
| - ///
|
| - /// This also validates that there weren't any duplicate scripts.
|
| - Future _extractInlineScripts(AssetId asset, dom.Document doc) {
|
| - var scripts = doc.querySelectorAll('script[type="$dartType"]');
|
| - return Future.forEach(scripts, (script) {
|
| - var type = script.attributes['type'];
|
| - var src = script.attributes['src'];
|
| -
|
| - if (src != null) {
|
| - return _addScript(
|
| - asset, uriToAssetId(asset, src, logger, script.sourceSpan),
|
| - span: script.sourceSpan);
|
| - }
|
| -
|
| - final count = inlineScriptCounter++;
|
| - var code = script.text;
|
| - // TODO(sigmund): ensure this path is unique (dartbug.com/12618).
|
| - var newId = primaryInput.addExtension('.$count.dart');
|
| - if (!_hasLibraryDirective(code)) {
|
| - var libName = _libraryNameFor(primaryInput, count);
|
| - code = "library $libName;\n$code";
|
| - }
|
| -
|
| - // Normalize dart import paths.
|
| - code = _normalizeDartImports(code, asset, primaryInput);
|
| -
|
| - // Write out the file and record it.
|
| - transform.addOutput(new Asset.fromString(newId, code));
|
| -
|
| - return _addScript(asset, newId, validate: false).then((_) {
|
| - // If in the entry point, replace the inline script with one pointing to
|
| - // the new source file.
|
| - if (primaryInput == asset) {
|
| - script.text = '';
|
| - script.attributes['src'] = path.url.relative(newId.path,
|
| - from: path.url.dirname(primaryInput.path));
|
| - }
|
| - });
|
| - });
|
| - }
|
| -
|
| - // Normalize dart import paths when moving code from one asset to another.
|
| - String _normalizeDartImports(String code, AssetId from, AssetId to) {
|
| - var unit = parseDirectives(code, suppressErrors: true);
|
| - var file = new SourceFile(code, url: spanUrlFor(from, to, logger));
|
| - var output = new TextEditTransaction(code, file);
|
| - var foundLibraryDirective = false;
|
| - for (Directive directive in unit.directives) {
|
| - if (directive is UriBasedDirective) {
|
| - var uri = directive.uri.stringValue;
|
| - var span = getSpan(file, directive.uri);
|
| -
|
| - var id = uriToAssetId(from, uri, logger, span, errorOnAbsolute: false);
|
| - if (id == null) continue;
|
| -
|
| - var primaryId = primaryInput;
|
| - var newUri = assetUrlFor(id, primaryId, logger);
|
| - if (newUri != uri) {
|
| - output.edit(span.start.offset, span.end.offset, "'$newUri'");
|
| - }
|
| - } else if (directive is LibraryDirective) {
|
| - foundLibraryDirective = true;
|
| - }
|
| - }
|
| -
|
| - if (!output.hasEdits) return code;
|
| -
|
| - // TODO(sigmund): emit source maps when barback supports it (see
|
| - // dartbug.com/12340)
|
| - return (output.commit()..build(file.url.toString())).text;
|
| - }
|
| -
|
| - Future _addScript(AssetId from, AssetId scriptId,
|
| - {bool validate: true, SourceSpan span}) {
|
| - var validateFuture;
|
| - if (validate && !importScripts.contains(scriptId)) {
|
| - validateFuture = transform.hasInput(scriptId);
|
| - } else {
|
| - validateFuture = new Future.value(true);
|
| - }
|
| - return validateFuture.then((exists) {
|
| - if (!exists) {
|
| - logger.warning(scriptFileNotFound.create({'url': scriptId}),
|
| - span: span);
|
| - }
|
| -
|
| - if (from == primaryInput) {
|
| - if (mainScript != null) {
|
| - logger
|
| - .error(exactlyOneScriptPerEntryPoint.create({'url': from.path}));
|
| - }
|
| - mainScript = scriptId;
|
| - } else {
|
| - importScripts.add(scriptId);
|
| - }
|
| - });
|
| - }
|
| -}
|
| -
|
| -/// Generate a library name for an asset.
|
| -String _libraryNameFor(AssetId id, [int suffix]) {
|
| - var name = '${path.withoutExtension(id.path)}_'
|
| - '${path.extension(id.path).substring(1)}';
|
| - if (name.startsWith('lib/')) name = name.substring(4);
|
| - name = name.split('/').map((part) {
|
| - part = part.replaceAll(_invalidLibCharsRegex, '_');
|
| - if (part.startsWith(_numRegex)) part = '_${part}';
|
| - return part;
|
| - }).join(".");
|
| - var suffixString = suffix != null ? '_$suffix' : '';
|
| - return '${id.package}.${name}$suffixString';
|
| -}
|
| -
|
| -/// Parse [code] and determine whether it has a library directive.
|
| -bool _hasLibraryDirective(String code) =>
|
| - parseDirectives(code, suppressErrors: true).directives
|
| - .any((d) => d is LibraryDirective);
|
| -
|
| -/// Returns the dart import path to reach [id] relative to [primaryInput].
|
| -String _importPath(AssetId id, AssetId primaryInput) {
|
| - var parts = path.url.split(id.path);
|
| - if (parts[0] == 'lib') {
|
| - parts[0] = id.package;
|
| - return 'package:${path.url.joinAll(parts)}';
|
| - }
|
| - return path.url.relative(id.path, from: path.url.dirname(primaryInput.path));
|
| -}
|
| -
|
| -// Constant and final variables
|
| -final _invalidLibCharsRegex = new RegExp('[^a-z0-9_]');
|
| -final _numRegex = new RegExp('[0-9]');
|
|
|