mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 07:17:18 +00:00
fix(GUI): make archive-embedded svgs work again (#1642)
We make the svg-icon component accept XML in its path argument to handle archive-embedded SVG icons. Changelog-Entry: Make archive-embedded SVG icons work again. Fixes: https://github.com/resin-io/etcher/issues/1636
This commit is contained in:
parent
a63b6bf18c
commit
7714e8b50a
@ -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
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
svg-icon {
|
||||
display: inline-block;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -37,7 +37,26 @@ describe('Browser: SVGIcon', function() {
|
||||
|
||||
const element = $compile(`<svg-icon path="'${icon}'">Resin.io</svg-icon>`)($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 = '<svg><rect x="10" y="10" height="100" width="100" style="stroke:red;fill:blue;"/></svg>';
|
||||
const img = `<img src="data:image/svg+xml,${encodeURIComponent(iconContents)}">`;
|
||||
$rootScope.iconContents = iconContents;
|
||||
|
||||
const element = $compile('<svg-icon path="iconContents">Resin.io</svg-icon>')($rootScope);
|
||||
$rootScope.$digest();
|
||||
m.chai.expect(element.children().html()).to.equal(img);
|
||||
});
|
||||
|
||||
it('should default the size to 40x40 pixels', function() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user