refactor(compiler): Load the translation bundle only once in the i18n html parser (#14362)
fixes #14322
This commit is contained in:
parent
c4817988ca
commit
881dce841f
|
@ -24,11 +24,18 @@ export class I18NHtmlParser implements HtmlParser {
|
|||
// @override
|
||||
getTagDefinition: any;
|
||||
|
||||
private _translationBundle: TranslationBundle;
|
||||
|
||||
constructor(
|
||||
private _htmlParser: HtmlParser, private _translations?: string,
|
||||
private _translationsFormat?: string,
|
||||
private _missingTranslation: MissingTranslationStrategy = MissingTranslationStrategy.Warning,
|
||||
private _console?: Console) {}
|
||||
private _htmlParser: HtmlParser, translations?: string, translationsFormat?: string,
|
||||
missingTranslation: MissingTranslationStrategy = MissingTranslationStrategy.Warning,
|
||||
console?: Console) {
|
||||
if (translations) {
|
||||
const serializer = createSerializer(translationsFormat);
|
||||
this._translationBundle =
|
||||
TranslationBundle.load(translations, 'i18n', serializer, missingTranslation, console);
|
||||
}
|
||||
}
|
||||
|
||||
parse(
|
||||
source: string, url: string, parseExpansionForms: boolean = false,
|
||||
|
@ -36,36 +43,31 @@ export class I18NHtmlParser implements HtmlParser {
|
|||
const parseResult =
|
||||
this._htmlParser.parse(source, url, parseExpansionForms, interpolationConfig);
|
||||
|
||||
if (!this._translations || this._translations === '') {
|
||||
if (!this._translationBundle) {
|
||||
// Do not enable i18n when no translation bundle is provided
|
||||
return parseResult;
|
||||
}
|
||||
|
||||
// TODO(vicb): add support for implicit tags / attributes
|
||||
|
||||
if (parseResult.errors.length) {
|
||||
return new ParseTreeResult(parseResult.rootNodes, parseResult.errors);
|
||||
}
|
||||
|
||||
const serializer = this._createSerializer();
|
||||
const translationBundle = TranslationBundle.load(
|
||||
this._translations, url, serializer, this._missingTranslation, this._console);
|
||||
|
||||
return mergeTranslations(parseResult.rootNodes, translationBundle, interpolationConfig, [], {});
|
||||
}
|
||||
|
||||
private _createSerializer(): Serializer {
|
||||
const format = (this._translationsFormat || 'xlf').toLowerCase();
|
||||
|
||||
switch (format) {
|
||||
case 'xmb':
|
||||
return new Xmb();
|
||||
case 'xtb':
|
||||
return new Xtb();
|
||||
case 'xliff':
|
||||
case 'xlf':
|
||||
default:
|
||||
return new Xliff();
|
||||
}
|
||||
return mergeTranslations(
|
||||
parseResult.rootNodes, this._translationBundle, interpolationConfig, [], {});
|
||||
}
|
||||
}
|
||||
|
||||
function createSerializer(format?: string): Serializer {
|
||||
format = (format || 'xlf').toLowerCase();
|
||||
|
||||
switch (format) {
|
||||
case 'xmb':
|
||||
return new Xmb();
|
||||
case 'xtb':
|
||||
return new Xtb();
|
||||
case 'xliff':
|
||||
case 'xlf':
|
||||
default:
|
||||
return new Xliff();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {I18NHtmlParser} from '@angular/compiler/src/i18n/i18n_html_parser';
|
||||
import {TranslationBundle} from '@angular/compiler/src/i18n/translation_bundle';
|
||||
import {HtmlParser} from '@angular/compiler/src/ml_parser/html_parser';
|
||||
import {ParseTreeResult} from '@angular/compiler/src/ml_parser/parser';
|
||||
|
||||
export function main() {
|
||||
describe('I18N html parser', () => {
|
||||
|
||||
it('should return the html nodes when no translations are given', () => {
|
||||
const htmlParser = new HtmlParser();
|
||||
const i18nHtmlParser = new I18NHtmlParser(htmlParser);
|
||||
const ptResult = new ParseTreeResult([], []);
|
||||
|
||||
spyOn(htmlParser, 'parse').and.returnValue(ptResult);
|
||||
spyOn(i18nHtmlParser, 'parse').and.callThrough();
|
||||
|
||||
expect(i18nHtmlParser.parse('source', 'url')).toBe(ptResult);
|
||||
|
||||
expect(htmlParser.parse).toHaveBeenCalledTimes(1);
|
||||
expect(htmlParser.parse)
|
||||
.toHaveBeenCalledWith('source', 'url', jasmine.anything(), jasmine.anything());
|
||||
});
|
||||
|
||||
// https://github.com/angular/angular/issues/14322
|
||||
it('should parse the translations only once', () => {
|
||||
const transBundle = new TranslationBundle({}, () => 'id');
|
||||
spyOn(TranslationBundle, 'load').and.returnValue(transBundle);
|
||||
const htmlParser = new HtmlParser();
|
||||
const i18nHtmlParser = new I18NHtmlParser(htmlParser, 'translations');
|
||||
|
||||
expect(TranslationBundle.load).toHaveBeenCalledTimes(1);
|
||||
|
||||
i18nHtmlParser.parse('source', 'url');
|
||||
i18nHtmlParser.parse('source', 'url');
|
||||
expect(TranslationBundle.load).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
|
@ -6,13 +6,11 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {digest} from '@angular/compiler/src/i18n/digest';
|
||||
import {digest, serializeNodes} from '@angular/compiler/src/i18n/digest';
|
||||
import {extractMessages} from '@angular/compiler/src/i18n/extractor_merger';
|
||||
import {Message} from '@angular/compiler/src/i18n/i18n_ast';
|
||||
|
||||
import {serializeNodes} from '../../src/i18n/digest';
|
||||
import {HtmlParser} from '../../src/ml_parser/html_parser';
|
||||
import {DEFAULT_INTERPOLATION_CONFIG} from '../../src/ml_parser/interpolation_config';
|
||||
import {HtmlParser} from '@angular/compiler/src/ml_parser/html_parser';
|
||||
import {DEFAULT_INTERPOLATION_CONFIG} from '@angular/compiler/src/ml_parser/interpolation_config';
|
||||
|
||||
export function main() {
|
||||
describe('I18nParser', () => {
|
||||
|
|
Loading…
Reference in New Issue