@blocklet/editor 2.0.89 → 2.0.95
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.
|
@@ -3,7 +3,9 @@ type OnChange = (editorState: EditorState, editor: LexicalEditor) => void;
|
|
|
3
3
|
/**
|
|
4
4
|
* 检听内容变化
|
|
5
5
|
* - 忽略 selection 事件
|
|
6
|
-
* - 默认忽略首次 onChange 事件 (editor
|
|
6
|
+
* - 默认忽略首次 onChange 事件 (autofocus 开启时 editor 初始化后会自动触发 onChange)
|
|
7
|
+
*
|
|
8
|
+
* 注意: Editor#autofocus 与 OnChangePlugin 行为有关系: https://github.com/facebook/lexical/issues/4493
|
|
7
9
|
*/
|
|
8
10
|
export declare function OnContentChangePlugin({ onChange, ignoreInitialChange, }: {
|
|
9
11
|
onChange: OnChange;
|
|
@@ -1,19 +1,35 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';
|
|
3
|
-
import { useRef } from 'react';
|
|
3
|
+
import { useLayoutEffect, useRef } from 'react';
|
|
4
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
4
5
|
/**
|
|
5
6
|
* 检听内容变化
|
|
6
7
|
* - 忽略 selection 事件
|
|
7
|
-
* - 默认忽略首次 onChange 事件 (editor
|
|
8
|
+
* - 默认忽略首次 onChange 事件 (autofocus 开启时 editor 初始化后会自动触发 onChange)
|
|
9
|
+
*
|
|
10
|
+
* 注意: Editor#autofocus 与 OnChangePlugin 行为有关系: https://github.com/facebook/lexical/issues/4493
|
|
8
11
|
*/
|
|
9
12
|
export function OnContentChangePlugin({ onChange, ignoreInitialChange = true, }) {
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const [editor] = useLexicalComposerContext();
|
|
14
|
+
const initialContentRef = useRef();
|
|
15
|
+
const changedRef = useRef(false);
|
|
16
|
+
useLayoutEffect(() => {
|
|
17
|
+
if (initialContentRef.current === undefined) {
|
|
18
|
+
const editorState = editor.getEditorState();
|
|
19
|
+
initialContentRef.current = editorState ? JSON.stringify(editorState) : '';
|
|
20
|
+
}
|
|
21
|
+
}, [editor]);
|
|
22
|
+
const handleOnChange = (editorState, lexicalEditor) => {
|
|
23
|
+
if (changedRef.current) {
|
|
24
|
+
onChange(editorState, lexicalEditor);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const content = editorState ? JSON.stringify(editorState) : '';
|
|
28
|
+
if (content !== initialContentRef.current || !ignoreInitialChange) {
|
|
29
|
+
onChange(editorState, lexicalEditor);
|
|
30
|
+
changedRef.current = true;
|
|
31
|
+
}
|
|
15
32
|
}
|
|
16
|
-
onChange(editorState, editor);
|
|
17
33
|
};
|
|
18
34
|
return _jsx(OnChangePlugin, { onChange: handleOnChange, ignoreSelectionChange: true });
|
|
19
35
|
}
|
|
@@ -37,6 +37,12 @@ export default function ExcalidrawModal({ closeOnClickOutside = false, onSave, i
|
|
|
37
37
|
const [loading, setLoading] = useState(false);
|
|
38
38
|
const [saveText, setSaveText] = useState('Save');
|
|
39
39
|
const [fullScreen, setFullScreen] = useState(false);
|
|
40
|
+
const markBlockletDirtyState = () => {
|
|
41
|
+
window.dispatchEvent(new CustomEvent('blocklet:markDirty', { detail: { key: 'excalidraw' } }));
|
|
42
|
+
};
|
|
43
|
+
const resetBlockletDirtyState = () => {
|
|
44
|
+
window.dispatchEvent(new CustomEvent('blocklet:resetDirty', { detail: { key: 'excalidraw' } }));
|
|
45
|
+
};
|
|
40
46
|
useEffect(() => {
|
|
41
47
|
// @ts-ignore set window.name to add library target
|
|
42
48
|
window.name = window.location.href;
|
|
@@ -127,12 +133,14 @@ export default function ExcalidrawModal({ closeOnClickOutside = false, onSave, i
|
|
|
127
133
|
finally {
|
|
128
134
|
setLoading(false);
|
|
129
135
|
setSaveText('Save');
|
|
136
|
+
resetBlockletDirtyState();
|
|
130
137
|
}
|
|
131
138
|
};
|
|
132
139
|
const discard = () => {
|
|
133
140
|
if (elements.filter((el) => !el.isDeleted).length === 0) {
|
|
134
141
|
// delete node if the scene is clear
|
|
135
142
|
onDelete();
|
|
143
|
+
resetBlockletDirtyState();
|
|
136
144
|
}
|
|
137
145
|
else {
|
|
138
146
|
// Otherwise, show confirmation dialog before closing
|
|
@@ -144,6 +152,7 @@ export default function ExcalidrawModal({ closeOnClickOutside = false, onSave, i
|
|
|
144
152
|
return (_jsxs(Modal, { title: "Discard", onClose: () => {
|
|
145
153
|
setDiscardModalOpen(false);
|
|
146
154
|
}, closeOnClickOutside: false, children: ["Are you sure you want to discard the changes?", _jsxs("div", { className: "ExcalidrawModal__discardModal", children: [_jsx(Button, { onClick: () => {
|
|
155
|
+
resetBlockletDirtyState();
|
|
147
156
|
setDiscardModalOpen(false);
|
|
148
157
|
onClose();
|
|
149
158
|
}, children: "Discard" }), ' ', _jsx(Button, { onClick: () => {
|
|
@@ -154,6 +163,7 @@ export default function ExcalidrawModal({ closeOnClickOutside = false, onSave, i
|
|
|
154
163
|
return null;
|
|
155
164
|
}
|
|
156
165
|
const onChange = (els, _, fls) => {
|
|
166
|
+
markBlockletDirtyState();
|
|
157
167
|
setElements(els);
|
|
158
168
|
setFiles(fls);
|
|
159
169
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/editor",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.95",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "npm run storybook",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
]
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@arcblock/ux": "^2.10.
|
|
40
|
+
"@arcblock/ux": "^2.10.12",
|
|
41
41
|
"@blocklet/embed": "^0.1.11",
|
|
42
|
-
"@blocklet/pages-kit": "^0.2.
|
|
43
|
-
"@blocklet/pdf": "2.0.
|
|
42
|
+
"@blocklet/pages-kit": "^0.2.390",
|
|
43
|
+
"@blocklet/pdf": "2.0.95",
|
|
44
44
|
"@excalidraw/excalidraw": "^0.14.2",
|
|
45
45
|
"@iconify/iconify": "^3.0.1",
|
|
46
46
|
"@iconify/icons-tabler": "^1.2.95",
|
|
@@ -113,5 +113,5 @@
|
|
|
113
113
|
"react": "*",
|
|
114
114
|
"react-dom": "*"
|
|
115
115
|
},
|
|
116
|
-
"gitHead": "
|
|
116
|
+
"gitHead": "1a046d557cce0678f2ac833bd314dcdd25872733"
|
|
117
117
|
}
|