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,15 +129,16 @@ const verify = (input: string, output: string, extra: any = {}): void => {
|
|||||||
({i18nUseExternalIds, ...(extra.compilerOptions || {})});
|
({i18nUseExternalIds, ...(extra.compilerOptions || {})});
|
||||||
|
|
||||||
// invoke with file-based prefix translation names
|
// invoke with file-based prefix translation names
|
||||||
let result = compile(files, angularFiles, opts(false));
|
if (!extra.skipPathBasedCheck) {
|
||||||
|
const result = compile(files, angularFiles, opts(false));
|
||||||
maybePrint(result.source, extra.verbose);
|
maybePrint(result.source, extra.verbose);
|
||||||
expect(verifyPlaceholdersIntegrity(result.source)).toBe(true);
|
expect(verifyPlaceholdersIntegrity(result.source)).toBe(true);
|
||||||
expectEmit(result.source, output, 'Incorrect template');
|
expectEmit(result.source, output, 'Incorrect template');
|
||||||
|
}
|
||||||
if (extra.skipIdBasedCheck) return;
|
|
||||||
|
|
||||||
// invoke with translation names based on external ids
|
// invoke with translation names based on external ids
|
||||||
result = compile(files, angularFiles, opts(true));
|
if (!extra.skipIdBasedCheck) {
|
||||||
|
const result = compile(files, angularFiles, opts(true));
|
||||||
maybePrint(result.source, extra.verbose);
|
maybePrint(result.source, extra.verbose);
|
||||||
const interpolationConfig = extra.inputArgs && extra.inputArgs.interpolation ?
|
const interpolationConfig = extra.inputArgs && extra.inputArgs.interpolation ?
|
||||||
InterpolationConfig.fromArray(extra.inputArgs.interpolation) :
|
InterpolationConfig.fromArray(extra.inputArgs.interpolation) :
|
||||||
@ -146,6 +147,7 @@ const verify = (input: string, output: string, extra: any = {}): void => {
|
|||||||
.toBe(true);
|
.toBe(true);
|
||||||
expect(verifyPlaceholdersIntegrity(result.source)).toBe(true);
|
expect(verifyPlaceholdersIntegrity(result.source)).toBe(true);
|
||||||
expectEmit(result.source, output, 'Incorrect template');
|
expectEmit(result.source, output, 'Incorrect template');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('i18n support in the view compiler', () => {
|
describe('i18n support in the view compiler', () => {
|
||||||
@ -589,6 +591,27 @@ describe('i18n support in the view compiler', () => {
|
|||||||
|
|
||||||
verify(input, output);
|
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', () => {
|
describe('nested nodes', () => {
|
||||||
|
@ -362,7 +362,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||||||
if (this.i18nUseExternalIds) {
|
if (this.i18nUseExternalIds) {
|
||||||
const prefix = getTranslationConstPrefix(`EXTERNAL_`);
|
const prefix = getTranslationConstPrefix(`EXTERNAL_`);
|
||||||
const uniqueSuffix = this.constantPool.uniqueName(suffix);
|
const uniqueSuffix = this.constantPool.uniqueName(suffix);
|
||||||
name = `${prefix}${messageId}$$${uniqueSuffix}`;
|
name = `${prefix}${sanitizeIdentifier(messageId)}$$${uniqueSuffix}`;
|
||||||
} else {
|
} else {
|
||||||
const prefix = getTranslationConstPrefix(suffix);
|
const prefix = getTranslationConstPrefix(suffix);
|
||||||
name = this.constantPool.uniqueName(prefix);
|
name = this.constantPool.uniqueName(prefix);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user