Chromium Code Reviews| Index: lib/src/compiler.dart |
| diff --git a/lib/src/compiler.dart b/lib/src/compiler.dart |
| index 8ebeb6ec68f1ef490cddd63a7fb921d2180860b9..43eebc0fffd22b79a019037c145f52cc75599c61 100644 |
| --- a/lib/src/compiler.dart |
| +++ b/lib/src/compiler.dart |
| @@ -163,6 +163,14 @@ class Compiler { |
| } |
| } |
| + // Load stylesheet files referenced by [file]. |
| + for (var href in fileInfo.styleSheetHref) { |
| + if (!_processed.contains(href)) { |
| + _processed.add(href); |
| + _tasks.add(_parseStyleSheetFile(href).then(_processStyleSheetFile)); |
| + } |
| + } |
| + |
| // Load .dart files being referenced in the page. |
| var src = fileInfo.externalFile; |
| if (src != null && !_processed.contains(src)) { |
| @@ -196,7 +204,8 @@ class Compiler { |
| /** Parse [filename] and treat it as a .dart file. */ |
| Future<SourceFile> _parseDartFile(Path path) { |
| return fileSystem.readText(path) |
| - .then((code) => new SourceFile(path, isDart: true)..code = code) |
| + .then((code) => new SourceFile(path, type: SourceFile.DART) |
| + ..code = code) |
| .catchError((e) => _readError(e, path)); |
| } |
| @@ -237,6 +246,31 @@ class Compiler { |
| } |
| } |
| + /** Parse [filename] and treat it as a .dart file. */ |
| + Future<SourceFile> _parseStyleSheetFile(Path path) { |
| + return fileSystem.readText(path) |
| + .then((code) => |
| + new SourceFile(path, type: SourceFile.STYLESHEET) |
| + ..code = code.trim()) |
|
Siggi Cherem (dart-lang)
2013/03/08 21:57:52
Maybe remove 'trim' here?
You are also trimming t
terry
2013/03/08 22:42:23
I like it _parseCss only.
On 2013/03/08 21:57:52,
|
| + .catchError((e) => _readError(e, path)); |
| + } |
| + |
| + void _processStyleSheetFile(SourceFile cssFile) { |
| + if (!_shouldProcessFile(cssFile)) return; |
| + |
| + files.add(cssFile); |
| + |
| + var fileInfo = new FileInfo(cssFile.path); |
| + info[cssFile.path] = fileInfo; |
| + |
| + var uriVisitor = new UriVisitor(_pathInfo, _mainPath, fileInfo.path); |
| + var styleSheet = _parseCss(cssFile.path.toString(), |
| + cssFile.code, uriVisitor, options); |
| + if (styleSheet != null) { |
| + fileInfo.styleSheets.add(styleSheet); |
| + } |
| + } |
| + |
| Path _getDirectivePath(LibraryInfo libInfo, Directive directive) { |
| var uriDirective = (directive as UriBasedDirective).uri; |
| var uri = uriDirective.value; |
| @@ -414,20 +448,26 @@ class Compiler { |
| void _analyze() { |
| var uniqueIds = new IntIterator(); |
| for (var file in files) { |
| - if (file.isDart) continue; |
| - _time('Analyzed contents', file.path, () => |
| - analyzeFile(file, info, uniqueIds, _messages)); |
| + var fileInfo = info[file.path]; |
|
Siggi Cherem (dart-lang)
2013/03/08 21:57:52
delete this unused variable
terry
2013/03/08 22:42:23
Done.
|
| + if (file.isHtml) { |
| + _time('Analyzed contents', file.path, () => |
| + analyzeFile(file, info, uniqueIds, _messages)); |
| + } |
| } |
| } |
| /** Emit the generated code corresponding to each input file. */ |
| void _emit() { |
| for (var file in files) { |
| - if (file.isDart) continue; |
| + if (file.isDart || file.isStyleSheet) continue; |
| _time('Codegen', file.path, () { |
| var fileInfo = info[file.path]; |
| cleanHtmlNodes(fileInfo); |
| - _processStylesheet(fileInfo, options: options); |
| + if (!fileInfo.isEntryPoint) { |
|
Siggi Cherem (dart-lang)
2013/03/08 21:57:52
&& options.processCss
terry
2013/03/08 22:42:23
I'm not sure this is right. Don't we want to supp
Siggi Cherem (dart-lang)
2013/03/09 01:32:10
my understanding was that 'processCss' is not just
|
| + // Check all components files for <style> tags and parse the CSS. |
| + var uriVisitor = new UriVisitor(_pathInfo, _mainPath, fileInfo.path); |
| + _processStylesheet(uriVisitor, fileInfo, options: options); |
| + } |
| fixupHtmlCss(fileInfo, options); |
| _emitComponents(fileInfo); |
| if (fileInfo.isEntryPoint) { |
| @@ -436,12 +476,16 @@ class Compiler { |
| } |
| }); |
| } |
| + |
| + if (options.processCss) { |
| + _emitAllCss(); |
| + } |
| } |
| /** Emit the main .dart file. */ |
| void _emitMainDart(SourceFile file) { |
| var fileInfo = info[file.path]; |
| - var printer = new MainPageEmitter(fileInfo) |
| + var printer = new MainPageEmitter(fileInfo, options.processCss) |
| .run(file.document, _pathInfo, _edits[fileInfo.userCode], |
| options.rewriteUrls); |
| _emitFileAndSourceMaps(fileInfo, printer, fileInfo.inputPath); |
| @@ -493,9 +537,65 @@ class Compiler { |
| document.outerHtml, source: file.path)); |
| } |
| + /** Generate an CSS file for all style sheets (main and components). */ |
| + void _emitAllCss() { |
| + StringBuffer allCssBuff = new StringBuffer(); |
|
Siggi Cherem (dart-lang)
2013/03/08 21:57:52
style nit: use var
terry
2013/03/08 22:42:23
Done.
|
| + |
|
Siggi Cherem (dart-lang)
2013/03/08 21:57:52
style nit, delete empty line
terry
2013/03/08 22:42:23
Done.
|
| + var mainFile; |
| + |
| + // Emit all linked style sheet files first. |
| + for (var file in files) { |
| + var fileInfo = info[file.path]; |
| + if (fileInfo.isEntryPoint) mainFile = file; |
| + if (file.isStyleSheet) { |
| + for (var styleSheet in fileInfo.styleSheets) { |
| + allCssBuff.write( |
| + '/* ==================================================== */\n' |
| + '/* Linked style sheet href = ${file.path.filename} */\n' |
| + '/* ==================================================== */\n'); |
| + allCssBuff.write(emitStyleSheet(styleSheet)); |
| + allCssBuff.write('\n\n'); |
| + } |
| + } |
| + } |
| + |
| + // Emit all CSS in each component (style scoped). |
| + for (var file in files) { |
| + var fileInfo = info[file.path]; |
|
Siggi Cherem (dart-lang)
2013/03/08 21:57:52
move this down inside the next if
terry
2013/03/08 22:42:23
Done.
|
| + if (!file.isStyleSheet) { |
|
Siggi Cherem (dart-lang)
2013/03/08 21:57:52
!file.isStylesheet => file.isHtml
(skip dart files
terry
2013/03/08 22:42:23
Right should only be isHtml (dart and stylesheets
|
| + for (var component in fileInfo.declaredComponents) { |
| + for (var styleSheet in component.styleSheets) { |
| + allCssBuff.write( |
| + '/* ==================================================== */\n' |
| + '/* Component ${component.tagName} stylesheet */\n' |
| + '/* ==================================================== */\n'); |
| + allCssBuff.write(emitStyleSheet(styleSheet, component.tagName)); |
| + allCssBuff.write('\n\n'); |
| + } |
| + } |
| + } |
| + } |
| + |
| + assert(mainFile != null); |
| + |
| + var allCss = allCssBuff.toString(); |
| + if (!allCss.isEmpty) { |
| + var allCssFile = '${mainFile.path.filename}.css'; |
| + var allCssPath = mainFile.path.directoryPath.append(allCssFile); |
| + var allCssOutPath = _pathInfo.outputPath(allCssPath, ''); |
| + output.add(new OutputFile(allCssOutPath, allCss)); |
| + } |
| + } |
| + |
| /** Emits the Dart code for all components in [fileInfo]. */ |
| void _emitComponents(FileInfo fileInfo) { |
| for (var component in fileInfo.declaredComponents) { |
| + // TODO(terry): Handle one stylesheet per component see fixupHtmlCss. |
| + if (component.styleSheets.length > 1) { |
|
Siggi Cherem (dart-lang)
2013/03/08 21:57:52
&& options.processCss
terry
2013/03/08 22:42:23
Done.
terry
2013/03/08 22:42:23
Done.
|
| + _messages.warning( |
| + 'Component has more than one stylesheet' |
| + ' - first stylesheet used.', null, file: component.externalFile); |
| + } |
| var printer = new WebComponentEmitter(fileInfo, _messages) |
| .run(component, _pathInfo, _edits[component.userCode]); |
| _emitFileAndSourceMaps(component, printer, component.externalFile); |
| @@ -565,33 +665,57 @@ class Compiler { |
| } |
| /** Parse all stylesheet for polyfilling assciated with [info]. */ |
| -void _processStylesheet(info, {CompilerOptions options : null}) { |
| - new _ProcessCss(options).visit(info); |
| +void _processStylesheet(uriVisitor, info, {CompilerOptions options : null}) { |
| + new _ProcessCss(uriVisitor, options).visit(info); |
| +} |
| + |
| +StyleSheet _parseCss(String src, String content, UriVisitor uriVisitor, |
| + CompilerOptions options) { |
| + if (!content.trim().isEmpty) { |
| + // TODO(terry): Add --checked when fully implemented and error handling. |
| + var styleSheet = css.parse(content, options: |
| + [options.warningsAsErrors ? '--warnings_as_errors' : '', 'memory']); |
| + uriVisitor.visitTree(styleSheet); |
| + if (options.debugCss) { |
| + print('\nCSS source: $src'); |
| + print('==========\n'); |
| + print(treeToDebugString(styleSheet)); |
| + } |
| + return styleSheet; |
| + } |
| } |
| /** Post-analysis of style sheet; parsed ready for emitting with polyfill. */ |
| class _ProcessCss extends InfoVisitor { |
| + final UriVisitor uriVisitor; |
| final CompilerOptions options; |
| + ComponentInfo component; |
| - _ProcessCss(this.options); |
| - |
| - // TODO(terry): Add --checked when fully implemented and error handling too. |
| - StyleSheet _parseCss(String cssInput, CompilerOptions option) => |
| - css.parse(cssInput, options: |
| - [option.warningsAsErrors ? '--warnings_as_errors' : '', 'memory']); |
| + _ProcessCss(this.uriVisitor, this.options); |
| void visitComponentInfo(ComponentInfo info) { |
| - if (!info.cssSource.isEmpty) { |
| - info.styleSheet = _parseCss(info.cssSource.toString(), options); |
| - info.cssSource = null; // Once CSS parsed original not needed. |
| - |
| - if (options.debugCss) { |
| - print('\nComponent: ${info.tagName}'); |
| - print('==========\n'); |
| - print(treeToDebugString(info.styleSheet)); |
| + var oldComponent = component; |
| + component = info; |
| + |
| + super.visitComponentInfo(info); |
| + |
| + component = oldComponent; |
| + } |
| + |
| + void visitElementInfo(ElementInfo info) { |
| + if (component != null) { |
| + var node = info.node; |
| + if (node.tagName == 'style' && node.attributes.containsKey("scoped")) { |
| + // Get contents of style tag. |
| + var content = node.nodes.single.value.toString(); |
|
Siggi Cherem (dart-lang)
2013/03/08 21:57:52
do we need a 'toString'? I'm not sure what's the t
terry
2013/03/08 22:42:23
Yep only need .value
On 2013/03/08 21:57:52, Sigg
|
| + var styleSheet = _parseCss(component.tagName, content, uriVisitor, |
| + options); |
| + if (styleSheet != null) { |
| + component.styleSheets.add(styleSheet); |
| + } |
| } |
| } |
| - super.visitComponentInfo(info); |
| + super.visitElementInfo(info); |
| } |
| } |