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

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

Issue 27903006: Improves how to initialize polymer apps and fixes polymer build and linter to (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 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 combines multiple dart script tags into a single one. */ 5 /** Transfomer that combines multiple dart script tags into a single one. */
6 library polymer.src.build.script_compactor; 6 library polymer.src.build.script_compactor;
7 7
8 import 'dart:async'; 8 import 'dart:async';
9 import 'dart:convert';
9 10
10 import 'package:barback/barback.dart'; 11 import 'package:barback/barback.dart';
11 import 'package:html5lib/parser.dart' show parseFragment; 12 import 'package:html5lib/parser.dart' show parseFragment;
12 import 'package:path/path.dart' as path; 13 import 'package:path/path.dart' as path;
13 14
14 import 'code_extractor.dart'; // import just for documentation. 15 import 'code_extractor.dart'; // import just for documentation.
15 import 'common.dart'; 16 import 'common.dart';
16 17
17 /** 18 /**
18 * Combines Dart script tags into a single script tag, and creates a new Dart 19 * Combines Dart script tags into a single script tag, and creates a new Dart
19 * file that calls the main function of each of the original script tags. 20 * file that calls the main function of each of the original script tags.
20 * 21 *
21 * This transformer assumes that all script tags point to external files. To 22 * This transformer assumes that all script tags point to external files. To
22 * support script tags with inlined code, use this transformer after running 23 * support script tags with inlined code, use this transformer after running
23 * [InlineCodeExtractor] on an earlier phase. 24 * [InlineCodeExtractor] on an earlier phase.
24 * 25 *
25 * Internally, this transformer will convert each script tag into an import 26 * Internally, this transformer will convert each script tag into an import
26 * statement to a library, and then uses `initPolymer` (see polymer.dart) to 27 * statement to a library, and then uses `initPolymer` (see polymer.dart) to
27 * invoke the main method on each of these libraries and register any polymer 28 * process `@initMethod` and `@CustomTag` annotations in those libraries.
28 * elements annotated with `@CustomTag`.
29 */ 29 */
30 class ScriptCompactor extends Transformer with PolymerTransformer { 30 class ScriptCompactor extends Transformer with PolymerTransformer {
31 final TransformOptions options; 31 final TransformOptions options;
32 32
33 ScriptCompactor(this.options); 33 ScriptCompactor(this.options);
34 34
35 /** Only run on entry point .html files. */ 35 /** Only run on entry point .html files. */
36 Future<bool> isPrimary(Asset input) => 36 Future<bool> isPrimary(Asset input) =>
37 new Future.value(options.isHtmlEntryPoint(input.id)); 37 new Future.value(options.isHtmlEntryPoint(input.id));
38 38
39 Future apply(Transform transform) { 39 Future apply(Transform transform) {
40 var id = transform.primaryInput.id; 40 var id = transform.primaryInput.id;
41 var secondaryId = id.addExtension('.scriptUrls');
41 var logger = transform.logger; 42 var logger = transform.logger;
42 return readPrimaryAsHtml(transform).then((document) { 43 return readPrimaryAsHtml(transform).then((document) {
43 var libraries = []; 44 return transform.readInputAsString(secondaryId).then((libraryIds) {
44 bool changed = false; 45 var libraries = JSON.decode(libraryIds).map(
45 var dartLoaderTag = null; 46 (data) => new AssetId.deserialize(data)).toList();
46 for (var tag in document.queryAll('script')) { 47 var mainLibraryId;
47 var src = tag.attributes['src']; 48 var mainScriptTag;
48 if (src != null) { 49 bool changed = false;
49 if (src == 'packages/polymer/boot.js' || 50
50 src == 'packages/polymer/init.dart') { 51 for (var tag in document.queryAll('script')) {
52 var src = tag.attributes['src'];
53 if (src == 'packages/polymer/boot.js') {
51 tag.remove(); 54 tag.remove();
52 continue; 55 continue;
53 } 56 }
54 var last = src.split('/').last; 57 if (tag.attributes['type'] != 'application/dart') continue;
55 if (last == 'dart.js') { 58 if (src == null) {
56 dartLoaderTag = tag; 59 logger.warning('unexpected script without a src url. The '
60 'ScriptCompactor transformer should run after running the '
61 'InlineCodeExtractor', span: tag.sourceSpan);
62 continue;
57 } 63 }
64 if (mainLibraryId != null) {
65 logger.warning('unexpected script. Only one Dart script tag '
66 'per document is allowed.', span: tag.sourceSpan);
67 tag.remove();
68 continue;
69 }
70 mainLibraryId = resolve(id, src, logger, tag.sourceSpan);
71 mainScriptTag = tag;
58 } 72 }
59 if (tag.attributes['type'] != 'application/dart') continue; 73
60 tag.remove(); 74 if (mainScriptTag == null) {
61 changed = true; 75 // We didn't find any main library, nothing to do.
62 if (src == null) { 76 transform.addOutput(transform.primaryInput);
63 logger.warning('unexpected script without a src url. The ' 77 return;
64 'ScriptCompactor transformer should run after running the '
65 'InlineCodeExtractor', tag.sourceSpan);
66 continue;
67 } 78 }
68 var libraryId = resolve(id, src, logger, tag.sourceSpan);
69 79
70 // TODO(sigmund): should we detect/remove duplicates? 80 var bootstrapId = id.addExtension('_bootstrap.dart');
71 if (libraryId == null) continue; 81 mainScriptTag.attributes['src'] =
72 libraries.add(libraryId); 82 path.url.basename(bootstrapId.path);
73 }
74 83
75 if (!changed) { 84 libraries.add(mainLibraryId);
76 transform.addOutput(transform.primaryInput); 85 var urls = libraries.map((id) => assetUrlFor(id, bootstrapId, logger))
77 return; 86 .where((url) => url != null).toList();
78 } 87 var buffer = new StringBuffer()..writeln(MAIN_HEADER);
88 int i = 0;
89 for (; i < urls.length; i++) {
90 buffer.writeln("import '${urls[i]}' as i$i;");
91 }
79 92
80 var bootstrapId = id.addExtension('_bootstrap.dart'); 93 buffer..write('\n')
81 var filename = path.url.basename(bootstrapId.path); 94 ..writeln('void main() {')
95 ..writeln(' librariesToLoad = [')
96 ..writeAll(urls.map((url) => " '$url',\n"))
97 ..writeln(' ];')
98 ..writeln(' i${i - 1}.main();')
99 ..writeln('}');
82 100
83 var bootstrapScript = parseFragment( 101 transform.addOutput(new Asset.fromString(
84 '<script type="application/dart" src="$filename"></script>'); 102 bootstrapId, buffer.toString()));
85 if (dartLoaderTag == null) { 103 transform.addOutput(new Asset.fromString(id, document.outerHtml));
86 document.body.nodes.add(bootstrapScript); 104 });
87 document.body.nodes.add(parseFragment(
88 '<script src="packages/browser/dart.js"></script>'));
89 } else {
90 dartLoaderTag.parent.insertBefore(bootstrapScript, dartLoaderTag);
91 }
92
93 var urls = libraries.map((id) => assetUrlFor(id, bootstrapId, logger))
94 .where((url) => url != null).toList();
95 var buffer = new StringBuffer()..writeln(MAIN_HEADER);
96 for (int i = 0; i < urls.length; i++) {
97 buffer.writeln("import '${urls[i]}' as i$i;");
98 }
99 buffer..write(_mainPrefix)
100 ..writeAll(urls.map((url) => " '$url',\n"))
101 ..write(_mainSuffix);
102
103 transform.addOutput(new Asset.fromString(bootstrapId, buffer.toString()));
104 transform.addOutput(new Asset.fromString(id, document.outerHtml));
105 }); 105 });
106 } 106 }
107 } 107 }
108 108
109 const MAIN_HEADER = """ 109 const MAIN_HEADER = """
110 library app_bootstrap; 110 library app_bootstrap;
111 111
112 import 'package:polymer/polymer.dart'; 112 import 'package:polymer/polymer.dart';
113 """; 113 """;
114
115 const _mainPrefix = """
116
117 void main() {
118 initPolymer([
119 """;
120
121 const _mainSuffix = """
122 ]);
123 }
124 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698