2021-06-05 03:56:29 +08:00
import { Extension } from '@tiptap/core'
2021-02-22 17:40:56 +08:00
import { UndoManager } from 'yjs'
2020-09-26 05:22:21 +08:00
import {
2020-11-25 16:50:54 +08:00
redo ,
undo ,
ySyncPlugin ,
yUndoPlugin ,
2021-02-22 17:40:56 +08:00
yUndoPluginKey ,
2020-09-26 05:22:21 +08:00
} from 'y-prosemirror'
2020-09-26 05:55:34 +08:00
2021-02-10 16:59:35 +08:00
declare module '@tiptap/core' {
2021-06-05 03:56:29 +08:00
interface Commands < ReturnType > {
2021-02-16 18:27:58 +08:00
collaboration : {
/ * *
* Undo recent changes
* /
2021-06-05 03:56:29 +08:00
undo : ( ) = > ReturnType ,
2021-02-16 18:27:58 +08:00
/ * *
* Reapply reverted changes
* /
2021-06-05 03:56:29 +08:00
redo : ( ) = > ReturnType ,
2021-02-16 18:27:58 +08:00
}
2021-02-10 16:59:35 +08:00
}
}
2020-09-26 16:43:08 +08:00
export interface CollaborationOptions {
2021-01-09 01:02:06 +08:00
/ * *
* An initialized Y . js document .
* /
document : any ,
2021-01-11 21:43:41 +08:00
/ * *
2021-01-12 01:37:30 +08:00
* Name of a Y . js fragment , can be changed to sync multiple fields with one Y . js document .
2021-01-11 21:43:41 +08:00
* /
2021-01-12 01:37:30 +08:00
field : string ,
/ * *
* A raw Y . js fragment , can be used instead of ` document ` and ` field ` .
* /
fragment : any ,
2020-09-26 05:55:34 +08:00
}
2020-09-26 05:22:21 +08:00
2021-02-11 01:25:08 +08:00
export const Collaboration = Extension . create < CollaborationOptions > ( {
2020-12-02 16:44:46 +08:00
name : 'collaboration' ,
2021-10-04 12:53:59 +08:00
priority : 1000 ,
2021-10-27 00:31:13 +08:00
addOptions() {
return {
document : null ,
field : 'default' ,
fragment : null ,
}
2020-10-22 18:34:49 +08:00
} ,
2021-05-10 05:49:20 +08:00
onCreate() {
if ( this . editor . extensionManager . extensions . find ( extension = > extension . name === 'history' ) ) {
console . warn ( '[tiptap warn]: "@tiptap/extension-collaboration" comes with its own history support and is not compatible with "@tiptap/extension-history".' )
}
} ,
2020-12-02 16:28:55 +08:00
addCommands() {
return {
2021-02-22 17:40:56 +08:00
undo : ( ) = > ( { tr , state , dispatch } ) = > {
2020-12-02 19:05:35 +08:00
tr . setMeta ( 'preventDispatch' , true )
2021-02-22 17:40:56 +08:00
const undoManager : UndoManager = yUndoPluginKey . getState ( state ) . undoManager
if ( undoManager . undoStack . length === 0 ) {
return false
}
if ( ! dispatch ) {
return true
}
2020-12-02 16:28:55 +08:00
return undo ( state )
} ,
2021-02-22 17:40:56 +08:00
redo : ( ) = > ( { tr , state , dispatch } ) = > {
2020-12-02 19:05:35 +08:00
tr . setMeta ( 'preventDispatch' , true )
2021-02-22 17:40:56 +08:00
const undoManager : UndoManager = yUndoPluginKey . getState ( state ) . undoManager
if ( undoManager . redoStack . length === 0 ) {
return false
}
if ( ! dispatch ) {
return true
}
2020-12-02 16:28:55 +08:00
return redo ( state )
} ,
}
} ,
addKeyboardShortcuts() {
return {
'Mod-z' : ( ) = > this . editor . commands . undo ( ) ,
'Mod-y' : ( ) = > this . editor . commands . redo ( ) ,
'Shift-Mod-z' : ( ) = > this . editor . commands . redo ( ) ,
}
} ,
2020-10-22 18:34:49 +08:00
addProseMirrorPlugins() {
2021-01-12 01:37:30 +08:00
const fragment = this . options . fragment
? this . options . fragment
: this . options . document . getXmlFragment ( this . options . field )
2020-10-22 18:34:49 +08:00
return [
2021-01-12 01:37:30 +08:00
ySyncPlugin ( fragment ) ,
2020-10-22 18:34:49 +08:00
yUndoPlugin ( ) ,
]
} ,
} )