From 01c2a54f9117c3fd8e0a04dc35c36d626b64cbf1 Mon Sep 17 00:00:00 2001 From: Gerard Rovira Date: Fri, 21 Apr 2023 15:54:21 -0400 Subject: [PATCH 1/4] Fix HistoryPlugin selection out of sync --- packages/lexical-history/src/index.ts | 13 +++++-------- .../src/plugins/ImagesPlugin/index.tsx | 4 ++++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/lexical-history/src/index.ts b/packages/lexical-history/src/index.ts index 80518b843b9..1d474ed3bbe 100644 --- a/packages/lexical-history/src/index.ts +++ b/packages/lexical-history/src/index.ts @@ -47,7 +47,6 @@ const DELETE_CHARACTER_AFTER_SELECTION = 4; export type HistoryStateEntry = { editor: LexicalEditor; editorState: EditorState; - undoSelection?: RangeSelection | NodeSelection | GridSelection | null; }; export type HistoryState = { current: null | HistoryStateEntry; @@ -374,12 +373,9 @@ function undo(editor: LexicalEditor, historyState: HistoryState): void { historyState.current = historyStateEntry || null; if (historyStateEntry) { - historyStateEntry.editor.setEditorState( - historyStateEntry.editorState.clone(historyStateEntry.undoSelection), - { - tag: 'historic', - }, - ); + historyStateEntry.editor.setEditorState(historyStateEntry.editorState, { + tag: 'historic', + }); } } } @@ -446,8 +442,9 @@ export function registerHistory( if (current !== null) { undoStack.push({ ...current, - undoSelection: prevEditorState.read($getSelection), + // undoSelection: prevEditorState.read($getSelection), }); + console.info(undoStack); editor.dispatchCommand(CAN_UNDO_COMMAND, true); } } else if (mergeAction === DISCARD_HISTORY_CANDIDATE) { diff --git a/packages/lexical-playground/src/plugins/ImagesPlugin/index.tsx b/packages/lexical-playground/src/plugins/ImagesPlugin/index.tsx index 32d8ccfbae0..2aae3c60a13 100644 --- a/packages/lexical-playground/src/plugins/ImagesPlugin/index.tsx +++ b/packages/lexical-playground/src/plugins/ImagesPlugin/index.tsx @@ -24,6 +24,7 @@ import { DROP_COMMAND, LexicalCommand, LexicalEditor, + $getRoot, } from 'lexical'; import {useEffect, useRef, useState} from 'react'; import * as React from 'react'; @@ -222,6 +223,9 @@ export default function ImagesPlugin({ (payload) => { const imageNode = $createImageNode(payload); $insertNodes([imageNode]); + imageNode.__caption.update(() => { + $getRoot().append($createParagraphNode()).selectEnd(); + }); if ($isRootOrShadowRoot(imageNode.getParentOrThrow())) { $wrapNodeInElement(imageNode, $createParagraphNode).selectEnd(); } From 06f92edca204a72f865e2a4518f9b2d2afebfed7 Mon Sep 17 00:00:00 2001 From: Gerard Rovira Date: Fri, 21 Apr 2023 20:57:27 -0400 Subject: [PATCH 2/4] test --- .../__tests__/unit/LexicalHistory.test.tsx | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/packages/lexical-history/src/__tests__/unit/LexicalHistory.test.tsx b/packages/lexical-history/src/__tests__/unit/LexicalHistory.test.tsx index cfa3087ec2f..f3d03ac0a6f 100644 --- a/packages/lexical-history/src/__tests__/unit/LexicalHistory.test.tsx +++ b/packages/lexical-history/src/__tests__/unit/LexicalHistory.test.tsx @@ -6,6 +6,7 @@ * */ +import {createEmptyHistoryState, registerHistory} from '@lexical/history'; import {useLexicalComposerContext} from '@lexical/react/src/LexicalComposerContext'; import {ContentEditable} from '@lexical/react/src/LexicalContentEditable'; import LexicalErrorBoundary from '@lexical/react/src/LexicalErrorBoundary'; @@ -14,7 +15,9 @@ import {RichTextPlugin} from '@lexical/react/src/LexicalRichTextPlugin'; import {$createQuoteNode} from '@lexical/rich-text/src'; import {$setBlocksType} from '@lexical/selection/src'; import { + $createNodeSelection, $createRangeSelection, + $isNodeSelection, CAN_REDO_COMMAND, CAN_UNDO_COMMAND, CLEAR_HISTORY_COMMAND, @@ -25,7 +28,7 @@ import { SerializedTextNode, UNDO_COMMAND, } from 'lexical/src'; -import {TestComposer} from 'lexical/src/__tests__/utils'; +import {createTestEditor, TestComposer} from 'lexical/src/__tests__/utils'; import {$getRoot, $setSelection} from 'lexical/src/LexicalUtils'; import {$createParagraphNode} from 'lexical/src/nodes/LexicalParagraphNode'; import {$createTextNode} from 'lexical/src/nodes/LexicalTextNode'; @@ -265,6 +268,50 @@ describe('LexicalHistory tests', () => { expect(canRedo).toBe(false); expect(canUndo).toBe(true); }); + + test('undoStack selection points to the same editor', async () => { + const editor_ = createTestEditor({namespace: 'parent'}); + const sharedHistory = createEmptyHistoryState(); + registerHistory(editor_, sharedHistory, 1000); + await editor_.update(() => { + const root = $getRoot(); + const paragraph = $createParagraphNode(); + root.append(paragraph); + }); + await editor_.update(() => { + const root = $getRoot(); + const paragraph = $createParagraphNode(); + root.append(paragraph); + const nodeSelection = $createNodeSelection(); + nodeSelection.add(paragraph.getKey()); + $setSelection(nodeSelection); + }); + const nestedEditor = createTestEditor({namespace: 'nested'}); + await nestedEditor.update( + () => { + const root = $getRoot(); + const paragraph = $createParagraphNode(); + root.append(paragraph); + paragraph.selectEnd(); + }, + { + tag: 'history-merge', + }, + ); + nestedEditor._parentEditor = editor_; + registerHistory(nestedEditor, sharedHistory, 1000); + + await nestedEditor.update(() => { + const root = $getRoot(); + const paragraph = $createParagraphNode(); + root.append(paragraph); + paragraph.selectEnd(); + }); + + expect(sharedHistory.undoStack.length).toBe(2); + await editor_.dispatchCommand(UNDO_COMMAND, undefined); + expect($isNodeSelection(editor_.getEditorState()._selection)).toBe(true); + }); }); const createParagraphNode = (text: string) => { From eee3c3b7b9e7f05f31ce9ce6d3fd5b4d99f9d886 Mon Sep 17 00:00:00 2001 From: Gerard Rovira Date: Fri, 21 Apr 2023 20:58:27 -0400 Subject: [PATCH 3/4] r --- .../lexical-playground/src/plugins/ImagesPlugin/index.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/lexical-playground/src/plugins/ImagesPlugin/index.tsx b/packages/lexical-playground/src/plugins/ImagesPlugin/index.tsx index 2aae3c60a13..32d8ccfbae0 100644 --- a/packages/lexical-playground/src/plugins/ImagesPlugin/index.tsx +++ b/packages/lexical-playground/src/plugins/ImagesPlugin/index.tsx @@ -24,7 +24,6 @@ import { DROP_COMMAND, LexicalCommand, LexicalEditor, - $getRoot, } from 'lexical'; import {useEffect, useRef, useState} from 'react'; import * as React from 'react'; @@ -223,9 +222,6 @@ export default function ImagesPlugin({ (payload) => { const imageNode = $createImageNode(payload); $insertNodes([imageNode]); - imageNode.__caption.update(() => { - $getRoot().append($createParagraphNode()).selectEnd(); - }); if ($isRootOrShadowRoot(imageNode.getParentOrThrow())) { $wrapNodeInElement(imageNode, $createParagraphNode).selectEnd(); } From d57417d5cad544811d4fedb7e6f9a5695f0e7964 Mon Sep 17 00:00:00 2001 From: Gerard Rovira Date: Fri, 21 Apr 2023 20:59:50 -0400 Subject: [PATCH 4/4] . --- packages/lexical-history/src/index.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/packages/lexical-history/src/index.ts b/packages/lexical-history/src/index.ts index 1d474ed3bbe..3b33f9f4d76 100644 --- a/packages/lexical-history/src/index.ts +++ b/packages/lexical-history/src/index.ts @@ -7,19 +7,10 @@ * */ -import type { - EditorState, - GridSelection, - LexicalEditor, - LexicalNode, - NodeKey, - NodeSelection, - RangeSelection, -} from 'lexical'; +import type {EditorState, LexicalEditor, LexicalNode, NodeKey} from 'lexical'; import {mergeRegister} from '@lexical/utils'; import { - $getSelection, $isRangeSelection, $isRootNode, $isTextNode, @@ -442,9 +433,7 @@ export function registerHistory( if (current !== null) { undoStack.push({ ...current, - // undoSelection: prevEditorState.read($getSelection), }); - console.info(undoStack); editor.dispatchCommand(CAN_UNDO_COMMAND, true); } } else if (mergeAction === DISCARD_HISTORY_CANDIDATE) {