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