@malaya_jeeva/rich-text-editor 1.0.7 → 1.0.9
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.js +47 -6
- package/dist/index.mjs +47 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -66,7 +66,7 @@ var PALETTE = [
|
|
|
66
66
|
];
|
|
67
67
|
var CSS = `
|
|
68
68
|
*{box-sizing:border-box;}
|
|
69
|
-
.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:1px;padding:4px 8px;background:#f8f8f8;border-bottom:1px solid #e0e0e0;}
|
|
69
|
+
.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:1px;padding:4px 8px;background:#f8f8f8;border-bottom:1px solid #e0e0e0;position: sticky;top: 0;z-index: 9;}
|
|
70
70
|
@media(prefers-color-scheme:dark){.rte-toolbar{background:#1e1e1e;border-color:#333;}}
|
|
71
71
|
.rte-btn{background:transparent;border:none;border-radius:3px;cursor:pointer;height:30px;min-width:30px;padding:0 6px;color:#444;font-size:13px;font-weight:500;font-family:var(--font-sans);display:inline-flex;align-items:center;justify-content:center;user-select:none;white-space:nowrap;transition:background 0.1s;flex-shrink:0;}
|
|
72
72
|
.rte-btn:hover{background:#e8e8e8;}.rte-btn.active{background:#d0e4ff;color:#1a5fb4;}
|
|
@@ -170,6 +170,12 @@ var CSS = `
|
|
|
170
170
|
.rte-ie-apply{flex:1;height:26px;background:#1a6fc4;color:#fff;border:none;border-radius:4px;font-size:11px;font-weight:600;cursor:pointer;}
|
|
171
171
|
.rte-ie-remove{flex:1;height:26px;background:#fdecea;color:#c0392b;border:1px solid #f5c6c2;border-radius:4px;font-size:11px;cursor:pointer;}
|
|
172
172
|
.rte-handle{position:absolute;width:10px;height:10px;background:#fff;border:2px solid #1a5fb4;border-radius:2px;pointer-events:all;z-index:53;}
|
|
173
|
+
.customeditor {
|
|
174
|
+
max-height: 350px;
|
|
175
|
+
overflow-y: auto;
|
|
176
|
+
position: relative;
|
|
177
|
+
}
|
|
178
|
+
|
|
173
179
|
`;
|
|
174
180
|
|
|
175
181
|
// src/rte/utils.ts
|
|
@@ -218,7 +224,42 @@ function getColorAtCursor(editor) {
|
|
|
218
224
|
}
|
|
219
225
|
return "#000000";
|
|
220
226
|
}
|
|
227
|
+
function sanitizeScriptTags(html) {
|
|
228
|
+
const div = document.createElement("div");
|
|
229
|
+
div.innerHTML = html;
|
|
230
|
+
div.querySelectorAll("script").forEach((script) => script.remove());
|
|
231
|
+
const riskyAttrs = [
|
|
232
|
+
"onabort",
|
|
233
|
+
"onblur",
|
|
234
|
+
"onchange",
|
|
235
|
+
"onclick",
|
|
236
|
+
"ondblclick",
|
|
237
|
+
"onerror",
|
|
238
|
+
"onfocus",
|
|
239
|
+
"onkeydown",
|
|
240
|
+
"onkeypress",
|
|
241
|
+
"onkeyup",
|
|
242
|
+
"onload",
|
|
243
|
+
"onmousedown",
|
|
244
|
+
"onmousemove",
|
|
245
|
+
"onmouseout",
|
|
246
|
+
"onmouseover",
|
|
247
|
+
"onmouseup",
|
|
248
|
+
"onresize",
|
|
249
|
+
"onscroll",
|
|
250
|
+
"onselect",
|
|
251
|
+
"onsubmit",
|
|
252
|
+
"onunload"
|
|
253
|
+
];
|
|
254
|
+
div.querySelectorAll("*").forEach((el) => {
|
|
255
|
+
riskyAttrs.forEach((attr) => {
|
|
256
|
+
if (el.hasAttribute(attr)) el.removeAttribute(attr);
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
return div.innerHTML;
|
|
260
|
+
}
|
|
221
261
|
function prettifyHtml(html) {
|
|
262
|
+
const cleanHtml = sanitizeScriptTags(html);
|
|
222
263
|
const INLINE = /* @__PURE__ */ new Set(["a", "b", "i", "u", "em", "strong", "span", "code", "br", "small", "sub", "sup"]);
|
|
223
264
|
let indent = 0;
|
|
224
265
|
const pad = () => " ".repeat(indent);
|
|
@@ -1201,8 +1242,8 @@ function RichTextEditor({ value, onChange, toolbar }) {
|
|
|
1201
1242
|
else setLinkInfoFP(null);
|
|
1202
1243
|
const txt = (_b = (_a2 = editorRef.current) == null ? void 0 : _a2.innerText) != null ? _b : "";
|
|
1203
1244
|
setWords(txt.trim() ? txt.trim().split(/\s+/).length : 0);
|
|
1204
|
-
onChange == null ? void 0 : onChange((_d = (_c = editorRef.current) == null ? void 0 : _c.innerHTML) != null ? _d : "");
|
|
1205
|
-
}, [onChange, calcFloat, linkBar]);
|
|
1245
|
+
onChange == null ? void 0 : onChange(sanitizeScriptTags((_d = (_c = editorRef.current) == null ? void 0 : _c.innerHTML) != null ? _d : ""));
|
|
1246
|
+
}, [onChange, calcFloat, linkBar, sanitizeScriptTags]);
|
|
1206
1247
|
const exec = (0, import_react5.useCallback)((cmd, val = null) => {
|
|
1207
1248
|
var _a2;
|
|
1208
1249
|
(_a2 = editorRef.current) == null ? void 0 : _a2.focus();
|
|
@@ -1443,7 +1484,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
|
|
|
1443
1484
|
setIsCode(true);
|
|
1444
1485
|
};
|
|
1445
1486
|
const toVisual = () => {
|
|
1446
|
-
if (editorRef.current) editorRef.current.innerHTML = codeVal;
|
|
1487
|
+
if (editorRef.current) editorRef.current.innerHTML = sanitizeScriptTags(codeVal);
|
|
1447
1488
|
setIsCode(false);
|
|
1448
1489
|
refresh();
|
|
1449
1490
|
};
|
|
@@ -1454,7 +1495,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
|
|
|
1454
1495
|
};
|
|
1455
1496
|
(0, import_react5.useEffect)(() => {
|
|
1456
1497
|
if (editorRef.current) {
|
|
1457
|
-
editorRef.current.innerHTML = value != null ? value : "<p>Start writing here...</p>";
|
|
1498
|
+
editorRef.current.innerHTML = sanitizeScriptTags(value != null ? value : "<p>Start writing here...</p>");
|
|
1458
1499
|
refresh();
|
|
1459
1500
|
}
|
|
1460
1501
|
}, []);
|
|
@@ -1464,7 +1505,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
|
|
|
1464
1505
|
const show = (key) => !toolbar || toolbar.includes(key);
|
|
1465
1506
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { padding: "1rem 0" }, children: [
|
|
1466
1507
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: CSS }),
|
|
1467
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { border: "1px solid #d8d8d8", borderRadius: 4, boxShadow: "0 1px 3px rgba(0,0,0,0.06)" }, children: [
|
|
1508
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "customeditor", style: { border: "1px solid #d8d8d8", borderRadius: 4, boxShadow: "0 1px 3px rgba(0,0,0,0.06)" }, children: [
|
|
1468
1509
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rte-toolbar", children: [
|
|
1469
1510
|
!isCode && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1470
1511
|
show("bold") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("bold"), title: "Bold (Ctrl+B)", active: fmt.bold, style: { fontWeight: 800, fontFamily: "Georgia,serif" }, children: "B" }),
|
package/dist/index.mjs
CHANGED
|
@@ -45,7 +45,7 @@ var PALETTE = [
|
|
|
45
45
|
];
|
|
46
46
|
var CSS = `
|
|
47
47
|
*{box-sizing:border-box;}
|
|
48
|
-
.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:1px;padding:4px 8px;background:#f8f8f8;border-bottom:1px solid #e0e0e0;}
|
|
48
|
+
.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:1px;padding:4px 8px;background:#f8f8f8;border-bottom:1px solid #e0e0e0;position: sticky;top: 0;z-index: 9;}
|
|
49
49
|
@media(prefers-color-scheme:dark){.rte-toolbar{background:#1e1e1e;border-color:#333;}}
|
|
50
50
|
.rte-btn{background:transparent;border:none;border-radius:3px;cursor:pointer;height:30px;min-width:30px;padding:0 6px;color:#444;font-size:13px;font-weight:500;font-family:var(--font-sans);display:inline-flex;align-items:center;justify-content:center;user-select:none;white-space:nowrap;transition:background 0.1s;flex-shrink:0;}
|
|
51
51
|
.rte-btn:hover{background:#e8e8e8;}.rte-btn.active{background:#d0e4ff;color:#1a5fb4;}
|
|
@@ -149,6 +149,12 @@ var CSS = `
|
|
|
149
149
|
.rte-ie-apply{flex:1;height:26px;background:#1a6fc4;color:#fff;border:none;border-radius:4px;font-size:11px;font-weight:600;cursor:pointer;}
|
|
150
150
|
.rte-ie-remove{flex:1;height:26px;background:#fdecea;color:#c0392b;border:1px solid #f5c6c2;border-radius:4px;font-size:11px;cursor:pointer;}
|
|
151
151
|
.rte-handle{position:absolute;width:10px;height:10px;background:#fff;border:2px solid #1a5fb4;border-radius:2px;pointer-events:all;z-index:53;}
|
|
152
|
+
.customeditor {
|
|
153
|
+
max-height: 350px;
|
|
154
|
+
overflow-y: auto;
|
|
155
|
+
position: relative;
|
|
156
|
+
}
|
|
157
|
+
|
|
152
158
|
`;
|
|
153
159
|
|
|
154
160
|
// src/rte/utils.ts
|
|
@@ -197,7 +203,42 @@ function getColorAtCursor(editor) {
|
|
|
197
203
|
}
|
|
198
204
|
return "#000000";
|
|
199
205
|
}
|
|
206
|
+
function sanitizeScriptTags(html) {
|
|
207
|
+
const div = document.createElement("div");
|
|
208
|
+
div.innerHTML = html;
|
|
209
|
+
div.querySelectorAll("script").forEach((script) => script.remove());
|
|
210
|
+
const riskyAttrs = [
|
|
211
|
+
"onabort",
|
|
212
|
+
"onblur",
|
|
213
|
+
"onchange",
|
|
214
|
+
"onclick",
|
|
215
|
+
"ondblclick",
|
|
216
|
+
"onerror",
|
|
217
|
+
"onfocus",
|
|
218
|
+
"onkeydown",
|
|
219
|
+
"onkeypress",
|
|
220
|
+
"onkeyup",
|
|
221
|
+
"onload",
|
|
222
|
+
"onmousedown",
|
|
223
|
+
"onmousemove",
|
|
224
|
+
"onmouseout",
|
|
225
|
+
"onmouseover",
|
|
226
|
+
"onmouseup",
|
|
227
|
+
"onresize",
|
|
228
|
+
"onscroll",
|
|
229
|
+
"onselect",
|
|
230
|
+
"onsubmit",
|
|
231
|
+
"onunload"
|
|
232
|
+
];
|
|
233
|
+
div.querySelectorAll("*").forEach((el) => {
|
|
234
|
+
riskyAttrs.forEach((attr) => {
|
|
235
|
+
if (el.hasAttribute(attr)) el.removeAttribute(attr);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
return div.innerHTML;
|
|
239
|
+
}
|
|
200
240
|
function prettifyHtml(html) {
|
|
241
|
+
const cleanHtml = sanitizeScriptTags(html);
|
|
201
242
|
const INLINE = /* @__PURE__ */ new Set(["a", "b", "i", "u", "em", "strong", "span", "code", "br", "small", "sub", "sup"]);
|
|
202
243
|
let indent = 0;
|
|
203
244
|
const pad = () => " ".repeat(indent);
|
|
@@ -1180,8 +1221,8 @@ function RichTextEditor({ value, onChange, toolbar }) {
|
|
|
1180
1221
|
else setLinkInfoFP(null);
|
|
1181
1222
|
const txt = (_b = (_a2 = editorRef.current) == null ? void 0 : _a2.innerText) != null ? _b : "";
|
|
1182
1223
|
setWords(txt.trim() ? txt.trim().split(/\s+/).length : 0);
|
|
1183
|
-
onChange == null ? void 0 : onChange((_d = (_c = editorRef.current) == null ? void 0 : _c.innerHTML) != null ? _d : "");
|
|
1184
|
-
}, [onChange, calcFloat, linkBar]);
|
|
1224
|
+
onChange == null ? void 0 : onChange(sanitizeScriptTags((_d = (_c = editorRef.current) == null ? void 0 : _c.innerHTML) != null ? _d : ""));
|
|
1225
|
+
}, [onChange, calcFloat, linkBar, sanitizeScriptTags]);
|
|
1185
1226
|
const exec = useCallback3((cmd, val = null) => {
|
|
1186
1227
|
var _a2;
|
|
1187
1228
|
(_a2 = editorRef.current) == null ? void 0 : _a2.focus();
|
|
@@ -1422,7 +1463,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
|
|
|
1422
1463
|
setIsCode(true);
|
|
1423
1464
|
};
|
|
1424
1465
|
const toVisual = () => {
|
|
1425
|
-
if (editorRef.current) editorRef.current.innerHTML = codeVal;
|
|
1466
|
+
if (editorRef.current) editorRef.current.innerHTML = sanitizeScriptTags(codeVal);
|
|
1426
1467
|
setIsCode(false);
|
|
1427
1468
|
refresh();
|
|
1428
1469
|
};
|
|
@@ -1433,7 +1474,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
|
|
|
1433
1474
|
};
|
|
1434
1475
|
useEffect3(() => {
|
|
1435
1476
|
if (editorRef.current) {
|
|
1436
|
-
editorRef.current.innerHTML = value != null ? value : "<p>Start writing here...</p>";
|
|
1477
|
+
editorRef.current.innerHTML = sanitizeScriptTags(value != null ? value : "<p>Start writing here...</p>");
|
|
1437
1478
|
refresh();
|
|
1438
1479
|
}
|
|
1439
1480
|
}, []);
|
|
@@ -1443,7 +1484,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
|
|
|
1443
1484
|
const show = (key) => !toolbar || toolbar.includes(key);
|
|
1444
1485
|
return /* @__PURE__ */ jsxs6("div", { style: { padding: "1rem 0" }, children: [
|
|
1445
1486
|
/* @__PURE__ */ jsx7("style", { children: CSS }),
|
|
1446
|
-
/* @__PURE__ */ jsxs6("div", { style: { border: "1px solid #d8d8d8", borderRadius: 4, boxShadow: "0 1px 3px rgba(0,0,0,0.06)" }, children: [
|
|
1487
|
+
/* @__PURE__ */ jsxs6("div", { className: "customeditor", style: { border: "1px solid #d8d8d8", borderRadius: 4, boxShadow: "0 1px 3px rgba(0,0,0,0.06)" }, children: [
|
|
1447
1488
|
/* @__PURE__ */ jsxs6("div", { className: "rte-toolbar", children: [
|
|
1448
1489
|
!isCode && /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1449
1490
|
show("bold") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("bold"), title: "Bold (Ctrl+B)", active: fmt.bold, style: { fontWeight: 800, fontFamily: "Georgia,serif" }, children: "B" }),
|