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
|
// @override
|
||||||
getTagDefinition: any;
|
getTagDefinition: any;
|
||||||
|
|
||||||
|
private _translationBundle: TranslationBundle;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _htmlParser: HtmlParser, private _translations?: string,
|
private _htmlParser: HtmlParser, translations?: string, translationsFormat?: string,
|
||||||
private _translationsFormat?: string,
|
missingTranslation: MissingTranslationStrategy = MissingTranslationStrategy.Warning,
|
||||||
private _missingTranslation: MissingTranslationStrategy = MissingTranslationStrategy.Warning,
|
console?: Console) {
|
||||||
private _console?: Console) {}
|
if (translations) {
|
||||||
|
const serializer = createSerializer(translationsFormat);
|
||||||
|
this._translationBundle =
|
||||||
|
TranslationBundle.load(translations, 'i18n', serializer, missingTranslation, console);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parse(
|
parse(
|
||||||
source: string, url: string, parseExpansionForms: boolean = false,
|
source: string, url: string, parseExpansionForms: boolean = false,
|
||||||
|
@ -36,26 +43,22 @@ export class I18NHtmlParser implements HtmlParser {
|
||||||
const parseResult =
|
const parseResult =
|
||||||
this._htmlParser.parse(source, url, parseExpansionForms, interpolationConfig);
|
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
|
// Do not enable i18n when no translation bundle is provided
|
||||||
return parseResult;
|
return parseResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(vicb): add support for implicit tags / attributes
|
|
||||||
|
|
||||||
if (parseResult.errors.length) {
|
if (parseResult.errors.length) {
|
||||||
return new ParseTreeResult(parseResult.rootNodes, parseResult.errors);
|
return new ParseTreeResult(parseResult.rootNodes, parseResult.errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
const serializer = this._createSerializer();
|
return mergeTranslations(
|
||||||
const translationBundle = TranslationBundle.load(
|
parseResult.rootNodes, this._translationBundle, interpolationConfig, [], {});
|
||||||
this._translations, url, serializer, this._missingTranslation, this._console);
|
|
||||||
|
|
||||||
return mergeTranslations(parseResult.rootNodes, translationBundle, interpolationConfig, [], {});
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _createSerializer(): Serializer {
|
function createSerializer(format?: string): Serializer {
|
||||||
const format = (this._translationsFormat || 'xlf').toLowerCase();
|
format = (format || 'xlf').toLowerCase();
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case 'xmb':
|
case 'xmb':
|
||||||
|
@ -67,5 +70,4 @@ export class I18NHtmlParser implements HtmlParser {
|
||||||
default:
|
default:
|
||||||
return new Xliff();
|
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
|
* 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 {extractMessages} from '@angular/compiler/src/i18n/extractor_merger';
|
||||||
import {Message} from '@angular/compiler/src/i18n/i18n_ast';
|
import {Message} from '@angular/compiler/src/i18n/i18n_ast';
|
||||||
|
import {HtmlParser} from '@angular/compiler/src/ml_parser/html_parser';
|
||||||
import {serializeNodes} from '../../src/i18n/digest';
|
import {DEFAULT_INTERPOLATION_CONFIG} from '@angular/compiler/src/ml_parser/interpolation_config';
|
||||||
import {HtmlParser} from '../../src/ml_parser/html_parser';
|
|
||||||
import {DEFAULT_INTERPOLATION_CONFIG} from '../../src/ml_parser/interpolation_config';
|
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('I18nParser', () => {
|
describe('I18nParser', () => {
|
||||||
|
|
Loading…
Reference in New Issue