diff --git a/modules/@angular/compiler-cli/integrationtest/src/messages.fi.xlf b/modules/@angular/compiler-cli/integrationtest/src/messages.fi.xlf
new file mode 100644
index 0000000000..8ed5cbf868
--- /dev/null
+++ b/modules/@angular/compiler-cli/integrationtest/src/messages.fi.xlf
@@ -0,0 +1,17 @@
+
+
+
+
+
+ translate me
+ käännä teksti
+ desc
+ meaning
+
+
+ Welcome
+ tervetuloa
+
+
+
+
\ No newline at end of file
diff --git a/modules/@angular/compiler-cli/integrationtest/src/messages.fi.xtb b/modules/@angular/compiler-cli/integrationtest/src/messages.fi.xtb
index 7b3b157e47..5c24884c84 100644
--- a/modules/@angular/compiler-cli/integrationtest/src/messages.fi.xtb
+++ b/modules/@angular/compiler-cli/integrationtest/src/messages.fi.xtb
@@ -1,3 +1,11 @@
+
+
+
+
+
+
+
+]>
käännä teksti
tervetuloa
diff --git a/modules/@angular/compiler-cli/integrationtest/test/basic_spec.ts b/modules/@angular/compiler-cli/integrationtest/test/basic_spec.ts
index c4b2dcf5b8..45a3952e28 100644
--- a/modules/@angular/compiler-cli/integrationtest/test/basic_spec.ts
+++ b/modules/@angular/compiler-cli/integrationtest/test/basic_spec.ts
@@ -73,7 +73,7 @@ describe('template codegen output', () => {
it('should inject the translations format into the component', () => {
const compFixture = createComponent(BasicComp);
- expect(compFixture.componentInstance.translationsFormat).toEqual('xtb');
+ expect(compFixture.componentInstance.translationsFormat).toEqual('xlf');
});
it('should support i18n for content tags', () => {
diff --git a/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts b/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts
index f382332f46..c4fdabd964 100644
--- a/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts
+++ b/modules/@angular/compiler-cli/integrationtest/test/i18n_spec.ts
@@ -11,11 +11,7 @@ import './init';
import * as fs from 'fs';
import * as path from 'path';
-describe('template i18n extraction output', () => {
- const outDir = '';
-
- it('should extract i18n messages', () => {
- const EXPECTED = `
+const EXPECTED_XMB = `
@@ -42,9 +38,39 @@ describe('template i18n extraction output', () => {
Welcome
`;
+const EXPECTED_XLIFF = `
+
+
+
+
+ translate me
+
+ desc
+ meaning
+
+
+ Welcome
+
+
+
+
+`;
+
+describe('template i18n extraction output', () => {
+ const outDir = '';
+
+ it('should extract i18n messages as xmb', () => {
const xmbOutput = path.join(outDir, 'messages.xmb');
expect(fs.existsSync(xmbOutput)).toBeTruthy();
const xmb = fs.readFileSync(xmbOutput, {encoding: 'utf-8'});
- expect(xmb).toEqual(EXPECTED);
+ expect(xmb).toEqual(EXPECTED_XMB);
});
+
+ it('should extract i18n messages as xliff', () => {
+ const xlfOutput = path.join(outDir, 'messages.xlf');
+ expect(fs.existsSync(xlfOutput)).toBeTruthy();
+ const xlf = fs.readFileSync(xlfOutput, {encoding: 'utf-8'});
+ expect(xlf).toEqual(EXPECTED_XLIFF);
+ });
+
});
diff --git a/modules/@angular/compiler-cli/src/codegen.ts b/modules/@angular/compiler-cli/src/codegen.ts
index 5f79f7ea1d..47667b0162 100644
--- a/modules/@angular/compiler-cli/src/codegen.ts
+++ b/modules/@angular/compiler-cli/src/codegen.ts
@@ -144,7 +144,8 @@ export class CodeGenerator {
const reflectorHost = new ReflectorHost(program, compilerHost, options, reflectorHostContext);
const staticReflector = new StaticReflector(reflectorHost);
StaticAndDynamicReflectionCapabilities.install(staticReflector);
- const htmlParser = new compiler.i18n.HtmlParser(new HtmlParser(), transContent);
+ const htmlParser =
+ new compiler.i18n.HtmlParser(new HtmlParser(), transContent, cliOptions.i18nFormat);
const config = new compiler.CompilerConfig({
genDebugInfo: options.debug === true,
defaultEncapsulation: ViewEncapsulation.Emulated,
@@ -161,6 +162,7 @@ export class CodeGenerator {
new compiler.NgModuleResolver(staticReflector),
new compiler.DirectiveResolver(staticReflector), new compiler.PipeResolver(staticReflector),
config, console, elementSchemaRegistry, staticReflector);
+ // TODO(vicb): do not pass cliOptions.i18nFormat here
const offlineCompiler = new compiler.OfflineCompiler(
resolver, normalizer, tmplParser, new StyleCompiler(urlResolver), new ViewCompiler(config),
new NgModuleCompiler(), new TypeScriptEmitter(reflectorHost), cliOptions.locale,
diff --git a/modules/@angular/compiler-cli/src/extract_i18n.ts b/modules/@angular/compiler-cli/src/extract_i18n.ts
index 75676aef2f..a67f555f9d 100644
--- a/modules/@angular/compiler-cli/src/extract_i18n.ts
+++ b/modules/@angular/compiler-cli/src/extract_i18n.ts
@@ -30,12 +30,29 @@ import {StaticReflector, StaticSymbol} from './static_reflector';
function extract(
ngOptions: tsc.AngularCompilerOptions, cliOptions: tsc.I18nExtractionCliOptions,
program: ts.Program, host: ts.CompilerHost) {
- const extractor = Extractor.create(ngOptions, cliOptions.i18nFormat, program, host);
+ const htmlParser = new compiler.i18n.HtmlParser(new HtmlParser());
+ const extractor = Extractor.create(ngOptions, cliOptions.i18nFormat, program, host, htmlParser);
const bundlePromise: Promise = extractor.extract();
return (bundlePromise).then(messageBundle => {
- const serializer = new compiler.i18n.Xmb();
- const dstPath = path.join(ngOptions.genDir, 'messages.xmb');
+ let ext: string;
+ let serializer: compiler.i18n.Serializer;
+ const format = (cliOptions.i18nFormat || 'xlf').toLowerCase();
+
+ switch (format) {
+ case 'xmb':
+ ext = 'xmb';
+ serializer = new compiler.i18n.Xmb();
+ break;
+ case 'xliff':
+ case 'xlf':
+ default:
+ ext = 'xlf';
+ serializer = new compiler.i18n.Xliff(htmlParser, compiler.DEFAULT_INTERPOLATION_CONFIG);
+ break;
+ }
+
+ const dstPath = path.join(ngOptions.genDir, `messages.${ext}`);
host.writeFile(dstPath, messageBundle.write(serializer), false);
});
}
@@ -128,7 +145,8 @@ export class Extractor {
static create(
options: tsc.AngularCompilerOptions, translationsFormat: string, program: ts.Program,
- compilerHost: ts.CompilerHost, reflectorHostContext?: ReflectorHostContext): Extractor {
+ compilerHost: ts.CompilerHost, htmlParser: compiler.i18n.HtmlParser,
+ reflectorHostContext?: ReflectorHostContext): Extractor {
const xhr: compiler.XHR = {
get: (s: string) => {
if (!compilerHost.fileExists(s)) {
@@ -143,7 +161,6 @@ export class Extractor {
const reflectorHost = new ReflectorHost(program, compilerHost, options, reflectorHostContext);
const staticReflector = new StaticReflector(reflectorHost);
StaticAndDynamicReflectionCapabilities.install(staticReflector);
- const htmlParser = new compiler.i18n.HtmlParser(new HtmlParser());
const config = new compiler.CompilerConfig({
genDebugInfo: options.debug === true,
diff --git a/modules/@angular/compiler/index.ts b/modules/@angular/compiler/index.ts
index 1dc751de3a..1b7ba3a397 100644
--- a/modules/@angular/compiler/index.ts
+++ b/modules/@angular/compiler/index.ts
@@ -14,7 +14,7 @@
import * as i18n from './src/i18n/index';
export {COMPILER_PROVIDERS, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileFactoryMetadata, CompileIdentifierMetadata, CompileMetadataWithIdentifier, CompilePipeMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata, CompilerConfig, DEFAULT_PACKAGE_URL_PROVIDER, DirectiveResolver, NgModuleResolver, OfflineCompiler, PipeResolver, RenderTypes, RuntimeCompiler, SourceModule, TEMPLATE_TRANSFORMS, UrlResolver, XHR, analyzeAppProvidersForDeprecatedConfiguration, createOfflineCompileUrlResolver, platformCoreDynamic} from './src/compiler';
-export {InterpolationConfig} from './src/ml_parser/interpolation_config';
+export {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from './src/ml_parser/interpolation_config';
export {ElementSchemaRegistry} from './src/schema/element_schema_registry';
export {i18n};
diff --git a/modules/@angular/compiler/src/compiler.ts b/modules/@angular/compiler/src/compiler.ts
index f96e6fe505..8637217dcc 100644
--- a/modules/@angular/compiler/src/compiler.ts
+++ b/modules/@angular/compiler/src/compiler.ts
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {COMPILER_OPTIONS, Compiler, CompilerFactory, CompilerOptions, Component, Inject, Injectable, OptionalMetadata, PLATFORM_INITIALIZER, PlatformRef, Provider, ReflectiveInjector, TRANSLATIONS, Type, ViewEncapsulation, createPlatformFactory, isDevMode, platformCore} from '@angular/core';
+import {COMPILER_OPTIONS, Compiler, CompilerFactory, CompilerOptions, Component, Inject, Injectable, OptionalMetadata, PLATFORM_INITIALIZER, PlatformRef, Provider, ReflectiveInjector, TRANSLATIONS, TRANSLATIONS_FORMAT, Type, ViewEncapsulation, createPlatformFactory, isDevMode, platformCore} from '@angular/core';
export * from './template_parser/template_ast';
export {TEMPLATE_TRANSFORMS} from './template_parser/template_parser';
@@ -63,9 +63,13 @@ export const COMPILER_PROVIDERS: Array|{[k: string]: any}|any[]> =
HtmlParser,
{
provide: i18n.HtmlParser,
- useFactory: (parser: HtmlParser, translations: string) =>
- new i18n.HtmlParser(parser, translations),
- deps: [HtmlParser, [new OptionalMetadata(), new Inject(TRANSLATIONS)]]
+ useFactory: (parser: HtmlParser, translations: string, format: string) =>
+ new i18n.HtmlParser(parser, translations, format),
+ deps: [
+ HtmlParser,
+ [new OptionalMetadata(), new Inject(TRANSLATIONS)],
+ [new OptionalMetadata(), new Inject(TRANSLATIONS_FORMAT)],
+ ]
},
TemplateParser,
DirectiveNormalizer,
diff --git a/modules/@angular/compiler/src/i18n/html_parser.ts b/modules/@angular/compiler/src/i18n/html_parser.ts
index 5672d29014..2a436aa630 100644
--- a/modules/@angular/compiler/src/i18n/html_parser.ts
+++ b/modules/@angular/compiler/src/i18n/html_parser.ts
@@ -12,17 +12,22 @@ import {ParseTreeResult} from '../ml_parser/parser';
import {mergeTranslations} from './extractor_merger';
import {MessageBundle} from './message_bundle';
+import {Serializer} from './serializers/serializer';
+import {Xliff} from './serializers/xliff';
+import {Xmb} from './serializers/xmb';
import {Xtb} from './serializers/xtb';
import {TranslationBundle} from './translation_bundle';
export class HtmlParser implements BaseHtmlParser {
// @override
- public getTagDefinition: any;
+ getTagDefinition: any;
// TODO(vicb): transB.load() should not need a msgB & add transB.resolve(msgB,
// interpolationConfig)
// TODO(vicb): remove the interpolationConfig from the Xtb serializer
- constructor(private _htmlParser: BaseHtmlParser, private _translations?: string) {}
+ constructor(
+ private _htmlParser: BaseHtmlParser, private _translations?: string,
+ private _translationsFormat?: string) {}
parse(
source: string, url: string, parseExpansionForms: boolean = false,
@@ -43,9 +48,25 @@ export class HtmlParser implements BaseHtmlParser {
return new ParseTreeResult(parseResult.rootNodes, parseResult.errors.concat(errors));
}
- const xtb = new Xtb(this._htmlParser, interpolationConfig);
- const translationBundle = TranslationBundle.load(this._translations, url, messageBundle, xtb);
+ const serializer = this._createSerializer(interpolationConfig);
+ const translationBundle =
+ TranslationBundle.load(this._translations, url, messageBundle, serializer);
return mergeTranslations(parseResult.rootNodes, translationBundle, interpolationConfig, [], {});
}
+
+ private _createSerializer(interpolationConfig: InterpolationConfig): Serializer {
+ const format = (this._translationsFormat || 'xlf').toLowerCase();
+
+ switch (format) {
+ case 'xmb':
+ return new Xmb();
+ case 'xtb':
+ return new Xtb(this._htmlParser, interpolationConfig);
+ case 'xliff':
+ case 'xlf':
+ default:
+ return new Xliff(this._htmlParser, interpolationConfig);
+ }
+ }
}
\ No newline at end of file
diff --git a/modules/@angular/compiler/src/i18n/index.ts b/modules/@angular/compiler/src/i18n/index.ts
index 6c43336835..b7e136de49 100644
--- a/modules/@angular/compiler/src/i18n/index.ts
+++ b/modules/@angular/compiler/src/i18n/index.ts
@@ -9,5 +9,6 @@
export {HtmlParser} from './html_parser';
export {MessageBundle} from './message_bundle';
export {Serializer} from './serializers/serializer';
+export {Xliff} from './serializers/xliff';
export {Xmb} from './serializers/xmb';
export {Xtb} from './serializers/xtb';
diff --git a/modules/@angular/compiler/test/i18n/integration_spec.ts b/modules/@angular/compiler/test/i18n/integration_spec.ts
index 362f3ff5ff..b81f47a27e 100644
--- a/modules/@angular/compiler/test/i18n/integration_spec.ts
+++ b/modules/@angular/compiler/test/i18n/integration_spec.ts
@@ -8,10 +8,9 @@
import {DirectiveResolver, XHR, i18n} from '@angular/compiler';
import {MockDirectiveResolver} from '@angular/compiler/testing';
-import {Compiler, Component, DebugElement, Injector, TRANSLATIONS} from '@angular/core';
+import {Compiler, Component, DebugElement, Injector, TRANSLATIONS, TRANSLATIONS_FORMAT} from '@angular/core';
import {TestBed, fakeAsync} from '@angular/core/testing';
-
-import {beforeEach, TestComponentBuilder, beforeEachProviders, ddescribe, describe, iit, inject, it, xdescribe, xit,} from '@angular/core/testing/testing_internal';
+import {beforeEach, TestComponentBuilder, ddescribe, describe, iit, inject, it, xdescribe, xit,} from '@angular/core/testing/testing_internal';
import {expect} from '@angular/platform-browser/testing/matchers';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {SpyXHR} from '../spies';
@@ -32,6 +31,7 @@ export function main() {
{provide: XHR, useClass: SpyXHR},
{provide: NgLocalization, useClass: FrLocalization},
{provide: TRANSLATIONS, useValue: XTB},
+ {provide: TRANSLATIONS_FORMAT, useValue: 'xtb'},
]
});
});
diff --git a/scripts/ci-lite/offline_compiler_test.sh b/scripts/ci-lite/offline_compiler_test.sh
index 0bfc6ac4ae..cf956fa539 100755
--- a/scripts/ci-lite/offline_compiler_test.sh
+++ b/scripts/ci-lite/offline_compiler_test.sh
@@ -33,8 +33,11 @@ cp -v package.json $TMP
./node_modules/.bin/tsc --version
# Compile the compiler-cli integration tests
- ./node_modules/.bin/ngc --i18nFile=src/messages.fi.xtb --locale=fi --i18nFormat=xtb
- ./node_modules/.bin/ng-xi18n
+ # TODO(vicb): restore the test for .xtb
+ #./node_modules/.bin/ngc --i18nFile=src/messages.fi.xtb --locale=fi --i18nFormat=xtb
+ ./node_modules/.bin/ngc --i18nFile=src/messages.fi.xlf --locale=fi --i18nFormat=xlf
+ ./node_modules/.bin/ng-xi18n --i18nFormat=xlf
+ ./node_modules/.bin/ng-xi18n --i18nFormat=xmb
./node_modules/.bin/jasmine init
# Run compiler-cli integration tests in node