From 18eefa0e07bd64c1b4abda97adcb6cc1128864c5 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Tue, 27 Aug 2019 20:30:23 +0200 Subject: [PATCH] fix(icon): not copying attributes from symbol nodes Currently we have some special handling for the cases where an icon resolves to a `symbol` node, because cloning it directly won't display anything. Our workaround is set up by creating a blank SVG and copying over all of the children of the `symbol` into it, however this doesn't account for any attributes on the `symbol` (e.g. its `viewBox`). These changes also copy over all the attributes. Fixes #16892. --- src/material/icon/fake-svgs.ts | 7 +++++++ src/material/icon/icon-registry.ts | 10 ++++++++++ src/material/icon/icon.spec.ts | 17 +++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/src/material/icon/fake-svgs.ts b/src/material/icon/fake-svgs.ts index ec345f525673..0bd65c7ba3e6 100644 --- a/src/material/icon/fake-svgs.ts +++ b/src/material/icon/fake-svgs.ts @@ -45,6 +45,13 @@ export const FAKE_SVGS = { `, + farmSet5: ` + + + + + + `, arrows: ` diff --git a/src/material/icon/icon-registry.ts b/src/material/icon/icon-registry.ts index e32dcb741fed..0f2913c09b0d 100644 --- a/src/material/icon/icon-registry.ts +++ b/src/material/icon/icon-registry.ts @@ -525,6 +525,16 @@ export class MatIconRegistry implements OnDestroy { */ private _toSvgElement(element: Element): SVGElement { const svg = this._svgElementFromString(''); + const attributes = element.attributes; + + // Copy over all the attributes from the `symbol` to the new SVG, except the id. + for (let i = 0; i < attributes.length; i++) { + const {name, value} = attributes[i]; + + if (name !== 'id') { + svg.setAttribute(name, value); + } + } for (let i = 0; i < element.childNodes.length; i++) { if (element.childNodes[i].nodeType === this._document.ELEMENT_NODE) { diff --git a/src/material/icon/icon.spec.ts b/src/material/icon/icon.spec.ts index 9fc58199afa9..d0d2d885ca52 100644 --- a/src/material/icon/icon.spec.ts +++ b/src/material/icon/icon.spec.ts @@ -433,6 +433,23 @@ describe('MatIcon', () => { expect((firstChild as HTMLElement).getAttribute('name')).toBe('quack'); }); + it('should copy over the attributes when unwrapping nodes', () => { + iconRegistry.addSvgIconSetInNamespace('farm', trustUrl('farm-set-5.svg')); + + const fixture = TestBed.createComponent(IconFromSvgName); + const testComponent = fixture.componentInstance; + const matIconElement = fixture.debugElement.nativeElement.querySelector('mat-icon'); + + testComponent.iconName = 'farm:duck'; + fixture.detectChanges(); + http.expectOne('farm-set-5.svg').flush(FAKE_SVGS.farmSet5); + + const svgElement = verifyAndGetSingleSvgChild(matIconElement); + expect(svgElement.getAttribute('viewBox')).toBe('0 0 13 37'); + expect(svgElement.getAttribute('id')).toBeFalsy(); + expect(svgElement.querySelector('symbol')).toBeFalsy(); + }); + it('should not wrap elements in icon sets in another svg tag', () => { iconRegistry.addSvgIconSet(trustUrl('arrow-set.svg'));