diff --git a/lib/gui/components/svg-icon.js b/lib/gui/components/svg-icon.js index 2df911e8..304f3a6f 100644 --- a/lib/gui/components/svg-icon.js +++ b/lib/gui/components/svg-icon.js @@ -22,6 +22,7 @@ * @module Etcher.Components.SVGIcon */ +const _ = require('lodash'); const angular = require('angular'); const react = require('react'); const propTypes = require('prop-types'); @@ -53,13 +54,27 @@ class SVGIcon extends react.Component { // relatively to the `index.html`. const imagePath = path.join(__dirname, this.props.path); - const contents = fs.readFileSync(imagePath, { - encoding: 'utf8' - }); + let contents = ''; + + if (_.startsWith(this.props.path, '<')) { + contents = this.props.path; + + } else { + contents = fs.readFileSync(imagePath, { + encoding: 'utf8' + }); + } const width = this.props.width || DEFAULT_SIZE; const height = this.props.height || DEFAULT_SIZE; + const parser = new DOMParser(); + const doc = parser.parseFromString(contents, 'image/svg+xml'); + const svg = doc.querySelector('svg'); + + const img = document.createElement('img'); + img.src = `data:image/svg+xml,${encodeURIComponent(svg.outerHTML)}`; + return react.createElement('div', { className: 'svg-icon', height, @@ -70,7 +85,7 @@ class SVGIcon extends react.Component { }, disabled: this.props.disabled, dangerouslySetInnerHTML: { - __html: contents + __html: img.outerHTML } }); } diff --git a/lib/gui/components/svg-icon/styles/_svg-icon.scss b/lib/gui/components/svg-icon/styles/_svg-icon.scss index 1829c745..b0d80e0f 100644 --- a/lib/gui/components/svg-icon/styles/_svg-icon.scss +++ b/lib/gui/components/svg-icon/styles/_svg-icon.scss @@ -1,9 +1,9 @@ -svg { - width: 100%; - height: 100%; -} - svg-icon { display: inline-block; + + img { + width: 100%; + height: 100%; + } } diff --git a/lib/gui/css/main.css b/lib/gui/css/main.css index 8a57eb2a..4cd721d4 100644 --- a/lib/gui/css/main.css +++ b/lib/gui/css/main.css @@ -6413,12 +6413,11 @@ body { .modal-drive-selector-modal .word-keep { word-break: keep-all; } -svg { - width: 100%; - height: 100%; } - svg-icon { display: inline-block; } + svg-icon img { + width: 100%; + height: 100%; } /* * Copyright 2016 resin.io diff --git a/tests/gui/components/svg-icon.spec.js b/tests/gui/components/svg-icon.spec.js index d5753db1..1c2a2db0 100644 --- a/tests/gui/components/svg-icon.spec.js +++ b/tests/gui/components/svg-icon.spec.js @@ -37,7 +37,26 @@ describe('Browser: SVGIcon', function() { const element = $compile(`Resin.io`)($rootScope); $rootScope.$digest(); - m.chai.expect(element.children().html()).to.equal(iconContents); + + // We parse the SVGs to get rid of discrepancies caused by string differences + // in the outputs; the XML trees are still equal, as proven here. + const originalSVGParser = new DOMParser(); + const originalDoc = originalSVGParser.parseFromString(iconContents, 'image/svg+xml'); + const compiledSVGParser = new DOMParser(); + const compiledContents = decodeURIComponent(element.children()[0].children[0].src.substr(19)); + const compiledDoc = compiledSVGParser.parseFromString(compiledContents, 'image/svg+xml'); + + m.chai.expect(compiledDoc.outerHTML).to.equal(originalDoc.outerHTML); + }); + + it('should accept an SVG in the path attribute', function() { + const iconContents = ''; + const img = ``; + $rootScope.iconContents = iconContents; + + const element = $compile('Resin.io')($rootScope); + $rootScope.$digest(); + m.chai.expect(element.children().html()).to.equal(img); }); it('should default the size to 40x40 pixels', function() {