@@ -93,6 +93,7 @@ import {
93
93
import { Dictionary } from "../i18n/dictionary.js" ;
94
94
import { en } from "../i18n/locales/index.js" ;
95
95
96
+ import { redo , undo } from "@tiptap/pm/history" ;
96
97
import {
97
98
TextSelection ,
98
99
type Command ,
@@ -101,8 +102,14 @@ import {
101
102
} from "@tiptap/pm/state" ;
102
103
import { dropCursor } from "prosemirror-dropcursor" ;
103
104
import { EditorView } from "prosemirror-view" ;
104
- import { undoCommand , redoCommand , ySyncPluginKey } from "y-prosemirror" ;
105
- import { undo , redo } from "@tiptap/pm/history" ;
105
+ import {
106
+ redoCommand ,
107
+ undoCommand ,
108
+ yCursorPluginKey ,
109
+ ySyncPlugin ,
110
+ ySyncPluginKey ,
111
+ yUndoPluginKey ,
112
+ } from "y-prosemirror" ;
106
113
import { createInternalHTMLSerializer } from "../api/exporters/html/internalHTMLSerializer.js" ;
107
114
import { inlineContentToNodes } from "../api/nodeConversions/blockToNode.js" ;
108
115
import { nodeToBlock } from "../api/nodeConversions/nodeToBlock.js" ;
@@ -113,9 +120,11 @@ import {
113
120
import { nestedListsToBlockNoteStructure } from "../api/parsers/html/util/nestedLists.js" ;
114
121
import { CodeBlockOptions } from "../blocks/CodeBlockContent/CodeBlockContent.js" ;
115
122
import type { ThreadStore , User } from "../comments/index.js" ;
123
+ import { CursorPlugin } from "../extensions/Collaboration/CursorPlugin.js" ;
116
124
import "../style.css" ;
117
125
import { EventEmitter } from "../util/EventEmitter.js" ;
118
- import { CursorPlugin } from "../extensions/Collaboration/CursorPlugin.js" ;
126
+ import { SyncPlugin } from "../extensions/Collaboration/SyncPlugin.js" ;
127
+ import { UndoPlugin } from "../extensions/Collaboration/UndoPlugin.js" ;
119
128
120
129
export type BlockNoteExtensionFactory = (
121
130
editor : BlockNoteEditor < any , any , any >
@@ -474,7 +483,7 @@ export class BlockNoteEditor<
474
483
475
484
private readonly showSelectionPlugin : ShowSelectionPlugin ;
476
485
477
- private readonly cursorPlugin : CursorPlugin ;
486
+ private cursorPlugin : CursorPlugin ;
478
487
479
488
/**
480
489
* The `uploadFile` method is what the editor uses when files need to be uploaded (for example when selecting an image to upload).
@@ -934,6 +943,46 @@ export class BlockNoteEditor<
934
943
} ;
935
944
}
936
945
946
+ private yjsState :
947
+ | {
948
+ prevFragment : Y . XmlFragment ;
949
+ nextFragment : Y . XmlFragment ;
950
+ }
951
+ | undefined ;
952
+
953
+ public pauseYjsSync ( ) {
954
+ const prevFragment = this . options . collaboration ?. fragment ;
955
+
956
+ if ( ! prevFragment ) {
957
+ throw new Error ( "No Yjs document found" ) ;
958
+ }
959
+ const nextFragment = prevFragment . clone ( ) ;
960
+ const doc = new Y . Doc ( ) ;
961
+ nextFragment . _integrate ( doc , nextFragment . _item ! ) ;
962
+
963
+ this . yjsState = {
964
+ prevFragment,
965
+ nextFragment,
966
+ } ;
967
+ this . _tiptapEditor . unregisterPlugin ( yCursorPluginKey ) ;
968
+ this . _tiptapEditor . unregisterPlugin ( yUndoPluginKey ) ;
969
+ this . _tiptapEditor . unregisterPlugin ( ySyncPluginKey ) ;
970
+ this . _tiptapEditor . registerPlugin ( ySyncPlugin ( nextFragment ) ) ;
971
+ }
972
+
973
+ public resumeYjsSync ( ) {
974
+ if ( ! this . yjsState ) {
975
+ throw new Error ( "No Yjs document found" ) ;
976
+ }
977
+ this . _tiptapEditor . unregisterPlugin ( ySyncPluginKey ) ;
978
+ this . _tiptapEditor . registerPlugin (
979
+ new SyncPlugin ( this . yjsState . prevFragment ) . plugin
980
+ ) ;
981
+ this . cursorPlugin = new CursorPlugin ( this . options . collaboration ! ) ;
982
+ this . _tiptapEditor . registerPlugin ( this . cursorPlugin . plugin ) ;
983
+ this . _tiptapEditor . registerPlugin ( new UndoPlugin ( ) . plugin ) ;
984
+ }
985
+
937
986
/**
938
987
* @deprecated , use `editor.document` instead
939
988
*/
0 commit comments