diff --git a/modules_dart/transform/lib/src/transform/common/ng_compiler.dart b/modules_dart/transform/lib/src/transform/common/ng_compiler.dart index 55c25126f3..006d861b27 100644 --- a/modules_dart/transform/lib/src/transform/common/ng_compiler.dart +++ b/modules_dart/transform/lib/src/transform/common/ng_compiler.dart @@ -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/router/router_link_dsl.dart'; import 'package:angular2/src/compiler/proto_view_compiler.dart'; +import 'package:angular2/i18n.dart'; import 'xhr_impl.dart'; import 'url_resolver.dart'; TemplateCompiler createTemplateCompiler(AssetReader reader, - {ChangeDetectorGenConfig changeDetectionConfig}) { + {ChangeDetectorGenConfig changeDetectionConfig, XmbDeserializationResult translations}) { var _xhr = new XhrImpl(reader); - var _htmlParser = new HtmlParser(); var _urlResolver = const TransformerUrlResolver(); // TODO(yjbanov): add router AST transformer when ready var parser = new ng.Parser(new ng.Lexer()); + var _htmlParser = _createHtmlParser(translations, parser); + var templateParser = new TemplateParser( parser, new DomElementSchemaRegistry(), @@ -47,3 +49,11 @@ TemplateCompiler createTemplateCompiler(AssetReader reader, null /* ResolvedMetadataCache */, 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(); + } +} \ No newline at end of file diff --git a/modules_dart/transform/lib/src/transform/common/options.dart b/modules_dart/transform/lib/src/transform/common/options.dart index 1b67fcf459..ec3017976b 100644 --- a/modules_dart/transform/lib/src/transform/common/options.dart +++ b/modules_dart/transform/lib/src/transform/common/options.dart @@ -4,6 +4,7 @@ import 'package:glob/glob.dart'; import 'annotation_matcher.dart'; import 'mirror_mode.dart'; +import 'package:barback/src/asset/asset_id.dart'; const CUSTOM_ANNOTATIONS_PARAM = 'custom_annotations'; const ENTRY_POINT_PARAM = 'entry_points'; @@ -16,6 +17,7 @@ const INIT_REFLECTOR_PARAM = 'init_reflector'; const INLINE_VIEWS_PARAM = 'inline_views'; const MIRROR_MODE_PARAM = 'mirror_mode'; const LAZY_TRANSFORMERS = 'lazy_transformers'; +const TRANSLATIONS = 'translations'; /// Provides information necessary to transform an Angular2 app. class TransformerOptions { @@ -88,6 +90,9 @@ class TransformerOptions { /// change. final bool genCompiledTemplates; + /// The path to the file with translations. + final AssetId translations; + TransformerOptions._internal( this.entryPoints, this.entryPointGlobs, @@ -103,6 +108,7 @@ class TransformerOptions { this.platformDirectives, this.platformPipes, this.resolvedIdentifiers, + this.translations, this.reflectPropertiesAsAttributes}); factory TransformerOptions(List entryPoints, @@ -118,6 +124,7 @@ class TransformerOptions { List platformPipes, Map resolvedIdentifiers, bool lazyTransformers: false, + AssetId translations: null, bool formatCode: false}) { var annotationMatcher = new AnnotationMatcher() ..addAll(customAnnotationDescriptors); @@ -134,6 +141,7 @@ class TransformerOptions { resolvedIdentifiers: resolvedIdentifiers, inlineViews: inlineViews, lazyTransformers: lazyTransformers, + translations: translations, formatCode: formatCode); } } diff --git a/modules_dart/transform/lib/src/transform/common/options_reader.dart b/modules_dart/transform/lib/src/transform/common/options_reader.dart index 36dab07bb1..a7c4d96caa 100644 --- a/modules_dart/transform/lib/src/transform/common/options_reader.dart +++ b/modules_dart/transform/lib/src/transform/common/options_reader.dart @@ -4,6 +4,7 @@ import 'package:barback/barback.dart'; import 'annotation_matcher.dart'; import 'mirror_mode.dart'; import 'options.dart'; +import './url_resolver.dart'; TransformerOptions parseBarbackSettings(BarbackSettings settings) { var config = settings.configuration; @@ -43,6 +44,7 @@ import 'options.dart'; inlineViews: _readBool(config, INLINE_VIEWS_PARAM, defaultValue: false), lazyTransformers: _readBool(config, LAZY_TRANSFORMERS, defaultValue: false), + translations: _readAssetId(config, TRANSLATIONS), formatCode: formatCode); } @@ -52,6 +54,14 @@ bool _readBool(Map config, String paramName, {bool defaultValue}) { : defaultValue; } +AssetId _readAssetId(Map config, String paramName) { + if (config.containsKey(paramName)) { + return fromUri(config[paramName]); + } else { + return null; + } +} + /// Cribbed from the polymer project. /// {@link https://github.com/dart-lang/polymer-dart} List _readStringList(Map config, String paramName) { diff --git a/modules_dart/transform/lib/src/transform/template_compiler/generator.dart b/modules_dart/transform/lib/src/transform/template_compiler/generator.dart index 460cf73d25..a373bf2686 100644 --- a/modules_dart/transform/lib/src/transform/template_compiler/generator.dart +++ b/modules_dart/transform/lib/src/transform/template_compiler/generator.dart @@ -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/ng_compiler.dart'; import 'package:angular2/src/transform/common/zone.dart' as zone; +import 'package:angular2/i18n.dart'; import 'reflection/processor.dart' as reg; import 'reflection/reflection_capabilities.dart'; @@ -39,6 +40,7 @@ Future processTemplates(AssetReader reader, AssetId assetId, bool reflectPropertiesAsAttributes: false, List platformDirectives, List platformPipes, + XmbDeserializationResult translations, Map resolvedIdentifiers }) async { var viewDefResults = await createCompileData( @@ -61,7 +63,9 @@ Future processTemplates(AssetReader reader, AssetId assetId, if (templateCompiler == null) { templateCompiler = createTemplateCompiler(reader, changeDetectionConfig: new ChangeDetectorGenConfig( - genChangeDetectionDebugInfo, reflectPropertiesAsAttributes, false)); + genChangeDetectionDebugInfo, reflectPropertiesAsAttributes, false), + translations: translations + ); } final compileData = diff --git a/modules_dart/transform/lib/src/transform/template_compiler/transformer.dart b/modules_dart/transform/lib/src/transform/template_compiler/transformer.dart index 298dc68c22..46e31a1c39 100644 --- a/modules_dart/transform/lib/src/transform/template_compiler/transformer.dart +++ b/modules_dart/transform/lib/src/transform/template_compiler/transformer.dart @@ -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/names.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/i18n.dart'; import 'generator.dart'; @@ -26,6 +28,7 @@ import 'generator.dart'; /// See `angular2/src/transform/transformer.dart` for transformer ordering. class TemplateCompiler extends Transformer implements LazyTransformer { final TransformerOptions options; + XmbDeserializationResult translations; TemplateCompiler(this.options); @@ -43,12 +46,17 @@ class TemplateCompiler extends Transformer implements LazyTransformer { Html5LibDomAdapter.makeCurrent(); var primaryId = transform.primaryInput.id; var reader = new AssetReader.fromTransform(transform); + if (translations == null && options.translations != null) { + translations = await _deserializeXmb(reader, options.translations); + } + var outputs = await processTemplates(reader, primaryId, genChangeDetectionDebugInfo: options.genChangeDetectionDebugInfo, reflectPropertiesAsAttributes: options.reflectPropertiesAsAttributes, platformDirectives: options.platformDirectives, platformPipes: options.platformPipes, - resolvedIdentifiers: options.resolvedIdentifiers + resolvedIdentifiers: options.resolvedIdentifiers, + translations: translations ); var ngDepsCode = _emptyNgDepsContents; if (outputs != null) { @@ -65,6 +73,17 @@ class TemplateCompiler extends Transformer implements LazyTransformer { new Asset.fromString(templatesAssetId(primaryId), ngDepsCode)); }, 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'; diff --git a/modules_dart/transform/test/transform/template_compiler/all_tests.dart b/modules_dart/transform/test/transform/template_compiler/all_tests.dart index bbd0fca8a8..ac47db14f7 100644 --- a/modules_dart/transform/test/transform/template_compiler/all_tests.dart +++ b/modules_dart/transform/test/transform/template_compiler/all_tests.dart @@ -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/template_compiler/generator.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 '../common/compile_directive_metadata/ng_for.ng_meta.dart' as ngMeta; @@ -83,13 +84,15 @@ void allTests() { }); Future process(AssetId assetId, - {List platformDirectives, List platformPipes, Map resolvedIdentifiers}) { + {List platformDirectives, List platformPipes, Map resolvedIdentifiers, + XmbDeserializationResult translations}) { logger = new RecordingLogger(); return zone.exec( () => processTemplates(reader, assetId, platformDirectives: platformDirectives, platformPipes: platformPipes, - resolvedIdentifiers: resolvedIdentifiers), + resolvedIdentifiers: resolvedIdentifiers, + translations: translations), log: logger); } @@ -646,6 +649,23 @@ void allTests() { expect(cmp.providers[0].useClass.name).toEqual("Service2"); expect(cmp.providers[0].useClass.moduleUrl).toEqual("moduleUrl"); }); + + it('should use i18n parser when translations are provided.', () async { + fooComponentMeta.template = new CompileTemplateMetadata( + template: '
content
', + templateUrl: 'template.html'); + updateReader(); + + final translations = deserializeXmb(""" + + another + + """, "someUrl"); + + final outputs = await process(fooAssetId, translations: translations); + expect(_generatedCode(outputs)).toContain('another'); + expect(_generatedCode(outputs)).not.toContain('content'); + }); } String _generatedCode(Outputs outputs) {