diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/GOLDEN_PARTIAL.js index e759cc6def59a..a43dd277b0acd 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/GOLDEN_PARTIAL.js @@ -358,66 +358,6 @@ export declare class MyModule { static ɵinj: i0.ɵɵInjectorDeclaration; } -/**************************************************************************************************** - * PARTIAL FILE: interpolated_attributes.js - ****************************************************************************************************/ -import { Component, NgModule } from '@angular/core'; -import * as i0 from "@angular/core"; -export class MyComponent { - constructor() { - this.name = 'Angular'; - } -} -MyComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); -MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: ` -
-
- `, isInline: true }); -i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyComponent, decorators: [{ - type: Component, - args: [{ - selector: 'my-component', - template: ` -
-
- ` - }] - }] }); -export class MyModule { -} -MyModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); -MyModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyModule, declarations: [MyComponent] }); -MyModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyModule }); -i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyModule, decorators: [{ - type: NgModule, - args: [{ declarations: [MyComponent] }] - }] }); - -/**************************************************************************************************** - * PARTIAL FILE: interpolated_attributes.d.ts - ****************************************************************************************************/ -import * as i0 from "@angular/core"; -export declare class MyComponent { - name: string; - static ɵfac: i0.ɵɵFactoryDeclaration; - static ɵcmp: i0.ɵɵComponentDeclaration; -} -export declare class MyModule { - static ɵfac: i0.ɵɵFactoryDeclaration; - static ɵmod: i0.ɵɵNgModuleDeclaration; - static ɵinj: i0.ɵɵInjectorDeclaration; -} - /**************************************************************************************************** * PARTIAL FILE: static_attributes.js ****************************************************************************************************/ diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/TEST_CASES.json index dde7fe0746c17..6d84fd7bcc65d 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/TEST_CASES.json @@ -99,20 +99,6 @@ } ] }, - { - "description": "should create translations for interpolated attributes", - "inputFiles": [ - "interpolated_attributes.ts" - ], - "expectations": [ - { - "extraChecks": [ - "verifyPlaceholdersIntegrity", - "verifyUniqueConsts" - ] - } - ] - }, { "description": "should translate static attributes", "inputFiles": [ diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/interpolated_attributes.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/interpolated_attributes.js deleted file mode 100644 index d4953741084f0..0000000000000 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/interpolated_attributes.js +++ /dev/null @@ -1,21 +0,0 @@ -consts: function () { - __i18nMsg__('title {$interpolation}', [['interpolation', String.raw`\uFFFD0\uFFFD`]], {}) - __i18nMsg__('label {$interpolation}', [['interpolation', String.raw`\uFFFD0\uFFFD`]], {id: 'id1'}) - __i18nMsg__('lang {$interpolation}', [['interpolation', String.raw`\uFFFD0\uFFFD`]], {id: 'id2'}) - __i18nMsg__('dir {$interpolation}', [['interpolation', String.raw`\uFFFD0\uFFFD`]], {id: 'id3'}) - __i18nMsg__('draggable {$interpolation}', [['interpolation', String.raw`\uFFFD0\uFFFD`]], {id: 'id6'}) - return [ - [6, "title", "label", "lang", "dir", "draggable"], ["title", $i18n_1$, "label", $i18n_2$, "lang", $i18n_3$, "dir", $i18n_4$, "draggable", $i18n_5$] - ]; -}, -template: function MyComponent_Template(rf, ctx) { - if (rf & 1) { - i0.ɵɵelementStart(0, "div", 0); - i0.ɵɵi18nAttributes(1, 1); - i0.ɵɵelementEnd(); - } - if (rf & 2) { - i0.ɵɵi18nExp(ctx.name)(ctx.name)(ctx.name)(ctx.name)(ctx.name); - i0.ɵɵi18nApply(1); - } -} diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/interpolated_attributes.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/interpolated_attributes.ts deleted file mode 100644 index e641fd48e45d1..0000000000000 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/element_attributes/interpolated_attributes.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {Component, NgModule} from '@angular/core'; - -@Component({ - selector: 'my-component', - template: ` -
-
- ` -}) -export class MyComponent { - name = 'Angular'; -} - -@NgModule({declarations: [MyComponent]}) -export class MyModule { -} diff --git a/packages/compiler/src/render3/view/i18n/meta.ts b/packages/compiler/src/render3/view/i18n/meta.ts index 9ca2fd285c1ec..ebc8681aa9cbb 100644 --- a/packages/compiler/src/render3/view/i18n/meta.ts +++ b/packages/compiler/src/render3/view/i18n/meta.ts @@ -16,7 +16,7 @@ import {ParseTreeResult} from '../../../ml_parser/parser'; import * as o from '../../../output/output_ast'; import {isTrustedTypesSink} from '../../../schema/trusted_types_sinks'; -import {ATTR_BINDING_MATCHER, hasI18nAttrs, I18N_ATTR, I18N_ATTR_PREFIX, icuFromI18nMessage} from './util'; +import {hasI18nAttrs, I18N_ATTR, I18N_ATTR_PREFIX, icuFromI18nMessage} from './util'; export type I18nMeta = { id?: string, @@ -81,7 +81,7 @@ export class I18nMetaVisitor implements html.Visitor { for (const attr of element.attrs) { if (attr.name === I18N_ATTR) { - // 'i18n' attribute that marks the element contents as an i18n message + // root 'i18n' node attribute const i18n = element.i18n || attr.value; const message = this._generateI18nMessage(element.children, i18n, setI18nRefs); // do not assign empty i18n meta @@ -107,10 +107,7 @@ export class I18nMetaVisitor implements html.Visitor { // set i18n meta for attributes if (Object.keys(attrsMeta).length) { for (const attr of attrs) { - // First try to match the metadata to the attribute name as-is. - // If that cannot be found try removing any `attr.` prefix from the attribute name. - const meta = - attrsMeta[attr.name] ?? attrsMeta[attr.name.replace(ATTR_BINDING_MATCHER, '')]; + const meta = attrsMeta[attr.name]; // do not create translation for empty attributes if (meta !== undefined && attr.value) { attr.i18n = this._generateI18nMessage([attr], attr.i18n || meta); diff --git a/packages/compiler/src/render3/view/i18n/util.ts b/packages/compiler/src/render3/view/i18n/util.ts index 821d83c40bf2a..3c0360cffeb99 100644 --- a/packages/compiler/src/render3/view/i18n/util.ts +++ b/packages/compiler/src/render3/view/i18n/util.ts @@ -24,12 +24,6 @@ export const TRANSLATION_VAR_PREFIX = 'i18n_'; /** Name of the i18n attributes **/ export const I18N_ATTR = 'i18n'; export const I18N_ATTR_PREFIX = 'i18n-'; -/** - * Matches the prefix used when binding to an attribute rather than a property. - * - * For example: `[attr.title]="expression"`. - * */ -export const ATTR_BINDING_MATCHER = /^attr\./i; /** Prefix of var expressions used in ICUs */ export const I18N_ICU_VAR_PREFIX = 'VAR_'; diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index e32ede0465442..a37caa822b289 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -656,8 +656,7 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver element.inputs.forEach(input => { const stylingInputWasSet = stylingBuilder.registerBoundInput(input); if (!stylingInputWasSet) { - if ((input.type === BindingType.Property || input.type === BindingType.Attribute) && - input.i18n) { + if (input.type === BindingType.Property && input.i18n) { boundI18nAttrs.push(input); } else { allOtherInputs.push(input); diff --git a/packages/core/test/acceptance/i18n_spec.ts b/packages/core/test/acceptance/i18n_spec.ts index 454954692e2c5..e7d53802f7bfe 100644 --- a/packages/core/test/acceptance/i18n_spec.ts +++ b/packages/core/test/acceptance/i18n_spec.ts @@ -1616,27 +1616,6 @@ onlyInIvy('Ivy i18n logic').describe('runtime i18n', () => { expect(fixture.nativeElement.innerHTML).toEqual(`
`); }); - it('interpolated "attr." bindings', () => { - loadTranslations({ - [computeMsgId('hello {$INTERPOLATION}')]: 'bonjour {$INTERPOLATION}', - custom: 'translated-{$INTERPOLATION}' - }); - const fixture = initWithTemplate(AppComp, ` -
-
-
- `); - expect(fixture.nativeElement.innerHTML) - .toEqual( - `
`); - - fixture.componentRef.instance.name = 'John'; - fixture.detectChanges(); - expect(fixture.nativeElement.innerHTML) - .toEqual( - `
`); - }); - it('with pipes', () => { loadTranslations({[computeMsgId('hello {$INTERPOLATION}')]: 'bonjour {$INTERPOLATION}'}); const fixture = initWithTemplate(