UNPKG

react-svg

Version:

A React component that injects SVG into the DOM.

1,070 lines (992 loc) 37.7 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('prop-types'), require('react')) : typeof define === 'function' && define.amd ? define(['exports', 'prop-types', 'react'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ReactSVG = {}, global.PropTypes, global.React)); })(this, (function (exports, PropTypes, React) { 'use strict'; function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var PropTypes__namespace = /*#__PURE__*/_interopNamespaceDefault(PropTypes); var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React); function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } function _inheritsLoose(t, o) { t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o); } /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ function __spreadArray(to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; var contentType = {}; /*! * content-type * Copyright(c) 2015 Douglas Christopher Wilson * MIT Licensed */ var hasRequiredContentType; function requireContentType () { if (hasRequiredContentType) return contentType; hasRequiredContentType = 1; /** * RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1 * * parameter = token "=" ( token / quoted-string ) * token = 1*tchar * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" * / DIGIT / ALPHA * ; any VCHAR, except delimiters * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text * obs-text = %x80-FF * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) */ var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g; // eslint-disable-line no-control-regex var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/; // eslint-disable-line no-control-regex var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; /** * RegExp to match quoted-pair in RFC 7230 sec 3.2.6 * * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) * obs-text = %x80-FF */ var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g; // eslint-disable-line no-control-regex /** * RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6 */ var QUOTE_REGEXP = /([\\"])/g; /** * RegExp to match type in RFC 7231 sec 3.1.1.1 * * media-type = type "/" subtype * type = token * subtype = token */ var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/; /** * Module exports. * @public */ contentType.format = format; contentType.parse = parse; /** * Format object to media type. * * @param {object} obj * @return {string} * @public */ function format (obj) { if (!obj || typeof obj !== 'object') { throw new TypeError('argument obj is required') } var parameters = obj.parameters; var type = obj.type; if (!type || !TYPE_REGEXP.test(type)) { throw new TypeError('invalid type') } var string = type; // append parameters if (parameters && typeof parameters === 'object') { var param; var params = Object.keys(parameters).sort(); for (var i = 0; i < params.length; i++) { param = params[i]; if (!TOKEN_REGEXP.test(param)) { throw new TypeError('invalid parameter name') } string += '; ' + param + '=' + qstring(parameters[param]); } } return string } /** * Parse media type to object. * * @param {string|object} string * @return {Object} * @public */ function parse (string) { if (!string) { throw new TypeError('argument string is required') } // support req/res-like objects as argument var header = typeof string === 'object' ? getcontenttype(string) : string; if (typeof header !== 'string') { throw new TypeError('argument string is required to be a string') } var index = header.indexOf(';'); var type = index !== -1 ? header.slice(0, index).trim() : header.trim(); if (!TYPE_REGEXP.test(type)) { throw new TypeError('invalid media type') } var obj = new ContentType(type.toLowerCase()); // parse parameters if (index !== -1) { var key; var match; var value; PARAM_REGEXP.lastIndex = index; while ((match = PARAM_REGEXP.exec(header))) { if (match.index !== index) { throw new TypeError('invalid parameter format') } index += match[0].length; key = match[1].toLowerCase(); value = match[2]; if (value.charCodeAt(0) === 0x22 /* " */) { // remove quotes value = value.slice(1, -1); // remove escapes if (value.indexOf('\\') !== -1) { value = value.replace(QESC_REGEXP, '$1'); } } obj.parameters[key] = value; } if (index !== header.length) { throw new TypeError('invalid parameter format') } } return obj } /** * Get content-type from req/res objects. * * @param {object} * @return {Object} * @private */ function getcontenttype (obj) { var header; if (typeof obj.getHeader === 'function') { // res-like header = obj.getHeader('content-type'); } else if (typeof obj.headers === 'object') { // req-like header = obj.headers && obj.headers['content-type']; } if (typeof header !== 'string') { throw new TypeError('content-type header is missing from object') } return header } /** * Quote a string if necessary. * * @param {string} val * @return {string} * @private */ function qstring (val) { var str = String(val); // no need to quote tokens if (TOKEN_REGEXP.test(str)) { return str } if (str.length > 0 && !TEXT_REGEXP.test(str)) { throw new TypeError('invalid parameter value') } return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"' } /** * Class to represent a content type. * @private */ function ContentType (type) { this.parameters = Object.create(null); this.type = type; } return contentType; } var contentTypeExports = requireContentType(); var svgNamespace$1 = 'http://www.w3.org/2000/svg'; var extractSymbol = function (spriteSvg, symbolId) { var symbol = spriteSvg.querySelector('#' + CSS.escape(symbolId)); if ((symbol === null || symbol === void 0 ? void 0 : symbol.tagName.toLowerCase()) !== 'symbol') { return null; } var svg = document.createElementNS(svgNamespace$1, 'svg'); var attrs = symbol.attributes; for (var i = 0, len = attrs.length; i < len; i++) { var attr = attrs[i]; if (attr.name !== 'id') { svg.setAttribute(attr.name, attr.value); } } var children = symbol.childNodes; for (var i = 0, len = children.length; i < len; i++) { svg.appendChild(children[i].cloneNode(true)); } return svg; }; var cache = new Map(); var cloneSvg = function (sourceSvg) { return sourceSvg.cloneNode(true); }; var isLocal = function () { return window.location.protocol === 'file:'; }; var makeAjaxRequest = function (url, httpRequestWithCredentials, callback) { var httpRequest = new XMLHttpRequest(); httpRequest.onreadystatechange = function () { try { if (!/\.svg/i.test(url) && httpRequest.readyState === 2) { var contentType = httpRequest.getResponseHeader('Content-Type'); if (!contentType) { throw new Error('Content type not found'); } var type = contentTypeExports.parse(contentType).type; if (!(type === 'image/svg+xml' || type === 'text/plain')) { throw new Error("Invalid content type: ".concat(type)); } } if (httpRequest.readyState === 4) { if (httpRequest.status === 404 || httpRequest.responseXML === null) { throw new Error(isLocal() ? 'Note: SVG injection ajax calls do not work locally without ' + 'adjusting security settings in your browser. Or consider ' + 'using a local webserver.' : 'Unable to load SVG file: ' + url); } if (httpRequest.status === 200 || isLocal() && httpRequest.status === 0) { callback(null, httpRequest); } else { throw new Error('There was a problem injecting the SVG: ' + httpRequest.status + ' ' + httpRequest.statusText); } } } catch (error) { httpRequest.abort(); if (error instanceof Error) { callback(error, httpRequest); } else { throw error; } } }; httpRequest.open('GET', url); httpRequest.withCredentials = httpRequestWithCredentials; if (httpRequest.overrideMimeType) { httpRequest.overrideMimeType('image/svg+xml'); } httpRequest.send(); }; var requestQueue = {}; var queueRequest = function (url, callback) { var _a; (_a = requestQueue[url]) !== null && _a !== void 0 ? _a : requestQueue[url] = []; requestQueue[url].push(callback); }; var processRequestQueue = function (url) { var callbacks = requestQueue[url]; if (!callbacks) { return; } var _loop_1 = function (i, len) { setTimeout(function () { if (Array.isArray(requestQueue[url])) { var cacheValue = cache.get(url); var callback = callbacks[i]; if (!callback) { return; } if (cacheValue instanceof SVGSVGElement) { callback(null, cloneSvg(cacheValue)); } if (cacheValue instanceof Error) { callback(cacheValue); } if (i === callbacks.length - 1) { delete requestQueue[url]; } } }, 0); }; for (var i = 0, len = callbacks.length; i < len; i++) { _loop_1(i); } }; var loadSvgCached = function (url, httpRequestWithCredentials, callback) { if (cache.has(url)) { var cacheValue = cache.get(url); if (cacheValue === undefined) { queueRequest(url, callback); return; } if (cacheValue instanceof SVGSVGElement) { callback(null, cloneSvg(cacheValue)); return; } } cache.set(url, undefined); queueRequest(url, callback); makeAjaxRequest(url, httpRequestWithCredentials, function (error, httpRequest) { var _a; if (error) { cache.set(url, error); } else if (((_a = httpRequest.responseXML) === null || _a === void 0 ? void 0 : _a.documentElement) instanceof SVGSVGElement) { cache.set(url, httpRequest.responseXML.documentElement); } processRequestQueue(url); }); }; var loadSvgUncached = function (url, httpRequestWithCredentials, callback) { makeAjaxRequest(url, httpRequestWithCredentials, function (error, httpRequest) { var _a; if (error) { callback(error); } else if (((_a = httpRequest.responseXML) === null || _a === void 0 ? void 0 : _a.documentElement) instanceof SVGSVGElement) { callback(null, httpRequest.responseXML.documentElement); } }); }; var dataUrlPrefix = 'data:image/svg+xml'; var parseDataUrl = function (url) { if (!url.startsWith(dataUrlPrefix)) { return null; } var rest = url.slice(dataUrlPrefix.length); var svgString; if (rest.startsWith(';base64,')) { try { svgString = atob(rest.slice(';base64,'.length)); } catch (_a) { return new Error('Invalid base64 in data URL'); } } else if (rest.startsWith(',')) { try { svgString = decodeURIComponent(rest.slice(','.length)); } catch (_b) { return new Error('Invalid encoding in data URL'); } } else if (rest.startsWith(';charset=utf-8,')) { try { svgString = decodeURIComponent(rest.slice(';charset=utf-8,'.length)); } catch (_c) { return new Error('Invalid encoding in data URL'); } } else { return new Error('Unsupported data URL format'); } var doc = new DOMParser().parseFromString(svgString, 'image/svg+xml'); var parserError = doc.querySelector('parsererror'); if (parserError) { return new Error('Data URL SVG parse error: ' + parserError.textContent.trim()); } if (!(doc.documentElement instanceof SVGSVGElement)) { return new Error('Data URL did not contain a valid SVG element'); } return doc.documentElement; }; var idCounter$1 = 0; var uniqueId = function () { return ++idCounter$1; }; var injectedElements = []; var ranScripts = {}; var svgNamespace$2 = 'http://www.w3.org/2000/svg'; var xlinkNamespace$1 = 'http://www.w3.org/1999/xlink'; var injectElement = function (el, evalScripts, renumerateIRIElements, cacheRequests, httpRequestWithCredentials, beforeEach, callback) { var _a; var elUrl = (_a = el.getAttribute('data-src')) !== null && _a !== void 0 ? _a : el.getAttribute('src'); if (!elUrl) { callback(new Error('Invalid data-src or src attribute')); return; } if (injectedElements.indexOf(el) !== -1) { injectedElements.splice(injectedElements.indexOf(el), 1); el = null; return; } injectedElements.push(el); el.setAttribute('src', ''); var hashIndex = elUrl.indexOf('#'); var baseUrl = hashIndex !== -1 ? elUrl.slice(0, hashIndex) : elUrl; var symbolId = hashIndex !== -1 ? elUrl.slice(hashIndex + 1) : null; var dataUrlResult = parseDataUrl(baseUrl); if (dataUrlResult instanceof Error) { injectedElements.splice(injectedElements.indexOf(el), 1); el = null; callback(dataUrlResult); return; } var handleLoadedSvg = function (error, loadedSvg) { var _a, _b; if (!loadedSvg) { injectedElements.splice(injectedElements.indexOf(el), 1); el = null; callback(error); return; } var svg = loadedSvg; if (symbolId) { var symbolSvg = extractSymbol(loadedSvg, symbolId); if (!symbolSvg) { injectedElements.splice(injectedElements.indexOf(el), 1); el = null; callback(new Error("Symbol \"".concat(symbolId, "\" not found in ").concat(baseUrl))); return; } svg = symbolSvg; } var elId = el.getAttribute('id'); if (elId) { svg.setAttribute('id', elId); } var elTitle = el.getAttribute('title'); if (elTitle) { svg.setAttribute('title', elTitle); } var elWidth = el.getAttribute('width'); if (elWidth) { svg.setAttribute('width', elWidth); } var elHeight = el.getAttribute('height'); if (elHeight) { svg.setAttribute('height', elHeight); } var mergedClasses = Array.from(new Set(__spreadArray(__spreadArray(__spreadArray([], ((_a = svg.getAttribute('class')) !== null && _a !== void 0 ? _a : '').split(' '), true), ['injected-svg'], false), ((_b = el.getAttribute('class')) !== null && _b !== void 0 ? _b : '').split(' '), true))).join(' ').trim(); svg.setAttribute('class', mergedClasses); var elStyle = el.getAttribute('style'); if (elStyle) { svg.setAttribute('style', elStyle); } svg.setAttribute('data-src', elUrl); var elData = [].filter.call(el.attributes, function (at) { return /^data-\w[\w-]*$/.test(at.name); }); Array.prototype.forEach.call(elData, function (dataAttr) { if (dataAttr.name && dataAttr.value) { svg.setAttribute(dataAttr.name, dataAttr.value); } }); if (renumerateIRIElements) { var iriElementsAndProperties_1 = { clipPath: ['clip-path'], 'color-profile': ['color-profile'], cursor: ['cursor'], filter: ['filter'], linearGradient: ['fill', 'stroke'], marker: ['marker', 'marker-start', 'marker-mid', 'marker-end'], mask: ['mask'], path: [], pattern: ['fill', 'stroke'], radialGradient: ['fill', 'stroke'] }; var replaceIriReferences_1 = function (value, iriIdMap) { return value.replace(/url\((['"]?)\s*#([^\s'"\)]+)\s*\1\)/g, function (match, _quote, iriId) { var newId = iriIdMap[iriId]; return newId ? "url(#".concat(newId, ")") : match; }); }; var replaceHrefReference = function (value, iriIdMap) { if (!value.startsWith('#')) { return value; } var iriId = value.slice(1); var newId = iriIdMap[iriId]; return newId ? '#' + newId : value; }; var element_1; var elements_1; var properties_1; var currentId_1; var newId_1; var renumeratedElements_1 = []; var iriIdMap_1 = {}; Object.keys(iriElementsAndProperties_1).forEach(function (key) { element_1 = key; elements_1 = svg.querySelectorAll(element_1 + '[id]'); for (var a = 0, elementsLen = elements_1.length; a < elementsLen; a++) { var currentElement = elements_1[a]; currentId_1 = currentElement.id; newId_1 = currentId_1 + '-' + uniqueId(); iriIdMap_1[currentId_1] = newId_1; renumeratedElements_1.push({ element: currentElement, currentId: currentId_1, newId: newId_1 }); } }); Object.keys(iriElementsAndProperties_1).forEach(function (key) { properties_1 = iriElementsAndProperties_1[key]; var referencingElements; Array.prototype.forEach.call(properties_1, function (property) { referencingElements = svg.querySelectorAll('[' + property + ']'); for (var b = 0, referencingElementLen = referencingElements.length; b < referencingElementLen; b++) { var referencingElement = referencingElements[b]; var attrValue = referencingElement.getAttribute(property); if (attrValue) { var nextValue = replaceIriReferences_1(attrValue, iriIdMap_1); if (nextValue !== attrValue) { referencingElement.setAttribute(property, nextValue); } } } }); }); var allLinks = svg.querySelectorAll('*'); for (var c = 0, allLinksLen = allLinks.length; c < allLinksLen; c++) { var link = allLinks[c]; var href = link.getAttribute('href'); if (href) { var nextHref = replaceHrefReference(href, iriIdMap_1); if (nextHref !== href) { link.setAttribute('href', nextHref); } } var xlinkHref = link.getAttributeNS(xlinkNamespace$1, 'href'); if (xlinkHref) { var nextXlinkHref = replaceHrefReference(xlinkHref, iriIdMap_1); if (nextXlinkHref !== xlinkHref) { link.setAttributeNS(xlinkNamespace$1, 'href', nextXlinkHref); } } } var styleElements = svg.querySelectorAll('[style]'); for (var d = 0, styleElementsLen = styleElements.length; d < styleElementsLen; d++) { var styleElement = styleElements[d]; var styleValue = styleElement.getAttribute('style'); if (styleValue) { var nextStyleValue = replaceIriReferences_1(styleValue, iriIdMap_1); if (nextStyleValue !== styleValue) { styleElement.setAttribute('style', nextStyleValue); } } } var styleTagElements = svg.querySelectorAll('style'); for (var e = 0, styleTagElementsLen = styleTagElements.length; e < styleTagElementsLen; e++) { var styleTagElement = styleTagElements[e]; var textContent = styleTagElement.textContent; if (textContent) { var nextTextContent = replaceIriReferences_1(textContent, iriIdMap_1); if (nextTextContent !== textContent) { styleTagElement.textContent = nextTextContent; } } } for (var f = 0, renumeratedElementsLen = renumeratedElements_1.length; f < renumeratedElementsLen; f++) { renumeratedElements_1[f].element.id = renumeratedElements_1[f].newId; } } svg.removeAttribute('xmlns:a'); var scripts = svg.querySelectorAll('script'); var scriptsToEval = []; var script; var scriptType; for (var i = 0, scriptsLen = scripts.length; i < scriptsLen; i++) { var scriptElement = scripts[i]; scriptType = scriptElement.getAttribute('type'); if (!scriptType || scriptType === 'application/ecmascript' || scriptType === 'application/javascript' || scriptType === 'text/javascript') { script = scriptElement.innerText || scriptElement.textContent; if (script) { scriptsToEval.push(script); } svg.removeChild(scriptElement); } } if (scriptsToEval.length > 0 && (evalScripts === 'always' || evalScripts === 'once' && !ranScripts[elUrl])) { for (var l = 0, scriptsToEvalLen = scriptsToEval.length; l < scriptsToEvalLen; l++) { new Function(scriptsToEval[l])(window); } ranScripts[elUrl] = true; } var styleTags = svg.querySelectorAll('style'); Array.prototype.forEach.call(styleTags, function (styleTag) { styleTag.textContent += ''; }); svg.setAttribute('xmlns', svgNamespace$2); svg.setAttribute('xmlns:xlink', xlinkNamespace$1); beforeEach(svg); if (!el.parentNode) { injectedElements.splice(injectedElements.indexOf(el), 1); el = null; callback(new Error('Parent node is null')); return; } el.parentNode.replaceChild(svg, el); injectedElements.splice(injectedElements.indexOf(el), 1); el = null; callback(null, svg); }; if (dataUrlResult) { setTimeout(function () { handleLoadedSvg(null, dataUrlResult); }, 0); return; } var loadSvg = cacheRequests ? loadSvgCached : loadSvgUncached; loadSvg(baseUrl, httpRequestWithCredentials, handleLoadedSvg); }; var SVGInjector = function (elements, _a) { var _b = _a === void 0 ? {} : _a, _c = _b.afterAll, afterAll = _c === void 0 ? function () { return undefined; } : _c, _d = _b.afterEach, afterEach = _d === void 0 ? function () { return undefined; } : _d, _e = _b.beforeEach, beforeEach = _e === void 0 ? function () { return undefined; } : _e, _f = _b.cacheRequests, cacheRequests = _f === void 0 ? true : _f, _g = _b.evalScripts, evalScripts = _g === void 0 ? 'never' : _g, _h = _b.httpRequestWithCredentials, httpRequestWithCredentials = _h === void 0 ? false : _h, _j = _b.renumerateIRIElements, renumerateIRIElements = _j === void 0 ? true : _j; if (elements && 'length' in elements) { var elementsLoaded_1 = 0; for (var i = 0, j = elements.length; i < j; i++) { var element = elements[i]; if (!element) { continue; } injectElement(element, evalScripts, renumerateIRIElements, cacheRequests, httpRequestWithCredentials, beforeEach, function (error, svg) { afterEach(error, svg); if (elements && 'length' in elements && elements.length === ++elementsLoaded_1) { afterAll(elementsLoaded_1); } }); } } else if (elements) { injectElement(elements, evalScripts, renumerateIRIElements, cacheRequests, httpRequestWithCredentials, beforeEach, function (error, svg) { afterEach(error, svg); afterAll(1); elements = null; }); } else { afterAll(0); } }; // Hat-tip: https://github.com/mui/material-ui/tree/master/packages/mui-utils/src. var ownerWindow = function ownerWindow(node) { var doc = (node == null ? void 0 : node.ownerDocument) || document; return doc.defaultView || window; }; // Hat-tip: https://github.com/developit/preact-compat/blob/master/src/index.js#L402. var shallowDiffers = function shallowDiffers(a, b) { for (var i in a) { if (!(i in b)) { return true; } } for (var _i in b) { if (a[_i] !== b[_i]) { return true; } } return false; }; var _excluded = ["afterInjection", "beforeInjection", "desc", "evalScripts", "fallback", "httpRequestWithCredentials", "loading", "renumerateIRIElements", "src", "title", "useRequestCache", "wrapper"]; var svgNamespace = 'http://www.w3.org/2000/svg'; var xlinkNamespace = 'http://www.w3.org/1999/xlink'; // Random prefix avoids ID collisions when multiple copies of react-svg are // bundled (e.g. microfrontends). The counter ensures each component instance // within the same bundle gets a unique ID. var idPrefix = "react-svg-" + Math.random().toString(36).slice(2, 6); var idCounter = 0; var ReactSVG = /*#__PURE__*/function (_React$Component) { function ReactSVG() { var _this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this; _this.initialState = { hasError: false, isLoading: true }; _this.state = _this.initialState; _this._isMounted = false; _this.reactWrapper = void 0; _this.nonReactWrapper = void 0; _this.refCallback = function (reactWrapper) { _this.reactWrapper = reactWrapper; }; return _this; } _inheritsLoose(ReactSVG, _React$Component); var _proto = ReactSVG.prototype; _proto.renderSVG = function renderSVG() { var _this2 = this; /* istanbul ignore else */ if (this.reactWrapper instanceof ownerWindow(this.reactWrapper).Node) { var _this$props = this.props, desc = _this$props.desc, evalScripts = _this$props.evalScripts, httpRequestWithCredentials = _this$props.httpRequestWithCredentials, renumerateIRIElements = _this$props.renumerateIRIElements, src = _this$props.src, title = _this$props.title, useRequestCache = _this$props.useRequestCache; var onError = this.props.onError; var beforeInjection = this.props.beforeInjection; var afterInjection = this.props.afterInjection; var wrapper = this.props.wrapper; var nonReactWrapper; var nonReactTarget; if (wrapper === 'svg') { nonReactWrapper = document.createElementNS(svgNamespace, wrapper); nonReactWrapper.setAttribute('xmlns', svgNamespace); nonReactWrapper.setAttribute('xmlns:xlink', xlinkNamespace); nonReactTarget = document.createElementNS(svgNamespace, wrapper); } else { nonReactWrapper = document.createElement(wrapper); nonReactTarget = document.createElement(wrapper); } nonReactWrapper.appendChild(nonReactTarget); nonReactTarget.dataset.src = src; this.nonReactWrapper = this.reactWrapper.appendChild(nonReactWrapper); var handleError = function handleError(error) { _this2.removeSVG(); if (!_this2._isMounted) { onError(error); return; } _this2.setState(function () { return { hasError: true, isLoading: false }; }, function () { onError(error); }); }; var afterEach = function afterEach(error, svg) { if (error) { handleError(error); return; } // TODO (Tane): It'd be better to cleanly unsubscribe from SVGInjector // callbacks instead of tracking a property like this. if (_this2._isMounted) { _this2.setState(function () { return { isLoading: false }; }, function () { try { afterInjection(svg); } catch (afterInjectionError) { handleError(afterInjectionError); } }); } }; // WAI best practice: SVGs need role="img" plus aria-labelledby/ // aria-describedby pointing to <title>/<desc> element IDs for screen // readers to announce them. svg-injector copies the HTML title // *attribute* (tooltip) but doesn't create SVG-namespace child // elements or ARIA linkage, so we handle that here. var beforeEach = function beforeEach(svg) { svg.setAttribute('role', 'img'); var ariaLabelledBy = []; var ariaDescribedBy = []; if (title) { var originalTitle = svg.querySelector(':scope > title'); if (originalTitle) { svg.removeChild(originalTitle); } var titleId = idPrefix + "-title-" + ++idCounter; // createElementNS is required: createElement would produce an // HTML-namespace node that screen readers ignore inside SVG. var newTitle = document.createElementNS(svgNamespace, 'title'); newTitle.id = titleId; newTitle.textContent = title; svg.prepend(newTitle); ariaLabelledBy.push(titleId); } if (desc) { var originalDesc = svg.querySelector(':scope > desc'); if (originalDesc) { svg.removeChild(originalDesc); } var descId = idPrefix + "-desc-" + ++idCounter; var newDesc = document.createElementNS(svgNamespace, 'desc'); newDesc.id = descId; newDesc.textContent = desc; var existingTitle = svg.querySelector(':scope > title'); if (existingTitle) { existingTitle.after(newDesc); } else { svg.prepend(newDesc); } ariaDescribedBy.push(descId); } if (ariaLabelledBy.length > 0) { svg.setAttribute('aria-labelledby', ariaLabelledBy.join(' ')); } if (ariaDescribedBy.length > 0) { svg.setAttribute('aria-describedby', ariaDescribedBy.join(' ')); } try { beforeInjection(svg); } catch (error) { handleError(error); } }; SVGInjector(nonReactTarget, { afterEach: afterEach, beforeEach: beforeEach, cacheRequests: useRequestCache, evalScripts: evalScripts, httpRequestWithCredentials: httpRequestWithCredentials, renumerateIRIElements: renumerateIRIElements }); } }; _proto.removeSVG = function removeSVG() { var _this$nonReactWrapper; if ((_this$nonReactWrapper = this.nonReactWrapper) != null && _this$nonReactWrapper.parentNode) { this.nonReactWrapper.parentNode.removeChild(this.nonReactWrapper); this.nonReactWrapper = null; } }; _proto.componentDidMount = function componentDidMount() { this._isMounted = true; this.renderSVG(); }; _proto.componentDidUpdate = function componentDidUpdate(prevProps) { var _this3 = this; if (shallowDiffers(_extends({}, prevProps), this.props)) { this.setState(function () { return _this3.initialState; }, function () { _this3.removeSVG(); _this3.renderSVG(); }); } }; _proto.componentWillUnmount = function componentWillUnmount() { this._isMounted = false; this.removeSVG(); }; _proto.render = function render() { /* eslint-disable @typescript-eslint/no-unused-vars */ var _this$props2 = this.props; _this$props2.afterInjection; _this$props2.beforeInjection; _this$props2.desc; _this$props2.evalScripts; var Fallback = _this$props2.fallback; _this$props2.httpRequestWithCredentials; var Loading = _this$props2.loading; _this$props2.renumerateIRIElements; _this$props2.src; _this$props2.title; _this$props2.useRequestCache; var wrapper = _this$props2.wrapper, rest = _objectWithoutPropertiesLoose(_this$props2, _excluded); /* eslint-enable @typescript-eslint/no-unused-vars */ var Wrapper = wrapper; return /*#__PURE__*/React__namespace.createElement(Wrapper, _extends({}, rest, { ref: this.refCallback }, wrapper === 'svg' ? { xmlns: svgNamespace, xmlnsXlink: xlinkNamespace } : {}), this.state.isLoading && Loading && /*#__PURE__*/React__namespace.createElement(Loading, null), this.state.hasError && Fallback && /*#__PURE__*/React__namespace.createElement(Fallback, null)); }; return ReactSVG; }(React__namespace.Component); ReactSVG.defaultProps = { afterInjection: function afterInjection() { return undefined; }, beforeInjection: function beforeInjection() { return undefined; }, desc: '', evalScripts: 'never', fallback: null, httpRequestWithCredentials: false, loading: null, onError: function onError() { return undefined; }, renumerateIRIElements: true, title: '', useRequestCache: true, wrapper: 'div' }; ReactSVG.propTypes = { afterInjection: PropTypes__namespace.func, beforeInjection: PropTypes__namespace.func, desc: PropTypes__namespace.string, evalScripts: PropTypes__namespace.oneOf(['always', 'once', 'never']), fallback: PropTypes__namespace.oneOfType([PropTypes__namespace.func, PropTypes__namespace.object, PropTypes__namespace.string]), httpRequestWithCredentials: PropTypes__namespace.bool, loading: PropTypes__namespace.oneOfType([PropTypes__namespace.func, PropTypes__namespace.object, PropTypes__namespace.string]), onError: PropTypes__namespace.func, renumerateIRIElements: PropTypes__namespace.bool, src: PropTypes__namespace.string.isRequired, title: PropTypes__namespace.string, useRequestCache: PropTypes__namespace.bool, wrapper: PropTypes__namespace.oneOf(['div', 'span', 'svg']) }; exports.ReactSVG = ReactSVG; })); //# sourceMappingURL=react-svg.umd.development.js.map