@flozy/editor 1.2.1 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
@@ -9,6 +9,7 @@ import withCommon from "./hooks/withCommon";
|
|
9
9
|
import withCollaborative from "./hooks/withCollaborative";
|
10
10
|
import CommonEditor from "./CommonEditor";
|
11
11
|
import { jsx as _jsx } from "react/jsx-runtime";
|
12
|
+
import { Fragment as _Fragment } from "react/jsx-runtime";
|
12
13
|
const CollaborativeEditor = props => {
|
13
14
|
const editorRef = useRef(null);
|
14
15
|
const {
|
@@ -108,6 +109,17 @@ const CollaborativeEditor = props => {
|
|
108
109
|
setConnected(false);
|
109
110
|
setMessage("Seems your connection is lost... Reload the page to edit the document...");
|
110
111
|
});
|
112
|
+
|
113
|
+
// const getContent = () => {
|
114
|
+
// console.log(editorRef.current.getContent());
|
115
|
+
// };
|
116
|
+
|
117
|
+
// const insertFragments = () => {
|
118
|
+
// editorRef.current.insertFragments([
|
119
|
+
// { type: "paragraph", children: [{ text: "some fragements to inss" }] },
|
120
|
+
// ]);
|
121
|
+
// };
|
122
|
+
|
111
123
|
if (authenticated.status === "error") {
|
112
124
|
return /*#__PURE__*/_jsx("h1", {
|
113
125
|
"data-status": connected,
|
@@ -119,18 +131,20 @@ const CollaborativeEditor = props => {
|
|
119
131
|
children: message || "Loading..."
|
120
132
|
});
|
121
133
|
}
|
122
|
-
return /*#__PURE__*/_jsx(
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
+
return /*#__PURE__*/_jsx(_Fragment, {
|
135
|
+
children: /*#__PURE__*/_jsx(CommonEditor, {
|
136
|
+
ref: editorRef,
|
137
|
+
editor: editor,
|
138
|
+
id: id,
|
139
|
+
content: [],
|
140
|
+
onSave: onSave,
|
141
|
+
readOnly: authenticated.scope,
|
142
|
+
otherProps: {
|
143
|
+
token: user?.token,
|
144
|
+
API_HOST: apiHOST
|
145
|
+
},
|
146
|
+
...rest
|
147
|
+
})
|
134
148
|
});
|
135
149
|
};
|
136
150
|
export default CollaborativeEditor;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import React, { useRef, useCallback, useEffect, useMemo, useState, forwardRef, useImperativeHandle } from "react";
|
2
2
|
import { createEditor } from "slate";
|
3
|
-
import { Slate, Editable } from "slate-react";
|
4
|
-
import
|
3
|
+
import { Slate, Editable, ReactEditor } from "slate-react";
|
4
|
+
import { useDebounce } from "use-debounce";
|
5
5
|
import Toolbar from "./Toolbar/Toolbar";
|
6
6
|
import { getMarked, getBlock } from "./utils/SlateUtilityFunctions";
|
7
7
|
import CodeToText from "./Elements/CodeToText/CodeToText";
|
@@ -15,8 +15,10 @@ import DialogWrapper from "./DialogWrapper";
|
|
15
15
|
import useTimeout from "./hooks/useTimeout";
|
16
16
|
import "./Editor.css";
|
17
17
|
import { serialize } from "./utils/serializer";
|
18
|
+
import { getThumbnailImage } from "./helper";
|
18
19
|
import { jsx as _jsx } from "react/jsx-runtime";
|
19
20
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
21
|
+
const PREVIEW_IMAGE_HIDE_CLASS = ["grid-container-toolbar", "grid-item-toolbar", "element-toolbar"];
|
20
22
|
const Element = props => {
|
21
23
|
return getBlock(props);
|
22
24
|
};
|
@@ -46,7 +48,7 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
|
|
46
48
|
data: content
|
47
49
|
});
|
48
50
|
const [value, setValue] = useState(convertedContent);
|
49
|
-
const [
|
51
|
+
const [deboundedValue] = useDebounce(value, 500);
|
50
52
|
const [count] = useTimeout({
|
51
53
|
timeoutInMS: timeoutInMS
|
52
54
|
});
|
@@ -75,20 +77,53 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
|
|
75
77
|
}, [id, content]);
|
76
78
|
useEffect(() => {
|
77
79
|
if (count > 0) {
|
78
|
-
|
80
|
+
if (editorWrapper && editorWrapper?.current) {
|
81
|
+
const text = serialize(deboundedValue);
|
82
|
+
onSave(JSON.stringify(deboundedValue), {
|
83
|
+
text: text
|
84
|
+
});
|
85
|
+
}
|
79
86
|
}
|
80
|
-
}, [
|
87
|
+
}, [deboundedValue]);
|
88
|
+
const getPreviewImage = async (needBackground = false, options = {}) => {
|
89
|
+
ReactEditor.blur(editor);
|
90
|
+
const dom = needBackground ? editorWrapper?.current : editorWrapper?.current.getElementsByClassName("innert-editor-textbox")[0];
|
91
|
+
const c = await getThumbnailImage(dom, {
|
92
|
+
...options,
|
93
|
+
allowTaint: true,
|
94
|
+
backgroundColor: null,
|
95
|
+
proxy: "anonymous",
|
96
|
+
useCORS: true,
|
97
|
+
onclone: document => {
|
98
|
+
// hide class
|
99
|
+
for (let hidedeClass of PREVIEW_IMAGE_HIDE_CLASS) {
|
100
|
+
for (let element of document.getElementsByClassName(hidedeClass)) {
|
101
|
+
element.style.display = "none";
|
102
|
+
}
|
103
|
+
}
|
104
|
+
return document;
|
105
|
+
}
|
106
|
+
});
|
107
|
+
return c;
|
108
|
+
};
|
81
109
|
useImperativeHandle(ref, () => ({
|
82
|
-
async getThumbnail() {
|
110
|
+
async getThumbnail(needBackground = false, options = {}) {
|
83
111
|
try {
|
84
|
-
const c = await
|
85
|
-
|
86
|
-
return c.toDataURL();
|
87
|
-
}
|
112
|
+
const c = await getPreviewImage(needBackground, options);
|
113
|
+
return c;
|
88
114
|
} catch (err) {
|
89
115
|
console.log(err);
|
90
116
|
return null;
|
91
117
|
}
|
118
|
+
},
|
119
|
+
getEditor() {
|
120
|
+
return editor;
|
121
|
+
},
|
122
|
+
getContent() {
|
123
|
+
return value;
|
124
|
+
},
|
125
|
+
insertFragments(fragments) {
|
126
|
+
editor.insertNode(fragments);
|
92
127
|
}
|
93
128
|
}));
|
94
129
|
const [htmlAction, setHtmlAction] = useState({
|
@@ -109,28 +144,6 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
|
|
109
144
|
const chars = CHARACTERS.filter(c => c.toLowerCase().startsWith(search?.toLowerCase())).slice(0, 10);
|
110
145
|
const handleEditorChange = newValue => {
|
111
146
|
setValue(newValue);
|
112
|
-
const isAstChange = editor.operations.some(op => "set_selection" !== op.type);
|
113
|
-
if (isAstChange && onSave && timeoutInMS === 0) {
|
114
|
-
// send the value to onSave api
|
115
|
-
updateChanges(newValue);
|
116
|
-
}
|
117
|
-
};
|
118
|
-
const updateChanges = newValue => {
|
119
|
-
const stringify = JSON.stringify(newValue);
|
120
|
-
const text = serialize(newValue);
|
121
|
-
if (stringify !== lastUpdated && count > 0 && text?.trim().length > 3 && onSave) {
|
122
|
-
if (editorWrapper && editorWrapper?.current) {
|
123
|
-
html2canvas(editorWrapper?.current, {
|
124
|
-
height: 350
|
125
|
-
}).then(c => {
|
126
|
-
onSave(stringify, {
|
127
|
-
text: text,
|
128
|
-
thumbnail: c.toDataURL()
|
129
|
-
});
|
130
|
-
setLastUpdated(stringify);
|
131
|
-
});
|
132
|
-
}
|
133
|
-
}
|
134
147
|
};
|
135
148
|
const customProps = {
|
136
149
|
...(otherProps || {})
|
@@ -203,6 +216,7 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
|
|
203
216
|
paddingBottom: `${bannerSpacing?.bottom}px`
|
204
217
|
},
|
205
218
|
children: [/*#__PURE__*/_jsx(Editable, {
|
219
|
+
className: "innert-editor-textbox",
|
206
220
|
readOnly: isReadOnly,
|
207
221
|
placeholder: "Write something",
|
208
222
|
renderElement: renderElement,
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
3
|
+
const PageSettings = props => {
|
4
|
+
const {
|
5
|
+
attributes
|
6
|
+
} = props;
|
7
|
+
return /*#__PURE__*/_jsx("div", {
|
8
|
+
...attributes,
|
9
|
+
className: "page-settings",
|
10
|
+
contentEditable: false
|
11
|
+
});
|
12
|
+
};
|
13
|
+
export default PageSettings;
|
@@ -24,6 +24,7 @@ import ImageText from "../Elements/ImageText/ImageText";
|
|
24
24
|
import ChipText from "../Elements/ChipText/ChipText";
|
25
25
|
import DrawerMenu from "../Elements/DrawerMenu/DrawerMenu";
|
26
26
|
import AppHeader from "../Elements/AppHeader/AppHeader";
|
27
|
+
import PageSettings from "../Elements/PageSettings/PageSettings";
|
27
28
|
import { jsx as _jsx } from "react/jsx-runtime";
|
28
29
|
const alignment = ["alignLeft", "alignRight", "alignCenter"];
|
29
30
|
const list_types = ["orderedList", "unorderedList"];
|
@@ -358,6 +359,10 @@ export const getBlock = props => {
|
|
358
359
|
return /*#__PURE__*/_jsx(AppHeader, {
|
359
360
|
...props
|
360
361
|
});
|
362
|
+
case "page-settings":
|
363
|
+
return /*#__PURE__*/_jsx(PageSettings, {
|
364
|
+
...props
|
365
|
+
});
|
361
366
|
default:
|
362
367
|
return /*#__PURE__*/_jsx("div", {
|
363
368
|
...element.attr,
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@flozy/editor",
|
3
|
-
"version": "1.2.
|
3
|
+
"version": "1.2.3",
|
4
4
|
"description": "An Editor for flozy app brain",
|
5
5
|
"files": [
|
6
6
|
"dist"
|
@@ -34,6 +34,7 @@
|
|
34
34
|
"slate-history": "^0.93.0",
|
35
35
|
"slate-react": "^0.98.3",
|
36
36
|
"styled-components": "^5.3.11",
|
37
|
+
"use-debounce": "^10.0.0",
|
37
38
|
"web-vitals": "^2.1.4",
|
38
39
|
"y-websocket": "^1.5.0",
|
39
40
|
"yjs": "^13.6.8"
|