Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

Commit

Permalink
feat: add option to use external css rewriter in template_cache_gener…
Browse files Browse the repository at this point in the history
…ator.

The provided rewriter will be used to transform every css read by the
TemplateCache, the original css is provided on stdin, and result is read
from the stdout of provided binary.

TESTING:

The test uses a simple sed script to exercise the integration.

The test runs only if sed is present on the running system.  The test
uses CSS with simple rules that are being translated for RTL locales.

Closes #1052
  • Loading branch information
rkj authored and chirayuk committed Aug 7, 2014
1 parent 3de00bd commit 20defb2
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 12 deletions.
47 changes: 35 additions & 12 deletions lib/tools/template_cache_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:args/args.dart';
import 'package:di/generator.dart';
import 'dart:convert';

const String PACKAGE_PREFIX = 'package:';
const String DART_PACKAGE_PREFIX = 'dart:';
Expand Down Expand Up @@ -56,7 +57,8 @@ main(List arguments) {
sink = f.openWrite();
}
return printTemplateCache(
templates, options.urlRewrites, options.outputLibrary, sink)
templates, options.urlRewrites, options.outputLibrary, sink,
options.cssRewriter)
.then((_) => sink.flush());
}

Expand All @@ -70,6 +72,7 @@ class Options {
Map<RegExp, String> urlRewrites;
Set<String> skippedClasses;
bool verbose;
String cssRewriter;
}

Options parseArgs(List arguments) {
Expand All @@ -89,6 +92,9 @@ Options parseArgs(List arguments) {
'patternUrl,rewriteTo')
..addOption('skip-classes', abbr: 'b',
help: 'comma-separated list of classes to skip templating')
..addOption('css-rewriter', defaultsTo: null,
help: 'application used to rewrite css. Each css file will be passed '
'to stdin and rewriten one is expected on stdout.')
..addFlag('verbose', abbr: 'v', help: 'verbose output')
..addFlag('help', abbr: 'h', negatable: false, help: 'show this help');

Expand Down Expand Up @@ -142,31 +148,48 @@ Options parseArgs(List arguments) {
if (args.rest.length != 2) {
fail('unexpected arguments: ${args.rest.join(' ')}');
}
options.cssRewriter = args['css-rewriter'];
options.entryPoint = args.rest[0];
options.outputLibrary = args.rest[1];
return options;
}

printTemplateCache(Map<String, String> templateKeyMap,
Map<RegExp, String> urlRewriters,
String outputLibrary,
IOSink outSink) {
Map<RegExp, String> urlRewriters,
String outputLibrary,
IOSink outSink,
String cssRewriter) {

outSink.write(fileHeader(outputLibrary));

Future future = new Future.value(0);
List uris = templateKeyMap.keys.toList()..sort()..forEach((uri) {
var templateFile = templateKeyMap[uri];
String resultUri = uri;
urlRewriters.forEach((regexp, replacement) {
resultUri = resultUri.replaceFirst(regexp, replacement);
});
var putToCache = (String content) {
var out = content.replaceAll('"""', r'\"\"\"');
outSink.write(
'tc.put("$resultUri", new HttpResponse(200, r"""$out"""));\n');
};
future = future.then((_) {
return new File(templateFile).readAsString().then((fileStr) {
fileStr = fileStr.replaceAll('"""', r'\"\"\"');
String resultUri = uri;
urlRewriters.forEach((regexp, replacement) {
resultUri = resultUri.replaceFirst(regexp, replacement);
var fileContentFuture = new File(templateFile).readAsString();
if (templateFile.endsWith(".css") && cssRewriter != null) {
return fileContentFuture.then((fileStr) {
return Process.start(cssRewriter, []).then((process) {
process.stdin.write(fileStr);
process.stdin.close();
return process.stdout
.transform(UTF8.decoder)
.join("")
.then(putToCache);
});
});
outSink.write(
'tc.put("$resultUri", new HttpResponse(200, r"""$fileStr"""));\n');
});
} else {
return fileContentFuture.then(putToCache);
}
});
});

Expand Down
39 changes: 39 additions & 0 deletions test/io/template_cache_generator_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,45 @@ void main() {
});
});

if (new File("/bin/sed").existsSync()) {
it('should correctly use simple sed rewritter to fake css mirroring', () {
var tmpDir = Directory.systemTemp.createTempSync();
Future flush;
try {
flush = generator.main([
'--out=${tmpDir.path}/generated.dart',
'--url-rewrites=/test/io/test_files,rewritten',
'--css-rewriter=test/io/test_files/rewritter.sh',
'test/io/test_files/cssUrls/main.dart',
'generated']);
} catch(_) {
tmpDir.deleteSync(recursive: true);
rethrow;
}
return flush.then((_) {
expect(new File('${tmpDir.path}/generated.dart').readAsStringSync(),
'''// GENERATED, DO NOT EDIT!
library generated;
import 'package:angular/angular.dart';
primeTemplateCache(TemplateCache tc) {
tc.put("rewritten/cssUrls/four.css", new HttpResponse(200, r""".float-right {
float: right;
}
.right-margin {
margin-right: 20px;
}
"""));
tc.put("rewritten/cssUrls/one.css", new HttpResponse(200, r"""body {}"""));
tc.put("rewritten/cssUrls/three.css", new HttpResponse(200, r"""body {}"""));
tc.put("rewritten/cssUrls/two.css", new HttpResponse(200, r"""body {}"""));
}''');
}).whenComplete(() {
tmpDir.deleteSync(recursive: true);
});
});
}
});
}
7 changes: 7 additions & 0 deletions test/io/test_files/cssUrls/four.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.float-left {
float: left;
}
.left-margin {
margin-left: 20px;
}

3 changes: 3 additions & 0 deletions test/io/test_files/rewritter.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

/bin/sed 's/left/right/g'

0 comments on commit 20defb2

Please sign in to comment.