diff --git a/packages/core/src/render3/di.ts b/packages/core/src/render3/di.ts index dcfb0669cf..1e4fdde2a0 100644 --- a/packages/core/src/render3/di.ts +++ b/packages/core/src/render3/di.ts @@ -279,7 +279,14 @@ export function injectAttributeImpl(tNode: TNode, attrNameToInject: string): str // If we hit a `Bindings` or `Template` marker then we are done. if (isNameOnlyAttributeMarker(value)) break; - if (typeof value === 'number') { + // Skip namespaced attributes + if (value === AttributeMarker.NamespaceURI) { + // we skip the next two values + // as namespaced attributes looks like + // [..., AttributeMarker.NamespaceURI, 'http://someuri.com/test', 'test:exist', + // 'existValue', ...] + i = i + 2; + } else if (typeof value === 'number') { // Skip to the first value of the marked attribute. i++; if (value === AttributeMarker.Classes && attrNameToInject === 'class') { @@ -300,7 +307,6 @@ export function injectAttributeImpl(tNode: TNode, attrNameToInject: string): str } } } else if (value === attrNameToInject) { - // TODO(FW-1137): Skip namespaced attributes return attrs[i + 1] as string; } else { i = i + 2; diff --git a/packages/core/test/acceptance/di_spec.ts b/packages/core/test/acceptance/di_spec.ts index b7bd4b134e..3f88304fc9 100644 --- a/packages/core/test/acceptance/di_spec.ts +++ b/packages/core/test/acceptance/di_spec.ts @@ -131,30 +131,62 @@ describe('di', () => { expect(fixture.componentInstance.myDir.localeId).toBe('en-GB'); }); - it('should be able to inject different kinds of attributes', () => { - @Directive({selector: '[dir]'}) - class MyDir { - constructor( - @Attribute('class') public className: string, - @Attribute('style') public inlineStyles: string, - @Attribute('other-attr') public otherAttr: string) {} - } - @Component({ - template: - '
' - }) - class MyComp { - @ViewChild(MyDir) directiveInstance !: MyDir; - } + describe('@Attribute', () => { - TestBed.configureTestingModule({declarations: [MyDir, MyComp, MyComp]}); - const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); + it('should be able to inject different kinds of attributes', () => { + @Directive({selector: '[dir]'}) + class MyDir { + constructor( + @Attribute('class') public className: string, + @Attribute('style') public inlineStyles: string, + @Attribute('other-attr') public otherAttr: string) {} + } - const directive = fixture.componentInstance.directiveInstance; + @Component({ + template: + '
' + }) + class MyComp { + @ViewChild(MyDir) directiveInstance !: MyDir; + } - expect(directive.otherAttr).toBe('value'); - expect(directive.className).toBe('hello there'); - expect(directive.inlineStyles).toBe('margin: 1px; color: red;'); + TestBed.configureTestingModule({declarations: [MyDir, MyComp]}); + const fixture = TestBed.createComponent(MyComp); + fixture.detectChanges(); + + const directive = fixture.componentInstance.directiveInstance; + + expect(directive.otherAttr).toBe('value'); + expect(directive.className).toBe('hello there'); + expect(directive.inlineStyles).toBe('margin: 1px; color: red;'); + + }); + + it('should not inject attributes with namespace', () => { + @Directive({selector: '[dir]'}) + class MyDir { + constructor( + @Attribute('exist') public exist: string, + @Attribute('svg:exist') public namespacedExist: string, + @Attribute('other') public other: string) {} + } + + @Component({ + template: '
' + }) + class MyComp { + @ViewChild(MyDir) directiveInstance !: MyDir; + } + + TestBed.configureTestingModule({declarations: [MyDir, MyComp]}); + const fixture = TestBed.createComponent(MyComp); + fixture.detectChanges(); + + const directive = fixture.componentInstance.directiveInstance; + + expect(directive.exist).toBe('existValue'); + expect(directive.namespacedExist).toBeNull(); + expect(directive.other).toBe('otherValue'); + }); }); });