| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /// Transfomer used for pub-serve and pub-deploy. | |
| 6 library polymer.transformer; | |
| 7 | |
| 8 import 'package:barback/barback.dart'; | |
| 9 import 'package:web_components/transformer.dart' as web_components; | |
| 10 import 'package:observe/transformer.dart'; | |
| 11 | |
| 12 import 'src/build/build_filter.dart'; | |
| 13 import 'src/build/common.dart'; | |
| 14 import 'src/build/index_page_builder.dart'; | |
| 15 import 'src/build/html_finalizer.dart'; | |
| 16 import 'src/build/linter.dart'; | |
| 17 import 'src/build/build_log_combiner.dart'; | |
| 18 import 'src/build/polyfill_injector.dart'; | |
| 19 import 'src/build/polymer_bootstrap.dart'; | |
| 20 | |
| 21 /// The Polymer transformer, which internally runs several phases that will: | |
| 22 /// * Extract inlined script tags into their separate files | |
| 23 /// * Apply the observable transformer on every Dart script. | |
| 24 /// * Inline imported html files | |
| 25 /// * Combine scripts from multiple files into a single script tag | |
| 26 /// * Inject extra polyfills needed to run on all browsers. | |
| 27 /// | |
| 28 /// At the end of these phases, this tranformer produces a single entrypoint | |
| 29 /// HTML file with a single Dart script that can later be compiled with dart2js. | |
| 30 class PolymerTransformerGroup implements TransformerGroup { | |
| 31 final Iterable<Iterable> phases; | |
| 32 | |
| 33 PolymerTransformerGroup(TransformOptions options) | |
| 34 : phases = createDeployPhases(options); | |
| 35 | |
| 36 PolymerTransformerGroup.asPlugin(BarbackSettings settings) | |
| 37 : this(_parseSettings(settings)); | |
| 38 } | |
| 39 | |
| 40 TransformOptions _parseSettings(BarbackSettings settings) { | |
| 41 var args = settings.configuration; | |
| 42 bool releaseMode = settings.mode == BarbackMode.RELEASE; | |
| 43 bool jsOption = args['js']; | |
| 44 bool csp = args['csp'] == true; // defaults to false | |
| 45 bool injectBuildLogs = | |
| 46 !releaseMode && args['inject_build_logs_in_output'] != false; | |
| 47 bool injectWebComponentsJs = true; | |
| 48 if (args['inject_platform_js'] != null) { | |
| 49 print( | |
| 50 'Deprecated polymer transformer option `inject_platform_js`. This has ' | |
| 51 'been renamed `inject_web_components_js` to match the new file name.'); | |
| 52 injectWebComponentsJs = args['inject_platform_js'] != false; | |
| 53 } | |
| 54 if (args['inject_webcomponents_js'] != null) { | |
| 55 injectWebComponentsJs = args['inject_webcomponents_js'] != false; | |
| 56 } | |
| 57 return new TransformOptions( | |
| 58 entryPoints: readFileList(args['entry_points']), | |
| 59 inlineStylesheets: _readInlineStylesheets(args['inline_stylesheets']), | |
| 60 directlyIncludeJS: jsOption == null ? releaseMode : jsOption, | |
| 61 contentSecurityPolicy: csp, | |
| 62 releaseMode: releaseMode, | |
| 63 lint: _parseLintOption(args['lint']), | |
| 64 injectBuildLogsInOutput: injectBuildLogs, | |
| 65 injectWebComponentsJs: injectWebComponentsJs); | |
| 66 } | |
| 67 | |
| 68 // Lint option can be empty (all files), false, true, or a map indicating | |
| 69 // include/exclude files. | |
| 70 _parseLintOption(value) { | |
| 71 var lint = null; | |
| 72 if (value == null || value == true) return new LintOptions(); | |
| 73 if (value == false) return new LintOptions.disabled(); | |
| 74 if (value is Map && value.length == 1) { | |
| 75 var key = value.keys.single; | |
| 76 var files = readFileList(value[key]); | |
| 77 if (key == 'include') { | |
| 78 return new LintOptions.include(files); | |
| 79 } else if (key == 'exclude') { | |
| 80 return new LintOptions.exclude(files); | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 // Any other case it is an error: | |
| 85 print('Invalid value for "lint" in the polymer transformer. ' | |
| 86 'Expected one of the following: \n' | |
| 87 ' lint: true # or\n' | |
| 88 ' lint: false # or\n' | |
| 89 ' lint: \n' | |
| 90 ' include: \n' | |
| 91 ' - file1 \n' | |
| 92 ' - file2 # or \n' | |
| 93 ' lint: \n' | |
| 94 ' exclude: \n' | |
| 95 ' - file1 \n' | |
| 96 ' - file2 \n'); | |
| 97 return new LintOptions(); | |
| 98 } | |
| 99 | |
| 100 readFileList(value) { | |
| 101 if (value == null) return null; | |
| 102 var files = []; | |
| 103 bool error; | |
| 104 if (value is List) { | |
| 105 files = value; | |
| 106 error = value.any((e) => e is! String); | |
| 107 } else if (value is String) { | |
| 108 files = [value]; | |
| 109 error = false; | |
| 110 } else { | |
| 111 error = true; | |
| 112 } | |
| 113 if (error) { | |
| 114 print('Invalid value for "entry_points" in the polymer transformer.'); | |
| 115 } | |
| 116 return files; | |
| 117 } | |
| 118 | |
| 119 Map<String, bool> _readInlineStylesheets(settingValue) { | |
| 120 if (settingValue == null) return null; | |
| 121 var inlineStylesheets = {}; | |
| 122 bool error = false; | |
| 123 if (settingValue is Map) { | |
| 124 settingValue.forEach((key, value) { | |
| 125 if (value is! bool || key is! String) { | |
| 126 error = true; | |
| 127 return; | |
| 128 } | |
| 129 if (key == 'default') { | |
| 130 inlineStylesheets[key] = value; | |
| 131 return; | |
| 132 } | |
| 133 | |
| 134 key = systemToAssetPath(key); | |
| 135 // Special case package urls, convert to AssetId and use serialized form. | |
| 136 var packageMatch = _PACKAGE_PATH_REGEX.matchAsPrefix(key); | |
| 137 if (packageMatch != null) { | |
| 138 var package = packageMatch[1]; | |
| 139 var path = 'lib/${packageMatch[2]}'; | |
| 140 key = new AssetId(package, path).toString(); | |
| 141 } | |
| 142 inlineStylesheets[key] = value; | |
| 143 }); | |
| 144 } else if (settingValue is bool) { | |
| 145 inlineStylesheets['default'] = settingValue; | |
| 146 } else { | |
| 147 error = true; | |
| 148 } | |
| 149 if (error) { | |
| 150 print('Invalid value for "inline_stylesheets" in the polymer transformer.'); | |
| 151 } | |
| 152 return inlineStylesheets; | |
| 153 } | |
| 154 | |
| 155 /// Create deploy phases for Polymer. Note that inlining HTML Imports | |
| 156 /// comes first (other than linter, if [options.linter] is enabled), which | |
| 157 /// allows the rest of the HTML-processing phases to operate only on HTML that | |
| 158 /// is actually imported. | |
| 159 List<List<Transformer>> createDeployPhases(TransformOptions options, | |
| 160 {String sdkDir}) { | |
| 161 // TODO(sigmund): this should be done differently. We should lint everything | |
| 162 // that is reachable and have the option to lint the rest (similar to how | |
| 163 // dart2js can analyze reachable code or entire libraries). | |
| 164 var phases = []; | |
| 165 | |
| 166 phases.addAll([ | |
| 167 /// Must happen first, temporarily rewrites <link rel="x-dart-test"> tags to | |
| 168 /// <script type="application/dart" _was_test></script> tags. | |
| 169 [new web_components.RewriteXDartTestToScript(options.entryPoints)], | |
| 170 [new web_components.ScriptCompactorTransformer(options.entryPoints)], | |
| 171 [new PolymerBootstrapTransformer(options)], | |
| 172 ]); | |
| 173 | |
| 174 // Lint after injecting @HtmlImport imports otherwise we will likely have | |
| 175 // incorrect warnings about missing elements. | |
| 176 if (options.lint.enabled) phases.add([new Linter(options)]); | |
| 177 | |
| 178 phases.addAll([ | |
| 179 [ | |
| 180 new web_components.ImportInlinerTransformer( | |
| 181 options.entryPoints, ['[[', '{{']) | |
| 182 ], | |
| 183 [new HtmlFinalizer(options)], | |
| 184 [ | |
| 185 new ObservableTransformer( | |
| 186 releaseMode: options.releaseMode, | |
| 187 injectBuildLogsInOutput: options.injectBuildLogsInOutput) | |
| 188 ], | |
| 189 // TODO(jakemac): Move to web_components. | |
| 190 [new PolyfillInjector(options)], | |
| 191 [new BuildFilter(options)], | |
| 192 [new BuildLogCombiner(options)], | |
| 193 ]); | |
| 194 if (!options.releaseMode) { | |
| 195 phases.add([new IndexPageBuilder(options)]); | |
| 196 } | |
| 197 /// Must happen last, rewrites | |
| 198 /// <script type="application/dart" _was_test></script> tags back to | |
| 199 /// <link rel="x-dart-test"> tags. | |
| 200 phases.add( | |
| 201 [new web_components.RewriteScriptToXDartTest(options.entryPoints)]); | |
| 202 return phases; | |
| 203 } | |
| 204 | |
| 205 final RegExp _PACKAGE_PATH_REGEX = new RegExp(r'packages\/([^\/]+)\/(.*)'); | |
| OLD | NEW |