From 73a914fea3854c6e71cceb0a016461bcc3bb71a9 Mon Sep 17 00:00:00 2001 From: emrahtoy <09020203> Date: Sun, 24 Sep 2017 06:16:10 +0300 Subject: [PATCH] were not supported. fill-opacity,xlink:href, href attributes were not supported --- index.js | 239 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 123 insertions(+), 116 deletions(-) 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 {childs}; - 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 {childs}; + 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; }