@vervedoc/docx-editor-collaboration 1.0.0
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.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docx-editor-collaboration.js","sources":["../src/types.ts","../node_modules/fast-json-patch/module/helpers.mjs","../node_modules/fast-json-patch/module/core.mjs","../node_modules/fast-json-patch/module/duplex.mjs","../node_modules/fast-json-patch/index.mjs","../src/binding/YjsBinding.ts","../src/cursor/AwarenessCursorManager.ts","../node_modules/eventemitter3/index.js","../src/plugin/CollaborationPlugin.ts"],"sourcesContent":["/**\r\n * 协同编辑类型定义\r\n * 基于 Yjs CRDT + Hocuspocus\r\n */\r\n\r\n/**\r\n * 用户信息\r\n */\r\nexport interface UserInfo {\r\n userId: string\r\n userName: string\r\n color: string\r\n}\r\n\r\n/**\r\n * 协同会话配置\r\n */\r\nexport interface CollaborationConfig {\r\n /** Hocuspocus WebSocket 服务器地址,例如 ws://localhost:1234 */\r\n serverUrl: string\r\n /** 文档 ID(对应 Hocuspocus documentName) */\r\n docId: string\r\n /** 当前用户信息 */\r\n user: UserInfo\r\n /** 认证令牌(传给 Hocuspocus onAuthenticate);不传则自动从 user 构造 */\r\n token?: string\r\n}\r\n\r\n/**\r\n * 光标位置\r\n */\r\nexport interface CursorPosition {\r\n index: number\r\n endIndex?: number\r\n}\r\n\r\n/**\r\n * 远程用户光标\r\n */\r\nexport interface RemoteCursor {\r\n userId: string\r\n userName: string\r\n color: string\r\n position: CursorPosition\r\n lastUpdate: number\r\n}\r\n\r\n/**\r\n * 编辑器接口(与 DocxEditor 兼容)\r\n */\r\nexport interface EditorInterface {\r\n command: {\r\n getValue(): {\r\n version: string\r\n data: { header?: unknown[]; main: unknown[]; footer?: unknown[] }\r\n options: unknown\r\n }\r\n executeSetValue(\r\n payload: { header?: unknown[]; main?: unknown[]; footer?: unknown[] },\r\n options?: { isSetCursor?: boolean },\r\n ): void\r\n getRange(): { startIndex: number; endIndex: number } | null\r\n executeSetRange(startIndex: number, endIndex: number): void\r\n }\r\n listener: {\r\n contentChange?: () => void\r\n rangeStyleChange?: (rangeStyle: unknown) => void\r\n }\r\n eventBus: {\r\n select(event: string): {\r\n subscribe(callback: (...args: unknown[]) => void): { unsubscribe: () => void }\r\n }\r\n on?(event: string, callback: (...args: unknown[]) => void): void\r\n off?(event: string, callback: (...args: unknown[]) => void): void\r\n }\r\n}\r\n\r\n/**\r\n * 连接状态\r\n */\r\nexport enum ConnectionState {\r\n DISCONNECTED = 'disconnected',\r\n CONNECTING = 'connecting',\r\n CONNECTED = 'connected',\r\n}\r\n\r\n/**\r\n * 同步状态\r\n */\r\nexport enum SyncState {\r\n SYNCING = 'syncing',\r\n SYNCED = 'synced',\r\n}\r\n","/*!\n * https://github.com/Starcounter-Jack/JSON-Patch\n * (c) 2017-2022 Joachim Wester\n * MIT licensed\n */\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\nexport function hasOwnProperty(obj, key) {\n return _hasOwnProperty.call(obj, key);\n}\nexport function _objectKeys(obj) {\n if (Array.isArray(obj)) {\n var keys_1 = new Array(obj.length);\n for (var k = 0; k < keys_1.length; k++) {\n keys_1[k] = \"\" + k;\n }\n return keys_1;\n }\n if (Object.keys) {\n return Object.keys(obj);\n }\n var keys = [];\n for (var i in obj) {\n if (hasOwnProperty(obj, i)) {\n keys.push(i);\n }\n }\n return keys;\n}\n;\n/**\n* Deeply clone the object.\n* https://jsperf.com/deep-copy-vs-json-stringify-json-parse/25 (recursiveDeepCopy)\n* @param {any} obj value to clone\n* @return {any} cloned obj\n*/\nexport function _deepClone(obj) {\n switch (typeof obj) {\n case \"object\":\n return JSON.parse(JSON.stringify(obj)); //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5\n case \"undefined\":\n return null; //this is how JSON.stringify behaves for array items\n default:\n return obj; //no need to clone primitives\n }\n}\n//3x faster than cached /^\\d+$/.test(str)\nexport function isInteger(str) {\n var i = 0;\n var len = str.length;\n var charCode;\n while (i < len) {\n charCode = str.charCodeAt(i);\n if (charCode >= 48 && charCode <= 57) {\n i++;\n continue;\n }\n return false;\n }\n return true;\n}\n/**\n* Escapes a json pointer path\n* @param path The raw pointer\n* @return the Escaped path\n*/\nexport function escapePathComponent(path) {\n if (path.indexOf('/') === -1 && path.indexOf('~') === -1)\n return path;\n return path.replace(/~/g, '~0').replace(/\\//g, '~1');\n}\n/**\n * Unescapes a json pointer path\n * @param path The escaped pointer\n * @return The unescaped path\n */\nexport function unescapePathComponent(path) {\n return path.replace(/~1/g, '/').replace(/~0/g, '~');\n}\nexport function _getPathRecursive(root, obj) {\n var found;\n for (var key in root) {\n if (hasOwnProperty(root, key)) {\n if (root[key] === obj) {\n return escapePathComponent(key) + '/';\n }\n else if (typeof root[key] === 'object') {\n found = _getPathRecursive(root[key], obj);\n if (found != '') {\n return escapePathComponent(key) + '/' + found;\n }\n }\n }\n }\n return '';\n}\nexport function getPath(root, obj) {\n if (root === obj) {\n return '/';\n }\n var path = _getPathRecursive(root, obj);\n if (path === '') {\n throw new Error(\"Object not found in root\");\n }\n return \"/\" + path;\n}\n/**\n* Recursively checks whether an object has any undefined values inside.\n*/\nexport function hasUndefined(obj) {\n if (obj === undefined) {\n return true;\n }\n if (obj) {\n if (Array.isArray(obj)) {\n for (var i_1 = 0, len = obj.length; i_1 < len; i_1++) {\n if (hasUndefined(obj[i_1])) {\n return true;\n }\n }\n }\n else if (typeof obj === \"object\") {\n var objKeys = _objectKeys(obj);\n var objKeysLength = objKeys.length;\n for (var i = 0; i < objKeysLength; i++) {\n if (hasUndefined(obj[objKeys[i]])) {\n return true;\n }\n }\n }\n }\n return false;\n}\nfunction patchErrorMessageFormatter(message, args) {\n var messageParts = [message];\n for (var key in args) {\n var value = typeof args[key] === 'object' ? JSON.stringify(args[key], null, 2) : args[key]; // pretty print\n if (typeof value !== 'undefined') {\n messageParts.push(key + \": \" + value);\n }\n }\n return messageParts.join('\\n');\n}\nvar PatchError = /** @class */ (function (_super) {\n __extends(PatchError, _super);\n function PatchError(message, name, index, operation, tree) {\n var _newTarget = this.constructor;\n var _this = _super.call(this, patchErrorMessageFormatter(message, { name: name, index: index, operation: operation, tree: tree })) || this;\n _this.name = name;\n _this.index = index;\n _this.operation = operation;\n _this.tree = tree;\n Object.setPrototypeOf(_this, _newTarget.prototype); // restore prototype chain, see https://stackoverflow.com/a/48342359\n _this.message = patchErrorMessageFormatter(message, { name: name, index: index, operation: operation, tree: tree });\n return _this;\n }\n return PatchError;\n}(Error));\nexport { PatchError };\n","import { PatchError, _deepClone, isInteger, unescapePathComponent, hasUndefined } from './helpers.mjs';\nexport var JsonPatchError = PatchError;\nexport var deepClone = _deepClone;\n/* We use a Javascript hash to store each\n function. Each hash entry (property) uses\n the operation identifiers specified in rfc6902.\n In this way, we can map each patch operation\n to its dedicated function in efficient way.\n */\n/* The operations applicable to an object */\nvar objOps = {\n add: function (obj, key, document) {\n obj[key] = this.value;\n return { newDocument: document };\n },\n remove: function (obj, key, document) {\n var removed = obj[key];\n delete obj[key];\n return { newDocument: document, removed: removed };\n },\n replace: function (obj, key, document) {\n var removed = obj[key];\n obj[key] = this.value;\n return { newDocument: document, removed: removed };\n },\n move: function (obj, key, document) {\n /* in case move target overwrites an existing value,\n return the removed value, this can be taxing performance-wise,\n and is potentially unneeded */\n var removed = getValueByPointer(document, this.path);\n if (removed) {\n removed = _deepClone(removed);\n }\n var originalValue = applyOperation(document, { op: \"remove\", path: this.from }).removed;\n applyOperation(document, { op: \"add\", path: this.path, value: originalValue });\n return { newDocument: document, removed: removed };\n },\n copy: function (obj, key, document) {\n var valueToCopy = getValueByPointer(document, this.from);\n // enforce copy by value so further operations don't affect source (see issue #177)\n applyOperation(document, { op: \"add\", path: this.path, value: _deepClone(valueToCopy) });\n return { newDocument: document };\n },\n test: function (obj, key, document) {\n return { newDocument: document, test: _areEquals(obj[key], this.value) };\n },\n _get: function (obj, key, document) {\n this.value = obj[key];\n return { newDocument: document };\n }\n};\n/* The operations applicable to an array. Many are the same as for the object */\nvar arrOps = {\n add: function (arr, i, document) {\n if (isInteger(i)) {\n arr.splice(i, 0, this.value);\n }\n else { // array props\n arr[i] = this.value;\n }\n // this may be needed when using '-' in an array\n return { newDocument: document, index: i };\n },\n remove: function (arr, i, document) {\n var removedList = arr.splice(i, 1);\n return { newDocument: document, removed: removedList[0] };\n },\n replace: function (arr, i, document) {\n var removed = arr[i];\n arr[i] = this.value;\n return { newDocument: document, removed: removed };\n },\n move: objOps.move,\n copy: objOps.copy,\n test: objOps.test,\n _get: objOps._get\n};\n/**\n * Retrieves a value from a JSON document by a JSON pointer.\n * Returns the value.\n *\n * @param document The document to get the value from\n * @param pointer an escaped JSON pointer\n * @return The retrieved value\n */\nexport function getValueByPointer(document, pointer) {\n if (pointer == '') {\n return document;\n }\n var getOriginalDestination = { op: \"_get\", path: pointer };\n applyOperation(document, getOriginalDestination);\n return getOriginalDestination.value;\n}\n/**\n * Apply a single JSON Patch Operation on a JSON document.\n * Returns the {newDocument, result} of the operation.\n * It modifies the `document` and `operation` objects - it gets the values by reference.\n * If you would like to avoid touching your values, clone them:\n * `jsonpatch.applyOperation(document, jsonpatch._deepClone(operation))`.\n *\n * @param document The document to patch\n * @param operation The operation to apply\n * @param validateOperation `false` is without validation, `true` to use default jsonpatch's validation, or you can pass a `validateOperation` callback to be used for validation.\n * @param mutateDocument Whether to mutate the original document or clone it before applying\n * @param banPrototypeModifications Whether to ban modifications to `__proto__`, defaults to `true`.\n * @return `{newDocument, result}` after the operation\n */\nexport function applyOperation(document, operation, validateOperation, mutateDocument, banPrototypeModifications, index) {\n if (validateOperation === void 0) { validateOperation = false; }\n if (mutateDocument === void 0) { mutateDocument = true; }\n if (banPrototypeModifications === void 0) { banPrototypeModifications = true; }\n if (index === void 0) { index = 0; }\n if (validateOperation) {\n if (typeof validateOperation == 'function') {\n validateOperation(operation, 0, document, operation.path);\n }\n else {\n validator(operation, 0);\n }\n }\n /* ROOT OPERATIONS */\n if (operation.path === \"\") {\n var returnValue = { newDocument: document };\n if (operation.op === 'add') {\n returnValue.newDocument = operation.value;\n return returnValue;\n }\n else if (operation.op === 'replace') {\n returnValue.newDocument = operation.value;\n returnValue.removed = document; //document we removed\n return returnValue;\n }\n else if (operation.op === 'move' || operation.op === 'copy') { // it's a move or copy to root\n returnValue.newDocument = getValueByPointer(document, operation.from); // get the value by json-pointer in `from` field\n if (operation.op === 'move') { // report removed item\n returnValue.removed = document;\n }\n return returnValue;\n }\n else if (operation.op === 'test') {\n returnValue.test = _areEquals(document, operation.value);\n if (returnValue.test === false) {\n throw new JsonPatchError(\"Test operation failed\", 'TEST_OPERATION_FAILED', index, operation, document);\n }\n returnValue.newDocument = document;\n return returnValue;\n }\n else if (operation.op === 'remove') { // a remove on root\n returnValue.removed = document;\n returnValue.newDocument = null;\n return returnValue;\n }\n else if (operation.op === '_get') {\n operation.value = document;\n return returnValue;\n }\n else { /* bad operation */\n if (validateOperation) {\n throw new JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, document);\n }\n else {\n return returnValue;\n }\n }\n } /* END ROOT OPERATIONS */\n else {\n if (!mutateDocument) {\n document = _deepClone(document);\n }\n var path = operation.path || \"\";\n var keys = path.split('/');\n var obj = document;\n var t = 1; //skip empty element - http://jsperf.com/to-shift-or-not-to-shift\n var len = keys.length;\n var existingPathFragment = undefined;\n var key = void 0;\n var validateFunction = void 0;\n if (typeof validateOperation == 'function') {\n validateFunction = validateOperation;\n }\n else {\n validateFunction = validator;\n }\n while (true) {\n key = keys[t];\n if (key && key.indexOf('~') != -1) {\n key = unescapePathComponent(key);\n }\n if (banPrototypeModifications &&\n (key == '__proto__' ||\n (key == 'prototype' && t > 0 && keys[t - 1] == 'constructor'))) {\n throw new TypeError('JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README');\n }\n if (validateOperation) {\n if (existingPathFragment === undefined) {\n if (obj[key] === undefined) {\n existingPathFragment = keys.slice(0, t).join('/');\n }\n else if (t == len - 1) {\n existingPathFragment = operation.path;\n }\n if (existingPathFragment !== undefined) {\n validateFunction(operation, 0, document, existingPathFragment);\n }\n }\n }\n t++;\n if (Array.isArray(obj)) {\n if (key === '-') {\n key = obj.length;\n }\n else {\n if (validateOperation && !isInteger(key)) {\n throw new JsonPatchError(\"Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index\", \"OPERATION_PATH_ILLEGAL_ARRAY_INDEX\", index, operation, document);\n } // only parse key when it's an integer for `arr.prop` to work\n else if (isInteger(key)) {\n key = ~~key;\n }\n }\n if (t >= len) {\n if (validateOperation && operation.op === \"add\" && key > obj.length) {\n throw new JsonPatchError(\"The specified index MUST NOT be greater than the number of elements in the array\", \"OPERATION_VALUE_OUT_OF_BOUNDS\", index, operation, document);\n }\n var returnValue = arrOps[operation.op].call(operation, obj, key, document); // Apply patch\n if (returnValue.test === false) {\n throw new JsonPatchError(\"Test operation failed\", 'TEST_OPERATION_FAILED', index, operation, document);\n }\n return returnValue;\n }\n }\n else {\n if (t >= len) {\n var returnValue = objOps[operation.op].call(operation, obj, key, document); // Apply patch\n if (returnValue.test === false) {\n throw new JsonPatchError(\"Test operation failed\", 'TEST_OPERATION_FAILED', index, operation, document);\n }\n return returnValue;\n }\n }\n obj = obj[key];\n // If we have more keys in the path, but the next value isn't a non-null object,\n // throw an OPERATION_PATH_UNRESOLVABLE error instead of iterating again.\n if (validateOperation && t < len && (!obj || typeof obj !== \"object\")) {\n throw new JsonPatchError('Cannot perform operation at the desired path', 'OPERATION_PATH_UNRESOLVABLE', index, operation, document);\n }\n }\n }\n}\n/**\n * Apply a full JSON Patch array on a JSON document.\n * Returns the {newDocument, result} of the patch.\n * It modifies the `document` object and `patch` - it gets the values by reference.\n * If you would like to avoid touching your values, clone them:\n * `jsonpatch.applyPatch(document, jsonpatch._deepClone(patch))`.\n *\n * @param document The document to patch\n * @param patch The patch to apply\n * @param validateOperation `false` is without validation, `true` to use default jsonpatch's validation, or you can pass a `validateOperation` callback to be used for validation.\n * @param mutateDocument Whether to mutate the original document or clone it before applying\n * @param banPrototypeModifications Whether to ban modifications to `__proto__`, defaults to `true`.\n * @return An array of `{newDocument, result}` after the patch\n */\nexport function applyPatch(document, patch, validateOperation, mutateDocument, banPrototypeModifications) {\n if (mutateDocument === void 0) { mutateDocument = true; }\n if (banPrototypeModifications === void 0) { banPrototypeModifications = true; }\n if (validateOperation) {\n if (!Array.isArray(patch)) {\n throw new JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY');\n }\n }\n if (!mutateDocument) {\n document = _deepClone(document);\n }\n var results = new Array(patch.length);\n for (var i = 0, length_1 = patch.length; i < length_1; i++) {\n // we don't need to pass mutateDocument argument because if it was true, we already deep cloned the object, we'll just pass `true`\n results[i] = applyOperation(document, patch[i], validateOperation, true, banPrototypeModifications, i);\n document = results[i].newDocument; // in case root was replaced\n }\n results.newDocument = document;\n return results;\n}\n/**\n * Apply a single JSON Patch Operation on a JSON document.\n * Returns the updated document.\n * Suitable as a reducer.\n *\n * @param document The document to patch\n * @param operation The operation to apply\n * @return The updated document\n */\nexport function applyReducer(document, operation, index) {\n var operationResult = applyOperation(document, operation);\n if (operationResult.test === false) { // failed test\n throw new JsonPatchError(\"Test operation failed\", 'TEST_OPERATION_FAILED', index, operation, document);\n }\n return operationResult.newDocument;\n}\n/**\n * Validates a single operation. Called from `jsonpatch.validate`. Throws `JsonPatchError` in case of an error.\n * @param {object} operation - operation object (patch)\n * @param {number} index - index of operation in the sequence\n * @param {object} [document] - object where the operation is supposed to be applied\n * @param {string} [existingPathFragment] - comes along with `document`\n */\nexport function validator(operation, index, document, existingPathFragment) {\n if (typeof operation !== 'object' || operation === null || Array.isArray(operation)) {\n throw new JsonPatchError('Operation is not an object', 'OPERATION_NOT_AN_OBJECT', index, operation, document);\n }\n else if (!objOps[operation.op]) {\n throw new JsonPatchError('Operation `op` property is not one of operations defined in RFC-6902', 'OPERATION_OP_INVALID', index, operation, document);\n }\n else if (typeof operation.path !== 'string') {\n throw new JsonPatchError('Operation `path` property is not a string', 'OPERATION_PATH_INVALID', index, operation, document);\n }\n else if (operation.path.indexOf('/') !== 0 && operation.path.length > 0) {\n // paths that aren't empty string should start with \"/\"\n throw new JsonPatchError('Operation `path` property must start with \"/\"', 'OPERATION_PATH_INVALID', index, operation, document);\n }\n else if ((operation.op === 'move' || operation.op === 'copy') && typeof operation.from !== 'string') {\n throw new JsonPatchError('Operation `from` property is not present (applicable in `move` and `copy` operations)', 'OPERATION_FROM_REQUIRED', index, operation, document);\n }\n else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && operation.value === undefined) {\n throw new JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_REQUIRED', index, operation, document);\n }\n else if ((operation.op === 'add' || operation.op === 'replace' || operation.op === 'test') && hasUndefined(operation.value)) {\n throw new JsonPatchError('Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)', 'OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED', index, operation, document);\n }\n else if (document) {\n if (operation.op == \"add\") {\n var pathLen = operation.path.split(\"/\").length;\n var existingPathLen = existingPathFragment.split(\"/\").length;\n if (pathLen !== existingPathLen + 1 && pathLen !== existingPathLen) {\n throw new JsonPatchError('Cannot perform an `add` operation at the desired path', 'OPERATION_PATH_CANNOT_ADD', index, operation, document);\n }\n }\n else if (operation.op === 'replace' || operation.op === 'remove' || operation.op === '_get') {\n if (operation.path !== existingPathFragment) {\n throw new JsonPatchError('Cannot perform the operation at a path that does not exist', 'OPERATION_PATH_UNRESOLVABLE', index, operation, document);\n }\n }\n else if (operation.op === 'move' || operation.op === 'copy') {\n var existingValue = { op: \"_get\", path: operation.from, value: undefined };\n var error = validate([existingValue], document);\n if (error && error.name === 'OPERATION_PATH_UNRESOLVABLE') {\n throw new JsonPatchError('Cannot perform the operation from a path that does not exist', 'OPERATION_FROM_UNRESOLVABLE', index, operation, document);\n }\n }\n }\n}\n/**\n * Validates a sequence of operations. If `document` parameter is provided, the sequence is additionally validated against the object document.\n * If error is encountered, returns a JsonPatchError object\n * @param sequence\n * @param document\n * @returns {JsonPatchError|undefined}\n */\nexport function validate(sequence, document, externalValidator) {\n try {\n if (!Array.isArray(sequence)) {\n throw new JsonPatchError('Patch sequence must be an array', 'SEQUENCE_NOT_AN_ARRAY');\n }\n if (document) {\n //clone document and sequence so that we can safely try applying operations\n applyPatch(_deepClone(document), _deepClone(sequence), externalValidator || true);\n }\n else {\n externalValidator = externalValidator || validator;\n for (var i = 0; i < sequence.length; i++) {\n externalValidator(sequence[i], i, document, undefined);\n }\n }\n }\n catch (e) {\n if (e instanceof JsonPatchError) {\n return e;\n }\n else {\n throw e;\n }\n }\n}\n// based on https://github.com/epoberezkin/fast-deep-equal\n// MIT License\n// Copyright (c) 2017 Evgeny Poberezkin\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\nexport function _areEquals(a, b) {\n if (a === b)\n return true;\n if (a && b && typeof a == 'object' && typeof b == 'object') {\n var arrA = Array.isArray(a), arrB = Array.isArray(b), i, length, key;\n if (arrA && arrB) {\n length = a.length;\n if (length != b.length)\n return false;\n for (i = length; i-- !== 0;)\n if (!_areEquals(a[i], b[i]))\n return false;\n return true;\n }\n if (arrA != arrB)\n return false;\n var keys = Object.keys(a);\n length = keys.length;\n if (length !== Object.keys(b).length)\n return false;\n for (i = length; i-- !== 0;)\n if (!b.hasOwnProperty(keys[i]))\n return false;\n for (i = length; i-- !== 0;) {\n key = keys[i];\n if (!_areEquals(a[key], b[key]))\n return false;\n }\n return true;\n }\n return a !== a && b !== b;\n}\n;\n","/*!\n * https://github.com/Starcounter-Jack/JSON-Patch\n * (c) 2017-2021 Joachim Wester\n * MIT license\n */\nimport { _deepClone, _objectKeys, escapePathComponent, hasOwnProperty } from './helpers.mjs';\nimport { applyPatch } from './core.mjs';\nvar beforeDict = new WeakMap();\nvar Mirror = /** @class */ (function () {\n function Mirror(obj) {\n this.observers = new Map();\n this.obj = obj;\n }\n return Mirror;\n}());\nvar ObserverInfo = /** @class */ (function () {\n function ObserverInfo(callback, observer) {\n this.callback = callback;\n this.observer = observer;\n }\n return ObserverInfo;\n}());\nfunction getMirror(obj) {\n return beforeDict.get(obj);\n}\nfunction getObserverFromMirror(mirror, callback) {\n return mirror.observers.get(callback);\n}\nfunction removeObserverFromMirror(mirror, observer) {\n mirror.observers.delete(observer.callback);\n}\n/**\n * Detach an observer from an object\n */\nexport function unobserve(root, observer) {\n observer.unobserve();\n}\n/**\n * Observes changes made to an object, which can then be retrieved using generate\n */\nexport function observe(obj, callback) {\n var patches = [];\n var observer;\n var mirror = getMirror(obj);\n if (!mirror) {\n mirror = new Mirror(obj);\n beforeDict.set(obj, mirror);\n }\n else {\n var observerInfo = getObserverFromMirror(mirror, callback);\n observer = observerInfo && observerInfo.observer;\n }\n if (observer) {\n return observer;\n }\n observer = {};\n mirror.value = _deepClone(obj);\n if (callback) {\n observer.callback = callback;\n observer.next = null;\n var dirtyCheck = function () {\n generate(observer);\n };\n var fastCheck = function () {\n clearTimeout(observer.next);\n observer.next = setTimeout(dirtyCheck);\n };\n if (typeof window !== 'undefined') { //not Node\n window.addEventListener('mouseup', fastCheck);\n window.addEventListener('keyup', fastCheck);\n window.addEventListener('mousedown', fastCheck);\n window.addEventListener('keydown', fastCheck);\n window.addEventListener('change', fastCheck);\n }\n }\n observer.patches = patches;\n observer.object = obj;\n observer.unobserve = function () {\n generate(observer);\n clearTimeout(observer.next);\n removeObserverFromMirror(mirror, observer);\n if (typeof window !== 'undefined') {\n window.removeEventListener('mouseup', fastCheck);\n window.removeEventListener('keyup', fastCheck);\n window.removeEventListener('mousedown', fastCheck);\n window.removeEventListener('keydown', fastCheck);\n window.removeEventListener('change', fastCheck);\n }\n };\n mirror.observers.set(callback, new ObserverInfo(callback, observer));\n return observer;\n}\n/**\n * Generate an array of patches from an observer\n */\nexport function generate(observer, invertible) {\n if (invertible === void 0) { invertible = false; }\n var mirror = beforeDict.get(observer.object);\n _generate(mirror.value, observer.object, observer.patches, \"\", invertible);\n if (observer.patches.length) {\n applyPatch(mirror.value, observer.patches);\n }\n var temp = observer.patches;\n if (temp.length > 0) {\n observer.patches = [];\n if (observer.callback) {\n observer.callback(temp);\n }\n }\n return temp;\n}\n// Dirty check if obj is different from mirror, generate patches and update mirror\nfunction _generate(mirror, obj, patches, path, invertible) {\n if (obj === mirror) {\n return;\n }\n if (typeof obj.toJSON === \"function\") {\n obj = obj.toJSON();\n }\n var newKeys = _objectKeys(obj);\n var oldKeys = _objectKeys(mirror);\n var changed = false;\n var deleted = false;\n //if ever \"move\" operation is implemented here, make sure this test runs OK: \"should not generate the same patch twice (move)\"\n for (var t = oldKeys.length - 1; t >= 0; t--) {\n var key = oldKeys[t];\n var oldVal = mirror[key];\n if (hasOwnProperty(obj, key) && !(obj[key] === undefined && oldVal !== undefined && Array.isArray(obj) === false)) {\n var newVal = obj[key];\n if (typeof oldVal == \"object\" && oldVal != null && typeof newVal == \"object\" && newVal != null && Array.isArray(oldVal) === Array.isArray(newVal)) {\n _generate(oldVal, newVal, patches, path + \"/\" + escapePathComponent(key), invertible);\n }\n else {\n if (oldVal !== newVal) {\n changed = true;\n if (invertible) {\n patches.push({ op: \"test\", path: path + \"/\" + escapePathComponent(key), value: _deepClone(oldVal) });\n }\n patches.push({ op: \"replace\", path: path + \"/\" + escapePathComponent(key), value: _deepClone(newVal) });\n }\n }\n }\n else if (Array.isArray(mirror) === Array.isArray(obj)) {\n if (invertible) {\n patches.push({ op: \"test\", path: path + \"/\" + escapePathComponent(key), value: _deepClone(oldVal) });\n }\n patches.push({ op: \"remove\", path: path + \"/\" + escapePathComponent(key) });\n deleted = true; // property has been deleted\n }\n else {\n if (invertible) {\n patches.push({ op: \"test\", path: path, value: mirror });\n }\n patches.push({ op: \"replace\", path: path, value: obj });\n changed = true;\n }\n }\n if (!deleted && newKeys.length == oldKeys.length) {\n return;\n }\n for (var t = 0; t < newKeys.length; t++) {\n var key = newKeys[t];\n if (!hasOwnProperty(mirror, key) && obj[key] !== undefined) {\n patches.push({ op: \"add\", path: path + \"/\" + escapePathComponent(key), value: _deepClone(obj[key]) });\n }\n }\n}\n/**\n * Create an array of patches from the differences in two objects\n */\nexport function compare(tree1, tree2, invertible) {\n if (invertible === void 0) { invertible = false; }\n var patches = [];\n _generate(tree1, tree2, patches, '', invertible);\n return patches;\n}\n","export * from './module/core.mjs';\nexport * from './module/duplex.mjs';\nexport {\n PatchError as JsonPatchError,\n _deepClone as deepClone,\n escapePathComponent,\n unescapePathComponent\n} from './module/helpers.mjs';\n\n\n/**\n * Default export for backwards compat\n */\n\nimport * as core from './module/core.mjs';\nimport * as duplex from './module/duplex.mjs';\nimport {\n PatchError as JsonPatchError,\n _deepClone as deepClone,\n escapePathComponent,\n unescapePathComponent\n} from './module/helpers.mjs';\n\nexport default Object.assign({}, core, duplex, {\n JsonPatchError,\n deepClone,\n escapePathComponent,\n unescapePathComponent\n});","/**\r\n * Y.Doc ↔ EditorInterface 双向绑定\r\n *\r\n * 职责:\r\n * - 监听 Y.Array<Y.Map>(\"elements\") 变化 → 推送到编辑器\r\n * - 监听编辑器 contentChange → 回写到 Y.Doc\r\n *\r\n * 设计说明:\r\n * 编辑器以 IElement[] 扁平数组为数据模型(字符级),Y.Doc 用\r\n * Y.Array<Y.Map> 一一对应。增量同步采用 JSON Patch(RFC 6902)\r\n * 计算差异并映射到 Y.Array,尽可能减少全量重写。\r\n */\r\nimport * as Y from 'yjs'\r\nimport { compare, type Operation } from 'fast-json-patch'\r\nimport type { EditorInterface } from '../types'\r\n\r\n/** 需要作为 Y.Array 嵌套的数组字段 */\r\nconst NESTED_ARRAY_KEYS = new Set([\r\n 'valueList', 'trList', 'tdList', 'colgroup',\r\n])\r\n\r\nfunction subscribeEventBus(\r\n eventBus: EditorInterface['eventBus'],\r\n event: string,\r\n handler: (...args: unknown[]) => void\r\n): { unsubscribe: () => void } {\r\n if (typeof (eventBus as any).select === 'function') {\r\n return (eventBus as any).select(event).subscribe(handler)\r\n }\r\n if (typeof (eventBus as any).on === 'function') {\r\n ;(eventBus as any).on(event, handler)\r\n return {\r\n unsubscribe: () => {\r\n if (typeof (eventBus as any).off === 'function') {\r\n ;(eventBus as any).off(event, handler)\r\n }\r\n }\r\n }\r\n }\r\n return { unsubscribe: () => {} }\r\n}\r\n\r\nexport class YjsBinding {\r\n private doc: Y.Doc\r\n private editor: EditorInterface\r\n private yElements: Y.Array<Y.Map<unknown>>\r\n\r\n /** 是否正在把远程变更写入编辑器(防回环) */\r\n private isApplyingRemote = false\r\n /** 是否正在把本地编辑写入 Y.Doc(防回环) */\r\n private isApplyingLocal = false\r\n\r\n /** 上一次同步到编辑器的快照(用于 diff) */\r\n private lastSnapshot: Record<string, unknown>[] = []\r\n\r\n /** 编辑器事件回调引用 */\r\n private contentChangeHandler: (() => void) | null = null\r\n private contentChangeSubscription: { unsubscribe: () => void } | null = null\r\n /** Y.Array observe 回调引用 */\r\n private yObserver: ((event: Y.YArrayEvent<Y.Map<unknown>>, tx: Y.Transaction) => void) | null = null\r\n\r\n constructor(doc: Y.Doc, editor: EditorInterface) {\r\n this.doc = doc\r\n this.editor = editor\r\n this.yElements = doc.getArray<Y.Map<unknown>>('elements')\r\n\r\n this.bindYjsToEditor()\r\n this.bindEditorToYjs()\r\n\r\n // 如果 Y.Doc 已有内容(Hocuspocus 从服务端加载),先推送到编辑器\r\n if (this.yElements.length > 0) {\r\n this.pushYDocToEditor()\r\n }\r\n }\r\n\r\n destroy(): void {\r\n if (this.yObserver) {\r\n this.yElements.unobserve(this.yObserver)\r\n this.yObserver = null\r\n }\r\n this.contentChangeSubscription?.unsubscribe()\r\n this.contentChangeSubscription = null\r\n this.contentChangeHandler = null\r\n }\r\n\r\n // ---- Y.Doc → Editor ----\r\n\r\n private bindYjsToEditor(): void {\r\n this.yObserver = (_event, tx) => {\r\n // 忽略本地写入引起的变更\r\n if (this.isApplyingLocal) return\r\n // 忽略本地 origin 的事务(由 pushEditorToYDoc 发起)\r\n if (tx.local) return\r\n this.pushYDocToEditor()\r\n }\r\n this.yElements.observeDeep(this.yObserver as any)\r\n }\r\n\r\n /** 将 Y.Doc 当前内容推送到编辑器 */\r\n private pushYDocToEditor(): void {\r\n this.isApplyingRemote = true\r\n try {\r\n const elements = this.yElements.toJSON() as Record<string, unknown>[]\r\n this.editor.command.executeSetValue({ main: elements as any }, { isSetCursor: false })\r\n this.lastSnapshot = elements\r\n } finally {\r\n this.isApplyingRemote = false\r\n }\r\n }\r\n\r\n // ---- Editor → Y.Doc ----\r\n\r\n private bindEditorToYjs(): void {\r\n this.contentChangeHandler = () => {\r\n if (this.isApplyingRemote) return\r\n this.pushEditorToYDoc()\r\n }\r\n this.contentChangeSubscription = subscribeEventBus(\r\n this.editor.eventBus,\r\n 'contentChange',\r\n this.contentChangeHandler as any\r\n )\r\n }\r\n\r\n /** 将编辑器当前内容全量同步到 Y.Doc */\r\n private pushEditorToYDoc(): void {\r\n const value = this.editor.command.getValue()\r\n const current = (value.data.main ?? []) as Record<string, unknown>[]\r\n\r\n const operations = compare(this.lastSnapshot, current)\r\n if (!operations.length) return\r\n\r\n this.isApplyingLocal = true\r\n try {\r\n this.doc.transact(() => {\r\n this.applyPatchToYArray(this.yElements, operations, current)\r\n }, this) // origin = this 表示本地事务\r\n this.lastSnapshot = this.cloneSnapshot(current)\r\n } finally {\r\n this.isApplyingLocal = false\r\n }\r\n }\r\n\r\n private applyPatchToYArray(\r\n yArray: Y.Array<Y.Map<unknown>>,\r\n operations: Operation[],\r\n current: Record<string, unknown>[]\r\n ): void {\r\n for (const operation of operations) {\r\n const index = this.getTopLevelIndex(operation.path)\r\n if (index === null) continue\r\n\r\n if (operation.op === 'remove') {\r\n if (index < yArray.length) {\r\n yArray.delete(index, 1)\r\n }\r\n continue\r\n }\r\n\r\n if (operation.op === 'add' || operation.op === 'replace') {\r\n const rootValue = this.getRootValueFromOperation(operation, current)\r\n if (!rootValue || Array.isArray(rootValue)) {\r\n continue\r\n }\r\n const yMap = this.jsonToYMap(rootValue)\r\n if (operation.op === 'add') {\r\n yArray.insert(index, [yMap])\r\n } else {\r\n if (index < yArray.length) {\r\n yArray.delete(index, 1)\r\n }\r\n yArray.insert(index, [yMap])\r\n }\r\n }\r\n }\r\n }\r\n\r\n private getTopLevelIndex(path: string): number | null {\r\n const pathSegment = path.split('/')[1]\r\n if (!pathSegment) return null\r\n const index = Number(pathSegment)\r\n return Number.isInteger(index) ? index : null\r\n }\r\n\r\n private getRootValueFromOperation(\r\n operation: Operation,\r\n current: Record<string, unknown>[]\r\n ): Record<string, unknown> | null {\r\n if (operation.path.split('/').length <= 2) {\r\n const value = (operation as { value?: unknown }).value\r\n if (value && typeof value === 'object' && !Array.isArray(value)) {\r\n return value as Record<string, unknown>\r\n }\r\n }\r\n const topIndex = this.getTopLevelIndex(operation.path)\r\n if (topIndex !== null && current[topIndex] && typeof current[topIndex] === 'object') {\r\n return current[topIndex]\r\n }\r\n return null\r\n }\r\n\r\n private cloneSnapshot(arr: Record<string, unknown>[]): Record<string, unknown>[] {\r\n return JSON.parse(JSON.stringify(arr))\r\n }\r\n\r\n /** 将普通 JSON 对象转换为 Y.Map(递归处理嵌套数组) */\r\n private jsonToYMap(obj: Record<string, unknown>): Y.Map<unknown> {\r\n const yMap = new Y.Map<unknown>()\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (value === undefined || value === null) continue\r\n if (NESTED_ARRAY_KEYS.has(key) && Array.isArray(value)) {\r\n const yArr = new Y.Array<Y.Map<unknown>>()\r\n const children = value.map((child: Record<string, unknown>) => this.jsonToYMap(child))\r\n yArr.insert(0, children)\r\n yMap.set(key, yArr)\r\n } else {\r\n yMap.set(key, value)\r\n }\r\n }\r\n return yMap\r\n }\r\n}\r\n","/**\r\n * 基于 Yjs Awareness 协议的远程光标管理器\r\n *\r\n * 与旧版 RemoteCursorManager 保持相同的 DOM 渲染逻辑,\r\n * 但数据源从手动 WebSocket 消息切换为 Awareness 状态自动同步。\r\n */\r\nimport type { Awareness } from 'y-protocols/awareness'\r\nimport type { CursorPosition, RemoteCursor, UserInfo } from '../types'\r\n\r\n/**\r\n * 光标渲染配置\r\n */\r\nexport interface CursorRenderConfig {\r\n showLabel: boolean\r\n labelDuration: number\r\n enableBlink: boolean\r\n expireTime: number\r\n}\r\n\r\nconst DEFAULT_CONFIG: CursorRenderConfig = {\r\n showLabel: true,\r\n labelDuration: 3000,\r\n enableBlink: true,\r\n expireTime: 30000,\r\n}\r\n\r\ninterface CursorElement {\r\n container: HTMLDivElement\r\n cursor: HTMLDivElement\r\n label: HTMLDivElement\r\n labelTimer: ReturnType<typeof setTimeout> | null\r\n}\r\n\r\n/**\r\n * 位置计算回调:将文档中的元素索引转换为屏幕像素坐标\r\n */\r\nexport type PositionCalculator = (\r\n index: number,\r\n) => { x: number; y: number; height: number } | null\r\n\r\nexport class AwarenessCursorManager {\r\n private awareness: Awareness | null = null\r\n\r\n private container: HTMLElement | null = null\r\n private config: CursorRenderConfig\r\n private positionCalculator: PositionCalculator | null = null\r\n\r\n private cursors = new Map<string, RemoteCursor>()\r\n private elements = new Map<string, CursorElement>()\r\n private styleElement: HTMLStyleElement | null = null\r\n private cleanupTimer: ReturnType<typeof setInterval> | null = null\r\n private awarenessHandler: ((change: { added: number[]; updated: number[]; removed: number[] }) => void) | null = null\r\n\r\n constructor(config: Partial<CursorRenderConfig> = {}) {\r\n this.config = { ...DEFAULT_CONFIG, ...config }\r\n }\r\n\r\n /**\r\n * 绑定 Awareness 实例和当前用户信息\r\n */\r\n bindAwareness(awareness: Awareness, localUser: UserInfo): void {\r\n this.awareness = awareness\r\n\r\n // 设置本地 awareness 用户信息\r\n awareness.setLocalStateField('user', {\r\n userId: localUser.userId,\r\n userName: localUser.userName,\r\n color: localUser.color,\r\n })\r\n\r\n // 监听远程 awareness 变化\r\n this.awarenessHandler = ({ added, updated, removed }) => {\r\n const changed = [...added, ...updated]\r\n for (const clientId of changed) {\r\n if (clientId === this.awareness!.clientID) continue\r\n const state = this.awareness!.getStates().get(clientId)\r\n if (!state?.user || !state?.cursor) continue\r\n\r\n const user = state.user as UserInfo\r\n const cursor = state.cursor as CursorPosition\r\n const remoteCursor: RemoteCursor = {\r\n userId: user.userId,\r\n userName: user.userName,\r\n color: user.color,\r\n position: cursor,\r\n lastUpdate: Date.now(),\r\n }\r\n this.cursors.set(user.userId, remoteCursor)\r\n this.renderCursor(remoteCursor)\r\n }\r\n if (removed.length > 0) {\r\n const allStates = this.awareness!.getStates()\r\n this.cleanupRemovedClients(allStates)\r\n }\r\n }\r\n awareness.on('change', this.awarenessHandler)\r\n }\r\n\r\n /**\r\n * 更新本地光标位置(写入 Awareness,自动广播到其他客户端)\r\n */\r\n setLocalCursor(position: CursorPosition): void {\r\n this.awareness?.setLocalStateField('cursor', position)\r\n }\r\n\r\n /**\r\n * 初始化 DOM 渲染\r\n */\r\n initializeCursorRendering(container: HTMLElement, positionCalculator: PositionCalculator): void {\r\n this.container = container\r\n this.positionCalculator = positionCalculator\r\n this.injectStyles()\r\n this.startCleanupTimer()\r\n }\r\n\r\n /**\r\n * 刷新所有光标位置(文档内容变化后调用)\r\n */\r\n refreshAllCursors(): void {\r\n this.cursors.forEach((cursor) => this.renderCursor(cursor))\r\n }\r\n\r\n /**\r\n * 获取所有远程光标\r\n */\r\n getAllCursors(): RemoteCursor[] {\r\n return Array.from(this.cursors.values())\r\n }\r\n\r\n /**\r\n * 销毁\r\n */\r\n destroy(): void {\r\n if (this.awarenessHandler && this.awareness) {\r\n this.awareness.off('change', this.awarenessHandler)\r\n this.awarenessHandler = null\r\n }\r\n this.stopCleanupTimer()\r\n this.clearAllElements()\r\n this.removeStyles()\r\n this.container = null\r\n this.positionCalculator = null\r\n this.awareness = null\r\n }\r\n\r\n // ---- 内部渲染 ----\r\n\r\n private renderCursor(cursor: RemoteCursor): void {\r\n if (!this.container || !this.positionCalculator) return\r\n\r\n const position = this.positionCalculator(cursor.position.index)\r\n if (!position) {\r\n const el = this.elements.get(cursor.userId)\r\n if (el) el.container.style.display = 'none'\r\n return\r\n }\r\n\r\n let el = this.elements.get(cursor.userId)\r\n if (!el) {\r\n el = this.createCursorElement(cursor)\r\n this.elements.set(cursor.userId, el)\r\n }\r\n\r\n el.container.style.left = `${position.x}px`\r\n el.container.style.top = `${position.y}px`\r\n el.container.style.display = 'block'\r\n el.cursor.style.height = `${position.height}px`\r\n el.cursor.style.backgroundColor = cursor.color\r\n el.label.textContent = cursor.userName\r\n el.label.style.backgroundColor = cursor.color\r\n\r\n if (this.config.showLabel) this.showLabel(el)\r\n }\r\n\r\n private createCursorElement(cursor: RemoteCursor): CursorElement {\r\n const container = document.createElement('div')\r\n container.className = 'remote-cursor-container'\r\n container.dataset.userId = cursor.userId\r\n\r\n const cursorLine = document.createElement('div')\r\n cursorLine.className = 'remote-cursor-line'\r\n if (this.config.enableBlink) cursorLine.classList.add('remote-cursor-blink')\r\n\r\n const label = document.createElement('div')\r\n label.className = 'remote-cursor-label'\r\n label.textContent = cursor.userName\r\n\r\n container.appendChild(cursorLine)\r\n container.appendChild(label)\r\n this.container!.appendChild(container)\r\n\r\n return { container, cursor: cursorLine, label, labelTimer: null }\r\n }\r\n\r\n private showLabel(el: CursorElement): void {\r\n el.label.style.opacity = '1'\r\n if (el.labelTimer) {\r\n clearTimeout(el.labelTimer)\r\n el.labelTimer = null\r\n }\r\n if (this.config.labelDuration > 0) {\r\n el.labelTimer = setTimeout(() => {\r\n el.label.style.opacity = '0'\r\n el.labelTimer = null\r\n }, this.config.labelDuration)\r\n }\r\n }\r\n\r\n private clearAllElements(): void {\r\n this.elements.forEach((el) => {\r\n if (el.labelTimer) clearTimeout(el.labelTimer)\r\n el.container.remove()\r\n })\r\n this.elements.clear()\r\n this.cursors.clear()\r\n }\r\n\r\n /** 移除已经不在 awareness 中的客户端光标 */\r\n private cleanupRemovedClients(allStates: Map<number, Record<string, unknown>>): void {\r\n const activeUserIds = new Set<string>()\r\n allStates.forEach((state, clientId) => {\r\n if (clientId === this.awareness!.clientID) return\r\n const user = state.user as UserInfo | undefined\r\n if (user?.userId) activeUserIds.add(user.userId)\r\n })\r\n\r\n const toRemove: string[] = []\r\n this.cursors.forEach((_, userId) => {\r\n if (!activeUserIds.has(userId)) toRemove.push(userId)\r\n })\r\n for (const userId of toRemove) {\r\n this.removeCursor(userId)\r\n }\r\n }\r\n\r\n private removeCursor(userId: string): void {\r\n this.cursors.delete(userId)\r\n const el = this.elements.get(userId)\r\n if (el) {\r\n if (el.labelTimer) clearTimeout(el.labelTimer)\r\n el.container.remove()\r\n this.elements.delete(userId)\r\n }\r\n }\r\n\r\n // ---- 过期清理 ----\r\n\r\n private startCleanupTimer(): void {\r\n this.cleanupTimer = setInterval(() => {\r\n const now = Date.now()\r\n this.cursors.forEach((cursor, userId) => {\r\n if (now - cursor.lastUpdate > this.config.expireTime) {\r\n this.removeCursor(userId)\r\n }\r\n })\r\n }, 5000)\r\n }\r\n\r\n private stopCleanupTimer(): void {\r\n if (this.cleanupTimer) {\r\n clearInterval(this.cleanupTimer)\r\n this.cleanupTimer = null\r\n }\r\n }\r\n\r\n // ---- 样式注入 ----\r\n\r\n private injectStyles(): void {\r\n if (this.styleElement) return\r\n this.styleElement = document.createElement('style')\r\n this.styleElement.textContent = `\r\n .remote-cursor-container {\r\n position: absolute;\r\n pointer-events: none;\r\n z-index: 1000;\r\n }\r\n .remote-cursor-line {\r\n width: 2px;\r\n min-height: 16px;\r\n border-radius: 1px;\r\n }\r\n .remote-cursor-blink {\r\n animation: remote-cursor-blink 1s infinite;\r\n }\r\n @keyframes remote-cursor-blink {\r\n 0%, 50% { opacity: 1; }\r\n 51%, 100% { opacity: 0; }\r\n }\r\n .remote-cursor-label {\r\n position: absolute;\r\n top: -20px;\r\n left: 0;\r\n padding: 2px 6px;\r\n border-radius: 3px;\r\n color: white;\r\n font-size: 12px;\r\n white-space: nowrap;\r\n transition: opacity 0.3s ease;\r\n opacity: 0;\r\n }\r\n .remote-cursor-selection {\r\n position: absolute;\r\n opacity: 0.3;\r\n pointer-events: none;\r\n }\r\n `\r\n document.head.appendChild(this.styleElement)\r\n }\r\n\r\n private removeStyles(): void {\r\n if (this.styleElement) {\r\n this.styleElement.remove()\r\n this.styleElement = null\r\n }\r\n }\r\n}\r\n","'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n","/**\r\n * 协同编辑插件(Yjs + Hocuspocus 实现)\r\n *\r\n * 外部 API 与旧 OT 版本保持一致,内部替换为:\r\n * - HocuspocusProvider → WebSocket 连接 & 文档同步\r\n * - Y.Doc → 文档状态(CRDT 自动合并冲突)\r\n * - YjsBinding → Y.Doc ↔ EditorInterface 双向绑定\r\n * - AwarenessCursorManager → 远程光标同步\r\n */\r\nimport * as Y from 'yjs'\r\nimport { HocuspocusProvider } from '@hocuspocus/provider'\r\nimport type {\r\n CollaborationConfig,\r\n EditorInterface,\r\n UserInfo,\r\n RemoteCursor,\r\n CursorPosition,\r\n} from '../types'\r\nimport { ConnectionState, SyncState } from '../types'\r\nimport { YjsBinding } from '../binding/YjsBinding'\r\nimport {\r\n AwarenessCursorManager,\r\n type PositionCalculator,\r\n} from '../cursor/AwarenessCursorManager'\r\nimport EventEmitter from 'eventemitter3'\r\n\r\nfunction subscribeEventBus(\r\n eventBus: EditorInterface['eventBus'],\r\n event: string,\r\n handler: (...args: unknown[]) => void\r\n): { unsubscribe: () => void } {\r\n if (typeof (eventBus as any).select === 'function') {\r\n return (eventBus as any).select(event).subscribe(handler)\r\n }\r\n if (typeof (eventBus as any).on === 'function') {\r\n ;(eventBus as any).on(event, handler)\r\n return {\r\n unsubscribe: () => {\r\n if (typeof (eventBus as any).off === 'function') {\r\n ;(eventBus as any).off(event, handler)\r\n }\r\n }\r\n }\r\n }\r\n return { unsubscribe: () => {} }\r\n}\r\n\r\n/**\r\n * 插件配置\r\n */\r\nexport interface CollaborationPluginConfig {\r\n collaboration: CollaborationConfig\r\n enableRemoteCursors?: boolean\r\n cursorThrottleMs?: number\r\n}\r\n\r\n/**\r\n * 插件事件\r\n */\r\nexport interface PluginEvents {\r\n connectionChange: (state: ConnectionState) => void\r\n syncStateChange: (state: SyncState) => void\r\n userJoin: (user: UserInfo) => void\r\n userLeave: (userId: string) => void\r\n usersChange: (users: UserInfo[]) => void\r\n error: (error: { code: string; message: string }) => void\r\n}\r\n\r\n/**\r\n * 协同编辑插件\r\n */\r\nexport class CollaborationPlugin {\r\n private editor: EditorInterface | null = null\r\n private config: Required<Pick<CollaborationPluginConfig, 'enableRemoteCursors' | 'cursorThrottleMs'>> & CollaborationPluginConfig\r\n\r\n private doc: Y.Doc | null = null\r\n private provider: HocuspocusProvider | null = null\r\n private binding: YjsBinding | null = null\r\n private cursorManager: AwarenessCursorManager\r\n\r\n private connectionState: ConnectionState = ConnectionState.DISCONNECTED\r\n private syncState: SyncState = SyncState.SYNCING\r\n\r\n /** 光标节流 */\r\n private cursorThrottleTimer: ReturnType<typeof setTimeout> | null = null\r\n /** 编辑器事件引用 */\r\n private rangeChangeHandler: ((rangeStyle: unknown) => void) | null = null\r\n private rangeChangeSubscription: { unsubscribe: () => void } | null = null\r\n\r\n private eventEmitter = new EventEmitter<PluginEvents>()\r\n\r\n /** 已知在线用户(从 Awareness 维护) */\r\n private onlineUsers = new Map<string, UserInfo>()\r\n\r\n constructor(config: CollaborationPluginConfig) {\r\n this.config = {\r\n enableRemoteCursors: true,\r\n cursorThrottleMs: 100,\r\n ...config,\r\n }\r\n this.cursorManager = new AwarenessCursorManager()\r\n }\r\n\r\n // ==================== 公开 API ====================\r\n\r\n install(editor: EditorInterface): void {\r\n this.editor = editor\r\n }\r\n\r\n uninstall(): void {\r\n this.disconnect()\r\n this.rangeChangeSubscription?.unsubscribe()\r\n this.rangeChangeSubscription = null\r\n this.rangeChangeHandler = null\r\n this.cursorManager.destroy()\r\n this.editor = null\r\n }\r\n\r\n async connect(): Promise<void> {\r\n if (!this.editor) throw new Error('Plugin not installed')\r\n if (this.provider) return // 已连接\r\n\r\n const { collaboration } = this.config\r\n\r\n // 1. 创建 Y.Doc\r\n this.doc = new Y.Doc()\r\n\r\n // 2. 构造 token\r\n const token =\r\n collaboration.token ??\r\n JSON.stringify({\r\n userId: collaboration.user.userId,\r\n userName: collaboration.user.userName,\r\n color: collaboration.user.color,\r\n })\r\n\r\n // 3. 创建 HocuspocusProvider\r\n this.setConnectionState(ConnectionState.CONNECTING)\r\n\r\n this.provider = new HocuspocusProvider({\r\n url: collaboration.serverUrl,\r\n name: collaboration.docId,\r\n document: this.doc,\r\n token,\r\n // 连接事件\r\n onConnect: () => {\r\n this.setConnectionState(ConnectionState.CONNECTED)\r\n },\r\n onDisconnect: () => {\r\n this.setConnectionState(ConnectionState.DISCONNECTED)\r\n },\r\n onSynced: ({ state }) => {\r\n if (state) {\r\n this.setSyncState(SyncState.SYNCED)\r\n // 同步完成后再建立双向绑定,避免绑定期间的空文档问题\r\n if (!this.binding && this.editor && this.doc) {\r\n this.binding = new YjsBinding(this.doc, this.editor)\r\n }\r\n }\r\n },\r\n onAuthenticationFailed: ({ reason }) => {\r\n this.emitEvent('error', { code: 'AUTH_FAILED', message: reason })\r\n },\r\n })\r\n\r\n // 4. Awareness 光标\r\n if (this.config.enableRemoteCursors) {\r\n this.cursorManager.bindAwareness(this.provider.awareness!, collaboration.user)\r\n this.setupAwarenessUserTracking()\r\n }\r\n\r\n // 5. 监听编辑器光标变化\r\n this.setupCursorSync()\r\n }\r\n\r\n disconnect(): void {\r\n if (this.binding) {\r\n this.binding.destroy()\r\n this.binding = null\r\n }\r\n if (this.cursorThrottleTimer) {\r\n clearTimeout(this.cursorThrottleTimer)\r\n this.cursorThrottleTimer = null\r\n }\r\n if (this.provider) {\r\n this.provider.destroy()\r\n this.provider = null\r\n }\r\n if (this.doc) {\r\n this.doc.destroy()\r\n this.doc = null\r\n }\r\n this.onlineUsers.clear()\r\n this.setConnectionState(ConnectionState.DISCONNECTED)\r\n }\r\n\r\n getConnectionState(): ConnectionState {\r\n return this.connectionState\r\n }\r\n\r\n getSyncState(): SyncState {\r\n return this.syncState\r\n }\r\n\r\n getOnlineUsers(): UserInfo[] {\r\n return Array.from(this.onlineUsers.values())\r\n }\r\n\r\n getRemoteCursors(): RemoteCursor[] {\r\n return this.cursorManager.getAllCursors()\r\n }\r\n\r\n initializeCursors(container: HTMLElement, positionCalculator: PositionCalculator): void {\r\n if (this.config.enableRemoteCursors) {\r\n this.cursorManager.initializeCursorRendering(container, positionCalculator)\r\n }\r\n }\r\n\r\n private _positionListDirty = true\r\n private _cachedPositionList: any[] | null = null\r\n\r\n markPositionListDirty(): void {\r\n this._positionListDirty = true\r\n }\r\n\r\n initializeCursorsWithEditor(container: HTMLElement): void {\r\n if (!this.config.enableRemoteCursors || !this.editor) return\r\n const editor = this.editor\r\n const positionCalculator: PositionCalculator = (index: number) => {\r\n if (this._positionListDirty || !this._cachedPositionList) {\r\n this._cachedPositionList = (editor.command as any).getPositionList?.() || null\r\n this._positionListDirty = false\r\n }\r\n if (!this._cachedPositionList || index < 0 || index >= this._cachedPositionList.length) return null\r\n const pos = this._cachedPositionList[index]\r\n if (!pos?.coordinate) return null\r\n const pageNo = pos.pageNo ?? 0\r\n const canvases = container.querySelectorAll('canvas[data-index]')\r\n const canvas = canvases[pageNo] as HTMLElement\r\n if (!canvas) return null\r\n const canvasRect = canvas.getBoundingClientRect()\r\n const areaRect = container.getBoundingClientRect()\r\n const x = canvasRect.left - areaRect.left + container.scrollLeft + (pos.coordinate.leftTop?.[0] || 0)\r\n const y = canvasRect.top - areaRect.top + container.scrollTop + (pos.coordinate.leftTop?.[1] || 0)\r\n const height = pos.lineHeight || 16\r\n return { x, y, height }\r\n }\r\n this.cursorManager.initializeCursorRendering(container, positionCalculator)\r\n }\r\n\r\n refreshCursors(): void {\r\n this.cursorManager.refreshAllCursors()\r\n }\r\n\r\n on<K extends keyof PluginEvents>(event: K, callback: PluginEvents[K]): () => void {\r\n return this.addEventListener(event, callback)\r\n }\r\n\r\n addEventListener<K extends keyof PluginEvents>(event: K, callback: PluginEvents[K]): () => void {\r\n this.eventEmitter.on(event, callback as any)\r\n return () => {\r\n this.eventEmitter.off(event, callback as any)\r\n }\r\n }\r\n\r\n // ==================== 内部 ====================\r\n\r\n /** 监听 Awareness 变化维护在线用户列表 */\r\n private setupAwarenessUserTracking(): void {\r\n const awareness = this.provider!.awareness!\r\n const localUser = this.config.collaboration.user\r\n\r\n // 把自己加入在线用户列表\r\n this.onlineUsers.set(localUser.userId, localUser)\r\n this.emitEvent('usersChange', this.getOnlineUsers())\r\n\r\n const handler = ({ added, updated, removed }: { added: number[]; updated: number[]; removed: number[] }) => {\r\n let changed = false\r\n\r\n for (const clientId of [...added, ...updated]) {\r\n if (clientId === awareness.clientID) continue\r\n const state = awareness.getStates().get(clientId)\r\n const user = state?.user as UserInfo | undefined\r\n if (user?.userId && !this.onlineUsers.has(user.userId)) {\r\n this.onlineUsers.set(user.userId, user)\r\n this.emitEvent('userJoin', user)\r\n changed = true\r\n }\r\n }\r\n\r\n if (removed.length > 0) {\r\n // 重建在线用户列表(保留自己)\r\n const activeIds = new Set<string>()\r\n activeIds.add(localUser.userId)\r\n awareness.getStates().forEach((state, cid) => {\r\n if (cid === awareness.clientID) return\r\n const u = state.user as UserInfo | undefined\r\n if (u?.userId) activeIds.add(u.userId)\r\n })\r\n this.onlineUsers.forEach((_, uid) => {\r\n if (!activeIds.has(uid)) {\r\n this.onlineUsers.delete(uid)\r\n this.emitEvent('userLeave', uid)\r\n changed = true\r\n }\r\n })\r\n }\r\n\r\n if (changed) {\r\n this.emitEvent('usersChange', this.getOnlineUsers())\r\n }\r\n }\r\n awareness.on('change', handler)\r\n }\r\n\r\n /** 编辑器光标 → Awareness */\r\n private setupCursorSync(): void {\r\n if (!this.editor) return\r\n\r\n this.rangeChangeHandler = () => {\r\n if (this.cursorThrottleTimer) return\r\n this.cursorThrottleTimer = setTimeout(() => {\r\n this.cursorThrottleTimer = null\r\n const range = this.editor?.command.getRange()\r\n if (!range) return\r\n const pos: CursorPosition = {\r\n index: range.startIndex,\r\n endIndex: range.startIndex !== range.endIndex ? range.endIndex : undefined,\r\n }\r\n this.cursorManager.setLocalCursor(pos)\r\n }, this.config.cursorThrottleMs)\r\n }\r\n this.rangeChangeSubscription = subscribeEventBus(\r\n this.editor.eventBus,\r\n 'rangeStyleChange',\r\n this.rangeChangeHandler as any\r\n )\r\n }\r\n\r\n private setConnectionState(state: ConnectionState): void {\r\n if (this.connectionState === state) return\r\n this.connectionState = state\r\n this.emitEvent('connectionChange', state)\r\n }\r\n\r\n private setSyncState(state: SyncState): void {\r\n if (this.syncState === state) return\r\n this.syncState = state\r\n this.emitEvent('syncStateChange', state)\r\n }\r\n\r\n private emitEvent<K extends keyof PluginEvents>(event: K, ...args: Parameters<PluginEvents[K]>): void {\r\n const callbacks = this.eventEmitter.listeners(event) as Array<(...payload: unknown[]) => void>\r\n callbacks.forEach((callback) => {\r\n try {\r\n callback(...args as unknown[])\r\n } catch (err) {\r\n console.error(`[CollaborationPlugin] Error in ${String(event)} handler:`, err)\r\n }\r\n })\r\n }\r\n}\r\n"],"names":["ConnectionState","SyncState","__extends","extendStatics","d","b","p","__","_hasOwnProperty","hasOwnProperty","obj","key","_objectKeys","keys_1","k","keys","i","_deepClone","isInteger","str","len","charCode","escapePathComponent","path","unescapePathComponent","hasUndefined","i_1","objKeys","objKeysLength","patchErrorMessageFormatter","message","args","messageParts","value","PatchError","_super","name","index","operation","tree","_newTarget","_this","JsonPatchError","deepClone","objOps","document","removed","getValueByPointer","originalValue","applyOperation","valueToCopy","_areEquals","arrOps","arr","removedList","pointer","getOriginalDestination","validateOperation","mutateDocument","banPrototypeModifications","validator","returnValue","t","existingPathFragment","validateFunction","applyPatch","patch","results","length_1","applyReducer","operationResult","pathLen","existingPathLen","existingValue","error","validate","sequence","externalValidator","e","a","arrA","arrB","length","beforeDict","Mirror","ObserverInfo","callback","observer","getMirror","getObserverFromMirror","mirror","removeObserverFromMirror","unobserve","root","observe","patches","observerInfo","dirtyCheck","generate","fastCheck","invertible","_generate","temp","newKeys","oldKeys","deleted","oldVal","newVal","compare","tree1","tree2","core","duplex","NESTED_ARRAY_KEYS","subscribeEventBus","eventBus","event","handler","YjsBinding","doc","editor","__publicField","_a","_event","tx","elements","current","operations","yArray","rootValue","yMap","pathSegment","topIndex","Y","yArr","children","child","DEFAULT_CONFIG","AwarenessCursorManager","config","awareness","localUser","added","updated","changed","clientId","state","user","cursor","remoteCursor","allStates","position","container","positionCalculator","el","cursorLine","label","activeUserIds","toRemove","_","userId","now","has","prefix","Events","EE","fn","context","once","addListener","emitter","listener","evt","clearEvent","EventEmitter","names","events","handlers","l","ee","listeners","a1","a2","a3","a4","a5","j","module","CollaborationPlugin","collaboration","token","HocuspocusProvider","reason","_b","pos","pageNo","canvas","canvasRect","areaRect","x","_c","y","_d","height","activeIds","cid","u","uid","range","err"],"mappings":"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","x_google_ignoreList":[1,2,3,4,7]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
(function(w,E){typeof exports=="object"&&typeof module<"u"?E(exports,require("yjs"),require("@hocuspocus/provider")):typeof define=="function"&&define.amd?define(["exports","yjs","@hocuspocus/provider"],E):(w=typeof globalThis<"u"?globalThis:w||self,E(w.DocxEditorCollaboration={},w.Y,w.HocuspocusProvider))})(this,function(w,E,S){"use strict";var _e=Object.defineProperty;var Te=(w,E,S)=>E in w?_e(w,E,{enumerable:!0,configurable:!0,writable:!0,value:S}):w[E]=S;var d=(w,E,S)=>Te(w,typeof E!="symbol"?E+"":E,S);function V(t){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const r in t)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,n.get?n:{enumerable:!0,get:()=>t[r]})}}return e.default=t,Object.freeze(e)}const M=V(E);var C=(t=>(t.DISCONNECTED="disconnected",t.CONNECTING="connecting",t.CONNECTED="connected",t))(C||{}),R=(t=>(t.SYNCING="syncing",t.SYNCED="synced",t))(R||{});/*!
|
|
2
|
+
* https://github.com/Starcounter-Jack/JSON-Patch
|
|
3
|
+
* (c) 2017-2022 Joachim Wester
|
|
4
|
+
* MIT licensed
|
|
5
|
+
*/var k=function(){var t=function(e,r){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,s){n.__proto__=s}||function(n,s){for(var i in s)s.hasOwnProperty(i)&&(n[i]=s[i])},t(e,r)};return function(e,r){t(e,r);function n(){this.constructor=e}e.prototype=r===null?Object.create(r):(n.prototype=r.prototype,new n)}}(),ee=Object.prototype.hasOwnProperty;function U(t,e){return ee.call(t,e)}function Y(t){if(Array.isArray(t)){for(var e=new Array(t.length),r=0;r<e.length;r++)e[r]=""+r;return e}if(Object.keys)return Object.keys(t);var n=[];for(var s in t)U(t,s)&&n.push(s);return n}function _(t){switch(typeof t){case"object":return JSON.parse(JSON.stringify(t));case"undefined":return null;default:return t}}function H(t){for(var e=0,r=t.length,n;e<r;){if(n=t.charCodeAt(e),n>=48&&n<=57){e++;continue}return!1}return!0}function A(t){return t.indexOf("/")===-1&&t.indexOf("~")===-1?t:t.replace(/~/g,"~0").replace(/\//g,"~1")}function G(t){return t.replace(/~1/g,"/").replace(/~0/g,"~")}function j(t){if(t===void 0)return!0;if(t){if(Array.isArray(t)){for(var e=0,r=t.length;e<r;e++)if(j(t[e]))return!0}else if(typeof t=="object"){for(var n=Y(t),s=n.length,i=0;i<s;i++)if(j(t[n[i]]))return!0}}return!1}function $(t,e){var r=[t];for(var n in e){var s=typeof e[n]=="object"?JSON.stringify(e[n],null,2):e[n];typeof s<"u"&&r.push(n+": "+s)}return r.join(`
|
|
6
|
+
`)}var Q=function(t){k(e,t);function e(r,n,s,i,a){var c=this.constructor,u=t.call(this,$(r,{name:n,index:s,operation:i,tree:a}))||this;return u.name=n,u.index=s,u.operation=i,u.tree=a,Object.setPrototypeOf(u,c.prototype),u.message=$(r,{name:n,index:s,operation:i,tree:a}),u}return e}(Error),g=Q,te=_,I={add:function(t,e,r){return t[e]=this.value,{newDocument:r}},remove:function(t,e,r){var n=t[e];return delete t[e],{newDocument:r,removed:n}},replace:function(t,e,r){var n=t[e];return t[e]=this.value,{newDocument:r,removed:n}},move:function(t,e,r){var n=P(r,this.path);n&&(n=_(n));var s=b(r,{op:"remove",path:this.from}).removed;return b(r,{op:"add",path:this.path,value:s}),{newDocument:r,removed:n}},copy:function(t,e,r){var n=P(r,this.from);return b(r,{op:"add",path:this.path,value:_(n)}),{newDocument:r}},test:function(t,e,r){return{newDocument:r,test:L(t[e],this.value)}},_get:function(t,e,r){return this.value=t[e],{newDocument:r}}},re={add:function(t,e,r){return H(e)?t.splice(e,0,this.value):t[e]=this.value,{newDocument:r,index:e}},remove:function(t,e,r){var n=t.splice(e,1);return{newDocument:r,removed:n[0]}},replace:function(t,e,r){var n=t[e];return t[e]=this.value,{newDocument:r,removed:n}},move:I.move,copy:I.copy,test:I.test,_get:I._get};function P(t,e){if(e=="")return t;var r={op:"_get",path:e};return b(t,r),r.value}function b(t,e,r,n,s,i){if(r===void 0&&(r=!1),n===void 0&&(n=!0),s===void 0&&(s=!0),i===void 0&&(i=0),r&&(typeof r=="function"?r(e,0,t,e.path):x(e,0)),e.path===""){var a={newDocument:t};if(e.op==="add")return a.newDocument=e.value,a;if(e.op==="replace")return a.newDocument=e.value,a.removed=t,a;if(e.op==="move"||e.op==="copy")return a.newDocument=P(t,e.from),e.op==="move"&&(a.removed=t),a;if(e.op==="test"){if(a.test=L(t,e.value),a.test===!1)throw new g("Test operation failed","TEST_OPERATION_FAILED",i,e,t);return a.newDocument=t,a}else{if(e.op==="remove")return a.removed=t,a.newDocument=null,a;if(e.op==="_get")return e.value=t,a;if(r)throw new g("Operation `op` property is not one of operations defined in RFC-6902","OPERATION_OP_INVALID",i,e,t);return a}}else{n||(t=_(t));var c=e.path||"",u=c.split("/"),o=t,l=1,f=u.length,y=void 0,p=void 0,v=void 0;for(typeof r=="function"?v=r:v=x;;){if(p=u[l],p&&p.indexOf("~")!=-1&&(p=G(p)),s&&(p=="__proto__"||p=="prototype"&&l>0&&u[l-1]=="constructor"))throw new TypeError("JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README");if(r&&y===void 0&&(o[p]===void 0?y=u.slice(0,l).join("/"):l==f-1&&(y=e.path),y!==void 0&&v(e,0,t,y)),l++,Array.isArray(o)){if(p==="-")p=o.length;else{if(r&&!H(p))throw new g("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index","OPERATION_PATH_ILLEGAL_ARRAY_INDEX",i,e,t);H(p)&&(p=~~p)}if(l>=f){if(r&&e.op==="add"&&p>o.length)throw new g("The specified index MUST NOT be greater than the number of elements in the array","OPERATION_VALUE_OUT_OF_BOUNDS",i,e,t);var a=re[e.op].call(e,o,p,t);if(a.test===!1)throw new g("Test operation failed","TEST_OPERATION_FAILED",i,e,t);return a}}else if(l>=f){var a=I[e.op].call(e,o,p,t);if(a.test===!1)throw new g("Test operation failed","TEST_OPERATION_FAILED",i,e,t);return a}if(o=o[p],r&&l<f&&(!o||typeof o!="object"))throw new g("Cannot perform operation at the desired path","OPERATION_PATH_UNRESOLVABLE",i,e,t)}}}function F(t,e,r,n,s){if(n===void 0&&(n=!0),s===void 0&&(s=!0),r&&!Array.isArray(e))throw new g("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");n||(t=_(t));for(var i=new Array(e.length),a=0,c=e.length;a<c;a++)i[a]=b(t,e[a],r,!0,s,a),t=i[a].newDocument;return i.newDocument=t,i}function ne(t,e,r){var n=b(t,e);if(n.test===!1)throw new g("Test operation failed","TEST_OPERATION_FAILED",r,e,t);return n.newDocument}function x(t,e,r,n){if(typeof t!="object"||t===null||Array.isArray(t))throw new g("Operation is not an object","OPERATION_NOT_AN_OBJECT",e,t,r);if(I[t.op]){if(typeof t.path!="string")throw new g("Operation `path` property is not a string","OPERATION_PATH_INVALID",e,t,r);if(t.path.indexOf("/")!==0&&t.path.length>0)throw new g('Operation `path` property must start with "/"',"OPERATION_PATH_INVALID",e,t,r);if((t.op==="move"||t.op==="copy")&&typeof t.from!="string")throw new g("Operation `from` property is not present (applicable in `move` and `copy` operations)","OPERATION_FROM_REQUIRED",e,t,r);if((t.op==="add"||t.op==="replace"||t.op==="test")&&t.value===void 0)throw new g("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_REQUIRED",e,t,r);if((t.op==="add"||t.op==="replace"||t.op==="test")&&j(t.value))throw new g("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED",e,t,r);if(r){if(t.op=="add"){var s=t.path.split("/").length,i=n.split("/").length;if(s!==i+1&&s!==i)throw new g("Cannot perform an `add` operation at the desired path","OPERATION_PATH_CANNOT_ADD",e,t,r)}else if(t.op==="replace"||t.op==="remove"||t.op==="_get"){if(t.path!==n)throw new g("Cannot perform the operation at a path that does not exist","OPERATION_PATH_UNRESOLVABLE",e,t,r)}else if(t.op==="move"||t.op==="copy"){var a={op:"_get",path:t.from,value:void 0},c=q([a],r);if(c&&c.name==="OPERATION_PATH_UNRESOLVABLE")throw new g("Cannot perform the operation from a path that does not exist","OPERATION_FROM_UNRESOLVABLE",e,t,r)}}}else throw new g("Operation `op` property is not one of operations defined in RFC-6902","OPERATION_OP_INVALID",e,t,r)}function q(t,e,r){try{if(!Array.isArray(t))throw new g("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");if(e)F(_(e),_(t),r||!0);else{r=r||x;for(var n=0;n<t.length;n++)r(t[n],n,e,void 0)}}catch(s){if(s instanceof g)return s;throw s}}function L(t,e){if(t===e)return!0;if(t&&e&&typeof t=="object"&&typeof e=="object"){var r=Array.isArray(t),n=Array.isArray(e),s,i,a;if(r&&n){if(i=t.length,i!=e.length)return!1;for(s=i;s--!==0;)if(!L(t[s],e[s]))return!1;return!0}if(r!=n)return!1;var c=Object.keys(t);if(i=c.length,i!==Object.keys(e).length)return!1;for(s=i;s--!==0;)if(!e.hasOwnProperty(c[s]))return!1;for(s=i;s--!==0;)if(a=c[s],!L(t[a],e[a]))return!1;return!0}return t!==t&&e!==e}const se=Object.freeze(Object.defineProperty({__proto__:null,JsonPatchError:g,_areEquals:L,applyOperation:b,applyPatch:F,applyReducer:ne,deepClone:te,getValueByPointer:P,validate:q,validator:x},Symbol.toStringTag,{value:"Module"}));/*!
|
|
7
|
+
* https://github.com/Starcounter-Jack/JSON-Patch
|
|
8
|
+
* (c) 2017-2021 Joachim Wester
|
|
9
|
+
* MIT license
|
|
10
|
+
*/var J=new WeakMap,ie=function(){function t(e){this.observers=new Map,this.obj=e}return t}(),oe=function(){function t(e,r){this.callback=e,this.observer=r}return t}();function le(t){return J.get(t)}function ae(t,e){return t.observers.get(e)}function ue(t,e){t.observers.delete(e.callback)}function ce(t,e){e.unobserve()}function fe(t,e){var r=[],n,s=le(t);if(!s)s=new ie(t),J.set(t,s);else{var i=ae(s,e);n=i&&i.observer}if(n)return n;if(n={},s.value=_(t),e){n.callback=e,n.next=null;var a=function(){z(n)},c=function(){clearTimeout(n.next),n.next=setTimeout(a)};typeof window<"u"&&(window.addEventListener("mouseup",c),window.addEventListener("keyup",c),window.addEventListener("mousedown",c),window.addEventListener("keydown",c),window.addEventListener("change",c))}return n.patches=r,n.object=t,n.unobserve=function(){z(n),clearTimeout(n.next),ue(s,n),typeof window<"u"&&(window.removeEventListener("mouseup",c),window.removeEventListener("keyup",c),window.removeEventListener("mousedown",c),window.removeEventListener("keydown",c),window.removeEventListener("change",c))},s.observers.set(e,new oe(e,n)),n}function z(t,e){e===void 0&&(e=!1);var r=J.get(t.object);B(r.value,t.object,t.patches,"",e),t.patches.length&&F(r.value,t.patches);var n=t.patches;return n.length>0&&(t.patches=[],t.callback&&t.callback(n)),n}function B(t,e,r,n,s){if(e!==t){typeof e.toJSON=="function"&&(e=e.toJSON());for(var i=Y(e),a=Y(t),c=!1,u=a.length-1;u>=0;u--){var o=a[u],l=t[o];if(U(e,o)&&!(e[o]===void 0&&l!==void 0&&Array.isArray(e)===!1)){var f=e[o];typeof l=="object"&&l!=null&&typeof f=="object"&&f!=null&&Array.isArray(l)===Array.isArray(f)?B(l,f,r,n+"/"+A(o),s):l!==f&&(s&&r.push({op:"test",path:n+"/"+A(o),value:_(l)}),r.push({op:"replace",path:n+"/"+A(o),value:_(f)}))}else Array.isArray(t)===Array.isArray(e)?(s&&r.push({op:"test",path:n+"/"+A(o),value:_(l)}),r.push({op:"remove",path:n+"/"+A(o)}),c=!0):(s&&r.push({op:"test",path:n,value:t}),r.push({op:"replace",path:n,value:e}))}if(!(!c&&i.length==a.length))for(var u=0;u<i.length;u++){var o=i[u];!U(t,o)&&e[o]!==void 0&&r.push({op:"add",path:n+"/"+A(o),value:_(e[o])})}}}function K(t,e,r){r===void 0&&(r=!1);var n=[];return B(t,e,n,"",r),n}Object.assign({},se,Object.freeze(Object.defineProperty({__proto__:null,compare:K,generate:z,observe:fe,unobserve:ce},Symbol.toStringTag,{value:"Module"})),{JsonPatchError:Q,deepClone:_,escapePathComponent:A,unescapePathComponent:G});const he=new Set(["valueList","trList","tdList","colgroup"]);function pe(t,e,r){return typeof t.select=="function"?t.select(e).subscribe(r):typeof t.on=="function"?(t.on(e,r),{unsubscribe:()=>{typeof t.off=="function"&&t.off(e,r)}}):{unsubscribe:()=>{}}}class W{constructor(e,r){d(this,"doc");d(this,"editor");d(this,"yElements");d(this,"isApplyingRemote",!1);d(this,"isApplyingLocal",!1);d(this,"lastSnapshot",[]);d(this,"contentChangeHandler",null);d(this,"contentChangeSubscription",null);d(this,"yObserver",null);this.doc=e,this.editor=r,this.yElements=e.getArray("elements"),this.bindYjsToEditor(),this.bindEditorToYjs(),this.yElements.length>0&&this.pushYDocToEditor()}destroy(){var e;this.yObserver&&(this.yElements.unobserve(this.yObserver),this.yObserver=null),(e=this.contentChangeSubscription)==null||e.unsubscribe(),this.contentChangeSubscription=null,this.contentChangeHandler=null}bindYjsToEditor(){this.yObserver=(e,r)=>{this.isApplyingLocal||r.local||this.pushYDocToEditor()},this.yElements.observeDeep(this.yObserver)}pushYDocToEditor(){this.isApplyingRemote=!0;try{const e=this.yElements.toJSON();this.editor.command.executeSetValue({main:e},{isSetCursor:!1}),this.lastSnapshot=e}finally{this.isApplyingRemote=!1}}bindEditorToYjs(){this.contentChangeHandler=()=>{this.isApplyingRemote||this.pushEditorToYDoc()},this.contentChangeSubscription=pe(this.editor.eventBus,"contentChange",this.contentChangeHandler)}pushEditorToYDoc(){const r=this.editor.command.getValue().data.main??[],n=K(this.lastSnapshot,r);if(n.length){this.isApplyingLocal=!0;try{this.doc.transact(()=>{this.applyPatchToYArray(this.yElements,n,r)},this),this.lastSnapshot=this.cloneSnapshot(r)}finally{this.isApplyingLocal=!1}}}applyPatchToYArray(e,r,n){for(const s of r){const i=this.getTopLevelIndex(s.path);if(i!==null){if(s.op==="remove"){i<e.length&&e.delete(i,1);continue}if(s.op==="add"||s.op==="replace"){const a=this.getRootValueFromOperation(s,n);if(!a||Array.isArray(a))continue;const c=this.jsonToYMap(a);s.op==="add"?e.insert(i,[c]):(i<e.length&&e.delete(i,1),e.insert(i,[c]))}}}}getTopLevelIndex(e){const r=e.split("/")[1];if(!r)return null;const n=Number(r);return Number.isInteger(n)?n:null}getRootValueFromOperation(e,r){if(e.path.split("/").length<=2){const s=e.value;if(s&&typeof s=="object"&&!Array.isArray(s))return s}const n=this.getTopLevelIndex(e.path);return n!==null&&r[n]&&typeof r[n]=="object"?r[n]:null}cloneSnapshot(e){return JSON.parse(JSON.stringify(e))}jsonToYMap(e){const r=new M.Map;for(const[n,s]of Object.entries(e))if(s!=null)if(he.has(n)&&Array.isArray(s)){const i=new M.Array,a=s.map(c=>this.jsonToYMap(c));i.insert(0,a),r.set(n,i)}else r.set(n,s);return r}}const de={showLabel:!0,labelDuration:3e3,enableBlink:!0,expireTime:3e4};class X{constructor(e={}){d(this,"awareness",null);d(this,"container",null);d(this,"config");d(this,"positionCalculator",null);d(this,"cursors",new Map);d(this,"elements",new Map);d(this,"styleElement",null);d(this,"cleanupTimer",null);d(this,"awarenessHandler",null);this.config={...de,...e}}bindAwareness(e,r){this.awareness=e,e.setLocalStateField("user",{userId:r.userId,userName:r.userName,color:r.color}),this.awarenessHandler=({added:n,updated:s,removed:i})=>{const a=[...n,...s];for(const c of a){if(c===this.awareness.clientID)continue;const u=this.awareness.getStates().get(c);if(!(u!=null&&u.user)||!(u!=null&&u.cursor))continue;const o=u.user,l=u.cursor,f={userId:o.userId,userName:o.userName,color:o.color,position:l,lastUpdate:Date.now()};this.cursors.set(o.userId,f),this.renderCursor(f)}if(i.length>0){const c=this.awareness.getStates();this.cleanupRemovedClients(c)}},e.on("change",this.awarenessHandler)}setLocalCursor(e){var r;(r=this.awareness)==null||r.setLocalStateField("cursor",e)}initializeCursorRendering(e,r){this.container=e,this.positionCalculator=r,this.injectStyles(),this.startCleanupTimer()}refreshAllCursors(){this.cursors.forEach(e=>this.renderCursor(e))}getAllCursors(){return Array.from(this.cursors.values())}destroy(){this.awarenessHandler&&this.awareness&&(this.awareness.off("change",this.awarenessHandler),this.awarenessHandler=null),this.stopCleanupTimer(),this.clearAllElements(),this.removeStyles(),this.container=null,this.positionCalculator=null,this.awareness=null}renderCursor(e){if(!this.container||!this.positionCalculator)return;const r=this.positionCalculator(e.position.index);if(!r){const s=this.elements.get(e.userId);s&&(s.container.style.display="none");return}let n=this.elements.get(e.userId);n||(n=this.createCursorElement(e),this.elements.set(e.userId,n)),n.container.style.left=`${r.x}px`,n.container.style.top=`${r.y}px`,n.container.style.display="block",n.cursor.style.height=`${r.height}px`,n.cursor.style.backgroundColor=e.color,n.label.textContent=e.userName,n.label.style.backgroundColor=e.color,this.config.showLabel&&this.showLabel(n)}createCursorElement(e){const r=document.createElement("div");r.className="remote-cursor-container",r.dataset.userId=e.userId;const n=document.createElement("div");n.className="remote-cursor-line",this.config.enableBlink&&n.classList.add("remote-cursor-blink");const s=document.createElement("div");return s.className="remote-cursor-label",s.textContent=e.userName,r.appendChild(n),r.appendChild(s),this.container.appendChild(r),{container:r,cursor:n,label:s,labelTimer:null}}showLabel(e){e.label.style.opacity="1",e.labelTimer&&(clearTimeout(e.labelTimer),e.labelTimer=null),this.config.labelDuration>0&&(e.labelTimer=setTimeout(()=>{e.label.style.opacity="0",e.labelTimer=null},this.config.labelDuration))}clearAllElements(){this.elements.forEach(e=>{e.labelTimer&&clearTimeout(e.labelTimer),e.container.remove()}),this.elements.clear(),this.cursors.clear()}cleanupRemovedClients(e){const r=new Set;e.forEach((s,i)=>{if(i===this.awareness.clientID)return;const a=s.user;a!=null&&a.userId&&r.add(a.userId)});const n=[];this.cursors.forEach((s,i)=>{r.has(i)||n.push(i)});for(const s of n)this.removeCursor(s)}removeCursor(e){this.cursors.delete(e);const r=this.elements.get(e);r&&(r.labelTimer&&clearTimeout(r.labelTimer),r.container.remove(),this.elements.delete(e))}startCleanupTimer(){this.cleanupTimer=setInterval(()=>{const e=Date.now();this.cursors.forEach((r,n)=>{e-r.lastUpdate>this.config.expireTime&&this.removeCursor(n)})},5e3)}stopCleanupTimer(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null)}injectStyles(){this.styleElement||(this.styleElement=document.createElement("style"),this.styleElement.textContent=`
|
|
11
|
+
.remote-cursor-container {
|
|
12
|
+
position: absolute;
|
|
13
|
+
pointer-events: none;
|
|
14
|
+
z-index: 1000;
|
|
15
|
+
}
|
|
16
|
+
.remote-cursor-line {
|
|
17
|
+
width: 2px;
|
|
18
|
+
min-height: 16px;
|
|
19
|
+
border-radius: 1px;
|
|
20
|
+
}
|
|
21
|
+
.remote-cursor-blink {
|
|
22
|
+
animation: remote-cursor-blink 1s infinite;
|
|
23
|
+
}
|
|
24
|
+
@keyframes remote-cursor-blink {
|
|
25
|
+
0%, 50% { opacity: 1; }
|
|
26
|
+
51%, 100% { opacity: 0; }
|
|
27
|
+
}
|
|
28
|
+
.remote-cursor-label {
|
|
29
|
+
position: absolute;
|
|
30
|
+
top: -20px;
|
|
31
|
+
left: 0;
|
|
32
|
+
padding: 2px 6px;
|
|
33
|
+
border-radius: 3px;
|
|
34
|
+
color: white;
|
|
35
|
+
font-size: 12px;
|
|
36
|
+
white-space: nowrap;
|
|
37
|
+
transition: opacity 0.3s ease;
|
|
38
|
+
opacity: 0;
|
|
39
|
+
}
|
|
40
|
+
.remote-cursor-selection {
|
|
41
|
+
position: absolute;
|
|
42
|
+
opacity: 0.3;
|
|
43
|
+
pointer-events: none;
|
|
44
|
+
}
|
|
45
|
+
`,document.head.appendChild(this.styleElement))}removeStyles(){this.styleElement&&(this.styleElement.remove(),this.styleElement=null)}}function ve(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var Z={exports:{}};(function(t){var e=Object.prototype.hasOwnProperty,r="~";function n(){}Object.create&&(n.prototype=Object.create(null),new n().__proto__||(r=!1));function s(u,o,l){this.fn=u,this.context=o,this.once=l||!1}function i(u,o,l,f,y){if(typeof l!="function")throw new TypeError("The listener must be a function");var p=new s(l,f||u,y),v=r?r+o:o;return u._events[v]?u._events[v].fn?u._events[v]=[u._events[v],p]:u._events[v].push(p):(u._events[v]=p,u._eventsCount++),u}function a(u,o){--u._eventsCount===0?u._events=new n:delete u._events[o]}function c(){this._events=new n,this._eventsCount=0}c.prototype.eventNames=function(){var o=[],l,f;if(this._eventsCount===0)return o;for(f in l=this._events)e.call(l,f)&&o.push(r?f.slice(1):f);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(l)):o},c.prototype.listeners=function(o){var l=r?r+o:o,f=this._events[l];if(!f)return[];if(f.fn)return[f.fn];for(var y=0,p=f.length,v=new Array(p);y<p;y++)v[y]=f[y].fn;return v},c.prototype.listenerCount=function(o){var l=r?r+o:o,f=this._events[l];return f?f.fn?1:f.length:0},c.prototype.emit=function(o,l,f,y,p,v){var T=r?r+o:o;if(!this._events[T])return!1;var h=this._events[T],O=arguments.length,N,m;if(h.fn){switch(h.once&&this.removeListener(o,h.fn,void 0,!0),O){case 1:return h.fn.call(h.context),!0;case 2:return h.fn.call(h.context,l),!0;case 3:return h.fn.call(h.context,l,f),!0;case 4:return h.fn.call(h.context,l,f,y),!0;case 5:return h.fn.call(h.context,l,f,y,p),!0;case 6:return h.fn.call(h.context,l,f,y,p,v),!0}for(m=1,N=new Array(O-1);m<O;m++)N[m-1]=arguments[m];h.fn.apply(h.context,N)}else{var Ee=h.length,D;for(m=0;m<Ee;m++)switch(h[m].once&&this.removeListener(o,h[m].fn,void 0,!0),O){case 1:h[m].fn.call(h[m].context);break;case 2:h[m].fn.call(h[m].context,l);break;case 3:h[m].fn.call(h[m].context,l,f);break;case 4:h[m].fn.call(h[m].context,l,f,y);break;default:if(!N)for(D=1,N=new Array(O-1);D<O;D++)N[D-1]=arguments[D];h[m].fn.apply(h[m].context,N)}}return!0},c.prototype.on=function(o,l,f){return i(this,o,l,f,!1)},c.prototype.once=function(o,l,f){return i(this,o,l,f,!0)},c.prototype.removeListener=function(o,l,f,y){var p=r?r+o:o;if(!this._events[p])return this;if(!l)return a(this,p),this;var v=this._events[p];if(v.fn)v.fn===l&&(!y||v.once)&&(!f||v.context===f)&&a(this,p);else{for(var T=0,h=[],O=v.length;T<O;T++)(v[T].fn!==l||y&&!v[T].once||f&&v[T].context!==f)&&h.push(v[T]);h.length?this._events[p]=h.length===1?h[0]:h:a(this,p)}return this},c.prototype.removeAllListeners=function(o){var l;return o?(l=r?r+o:o,this._events[l]&&a(this,l)):(this._events=new n,this._eventsCount=0),this},c.prototype.off=c.prototype.removeListener,c.prototype.addListener=c.prototype.on,c.prefixed=r,c.EventEmitter=c,t.exports=c})(Z);var ge=Z.exports;const ye=ve(ge);function me(t,e,r){return typeof t.select=="function"?t.select(e).subscribe(r):typeof t.on=="function"?(t.on(e,r),{unsubscribe:()=>{typeof t.off=="function"&&t.off(e,r)}}):{unsubscribe:()=>{}}}class we{constructor(e){d(this,"editor",null);d(this,"config");d(this,"doc",null);d(this,"provider",null);d(this,"binding",null);d(this,"cursorManager");d(this,"connectionState",C.DISCONNECTED);d(this,"syncState",R.SYNCING);d(this,"cursorThrottleTimer",null);d(this,"rangeChangeHandler",null);d(this,"rangeChangeSubscription",null);d(this,"eventEmitter",new ye);d(this,"onlineUsers",new Map);d(this,"_positionListDirty",!0);d(this,"_cachedPositionList",null);this.config={enableRemoteCursors:!0,cursorThrottleMs:100,...e},this.cursorManager=new X}install(e){this.editor=e}uninstall(){var e;this.disconnect(),(e=this.rangeChangeSubscription)==null||e.unsubscribe(),this.rangeChangeSubscription=null,this.rangeChangeHandler=null,this.cursorManager.destroy(),this.editor=null}async connect(){if(!this.editor)throw new Error("Plugin not installed");if(this.provider)return;const{collaboration:e}=this.config;this.doc=new M.Doc;const r=e.token??JSON.stringify({userId:e.user.userId,userName:e.user.userName,color:e.user.color});this.setConnectionState(C.CONNECTING),this.provider=new S.HocuspocusProvider({url:e.serverUrl,name:e.docId,document:this.doc,token:r,onConnect:()=>{this.setConnectionState(C.CONNECTED)},onDisconnect:()=>{this.setConnectionState(C.DISCONNECTED)},onSynced:({state:n})=>{n&&(this.setSyncState(R.SYNCED),!this.binding&&this.editor&&this.doc&&(this.binding=new W(this.doc,this.editor)))},onAuthenticationFailed:({reason:n})=>{this.emitEvent("error",{code:"AUTH_FAILED",message:n})}}),this.config.enableRemoteCursors&&(this.cursorManager.bindAwareness(this.provider.awareness,e.user),this.setupAwarenessUserTracking()),this.setupCursorSync()}disconnect(){this.binding&&(this.binding.destroy(),this.binding=null),this.cursorThrottleTimer&&(clearTimeout(this.cursorThrottleTimer),this.cursorThrottleTimer=null),this.provider&&(this.provider.destroy(),this.provider=null),this.doc&&(this.doc.destroy(),this.doc=null),this.onlineUsers.clear(),this.setConnectionState(C.DISCONNECTED)}getConnectionState(){return this.connectionState}getSyncState(){return this.syncState}getOnlineUsers(){return Array.from(this.onlineUsers.values())}getRemoteCursors(){return this.cursorManager.getAllCursors()}initializeCursors(e,r){this.config.enableRemoteCursors&&this.cursorManager.initializeCursorRendering(e,r)}markPositionListDirty(){this._positionListDirty=!0}initializeCursorsWithEditor(e){if(!this.config.enableRemoteCursors||!this.editor)return;const r=this.editor,n=s=>{var v,T,h,O;if((this._positionListDirty||!this._cachedPositionList)&&(this._cachedPositionList=((T=(v=r.command).getPositionList)==null?void 0:T.call(v))||null,this._positionListDirty=!1),!this._cachedPositionList||s<0||s>=this._cachedPositionList.length)return null;const i=this._cachedPositionList[s];if(!(i!=null&&i.coordinate))return null;const a=i.pageNo??0,u=e.querySelectorAll("canvas[data-index]")[a];if(!u)return null;const o=u.getBoundingClientRect(),l=e.getBoundingClientRect(),f=o.left-l.left+e.scrollLeft+(((h=i.coordinate.leftTop)==null?void 0:h[0])||0),y=o.top-l.top+e.scrollTop+(((O=i.coordinate.leftTop)==null?void 0:O[1])||0),p=i.lineHeight||16;return{x:f,y,height:p}};this.cursorManager.initializeCursorRendering(e,n)}refreshCursors(){this.cursorManager.refreshAllCursors()}on(e,r){return this.addEventListener(e,r)}addEventListener(e,r){return this.eventEmitter.on(e,r),()=>{this.eventEmitter.off(e,r)}}setupAwarenessUserTracking(){const e=this.provider.awareness,r=this.config.collaboration.user;this.onlineUsers.set(r.userId,r),this.emitEvent("usersChange",this.getOnlineUsers());const n=({added:s,updated:i,removed:a})=>{let c=!1;for(const u of[...s,...i]){if(u===e.clientID)continue;const o=e.getStates().get(u),l=o==null?void 0:o.user;l!=null&&l.userId&&!this.onlineUsers.has(l.userId)&&(this.onlineUsers.set(l.userId,l),this.emitEvent("userJoin",l),c=!0)}if(a.length>0){const u=new Set;u.add(r.userId),e.getStates().forEach((o,l)=>{if(l===e.clientID)return;const f=o.user;f!=null&&f.userId&&u.add(f.userId)}),this.onlineUsers.forEach((o,l)=>{u.has(l)||(this.onlineUsers.delete(l),this.emitEvent("userLeave",l),c=!0)})}c&&this.emitEvent("usersChange",this.getOnlineUsers())};e.on("change",n)}setupCursorSync(){this.editor&&(this.rangeChangeHandler=()=>{this.cursorThrottleTimer||(this.cursorThrottleTimer=setTimeout(()=>{var n;this.cursorThrottleTimer=null;const e=(n=this.editor)==null?void 0:n.command.getRange();if(!e)return;const r={index:e.startIndex,endIndex:e.startIndex!==e.endIndex?e.endIndex:void 0};this.cursorManager.setLocalCursor(r)},this.config.cursorThrottleMs))},this.rangeChangeSubscription=me(this.editor.eventBus,"rangeStyleChange",this.rangeChangeHandler))}setConnectionState(e){this.connectionState!==e&&(this.connectionState=e,this.emitEvent("connectionChange",e))}setSyncState(e){this.syncState!==e&&(this.syncState=e,this.emitEvent("syncStateChange",e))}emitEvent(e,...r){this.eventEmitter.listeners(e).forEach(s=>{try{s(...r)}catch(i){console.error(`[CollaborationPlugin] Error in ${String(e)} handler:`,i)}})}}w.AwarenessCursorManager=X,w.CollaborationPlugin=we,w.ConnectionState=C,w.SyncState=R,w.YjsBinding=W,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})});
|
|
46
|
+
//# sourceMappingURL=docx-editor-collaboration.umd.cjs.map
|