102 lines
2.5 KiB
TypeScript
102 lines
2.5 KiB
TypeScript
/**
|
|
* TipTap mark extensions for track-changes suggestions.
|
|
*
|
|
* SuggestionInsert: wraps text that was inserted in suggesting mode (green underline).
|
|
* SuggestionDelete: wraps text that was marked for deletion in suggesting mode (red strikethrough).
|
|
*
|
|
* Both marks are stored in the Yjs document and sync in real-time.
|
|
* Accept/reject logic is handled by the suggestion-plugin.
|
|
*/
|
|
|
|
import { Mark, mergeAttributes } from '@tiptap/core';
|
|
|
|
export const SuggestionInsertMark = Mark.create({
|
|
name: 'suggestionInsert',
|
|
|
|
addAttributes() {
|
|
return {
|
|
suggestionId: { default: null },
|
|
authorId: { default: null },
|
|
authorName: { default: null },
|
|
createdAt: { default: null },
|
|
};
|
|
},
|
|
|
|
parseHTML() {
|
|
return [
|
|
{
|
|
tag: 'span[data-suggestion-insert]',
|
|
getAttrs: (el) => {
|
|
const element = el as HTMLElement;
|
|
return {
|
|
suggestionId: element.getAttribute('data-suggestion-id'),
|
|
authorId: element.getAttribute('data-author-id'),
|
|
authorName: element.getAttribute('data-author-name'),
|
|
createdAt: Number(element.getAttribute('data-created-at')) || null,
|
|
};
|
|
},
|
|
},
|
|
];
|
|
},
|
|
|
|
renderHTML({ HTMLAttributes }) {
|
|
return [
|
|
'span',
|
|
mergeAttributes({
|
|
class: 'suggestion-insert',
|
|
'data-suggestion-insert': '',
|
|
'data-suggestion-id': HTMLAttributes.suggestionId,
|
|
'data-author-id': HTMLAttributes.authorId,
|
|
'data-author-name': HTMLAttributes.authorName,
|
|
'data-created-at': HTMLAttributes.createdAt,
|
|
}),
|
|
0,
|
|
];
|
|
},
|
|
});
|
|
|
|
export const SuggestionDeleteMark = Mark.create({
|
|
name: 'suggestionDelete',
|
|
|
|
addAttributes() {
|
|
return {
|
|
suggestionId: { default: null },
|
|
authorId: { default: null },
|
|
authorName: { default: null },
|
|
createdAt: { default: null },
|
|
};
|
|
},
|
|
|
|
parseHTML() {
|
|
return [
|
|
{
|
|
tag: 'span[data-suggestion-delete]',
|
|
getAttrs: (el) => {
|
|
const element = el as HTMLElement;
|
|
return {
|
|
suggestionId: element.getAttribute('data-suggestion-id'),
|
|
authorId: element.getAttribute('data-author-id'),
|
|
authorName: element.getAttribute('data-author-name'),
|
|
createdAt: Number(element.getAttribute('data-created-at')) || null,
|
|
};
|
|
},
|
|
},
|
|
];
|
|
},
|
|
|
|
renderHTML({ HTMLAttributes }) {
|
|
return [
|
|
'span',
|
|
mergeAttributes({
|
|
class: 'suggestion-delete',
|
|
'data-suggestion-delete': '',
|
|
'data-suggestion-id': HTMLAttributes.suggestionId,
|
|
'data-author-id': HTMLAttributes.authorId,
|
|
'data-author-name': HTMLAttributes.authorName,
|
|
'data-created-at': HTMLAttributes.createdAt,
|
|
}),
|
|
0,
|
|
];
|
|
},
|
|
});
|