feat(i18n): update transformers to read a xmb file when provided and use I18nHtmlParser in this case

Closes #7790
This commit is contained in:
vsavkin 2016-03-27 18:32:26 -07:00 committed by Victor Savkin
parent d2ca7d81c8
commit 8430927e6b
6 changed files with 77 additions and 6 deletions

View File

@ -14,18 +14,20 @@ import 'package:angular2/src/core/change_detection/interfaces.dart';
import 'package:angular2/src/compiler/change_detector_compiler.dart'; import 'package:angular2/src/compiler/change_detector_compiler.dart';
import 'package:angular2/router/router_link_dsl.dart'; import 'package:angular2/router/router_link_dsl.dart';
import 'package:angular2/src/compiler/proto_view_compiler.dart'; import 'package:angular2/src/compiler/proto_view_compiler.dart';
import 'package:angular2/i18n.dart';
import 'xhr_impl.dart'; import 'xhr_impl.dart';
import 'url_resolver.dart'; import 'url_resolver.dart';
TemplateCompiler createTemplateCompiler(AssetReader reader, TemplateCompiler createTemplateCompiler(AssetReader reader,
{ChangeDetectorGenConfig changeDetectionConfig}) { {ChangeDetectorGenConfig changeDetectionConfig, XmbDeserializationResult translations}) {
var _xhr = new XhrImpl(reader); var _xhr = new XhrImpl(reader);
var _htmlParser = new HtmlParser();
var _urlResolver = const TransformerUrlResolver(); var _urlResolver = const TransformerUrlResolver();
// TODO(yjbanov): add router AST transformer when ready // TODO(yjbanov): add router AST transformer when ready
var parser = new ng.Parser(new ng.Lexer()); var parser = new ng.Parser(new ng.Lexer());
var _htmlParser = _createHtmlParser(translations, parser);
var templateParser = new TemplateParser( var templateParser = new TemplateParser(
parser, parser,
new DomElementSchemaRegistry(), new DomElementSchemaRegistry(),
@ -47,3 +49,11 @@ TemplateCompiler createTemplateCompiler(AssetReader reader,
null /* ResolvedMetadataCache */, null /* ResolvedMetadataCache */,
changeDetectionConfig); changeDetectionConfig);
} }
HtmlParser _createHtmlParser(XmbDeserializationResult translations, ng.Parser parser) {
if (translations != null) {
return new I18nHtmlParser(new HtmlParser(), parser, translations.content, translations.messages);
} else {
return new HtmlParser();
}
}

View File

@ -4,6 +4,7 @@ import 'package:glob/glob.dart';
import 'annotation_matcher.dart'; import 'annotation_matcher.dart';
import 'mirror_mode.dart'; import 'mirror_mode.dart';
import 'package:barback/src/asset/asset_id.dart';
const CUSTOM_ANNOTATIONS_PARAM = 'custom_annotations'; const CUSTOM_ANNOTATIONS_PARAM = 'custom_annotations';
const ENTRY_POINT_PARAM = 'entry_points'; const ENTRY_POINT_PARAM = 'entry_points';
@ -16,6 +17,7 @@ const INIT_REFLECTOR_PARAM = 'init_reflector';
const INLINE_VIEWS_PARAM = 'inline_views'; const INLINE_VIEWS_PARAM = 'inline_views';
const MIRROR_MODE_PARAM = 'mirror_mode'; const MIRROR_MODE_PARAM = 'mirror_mode';
const LAZY_TRANSFORMERS = 'lazy_transformers'; const LAZY_TRANSFORMERS = 'lazy_transformers';
const TRANSLATIONS = 'translations';
/// Provides information necessary to transform an Angular2 app. /// Provides information necessary to transform an Angular2 app.
class TransformerOptions { class TransformerOptions {
@ -88,6 +90,9 @@ class TransformerOptions {
/// change. /// change.
final bool genCompiledTemplates; final bool genCompiledTemplates;
/// The path to the file with translations.
final AssetId translations;
TransformerOptions._internal( TransformerOptions._internal(
this.entryPoints, this.entryPoints,
this.entryPointGlobs, this.entryPointGlobs,
@ -103,6 +108,7 @@ class TransformerOptions {
this.platformDirectives, this.platformDirectives,
this.platformPipes, this.platformPipes,
this.resolvedIdentifiers, this.resolvedIdentifiers,
this.translations,
this.reflectPropertiesAsAttributes}); this.reflectPropertiesAsAttributes});
factory TransformerOptions(List<String> entryPoints, factory TransformerOptions(List<String> entryPoints,
@ -118,6 +124,7 @@ class TransformerOptions {
List<String> platformPipes, List<String> platformPipes,
Map<String, String> resolvedIdentifiers, Map<String, String> resolvedIdentifiers,
bool lazyTransformers: false, bool lazyTransformers: false,
AssetId translations: null,
bool formatCode: false}) { bool formatCode: false}) {
var annotationMatcher = new AnnotationMatcher() var annotationMatcher = new AnnotationMatcher()
..addAll(customAnnotationDescriptors); ..addAll(customAnnotationDescriptors);
@ -134,6 +141,7 @@ class TransformerOptions {
resolvedIdentifiers: resolvedIdentifiers, resolvedIdentifiers: resolvedIdentifiers,
inlineViews: inlineViews, inlineViews: inlineViews,
lazyTransformers: lazyTransformers, lazyTransformers: lazyTransformers,
translations: translations,
formatCode: formatCode); formatCode: formatCode);
} }
} }

