refactoring

This commit is contained in:
Philipp Kühn
2021-02-12 00:18:15 +01:00
parent cb8d71dfe6
commit c21b1d2cbc
3 changed files with 70 additions and 36 deletions

View File

@@ -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)

View File

@@ -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
} }
} }

View File

@@ -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