mirror of
https://github.com/facebook/lexical.git
synced 2025-08-06 16:39:33 +08:00
Expose useOutlineHistory in sync + allow external state (#927)
This commit is contained in:

committed by
acywatson

parent
32eeeeb282
commit
302af329c4
@ -48,6 +48,7 @@ module.name_mapper='^outline-react/useOutlineIsBlank' -> '<PROJECT_ROOT>/package
|
||||
module.name_mapper='^outline-react/useOutlineIsTextContentEmpty' -> '<PROJECT_ROOT>/packages/outline-react/src/useOutlineIsTextContentEmpty.js'
|
||||
module.name_mapper='^outline-react/useOutlineCanShowPlaceholder' -> '<PROJECT_ROOT>/packages/outline-react/src/useOutlineCanShowPlaceholder.js'
|
||||
module.name_mapper='^outline-react/useOutlineCharacterLimit' -> '<PROJECT_ROOT>/packages/outline-react/src/useOutlineCharacterLimit.js'
|
||||
module.name_mapper='^outline-react/useOutlineHistory' -> '<PROJECT_ROOT>/packages/outline-react/src/useOutlineHistory.js'
|
||||
|
||||
module.name_mapper='^outline-yjs$' -> '<PROJECT_ROOT>/packages/outline-yjs/src/index.js'
|
||||
|
||||
|
@ -44,6 +44,7 @@ module.exports = {
|
||||
'outline-react/dist/useOutlineCanShowPlaceholder',
|
||||
'outline-react/useOutlineCharacterLimit':
|
||||
'outline-react/dist/useOutlineCharacterLimit',
|
||||
'outline-react/useOutlineHistory': 'outline-react/dist/useOutlineHistory',
|
||||
//Shared
|
||||
'shared/environment': 'shared/dist/environment',
|
||||
'shared/useLayoutEffect': 'shared/dist/useLayoutEffect',
|
||||
|
@ -23,6 +23,17 @@ const MERGE = 0;
|
||||
const NO_MERGE = 1;
|
||||
const DISCARD = 2;
|
||||
|
||||
export type HistoryStateEntry = {
|
||||
editor: OutlineEditor,
|
||||
editorState: EditorState,
|
||||
};
|
||||
|
||||
export type HistoryState = {
|
||||
current: null | HistoryStateEntry,
|
||||
redoStack: Array<HistoryStateEntry>,
|
||||
undoStack: Array<HistoryStateEntry>,
|
||||
};
|
||||
|
||||
function getDirtyNodes(
|
||||
editorState: EditorState,
|
||||
dirtyLeavesSet: Set<NodeKey>,
|
||||
@ -130,18 +141,13 @@ function getMergeAction(
|
||||
return NO_MERGE;
|
||||
}
|
||||
|
||||
export default function useOutlineHistory(editor: OutlineEditor): () => void {
|
||||
const historyState: {
|
||||
current: null | EditorState,
|
||||
redoStack: Array<EditorState>,
|
||||
undoStack: Array<EditorState>,
|
||||
} = useMemo(
|
||||
() => ({
|
||||
current: null,
|
||||
redoStack: [],
|
||||
undoStack: [],
|
||||
}),
|
||||
[],
|
||||
export function useOutlineHistory(
|
||||
editor: OutlineEditor,
|
||||
externalHistoryState?: HistoryState,
|
||||
): () => void {
|
||||
const historyState: HistoryState = useMemo(
|
||||
() => externalHistoryState || createEmptyHistoryState(),
|
||||
[externalHistoryState],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@ -149,12 +155,13 @@ export default function useOutlineHistory(editor: OutlineEditor): () => void {
|
||||
const current = historyState.current;
|
||||
const redoStack = historyState.redoStack;
|
||||
const undoStack = historyState.undoStack;
|
||||
const currentEditorState = current === null ? null : current.editorState;
|
||||
|
||||
if (editorState === current) {
|
||||
if (current !== null && editorState === currentEditorState) {
|
||||
return;
|
||||
}
|
||||
const mergeAction = getMergeAction(
|
||||
current,
|
||||
currentEditorState,
|
||||
editorState,
|
||||
dirtyLeaves,
|
||||
dirtyBlocks,
|
||||
@ -171,7 +178,10 @@ export default function useOutlineHistory(editor: OutlineEditor): () => void {
|
||||
return;
|
||||
}
|
||||
// Else we merge
|
||||
historyState.current = editorState;
|
||||
historyState.current = {
|
||||
editor,
|
||||
editorState,
|
||||
};
|
||||
};
|
||||
|
||||
const undo = () => {
|
||||
@ -184,9 +194,9 @@ export default function useOutlineHistory(editor: OutlineEditor): () => void {
|
||||
if (current !== null) {
|
||||
redoStack.push(current);
|
||||
}
|
||||
const editorState = undoStack.pop();
|
||||
historyState.current = editorState;
|
||||
editor.setEditorState(editorState);
|
||||
const historyStateEntry = undoStack.pop();
|
||||
historyState.current = historyStateEntry;
|
||||
historyStateEntry.editor.setEditorState(historyStateEntry.editorState);
|
||||
}
|
||||
};
|
||||
|
||||
@ -199,9 +209,9 @@ export default function useOutlineHistory(editor: OutlineEditor): () => void {
|
||||
if (current !== null) {
|
||||
undoStack.push(current);
|
||||
}
|
||||
const editorState = redoStack.pop();
|
||||
historyState.current = editorState;
|
||||
editor.setEditorState(editorState);
|
||||
const historyStateEntry = redoStack.pop();
|
||||
historyState.current = historyStateEntry;
|
||||
historyStateEntry.editor.setEditorState(historyStateEntry.editorState);
|
||||
}
|
||||
};
|
||||
|
||||
@ -209,6 +219,7 @@ export default function useOutlineHistory(editor: OutlineEditor): () => void {
|
||||
if (editor.isComposing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isUndo(event)) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
@ -266,3 +277,11 @@ export default function useOutlineHistory(editor: OutlineEditor): () => void {
|
||||
|
||||
return clearHistory;
|
||||
}
|
||||
|
||||
export function createEmptyHistoryState(): HistoryState {
|
||||
return {
|
||||
current: null,
|
||||
redoStack: [],
|
||||
undoStack: [],
|
||||
};
|
||||
}
|
@ -8,15 +8,19 @@
|
||||
*/
|
||||
|
||||
import type {OutlineEditor} from 'outline';
|
||||
import type {HistoryState} from './useOutlineHistory';
|
||||
|
||||
import {useCallback} from 'react';
|
||||
|
||||
import usePlainTextSetup from './shared/usePlainTextSetup';
|
||||
import useOutlineHistory from './shared/useOutlineHistory';
|
||||
import {useOutlineHistory} from './useOutlineHistory';
|
||||
|
||||
export default function useOutlinePlainText(editor: OutlineEditor): () => void {
|
||||
export default function useOutlinePlainText(
|
||||
editor: OutlineEditor,
|
||||
externalHistoryState?: HistoryState,
|
||||
): () => void {
|
||||
const clearEditor = usePlainTextSetup(editor, true);
|
||||
const clearHistory = useOutlineHistory(editor);
|
||||
const clearHistory = useOutlineHistory(editor, externalHistoryState);
|
||||
|
||||
return useCallback(
|
||||
(callbackFn?: () => void) => {
|
||||
|
@ -8,15 +8,19 @@
|
||||
*/
|
||||
|
||||
import type {OutlineEditor} from 'outline';
|
||||
import type {HistoryState} from './useOutlineHistory';
|
||||
|
||||
import {useCallback} from 'react';
|
||||
|
||||
import {useRichTextSetup} from './shared/useRichTextSetup';
|
||||
import useOutlineHistory from './shared/useOutlineHistory';
|
||||
import {useOutlineHistory} from './useOutlineHistory';
|
||||
|
||||
export default function useOutlineRichText(editor: OutlineEditor): () => void {
|
||||
export default function useOutlineRichText(
|
||||
editor: OutlineEditor,
|
||||
externalHistoryState?: HistoryState,
|
||||
): () => void {
|
||||
const clearEditor = useRichTextSetup(editor, true);
|
||||
const clearHistory = useOutlineHistory(editor);
|
||||
const clearHistory = useOutlineHistory(editor, externalHistoryState);
|
||||
|
||||
return useCallback(
|
||||
(callbackFn?: () => void) => {
|
||||
|
@ -310,8 +310,10 @@ outlineReactModules.forEach((outlineReactModule) => {
|
||||
// modules already.
|
||||
if (
|
||||
outlineReactModule === 'OutlineEnv' ||
|
||||
outlineReactModule === 'useOutlineHistory' ||
|
||||
outlineReactModule === 'useOutlineDragonSupport' ||
|
||||
outlineReactModule === 'usePlainTextSetup' ||
|
||||
outlineReactModule === 'useRichTextSetup' ||
|
||||
outlineReactModule === 'useYjsCollaboration' ||
|
||||
outlineReactModule === 'OutlineReactUtils'
|
||||
) {
|
||||
return;
|
||||
|
Reference in New Issue
Block a user