| 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:observe/transformer.dart'; | |
| 10 import 'package:path/path.dart' as path; | |
| 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/import_inliner.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/script_compactor.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 key = systemToAssetPath(key); | |
| 134 // Special case package urls, convert to AssetId and use serialized form. | |
| 135 var packageMatch = _PACKAGE_PATH_REGEX.matchAsPrefix(key); | |
| 136 if (packageMatch != null) { | |
| 137 var package = packageMatch[1]; | |
| 138 var path = 'lib/${packageMatch[2]}'; | |
| 139 key = new AssetId(package, path).toString(); | |
| 140 } | |
| 141 inlineStylesheets[key] = value; | |
| 142 }); | |
| 143 } else if (settingValue is bool) { | |
| 144 inlineStylesheets['default'] = settingValue; | |
| 145 } else { | |
| 146 error = true; | |
| 147 } | |
| 148 if (error) { | |
| 149 print('Invalid value for "inline_stylesheets" in the polymer transformer.'); | |
| 150 } | |
| 151 return inlineStylesheets; | |
| 152 } | |
| 153 | |
| 154 /// Create deploy phases for Polymer. Note that inlining HTML Imports | |
| 155 /// comes first (other than linter, if [options.linter] is enabled), which | |
| 156 /// allows the rest of the HTML-processing phases to operate only on HTML that | |
| 157 /// is actually imported. | |
| 158 List<List<Transformer>> createDeployPhases( | |
| 159 TransformOptions options, {String sdkDir}) { | |
| 160 // TODO(sigmund): this should be done differently. We should lint everything | |
| 161 // that is reachable and have the option to lint the rest (similar to how | |
| 162 // dart2js can analyze reachable code or entire libraries). | |
| 163 var phases = options.lint.enabled ? [[new Linter(options)]] : []; | |
| 164 phases.addAll([ | |
| 165 [new ImportInliner(options)], | |
| 166 [new ObservableTransformer()], | |
| 167 [new ScriptCompactor(options, sdkDir: sdkDir)], | |
| 168 [new PolyfillInjector(options)], | |
| 169 [new BuildFilter(options)], | |
| 170 [new BuildLogCombiner(options)], | |
| 171 ]); | |
| 172 if (!options.releaseMode) { | |
| 173 phases.add([new IndexPageBuilder(options)]); | |
| 174 } | |
| 175 return phases; | |
| 176 } | |
| 177 | |
| 178 final RegExp _PACKAGE_PATH_REGEX = new RegExp(r'packages\/([^\/]+)\/(.*)'); | |
| OLD | NEW |