@pdfme/ui 5.4.2-dev.3 → 5.4.3-dev.1
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.es.js +20 -7
- package/dist/index.umd.js +2 -2
- package/package.json +1 -1
- package/src/components/Designer/PluginIcon.tsx +53 -21
package/package.json
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { useContext } from 'react';
|
1
|
+
import React, { useContext, useMemo } from 'react';
|
2
2
|
import { Plugin, Schema } from '@pdfme/common';
|
3
3
|
import { OptionsContext } from '../../contexts.js';
|
4
4
|
import { theme } from 'antd';
|
@@ -10,27 +10,62 @@ interface PluginIconProps {
|
|
10
10
|
styles?: React.CSSProperties;
|
11
11
|
}
|
12
12
|
|
13
|
-
const
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
) => {
|
19
|
-
const
|
20
|
-
|
13
|
+
const SVGIcon = ({ svgString, size, styles, label }: {
|
14
|
+
svgString: string;
|
15
|
+
size?: number;
|
16
|
+
styles?: React.CSSProperties;
|
17
|
+
label: string;
|
18
|
+
}) => {
|
19
|
+
const processedSVG = useMemo(() => {
|
20
|
+
const parser = new DOMParser();
|
21
|
+
const doc = parser.parseFromString(svgString, 'image/svg+xml');
|
22
|
+
|
23
|
+
const svgElement = doc.querySelector('svg');
|
24
|
+
if (!svgElement) {
|
25
|
+
return null;
|
26
|
+
}
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
node.setAttribute('height', size.toString());
|
28
|
+
if (size) {
|
29
|
+
svgElement.setAttribute('width', size.toString());
|
30
|
+
svgElement.setAttribute('height', size.toString());
|
26
31
|
}
|
27
|
-
Array.from(node.children).forEach((child) => modifyNode(child as HTMLElement));
|
28
|
-
};
|
29
32
|
|
30
|
-
|
33
|
+
// Sanitize SVG by removing script tags and event handlers
|
34
|
+
const scripts = svgElement.querySelectorAll('script');
|
35
|
+
scripts.forEach(script => script.remove());
|
36
|
+
|
37
|
+
const allElements = svgElement.querySelectorAll('*');
|
38
|
+
allElements.forEach(element => {
|
39
|
+
Array.from(element.attributes).forEach(attr => {
|
40
|
+
const attrValue = attr.value.trim().toLowerCase();
|
41
|
+
if (
|
42
|
+
attr.name.startsWith('on') ||
|
43
|
+
(
|
44
|
+
attr.name === 'href' && (
|
45
|
+
attrValue.startsWith('javascript:') ||
|
46
|
+
attrValue.startsWith('data:') ||
|
47
|
+
attrValue.startsWith('vbscript:')
|
48
|
+
)
|
49
|
+
)
|
50
|
+
) {
|
51
|
+
element.removeAttribute(attr.name);
|
52
|
+
}
|
53
|
+
});
|
54
|
+
});
|
55
|
+
|
56
|
+
return svgElement.outerHTML;
|
57
|
+
}, [svgString, size]);
|
58
|
+
|
59
|
+
if (!processedSVG) {
|
60
|
+
return null;
|
61
|
+
}
|
31
62
|
|
32
63
|
return (
|
33
|
-
<div
|
64
|
+
<div
|
65
|
+
style={styles}
|
66
|
+
title={label}
|
67
|
+
dangerouslySetInnerHTML={{ __html: processedSVG }}
|
68
|
+
/>
|
34
69
|
);
|
35
70
|
};
|
36
71
|
|
@@ -50,10 +85,7 @@ const PluginIcon = (props: PluginIconProps) => {
|
|
50
85
|
};
|
51
86
|
|
52
87
|
if (icon) {
|
53
|
-
|
54
|
-
return getWithModifiedSize(icon, label, size, iconStyles);
|
55
|
-
}
|
56
|
-
return <div style={iconStyles} title={label} dangerouslySetInnerHTML={{ __html: icon }} />;
|
88
|
+
return <SVGIcon svgString={icon} size={size} styles={iconStyles} label={label} />;
|
57
89
|
}
|
58
90
|
|
59
91
|
return (
|