From 5e3228f61c799a7d4fd9aa1ce1445c81afac0ebb Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 22 Aug 2017 00:56:18 +0200 Subject: [PATCH] fix(icon): icon element not removed when svgIcon is reset (#6502) Fixes #6495. --- src/lib/icon/icon.spec.ts | 21 ++++++++++++++++++++- src/lib/icon/icon.ts | 33 ++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/lib/icon/icon.spec.ts b/src/lib/icon/icon.spec.ts index 7e3adb65945a..952e2b70185e 100644 --- a/src/lib/icon/icon.spec.ts +++ b/src/lib/icon/icon.spec.ts @@ -331,6 +331,25 @@ describe('MdIcon', () => { }).not.toThrow(); }); + it('should remove the SVG element from the DOM when the binding is cleared', () => { + mdIconRegistry.addSvgIconSet(trust('arrow-set.svg')); + + let fixture = TestBed.createComponent(IconFromSvgName); + + const testComponent = fixture.componentInstance; + const icon = fixture.debugElement.nativeElement.querySelector('md-icon'); + + testComponent.iconName = 'left-arrow'; + fixture.detectChanges(); + + expect(icon.querySelector('svg')).toBeTruthy(); + + testComponent.iconName = undefined; + fixture.detectChanges(); + + expect(icon.querySelector('svg')).toBeFalsy(); + }); + }); describe('custom fonts', () => { @@ -418,7 +437,7 @@ class IconWithCustomFontCss { @Component({template: ``}) class IconFromSvgName { - iconName = ''; + iconName: string | undefined = ''; } @Component({template: 'face'}) diff --git a/src/lib/icon/icon.ts b/src/lib/icon/icon.ts index 0e6832c90b0b..b959b434a2a9 100644 --- a/src/lib/icon/icon.ts +++ b/src/lib/icon/icon.ts @@ -118,24 +118,24 @@ export class MdIcon extends _MdIconMixinBase implements OnChanges, OnInit, CanCo } const parts = iconName.split(':'); switch (parts.length) { - case 1: - // Use default namespace. - return ['', parts[0]]; - case 2: - return <[string, string]>parts; - default: - throw Error(`Invalid icon name: "${iconName}"`); + case 1: return ['', parts[0]]; // Use default namespace. + case 2: return <[string, string]>parts; + default: throw Error(`Invalid icon name: "${iconName}"`); } } ngOnChanges(changes: SimpleChanges) { // Only update the inline SVG icon if the inputs changed, to avoid unnecessary DOM operations. - if (changes.svgIcon && this.svgIcon) { - const [namespace, iconName] = this._splitIconName(this.svgIcon); - - first.call(this._mdIconRegistry.getNamedSvgIcon(iconName, namespace)).subscribe( - svg => this._setSvgElement(svg), - (err: Error) => console.log(`Error retrieving icon: ${err.message}`)); + if (changes.svgIcon) { + if (this.svgIcon) { + const [namespace, iconName] = this._splitIconName(this.svgIcon); + + first.call(this._mdIconRegistry.getNamedSvgIcon(iconName, namespace)).subscribe( + svg => this._setSvgElement(svg), + (err: Error) => console.log(`Error retrieving icon: ${err.message}`)); + } else { + this._clearSvgElement(); + } } if (this._usingFontIcon()) { @@ -156,6 +156,11 @@ export class MdIcon extends _MdIconMixinBase implements OnChanges, OnInit, CanCo } private _setSvgElement(svg: SVGElement) { + this._clearSvgElement(); + this._renderer.appendChild(this._elementRef.nativeElement, svg); + } + + private _clearSvgElement() { const layoutElement = this._elementRef.nativeElement; const childCount = layoutElement.childNodes.length; @@ -164,8 +169,6 @@ export class MdIcon extends _MdIconMixinBase implements OnChanges, OnInit, CanCo for (let i = 0; i < childCount; i++) { this._renderer.removeChild(layoutElement, layoutElement.childNodes[i]); } - - this._renderer.appendChild(layoutElement, svg); } private _updateFontIconClasses() {