@inshapardaz/likhari-react 0.1.42 → 0.1.43-dev.323
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/EditorRoot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"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"}
|
package/dist/EditorRoot.js
CHANGED
|
@@ -276,6 +276,9 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, autoCorre
|
|
|
276
276
|
autosaveTimerRef.current = null;
|
|
277
277
|
}
|
|
278
278
|
pendingDraftRef.current = null;
|
|
279
|
+
// What follows the load (plugin transforms, node normalisation) is
|
|
280
|
+
// part of the loaded content, not an edit: see `loadSettlingRef`.
|
|
281
|
+
loadSettlingRef.current = true;
|
|
279
282
|
editor.setEditorState(parsed);
|
|
280
283
|
setIsDirty(false);
|
|
281
284
|
},
|
|
@@ -291,8 +294,43 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, autoCorre
|
|
|
291
294
|
}), [isDirty]);
|
|
292
295
|
const rootElementRef = useRef(null);
|
|
293
296
|
const editorInstanceRef = useRef(null);
|
|
297
|
+
// True from a content load (mount, or `setContent`) until the user first
|
|
298
|
+
// interacts with the editor. Loading doesn't always settle in one update:
|
|
299
|
+
// plugins and Lexical's own normalisation can rewrite the state right
|
|
300
|
+
// afterwards, and comparing that against the content as it arrived would
|
|
301
|
+
// call an untouched document "changed" (and autosave a draft of it). Until
|
|
302
|
+
// the user interacts, a change is therefore folded into the clean baseline
|
|
303
|
+
// instead: no dirty flag, no draft, no `onChange`.
|
|
304
|
+
const loadSettlingRef = useRef(true);
|
|
305
|
+
useEffect(() => {
|
|
306
|
+
const root = rootElementRef.current;
|
|
307
|
+
if (!root)
|
|
308
|
+
return;
|
|
309
|
+
const onInteraction = () => {
|
|
310
|
+
if (!loadSettlingRef.current)
|
|
311
|
+
return;
|
|
312
|
+
loadSettlingRef.current = false;
|
|
313
|
+
// The edit this event leads to has not been applied yet, so the editor's
|
|
314
|
+
// current state is the loaded content, as normalised.
|
|
315
|
+
const editor = editorInstanceRef.current;
|
|
316
|
+
if (editor && !isDirtyRef.current)
|
|
317
|
+
lastSavedJsonRef.current = JSON.stringify(editor.getEditorState().toJSON());
|
|
318
|
+
};
|
|
319
|
+
const events = ['keydown', 'pointerdown', 'beforeinput', 'paste', 'cut', 'drop', 'compositionstart'];
|
|
320
|
+
for (const type of events)
|
|
321
|
+
root.addEventListener(type, onInteraction, true);
|
|
322
|
+
return () => {
|
|
323
|
+
for (const type of events)
|
|
324
|
+
root.removeEventListener(type, onInteraction, true);
|
|
325
|
+
};
|
|
326
|
+
}, []);
|
|
294
327
|
const handleChange = (state) => {
|
|
295
328
|
editorStateRef.current = state;
|
|
329
|
+
if (loadSettlingRef.current) {
|
|
330
|
+
lastSavedJsonRef.current = JSON.stringify(state.toJSON());
|
|
331
|
+
setIsDirty(false);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
296
334
|
const json = JSON.stringify(state.toJSON());
|
|
297
335
|
setIsDirty(json !== lastSavedJsonRef.current);
|
|
298
336
|
onChange?.(state.toJSON());
|
|
@@ -305,6 +343,9 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, autoCorre
|
|
|
305
343
|
};
|
|
306
344
|
/** A draft was restored into the editor: that content is unsaved work. */
|
|
307
345
|
const handleDraftRestored = (entry) => {
|
|
346
|
+
// No clean baseline to compare with: it stays unsaved until it is saved.
|
|
347
|
+
loadSettlingRef.current = false;
|
|
348
|
+
lastSavedJsonRef.current = null;
|
|
308
349
|
setIsDirty(true);
|
|
309
350
|
if (documentId && entry.id === documentId)
|
|
310
351
|
onDraftRestored?.({ documentId, savedAt: entry.draft.savedAt });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"joinLinesActions.d.ts","sourceRoot":"","sources":["../../src/join/joinLinesActions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"joinLinesActions.d.ts","sourceRoot":"","sources":["../../src/join/joinLinesActions.ts"],"names":[],"mappings":"AAoCA,wBAAgB,aAAa,IAAI,OAAO,CAKvC;AAiDD;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CA2B5C"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $createTextNode, $getSelection, $isLineBreakNode, $isParagraphNode, $isRangeSelection, $createParagraphNode, } from 'lexical';
|
|
1
|
+
import { $createTextNode, $getSelection, $isLineBreakNode, $isParagraphNode, $isRangeSelection, $isTextNode, $createParagraphNode, } from 'lexical';
|
|
2
2
|
function $paragraphsInSelection(selection) {
|
|
3
3
|
const seen = new Set();
|
|
4
4
|
const paragraphs = [];
|
|
@@ -11,13 +11,30 @@ function $paragraphsInSelection(selection) {
|
|
|
11
11
|
}
|
|
12
12
|
return paragraphs;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Text nodes in the selection that hold a literal newline. Lexical shows these
|
|
16
|
+
* as line breaks, but they are not line-break nodes: content loaded from
|
|
17
|
+
* plain text or a foreign Lexical document can be shaped this way.
|
|
18
|
+
*/
|
|
19
|
+
function $textNodesWithNewlines(selection) {
|
|
20
|
+
return selection.getNodes().filter((node) => $isTextNode(node) && node.getTextContent().includes('\n'));
|
|
21
|
+
}
|
|
14
22
|
export function $canJoinLines() {
|
|
15
23
|
const selection = $getSelection();
|
|
16
24
|
if (!$isRangeSelection(selection) || selection.isCollapsed())
|
|
17
25
|
return false;
|
|
18
26
|
if ($paragraphsInSelection(selection).length > 1)
|
|
19
27
|
return true;
|
|
20
|
-
return selection.getNodes().some($isLineBreakNode);
|
|
28
|
+
return selection.getNodes().some($isLineBreakNode) || $textNodesWithNewlines(selection).length > 0;
|
|
29
|
+
}
|
|
30
|
+
/** Replaces the newlines in the selected part of a text node, each by one space (none if one is already there). */
|
|
31
|
+
function $replaceNewlinesInText(node, selection) {
|
|
32
|
+
const [start, end] = selection.getStartEndPoints() ?? [];
|
|
33
|
+
const text = node.getTextContent();
|
|
34
|
+
const from = start && start.key === node.getKey() ? start.offset : 0;
|
|
35
|
+
const to = end && end.key === node.getKey() ? end.offset : text.length;
|
|
36
|
+
const joined = text.slice(from, to).replace(/[ \t]*\r?\n[ \t]*/g, ' ');
|
|
37
|
+
node.setTextContent(text.slice(0, from) + joined + text.slice(to));
|
|
21
38
|
}
|
|
22
39
|
/** A soft break becomes one space, unless the text either side already has a space there. */
|
|
23
40
|
function $replaceBreakWithSpace(lineBreak) {
|
|
@@ -67,13 +84,16 @@ export function $joinSelectedLines() {
|
|
|
67
84
|
const paragraphs = $paragraphsInSelection(selection);
|
|
68
85
|
const nodes = selection.getNodes();
|
|
69
86
|
const lineBreaks = nodes.filter($isLineBreakNode);
|
|
70
|
-
|
|
87
|
+
const textsWithNewlines = $textNodesWithNewlines(selection);
|
|
88
|
+
if (paragraphs.length < 2 && lineBreaks.length === 0 && textsWithNewlines.length === 0)
|
|
71
89
|
return false;
|
|
72
90
|
const last = nodes[nodes.length - 1];
|
|
73
91
|
const breakAfter = last?.getNextSibling();
|
|
74
92
|
const trailingBreak = $isLineBreakNode(breakAfter) ? breakAfter : null;
|
|
75
93
|
for (const lineBreak of lineBreaks)
|
|
76
94
|
$replaceBreakWithSpace(lineBreak);
|
|
95
|
+
for (const textNode of textsWithNewlines)
|
|
96
|
+
$replaceNewlinesInText(textNode, selection);
|
|
77
97
|
const [target, ...rest] = paragraphs;
|
|
78
98
|
if (!target)
|
|
79
99
|
return false;
|