@liveblocks/react-tiptap 3.13.4 → 3.13.5
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/README.md +1 -1
- package/dist/LiveblocksExtension.cjs +4 -4
- package/dist/LiveblocksExtension.cjs.map +1 -1
- package/dist/LiveblocksExtension.js +2 -2
- package/dist/LiveblocksExtension.js.map +1 -1
- package/dist/collaboration/collaboration.cjs +149 -0
- package/dist/collaboration/collaboration.cjs.map +1 -0
- package/dist/collaboration/collaboration.js +147 -0
- package/dist/collaboration/collaboration.js.map +1 -0
- package/dist/collaboration/helpers/CollaborationMappablePosition.cjs +65 -0
- package/dist/collaboration/helpers/CollaborationMappablePosition.cjs.map +1 -0
- package/dist/collaboration/helpers/CollaborationMappablePosition.js +61 -0
- package/dist/collaboration/helpers/CollaborationMappablePosition.js.map +1 -0
- package/dist/collaboration/helpers/isChangeOrigin.cjs +10 -0
- package/dist/collaboration/helpers/isChangeOrigin.cjs.map +1 -0
- package/dist/collaboration/helpers/isChangeOrigin.js +8 -0
- package/dist/collaboration/helpers/isChangeOrigin.js.map +1 -0
- package/dist/collaboration/helpers/yRelativePosition.cjs +25 -0
- package/dist/collaboration/helpers/yRelativePosition.cjs.map +1 -0
- package/dist/collaboration/helpers/yRelativePosition.js +22 -0
- package/dist/collaboration/helpers/yRelativePosition.js.map +1 -0
- package/dist/collaboration-caret/collaboration-caret.cjs +99 -0
- package/dist/collaboration-caret/collaboration-caret.cjs.map +1 -0
- package/dist/collaboration-caret/collaboration-caret.js +97 -0
- package/dist/collaboration-caret/collaboration-caret.js.map +1 -0
- package/dist/comments/AnchoredThreads.cjs +4 -1
- package/dist/comments/AnchoredThreads.cjs.map +1 -1
- package/dist/comments/AnchoredThreads.js +4 -1
- package/dist/comments/AnchoredThreads.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/package.json +13 -15
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collaboration.js","sources":["../../src/collaboration/collaboration.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\nimport {\n redo,\n undo,\n ySyncPlugin,\n yUndoPlugin,\n yUndoPluginKey,\n yXmlFragmentToProsemirrorJSON,\n} from \"y-prosemirror\";\nimport type { Doc, UndoManager, XmlFragment } from \"yjs\";\n\nimport {\n createMappablePosition,\n getUpdatedPosition,\n} from \"./helpers/CollaborationMappablePosition\";\n\ntype YSyncOpts = Parameters<typeof ySyncPlugin>[1];\ntype YUndoOpts = Parameters<typeof yUndoPlugin>[0];\n\nexport interface CollaborationStorage {\n /**\n * Whether collaboration is currently disabled.\n * Disabling collaboration will prevent any changes from being synced with other users.\n */\n isDisabled: boolean;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaboration: {\n /**\n * Undo recent changes\n * @example editor.commands.undo()\n */\n undo: () => ReturnType;\n /**\n * Reapply reverted changes\n * @example editor.commands.redo()\n */\n redo: () => ReturnType;\n };\n }\n\n interface Storage {\n collaboration: CollaborationStorage;\n }\n}\n\nexport interface CollaborationOptions {\n /**\n * An initialized Y.js document.\n * @example new Y.Doc()\n */\n document?: Doc | null;\n\n /**\n * Name of a Y.js fragment, can be changed to sync multiple fields with one Y.js document.\n * @default 'default'\n * @example 'my-custom-field'\n */\n field?: string;\n\n /**\n * A raw Y.js fragment, can be used instead of `document` and `field`.\n * @example new Y.Doc().getXmlFragment('body')\n */\n fragment?: XmlFragment | null;\n\n /**\n * The collaboration provider.\n * @default null\n */\n provider?: any | null;\n\n /**\n * Fired when the content from Yjs is initially rendered to Tiptap.\n */\n onFirstRender?: () => void;\n\n /**\n * Options for the Yjs sync plugin.\n */\n ySyncOptions?: YSyncOpts;\n\n /**\n * Options for the Yjs undo plugin.\n */\n yUndoOptions?: YUndoOpts;\n}\n\n/**\n * This extension allows you to collaborate with others in real-time.\n * @see https://tiptap.dev/api/extensions/collaboration\n */\nexport const Collaboration = Extension.create<\n CollaborationOptions,\n CollaborationStorage\n>({\n name: \"collaboration\",\n\n priority: 1000,\n\n addOptions() {\n return {\n document: null,\n field: \"default\",\n fragment: null,\n provider: null,\n };\n },\n\n addStorage() {\n return {\n isDisabled: false,\n };\n },\n\n onCreate() {\n if (\n this.editor.extensionManager.extensions.find(\n (extension) => extension.name === \"undoRedo\"\n )\n ) {\n console.warn(\n '[tiptap warn]: \"@tiptap/extension-collaboration\" comes with its own history support and is not compatible with \"@tiptap/extension-undo-redo\".'\n );\n }\n },\n\n onBeforeCreate() {\n this.editor.utils.getUpdatedPosition = (position, transaction) =>\n getUpdatedPosition(position, transaction, this.editor.state);\n this.editor.utils.createMappablePosition = (position) =>\n createMappablePosition(position, this.editor.state);\n },\n\n addCommands() {\n return {\n undo:\n () =>\n ({ tr, state, dispatch }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n const undoManager: UndoManager =\n yUndoPluginKey.getState(state)!.undoManager;\n\n if (undoManager.undoStack.length === 0) {\n return false;\n }\n\n if (!dispatch) {\n return true;\n }\n\n return undo(state);\n },\n redo:\n () =>\n ({ tr, state, dispatch }) => {\n tr.setMeta(\"preventDispatch\", true);\n\n const undoManager: UndoManager =\n yUndoPluginKey.getState(state)!.undoManager;\n\n if (undoManager.redoStack.length === 0) {\n return false;\n }\n\n if (!dispatch) {\n return true;\n }\n\n return redo(state);\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n \"Mod-z\": () => this.editor.commands.undo(),\n \"Mod-y\": () => this.editor.commands.redo(),\n \"Shift-Mod-z\": () => this.editor.commands.redo(),\n };\n },\n\n addProseMirrorPlugins() {\n const fragment = this.options.fragment\n ? this.options.fragment\n : (this.options.document as Doc).getXmlFragment(this.options.field);\n\n // Quick fix until there is an official implementation (thanks to @hamflx).\n // See https://github.com/yjs/y-prosemirror/issues/114 and https://github.com/yjs/y-prosemirror/issues/102\n const yUndoPluginInstance = yUndoPlugin(this.options.yUndoOptions);\n const originalUndoPluginView = yUndoPluginInstance.spec.view;\n\n yUndoPluginInstance.spec.view = (view: EditorView) => {\n const { undoManager } = yUndoPluginKey.getState(view.state)!;\n\n if (\n \"restore\" in undoManager &&\n typeof undoManager.restore === \"function\"\n ) {\n undoManager.restore();\n undoManager.restore = () => {\n // noop\n };\n }\n\n const viewRet = originalUndoPluginView\n ? originalUndoPluginView(view)\n : undefined;\n\n return {\n destroy: () => {\n const hasUndoManSelf = undoManager.trackedOrigins.has(undoManager);\n // eslint-disable-next-line no-underscore-dangle\n const observers = undoManager._observers;\n\n if (\n \"restore\" in undoManager &&\n typeof undoManager.restore === \"function\"\n ) {\n undoManager.restore = () => {\n if (hasUndoManSelf) {\n undoManager.trackedOrigins.add(undoManager);\n }\n\n undoManager.doc.on(\n \"afterTransaction\",\n undoManager.afterTransactionHandler\n );\n // eslint-disable-next-line no-underscore-dangle\n undoManager._observers = observers;\n };\n }\n\n if (viewRet?.destroy) {\n viewRet.destroy();\n }\n },\n };\n };\n\n const ySyncPluginOptions: YSyncOpts = {\n ...this.options.ySyncOptions,\n onFirstRender: this.options.onFirstRender,\n };\n\n const ySyncPluginInstance = ySyncPlugin(fragment, ySyncPluginOptions);\n\n if (this.editor.options.enableContentCheck) {\n fragment.doc?.on(\"beforeTransaction\", () => {\n try {\n const jsonContent = yXmlFragmentToProsemirrorJSON(fragment);\n\n if (jsonContent.content.length === 0) {\n return;\n }\n\n this.editor.schema.nodeFromJSON(jsonContent).check();\n } catch (error) {\n this.editor.emit(\"contentError\", {\n error: error as Error,\n editor: this.editor,\n disableCollaboration: () => {\n fragment.doc?.destroy();\n this.storage.isDisabled = true;\n },\n });\n // If the content is invalid, return false to prevent the transaction from being applied\n return false;\n }\n });\n }\n\n return [\n ySyncPluginInstance,\n yUndoPluginInstance,\n // Only add the filterInvalidContent plugin if content checking is enabled\n this.editor.options.enableContentCheck &&\n new Plugin({\n key: new PluginKey(\"filterInvalidContent\"),\n filterTransaction: () => {\n // When collaboration is disabled, prevent any sync transactions from being applied\n if (this.storage.isDisabled !== false) {\n // Destroy the Yjs document to prevent any further sync transactions\n fragment.doc?.destroy();\n\n return true;\n }\n // TODO should we be returning false when the transaction is a collaboration transaction?\n\n return true;\n },\n }),\n ].filter(Boolean);\n },\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@tiptap/core');
|
|
4
|
+
var isChangeOrigin = require('./isChangeOrigin.cjs');
|
|
5
|
+
var yRelativePosition = require('./yRelativePosition.cjs');
|
|
6
|
+
|
|
7
|
+
class CollaborationMappablePosition extends core.MappablePosition {
|
|
8
|
+
/**
|
|
9
|
+
* The Y.js relative position used for mapping positions in collaborative editing.
|
|
10
|
+
*/
|
|
11
|
+
yRelativePosition;
|
|
12
|
+
constructor(position, yRelativePosition) {
|
|
13
|
+
super(position);
|
|
14
|
+
this.yRelativePosition = yRelativePosition;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Creates a CollaborationMappablePosition from a JSON object.
|
|
18
|
+
*/
|
|
19
|
+
static fromJSON(json) {
|
|
20
|
+
return new CollaborationMappablePosition(
|
|
21
|
+
json.position,
|
|
22
|
+
json.yRelativePosition
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Converts the CollaborationMappablePosition to a JSON object.
|
|
27
|
+
*/
|
|
28
|
+
toJSON() {
|
|
29
|
+
return {
|
|
30
|
+
position: this.position,
|
|
31
|
+
yRelativePosition: this.yRelativePosition
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function createMappablePosition(position, state) {
|
|
36
|
+
const yRelativePosition$1 = yRelativePosition.getYRelativePosition(state, position);
|
|
37
|
+
return new CollaborationMappablePosition(position, yRelativePosition$1);
|
|
38
|
+
}
|
|
39
|
+
function getUpdatedPosition(position, transaction, state) {
|
|
40
|
+
const yRelativePosition$1 = position instanceof CollaborationMappablePosition ? position.yRelativePosition : null;
|
|
41
|
+
if (isChangeOrigin.isChangeOrigin(transaction) && yRelativePosition$1) {
|
|
42
|
+
const absolutePosition2 = yRelativePosition.getYAbsolutePosition(state, yRelativePosition$1);
|
|
43
|
+
return {
|
|
44
|
+
position: new CollaborationMappablePosition(
|
|
45
|
+
absolutePosition2,
|
|
46
|
+
yRelativePosition$1
|
|
47
|
+
),
|
|
48
|
+
mapResult: null
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const result = core.getUpdatedPosition(position, transaction);
|
|
52
|
+
const absolutePosition = result.position.position;
|
|
53
|
+
return {
|
|
54
|
+
position: new CollaborationMappablePosition(
|
|
55
|
+
absolutePosition,
|
|
56
|
+
yRelativePosition$1 ?? yRelativePosition.getYRelativePosition(state, absolutePosition)
|
|
57
|
+
),
|
|
58
|
+
mapResult: result.mapResult
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
exports.CollaborationMappablePosition = CollaborationMappablePosition;
|
|
63
|
+
exports.createMappablePosition = createMappablePosition;
|
|
64
|
+
exports.getUpdatedPosition = getUpdatedPosition;
|
|
65
|
+
//# sourceMappingURL=CollaborationMappablePosition.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollaborationMappablePosition.cjs","sources":["../../../src/collaboration/helpers/CollaborationMappablePosition.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport {\n getUpdatedPosition as coreGetUpdatedPosition,\n type GetUpdatedPositionResult,\n MappablePosition,\n} from \"@tiptap/core\";\nimport type { EditorState, Transaction } from \"@tiptap/pm/state\";\n\nimport { isChangeOrigin } from \"./isChangeOrigin\";\nimport {\n getYAbsolutePosition,\n getYRelativePosition,\n type YRelativePosition,\n} from \"./yRelativePosition\";\n\n/**\n * A MappablePosition subclass that includes Y.js relative position information\n * to track positions in collaborative transactions.\n */\nexport class CollaborationMappablePosition extends MappablePosition {\n /**\n * The Y.js relative position used for mapping positions in collaborative editing.\n */\n public yRelativePosition: YRelativePosition;\n\n constructor(position: number, yRelativePosition: YRelativePosition) {\n super(position);\n this.yRelativePosition = yRelativePosition;\n }\n\n /**\n * Creates a CollaborationMappablePosition from a JSON object.\n */\n static fromJSON(json: any): CollaborationMappablePosition {\n return new CollaborationMappablePosition(\n json.position,\n json.yRelativePosition\n );\n }\n\n /**\n * Converts the CollaborationMappablePosition to a JSON object.\n */\n toJSON(): any {\n return {\n position: this.position,\n yRelativePosition: this.yRelativePosition,\n };\n }\n}\n\n/**\n * Creates a MappablePosition from a position number.\n * This is the collaboration implementation that returns a CollaborationMappablePosition.\n */\nexport function createMappablePosition(\n position: number,\n state: EditorState\n): CollaborationMappablePosition {\n const yRelativePosition = getYRelativePosition(state, position);\n return new CollaborationMappablePosition(position, yRelativePosition);\n}\n\n/**\n * Returns the new position after applying a transaction. Handles both Y.js\n * transactions and regular transactions.\n */\nexport function getUpdatedPosition(\n position: MappablePosition,\n transaction: Transaction,\n state: EditorState\n): GetUpdatedPositionResult {\n const yRelativePosition =\n position instanceof CollaborationMappablePosition\n ? position.yRelativePosition\n : null;\n\n if (isChangeOrigin(transaction) && yRelativePosition) {\n const absolutePosition = getYAbsolutePosition(state, yRelativePosition);\n\n return {\n position: new CollaborationMappablePosition(\n absolutePosition,\n yRelativePosition\n ),\n mapResult: null,\n };\n }\n\n const result = coreGetUpdatedPosition(position, transaction);\n\n const absolutePosition = result.position.position;\n\n return {\n position: new CollaborationMappablePosition(\n absolutePosition,\n yRelativePosition ?? getYRelativePosition(state, absolutePosition)\n ),\n mapResult: result.mapResult,\n };\n}\n"],"names":["MappablePosition","yRelativePosition","getYRelativePosition","isChangeOrigin","absolutePosition","getYAbsolutePosition","coreGetUpdatedPosition"],"mappings":";;;;;;AAgCO,MAAM,sCAAsCA,qBAAiB,CAAA;AAAA;AAAA;AAAA;AAAA,EAI3D,iBAAA,CAAA;AAAA,EAEP,WAAA,CAAY,UAAkB,iBAAsC,EAAA;AAClE,IAAA,KAAA,CAAM,QAAQ,CAAA,CAAA;AACd,IAAA,IAAA,CAAK,iBAAoB,GAAA,iBAAA,CAAA;AAAA,GAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,SAAS,IAA0C,EAAA;AACxD,IAAA,OAAO,IAAI,6BAAA;AAAA,MACT,IAAK,CAAA,QAAA;AAAA,MACL,IAAK,CAAA,iBAAA;AAAA,KACP,CAAA;AAAA,GACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,GAAA;AACZ,IAAO,OAAA;AAAA,MACL,UAAU,IAAK,CAAA,QAAA;AAAA,MACf,mBAAmB,IAAK,CAAA,iBAAA;AAAA,KAC1B,CAAA;AAAA,GACF;AACF,CAAA;AAMgB,SAAA,sBAAA,CACd,UACA,KAC+B,EAAA;AAC/B,EAAM,MAAAC,mBAAA,GAAoBC,sCAAqB,CAAA,KAAA,EAAO,QAAQ,CAAA,CAAA;AAC9D,EAAO,OAAA,IAAI,6BAA8B,CAAA,QAAA,EAAUD,mBAAiB,CAAA,CAAA;AACtE,CAAA;AAMgB,SAAA,kBAAA,CACd,QACA,EAAA,WAAA,EACA,KAC0B,EAAA;AAC1B,EAAA,MAAMA,mBACJ,GAAA,QAAA,YAAoB,6BAChB,GAAA,QAAA,CAAS,iBACT,GAAA,IAAA,CAAA;AAEN,EAAI,IAAAE,6BAAA,CAAe,WAAW,CAAA,IAAKF,mBAAmB,EAAA;AACpD,IAAMG,MAAAA,iBAAAA,GAAmBC,sCAAqB,CAAA,KAAA,EAAOJ,mBAAiB,CAAA,CAAA;AAEtE,IAAO,OAAA;AAAA,MACL,UAAU,IAAI,6BAAA;AAAA,QACZG,iBAAAA;AAAA,QACAH,mBAAA;AAAA,OACF;AAAA,MACA,SAAW,EAAA,IAAA;AAAA,KACb,CAAA;AAAA,GACF;AAEA,EAAM,MAAA,MAAA,GAASK,uBAAuB,CAAA,QAAA,EAAU,WAAW,CAAA,CAAA;AAE3D,EAAM,MAAA,gBAAA,GAAmB,OAAO,QAAS,CAAA,QAAA,CAAA;AAEzC,EAAO,OAAA;AAAA,IACL,UAAU,IAAI,6BAAA;AAAA,MACZ,gBAAA;AAAA,MACAL,mBAAA,IAAqBC,sCAAqB,CAAA,KAAA,EAAO,gBAAgB,CAAA;AAAA,KACnE;AAAA,IACA,WAAW,MAAO,CAAA,SAAA;AAAA,GACpB,CAAA;AACF;;;;;;"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { MappablePosition, getUpdatedPosition as getUpdatedPosition$1 } from '@tiptap/core';
|
|
2
|
+
import { isChangeOrigin } from './isChangeOrigin.js';
|
|
3
|
+
import { getYRelativePosition, getYAbsolutePosition } from './yRelativePosition.js';
|
|
4
|
+
|
|
5
|
+
class CollaborationMappablePosition extends MappablePosition {
|
|
6
|
+
/**
|
|
7
|
+
* The Y.js relative position used for mapping positions in collaborative editing.
|
|
8
|
+
*/
|
|
9
|
+
yRelativePosition;
|
|
10
|
+
constructor(position, yRelativePosition) {
|
|
11
|
+
super(position);
|
|
12
|
+
this.yRelativePosition = yRelativePosition;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates a CollaborationMappablePosition from a JSON object.
|
|
16
|
+
*/
|
|
17
|
+
static fromJSON(json) {
|
|
18
|
+
return new CollaborationMappablePosition(
|
|
19
|
+
json.position,
|
|
20
|
+
json.yRelativePosition
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Converts the CollaborationMappablePosition to a JSON object.
|
|
25
|
+
*/
|
|
26
|
+
toJSON() {
|
|
27
|
+
return {
|
|
28
|
+
position: this.position,
|
|
29
|
+
yRelativePosition: this.yRelativePosition
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function createMappablePosition(position, state) {
|
|
34
|
+
const yRelativePosition = getYRelativePosition(state, position);
|
|
35
|
+
return new CollaborationMappablePosition(position, yRelativePosition);
|
|
36
|
+
}
|
|
37
|
+
function getUpdatedPosition(position, transaction, state) {
|
|
38
|
+
const yRelativePosition = position instanceof CollaborationMappablePosition ? position.yRelativePosition : null;
|
|
39
|
+
if (isChangeOrigin(transaction) && yRelativePosition) {
|
|
40
|
+
const absolutePosition2 = getYAbsolutePosition(state, yRelativePosition);
|
|
41
|
+
return {
|
|
42
|
+
position: new CollaborationMappablePosition(
|
|
43
|
+
absolutePosition2,
|
|
44
|
+
yRelativePosition
|
|
45
|
+
),
|
|
46
|
+
mapResult: null
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const result = getUpdatedPosition$1(position, transaction);
|
|
50
|
+
const absolutePosition = result.position.position;
|
|
51
|
+
return {
|
|
52
|
+
position: new CollaborationMappablePosition(
|
|
53
|
+
absolutePosition,
|
|
54
|
+
yRelativePosition ?? getYRelativePosition(state, absolutePosition)
|
|
55
|
+
),
|
|
56
|
+
mapResult: result.mapResult
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { CollaborationMappablePosition, createMappablePosition, getUpdatedPosition };
|
|
61
|
+
//# sourceMappingURL=CollaborationMappablePosition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollaborationMappablePosition.js","sources":["../../../src/collaboration/helpers/CollaborationMappablePosition.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport {\n getUpdatedPosition as coreGetUpdatedPosition,\n type GetUpdatedPositionResult,\n MappablePosition,\n} from \"@tiptap/core\";\nimport type { EditorState, Transaction } from \"@tiptap/pm/state\";\n\nimport { isChangeOrigin } from \"./isChangeOrigin\";\nimport {\n getYAbsolutePosition,\n getYRelativePosition,\n type YRelativePosition,\n} from \"./yRelativePosition\";\n\n/**\n * A MappablePosition subclass that includes Y.js relative position information\n * to track positions in collaborative transactions.\n */\nexport class CollaborationMappablePosition extends MappablePosition {\n /**\n * The Y.js relative position used for mapping positions in collaborative editing.\n */\n public yRelativePosition: YRelativePosition;\n\n constructor(position: number, yRelativePosition: YRelativePosition) {\n super(position);\n this.yRelativePosition = yRelativePosition;\n }\n\n /**\n * Creates a CollaborationMappablePosition from a JSON object.\n */\n static fromJSON(json: any): CollaborationMappablePosition {\n return new CollaborationMappablePosition(\n json.position,\n json.yRelativePosition\n );\n }\n\n /**\n * Converts the CollaborationMappablePosition to a JSON object.\n */\n toJSON(): any {\n return {\n position: this.position,\n yRelativePosition: this.yRelativePosition,\n };\n }\n}\n\n/**\n * Creates a MappablePosition from a position number.\n * This is the collaboration implementation that returns a CollaborationMappablePosition.\n */\nexport function createMappablePosition(\n position: number,\n state: EditorState\n): CollaborationMappablePosition {\n const yRelativePosition = getYRelativePosition(state, position);\n return new CollaborationMappablePosition(position, yRelativePosition);\n}\n\n/**\n * Returns the new position after applying a transaction. Handles both Y.js\n * transactions and regular transactions.\n */\nexport function getUpdatedPosition(\n position: MappablePosition,\n transaction: Transaction,\n state: EditorState\n): GetUpdatedPositionResult {\n const yRelativePosition =\n position instanceof CollaborationMappablePosition\n ? position.yRelativePosition\n : null;\n\n if (isChangeOrigin(transaction) && yRelativePosition) {\n const absolutePosition = getYAbsolutePosition(state, yRelativePosition);\n\n return {\n position: new CollaborationMappablePosition(\n absolutePosition,\n yRelativePosition\n ),\n mapResult: null,\n };\n }\n\n const result = coreGetUpdatedPosition(position, transaction);\n\n const absolutePosition = result.position.position;\n\n return {\n position: new CollaborationMappablePosition(\n absolutePosition,\n yRelativePosition ?? getYRelativePosition(state, absolutePosition)\n ),\n mapResult: result.mapResult,\n };\n}\n"],"names":["absolutePosition","coreGetUpdatedPosition"],"mappings":";;;;AAgCO,MAAM,sCAAsC,gBAAiB,CAAA;AAAA;AAAA;AAAA;AAAA,EAI3D,iBAAA,CAAA;AAAA,EAEP,WAAA,CAAY,UAAkB,iBAAsC,EAAA;AAClE,IAAA,KAAA,CAAM,QAAQ,CAAA,CAAA;AACd,IAAA,IAAA,CAAK,iBAAoB,GAAA,iBAAA,CAAA;AAAA,GAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,SAAS,IAA0C,EAAA;AACxD,IAAA,OAAO,IAAI,6BAAA;AAAA,MACT,IAAK,CAAA,QAAA;AAAA,MACL,IAAK,CAAA,iBAAA;AAAA,KACP,CAAA;AAAA,GACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,GAAA;AACZ,IAAO,OAAA;AAAA,MACL,UAAU,IAAK,CAAA,QAAA;AAAA,MACf,mBAAmB,IAAK,CAAA,iBAAA;AAAA,KAC1B,CAAA;AAAA,GACF;AACF,CAAA;AAMgB,SAAA,sBAAA,CACd,UACA,KAC+B,EAAA;AAC/B,EAAM,MAAA,iBAAA,GAAoB,oBAAqB,CAAA,KAAA,EAAO,QAAQ,CAAA,CAAA;AAC9D,EAAO,OAAA,IAAI,6BAA8B,CAAA,QAAA,EAAU,iBAAiB,CAAA,CAAA;AACtE,CAAA;AAMgB,SAAA,kBAAA,CACd,QACA,EAAA,WAAA,EACA,KAC0B,EAAA;AAC1B,EAAA,MAAM,iBACJ,GAAA,QAAA,YAAoB,6BAChB,GAAA,QAAA,CAAS,iBACT,GAAA,IAAA,CAAA;AAEN,EAAI,IAAA,cAAA,CAAe,WAAW,CAAA,IAAK,iBAAmB,EAAA;AACpD,IAAMA,MAAAA,iBAAAA,GAAmB,oBAAqB,CAAA,KAAA,EAAO,iBAAiB,CAAA,CAAA;AAEtE,IAAO,OAAA;AAAA,MACL,UAAU,IAAI,6BAAA;AAAA,QACZA,iBAAAA;AAAA,QACA,iBAAA;AAAA,OACF;AAAA,MACA,SAAW,EAAA,IAAA;AAAA,KACb,CAAA;AAAA,GACF;AAEA,EAAM,MAAA,MAAA,GAASC,oBAAuB,CAAA,QAAA,EAAU,WAAW,CAAA,CAAA;AAE3D,EAAM,MAAA,gBAAA,GAAmB,OAAO,QAAS,CAAA,QAAA,CAAA;AAEzC,EAAO,OAAA;AAAA,IACL,UAAU,IAAI,6BAAA;AAAA,MACZ,gBAAA;AAAA,MACA,iBAAA,IAAqB,oBAAqB,CAAA,KAAA,EAAO,gBAAgB,CAAA;AAAA,KACnE;AAAA,IACA,WAAW,MAAO,CAAA,SAAA;AAAA,GACpB,CAAA;AACF;;;;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var yProsemirror = require('y-prosemirror');
|
|
4
|
+
|
|
5
|
+
function isChangeOrigin(transaction) {
|
|
6
|
+
return !!transaction.getMeta(yProsemirror.ySyncPluginKey);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
exports.isChangeOrigin = isChangeOrigin;
|
|
10
|
+
//# sourceMappingURL=isChangeOrigin.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isChangeOrigin.cjs","sources":["../../../src/collaboration/helpers/isChangeOrigin.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\n/**\n * Checks if a transaction was originated from a Yjs change.\n * @param {Transaction} transaction - The transaction to check.\n * @returns {boolean} - True if the transaction was originated from a Yjs change, false otherwise.\n * @example\n * const transaction = new Transaction(doc)\n * const isOrigin = isChangeOrigin(transaction) // returns false\n */\nexport function isChangeOrigin(transaction: Transaction): boolean {\n return !!transaction.getMeta(ySyncPluginKey);\n}\n"],"names":["ySyncPluginKey"],"mappings":";;;;AAyBO,SAAS,eAAe,WAAmC,EAAA;AAChE,EAAA,OAAO,CAAC,CAAC,WAAY,CAAA,OAAA,CAAQA,2BAAc,CAAA,CAAA;AAC7C;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isChangeOrigin.js","sources":["../../../src/collaboration/helpers/isChangeOrigin.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { ySyncPluginKey } from \"y-prosemirror\";\n\n/**\n * Checks if a transaction was originated from a Yjs change.\n * @param {Transaction} transaction - The transaction to check.\n * @returns {boolean} - True if the transaction was originated from a Yjs change, false otherwise.\n * @example\n * const transaction = new Transaction(doc)\n * const isOrigin = isChangeOrigin(transaction) // returns false\n */\nexport function isChangeOrigin(transaction: Transaction): boolean {\n return !!transaction.getMeta(ySyncPluginKey);\n}\n"],"names":[],"mappings":";;AAyBO,SAAS,eAAe,WAAmC,EAAA;AAChE,EAAA,OAAO,CAAC,CAAC,WAAY,CAAA,OAAA,CAAQ,cAAc,CAAA,CAAA;AAC7C;;;;"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var yProsemirror = require('y-prosemirror');
|
|
4
|
+
|
|
5
|
+
function getYAbsolutePosition(state, relativePos) {
|
|
6
|
+
const ystate = yProsemirror.ySyncPluginKey.getState(state);
|
|
7
|
+
return yProsemirror.relativePositionToAbsolutePosition(
|
|
8
|
+
ystate.doc,
|
|
9
|
+
ystate.type,
|
|
10
|
+
relativePos,
|
|
11
|
+
ystate.binding.mapping
|
|
12
|
+
) || 0;
|
|
13
|
+
}
|
|
14
|
+
function getYRelativePosition(state, absolutePos) {
|
|
15
|
+
const ystate = yProsemirror.ySyncPluginKey.getState(state);
|
|
16
|
+
return yProsemirror.absolutePositionToRelativePosition(
|
|
17
|
+
absolutePos,
|
|
18
|
+
ystate.type,
|
|
19
|
+
ystate.binding.mapping
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exports.getYAbsolutePosition = getYAbsolutePosition;
|
|
24
|
+
exports.getYRelativePosition = getYRelativePosition;
|
|
25
|
+
//# sourceMappingURL=yRelativePosition.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yRelativePosition.cjs","sources":["../../../src/collaboration/helpers/yRelativePosition.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport type { EditorState } from \"@tiptap/pm/state\";\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition,\n ySyncPluginKey,\n} from \"y-prosemirror\";\n\n/**\n * A type that represents a Y.js relative position. Used to map a position from\n * a transaction, handling both Yjs changes and regular transactions.\n *\n * If the editor is not collaborative, the value can be `null`.\n */\nexport type YRelativePosition = any;\n\n/**\n * Converts a Y.js relative position to a position in the Tiptap document.\n */\nexport function getYAbsolutePosition(\n state: EditorState,\n relativePos: YRelativePosition\n): number {\n // ystate is never null because we've checked it before calling this function\n const ystate = ySyncPluginKey.getState(state);\n return (\n relativePositionToAbsolutePosition(\n ystate.doc,\n ystate.type,\n relativePos,\n ystate.binding.mapping\n ) || 0\n );\n}\n\n/**\n * Converts a position in the Tiptap document to a Y.js relative position.\n */\nexport function getYRelativePosition(\n state: EditorState,\n absolutePos: number\n): YRelativePosition {\n // ystate is never null because we've checked it before calling this function\n const ystate = ySyncPluginKey.getState(state);\n return absolutePositionToRelativePosition(\n absolutePos,\n ystate.type,\n ystate.binding.mapping\n );\n}\n"],"names":["ySyncPluginKey","relativePositionToAbsolutePosition","absolutePositionToRelativePosition"],"mappings":";;;;AAgCgB,SAAA,oBAAA,CACd,OACA,WACQ,EAAA;AAER,EAAM,MAAA,MAAA,GAASA,2BAAe,CAAA,QAAA,CAAS,KAAK,CAAA,CAAA;AAC5C,EACE,OAAAC,+CAAA;AAAA,IACE,MAAO,CAAA,GAAA;AAAA,IACP,MAAO,CAAA,IAAA;AAAA,IACP,WAAA;AAAA,IACA,OAAO,OAAQ,CAAA,OAAA;AAAA,GACZ,IAAA,CAAA,CAAA;AAET,CAAA;AAKgB,SAAA,oBAAA,CACd,OACA,WACmB,EAAA;AAEnB,EAAM,MAAA,MAAA,GAASD,2BAAe,CAAA,QAAA,CAAS,KAAK,CAAA,CAAA;AAC5C,EAAO,OAAAE,+CAAA;AAAA,IACL,WAAA;AAAA,IACA,MAAO,CAAA,IAAA;AAAA,IACP,OAAO,OAAQ,CAAA,OAAA;AAAA,GACjB,CAAA;AACF;;;;;"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ySyncPluginKey, relativePositionToAbsolutePosition, absolutePositionToRelativePosition } from 'y-prosemirror';
|
|
2
|
+
|
|
3
|
+
function getYAbsolutePosition(state, relativePos) {
|
|
4
|
+
const ystate = ySyncPluginKey.getState(state);
|
|
5
|
+
return relativePositionToAbsolutePosition(
|
|
6
|
+
ystate.doc,
|
|
7
|
+
ystate.type,
|
|
8
|
+
relativePos,
|
|
9
|
+
ystate.binding.mapping
|
|
10
|
+
) || 0;
|
|
11
|
+
}
|
|
12
|
+
function getYRelativePosition(state, absolutePos) {
|
|
13
|
+
const ystate = ySyncPluginKey.getState(state);
|
|
14
|
+
return absolutePositionToRelativePosition(
|
|
15
|
+
absolutePos,
|
|
16
|
+
ystate.type,
|
|
17
|
+
ystate.binding.mapping
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { getYAbsolutePosition, getYRelativePosition };
|
|
22
|
+
//# sourceMappingURL=yRelativePosition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yRelativePosition.js","sources":["../../../src/collaboration/helpers/yRelativePosition.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport type { EditorState } from \"@tiptap/pm/state\";\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition,\n ySyncPluginKey,\n} from \"y-prosemirror\";\n\n/**\n * A type that represents a Y.js relative position. Used to map a position from\n * a transaction, handling both Yjs changes and regular transactions.\n *\n * If the editor is not collaborative, the value can be `null`.\n */\nexport type YRelativePosition = any;\n\n/**\n * Converts a Y.js relative position to a position in the Tiptap document.\n */\nexport function getYAbsolutePosition(\n state: EditorState,\n relativePos: YRelativePosition\n): number {\n // ystate is never null because we've checked it before calling this function\n const ystate = ySyncPluginKey.getState(state);\n return (\n relativePositionToAbsolutePosition(\n ystate.doc,\n ystate.type,\n relativePos,\n ystate.binding.mapping\n ) || 0\n );\n}\n\n/**\n * Converts a position in the Tiptap document to a Y.js relative position.\n */\nexport function getYRelativePosition(\n state: EditorState,\n absolutePos: number\n): YRelativePosition {\n // ystate is never null because we've checked it before calling this function\n const ystate = ySyncPluginKey.getState(state);\n return absolutePositionToRelativePosition(\n absolutePos,\n ystate.type,\n ystate.binding.mapping\n );\n}\n"],"names":[],"mappings":";;AAgCgB,SAAA,oBAAA,CACd,OACA,WACQ,EAAA;AAER,EAAM,MAAA,MAAA,GAAS,cAAe,CAAA,QAAA,CAAS,KAAK,CAAA,CAAA;AAC5C,EACE,OAAA,kCAAA;AAAA,IACE,MAAO,CAAA,GAAA;AAAA,IACP,MAAO,CAAA,IAAA;AAAA,IACP,WAAA;AAAA,IACA,OAAO,OAAQ,CAAA,OAAA;AAAA,GACZ,IAAA,CAAA,CAAA;AAET,CAAA;AAKgB,SAAA,oBAAA,CACd,OACA,WACmB,EAAA;AAEnB,EAAM,MAAA,MAAA,GAAS,cAAe,CAAA,QAAA,CAAS,KAAK,CAAA,CAAA;AAC5C,EAAO,OAAA,kCAAA;AAAA,IACL,WAAA;AAAA,IACA,MAAO,CAAA,IAAA;AAAA,IACP,OAAO,OAAQ,CAAA,OAAA;AAAA,GACjB,CAAA;AACF;;;;"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@tiptap/core');
|
|
4
|
+
var yProsemirror = require('y-prosemirror');
|
|
5
|
+
|
|
6
|
+
const awarenessStatesToArray = (states) => {
|
|
7
|
+
return Array.from(states.entries()).map(([key, value]) => {
|
|
8
|
+
return {
|
|
9
|
+
clientId: key,
|
|
10
|
+
...value.user
|
|
11
|
+
};
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
const defaultOnUpdate = () => null;
|
|
15
|
+
const CollaborationCaret = core.Extension.create({
|
|
16
|
+
name: "collaborationCaret",
|
|
17
|
+
priority: 999,
|
|
18
|
+
addOptions() {
|
|
19
|
+
return {
|
|
20
|
+
provider: null,
|
|
21
|
+
user: {
|
|
22
|
+
name: null,
|
|
23
|
+
color: null
|
|
24
|
+
},
|
|
25
|
+
render: (user) => {
|
|
26
|
+
const cursor = document.createElement("span");
|
|
27
|
+
cursor.classList.add("collaboration-carets__caret");
|
|
28
|
+
cursor.setAttribute("style", `border-color: ${user.color}`);
|
|
29
|
+
const label = document.createElement("div");
|
|
30
|
+
label.classList.add("collaboration-carets__label");
|
|
31
|
+
label.setAttribute("style", `background-color: ${user.color}`);
|
|
32
|
+
label.insertBefore(document.createTextNode(user.name), null);
|
|
33
|
+
cursor.insertBefore(label, null);
|
|
34
|
+
return cursor;
|
|
35
|
+
},
|
|
36
|
+
selectionRender: yProsemirror.defaultSelectionBuilder,
|
|
37
|
+
onUpdate: defaultOnUpdate
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
onCreate() {
|
|
41
|
+
if (this.options.onUpdate !== defaultOnUpdate) {
|
|
42
|
+
console.warn(
|
|
43
|
+
'[tiptap warn]: DEPRECATED: The "onUpdate" option is deprecated. Please use `editor.storage.collaborationCaret.users` instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret'
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (!this.options.provider) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
'The "provider" option is required for the CollaborationCaret extension'
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
addStorage() {
|
|
53
|
+
return {
|
|
54
|
+
users: []
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
addCommands() {
|
|
58
|
+
return {
|
|
59
|
+
updateUser: (attributes) => () => {
|
|
60
|
+
this.options.provider.awareness.setLocalStateField("user", attributes);
|
|
61
|
+
return true;
|
|
62
|
+
},
|
|
63
|
+
user: (attributes) => ({ editor }) => {
|
|
64
|
+
console.warn(
|
|
65
|
+
'[tiptap warn]: DEPRECATED: The "user" command is deprecated. Please use "updateUser" instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret'
|
|
66
|
+
);
|
|
67
|
+
return editor.commands.updateUser(attributes);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
addProseMirrorPlugins() {
|
|
72
|
+
return [
|
|
73
|
+
yProsemirror.yCursorPlugin(
|
|
74
|
+
(() => {
|
|
75
|
+
this.options.provider.awareness.setLocalStateField(
|
|
76
|
+
"user",
|
|
77
|
+
this.options.user
|
|
78
|
+
);
|
|
79
|
+
this.storage.users = awarenessStatesToArray(
|
|
80
|
+
this.options.provider.awareness.states
|
|
81
|
+
);
|
|
82
|
+
this.options.provider.awareness.on("update", () => {
|
|
83
|
+
this.storage.users = awarenessStatesToArray(
|
|
84
|
+
this.options.provider.awareness.states
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
return this.options.provider.awareness;
|
|
88
|
+
})(),
|
|
89
|
+
{
|
|
90
|
+
cursorBuilder: this.options.render,
|
|
91
|
+
selectionBuilder: this.options.selectionRender
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
exports.CollaborationCaret = CollaborationCaret;
|
|
99
|
+
//# sourceMappingURL=collaboration-caret.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collaboration-caret.cjs","sources":["../../src/collaboration-caret/collaboration-caret.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport { Extension } from \"@tiptap/core\";\nimport type { DecorationAttrs } from \"@tiptap/pm/view\";\nimport { defaultSelectionBuilder, yCursorPlugin } from \"y-prosemirror\";\n\ntype CollaborationCaretStorage = {\n users: { clientId: number; [key: string]: any }[];\n};\n\nexport interface CollaborationCaretOptions {\n /**\n * The Hocuspocus provider instance. This can also be a TiptapCloudProvider instance.\n * @type {HocuspocusProvider | TiptapCloudProvider}\n * @example new HocuspocusProvider()\n */\n provider: any;\n\n /**\n * The user details object – feel free to add properties to this object as needed\n * @example { name: 'John Doe', color: '#305500' }\n */\n user: Record<string, any>;\n\n /**\n * A function that returns a DOM element for the cursor.\n * @param user The user details object\n * @example\n * render: user => {\n * const cursor = document.createElement('span')\n * cursor.classList.add('collaboration-carets__caret')\n * cursor.setAttribute('style', `border-color: ${user.color}`)\n *\n * const label = document.createElement('div')\n * label.classList.add('collaboration-carets__label')\n * label.setAttribute('style', `background-color: ${user.color}`)\n * label.insertBefore(document.createTextNode(user.name), null)\n *\n * cursor.insertBefore(label, null)\n * return cursor\n * }\n */\n render(user: Record<string, any>): HTMLElement;\n\n /**\n * A function that returns a ProseMirror DecorationAttrs object for the selection.\n * @param user The user details object\n * @example\n * selectionRender: user => {\n * return {\n * nodeName: 'span',\n * class: 'collaboration-carets__selection',\n * style: `background-color: ${user.color}`,\n * 'data-user': user.name,\n * }\n */\n selectionRender(user: Record<string, any>): DecorationAttrs;\n\n /**\n * @deprecated The \"onUpdate\" option is deprecated. Please use `editor.storage.collaborationCaret.users` instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret\n */\n onUpdate: (users: { clientId: number; [key: string]: any }[]) => null;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaborationCaret: {\n /**\n * Update details of the current user\n * @example editor.commands.updateUser({ name: 'John Doe', color: '#305500' })\n */\n updateUser: (attributes: Record<string, any>) => ReturnType;\n /**\n * Update details of the current user\n *\n * @deprecated The \"user\" command is deprecated. Please use \"updateUser\" instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret\n */\n user: (attributes: Record<string, any>) => ReturnType;\n };\n }\n\n interface Storage {\n collaborationCaret: CollaborationCaretStorage;\n }\n}\n\nconst awarenessStatesToArray = (states: Map<number, Record<string, any>>) => {\n return Array.from(states.entries()).map(([key, value]) => {\n return {\n clientId: key,\n ...value.user,\n };\n });\n};\n\nconst defaultOnUpdate = () => null;\n\n/**\n * This extension allows you to add collaboration carets to your editor.\n * @see https://tiptap.dev/api/extensions/collaboration-caret\n */\nexport const CollaborationCaret = Extension.create<\n CollaborationCaretOptions,\n CollaborationCaretStorage\n>({\n name: \"collaborationCaret\",\n\n priority: 999,\n\n addOptions() {\n return {\n provider: null,\n user: {\n name: null,\n color: null,\n },\n render: (user) => {\n const cursor = document.createElement(\"span\");\n\n cursor.classList.add(\"collaboration-carets__caret\");\n cursor.setAttribute(\"style\", `border-color: ${user.color}`);\n\n const label = document.createElement(\"div\");\n\n label.classList.add(\"collaboration-carets__label\");\n label.setAttribute(\"style\", `background-color: ${user.color}`);\n label.insertBefore(document.createTextNode(user.name), null);\n cursor.insertBefore(label, null);\n\n return cursor;\n },\n selectionRender: defaultSelectionBuilder,\n onUpdate: defaultOnUpdate,\n };\n },\n\n onCreate() {\n if (this.options.onUpdate !== defaultOnUpdate) {\n console.warn(\n '[tiptap warn]: DEPRECATED: The \"onUpdate\" option is deprecated. Please use `editor.storage.collaborationCaret.users` instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret'\n );\n }\n if (!this.options.provider) {\n throw new Error(\n 'The \"provider\" option is required for the CollaborationCaret extension'\n );\n }\n },\n\n addStorage() {\n return {\n users: [],\n };\n },\n\n addCommands() {\n return {\n updateUser: (attributes) => () => {\n this.options.provider.awareness.setLocalStateField(\"user\", attributes);\n return true;\n },\n user:\n (attributes) =>\n ({ editor }) => {\n console.warn(\n '[tiptap warn]: DEPRECATED: The \"user\" command is deprecated. Please use \"updateUser\" instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret'\n );\n\n return editor.commands.updateUser(attributes);\n },\n };\n },\n\n addProseMirrorPlugins() {\n return [\n yCursorPlugin(\n (() => {\n this.options.provider.awareness.setLocalStateField(\n \"user\",\n this.options.user\n );\n\n this.storage.users = awarenessStatesToArray(\n this.options.provider.awareness.states\n );\n\n this.options.provider.awareness.on(\"update\", () => {\n this.storage.users = awarenessStatesToArray(\n this.options.provider.awareness.states\n );\n });\n\n return this.options.provider.awareness;\n })(),\n {\n cursorBuilder: this.options.render,\n selectionBuilder: this.options.selectionRender,\n }\n ),\n ];\n },\n});\n"],"names":["Extension","defaultSelectionBuilder","yCursorPlugin"],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
import { defaultSelectionBuilder, yCursorPlugin } from 'y-prosemirror';
|
|
3
|
+
|
|
4
|
+
const awarenessStatesToArray = (states) => {
|
|
5
|
+
return Array.from(states.entries()).map(([key, value]) => {
|
|
6
|
+
return {
|
|
7
|
+
clientId: key,
|
|
8
|
+
...value.user
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
const defaultOnUpdate = () => null;
|
|
13
|
+
const CollaborationCaret = Extension.create({
|
|
14
|
+
name: "collaborationCaret",
|
|
15
|
+
priority: 999,
|
|
16
|
+
addOptions() {
|
|
17
|
+
return {
|
|
18
|
+
provider: null,
|
|
19
|
+
user: {
|
|
20
|
+
name: null,
|
|
21
|
+
color: null
|
|
22
|
+
},
|
|
23
|
+
render: (user) => {
|
|
24
|
+
const cursor = document.createElement("span");
|
|
25
|
+
cursor.classList.add("collaboration-carets__caret");
|
|
26
|
+
cursor.setAttribute("style", `border-color: ${user.color}`);
|
|
27
|
+
const label = document.createElement("div");
|
|
28
|
+
label.classList.add("collaboration-carets__label");
|
|
29
|
+
label.setAttribute("style", `background-color: ${user.color}`);
|
|
30
|
+
label.insertBefore(document.createTextNode(user.name), null);
|
|
31
|
+
cursor.insertBefore(label, null);
|
|
32
|
+
return cursor;
|
|
33
|
+
},
|
|
34
|
+
selectionRender: defaultSelectionBuilder,
|
|
35
|
+
onUpdate: defaultOnUpdate
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
onCreate() {
|
|
39
|
+
if (this.options.onUpdate !== defaultOnUpdate) {
|
|
40
|
+
console.warn(
|
|
41
|
+
'[tiptap warn]: DEPRECATED: The "onUpdate" option is deprecated. Please use `editor.storage.collaborationCaret.users` instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret'
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
if (!this.options.provider) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
'The "provider" option is required for the CollaborationCaret extension'
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
addStorage() {
|
|
51
|
+
return {
|
|
52
|
+
users: []
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
addCommands() {
|
|
56
|
+
return {
|
|
57
|
+
updateUser: (attributes) => () => {
|
|
58
|
+
this.options.provider.awareness.setLocalStateField("user", attributes);
|
|
59
|
+
return true;
|
|
60
|
+
},
|
|
61
|
+
user: (attributes) => ({ editor }) => {
|
|
62
|
+
console.warn(
|
|
63
|
+
'[tiptap warn]: DEPRECATED: The "user" command is deprecated. Please use "updateUser" instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret'
|
|
64
|
+
);
|
|
65
|
+
return editor.commands.updateUser(attributes);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
addProseMirrorPlugins() {
|
|
70
|
+
return [
|
|
71
|
+
yCursorPlugin(
|
|
72
|
+
(() => {
|
|
73
|
+
this.options.provider.awareness.setLocalStateField(
|
|
74
|
+
"user",
|
|
75
|
+
this.options.user
|
|
76
|
+
);
|
|
77
|
+
this.storage.users = awarenessStatesToArray(
|
|
78
|
+
this.options.provider.awareness.states
|
|
79
|
+
);
|
|
80
|
+
this.options.provider.awareness.on("update", () => {
|
|
81
|
+
this.storage.users = awarenessStatesToArray(
|
|
82
|
+
this.options.provider.awareness.states
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
return this.options.provider.awareness;
|
|
86
|
+
})(),
|
|
87
|
+
{
|
|
88
|
+
cursorBuilder: this.options.render,
|
|
89
|
+
selectionBuilder: this.options.selectionRender
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
export { CollaborationCaret };
|
|
97
|
+
//# sourceMappingURL=collaboration-caret.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collaboration-caret.js","sources":["../../src/collaboration-caret/collaboration-caret.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025, Tiptap GmbH\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n// There are some lint errors in this file as it's a direct copy of the original code from Tiptap. In order to not diverge from the original code, we're disabling the lint errors.\n/* eslint-disable */\nimport { Extension } from \"@tiptap/core\";\nimport type { DecorationAttrs } from \"@tiptap/pm/view\";\nimport { defaultSelectionBuilder, yCursorPlugin } from \"y-prosemirror\";\n\ntype CollaborationCaretStorage = {\n users: { clientId: number; [key: string]: any }[];\n};\n\nexport interface CollaborationCaretOptions {\n /**\n * The Hocuspocus provider instance. This can also be a TiptapCloudProvider instance.\n * @type {HocuspocusProvider | TiptapCloudProvider}\n * @example new HocuspocusProvider()\n */\n provider: any;\n\n /**\n * The user details object – feel free to add properties to this object as needed\n * @example { name: 'John Doe', color: '#305500' }\n */\n user: Record<string, any>;\n\n /**\n * A function that returns a DOM element for the cursor.\n * @param user The user details object\n * @example\n * render: user => {\n * const cursor = document.createElement('span')\n * cursor.classList.add('collaboration-carets__caret')\n * cursor.setAttribute('style', `border-color: ${user.color}`)\n *\n * const label = document.createElement('div')\n * label.classList.add('collaboration-carets__label')\n * label.setAttribute('style', `background-color: ${user.color}`)\n * label.insertBefore(document.createTextNode(user.name), null)\n *\n * cursor.insertBefore(label, null)\n * return cursor\n * }\n */\n render(user: Record<string, any>): HTMLElement;\n\n /**\n * A function that returns a ProseMirror DecorationAttrs object for the selection.\n * @param user The user details object\n * @example\n * selectionRender: user => {\n * return {\n * nodeName: 'span',\n * class: 'collaboration-carets__selection',\n * style: `background-color: ${user.color}`,\n * 'data-user': user.name,\n * }\n */\n selectionRender(user: Record<string, any>): DecorationAttrs;\n\n /**\n * @deprecated The \"onUpdate\" option is deprecated. Please use `editor.storage.collaborationCaret.users` instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret\n */\n onUpdate: (users: { clientId: number; [key: string]: any }[]) => null;\n}\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n collaborationCaret: {\n /**\n * Update details of the current user\n * @example editor.commands.updateUser({ name: 'John Doe', color: '#305500' })\n */\n updateUser: (attributes: Record<string, any>) => ReturnType;\n /**\n * Update details of the current user\n *\n * @deprecated The \"user\" command is deprecated. Please use \"updateUser\" instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret\n */\n user: (attributes: Record<string, any>) => ReturnType;\n };\n }\n\n interface Storage {\n collaborationCaret: CollaborationCaretStorage;\n }\n}\n\nconst awarenessStatesToArray = (states: Map<number, Record<string, any>>) => {\n return Array.from(states.entries()).map(([key, value]) => {\n return {\n clientId: key,\n ...value.user,\n };\n });\n};\n\nconst defaultOnUpdate = () => null;\n\n/**\n * This extension allows you to add collaboration carets to your editor.\n * @see https://tiptap.dev/api/extensions/collaboration-caret\n */\nexport const CollaborationCaret = Extension.create<\n CollaborationCaretOptions,\n CollaborationCaretStorage\n>({\n name: \"collaborationCaret\",\n\n priority: 999,\n\n addOptions() {\n return {\n provider: null,\n user: {\n name: null,\n color: null,\n },\n render: (user) => {\n const cursor = document.createElement(\"span\");\n\n cursor.classList.add(\"collaboration-carets__caret\");\n cursor.setAttribute(\"style\", `border-color: ${user.color}`);\n\n const label = document.createElement(\"div\");\n\n label.classList.add(\"collaboration-carets__label\");\n label.setAttribute(\"style\", `background-color: ${user.color}`);\n label.insertBefore(document.createTextNode(user.name), null);\n cursor.insertBefore(label, null);\n\n return cursor;\n },\n selectionRender: defaultSelectionBuilder,\n onUpdate: defaultOnUpdate,\n };\n },\n\n onCreate() {\n if (this.options.onUpdate !== defaultOnUpdate) {\n console.warn(\n '[tiptap warn]: DEPRECATED: The \"onUpdate\" option is deprecated. Please use `editor.storage.collaborationCaret.users` instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret'\n );\n }\n if (!this.options.provider) {\n throw new Error(\n 'The \"provider\" option is required for the CollaborationCaret extension'\n );\n }\n },\n\n addStorage() {\n return {\n users: [],\n };\n },\n\n addCommands() {\n return {\n updateUser: (attributes) => () => {\n this.options.provider.awareness.setLocalStateField(\"user\", attributes);\n return true;\n },\n user:\n (attributes) =>\n ({ editor }) => {\n console.warn(\n '[tiptap warn]: DEPRECATED: The \"user\" command is deprecated. Please use \"updateUser\" instead. Read more: https://tiptap.dev/api/extensions/collaboration-caret'\n );\n\n return editor.commands.updateUser(attributes);\n },\n };\n },\n\n addProseMirrorPlugins() {\n return [\n yCursorPlugin(\n (() => {\n this.options.provider.awareness.setLocalStateField(\n \"user\",\n this.options.user\n );\n\n this.storage.users = awarenessStatesToArray(\n this.options.provider.awareness.states\n );\n\n this.options.provider.awareness.on(\"update\", () => {\n this.storage.users = awarenessStatesToArray(\n this.options.provider.awareness.states\n );\n });\n\n return this.options.provider.awareness;\n })(),\n {\n cursorBuilder: this.options.render,\n selectionBuilder: this.options.selectionRender,\n }\n ),\n ];\n },\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -156,7 +156,10 @@ function AnchoredThreads({
|
|
|
156
156
|
Math.min(position.from, editor.state.doc.content.size - 1)
|
|
157
157
|
);
|
|
158
158
|
const rect = utils.getRectFromCoords(coords);
|
|
159
|
-
|
|
159
|
+
let offset = 0;
|
|
160
|
+
if (editor.options.element instanceof HTMLElement) {
|
|
161
|
+
offset = editor.options.element.getBoundingClientRect().top;
|
|
162
|
+
}
|
|
160
163
|
let top = rect.top - offset;
|
|
161
164
|
if (positions.has(thread.id)) {
|
|
162
165
|
top = positions.get(thread.id);
|