View File

@ -4,6 +4,7 @@ import 'package:barback/barback.dart';
import 'annotation_matcher.dart'; import 'annotation_matcher.dart';
import 'mirror_mode.dart'; import 'mirror_mode.dart';
import 'options.dart'; import 'options.dart';
import './url_resolver.dart';
TransformerOptions parseBarbackSettings(BarbackSettings settings) { TransformerOptions parseBarbackSettings(BarbackSettings settings) {
var config = settings.configuration; var config = settings.configuration;
@ -43,6 +44,7 @@ import 'options.dart';
inlineViews: _readBool(config, INLINE_VIEWS_PARAM, defaultValue: false), inlineViews: _readBool(config, INLINE_VIEWS_PARAM, defaultValue: false),
lazyTransformers: lazyTransformers:
_readBool(config, LAZY_TRANSFORMERS, defaultValue: false), _readBool(config, LAZY_TRANSFORMERS, defaultValue: false),
translations: _readAssetId(config, TRANSLATIONS),
formatCode: formatCode); formatCode: formatCode);
} }
@ -52,6 +54,14 @@ bool _readBool(Map config, String paramName, {bool defaultValue}) {
: defaultValue; : defaultValue;
} }
AssetId _readAssetId(Map config, String paramName) {
if (config.containsKey(paramName)) {
return fromUri(config[paramName]);
} else {
return null;
}
}
/// Cribbed from the polymer project. /// Cribbed from the polymer project.
/// {@link https://github.com/dart-lang/polymer-dart} /// {@link https://github.com/dart-lang/polymer-dart}
List<String> _readStringList(Map config, String paramName) { List<String> _readStringList(Map config, String paramName) {

View File

@ -15,6 +15,7 @@ import 'package:angular2/src/transform/common/model/ng_deps_model.pb.dart';
import 'package:angular2/src/transform/common/names.dart'; import 'package:angular2/src/transform/common/names.dart';
import 'package:angular2/src/transform/common/ng_compiler.dart'; import 'package:angular2/src/transform/common/ng_compiler.dart';
import 'package:angular2/src/transform/common/zone.dart' as zone; import 'package:angular2/src/transform/common/zone.dart' as zone;
import 'package:angular2/i18n.dart';
import 'reflection/processor.dart' as reg; import 'reflection/processor.dart' as reg;
import 'reflection/reflection_capabilities.dart'; import 'reflection/reflection_capabilities.dart';
@ -39,6 +40,7 @@ Future<Outputs> processTemplates(AssetReader reader, AssetId assetId,
bool reflectPropertiesAsAttributes: false, bool reflectPropertiesAsAttributes: false,
List<String> platformDirectives, List<String> platformDirectives,
List<String> platformPipes, List<String> platformPipes,
XmbDeserializationResult translations,
Map<String, String> resolvedIdentifiers Map<String, String> resolvedIdentifiers
}) async { }) async {
var viewDefResults = await createCompileData( var viewDefResults = await createCompileData(
@ -61,7 +63,9 @@ Future<Outputs> processTemplates(AssetReader reader, AssetId assetId,
if (templateCompiler == null) { if (templateCompiler == null) {
templateCompiler = createTemplateCompiler(reader, templateCompiler = createTemplateCompiler(reader,
changeDetectionConfig: new ChangeDetectorGenConfig( changeDetectionConfig: new ChangeDetectorGenConfig(
genChangeDetectionDebugInfo, reflectPropertiesAsAttributes, false)); genChangeDetectionDebugInfo, reflectPropertiesAsAttributes, false),
translations: translations
);
} }
final compileData = final compileData =

View File

@ -11,7 +11,9 @@ import 'package:angular2/src/transform/common/code/source_module.dart';
import 'package:angular2/src/transform/common/formatter.dart'; import 'package:angular2/src/transform/common/formatter.dart';
import 'package:angular2/src/transform/common/names.dart'; import 'package:angular2/src/transform/common/names.dart';
import 'package:angular2/src/transform/common/options.dart'; import 'package:angular2/src/transform/common/options.dart';
import 'package:angular2/src/transform/common/logging.dart';
import 'package:angular2/src/transform/common/zone.dart' as zone; import 'package:angular2/src/transform/common/zone.dart' as zone;
import 'package:angular2/i18n.dart';
import 'generator.dart'; import 'generator.dart';
@ -26,6 +28,7 @@ import 'generator.dart';
/// See `angular2/src/transform/transformer.dart` for transformer ordering. /// See `angular2/src/transform/transformer.dart` for transformer ordering.
class TemplateCompiler extends Transformer implements LazyTransformer { class TemplateCompiler extends Transformer implements LazyTransformer {
final TransformerOptions options; final TransformerOptions options;
XmbDeserializationResult translations;
TemplateCompiler(this.options); TemplateCompiler(this.options);
@ -43,12 +46,17 @@ class TemplateCompiler extends Transformer implements LazyTransformer {
Html5LibDomAdapter.makeCurrent(); Html5LibDomAdapter.makeCurrent();
var primaryId = transform.primaryInput.id; var primaryId = transform.primaryInput.id;
var reader = new AssetReader.fromTransform(transform); var reader = new AssetReader.fromTransform(transform);
if (translations == null && options.translations != null) {
translations = await _deserializeXmb(reader, options.translations);
}
var outputs = await processTemplates(reader, primaryId, var outputs = await processTemplates(reader, primaryId,
genChangeDetectionDebugInfo: options.genChangeDetectionDebugInfo, genChangeDetectionDebugInfo: options.genChangeDetectionDebugInfo,
reflectPropertiesAsAttributes: options.reflectPropertiesAsAttributes, reflectPropertiesAsAttributes: options.reflectPropertiesAsAttributes,
platformDirectives: options.platformDirectives, platformDirectives: options.platformDirectives,
platformPipes: options.platformPipes, platformPipes: options.platformPipes,
resolvedIdentifiers: options.resolvedIdentifiers resolvedIdentifiers: options.resolvedIdentifiers,
translations: translations
); );
var ngDepsCode = _emptyNgDepsContents; var ngDepsCode = _emptyNgDepsContents;
if (outputs != null) { if (outputs != null) {
@ -65,6 +73,17 @@ class TemplateCompiler extends Transformer implements LazyTransformer {
new Asset.fromString(templatesAssetId(primaryId), ngDepsCode)); new Asset.fromString(templatesAssetId(primaryId), ngDepsCode));
}, log: transform.logger); }, log: transform.logger);
} }
Future _deserializeXmb(AssetReader reader, AssetId translations) async {
final content = await reader.readAsString(translations);
final res = deserializeXmb(content, translations.toString());
if (res.errors.length > 0) {
res.errors.forEach((e) => log.error(e.msg));
throw "Cannot parse xmb file";
} else {
return res;
}
}
} }
const _emptyNgDepsContents = 'initReflector() {}\n'; const _emptyNgDepsContents = 'initReflector() {}\n';

