mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-01-18 06:03:22 +08:00
refactoring
This commit is contained in:
parent
cb8d71dfe6
commit
c21b1d2cbc
@ -14,6 +14,7 @@ export interface AnnotationPluginOptions {
|
||||
|
||||
export const AnnotationPlugin = (options: AnnotationPluginOptions) => new Plugin({
|
||||
key: AnnotationPluginKey,
|
||||
|
||||
state: {
|
||||
init() {
|
||||
return new AnnotationState({
|
||||
@ -25,6 +26,7 @@ export const AnnotationPlugin = (options: AnnotationPluginOptions) => new Plugin
|
||||
return pluginState.apply(transaction, newState)
|
||||
},
|
||||
},
|
||||
|
||||
props: {
|
||||
decorations(state) {
|
||||
const { decorations } = this.getState(state)
|
||||
|
@ -1,8 +1,9 @@
|
||||
// @ts-nocheck
|
||||
import * as Y from 'yjs'
|
||||
import { EditorState } from 'prosemirror-state'
|
||||
import { EditorState, Transaction } from 'prosemirror-state'
|
||||
import { Decoration, DecorationSet } from 'prosemirror-view'
|
||||
import { ySyncPluginKey, relativePositionToAbsolutePosition, absolutePositionToRelativePosition } from 'y-prosemirror'
|
||||
import { AddAnnotationAction, DeleteAnnotationAction } from './annotation'
|
||||
import { AnnotationPluginKey } from './AnnotationPlugin'
|
||||
|
||||
export interface AnnotationStateOptions {
|
||||
@ -39,57 +40,72 @@ export class AnnotationState {
|
||||
}
|
||||
}
|
||||
|
||||
addAnnotation(action: AddAnnotationAction, state: EditorState) {
|
||||
const ystate = ySyncPluginKey.getState(state)
|
||||
const { type, binding } = ystate
|
||||
const { map, HTMLAttributes } = this.options
|
||||
const { from, to, data } = action
|
||||
const absoluteFrom = absolutePositionToRelativePosition(from, type, binding.mapping)
|
||||
const absoluteTo = absolutePositionToRelativePosition(to, type, binding.mapping)
|
||||
|
||||
map.set(data.id, {
|
||||
from: absoluteFrom,
|
||||
to: absoluteTo,
|
||||
data,
|
||||
})
|
||||
|
||||
const decoration = Decoration.inline(from, to, HTMLAttributes, { data })
|
||||
|
||||
this.decorations = this.decorations.add(state.doc, [decoration])
|
||||
}
|
||||
|
||||
deleteAnnotation(id: number) {
|
||||
const { map } = this.options
|
||||
const decoration = this.findAnnotation(id)
|
||||
|
||||
map.delete(id)
|
||||
this.decorations = this.decorations.remove([decoration])
|
||||
}
|
||||
|
||||
annotationsAt(position: number) {
|
||||
return this.decorations?.find(position, position)
|
||||
}
|
||||
|
||||
apply(transaction: any, state: EditorState) {
|
||||
updateDecorations(state: EditorState) {
|
||||
const { map, HTMLAttributes } = this.options
|
||||
const ystate = ySyncPluginKey.getState(state)
|
||||
const { doc, type, binding } = ystate
|
||||
const action = transaction.getMeta(AnnotationPluginKey)
|
||||
|
||||
const decorations = Array.from(map.keys()).map(id => {
|
||||
const dec = map.get(id)
|
||||
const from = relativePositionToAbsolutePosition(doc, type, dec.from, binding.mapping)
|
||||
const to = relativePositionToAbsolutePosition(doc, type, dec.to, binding.mapping)
|
||||
const decoration = Decoration.inline(from, to, HTMLAttributes, { data: dec.data })
|
||||
|
||||
return decoration
|
||||
})
|
||||
|
||||
this.decorations = DecorationSet.create(state.doc, decorations)
|
||||
}
|
||||
|
||||
apply(transaction: Transaction, state: EditorState) {
|
||||
const ystate = ySyncPluginKey.getState(state)
|
||||
const action = transaction.getMeta(AnnotationPluginKey) as AddAnnotationAction | DeleteAnnotationAction
|
||||
|
||||
if (action && action.type) {
|
||||
const { from, to, data } = action
|
||||
|
||||
if (action.type === 'addAnnotation') {
|
||||
const absoluteFrom = absolutePositionToRelativePosition(from, type, binding.mapping)
|
||||
const absoluteTo = absolutePositionToRelativePosition(to, type, binding.mapping)
|
||||
|
||||
map.set(data.id, {
|
||||
from: absoluteFrom,
|
||||
to: absoluteTo,
|
||||
data,
|
||||
})
|
||||
|
||||
const decoration = Decoration.inline(from, to, HTMLAttributes, { data })
|
||||
|
||||
this.decorations = this.decorations.add(transaction.doc, [decoration])
|
||||
this.addAnnotation(action, state)
|
||||
}
|
||||
|
||||
if (action.type === 'deleteAnnotation') {
|
||||
map.delete(action.id)
|
||||
|
||||
const decoration = this.findAnnotation(action.id)
|
||||
|
||||
this.decorations = this.decorations.remove([decoration])
|
||||
this.deleteAnnotation(action.id)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
if (ystate.isChangeOrigin) {
|
||||
|
||||
const decorations = Array.from(map.keys()).map(id => {
|
||||
const dec = map.get(id)
|
||||
const from = relativePositionToAbsolutePosition(doc, type, dec.from, binding.mapping)
|
||||
const to = relativePositionToAbsolutePosition(doc, type, dec.to, binding.mapping)
|
||||
const decoration = Decoration.inline(from, to, HTMLAttributes, { data: dec.data })
|
||||
|
||||
return decoration
|
||||
})
|
||||
|
||||
this.decorations = DecorationSet.create(state.doc, decorations)
|
||||
this.updateDecorations(state)
|
||||
|
||||
return this
|
||||
}
|
||||
@ -99,4 +115,5 @@ export class AnnotationState {
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,18 @@ function randomId() {
|
||||
return Math.floor(Math.random() * 0xffffffff)
|
||||
}
|
||||
|
||||
export interface AddAnnotationAction {
|
||||
type: 'addAnnotation',
|
||||
from: number,
|
||||
to: number,
|
||||
data: AnnotationItem,
|
||||
}
|
||||
|
||||
export interface DeleteAnnotationAction {
|
||||
id: number,
|
||||
type: 'deleteAnnotation',
|
||||
}
|
||||
|
||||
export interface AnnotationOptions {
|
||||
HTMLAttributes: {
|
||||
[key: string]: any
|
||||
@ -49,7 +61,7 @@ export const Annotation = Extension.create({
|
||||
}
|
||||
|
||||
if (dispatch && content) {
|
||||
dispatch(state.tr.setMeta(AnnotationPluginKey, {
|
||||
state.tr.setMeta(AnnotationPluginKey, <AddAnnotationAction>{
|
||||
type: 'addAnnotation',
|
||||
from: selection.from,
|
||||
to: selection.to,
|
||||
@ -57,14 +69,17 @@ export const Annotation = Extension.create({
|
||||
randomId(),
|
||||
content,
|
||||
),
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
deleteAnnotation: (id: number): Command => ({ dispatch, state }) => {
|
||||
if (dispatch) {
|
||||
dispatch(state.tr.setMeta(AnnotationPluginKey, { type: 'deleteAnnotation', id }))
|
||||
state.tr.setMeta(AnnotationPluginKey, <DeleteAnnotationAction>{
|
||||
type: 'deleteAnnotation',
|
||||
id,
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
|
Loading…
Reference in New Issue
Block a user