react-inlinesvg 4.0.5 → 4.1.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +6 -3
- package/dist/index.d.ts +6 -3
- package/dist/index.js +268 -222
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +276 -222
- package/dist/index.mjs.map +1 -1
- package/dist/provider.js.map +1 -1
- package/dist/provider.mjs.map +1 -1
- package/package.json +22 -29
- package/src/cache.ts +15 -7
- package/src/helpers.ts +1 -2
- package/src/hooks.tsx +11 -0
- package/src/index.tsx +300 -253
- package/src/types.ts +20 -16
package/dist/index.d.mts
CHANGED
|
@@ -14,7 +14,7 @@ type ErrorCallback = (error: Error | FetchError) => void;
|
|
|
14
14
|
type LoadCallback = (src: string, isCached: boolean) => void;
|
|
15
15
|
type PlainObject<T = unknown> = Record<string, T>;
|
|
16
16
|
type PreProcessorCallback = (code: string) => string;
|
|
17
|
-
|
|
17
|
+
type Props = Simplify<Omit<React.SVGProps<SVGElement>, 'onLoad' | 'onError' | 'ref'> & {
|
|
18
18
|
baseURL?: string;
|
|
19
19
|
cacheRequests?: boolean;
|
|
20
20
|
children?: React.ReactNode;
|
|
@@ -29,7 +29,7 @@ interface Props extends Omit<React.SVGProps<SVGElement>, 'onLoad' | 'onError' |
|
|
|
29
29
|
title?: string | null;
|
|
30
30
|
uniqueHash?: string;
|
|
31
31
|
uniquifyIDs?: boolean;
|
|
32
|
-
}
|
|
32
|
+
}>;
|
|
33
33
|
interface State {
|
|
34
34
|
content: string;
|
|
35
35
|
element: React.ReactNode;
|
|
@@ -42,6 +42,9 @@ interface FetchError extends Error {
|
|
|
42
42
|
message: string;
|
|
43
43
|
type: string;
|
|
44
44
|
}
|
|
45
|
+
type Simplify<T> = {
|
|
46
|
+
[KeyType in keyof T]: T[KeyType];
|
|
47
|
+
} & {};
|
|
45
48
|
type Status = (typeof STATUS)[keyof typeof STATUS];
|
|
46
49
|
interface StorageItem {
|
|
47
50
|
content: string;
|
|
@@ -70,4 +73,4 @@ declare class CacheStore {
|
|
|
70
73
|
declare let cacheStore: CacheStore;
|
|
71
74
|
declare function InlineSVG(props: Props): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
|
|
72
75
|
|
|
73
|
-
export { ErrorCallback, FetchError, LoadCallback, PlainObject, PreProcessorCallback, Props, State, Status, StorageItem, cacheStore, InlineSVG as default };
|
|
76
|
+
export { ErrorCallback, FetchError, LoadCallback, PlainObject, PreProcessorCallback, Props, Simplify, State, Status, StorageItem, cacheStore, InlineSVG as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ type ErrorCallback = (error: Error | FetchError) => void;
|
|
|
14
14
|
type LoadCallback = (src: string, isCached: boolean) => void;
|
|
15
15
|
type PlainObject<T = unknown> = Record<string, T>;
|
|
16
16
|
type PreProcessorCallback = (code: string) => string;
|
|
17
|
-
|
|
17
|
+
type Props = Simplify<Omit<React.SVGProps<SVGElement>, 'onLoad' | 'onError' | 'ref'> & {
|
|
18
18
|
baseURL?: string;
|
|
19
19
|
cacheRequests?: boolean;
|
|
20
20
|
children?: React.ReactNode;
|
|
@@ -29,7 +29,7 @@ interface Props extends Omit<React.SVGProps<SVGElement>, 'onLoad' | 'onError' |
|
|
|
29
29
|
title?: string | null;
|
|
30
30
|
uniqueHash?: string;
|
|
31
31
|
uniquifyIDs?: boolean;
|
|
32
|
-
}
|
|
32
|
+
}>;
|
|
33
33
|
interface State {
|
|
34
34
|
content: string;
|
|
35
35
|
element: React.ReactNode;
|
|
@@ -42,6 +42,9 @@ interface FetchError extends Error {
|
|
|
42
42
|
message: string;
|
|
43
43
|
type: string;
|
|
44
44
|
}
|
|
45
|
+
type Simplify<T> = {
|
|
46
|
+
[KeyType in keyof T]: T[KeyType];
|
|
47
|
+
} & {};
|
|
45
48
|
type Status = (typeof STATUS)[keyof typeof STATUS];
|
|
46
49
|
interface StorageItem {
|
|
47
50
|
content: string;
|
|
@@ -70,5 +73,5 @@ declare class CacheStore {
|
|
|
70
73
|
declare let cacheStore: CacheStore;
|
|
71
74
|
declare function InlineSVG(props: Props): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
|
|
72
75
|
|
|
73
|
-
export { ErrorCallback, FetchError, LoadCallback, PlainObject, PreProcessorCallback, Props, State, Status, StorageItem, cacheStore, InlineSVG as default };
|
|
76
|
+
export { ErrorCallback, FetchError, LoadCallback, PlainObject, PreProcessorCallback, Props, Simplify, State, Status, StorageItem, cacheStore, InlineSVG as default };
|
|
74
77
|
export = InlineSVG
|
package/dist/index.js
CHANGED
|
@@ -39,7 +39,7 @@ __export(src_exports, {
|
|
|
39
39
|
default: () => InlineSVG
|
|
40
40
|
});
|
|
41
41
|
module.exports = __toCommonJS(src_exports);
|
|
42
|
-
var
|
|
42
|
+
var import_react2 = require("react");
|
|
43
43
|
var import_react_from_dom = __toESM(require("react-from-dom"));
|
|
44
44
|
|
|
45
45
|
// src/config.ts
|
|
@@ -124,13 +124,16 @@ var CacheStore = class {
|
|
|
124
124
|
let usePersistentCache = false;
|
|
125
125
|
if (canUseDOM()) {
|
|
126
126
|
cacheName = window.REACT_INLINESVG_CACHE_NAME ?? CACHE_NAME;
|
|
127
|
-
usePersistentCache = !!window.REACT_INLINESVG_PERSISTENT_CACHE;
|
|
127
|
+
usePersistentCache = !!window.REACT_INLINESVG_PERSISTENT_CACHE && "caches" in window;
|
|
128
128
|
}
|
|
129
129
|
if (usePersistentCache) {
|
|
130
130
|
caches.open(cacheName).then((cache) => {
|
|
131
131
|
this.cacheApi = cache;
|
|
132
132
|
this.isReady = true;
|
|
133
133
|
this.subscribers.forEach((callback) => callback());
|
|
134
|
+
}).catch((error) => {
|
|
135
|
+
this.isReady = true;
|
|
136
|
+
console.error(`Failed to open cache: ${error.message}`);
|
|
134
137
|
});
|
|
135
138
|
} else {
|
|
136
139
|
this.isReady = true;
|
|
@@ -235,267 +238,310 @@ var CacheStore = class {
|
|
|
235
238
|
}
|
|
236
239
|
};
|
|
237
240
|
|
|
241
|
+
// src/hooks.tsx
|
|
242
|
+
var import_react = require("react");
|
|
243
|
+
function usePrevious(state) {
|
|
244
|
+
const ref = (0, import_react.useRef)();
|
|
245
|
+
(0, import_react.useEffect)(() => {
|
|
246
|
+
ref.current = state;
|
|
247
|
+
});
|
|
248
|
+
return ref.current;
|
|
249
|
+
}
|
|
250
|
+
|
|
238
251
|
// src/index.tsx
|
|
239
252
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
240
253
|
var cacheStore;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const { fetchOptions, src } = this.props;
|
|
249
|
-
const content = await request(src, fetchOptions);
|
|
250
|
-
this.handleLoad(content);
|
|
251
|
-
});
|
|
252
|
-
__publicField(this, "handleError", (error) => {
|
|
253
|
-
const { onError } = this.props;
|
|
254
|
-
const status = error.message === "Browser does not support SVG" ? STATUS.UNSUPPORTED : STATUS.FAILED;
|
|
255
|
-
if (this.isActive) {
|
|
256
|
-
this.setState({ status }, () => {
|
|
257
|
-
if (typeof onError === "function") {
|
|
258
|
-
onError(error);
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
__publicField(this, "handleLoad", (content, hasCache = false) => {
|
|
264
|
-
if (this.isActive) {
|
|
265
|
-
this.setState(
|
|
266
|
-
{
|
|
267
|
-
content,
|
|
268
|
-
isCached: hasCache,
|
|
269
|
-
status: STATUS.LOADED
|
|
270
|
-
},
|
|
271
|
-
this.getElement
|
|
272
|
-
);
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
this.state = {
|
|
276
|
-
content: "",
|
|
277
|
-
element: null,
|
|
278
|
-
isCached: !!props.cacheRequests && cacheStore.isCached(props.src),
|
|
279
|
-
status: STATUS.IDLE
|
|
280
|
-
};
|
|
281
|
-
this.hash = props.uniqueHash ?? randomString(8);
|
|
254
|
+
function updateSVGAttributes(node, options) {
|
|
255
|
+
const { baseURL = "", hash, uniquifyIDs } = options;
|
|
256
|
+
const replaceableAttributes = ["id", "href", "xlink:href", "xlink:role", "xlink:arcrole"];
|
|
257
|
+
const linkAttributes = ["href", "xlink:href"];
|
|
258
|
+
const isDataValue = (name, value) => linkAttributes.includes(name) && (value ? !value.includes("#") : false);
|
|
259
|
+
if (!uniquifyIDs) {
|
|
260
|
+
return node;
|
|
282
261
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
try {
|
|
291
|
-
if (status === STATUS.IDLE) {
|
|
292
|
-
if (!isSupportedEnvironment()) {
|
|
293
|
-
throw new Error("Browser does not support SVG");
|
|
262
|
+
[...node.children].forEach((d) => {
|
|
263
|
+
if (d.attributes?.length) {
|
|
264
|
+
const attributes = Object.values(d.attributes).map((a) => {
|
|
265
|
+
const attribute = a;
|
|
266
|
+
const match = /url\((.*?)\)/.exec(a.value);
|
|
267
|
+
if (match?.[1]) {
|
|
268
|
+
attribute.value = a.value.replace(match[0], `url(${baseURL}${match[1]}__${hash})`);
|
|
294
269
|
}
|
|
295
|
-
|
|
296
|
-
|
|
270
|
+
return attribute;
|
|
271
|
+
});
|
|
272
|
+
replaceableAttributes.forEach((r) => {
|
|
273
|
+
const attribute = attributes.find((a) => a.name === r);
|
|
274
|
+
if (attribute && !isDataValue(r, attribute.value)) {
|
|
275
|
+
attribute.value = `${attribute.value}__${hash}`;
|
|
297
276
|
}
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
} catch (error) {
|
|
301
|
-
this.handleError(error);
|
|
277
|
+
});
|
|
302
278
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
componentDidUpdate(previousProps, previousState) {
|
|
306
|
-
if (!canUseDOM()) {
|
|
307
|
-
return;
|
|
279
|
+
if (d.children.length) {
|
|
280
|
+
return updateSVGAttributes(d, options);
|
|
308
281
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
282
|
+
return d;
|
|
283
|
+
});
|
|
284
|
+
return node;
|
|
285
|
+
}
|
|
286
|
+
function getNode(options) {
|
|
287
|
+
const {
|
|
288
|
+
baseURL,
|
|
289
|
+
content,
|
|
290
|
+
description,
|
|
291
|
+
handleError,
|
|
292
|
+
hash,
|
|
293
|
+
preProcessor,
|
|
294
|
+
title,
|
|
295
|
+
uniquifyIDs = false
|
|
296
|
+
} = options;
|
|
297
|
+
try {
|
|
298
|
+
const svgText = processSVG(content, preProcessor);
|
|
299
|
+
const node = (0, import_react_from_dom.default)(svgText, { nodeOnly: true });
|
|
300
|
+
if (!node || !(node instanceof SVGSVGElement)) {
|
|
301
|
+
throw new Error("Could not convert the src to a DOM Node");
|
|
315
302
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
303
|
+
const svg = updateSVGAttributes(node, { baseURL, hash, uniquifyIDs });
|
|
304
|
+
if (description) {
|
|
305
|
+
const originalDesc = svg.querySelector("desc");
|
|
306
|
+
if (originalDesc?.parentNode) {
|
|
307
|
+
originalDesc.parentNode.removeChild(originalDesc);
|
|
320
308
|
}
|
|
321
|
-
|
|
309
|
+
const descElement = document.createElementNS("http://www.w3.org/2000/svg", "desc");
|
|
310
|
+
descElement.innerHTML = description;
|
|
311
|
+
svg.prepend(descElement);
|
|
322
312
|
}
|
|
323
|
-
if (
|
|
324
|
-
|
|
313
|
+
if (typeof title !== "undefined") {
|
|
314
|
+
const originalTitle = svg.querySelector("title");
|
|
315
|
+
if (originalTitle?.parentNode) {
|
|
316
|
+
originalTitle.parentNode.removeChild(originalTitle);
|
|
317
|
+
}
|
|
318
|
+
if (title) {
|
|
319
|
+
const titleElement = document.createElementNS("http://www.w3.org/2000/svg", "title");
|
|
320
|
+
titleElement.innerHTML = title;
|
|
321
|
+
svg.prepend(titleElement);
|
|
322
|
+
}
|
|
325
323
|
}
|
|
324
|
+
return svg;
|
|
325
|
+
} catch (error) {
|
|
326
|
+
return handleError(error);
|
|
326
327
|
}
|
|
327
|
-
|
|
328
|
-
|
|
328
|
+
}
|
|
329
|
+
function processSVG(content, preProcessor) {
|
|
330
|
+
if (preProcessor) {
|
|
331
|
+
return preProcessor(content);
|
|
329
332
|
}
|
|
330
|
-
|
|
333
|
+
return content;
|
|
334
|
+
}
|
|
335
|
+
function ReactInlineSVG(props) {
|
|
336
|
+
const {
|
|
337
|
+
cacheRequests = true,
|
|
338
|
+
children = null,
|
|
339
|
+
description,
|
|
340
|
+
fetchOptions,
|
|
341
|
+
innerRef,
|
|
342
|
+
loader = null,
|
|
343
|
+
onError,
|
|
344
|
+
onLoad,
|
|
345
|
+
src,
|
|
346
|
+
title,
|
|
347
|
+
uniqueHash
|
|
348
|
+
} = props;
|
|
349
|
+
const [state, setState] = (0, import_react2.useReducer)(
|
|
350
|
+
(previousState2, nextState) => ({
|
|
351
|
+
...previousState2,
|
|
352
|
+
...nextState
|
|
353
|
+
}),
|
|
354
|
+
{
|
|
355
|
+
content: "",
|
|
356
|
+
element: null,
|
|
357
|
+
isCached: cacheRequests && cacheStore.isCached(props.src),
|
|
358
|
+
status: STATUS.IDLE
|
|
359
|
+
}
|
|
360
|
+
);
|
|
361
|
+
const { content, element, isCached, status } = state;
|
|
362
|
+
const previousProps = usePrevious(props);
|
|
363
|
+
const previousState = usePrevious(state);
|
|
364
|
+
const hash = (0, import_react2.useRef)(uniqueHash ?? randomString(8));
|
|
365
|
+
const isActive = (0, import_react2.useRef)(false);
|
|
366
|
+
const isInitialized = (0, import_react2.useRef)(false);
|
|
367
|
+
const handleError = (0, import_react2.useCallback)(
|
|
368
|
+
(error) => {
|
|
369
|
+
if (isActive.current) {
|
|
370
|
+
setState({
|
|
371
|
+
status: error.message === "Browser does not support SVG" ? STATUS.UNSUPPORTED : STATUS.FAILED
|
|
372
|
+
});
|
|
373
|
+
onError?.(error);
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
[onError]
|
|
377
|
+
);
|
|
378
|
+
const handleLoad = (0, import_react2.useCallback)((loadedContent, hasCache = false) => {
|
|
379
|
+
if (isActive.current) {
|
|
380
|
+
setState({
|
|
381
|
+
content: loadedContent,
|
|
382
|
+
isCached: hasCache,
|
|
383
|
+
status: STATUS.LOADED
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}, []);
|
|
387
|
+
const getElement = (0, import_react2.useCallback)(() => {
|
|
331
388
|
try {
|
|
332
|
-
const node =
|
|
333
|
-
const
|
|
334
|
-
if (!
|
|
389
|
+
const node = getNode({ ...props, handleError, hash: hash.current, content });
|
|
390
|
+
const convertedElement = (0, import_react_from_dom.default)(node);
|
|
391
|
+
if (!convertedElement || !(0, import_react2.isValidElement)(convertedElement)) {
|
|
335
392
|
throw new Error("Could not convert the src to a React element");
|
|
336
393
|
}
|
|
337
|
-
|
|
338
|
-
element,
|
|
394
|
+
setState({
|
|
395
|
+
element: convertedElement,
|
|
339
396
|
status: STATUS.READY
|
|
340
397
|
});
|
|
341
398
|
} catch (error) {
|
|
342
|
-
|
|
399
|
+
handleError(new Error(error.message));
|
|
400
|
+
}
|
|
401
|
+
}, [content, handleError, props]);
|
|
402
|
+
const fetchContent = (0, import_react2.useCallback)(async () => {
|
|
403
|
+
const responseContent = await request(src, fetchOptions);
|
|
404
|
+
handleLoad(responseContent);
|
|
405
|
+
}, [fetchOptions, handleLoad, src]);
|
|
406
|
+
const getContent = (0, import_react2.useCallback)(async () => {
|
|
407
|
+
const dataURI = /^data:image\/svg[^,]*?(;base64)?,(.*)/u.exec(src);
|
|
408
|
+
let inlineSrc;
|
|
409
|
+
if (dataURI) {
|
|
410
|
+
inlineSrc = dataURI[1] ? window.atob(dataURI[2]) : decodeURIComponent(dataURI[2]);
|
|
411
|
+
} else if (src.includes("<svg")) {
|
|
412
|
+
inlineSrc = src;
|
|
413
|
+
}
|
|
414
|
+
if (inlineSrc) {
|
|
415
|
+
handleLoad(inlineSrc);
|
|
416
|
+
return;
|
|
343
417
|
}
|
|
344
|
-
}
|
|
345
|
-
getNode() {
|
|
346
|
-
const { description, title } = this.props;
|
|
347
418
|
try {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
419
|
+
if (cacheRequests) {
|
|
420
|
+
const cachedContent = await cacheStore.get(src, fetchOptions);
|
|
421
|
+
handleLoad(cachedContent, true);
|
|
422
|
+
} else {
|
|
423
|
+
await fetchContent();
|
|
352
424
|
}
|
|
353
|
-
const svg = this.updateSVGAttributes(node);
|
|
354
|
-
if (description) {
|
|
355
|
-
const originalDesc = svg.querySelector("desc");
|
|
356
|
-
if (originalDesc?.parentNode) {
|
|
357
|
-
originalDesc.parentNode.removeChild(originalDesc);
|
|
358
|
-
}
|
|
359
|
-
const descElement = document.createElementNS("http://www.w3.org/2000/svg", "desc");
|
|
360
|
-
descElement.innerHTML = description;
|
|
361
|
-
svg.prepend(descElement);
|
|
362
|
-
}
|
|
363
|
-
if (typeof title !== "undefined") {
|
|
364
|
-
const originalTitle = svg.querySelector("title");
|
|
365
|
-
if (originalTitle?.parentNode) {
|
|
366
|
-
originalTitle.parentNode.removeChild(originalTitle);
|
|
367
|
-
}
|
|
368
|
-
if (title) {
|
|
369
|
-
const titleElement = document.createElementNS("http://www.w3.org/2000/svg", "title");
|
|
370
|
-
titleElement.innerHTML = title;
|
|
371
|
-
svg.prepend(titleElement);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
return svg;
|
|
375
425
|
} catch (error) {
|
|
376
|
-
|
|
426
|
+
handleError(error);
|
|
377
427
|
}
|
|
378
|
-
}
|
|
379
|
-
load() {
|
|
380
|
-
if (
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
if (
|
|
398
|
-
|
|
399
|
-
return;
|
|
428
|
+
}, [cacheRequests, fetchContent, fetchOptions, handleError, handleLoad, src]);
|
|
429
|
+
const load = (0, import_react2.useCallback)(async () => {
|
|
430
|
+
if (isActive.current) {
|
|
431
|
+
setState({
|
|
432
|
+
content: "",
|
|
433
|
+
element: null,
|
|
434
|
+
isCached: false,
|
|
435
|
+
status: STATUS.LOADING
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
}, []);
|
|
439
|
+
(0, import_react2.useEffect)(
|
|
440
|
+
() => {
|
|
441
|
+
isActive.current = true;
|
|
442
|
+
if (!canUseDOM() || isInitialized.current) {
|
|
443
|
+
return () => void 0;
|
|
444
|
+
}
|
|
445
|
+
try {
|
|
446
|
+
if (status === STATUS.IDLE) {
|
|
447
|
+
if (!isSupportedEnvironment()) {
|
|
448
|
+
throw new Error("Browser does not support SVG");
|
|
400
449
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
const content = await cacheStore.get(src, fetchOptions);
|
|
404
|
-
this.handleLoad(content, true);
|
|
405
|
-
} else {
|
|
406
|
-
await this.fetchContent();
|
|
407
|
-
}
|
|
408
|
-
} catch (error) {
|
|
409
|
-
this.handleError(error);
|
|
450
|
+
if (!src) {
|
|
451
|
+
throw new Error("Missing src");
|
|
410
452
|
}
|
|
453
|
+
load();
|
|
411
454
|
}
|
|
412
|
-
)
|
|
455
|
+
} catch (error) {
|
|
456
|
+
handleError(error);
|
|
457
|
+
}
|
|
458
|
+
isInitialized.current = true;
|
|
459
|
+
return () => {
|
|
460
|
+
isActive.current = false;
|
|
461
|
+
};
|
|
462
|
+
},
|
|
463
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
464
|
+
[]
|
|
465
|
+
);
|
|
466
|
+
(0, import_react2.useEffect)(() => {
|
|
467
|
+
if (!canUseDOM()) {
|
|
468
|
+
return;
|
|
413
469
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
const { content } = this.state;
|
|
417
|
-
const { preProcessor } = this.props;
|
|
418
|
-
if (preProcessor) {
|
|
419
|
-
return preProcessor(content);
|
|
470
|
+
if (!previousProps) {
|
|
471
|
+
return;
|
|
420
472
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
const replaceableAttributes = ["id", "href", "xlink:href", "xlink:role", "xlink:arcrole"];
|
|
426
|
-
const linkAttributes = ["href", "xlink:href"];
|
|
427
|
-
const isDataValue = (name, value) => linkAttributes.includes(name) && (value ? !value.includes("#") : false);
|
|
428
|
-
if (!uniquifyIDs) {
|
|
429
|
-
return node;
|
|
430
|
-
}
|
|
431
|
-
[...node.children].forEach((d) => {
|
|
432
|
-
if (d.attributes?.length) {
|
|
433
|
-
const attributes = Object.values(d.attributes).map((a) => {
|
|
434
|
-
const attribute = a;
|
|
435
|
-
const match = /url\((.*?)\)/.exec(a.value);
|
|
436
|
-
if (match?.[1]) {
|
|
437
|
-
attribute.value = a.value.replace(match[0], `url(${baseURL}${match[1]}__${this.hash})`);
|
|
438
|
-
}
|
|
439
|
-
return attribute;
|
|
440
|
-
});
|
|
441
|
-
replaceableAttributes.forEach((r) => {
|
|
442
|
-
const attribute = attributes.find((a) => a.name === r);
|
|
443
|
-
if (attribute && !isDataValue(r, attribute.value)) {
|
|
444
|
-
attribute.value = `${attribute.value}__${this.hash}`;
|
|
445
|
-
}
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
if (d.children.length) {
|
|
449
|
-
return this.updateSVGAttributes(d);
|
|
473
|
+
if (previousProps.src !== src) {
|
|
474
|
+
if (!src) {
|
|
475
|
+
handleError(new Error("Missing src"));
|
|
476
|
+
return;
|
|
450
477
|
}
|
|
451
|
-
|
|
452
|
-
})
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
"title",
|
|
472
|
-
"uniqueHash",
|
|
473
|
-
"uniquifyIDs"
|
|
474
|
-
);
|
|
475
|
-
if (!canUseDOM()) {
|
|
476
|
-
return loader;
|
|
478
|
+
load();
|
|
479
|
+
} else if (previousProps.title !== title || previousProps.description !== description) {
|
|
480
|
+
getElement();
|
|
481
|
+
}
|
|
482
|
+
}, [
|
|
483
|
+
description,
|
|
484
|
+
getElement,
|
|
485
|
+
handleError,
|
|
486
|
+
isCached,
|
|
487
|
+
load,
|
|
488
|
+
onLoad,
|
|
489
|
+
previousProps,
|
|
490
|
+
previousState,
|
|
491
|
+
src,
|
|
492
|
+
status,
|
|
493
|
+
title
|
|
494
|
+
]);
|
|
495
|
+
(0, import_react2.useEffect)(() => {
|
|
496
|
+
if (!previousState) {
|
|
497
|
+
return;
|
|
477
498
|
}
|
|
478
|
-
if (
|
|
479
|
-
|
|
499
|
+
if (previousState.status !== STATUS.LOADING && status === STATUS.LOADING) {
|
|
500
|
+
getContent();
|
|
480
501
|
}
|
|
481
|
-
if (
|
|
482
|
-
|
|
502
|
+
if (previousState.status !== STATUS.LOADED && status === STATUS.LOADED) {
|
|
503
|
+
getElement();
|
|
504
|
+
}
|
|
505
|
+
if (previousState.status !== STATUS.READY && status === STATUS.READY) {
|
|
506
|
+
onLoad?.(src, isCached);
|
|
483
507
|
}
|
|
508
|
+
}, [getContent, getElement, isCached, onLoad, previousState, src, status]);
|
|
509
|
+
const elementProps = omit(
|
|
510
|
+
props,
|
|
511
|
+
"baseURL",
|
|
512
|
+
"cacheRequests",
|
|
513
|
+
"children",
|
|
514
|
+
"description",
|
|
515
|
+
"fetchOptions",
|
|
516
|
+
"innerRef",
|
|
517
|
+
"loader",
|
|
518
|
+
"onError",
|
|
519
|
+
"onLoad",
|
|
520
|
+
"preProcessor",
|
|
521
|
+
"src",
|
|
522
|
+
"title",
|
|
523
|
+
"uniqueHash",
|
|
524
|
+
"uniquifyIDs"
|
|
525
|
+
);
|
|
526
|
+
if (!canUseDOM()) {
|
|
484
527
|
return loader;
|
|
485
528
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
529
|
+
if (element) {
|
|
530
|
+
return (0, import_react2.cloneElement)(element, { ref: innerRef, ...elementProps });
|
|
531
|
+
}
|
|
532
|
+
if ([STATUS.UNSUPPORTED, STATUS.FAILED].includes(status)) {
|
|
533
|
+
return children;
|
|
534
|
+
}
|
|
535
|
+
return loader;
|
|
536
|
+
}
|
|
491
537
|
function InlineSVG(props) {
|
|
492
538
|
if (!cacheStore) {
|
|
493
539
|
cacheStore = new CacheStore();
|
|
494
540
|
}
|
|
495
541
|
const { loader } = props;
|
|
496
|
-
const hasCallback =
|
|
497
|
-
const [isReady, setReady] =
|
|
498
|
-
|
|
542
|
+
const hasCallback = (0, import_react2.useRef)(false);
|
|
543
|
+
const [isReady, setReady] = (0, import_react2.useState)(cacheStore.isReady);
|
|
544
|
+
(0, import_react2.useEffect)(() => {
|
|
499
545
|
if (!hasCallback.current) {
|
|
500
546
|
cacheStore.onReady(() => {
|
|
501
547
|
setReady(true);
|