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

Unified Diff: lib/src/compiler.dart

Issue 12474002: Support for parsing all CSS and producing one CSS file (Closed) Base URL: https://github.com/dart-lang/web-ui.git@master
Patch Set: merged Created 7 years, 9 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 side-by-side diff with in-line comments
Download patch
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);
}
}
« no previous file with comments | « lib/src/analyzer.dart ('k') | lib/src/emitters.dart » ('j') | lib/src/html_css_fixup.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698