@liveblocks/react-tiptap 3.15.4 → 3.16.0-feeds1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/comments/CommentsExtension.cjs +33 -0
- package/dist/comments/CommentsExtension.cjs.map +1 -1
- package/dist/comments/CommentsExtension.js +33 -0
- package/dist/comments/CommentsExtension.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +6 -6
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var core = require('@tiptap/core');
|
|
4
|
+
var model = require('@tiptap/pm/model');
|
|
4
5
|
var state = require('@tiptap/pm/state');
|
|
5
6
|
var view = require('@tiptap/pm/view');
|
|
6
7
|
var yProsemirror = require('y-prosemirror');
|
|
@@ -111,7 +112,39 @@ const Comment = core.Mark.create({
|
|
|
111
112
|
selectedThreadPos: selectedThreadId !== null ? threadPositions.get(selectedThreadId)?.to ?? null : null
|
|
112
113
|
};
|
|
113
114
|
};
|
|
115
|
+
const stripCommentMarks = (slice) => {
|
|
116
|
+
const stripFragment = (fragment) => {
|
|
117
|
+
let changed = false;
|
|
118
|
+
const nodes = [];
|
|
119
|
+
fragment.forEach((node) => {
|
|
120
|
+
const nextMarks = node.marks.filter(
|
|
121
|
+
(mark) => mark.type !== this.type
|
|
122
|
+
);
|
|
123
|
+
const marksChanged = nextMarks.length !== node.marks.length;
|
|
124
|
+
const nextContent = node.content.childCount > 0 ? stripFragment(node.content) : node.content;
|
|
125
|
+
const contentChanged = nextContent !== node.content;
|
|
126
|
+
if (marksChanged || contentChanged) {
|
|
127
|
+
changed = true;
|
|
128
|
+
nodes.push(
|
|
129
|
+
node.isText ? node.mark(nextMarks) : node.type.create(node.attrs, nextContent, nextMarks)
|
|
130
|
+
);
|
|
131
|
+
} else {
|
|
132
|
+
nodes.push(node);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
return changed ? model.Fragment.fromArray(nodes) : fragment;
|
|
136
|
+
};
|
|
137
|
+
const content = stripFragment(slice.content);
|
|
138
|
+
return content === slice.content ? slice : new model.Slice(content, slice.openStart, slice.openEnd);
|
|
139
|
+
};
|
|
114
140
|
return [
|
|
141
|
+
new state.Plugin({
|
|
142
|
+
key: new state.PluginKey("lb-comment-clipboard"),
|
|
143
|
+
props: {
|
|
144
|
+
transformCopied: (slice) => stripCommentMarks(slice),
|
|
145
|
+
transformPasted: (slice) => stripCommentMarks(slice)
|
|
146
|
+
}
|
|
147
|
+
}),
|
|
115
148
|
new state.Plugin({
|
|
116
149
|
key: types.THREADS_PLUGIN_KEY,
|
|
117
150
|
state: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommentsExtension.cjs","sources":["../../src/comments/CommentsExtension.ts"],"sourcesContent":["import { Extension, Mark, mergeAttributes } from \"@tiptap/core\";\nimport type { Node } from \"@tiptap/pm/model\";\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\nimport type { CommentsExtensionStorage, ThreadPluginState } from \"../types\";\nimport {\n LIVEBLOCKS_COMMENT_MARK_TYPE,\n ThreadPluginActions,\n THREADS_ACTIVE_SELECTION_PLUGIN,\n THREADS_PLUGIN_KEY,\n} from \"../types\";\n\ntype ThreadPluginAction = {\n name: ThreadPluginActions;\n data: string | null;\n};\n\nexport const FILTERED_THREADS_PLUGIN_KEY = new PluginKey<{\n filteredThreads?: Set<string>;\n}>();\n\n/**\n * Known issues: Overlapping marks are merged when reloading the doc. May be related:\n * https://github.com/ueberdosis/tiptap/issues/4339\n * https://github.com/yjs/y-prosemirror/issues/47\n */\nconst Comment = Mark.create({\n name: LIVEBLOCKS_COMMENT_MARK_TYPE,\n excludes: \"\",\n inclusive: false,\n keepOnSplit: true,\n parseHTML: () => {\n return [\n {\n tag: \"span\",\n getAttrs: (node) =>\n node.getAttribute(\"data-lb-thread-id\") !== null && null,\n },\n ];\n },\n addAttributes() {\n // Return an object with attribute configuration\n return {\n orphan: {\n parseHTML: (element) => !!element.getAttribute(\"data-orphan\"),\n renderHTML: (attributes) => {\n return (attributes as { orphan: boolean }).orphan\n ? {\n \"data-orphan\": \"true\",\n }\n : {};\n },\n default: false,\n },\n threadId: {\n parseHTML: (element) => element.getAttribute(\"data-lb-thread-id\"),\n renderHTML: (attributes) => {\n return {\n \"data-lb-thread-id\": (attributes as { threadId: string }).threadId,\n };\n },\n default: \"\",\n },\n };\n },\n\n renderHTML({ HTMLAttributes }: { HTMLAttributes: Record<string, any> }) {\n const filteredThreads = this.editor\n ? FILTERED_THREADS_PLUGIN_KEY.getState(this.editor.state)?.filteredThreads\n : undefined;\n const threadId = (HTMLAttributes as { [\"data-lb-thread-id\"]: string })[\n \"data-lb-thread-id\"\n ];\n if (filteredThreads && !filteredThreads.has(threadId)) {\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n \"data-hidden\": \"\",\n }),\n ];\n }\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n }),\n ];\n },\n\n /**\n * This plugin tracks the (first) position of each thread mark in the doc and creates a decoration for the selected thread\n */\n addProseMirrorPlugins() {\n const updateState = (doc: Node, selectedThreadId: string | null) => {\n const threadPositions = new Map<string, { from: number; to: number }>();\n const decorations: Decoration[] = [];\n // find all thread marks and store their position + create decoration for selected thread\n doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type === this.type) {\n const thisThreadId = (\n mark.attrs as { threadId: string | undefined }\n ).threadId;\n if (!thisThreadId) {\n return;\n }\n const from = pos;\n const to = from + node.nodeSize;\n\n // FloatingThreads component uses \"to\" as the position, so always store the largest \"to\" found\n // AnchoredThreads component uses \"from\" as the position, so always store the smallest \"from\" found\n const currentPosition = threadPositions.get(thisThreadId) ?? {\n from: Infinity,\n to: 0,\n };\n threadPositions.set(thisThreadId, {\n from: Math.min(from, currentPosition.from),\n to: Math.max(to, currentPosition.to),\n });\n\n if (selectedThreadId === thisThreadId) {\n decorations.push(\n Decoration.inline(from, to, {\n class: \"lb-root lb-tiptap-thread-mark-selected\",\n })\n );\n\n const decoration = this.editor.view.dom.querySelector(\n `.lb-tiptap-thread-mark[data-lb-thread-id=\"${thisThreadId}\"]`\n );\n\n if (decoration) {\n decoration.scrollIntoView({\n behavior: \"smooth\",\n block: \"nearest\",\n });\n }\n }\n }\n });\n });\n return {\n decorations: DecorationSet.create(doc, decorations),\n selectedThreadId,\n threadPositions,\n selectedThreadPos:\n selectedThreadId !== null\n ? (threadPositions.get(selectedThreadId)?.to ?? null)\n : null,\n };\n };\n\n return [\n new Plugin({\n key: THREADS_PLUGIN_KEY,\n state: {\n init() {\n return {\n threadPositions: new Map<string, { from: number; to: number }>(),\n selectedThreadId: null,\n selectedThreadPos: null,\n decorations: DecorationSet.empty,\n } as ThreadPluginState;\n },\n apply(tr, state) {\n const action = tr.getMeta(THREADS_PLUGIN_KEY) as ThreadPluginAction;\n if (!tr.docChanged && !action) {\n return state;\n }\n\n if (!action) {\n // Doc changed, but no action, just update rects\n return updateState(tr.doc, state.selectedThreadId);\n }\n // handle actions, possibly support more actions\n if (\n action.name === ThreadPluginActions.SET_SELECTED_THREAD_ID &&\n state.selectedThreadId !== action.data\n ) {\n return updateState(tr.doc, action.data);\n }\n\n return state;\n },\n },\n props: {\n decorations: (state) => {\n return (\n THREADS_PLUGIN_KEY.getState(state)?.decorations ??\n DecorationSet.empty\n );\n },\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return;\n }\n\n const selectThread = (threadId: string | null) => {\n view.dispatch(\n view.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: threadId,\n })\n );\n };\n\n const node = view.state.doc.nodeAt(pos);\n if (!node) {\n selectThread(null);\n return;\n }\n const commentMark = node.marks.find(\n (mark) => mark.type === this.type && !mark.attrs.orphan\n );\n // nothing to select\n if (!commentMark) {\n selectThread(null);\n return;\n }\n const threadId = commentMark?.attrs.threadId as string | undefined;\n\n const filtered = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n if (threadId && filtered && !filtered.has(threadId)) {\n selectThread(null);\n return;\n }\n\n selectThread(threadId ?? null);\n },\n },\n }),\n ];\n },\n});\n\nexport const CommentsExtension = Extension.create<\n { filteredThreads?: Set<string> },\n CommentsExtensionStorage\n>({\n name: \"liveblocksComments\",\n priority: 95,\n addExtensions() {\n return [Comment];\n },\n\n addStorage() {\n return {\n pendingComment: false,\n };\n },\n\n addCommands() {\n return {\n addPendingComment: () => () => {\n if (this.editor.state.selection.empty) {\n return false;\n }\n // unselect any open threads\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n this.storage.pendingComment = true;\n return true;\n },\n closePendingComment: () => () => {\n this.storage.pendingComment = false;\n return true;\n },\n selectThread: (id: string | null) => () => {\n const filtered = FILTERED_THREADS_PLUGIN_KEY.getState(\n this.editor.state\n )?.filteredThreads;\n if (id && filtered && !filtered.has(id)) {\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n return true;\n }\n\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: id,\n })\n );\n return true;\n },\n addComment:\n (id: string) =>\n ({ commands }) => {\n if (\n !this.storage.pendingComment ||\n this.editor.state.selection.empty\n ) {\n return false;\n }\n commands.setMark(LIVEBLOCKS_COMMENT_MARK_TYPE, { threadId: id });\n this.storage.pendingComment = false;\n return true;\n },\n };\n },\n onSelectionUpdate(\n this: { storage: CommentsExtensionStorage }, // NOTE: there are more types here I didn't override, this gets removed after submitting PR to tiptap\n { transaction }: { transaction: Transaction } // TODO: remove this after submitting PR to tiptap\n ) {\n // ignore changes made by yjs\n if (!this.storage.pendingComment || transaction.getMeta(ySyncPluginKey)) {\n return;\n }\n // if selection changes, hide the composer. We could keep the composer open and move it to the new selection?\n this.storage.pendingComment = false;\n },\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: THREADS_ACTIVE_SELECTION_PLUGIN,\n props: {\n decorations: ({ doc, selection }) => {\n if (!this.storage.pendingComment) {\n return DecorationSet.create(doc, []);\n }\n const { from, to } = selection;\n const decorations: Decoration[] = [\n Decoration.inline(from, to, {\n class: \"lb-root lb-selection lb-tiptap-active-selection\",\n }),\n ];\n return DecorationSet.create(doc, decorations);\n },\n },\n }),\n new Plugin({\n key: FILTERED_THREADS_PLUGIN_KEY,\n state: {\n init: () => ({\n filteredThreads: this.options.filteredThreads,\n }),\n apply(tr, value) {\n const meta = tr.getMeta(FILTERED_THREADS_PLUGIN_KEY) as\n | { filteredThreads?: Set<string> }\n | undefined;\n if (meta?.filteredThreads) {\n return { filteredThreads: meta.filteredThreads };\n }\n return value;\n },\n },\n view: (view) => {\n const syncDom = () => {\n const filteredThreads = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n\n // Toggle attribute for all comment-mark spans\n const els = view.dom.querySelectorAll<HTMLElement>(\n \"span.lb-tiptap-thread-mark[data-lb-thread-id]\"\n );\n els.forEach((el) => {\n const id = el.getAttribute(\"data-lb-thread-id\");\n if (!id) return;\n if (!filteredThreads || filteredThreads.has(id)) {\n el.removeAttribute(\"data-hidden\");\n } else {\n el.setAttribute(\"data-hidden\", \"\");\n }\n });\n };\n\n queueMicrotask(syncDom);\n\n return {\n update: (view, prevState) => {\n const curr = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n const prev =\n FILTERED_THREADS_PLUGIN_KEY.getState(\n prevState\n )?.filteredThreads;\n\n if (\n !areSetsEqual(prev, curr) ||\n view.state.doc !== prevState.doc\n ) {\n syncDom();\n\n const selected = THREADS_PLUGIN_KEY.getState(\n view.state\n )?.selectedThreadId;\n if (selected && curr && !curr.has(selected)) {\n view.dispatch(\n view.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n }\n }\n },\n };\n },\n }),\n ];\n },\n});\n\nexport function areSetsEqual(a?: Set<string>, b?: Set<string>): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n if (a.size !== b.size) return false;\n for (const v of a) if (!b.has(v)) return false;\n return true;\n}\n"],"names":["PluginKey","Mark","LIVEBLOCKS_COMMENT_MARK_TYPE","mergeAttributes","Decoration","DecorationSet","Plugin","THREADS_PLUGIN_KEY","ThreadPluginActions","threadId","Extension","ySyncPluginKey","THREADS_ACTIVE_SELECTION_PLUGIN","view"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CommentsExtension.cjs","sources":["../../src/comments/CommentsExtension.ts"],"sourcesContent":["import { Extension, Mark, mergeAttributes } from \"@tiptap/core\";\nimport type { Node } from \"@tiptap/pm/model\";\nimport { Fragment, Slice } from \"@tiptap/pm/model\";\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\nimport type { CommentsExtensionStorage, ThreadPluginState } from \"../types\";\nimport {\n LIVEBLOCKS_COMMENT_MARK_TYPE,\n ThreadPluginActions,\n THREADS_ACTIVE_SELECTION_PLUGIN,\n THREADS_PLUGIN_KEY,\n} from \"../types\";\n\ntype ThreadPluginAction = {\n name: ThreadPluginActions;\n data: string | null;\n};\n\nexport const FILTERED_THREADS_PLUGIN_KEY = new PluginKey<{\n filteredThreads?: Set<string>;\n}>();\n\n/**\n * Known issues: Overlapping marks are merged when reloading the doc. May be related:\n * https://github.com/ueberdosis/tiptap/issues/4339\n * https://github.com/yjs/y-prosemirror/issues/47\n */\nconst Comment = Mark.create({\n name: LIVEBLOCKS_COMMENT_MARK_TYPE,\n excludes: \"\",\n inclusive: false,\n keepOnSplit: true,\n parseHTML: () => {\n return [\n {\n tag: \"span\",\n getAttrs: (node) =>\n node.getAttribute(\"data-lb-thread-id\") !== null && null,\n },\n ];\n },\n addAttributes() {\n // Return an object with attribute configuration\n return {\n orphan: {\n parseHTML: (element) => !!element.getAttribute(\"data-orphan\"),\n renderHTML: (attributes) => {\n return (attributes as { orphan: boolean }).orphan\n ? {\n \"data-orphan\": \"true\",\n }\n : {};\n },\n default: false,\n },\n threadId: {\n parseHTML: (element) => element.getAttribute(\"data-lb-thread-id\"),\n renderHTML: (attributes) => {\n return {\n \"data-lb-thread-id\": (attributes as { threadId: string }).threadId,\n };\n },\n default: \"\",\n },\n };\n },\n\n renderHTML({ HTMLAttributes }: { HTMLAttributes: Record<string, any> }) {\n const filteredThreads = this.editor\n ? FILTERED_THREADS_PLUGIN_KEY.getState(this.editor.state)?.filteredThreads\n : undefined;\n const threadId = (HTMLAttributes as { [\"data-lb-thread-id\"]: string })[\n \"data-lb-thread-id\"\n ];\n if (filteredThreads && !filteredThreads.has(threadId)) {\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n \"data-hidden\": \"\",\n }),\n ];\n }\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n }),\n ];\n },\n\n /**\n * This plugin tracks the (first) position of each thread mark in the doc and creates a decoration for the selected thread\n */\n addProseMirrorPlugins() {\n const updateState = (doc: Node, selectedThreadId: string | null) => {\n const threadPositions = new Map<string, { from: number; to: number }>();\n const decorations: Decoration[] = [];\n // find all thread marks and store their position + create decoration for selected thread\n doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type === this.type) {\n const thisThreadId = (\n mark.attrs as { threadId: string | undefined }\n ).threadId;\n if (!thisThreadId) {\n return;\n }\n const from = pos;\n const to = from + node.nodeSize;\n\n // FloatingThreads component uses \"to\" as the position, so always store the largest \"to\" found\n // AnchoredThreads component uses \"from\" as the position, so always store the smallest \"from\" found\n const currentPosition = threadPositions.get(thisThreadId) ?? {\n from: Infinity,\n to: 0,\n };\n threadPositions.set(thisThreadId, {\n from: Math.min(from, currentPosition.from),\n to: Math.max(to, currentPosition.to),\n });\n\n if (selectedThreadId === thisThreadId) {\n decorations.push(\n Decoration.inline(from, to, {\n class: \"lb-root lb-tiptap-thread-mark-selected\",\n })\n );\n\n const decoration = this.editor.view.dom.querySelector(\n `.lb-tiptap-thread-mark[data-lb-thread-id=\"${thisThreadId}\"]`\n );\n\n if (decoration) {\n decoration.scrollIntoView({\n behavior: \"smooth\",\n block: \"nearest\",\n });\n }\n }\n }\n });\n });\n return {\n decorations: DecorationSet.create(doc, decorations),\n selectedThreadId,\n threadPositions,\n selectedThreadPos:\n selectedThreadId !== null\n ? (threadPositions.get(selectedThreadId)?.to ?? null)\n : null,\n };\n };\n\n // Recursively walks a Fragment and removes only this extension's comment mark from every node it finds.\n const stripCommentMarks = (slice: Slice): Slice => {\n const stripFragment = (fragment: Fragment): Fragment => {\n let changed = false;\n const nodes: Node[] = [];\n\n fragment.forEach((node) => {\n // Filter out this extension's comment mark from the node's marks so that it is not copied to the clipboard\n const nextMarks = node.marks.filter(\n (mark) => mark.type !== this.type\n );\n const marksChanged = nextMarks.length !== node.marks.length;\n\n // Recursively strip comment marks from child content (e.g. inline content inside paragraphs, list items)\n const nextContent =\n node.content.childCount > 0\n ? stripFragment(node.content)\n : node.content;\n const contentChanged = nextContent !== node.content;\n\n if (marksChanged || contentChanged) {\n changed = true;\n nodes.push(\n node.isText\n ? node.mark(nextMarks)\n : node.type.create(node.attrs, nextContent, nextMarks)\n );\n } else {\n nodes.push(node);\n }\n });\n\n return changed ? Fragment.fromArray(nodes) : fragment;\n };\n\n const content = stripFragment(slice.content);\n return content === slice.content\n ? slice\n : new Slice(content, slice.openStart, slice.openEnd);\n };\n\n return [\n new Plugin({\n key: new PluginKey(\"lb-comment-clipboard\"),\n props: {\n transformCopied: (slice) => stripCommentMarks(slice),\n transformPasted: (slice) => stripCommentMarks(slice),\n },\n }),\n new Plugin({\n key: THREADS_PLUGIN_KEY,\n state: {\n init() {\n return {\n threadPositions: new Map<string, { from: number; to: number }>(),\n selectedThreadId: null,\n selectedThreadPos: null,\n decorations: DecorationSet.empty,\n } as ThreadPluginState;\n },\n apply(tr, state) {\n const action = tr.getMeta(THREADS_PLUGIN_KEY) as ThreadPluginAction;\n if (!tr.docChanged && !action) {\n return state;\n }\n\n if (!action) {\n // Doc changed, but no action, just update rects\n return updateState(tr.doc, state.selectedThreadId);\n }\n // handle actions, possibly support more actions\n if (\n action.name === ThreadPluginActions.SET_SELECTED_THREAD_ID &&\n state.selectedThreadId !== action.data\n ) {\n return updateState(tr.doc, action.data);\n }\n\n return state;\n },\n },\n props: {\n decorations: (state) => {\n return (\n THREADS_PLUGIN_KEY.getState(state)?.decorations ??\n DecorationSet.empty\n );\n },\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return;\n }\n\n const selectThread = (threadId: string | null) => {\n view.dispatch(\n view.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: threadId,\n })\n );\n };\n\n const node = view.state.doc.nodeAt(pos);\n if (!node) {\n selectThread(null);\n return;\n }\n const commentMark = node.marks.find(\n (mark) => mark.type === this.type && !mark.attrs.orphan\n );\n // nothing to select\n if (!commentMark) {\n selectThread(null);\n return;\n }\n const threadId = commentMark?.attrs.threadId as string | undefined;\n\n const filtered = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n if (threadId && filtered && !filtered.has(threadId)) {\n selectThread(null);\n return;\n }\n\n selectThread(threadId ?? null);\n },\n },\n }),\n ];\n },\n});\n\nexport const CommentsExtension = Extension.create<\n { filteredThreads?: Set<string> },\n CommentsExtensionStorage\n>({\n name: \"liveblocksComments\",\n priority: 95,\n addExtensions() {\n return [Comment];\n },\n\n addStorage() {\n return {\n pendingComment: false,\n };\n },\n\n addCommands() {\n return {\n addPendingComment: () => () => {\n if (this.editor.state.selection.empty) {\n return false;\n }\n // unselect any open threads\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n this.storage.pendingComment = true;\n return true;\n },\n closePendingComment: () => () => {\n this.storage.pendingComment = false;\n return true;\n },\n selectThread: (id: string | null) => () => {\n const filtered = FILTERED_THREADS_PLUGIN_KEY.getState(\n this.editor.state\n )?.filteredThreads;\n if (id && filtered && !filtered.has(id)) {\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n return true;\n }\n\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: id,\n })\n );\n return true;\n },\n addComment:\n (id: string) =>\n ({ commands }) => {\n if (\n !this.storage.pendingComment ||\n this.editor.state.selection.empty\n ) {\n return false;\n }\n commands.setMark(LIVEBLOCKS_COMMENT_MARK_TYPE, { threadId: id });\n this.storage.pendingComment = false;\n return true;\n },\n };\n },\n onSelectionUpdate(\n this: { storage: CommentsExtensionStorage }, // NOTE: there are more types here I didn't override, this gets removed after submitting PR to tiptap\n { transaction }: { transaction: Transaction } // TODO: remove this after submitting PR to tiptap\n ) {\n // ignore changes made by yjs\n if (!this.storage.pendingComment || transaction.getMeta(ySyncPluginKey)) {\n return;\n }\n // if selection changes, hide the composer. We could keep the composer open and move it to the new selection?\n this.storage.pendingComment = false;\n },\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: THREADS_ACTIVE_SELECTION_PLUGIN,\n props: {\n decorations: ({ doc, selection }) => {\n if (!this.storage.pendingComment) {\n return DecorationSet.create(doc, []);\n }\n const { from, to } = selection;\n const decorations: Decoration[] = [\n Decoration.inline(from, to, {\n class: \"lb-root lb-selection lb-tiptap-active-selection\",\n }),\n ];\n return DecorationSet.create(doc, decorations);\n },\n },\n }),\n new Plugin({\n key: FILTERED_THREADS_PLUGIN_KEY,\n state: {\n init: () => ({\n filteredThreads: this.options.filteredThreads,\n }),\n apply(tr, value) {\n const meta = tr.getMeta(FILTERED_THREADS_PLUGIN_KEY) as\n | { filteredThreads?: Set<string> }\n | undefined;\n if (meta?.filteredThreads) {\n return { filteredThreads: meta.filteredThreads };\n }\n return value;\n },\n },\n view: (view) => {\n const syncDom = () => {\n const filteredThreads = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n\n // Toggle attribute for all comment-mark spans\n const els = view.dom.querySelectorAll<HTMLElement>(\n \"span.lb-tiptap-thread-mark[data-lb-thread-id]\"\n );\n els.forEach((el) => {\n const id = el.getAttribute(\"data-lb-thread-id\");\n if (!id) return;\n if (!filteredThreads || filteredThreads.has(id)) {\n el.removeAttribute(\"data-hidden\");\n } else {\n el.setAttribute(\"data-hidden\", \"\");\n }\n });\n };\n\n queueMicrotask(syncDom);\n\n return {\n update: (view, prevState) => {\n const curr = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n const prev =\n FILTERED_THREADS_PLUGIN_KEY.getState(\n prevState\n )?.filteredThreads;\n\n if (\n !areSetsEqual(prev, curr) ||\n view.state.doc !== prevState.doc\n ) {\n syncDom();\n\n const selected = THREADS_PLUGIN_KEY.getState(\n view.state\n )?.selectedThreadId;\n if (selected && curr && !curr.has(selected)) {\n view.dispatch(\n view.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n }\n }\n },\n };\n },\n }),\n ];\n },\n});\n\nexport function areSetsEqual(a?: Set<string>, b?: Set<string>): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n if (a.size !== b.size) return false;\n for (const v of a) if (!b.has(v)) return false;\n return true;\n}\n"],"names":["PluginKey","Mark","LIVEBLOCKS_COMMENT_MARK_TYPE","mergeAttributes","Decoration","DecorationSet","Fragment","Slice","Plugin","THREADS_PLUGIN_KEY","ThreadPluginActions","threadId","Extension","ySyncPluginKey","THREADS_ACTIVE_SELECTION_PLUGIN","view"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Mark, mergeAttributes, Extension } from '@tiptap/core';
|
|
2
|
+
import { Fragment, Slice } from '@tiptap/pm/model';
|
|
2
3
|
import { PluginKey, Plugin } from '@tiptap/pm/state';
|
|
3
4
|
import { Decoration, DecorationSet } from '@tiptap/pm/view';
|
|
4
5
|
import { ySyncPluginKey } from 'y-prosemirror';
|
|
@@ -109,7 +110,39 @@ const Comment = Mark.create({
|
|
|
109
110
|
selectedThreadPos: selectedThreadId !== null ? threadPositions.get(selectedThreadId)?.to ?? null : null
|
|
110
111
|
};
|
|
111
112
|
};
|
|
113
|
+
const stripCommentMarks = (slice) => {
|
|
114
|
+
const stripFragment = (fragment) => {
|
|
115
|
+
let changed = false;
|
|
116
|
+
const nodes = [];
|
|
117
|
+
fragment.forEach((node) => {
|
|
118
|
+
const nextMarks = node.marks.filter(
|
|
119
|
+
(mark) => mark.type !== this.type
|
|
120
|
+
);
|
|
121
|
+
const marksChanged = nextMarks.length !== node.marks.length;
|
|
122
|
+
const nextContent = node.content.childCount > 0 ? stripFragment(node.content) : node.content;
|
|
123
|
+
const contentChanged = nextContent !== node.content;
|
|
124
|
+
if (marksChanged || contentChanged) {
|
|
125
|
+
changed = true;
|
|
126
|
+
nodes.push(
|
|
127
|
+
node.isText ? node.mark(nextMarks) : node.type.create(node.attrs, nextContent, nextMarks)
|
|
128
|
+
);
|
|
129
|
+
} else {
|
|
130
|
+
nodes.push(node);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
return changed ? Fragment.fromArray(nodes) : fragment;
|
|
134
|
+
};
|
|
135
|
+
const content = stripFragment(slice.content);
|
|
136
|
+
return content === slice.content ? slice : new Slice(content, slice.openStart, slice.openEnd);
|
|
137
|
+
};
|
|
112
138
|
return [
|
|
139
|
+
new Plugin({
|
|
140
|
+
key: new PluginKey("lb-comment-clipboard"),
|
|
141
|
+
props: {
|
|
142
|
+
transformCopied: (slice) => stripCommentMarks(slice),
|
|
143
|
+
transformPasted: (slice) => stripCommentMarks(slice)
|
|
144
|
+
}
|
|
145
|
+
}),
|
|
113
146
|
new Plugin({
|
|
114
147
|
key: THREADS_PLUGIN_KEY,
|
|
115
148
|
state: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommentsExtension.js","sources":["../../src/comments/CommentsExtension.ts"],"sourcesContent":["import { Extension, Mark, mergeAttributes } from \"@tiptap/core\";\nimport type { Node } from \"@tiptap/pm/model\";\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\nimport type { CommentsExtensionStorage, ThreadPluginState } from \"../types\";\nimport {\n LIVEBLOCKS_COMMENT_MARK_TYPE,\n ThreadPluginActions,\n THREADS_ACTIVE_SELECTION_PLUGIN,\n THREADS_PLUGIN_KEY,\n} from \"../types\";\n\ntype ThreadPluginAction = {\n name: ThreadPluginActions;\n data: string | null;\n};\n\nexport const FILTERED_THREADS_PLUGIN_KEY = new PluginKey<{\n filteredThreads?: Set<string>;\n}>();\n\n/**\n * Known issues: Overlapping marks are merged when reloading the doc. May be related:\n * https://github.com/ueberdosis/tiptap/issues/4339\n * https://github.com/yjs/y-prosemirror/issues/47\n */\nconst Comment = Mark.create({\n name: LIVEBLOCKS_COMMENT_MARK_TYPE,\n excludes: \"\",\n inclusive: false,\n keepOnSplit: true,\n parseHTML: () => {\n return [\n {\n tag: \"span\",\n getAttrs: (node) =>\n node.getAttribute(\"data-lb-thread-id\") !== null && null,\n },\n ];\n },\n addAttributes() {\n // Return an object with attribute configuration\n return {\n orphan: {\n parseHTML: (element) => !!element.getAttribute(\"data-orphan\"),\n renderHTML: (attributes) => {\n return (attributes as { orphan: boolean }).orphan\n ? {\n \"data-orphan\": \"true\",\n }\n : {};\n },\n default: false,\n },\n threadId: {\n parseHTML: (element) => element.getAttribute(\"data-lb-thread-id\"),\n renderHTML: (attributes) => {\n return {\n \"data-lb-thread-id\": (attributes as { threadId: string }).threadId,\n };\n },\n default: \"\",\n },\n };\n },\n\n renderHTML({ HTMLAttributes }: { HTMLAttributes: Record<string, any> }) {\n const filteredThreads = this.editor\n ? FILTERED_THREADS_PLUGIN_KEY.getState(this.editor.state)?.filteredThreads\n : undefined;\n const threadId = (HTMLAttributes as { [\"data-lb-thread-id\"]: string })[\n \"data-lb-thread-id\"\n ];\n if (filteredThreads && !filteredThreads.has(threadId)) {\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n \"data-hidden\": \"\",\n }),\n ];\n }\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n }),\n ];\n },\n\n /**\n * This plugin tracks the (first) position of each thread mark in the doc and creates a decoration for the selected thread\n */\n addProseMirrorPlugins() {\n const updateState = (doc: Node, selectedThreadId: string | null) => {\n const threadPositions = new Map<string, { from: number; to: number }>();\n const decorations: Decoration[] = [];\n // find all thread marks and store their position + create decoration for selected thread\n doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type === this.type) {\n const thisThreadId = (\n mark.attrs as { threadId: string | undefined }\n ).threadId;\n if (!thisThreadId) {\n return;\n }\n const from = pos;\n const to = from + node.nodeSize;\n\n // FloatingThreads component uses \"to\" as the position, so always store the largest \"to\" found\n // AnchoredThreads component uses \"from\" as the position, so always store the smallest \"from\" found\n const currentPosition = threadPositions.get(thisThreadId) ?? {\n from: Infinity,\n to: 0,\n };\n threadPositions.set(thisThreadId, {\n from: Math.min(from, currentPosition.from),\n to: Math.max(to, currentPosition.to),\n });\n\n if (selectedThreadId === thisThreadId) {\n decorations.push(\n Decoration.inline(from, to, {\n class: \"lb-root lb-tiptap-thread-mark-selected\",\n })\n );\n\n const decoration = this.editor.view.dom.querySelector(\n `.lb-tiptap-thread-mark[data-lb-thread-id=\"${thisThreadId}\"]`\n );\n\n if (decoration) {\n decoration.scrollIntoView({\n behavior: \"smooth\",\n block: \"nearest\",\n });\n }\n }\n }\n });\n });\n return {\n decorations: DecorationSet.create(doc, decorations),\n selectedThreadId,\n threadPositions,\n selectedThreadPos:\n selectedThreadId !== null\n ? (threadPositions.get(selectedThreadId)?.to ?? null)\n : null,\n };\n };\n\n return [\n new Plugin({\n key: THREADS_PLUGIN_KEY,\n state: {\n init() {\n return {\n threadPositions: new Map<string, { from: number; to: number }>(),\n selectedThreadId: null,\n selectedThreadPos: null,\n decorations: DecorationSet.empty,\n } as ThreadPluginState;\n },\n apply(tr, state) {\n const action = tr.getMeta(THREADS_PLUGIN_KEY) as ThreadPluginAction;\n if (!tr.docChanged && !action) {\n return state;\n }\n\n if (!action) {\n // Doc changed, but no action, just update rects\n return updateState(tr.doc, state.selectedThreadId);\n }\n // handle actions, possibly support more actions\n if (\n action.name === ThreadPluginActions.SET_SELECTED_THREAD_ID &&\n state.selectedThreadId !== action.data\n ) {\n return updateState(tr.doc, action.data);\n }\n\n return state;\n },\n },\n props: {\n decorations: (state) => {\n return (\n THREADS_PLUGIN_KEY.getState(state)?.decorations ??\n DecorationSet.empty\n );\n },\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return;\n }\n\n const selectThread = (threadId: string | null) => {\n view.dispatch(\n view.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: threadId,\n })\n );\n };\n\n const node = view.state.doc.nodeAt(pos);\n if (!node) {\n selectThread(null);\n return;\n }\n const commentMark = node.marks.find(\n (mark) => mark.type === this.type && !mark.attrs.orphan\n );\n // nothing to select\n if (!commentMark) {\n selectThread(null);\n return;\n }\n const threadId = commentMark?.attrs.threadId as string | undefined;\n\n const filtered = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n if (threadId && filtered && !filtered.has(threadId)) {\n selectThread(null);\n return;\n }\n\n selectThread(threadId ?? null);\n },\n },\n }),\n ];\n },\n});\n\nexport const CommentsExtension = Extension.create<\n { filteredThreads?: Set<string> },\n CommentsExtensionStorage\n>({\n name: \"liveblocksComments\",\n priority: 95,\n addExtensions() {\n return [Comment];\n },\n\n addStorage() {\n return {\n pendingComment: false,\n };\n },\n\n addCommands() {\n return {\n addPendingComment: () => () => {\n if (this.editor.state.selection.empty) {\n return false;\n }\n // unselect any open threads\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n this.storage.pendingComment = true;\n return true;\n },\n closePendingComment: () => () => {\n this.storage.pendingComment = false;\n return true;\n },\n selectThread: (id: string | null) => () => {\n const filtered = FILTERED_THREADS_PLUGIN_KEY.getState(\n this.editor.state\n )?.filteredThreads;\n if (id && filtered && !filtered.has(id)) {\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n return true;\n }\n\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: id,\n })\n );\n return true;\n },\n addComment:\n (id: string) =>\n ({ commands }) => {\n if (\n !this.storage.pendingComment ||\n this.editor.state.selection.empty\n ) {\n return false;\n }\n commands.setMark(LIVEBLOCKS_COMMENT_MARK_TYPE, { threadId: id });\n this.storage.pendingComment = false;\n return true;\n },\n };\n },\n onSelectionUpdate(\n this: { storage: CommentsExtensionStorage }, // NOTE: there are more types here I didn't override, this gets removed after submitting PR to tiptap\n { transaction }: { transaction: Transaction } // TODO: remove this after submitting PR to tiptap\n ) {\n // ignore changes made by yjs\n if (!this.storage.pendingComment || transaction.getMeta(ySyncPluginKey)) {\n return;\n }\n // if selection changes, hide the composer. We could keep the composer open and move it to the new selection?\n this.storage.pendingComment = false;\n },\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: THREADS_ACTIVE_SELECTION_PLUGIN,\n props: {\n decorations: ({ doc, selection }) => {\n if (!this.storage.pendingComment) {\n return DecorationSet.create(doc, []);\n }\n const { from, to } = selection;\n const decorations: Decoration[] = [\n Decoration.inline(from, to, {\n class: \"lb-root lb-selection lb-tiptap-active-selection\",\n }),\n ];\n return DecorationSet.create(doc, decorations);\n },\n },\n }),\n new Plugin({\n key: FILTERED_THREADS_PLUGIN_KEY,\n state: {\n init: () => ({\n filteredThreads: this.options.filteredThreads,\n }),\n apply(tr, value) {\n const meta = tr.getMeta(FILTERED_THREADS_PLUGIN_KEY) as\n | { filteredThreads?: Set<string> }\n | undefined;\n if (meta?.filteredThreads) {\n return { filteredThreads: meta.filteredThreads };\n }\n return value;\n },\n },\n view: (view) => {\n const syncDom = () => {\n const filteredThreads = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n\n // Toggle attribute for all comment-mark spans\n const els = view.dom.querySelectorAll<HTMLElement>(\n \"span.lb-tiptap-thread-mark[data-lb-thread-id]\"\n );\n els.forEach((el) => {\n const id = el.getAttribute(\"data-lb-thread-id\");\n if (!id) return;\n if (!filteredThreads || filteredThreads.has(id)) {\n el.removeAttribute(\"data-hidden\");\n } else {\n el.setAttribute(\"data-hidden\", \"\");\n }\n });\n };\n\n queueMicrotask(syncDom);\n\n return {\n update: (view, prevState) => {\n const curr = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n const prev =\n FILTERED_THREADS_PLUGIN_KEY.getState(\n prevState\n )?.filteredThreads;\n\n if (\n !areSetsEqual(prev, curr) ||\n view.state.doc !== prevState.doc\n ) {\n syncDom();\n\n const selected = THREADS_PLUGIN_KEY.getState(\n view.state\n )?.selectedThreadId;\n if (selected && curr && !curr.has(selected)) {\n view.dispatch(\n view.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n }\n }\n },\n };\n },\n }),\n ];\n },\n});\n\nexport function areSetsEqual(a?: Set<string>, b?: Set<string>): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n if (a.size !== b.size) return false;\n for (const v of a) if (!b.has(v)) return false;\n return true;\n}\n"],"names":["threadId","view"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CommentsExtension.js","sources":["../../src/comments/CommentsExtension.ts"],"sourcesContent":["import { Extension, Mark, mergeAttributes } from \"@tiptap/core\";\nimport type { Node } from \"@tiptap/pm/model\";\nimport { Fragment, Slice } from \"@tiptap/pm/model\";\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\nimport type { CommentsExtensionStorage, ThreadPluginState } from \"../types\";\nimport {\n LIVEBLOCKS_COMMENT_MARK_TYPE,\n ThreadPluginActions,\n THREADS_ACTIVE_SELECTION_PLUGIN,\n THREADS_PLUGIN_KEY,\n} from \"../types\";\n\ntype ThreadPluginAction = {\n name: ThreadPluginActions;\n data: string | null;\n};\n\nexport const FILTERED_THREADS_PLUGIN_KEY = new PluginKey<{\n filteredThreads?: Set<string>;\n}>();\n\n/**\n * Known issues: Overlapping marks are merged when reloading the doc. May be related:\n * https://github.com/ueberdosis/tiptap/issues/4339\n * https://github.com/yjs/y-prosemirror/issues/47\n */\nconst Comment = Mark.create({\n name: LIVEBLOCKS_COMMENT_MARK_TYPE,\n excludes: \"\",\n inclusive: false,\n keepOnSplit: true,\n parseHTML: () => {\n return [\n {\n tag: \"span\",\n getAttrs: (node) =>\n node.getAttribute(\"data-lb-thread-id\") !== null && null,\n },\n ];\n },\n addAttributes() {\n // Return an object with attribute configuration\n return {\n orphan: {\n parseHTML: (element) => !!element.getAttribute(\"data-orphan\"),\n renderHTML: (attributes) => {\n return (attributes as { orphan: boolean }).orphan\n ? {\n \"data-orphan\": \"true\",\n }\n : {};\n },\n default: false,\n },\n threadId: {\n parseHTML: (element) => element.getAttribute(\"data-lb-thread-id\"),\n renderHTML: (attributes) => {\n return {\n \"data-lb-thread-id\": (attributes as { threadId: string }).threadId,\n };\n },\n default: \"\",\n },\n };\n },\n\n renderHTML({ HTMLAttributes }: { HTMLAttributes: Record<string, any> }) {\n const filteredThreads = this.editor\n ? FILTERED_THREADS_PLUGIN_KEY.getState(this.editor.state)?.filteredThreads\n : undefined;\n const threadId = (HTMLAttributes as { [\"data-lb-thread-id\"]: string })[\n \"data-lb-thread-id\"\n ];\n if (filteredThreads && !filteredThreads.has(threadId)) {\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n \"data-hidden\": \"\",\n }),\n ];\n }\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n class: \"lb-root lb-tiptap-thread-mark\",\n }),\n ];\n },\n\n /**\n * This plugin tracks the (first) position of each thread mark in the doc and creates a decoration for the selected thread\n */\n addProseMirrorPlugins() {\n const updateState = (doc: Node, selectedThreadId: string | null) => {\n const threadPositions = new Map<string, { from: number; to: number }>();\n const decorations: Decoration[] = [];\n // find all thread marks and store their position + create decoration for selected thread\n doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type === this.type) {\n const thisThreadId = (\n mark.attrs as { threadId: string | undefined }\n ).threadId;\n if (!thisThreadId) {\n return;\n }\n const from = pos;\n const to = from + node.nodeSize;\n\n // FloatingThreads component uses \"to\" as the position, so always store the largest \"to\" found\n // AnchoredThreads component uses \"from\" as the position, so always store the smallest \"from\" found\n const currentPosition = threadPositions.get(thisThreadId) ?? {\n from: Infinity,\n to: 0,\n };\n threadPositions.set(thisThreadId, {\n from: Math.min(from, currentPosition.from),\n to: Math.max(to, currentPosition.to),\n });\n\n if (selectedThreadId === thisThreadId) {\n decorations.push(\n Decoration.inline(from, to, {\n class: \"lb-root lb-tiptap-thread-mark-selected\",\n })\n );\n\n const decoration = this.editor.view.dom.querySelector(\n `.lb-tiptap-thread-mark[data-lb-thread-id=\"${thisThreadId}\"]`\n );\n\n if (decoration) {\n decoration.scrollIntoView({\n behavior: \"smooth\",\n block: \"nearest\",\n });\n }\n }\n }\n });\n });\n return {\n decorations: DecorationSet.create(doc, decorations),\n selectedThreadId,\n threadPositions,\n selectedThreadPos:\n selectedThreadId !== null\n ? (threadPositions.get(selectedThreadId)?.to ?? null)\n : null,\n };\n };\n\n // Recursively walks a Fragment and removes only this extension's comment mark from every node it finds.\n const stripCommentMarks = (slice: Slice): Slice => {\n const stripFragment = (fragment: Fragment): Fragment => {\n let changed = false;\n const nodes: Node[] = [];\n\n fragment.forEach((node) => {\n // Filter out this extension's comment mark from the node's marks so that it is not copied to the clipboard\n const nextMarks = node.marks.filter(\n (mark) => mark.type !== this.type\n );\n const marksChanged = nextMarks.length !== node.marks.length;\n\n // Recursively strip comment marks from child content (e.g. inline content inside paragraphs, list items)\n const nextContent =\n node.content.childCount > 0\n ? stripFragment(node.content)\n : node.content;\n const contentChanged = nextContent !== node.content;\n\n if (marksChanged || contentChanged) {\n changed = true;\n nodes.push(\n node.isText\n ? node.mark(nextMarks)\n : node.type.create(node.attrs, nextContent, nextMarks)\n );\n } else {\n nodes.push(node);\n }\n });\n\n return changed ? Fragment.fromArray(nodes) : fragment;\n };\n\n const content = stripFragment(slice.content);\n return content === slice.content\n ? slice\n : new Slice(content, slice.openStart, slice.openEnd);\n };\n\n return [\n new Plugin({\n key: new PluginKey(\"lb-comment-clipboard\"),\n props: {\n transformCopied: (slice) => stripCommentMarks(slice),\n transformPasted: (slice) => stripCommentMarks(slice),\n },\n }),\n new Plugin({\n key: THREADS_PLUGIN_KEY,\n state: {\n init() {\n return {\n threadPositions: new Map<string, { from: number; to: number }>(),\n selectedThreadId: null,\n selectedThreadPos: null,\n decorations: DecorationSet.empty,\n } as ThreadPluginState;\n },\n apply(tr, state) {\n const action = tr.getMeta(THREADS_PLUGIN_KEY) as ThreadPluginAction;\n if (!tr.docChanged && !action) {\n return state;\n }\n\n if (!action) {\n // Doc changed, but no action, just update rects\n return updateState(tr.doc, state.selectedThreadId);\n }\n // handle actions, possibly support more actions\n if (\n action.name === ThreadPluginActions.SET_SELECTED_THREAD_ID &&\n state.selectedThreadId !== action.data\n ) {\n return updateState(tr.doc, action.data);\n }\n\n return state;\n },\n },\n props: {\n decorations: (state) => {\n return (\n THREADS_PLUGIN_KEY.getState(state)?.decorations ??\n DecorationSet.empty\n );\n },\n handleClick: (view, pos, event) => {\n if (event.button !== 0) {\n return;\n }\n\n const selectThread = (threadId: string | null) => {\n view.dispatch(\n view.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: threadId,\n })\n );\n };\n\n const node = view.state.doc.nodeAt(pos);\n if (!node) {\n selectThread(null);\n return;\n }\n const commentMark = node.marks.find(\n (mark) => mark.type === this.type && !mark.attrs.orphan\n );\n // nothing to select\n if (!commentMark) {\n selectThread(null);\n return;\n }\n const threadId = commentMark?.attrs.threadId as string | undefined;\n\n const filtered = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n if (threadId && filtered && !filtered.has(threadId)) {\n selectThread(null);\n return;\n }\n\n selectThread(threadId ?? null);\n },\n },\n }),\n ];\n },\n});\n\nexport const CommentsExtension = Extension.create<\n { filteredThreads?: Set<string> },\n CommentsExtensionStorage\n>({\n name: \"liveblocksComments\",\n priority: 95,\n addExtensions() {\n return [Comment];\n },\n\n addStorage() {\n return {\n pendingComment: false,\n };\n },\n\n addCommands() {\n return {\n addPendingComment: () => () => {\n if (this.editor.state.selection.empty) {\n return false;\n }\n // unselect any open threads\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n this.storage.pendingComment = true;\n return true;\n },\n closePendingComment: () => () => {\n this.storage.pendingComment = false;\n return true;\n },\n selectThread: (id: string | null) => () => {\n const filtered = FILTERED_THREADS_PLUGIN_KEY.getState(\n this.editor.state\n )?.filteredThreads;\n if (id && filtered && !filtered.has(id)) {\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n return true;\n }\n\n this.editor.view.dispatch(\n this.editor.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: id,\n })\n );\n return true;\n },\n addComment:\n (id: string) =>\n ({ commands }) => {\n if (\n !this.storage.pendingComment ||\n this.editor.state.selection.empty\n ) {\n return false;\n }\n commands.setMark(LIVEBLOCKS_COMMENT_MARK_TYPE, { threadId: id });\n this.storage.pendingComment = false;\n return true;\n },\n };\n },\n onSelectionUpdate(\n this: { storage: CommentsExtensionStorage }, // NOTE: there are more types here I didn't override, this gets removed after submitting PR to tiptap\n { transaction }: { transaction: Transaction } // TODO: remove this after submitting PR to tiptap\n ) {\n // ignore changes made by yjs\n if (!this.storage.pendingComment || transaction.getMeta(ySyncPluginKey)) {\n return;\n }\n // if selection changes, hide the composer. We could keep the composer open and move it to the new selection?\n this.storage.pendingComment = false;\n },\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: THREADS_ACTIVE_SELECTION_PLUGIN,\n props: {\n decorations: ({ doc, selection }) => {\n if (!this.storage.pendingComment) {\n return DecorationSet.create(doc, []);\n }\n const { from, to } = selection;\n const decorations: Decoration[] = [\n Decoration.inline(from, to, {\n class: \"lb-root lb-selection lb-tiptap-active-selection\",\n }),\n ];\n return DecorationSet.create(doc, decorations);\n },\n },\n }),\n new Plugin({\n key: FILTERED_THREADS_PLUGIN_KEY,\n state: {\n init: () => ({\n filteredThreads: this.options.filteredThreads,\n }),\n apply(tr, value) {\n const meta = tr.getMeta(FILTERED_THREADS_PLUGIN_KEY) as\n | { filteredThreads?: Set<string> }\n | undefined;\n if (meta?.filteredThreads) {\n return { filteredThreads: meta.filteredThreads };\n }\n return value;\n },\n },\n view: (view) => {\n const syncDom = () => {\n const filteredThreads = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n\n // Toggle attribute for all comment-mark spans\n const els = view.dom.querySelectorAll<HTMLElement>(\n \"span.lb-tiptap-thread-mark[data-lb-thread-id]\"\n );\n els.forEach((el) => {\n const id = el.getAttribute(\"data-lb-thread-id\");\n if (!id) return;\n if (!filteredThreads || filteredThreads.has(id)) {\n el.removeAttribute(\"data-hidden\");\n } else {\n el.setAttribute(\"data-hidden\", \"\");\n }\n });\n };\n\n queueMicrotask(syncDom);\n\n return {\n update: (view, prevState) => {\n const curr = FILTERED_THREADS_PLUGIN_KEY.getState(\n view.state\n )?.filteredThreads;\n const prev =\n FILTERED_THREADS_PLUGIN_KEY.getState(\n prevState\n )?.filteredThreads;\n\n if (\n !areSetsEqual(prev, curr) ||\n view.state.doc !== prevState.doc\n ) {\n syncDom();\n\n const selected = THREADS_PLUGIN_KEY.getState(\n view.state\n )?.selectedThreadId;\n if (selected && curr && !curr.has(selected)) {\n view.dispatch(\n view.state.tr.setMeta(THREADS_PLUGIN_KEY, {\n name: ThreadPluginActions.SET_SELECTED_THREAD_ID,\n data: null,\n })\n );\n }\n }\n },\n };\n },\n }),\n ];\n },\n});\n\nexport function areSetsEqual(a?: Set<string>, b?: Set<string>): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n if (a.size !== b.size) return false;\n for (const v of a) if (!b.has(v)) return false;\n return true;\n}\n"],"names":["threadId","view"],"mappings":"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"}
|
package/dist/version.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const PKG_NAME = "@liveblocks/react-tiptap";
|
|
4
|
-
const PKG_VERSION = typeof "3.
|
|
4
|
+
const PKG_VERSION = typeof "3.16.0-feeds1" === "string" && "3.16.0-feeds1";
|
|
5
5
|
const PKG_FORMAT = typeof "cjs" === "string" && "cjs";
|
|
6
6
|
|
|
7
7
|
exports.PKG_FORMAT = PKG_FORMAT;
|
package/dist/version.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.cjs","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-tiptap\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":";;AAGO,MAAM,QAAW,GAAA,2BAAA;AACX,MAAA,WAAA,GAAc,OAAO,
|
|
1
|
+
{"version":3,"file":"version.cjs","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-tiptap\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":";;AAGO,MAAM,QAAW,GAAA,2BAAA;AACX,MAAA,WAAA,GAAc,OAAO,eAAA,KAAgB,QAAY,IAAA,gBAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;;;"}
|
package/dist/version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const PKG_NAME = "@liveblocks/react-tiptap";
|
|
2
|
-
const PKG_VERSION = typeof "3.
|
|
2
|
+
const PKG_VERSION = typeof "3.16.0-feeds1" === "string" && "3.16.0-feeds1";
|
|
3
3
|
const PKG_FORMAT = typeof "esm" === "string" && "esm";
|
|
4
4
|
|
|
5
5
|
export { PKG_FORMAT, PKG_NAME, PKG_VERSION };
|
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-tiptap\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":"AAGO,MAAM,QAAW,GAAA,2BAAA;AACX,MAAA,WAAA,GAAc,OAAO,
|
|
1
|
+
{"version":3,"file":"version.js","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-tiptap\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":"AAGO,MAAM,QAAW,GAAA,2BAAA;AACX,MAAA,WAAA,GAAc,OAAO,eAAA,KAAgB,QAAY,IAAA,gBAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liveblocks/react-tiptap",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.0-feeds1",
|
|
4
4
|
"description": "An integration of TipTap + React to enable collaboration, comments, live cursors, and more with Liveblocks.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Liveblocks Inc.",
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@floating-ui/react-dom": "^2.1.0",
|
|
48
|
-
"@liveblocks/client": "3.
|
|
49
|
-
"@liveblocks/core": "3.
|
|
50
|
-
"@liveblocks/react": "3.
|
|
51
|
-
"@liveblocks/react-ui": "3.
|
|
52
|
-
"@liveblocks/yjs": "3.
|
|
48
|
+
"@liveblocks/client": "3.16.0-feeds1",
|
|
49
|
+
"@liveblocks/core": "3.16.0-feeds1",
|
|
50
|
+
"@liveblocks/react": "3.16.0-feeds1",
|
|
51
|
+
"@liveblocks/react-ui": "3.16.0-feeds1",
|
|
52
|
+
"@liveblocks/yjs": "3.16.0-feeds1",
|
|
53
53
|
"@tiptap/core": "^3.19.0",
|
|
54
54
|
"@tiptap/react": "^3.19.0",
|
|
55
55
|
"@tiptap/suggestion": "^3.19.0",
|