View File

@ -16,6 +16,7 @@ import 'package:angular2/src/transform/common/code/source_module.dart';
import 'package:angular2/src/transform/common/zone.dart' as zone; import 'package:angular2/src/transform/common/zone.dart' as zone;
import 'package:angular2/src/transform/template_compiler/generator.dart'; import 'package:angular2/src/transform/template_compiler/generator.dart';
import 'package:angular2/src/transform/template_compiler/compile_data_creator.dart'; import 'package:angular2/src/transform/template_compiler/compile_data_creator.dart';
import 'package:angular2/i18n.dart';
import 'package:angular2/src/transform/common/model/parameter_model.pb.dart'; import 'package:angular2/src/transform/common/model/parameter_model.pb.dart';
import '../common/compile_directive_metadata/ng_for.ng_meta.dart' as ngMeta; import '../common/compile_directive_metadata/ng_for.ng_meta.dart' as ngMeta;
@ -83,13 +84,15 @@ void allTests() {
}); });
Future<String> process(AssetId assetId, Future<String> process(AssetId assetId,
{List<String> platformDirectives, List<String> platformPipes, Map<String,String> resolvedIdentifiers}) { {List<String> platformDirectives, List<String> platformPipes, Map<String,String> resolvedIdentifiers,
XmbDeserializationResult translations}) {
logger = new RecordingLogger(); logger = new RecordingLogger();
return zone.exec( return zone.exec(
() => processTemplates(reader, assetId, () => processTemplates(reader, assetId,
platformDirectives: platformDirectives, platformDirectives: platformDirectives,
platformPipes: platformPipes, platformPipes: platformPipes,
resolvedIdentifiers: resolvedIdentifiers), resolvedIdentifiers: resolvedIdentifiers,
translations: translations),
log: logger); log: logger);
} }
@ -646,6 +649,23 @@ void allTests() {
expect(cmp.providers[0].useClass.name).toEqual("Service2"); expect(cmp.providers[0].useClass.name).toEqual("Service2");
expect(cmp.providers[0].useClass.moduleUrl).toEqual("moduleUrl"); expect(cmp.providers[0].useClass.moduleUrl).toEqual("moduleUrl");
}); });
it('should use i18n parser when translations are provided.', () async {
fooComponentMeta.template = new CompileTemplateMetadata(
template: '<div i18n>content</div>',
templateUrl: 'template.html');
updateReader();
final translations = deserializeXmb("""
<message-bundle>
<msg id="${id(new Message("content", null))}">another</msg>
</message-bundle>
""", "someUrl");
final outputs = await process(fooAssetId, translations: translations);
expect(_generatedCode(outputs)).toContain('another');
expect(_generatedCode(outputs)).not.toContain('content');
});
} }
String _generatedCode(Outputs outputs) { String _generatedCode(Outputs outputs) {