@flozy/editor 3.4.9 → 3.5.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.
|
@@ -15,6 +15,12 @@ import { allowedDomains, decodeString } from "../../utils/helper";
|
|
|
15
15
|
// };
|
|
16
16
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
17
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
const getCode = (embedData, isEncoded) => {
|
|
19
|
+
if (isEncoded) {
|
|
20
|
+
return decodeString(embedData);
|
|
21
|
+
}
|
|
22
|
+
return embedData;
|
|
23
|
+
};
|
|
18
24
|
const Code = props => {
|
|
19
25
|
const codeRef = useRef();
|
|
20
26
|
const {
|
|
@@ -24,17 +30,20 @@ const Code = props => {
|
|
|
24
30
|
} = props;
|
|
25
31
|
const {
|
|
26
32
|
embedData,
|
|
27
|
-
isEncoded
|
|
33
|
+
isEncoded,
|
|
34
|
+
isSanitized
|
|
28
35
|
} = element;
|
|
29
36
|
useEffect(() => {
|
|
30
37
|
if (codeRef?.current) {
|
|
31
|
-
const
|
|
38
|
+
const code = getCode(embedData, isEncoded);
|
|
39
|
+
const clean = isSanitized ? code : sanitizeHtml(code, {
|
|
32
40
|
allowedTags: false,
|
|
33
41
|
// Allow all tags
|
|
34
42
|
allowedAttributes: false,
|
|
35
43
|
// Allow all attributes
|
|
36
|
-
allowedScriptDomains: allowedDomains
|
|
44
|
+
allowedScriptDomains: allowedDomains // for old code's that are already inserted without sanitization
|
|
37
45
|
});
|
|
46
|
+
|
|
38
47
|
const slotHtml = document.createRange().createContextualFragment(clean); // Create a 'tiny' document and parse the html string
|
|
39
48
|
codeRef.current.innerHTML = ""; // Clear the container
|
|
40
49
|
codeRef.current.appendChild(slotHtml);
|
|
@@ -1,26 +1,66 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
2
|
import ToolbarIcon from "../../common/ToolbarIcon";
|
|
3
3
|
import Icon from "../../common/Icon";
|
|
4
|
-
import { Button, Dialog, DialogActions, DialogContent, DialogTitle } from "@mui/material";
|
|
4
|
+
import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Tooltip } from "@mui/material";
|
|
5
5
|
import { insertEmbedScript } from "../../utils/embedScript";
|
|
6
|
+
import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
|
|
6
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
8
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
9
|
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
9
10
|
const EmbedScript = props => {
|
|
10
11
|
const {
|
|
11
12
|
editor,
|
|
12
|
-
icoBtnType
|
|
13
|
+
icoBtnType,
|
|
14
|
+
customProps
|
|
13
15
|
} = props;
|
|
14
16
|
const [open, setOpen] = useState(false);
|
|
15
17
|
const [code, setCode] = useState("");
|
|
18
|
+
const [apiStatus, setApiStatus] = useState({
|
|
19
|
+
loading: false,
|
|
20
|
+
error: false
|
|
21
|
+
});
|
|
22
|
+
const [allowedDomains, setAllowedDomains] = useState([]);
|
|
23
|
+
const {
|
|
24
|
+
loading,
|
|
25
|
+
error
|
|
26
|
+
} = apiStatus;
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
customProps.services("allowedDomains", {}).then(data => {
|
|
29
|
+
setAllowedDomains(data?.data || []);
|
|
30
|
+
}).catch(err => {
|
|
31
|
+
console.log(err);
|
|
32
|
+
});
|
|
33
|
+
}, []);
|
|
34
|
+
const updateApiStatus = update => {
|
|
35
|
+
setApiStatus(prev => ({
|
|
36
|
+
...prev,
|
|
37
|
+
...update
|
|
38
|
+
}));
|
|
39
|
+
};
|
|
16
40
|
const handleChange = e => {
|
|
17
41
|
setCode(e.target.value);
|
|
18
42
|
};
|
|
19
43
|
const handleClick = () => {
|
|
20
44
|
setOpen(true);
|
|
21
45
|
};
|
|
22
|
-
const onSubmit = () => {
|
|
23
|
-
|
|
46
|
+
const onSubmit = async () => {
|
|
47
|
+
updateApiStatus({
|
|
48
|
+
loading: true
|
|
49
|
+
});
|
|
50
|
+
const result = await customProps.services("validateCode", {
|
|
51
|
+
code
|
|
52
|
+
});
|
|
53
|
+
const {
|
|
54
|
+
error,
|
|
55
|
+
sanitizedCode
|
|
56
|
+
} = result?.data || {};
|
|
57
|
+
updateApiStatus({
|
|
58
|
+
loading: false,
|
|
59
|
+
error
|
|
60
|
+
});
|
|
61
|
+
if (!error) {
|
|
62
|
+
insertEmbedScript(editor, sanitizedCode || "");
|
|
63
|
+
}
|
|
24
64
|
};
|
|
25
65
|
const onCancel = () => {
|
|
26
66
|
setOpen(false);
|
|
@@ -37,9 +77,37 @@ const EmbedScript = props => {
|
|
|
37
77
|
open: open,
|
|
38
78
|
fullWidth: true,
|
|
39
79
|
children: [/*#__PURE__*/_jsx(DialogTitle, {
|
|
40
|
-
children:
|
|
41
|
-
|
|
42
|
-
|
|
80
|
+
children: /*#__PURE__*/_jsxs(Box, {
|
|
81
|
+
component: "div",
|
|
82
|
+
sx: {
|
|
83
|
+
display: "flex",
|
|
84
|
+
alignItems: "center",
|
|
85
|
+
gap: "6px"
|
|
86
|
+
},
|
|
87
|
+
children: ["Embed Code", allowedDomains?.length ? /*#__PURE__*/_jsx(Tooltip, {
|
|
88
|
+
title: /*#__PURE__*/_jsxs(Box, {
|
|
89
|
+
sx: {
|
|
90
|
+
textTransform: "none"
|
|
91
|
+
},
|
|
92
|
+
children: [/*#__PURE__*/_jsx("span", {
|
|
93
|
+
style: {
|
|
94
|
+
fontWeight: "bold"
|
|
95
|
+
},
|
|
96
|
+
children: "Allowed Domains"
|
|
97
|
+
}), /*#__PURE__*/_jsx("br", {}), allowedDomains.join(", ")]
|
|
98
|
+
}),
|
|
99
|
+
children: /*#__PURE__*/_jsx(InfoOutlinedIcon, {
|
|
100
|
+
color: "gray",
|
|
101
|
+
fontSize: "14px",
|
|
102
|
+
style: {
|
|
103
|
+
fill: "#94A3B8",
|
|
104
|
+
cursor: "pointer"
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
}) : null]
|
|
108
|
+
})
|
|
109
|
+
}), /*#__PURE__*/_jsxs(DialogContent, {
|
|
110
|
+
children: [/*#__PURE__*/_jsx("textarea", {
|
|
43
111
|
value: code,
|
|
44
112
|
onChange: handleChange,
|
|
45
113
|
style: {
|
|
@@ -49,11 +117,16 @@ const EmbedScript = props => {
|
|
|
49
117
|
padding: "4px",
|
|
50
118
|
boxSizing: "border-box"
|
|
51
119
|
}
|
|
52
|
-
})
|
|
120
|
+
}), /*#__PURE__*/_jsx(Box, {
|
|
121
|
+
component: "div",
|
|
122
|
+
color: "red",
|
|
123
|
+
children: error ? "There was some error on this code." : ""
|
|
124
|
+
})]
|
|
53
125
|
}), /*#__PURE__*/_jsxs(DialogActions, {
|
|
54
126
|
children: [/*#__PURE__*/_jsx(Button, {
|
|
55
127
|
onClick: onSubmit,
|
|
56
|
-
|
|
128
|
+
disabled: loading,
|
|
129
|
+
children: loading ? "Validating" : "Save"
|
|
57
130
|
}), /*#__PURE__*/_jsx(Button, {
|
|
58
131
|
onClick: onCancel,
|
|
59
132
|
children: "Cancel"
|
|
@@ -31,7 +31,11 @@ const FormNumbers = props => {
|
|
|
31
31
|
component: "input",
|
|
32
32
|
...rest,
|
|
33
33
|
type: "number",
|
|
34
|
+
inputProps: {
|
|
35
|
+
min: 0
|
|
36
|
+
},
|
|
34
37
|
onChange: onChange,
|
|
38
|
+
onWheel: e => e.target.blur(),
|
|
35
39
|
sx: {
|
|
36
40
|
width: "100%",
|
|
37
41
|
border: `1px solid ${borderColor || "#FFF"}`,
|
|
@@ -46,9 +50,17 @@ const FormNumbers = props => {
|
|
|
46
50
|
},
|
|
47
51
|
borderStyle: borderStyle || "solid",
|
|
48
52
|
color: textColor || "#000",
|
|
49
|
-
background: bgColor || "transparent"
|
|
53
|
+
background: bgColor || "transparent",
|
|
54
|
+
'&::-webkit-outer-spin-button, &::-webkit-inner-spin-button': {
|
|
55
|
+
'-webkit-appearance': 'none',
|
|
56
|
+
margin: 0
|
|
57
|
+
},
|
|
58
|
+
'&[type=number]': {
|
|
59
|
+
'-moz-appearance': 'textfield' // Hide spin buttons for Firefox
|
|
60
|
+
}
|
|
50
61
|
}
|
|
51
62
|
})
|
|
52
63
|
});
|
|
53
64
|
};
|
|
65
|
+
|
|
54
66
|
export default FormNumbers;
|
|
@@ -7,7 +7,9 @@ export const createEmbedScript = embedData => ({
|
|
|
7
7
|
children: [{
|
|
8
8
|
text: " "
|
|
9
9
|
}],
|
|
10
|
-
isEncoded: true
|
|
10
|
+
isEncoded: true,
|
|
11
|
+
// to handle the old code's that already inserted
|
|
12
|
+
isSanitized: true // to handle the old code's that already inserted
|
|
11
13
|
});
|
|
12
14
|
|
|
13
15
|
export const insertEmbedScript = (editor, embedData) => {
|