fix(ivy): sanitize external i18n ids before generating const names (#28522)
Prior to this change there was no i18n id sanitization before we output goog.getMsg calls. Due to the fact that message ids are used as a part of const names, some characters were bcausing issues while executing generated code. This commit adds sanitization to i18n ids used to generate i18n-related consts. PR Close #28522
This commit is contained in:
parent
7c5c1fae62
commit
3f73dfa151
|
@ -129,23 +129,25 @@ const verify = (input: string, output: string, extra: any = {}): void => {
|
|||
({i18nUseExternalIds, ...(extra.compilerOptions || {})});
|
||||
|
||||
// invoke with file-based prefix translation names
|
||||
let result = compile(files, angularFiles, opts(false));
|
||||
maybePrint(result.source, extra.verbose);
|
||||
expect(verifyPlaceholdersIntegrity(result.source)).toBe(true);
|
||||
expectEmit(result.source, output, 'Incorrect template');
|
||||
|
||||
if (extra.skipIdBasedCheck) return;
|
||||
if (!extra.skipPathBasedCheck) {
|
||||
const result = compile(files, angularFiles, opts(false));
|
||||
maybePrint(result.source, extra.verbose);
|
||||
expect(verifyPlaceholdersIntegrity(result.source)).toBe(true);
|
||||
expectEmit(result.source, output, 'Incorrect template');
|
||||
}
|
||||
|
||||
// invoke with translation names based on external ids
|
||||
result = compile(files, angularFiles, opts(true));
|
||||
maybePrint(result.source, extra.verbose);
|
||||
const interpolationConfig = extra.inputArgs && extra.inputArgs.interpolation ?
|
||||
InterpolationConfig.fromArray(extra.inputArgs.interpolation) :
|
||||
undefined;
|
||||
expect(verifyTranslationIds(input, result.source, extra.exceptions, interpolationConfig))
|
||||
.toBe(true);
|
||||
expect(verifyPlaceholdersIntegrity(result.source)).toBe(true);
|
||||
expectEmit(result.source, output, 'Incorrect template');
|
||||
if (!extra.skipIdBasedCheck) {
|
||||
const result = compile(files, angularFiles, opts(true));
|
||||
maybePrint(result.source, extra.verbose);
|
||||
const interpolationConfig = extra.inputArgs && extra.inputArgs.interpolation ?
|
||||
InterpolationConfig.fromArray(extra.inputArgs.interpolation) :
|
||||
undefined;
|
||||
expect(verifyTranslationIds(input, result.source, extra.exceptions, interpolationConfig))
|
||||
.toBe(true);
|
||||
expect(verifyPlaceholdersIntegrity(result.source)).toBe(true);
|
||||
expectEmit(result.source, output, 'Incorrect template');
|
||||
}
|
||||
};
|
||||
|
||||
describe('i18n support in the view compiler', () => {
|
||||
|
@ -589,6 +591,27 @@ describe('i18n support in the view compiler', () => {
|
|||
|
||||
verify(input, output);
|
||||
});
|
||||
|
||||
it('should sanitize ids and generate proper const names', () => {
|
||||
const input = `
|
||||
<div i18n="@@ID.WITH.INVALID.CHARS.2" i18n-title="@@ID.WITH.INVALID.CHARS" title="Element title">
|
||||
Some content
|
||||
</div>
|
||||
`;
|
||||
|
||||
const output = String.raw `
|
||||
const MSG_EXTERNAL_ID_WITH_INVALID_CHARS$$APP_SPEC_TS_0 = goog.getMsg("Element title");
|
||||
const $_c1$ = ["title", MSG_EXTERNAL_ID_WITH_INVALID_CHARS$$APP_SPEC_TS_0];
|
||||
const MSG_EXTERNAL_ID_WITH_INVALID_CHARS_2$$APP_SPEC_TS_2 = goog.getMsg(" Some content ");
|
||||
…
|
||||
`;
|
||||
|
||||
const exceptions = {
|
||||
'ID.WITH.INVALID.CHARS': 'Verify const name generation only',
|
||||
'ID.WITH.INVALID.CHARS.2': 'Verify const name generation only'
|
||||
};
|
||||
verify(input, output, {exceptions, skipPathBasedCheck: true});
|
||||
});
|
||||
});
|
||||
|
||||
describe('nested nodes', () => {
|
||||
|
|
|
@ -362,7 +362,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||
if (this.i18nUseExternalIds) {
|
||||
const prefix = getTranslationConstPrefix(`EXTERNAL_`);
|
||||
const uniqueSuffix = this.constantPool.uniqueName(suffix);
|
||||
name = `${prefix}${messageId}$$${uniqueSuffix}`;
|
||||
name = `${prefix}${sanitizeIdentifier(messageId)}$$${uniqueSuffix}`;
|
||||
} else {
|
||||
const prefix = getTranslationConstPrefix(suffix);
|
||||
name = this.constantPool.uniqueName(prefix);
|
||||
|
|
Loading…
Reference in New Issue