diff --git a/index.js b/index.js
index c6419021..6f2eedb6 100644
--- a/index.js
+++ b/index.js
@@ -4,21 +4,22 @@ import PropTypes from 'prop-types'
import xmldom from 'xmldom';
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
-import Svg,{
- Circle,
- Ellipse,
- G ,
- LinearGradient,
- RadialGradient,
- Line,
- Path,
- Polygon,
- Polyline,
- Rect,
- Text,
- TSpan,
- Defs,
- Stop
+import Svg, {
+ Circle,
+ Ellipse,
+ G,
+ LinearGradient,
+ RadialGradient,
+ Line,
+ Path,
+ Polygon,
+ Polyline,
+ Rect,
+ Text,
+ TSpan,
+ Defs,
+ Stop,
+ Use
} from 'react-native-svg';
import * as utils from './utils';
@@ -38,12 +39,13 @@ const ACCEPTED_SVG_ELEMENTS = [
'polygon',
'polyline',
'text',
- 'tspan'
+ 'tspan',
+ 'use'
];
// Attributes from SVG elements that are mapped directly.
const SVG_ATTS = ['viewBox', 'width', 'height'];
-const G_ATTS = ['id'];
+const G_ATTS = [];
const CIRCLE_ATTS = ['cx', 'cy', 'r'];
const PATH_ATTS = ['d'];
@@ -58,14 +60,14 @@ const TEXT_ATTS = ['fontFamily', 'fontSize', 'fontWeight']
const POLYGON_ATTS = ['points'];
const POLYLINE_ATTS = ['points'];
-
-const COMMON_ATTS = ['fill', 'fillOpacity', 'stroke', 'strokeWidth', 'strokeOpacity', 'opacity',
- 'strokeLinecap', 'strokeLinejoin',
- 'strokeDasharray', 'strokeDashoffset', 'x', 'y', 'rotate', 'scale', 'origin', 'originX', 'originY'];
+const USE_ATTS = ['xlink:href', 'href'];
+const COMMON_ATTS = ['fill', 'fillOpacity', 'fill-opacity', 'stroke', 'strokeWidth', 'strokeOpacity', 'opacity',
+ 'strokeLinecap', 'strokeLinejoin',
+ 'strokeDasharray', 'strokeDashoffset', 'x', 'y', 'rotate', 'scale', 'origin', 'originX', 'originY', 'id'];
let ind = 0;
-function fixYPosition (y, node) {
+function fixYPosition(y, node) {
if (node.attributes) {
const fontSizeAttr = Object.keys(node.attributes).find(a => node.attributes[a].name === 'font-size');
if (fontSizeAttr) {
@@ -78,19 +80,19 @@ function fixYPosition (y, node) {
return fixYPosition(y, node.parentNode)
}
-class SvgUri extends Component{
+class SvgUri extends Component {
- constructor(props){
+ constructor(props) {
super(props);
this.state = {fill: props.fill, svgXmlData: props.svgXmlData};
- this.createSVGElement = this.createSVGElement.bind(this);
- this.obtainComponentAtts = this.obtainComponentAtts.bind(this);
- this.inspectNode = this.inspectNode.bind(this);
- this.fetchSVGData = this.fetchSVGData.bind(this);
+ this.createSVGElement = this.createSVGElement.bind(this);
+ this.obtainComponentAtts = this.obtainComponentAtts.bind(this);
+ this.inspectNode = this.inspectNode.bind(this);
+ this.fetchSVGData = this.fetchSVGData.bind(this);
- this.isComponentMounted = false;
+ this.isComponentMounted = false;
// Gets the image data from an URL or a static file
if (props.source) {
@@ -103,21 +105,21 @@ class SvgUri extends Component{
this.isComponentMounted = true;
}
- componentWillReceiveProps (nextProps){
+ componentWillReceiveProps(nextProps) {
if (nextProps.source) {
const source = resolveAssetSource(nextProps.source) || {};
const oldSource = resolveAssetSource(this.props.source) || {};
- if(source.uri !== oldSource.uri){
+ if (source.uri !== oldSource.uri) {
this.fetchSVGData(source.uri);
}
}
if (nextProps.svgXmlData !== this.props.svgXmlData) {
- this.setState({ svgXmlData: nextProps.svgXmlData });
+ this.setState({svgXmlData: nextProps.svgXmlData});
}
if (nextProps.fill !== this.props.fill) {
- this.setState({ fill: nextProps.fill });
+ this.setState({fill: nextProps.fill});
}
}
@@ -125,96 +127,101 @@ class SvgUri extends Component{
this.isComponentMounted = false
}
- async fetchSVGData(uri){
+ async fetchSVGData(uri) {
let responseXML = null;
try {
const response = await fetch(uri);
responseXML = await response.text();
- } catch(e) {
+ } catch (e) {
console.error("ERROR SVG", e);
} finally {
if (this.isComponentMounted) {
- this.setState({svgXmlData:responseXML});
+ this.setState({svgXmlData: responseXML});
}
}
return responseXML;
}
-
- // Remove empty strings from children array
+
+ // Remove empty strings from children array
trimElementChilden(children) {
for (child of children) {
if (typeof child === 'string') {
if (child.trim.length === 0)
- children.splice(children.indexOf(child), 1);
+ children.splice(children.indexOf(child), 1);
}
}
}
- createSVGElement(node, childs){
+ createSVGElement(node, childs) {
this.trimElementChilden(childs);
let componentAtts = {};
const i = ind++;
switch (node.nodeName) {
- case 'svg':
- componentAtts = this.obtainComponentAtts(node, SVG_ATTS);
- if (this.props.width) {
- componentAtts.width = this.props.width;
- }
- if (this.props.height) {
- componentAtts.height = this.props.height;
- }
+ case 'svg':
+ componentAtts = this.obtainComponentAtts(node, SVG_ATTS);
+ if (this.props.width) {
+ componentAtts.width = this.props.width;
+ }
+ if (this.props.height) {
+ componentAtts.height = this.props.height;
+ }
- return ;
- case 'g':
- componentAtts = this.obtainComponentAtts(node, G_ATTS);
- return {childs};
- case 'path':
- componentAtts = this.obtainComponentAtts(node, PATH_ATTS);
- return {childs};
- case 'circle':
- componentAtts = this.obtainComponentAtts(node, CIRCLE_ATTS);
- return {childs};
- case 'rect':
- componentAtts = this.obtainComponentAtts(node, RECT_ATTS);
- return {childs};
- case 'line':
- componentAtts = this.obtainComponentAtts(node, LINE_ATTS);
- return {childs};
- case 'defs':
- return {childs};
- case 'linearGradient':
- componentAtts = this.obtainComponentAtts(node, LINEARG_ATTS);
- return {childs};
- case 'radialGradient':
- componentAtts = this.obtainComponentAtts(node, RADIALG_ATTS);
- return {childs};
- case 'stop':
- componentAtts = this.obtainComponentAtts(node, STOP_ATTS);
- return {childs};
- case 'ellipse':
- componentAtts = this.obtainComponentAtts(node, ELLIPSE_ATTS);
- return {childs};
- case 'polygon':
- componentAtts = this.obtainComponentAtts(node, POLYGON_ATTS);
- return {childs};
- case 'polyline':
- componentAtts = this.obtainComponentAtts(node, POLYLINE_ATTS);
- return {childs};
- case 'text':
- componentAtts = this.obtainComponentAtts(node, TEXT_ATTS);
- if (componentAtts.y) {
- componentAtts.y = fixYPosition(componentAtts.y, node)
- }
- return {childs};
- case 'tspan':
- componentAtts = this.obtainComponentAtts(node, TEXT_ATTS);
- if (componentAtts.y) {
- componentAtts.y = fixYPosition(componentAtts.y, node)
- }
- return {childs};
- default:
- return null;
+ return ;
+ case 'g':
+ componentAtts = this.obtainComponentAtts(node, G_ATTS);
+ return {childs};
+ case 'path':
+ componentAtts = this.obtainComponentAtts(node, PATH_ATTS);
+ return {childs};
+ case 'circle':
+ componentAtts = this.obtainComponentAtts(node, CIRCLE_ATTS);
+ return {childs};
+ case 'rect':
+ componentAtts = this.obtainComponentAtts(node, RECT_ATTS);
+ return {childs};
+ case 'line':
+ componentAtts = this.obtainComponentAtts(node, LINE_ATTS);
+ return {childs};
+ case 'defs':
+ return {childs};
+ case 'use':
+ componentAtts = this.obtainComponentAtts(node, USE_ATTS);
+ if (undefined !== componentAtts['xlink:href']) //react-native-svg may not know about xlink
+ componentAtts.href = componentAtts['xlink:href'];
+ return ;
+ case 'linearGradient':
+ componentAtts = this.obtainComponentAtts(node, LINEARG_ATTS);
+ return {childs};
+ case 'radialGradient':
+ componentAtts = this.obtainComponentAtts(node, RADIALG_ATTS);
+ return {childs};
+ case 'stop':
+ componentAtts = this.obtainComponentAtts(node, STOP_ATTS);
+ return {childs};
+ case 'ellipse':
+ componentAtts = this.obtainComponentAtts(node, ELLIPSE_ATTS);
+ return {childs};
+ case 'polygon':
+ componentAtts = this.obtainComponentAtts(node, POLYGON_ATTS);
+ return {childs};
+ case 'polyline':
+ componentAtts = this.obtainComponentAtts(node, POLYLINE_ATTS);
+ return {childs};
+ case 'text':
+ componentAtts = this.obtainComponentAtts(node, TEXT_ATTS);
+ if (componentAtts.y) {
+ componentAtts.y = fixYPosition(componentAtts.y, node)
+ }
+ return {childs};
+ case 'tspan':
+ componentAtts = this.obtainComponentAtts(node, TEXT_ATTS);
+ if (componentAtts.y) {
+ componentAtts.y = fixYPosition(componentAtts.y, node)
+ }
+ return {childs};
+ default:
+ return null;
}
}
@@ -228,7 +235,7 @@ class SvgUri extends Component{
}));
});
- const componentAtts = Array.from(attributes)
+ const componentAtts = Array.from(attributes)
.map(utils.camelCaseNodeName)
.map(utils.removePixelsFromNodeValue)
.filter(utils.getEnabledAttributes(enabledAttributes.concat(COMMON_ATTS)))
@@ -241,7 +248,7 @@ class SvgUri extends Component{
return componentAtts;
}
- inspectNode(node){
+ inspectNode(node) {
// Only process accepted elements
if (!ACCEPTED_SVG_ELEMENTS.includes(node.nodeName)) {
return null;
@@ -252,24 +259,24 @@ class SvgUri extends Component{
// if have children process them.
// Recursive function.
- if (node.childNodes && node.childNodes.length > 0){
- for (let i = 0; i < node.childNodes.length; i++){
- const isTextValue = node.childNodes[i].nodeValue
- if (isTextValue) {
- arrayElements.push(node.childNodes[i].nodeValue)
- } else {
- const nodo = this.inspectNode(node.childNodes[i]);
- if (nodo != null) {
- arrayElements.push(nodo);
- }
+ if (node.childNodes && node.childNodes.length > 0) {
+ for (let i = 0; i < node.childNodes.length; i++) {
+ const isTextValue = node.childNodes[i].nodeValue
+ if (isTextValue) {
+ arrayElements.push(node.childNodes[i].nodeValue)
+ } else {
+ const nodo = this.inspectNode(node.childNodes[i]);
+ if (nodo != null) {
+ arrayElements.push(nodo);
}
}
+ }
}
return this.createSVGElement(node, arrayElements);
}
- render () {
+ render() {
try {
if (this.state.svgXmlData == null) {
return null;
@@ -284,12 +291,12 @@ class SvgUri extends Component{
const rootSVG = this.inspectNode(doc.childNodes[0]);
- return(
-
- {rootSVG}
-
+ return (
+
+ {rootSVG}
+
);
- } catch(e){
+ } catch (e) {
console.error("ERROR SVG", e);
return null;
}