fix: Prevent duplicate of comment marks through copy/paste. closes #6263
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { toggleMark } from "prosemirror-commands";
|
import { toggleMark } from "prosemirror-commands";
|
||||||
import { MarkSpec, MarkType, Schema } from "prosemirror-model";
|
import { MarkSpec, MarkType, Schema, Mark as PMMark } from "prosemirror-model";
|
||||||
import { Command, Plugin } from "prosemirror-state";
|
import { Command, Plugin } from "prosemirror-state";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import collapseSelection from "../commands/collapseSelection";
|
import collapseSelection from "../commands/collapseSelection";
|
||||||
@@ -106,6 +106,45 @@ export default class Comment extends Mark {
|
|||||||
get plugins(): Plugin[] {
|
get plugins(): Plugin[] {
|
||||||
return [
|
return [
|
||||||
new Plugin({
|
new Plugin({
|
||||||
|
appendTransaction(transactions, oldState, newState) {
|
||||||
|
if (
|
||||||
|
!transactions.some(
|
||||||
|
(transaction) => transaction.getMeta("uiEvent") === "paste"
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record existing comment marks
|
||||||
|
const existingComments: PMMark[] = [];
|
||||||
|
oldState.doc.descendants((node) => {
|
||||||
|
node.marks.forEach((mark) => {
|
||||||
|
if (mark.type.name === "comment") {
|
||||||
|
existingComments.push(mark);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove comment marks that are new duplicates of existing ones. This allows us to cut
|
||||||
|
// and paste a comment mark, but not copy and paste.
|
||||||
|
let tr = newState.tr;
|
||||||
|
newState.doc.descendants((node, pos) => {
|
||||||
|
node.marks.forEach((mark) => {
|
||||||
|
if (
|
||||||
|
mark.type.name === "comment" &&
|
||||||
|
existingComments.find((m) => m.attrs.id === mark.attrs.id) &&
|
||||||
|
!existingComments.find((m) => m === mark)
|
||||||
|
) {
|
||||||
|
tr = tr.removeMark(pos, pos + node.nodeSize, mark.type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return tr;
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
handleDOMEvents: {
|
handleDOMEvents: {
|
||||||
mouseup: (_view, event: MouseEvent) => {
|
mouseup: (_view, event: MouseEvent) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user