UNPKG

@textbus/collaborate

Version:

Textbus is a rich text editor and framework that is highly customizable and extensible to achieve rich wysiwyg effects.

1,050 lines (1,046 loc) 125 kB
'use strict'; Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const core$1 = require('@viewfly/core'); const core = require('@textbus/core'); const stream = require('@tanbo/stream'); const yjs = require('yjs'); const provider = require('@hocuspocus/provider'); const yWebsocket = require('y-websocket'); function _assert_this_initialized$3(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _call_super$3(_this, derived, args) { derived = _get_prototype_of$3(derived); return _possible_constructor_return$3(_this, _is_native_reflect_construct$3() ? Reflect.construct(derived, args || [], _get_prototype_of$3(_this).constructor) : derived.apply(_this, args)); } function _class_call_check$a(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties$9(target, props) { for(var i = 0; i < props.length; i++){ var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _create_class$9(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties$9(Constructor.prototype, protoProps); return Constructor; } function _get_prototype_of$3(o) { _get_prototype_of$3 = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _get_prototype_of$3(o); } function _inherits$3(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _set_prototype_of$3(subClass, superClass); } function _possible_constructor_return$3(self, call) { if (call && (_type_of$4(call) === "object" || typeof call === "function")) { return call; } return _assert_this_initialized$3(self); } function _set_prototype_of$3(o, p) { _set_prototype_of$3 = Object.setPrototypeOf || function setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _set_prototype_of$3(o, p); } function _type_of$4(obj) { "@swc/helpers - typeof"; return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; } function _is_native_reflect_construct$3() { try { var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {})); } catch (_) {} return (_is_native_reflect_construct$3 = function() { return !!result; })(); } function _ts_decorate$3(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } var subModelLoaderErrorFn = core.makeError('subModelLoaderError'); /** * 子文档加载器 */ var SubModelLoader = function SubModelLoader() { _class_call_check$a(this, SubModelLoader); }; exports.NonSubModelLoader = /*#__PURE__*/ function(SubModelLoader) { _inherits$3(NonSubModelLoader, SubModelLoader); function NonSubModelLoader() { _class_call_check$a(this, NonSubModelLoader); return _call_super$3(this, NonSubModelLoader, arguments); } _create_class$9(NonSubModelLoader, [ { key: "createSubModelBySlot", value: function createSubModelBySlot() { throw subModelLoaderErrorFn('single document does not support async slot.'); } }, { key: "createSubModelByComponent", value: function createSubModelByComponent() { throw subModelLoaderErrorFn('single document does not support async component.'); } }, { key: "loadSubModelByComponent", value: function loadSubModelByComponent() { throw subModelLoaderErrorFn('single document does not support async component.'); } }, { key: "loadSubModelBySlot", value: function loadSubModelBySlot() { throw subModelLoaderErrorFn('single document does not support async slot.'); } }, { key: "getLoadedModelBySlot", value: function getLoadedModelBySlot() { throw subModelLoaderErrorFn('single document does not support async slot.'); } }, { key: "getLoadedModelByComponent", value: function getLoadedModelByComponent() { throw subModelLoaderErrorFn('single document does not support async component.'); } } ]); return NonSubModelLoader; }(SubModelLoader); exports.NonSubModelLoader = _ts_decorate$3([ core$1.Injectable() ], exports.NonSubModelLoader); function _array_like_to_array(arr, len) { if (len == null || len > arr.length) len = arr.length; for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i]; return arr2; } function _array_with_holes(arr) { if (Array.isArray(arr)) return arr; } function _array_without_holes(arr) { if (Array.isArray(arr)) return _array_like_to_array(arr); } function _class_call_check$9(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties$8(target, props) { for(var i = 0; i < props.length; i++){ var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _create_class$8(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties$8(Constructor.prototype, protoProps); return Constructor; } function _define_property$9(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _instanceof$1(left, right) { "@swc/helpers - instanceof"; if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } function _iterable_to_array(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _iterable_to_array_limit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){ _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally{ try { if (!_n && _i["return"] != null) _i["return"](); } finally{ if (_d) throw _e; } } return _arr; } function _non_iterable_rest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _non_iterable_spread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _sliced_to_array(arr, i) { return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest(); } function _to_consumable_array(arr) { return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread(); } function _type_of$3(obj) { "@swc/helpers - typeof"; return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; } function _unsupported_iterable_to_array(o, minLen) { if (!o) return; if (typeof o === "string") return _array_like_to_array(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen); } function _ts_decorate$2(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function _ts_metadata$2(k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); } /** 与本地稀疏数组「空洞」对应的 YXmlElement,仅放入 YArray,不作通用 XML 节点使用 */ var ARRAY_HOLE_ELEMENT_NODE = 'tb-array-hole'; var collaborateErrorFn = core.makeError('Collaborate'); var SlotMap = /*#__PURE__*/ function() { function SlotMap() { _class_call_check$9(this, SlotMap); _define_property$9(this, "slotAndYTextMap", new WeakMap()); _define_property$9(this, "yTextAndSlotMap", new WeakMap()); } _create_class$8(SlotMap, [ { key: "set", value: function set(key, value) { if (_instanceof$1(key, core.Slot)) { this.slotAndYTextMap.set(key, value); this.yTextAndSlotMap.set(value, key); } else { this.slotAndYTextMap.set(value, key); this.yTextAndSlotMap.set(key, value); } } }, { key: "get", value: function get(key) { if (_instanceof$1(key, core.Slot)) { return this.slotAndYTextMap.get(key) || null; } return this.yTextAndSlotMap.get(key) || null; } }, { key: "delete", value: function _delete(key) { if (_instanceof$1(key, core.Slot)) { var v = this.slotAndYTextMap.get(key); this.slotAndYTextMap.delete(key); if (v) { this.yTextAndSlotMap.delete(v); } } else { var v1 = this.yTextAndSlotMap.get(key); this.yTextAndSlotMap.delete(key); if (v1) { this.slotAndYTextMap.delete(v1); } } } } ]); return SlotMap; }(); exports.Collaborate = /*#__PURE__*/ function() { function Collaborate(scheduler, registry, selection, subModelLoader) { _class_call_check$9(this, Collaborate); _define_property$9(this, "scheduler", void 0); _define_property$9(this, "registry", void 0); _define_property$9(this, "selection", void 0); _define_property$9(this, "subModelLoader", void 0); _define_property$9(this, "yDoc", void 0); _define_property$9(this, "slotMap", void 0); _define_property$9(this, "onAddSubModel", void 0); _define_property$9(this, "subscriptions", void 0); _define_property$9(this, "updateFromRemote", void 0); _define_property$9(this, "addSubModelEvent", void 0); _define_property$9(this, "updateRemoteActions", void 0); _define_property$9(this, "noRecord", void 0); this.scheduler = scheduler; this.registry = registry; this.selection = selection; this.subModelLoader = subModelLoader; this.yDoc = new yjs.Doc(); this.slotMap = new SlotMap(); this.subscriptions = []; this.updateFromRemote = false; this.addSubModelEvent = new stream.Subject(); this.updateRemoteActions = new WeakMap(); this.noRecord = {}; this.onAddSubModel = this.addSubModelEvent.asObservable(); } _create_class$8(Collaborate, [ { key: "syncRootComponent", value: function syncRootComponent(yDoc, sharedComponent, localComponent) { this.initSyncEvent(yDoc); this.syncComponent(yDoc, sharedComponent, localComponent); } }, { key: "syncRootSlot", value: function syncRootSlot(yDoc, sharedSlot, localSlot) { var _this = this; if (sharedSlot.length) { localSlot.retain(0); localSlot.delete(localSlot.length); localSlot.cleanAttributes(); localSlot.cleanFormats(); this.initLocalSlotBySharedSlot(sharedSlot, localSlot); } else { yDoc.transact(function() { _this.initSharedSlotByLocalSlot(sharedSlot, localSlot); }); } this.initSyncEvent(yDoc); this.syncSlot(sharedSlot, localSlot); } }, { key: "getAbstractSelection", value: function getAbstractSelection(position) { var anchorPosition = yjs.createAbsolutePositionFromRelativePosition(position.anchor.position, position.anchor.doc); var focusPosition = yjs.createAbsolutePositionFromRelativePosition(position.focus.position, position.focus.doc); if (anchorPosition && focusPosition) { var focusSlot = this.slotMap.get(focusPosition.type); var anchorSlot = this.slotMap.get(anchorPosition.type); if (focusSlot && anchorSlot) { return { anchorSlot: anchorSlot, anchorOffset: anchorPosition.index, focusSlot: focusSlot, focusOffset: focusPosition.index }; } } return null; } }, { key: "getRelativeCursorLocation", value: function getRelativeCursorLocation() { var _this_selection = this.selection, anchorSlot = _this_selection.anchorSlot, anchorOffset = _this_selection.anchorOffset, focusSlot = _this_selection.focusSlot, focusOffset = _this_selection.focusOffset; if (anchorSlot) { var anchorYText = this.slotMap.get(anchorSlot); if (anchorYText) { var anchorPosition = yjs.createRelativePositionFromTypeIndex(anchorYText, anchorOffset); if (focusSlot) { var focusYText = this.slotMap.get(focusSlot); if (focusYText) { var focusPosition = yjs.createRelativePositionFromTypeIndex(focusYText, focusOffset); return { focus: { doc: focusYText.doc, position: focusPosition }, anchor: { doc: anchorYText.doc, position: anchorPosition } }; } } } } return null; } }, { key: "restoreCursorPosition", value: function restoreCursorPosition(position) { if (!position) { this.selection.unSelect(); return; } var selection = this.getAbstractSelection(position); if (selection) { this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset); } } }, { key: "initSyncEvent", value: function initSyncEvent(yDoc) { var _this = this; this.subscriptions.push(this.scheduler.onDocChanged.pipe(stream.map(function(item) { return item.filter(function(i) { return i.from !== core.ChangeOrigin.Remote; }); }), stream.filter(function(item) { return item.length; })).subscribe(function() { var updates = []; var update = null; var updateRemoteActions = _this.updateRemoteActions.get(yDoc) || []; var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; try { for(var _iterator = updateRemoteActions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){ var item = _step.value; if (!update) { update = { record: item.record, actions: [] }; updates.push(update); } if (update.record === item.record) { update.actions.push(item.action); } else { update = { record: item.record, actions: [ item.action ] }; updates.push(update); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally{ try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally{ if (_didIteratorError) { throw _iteratorError; } } } _this.updateRemoteActions.delete(yDoc); var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined; try { var _loop = function() { var item = _step1.value; yDoc.transact(function() { item.actions.forEach(function(fn) { fn(); }); }, item.record ? yDoc : _this.noRecord); }; for(var _iterator1 = updates[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true)_loop(); } catch (err) { _didIteratorError1 = true; _iteratorError1 = err; } finally{ try { if (!_iteratorNormalCompletion1 && _iterator1.return != null) { _iterator1.return(); } } finally{ if (_didIteratorError1) { throw _iteratorError1; } } } })); } }, { key: "syncComponent", value: function syncComponent(yDoc, sharedComponent, localComponent) { var state = sharedComponent.get('state'); if (!state) { state = new yjs.Map(); this.syncLocalMapToSharedMap(localComponent.state, state); yDoc.transact(function() { sharedComponent.set('state', state); }); } else { Object.keys(localComponent.state).forEach(function(key) { Reflect.deleteProperty(localComponent.state, key); }); this.syncSharedMapToLocalMap(state, localComponent.state); } } }, { key: "syncSlot", value: function syncSlot(sharedSlot, localSlot) { var _this = this; var syncRemote = function syncRemote(ev, tr) { _this.runRemoteUpdate(tr, function() { localSlot.retain(0); ev.keysChanged.forEach(function(key) { var change = ev.keys.get(key); if (!change) { return; } var updateType = change.action; if (updateType === 'update' || updateType === 'add') { var attribute = _this.registry.getAttribute(key); if (attribute) { localSlot.setAttribute(attribute, sharedSlot.getAttribute(key)); } } else if (updateType === 'delete') { var attribute1 = _this.registry.getAttribute(key); if (attribute1) { localSlot.removeAttribute(attribute1); } } }); ev.delta.forEach(function(action) { if (Reflect.has(action, 'retain')) { if (action.attributes) { var start = localSlot.index; var end = start + action.retain; var formats = remoteRetainFormatsToLocal(_this.registry, localSlot, start, end, action.attributes); if (formats.length) { localSlot.retain(action.retain, formats); } } localSlot.retain(localSlot.index + action.retain); } else if (action.insert) { var index = localSlot.index; var length = 1; if (typeof action.insert === 'string') { length = action.insert.length; localSlot.insert(action.insert, remoteInsertFormatsToLocal(_this.registry, action.attributes)); } else { var sharedComponent = action.insert; var component = _this.createLocalComponentBySharedComponent(sharedComponent); localSlot.insert(component); } if (_this.selection.isSelected && !_instanceof$1(tr.origin, yjs.UndoManager)) { if (localSlot === _this.selection.anchorSlot && _this.selection.anchorOffset > index) { _this.selection.setAnchor(localSlot, _this.selection.anchorOffset + length); } if (localSlot === _this.selection.focusSlot && _this.selection.focusOffset > index) { _this.selection.setFocus(localSlot, _this.selection.focusOffset + length); } } } else if (action.delete) { var index1 = localSlot.index; localSlot.delete(action.delete); if (_this.selection.isSelected && !_instanceof$1(tr.origin, yjs.UndoManager)) { if (localSlot === _this.selection.anchorSlot && _this.selection.anchorOffset >= index1) { _this.selection.setAnchor(localSlot, _this.selection.startOffset - action.delete); } if (localSlot === _this.selection.focusSlot && _this.selection.focusOffset >= index1) { _this.selection.setFocus(localSlot, _this.selection.focusOffset - action.delete); } } } }); }); }; sharedSlot.observe(syncRemote); var sub = localSlot.onContentChange.subscribe(function(actions) { _this.runLocalUpdate(sharedSlot.doc, true, function() { var offset = 0; var length = 0; var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; try { for(var _iterator = actions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){ var action = _step.value; if (action.type === 'retain') { var formats = action.formats; if (formats) { var attrs = localFormatsToYjsAttributes(_this.registry, localSlot, offset, offset + action.offset, formats); if (Object.keys(attrs).length) { sharedSlot.format(offset, action.offset, attrs); } } else { offset = action.offset; } } else if (action.type === 'contentInsert') { var delta = sharedSlot.toDelta(); var isEmpty = delta.length === 1 && delta[0].insert === core.Slot.emptyPlaceholder; if (typeof action.content === 'string') { length = action.content.length; sharedSlot.insert(offset, action.content, localFormatsRecordToRemote(_this.registry, action.formats) || {}); } else { length = 1; var sharedComponent = _this.createSharedComponentByLocalComponent(action.ref); sharedSlot.insertEmbed(offset, sharedComponent, localFormatsRecordToRemote(_this.registry, action.formats) || {}); } if (isEmpty && offset === 0) { sharedSlot.delete(sharedSlot.length - 1, 1); } offset += length; } else if (action.type === 'delete') { var delta1 = sharedSlot.toDelta(); if (sharedSlot.length) { sharedSlot.delete(offset, action.count); } if (sharedSlot.length === 0) { var _delta_; sharedSlot.insert(0, '\n', (_delta_ = delta1[0]) === null || _delta_ === void 0 ? void 0 : _delta_.attributes); } } else if (action.type === 'attrSet') { sharedSlot.setAttribute(action.name, action.value); } else if (action.type === 'attrDelete') { sharedSlot.removeAttribute(action.name); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally{ try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally{ if (_didIteratorError) { throw _iteratorError; } } } }); }); this.slotMap.set(localSlot, sharedSlot); localSlot.__changeMarker__.addDetachCallback(function() { _this.slotMap.delete(localSlot); sharedSlot.unobserve(syncRemote); sub.unsubscribe(); }); } }, { key: "destroy", value: function destroy() { this.subscriptions.forEach(function(i) { return i.unsubscribe(); }); this.subscriptions = []; } }, { key: "syncSharedMapToLocalMap", value: function syncSharedMapToLocalMap(sharedMap, localMap) { var _this = this; sharedMap.forEach(function(value, key) { localMap[key] = core.toRaw(_this.createLocalModelBySharedByModel(value)); }); this.syncObject(sharedMap, localMap); } }, { key: "createLocalMapBySharedMap", value: function createLocalMapBySharedMap(sharedMap) { var localMap = core.observe({}); this.syncSharedMapToLocalMap(sharedMap, localMap); return localMap; } }, { key: "createLocalArrayBySharedArray", value: function createLocalArrayBySharedArray(sharedArray) { var raw = []; for(var i = 0; i < sharedArray.length; i++){ var item = sharedArray.get(i); if (!this.isArrayHoleElement(item)) { raw[i] = core.toRaw(this.createLocalModelBySharedByModel(item)); } } raw.length = sharedArray.length; var localArray = core.observe(raw); this.syncArray(sharedArray, localArray); return localArray; } }, { key: "syncLocalMapToSharedMap", value: function syncLocalMapToSharedMap(localMap, sharedMap) { var _this = this; Object.entries(localMap).forEach(function(param) { var _param = _sliced_to_array(param, 2), key = _param[0], value = _param[1]; sharedMap.set(key, _this.createSharedModelByLocalModel(value)); }); this.syncObject(sharedMap, localMap); } }, { key: "createSharedMapByLocalMap", value: function createSharedMapByLocalMap(localMap) { var sharedMap = new yjs.Map(); this.syncLocalMapToSharedMap(localMap, sharedMap); return sharedMap; } }, { key: "createSharedArrayByLocalArray", value: function createSharedArrayByLocalArray(localArray) { var sharedArray = new yjs.Array(); for(var i = 0; i < localArray.length; i++){ if (i in localArray) { sharedArray.push([ this.sharedModelForArraySlot(localArray[i]) ]); } else { sharedArray.push([ this.createArrayHoleXmlElement() ]); } } this.syncArray(sharedArray, localArray); return sharedArray; } }, { key: "createSharedSlotByLocalSlot", value: function createSharedSlotByLocalSlot(localSlot) { var _this = this; var sharedSlot = new yjs.Text(); var isAsyncSlot = _instanceof$1(localSlot, core.AsyncSlot); sharedSlot.setAttribute('schema', _to_consumable_array(localSlot.schema)); sharedSlot.setAttribute('type', isAsyncSlot ? 'async' : 'sync'); if (isAsyncSlot) { var isDestroyed = false; var sharedMetadata = this.createSharedMapByLocalMap(localSlot.metadata); sharedSlot.setAttribute('metadata', sharedMetadata); this.subModelLoader.createSubModelBySlot(localSlot).then(function(subDocument) { if (isDestroyed) { return; } var content = subDocument.getText('content'); var state = subDocument.getMap('state'); _this.syncLocalMapToSharedMap(localSlot.state, state); _this.initSharedSlotByLocalSlot(content, localSlot); _this.syncSlot(content, localSlot); _this.addSubModelEvent.next({ yDoc: subDocument, yType: content }); _this.initSyncEvent(subDocument); localSlot.loader.markAsLoaded(); }); localSlot.__changeMarker__.addDetachCallback(function() { isDestroyed = true; }); return sharedSlot; } var sharedSlotState = new yjs.Map(); this.syncLocalMapToSharedMap(localSlot.state, sharedSlotState); sharedSlot.setAttribute('state', sharedSlotState); var sharedContent = new yjs.Text(); this.initSharedSlotByLocalSlot(sharedContent, localSlot); sharedSlot.insertEmbed(0, sharedContent); this.syncSlot(sharedContent, localSlot); return sharedSlot; } }, { key: "initSharedSlotByLocalSlot", value: function initSharedSlotByLocalSlot(sharedContent, localSlot) { var _this = this; var offset = 0; localSlot.toDelta().forEach(function(i) { var formats = i.formats ? formatsArrayToRemoteRecord(_this.registry, i.formats) : undefined; if (typeof i.insert === 'string') { sharedContent.insert(offset, i.insert, formats); } else { var sharedComponent = _this.createSharedComponentByLocalComponent(i.insert); sharedContent.insertEmbed(offset, sharedComponent, formats); } offset += i.insert.length; }); localSlot.getAttributes().forEach(function(item) { sharedContent.setAttribute(item[0].name, item[1]); }); } }, { key: "createLocalSlotBySharedSlot", value: function createLocalSlotBySharedSlot(sharedSlot) { var _this = this; var _contentDelta_; var type = sharedSlot.getAttribute('type'); var schema = sharedSlot.getAttribute('schema'); if (type === 'async') { var metadata = sharedSlot.getAttribute('metadata'); var slot = new core.AsyncSlot(schema || [], {}, {}); this.syncSharedMapToLocalMap(metadata, slot.metadata); var loadedSubDocument = this.subModelLoader.getLoadedModelBySlot(slot); if (loadedSubDocument) { var subContent = loadedSubDocument.getText('content'); var data = loadedSubDocument.getMap('state'); this.syncSharedMapToLocalMap(data, slot.state); this.syncRootSlot(loadedSubDocument, subContent, slot); this.addSubModelEvent.next({ yDoc: loadedSubDocument, yType: subContent }); slot.loader.markAsLoaded(); return slot; } var isDestroyed = false; slot.loader.onRequestLoad.toPromise().then(function() { return _this.subModelLoader.loadSubModelBySlot(slot); }).then(function(subDocument) { if (isDestroyed) { return; } var subContent = subDocument.getText('content'); var state = subDocument.getMap('state'); _this.syncSharedMapToLocalMap(state, slot.state); _this.syncRootSlot(subDocument, subContent, slot); _this.addSubModelEvent.next({ yDoc: subDocument, yType: subContent }); slot.loader.markAsLoaded(); }); slot.__changeMarker__.addDetachCallback(function() { isDestroyed = true; }); return slot; } var contentDelta = sharedSlot.toDelta(); var content = (_contentDelta_ = contentDelta[0]) === null || _contentDelta_ === void 0 ? void 0 : _contentDelta_.insert; if (!_instanceof$1(content, yjs.Text)) { throw collaborateErrorFn('shared slot content type is not `YText`.'); } var localSlot = new core.Slot(schema || [], {}); var sharedSlotState = sharedSlot.getAttribute('state'); this.syncSharedMapToLocalMap(sharedSlotState, localSlot.state); this.initLocalSlotBySharedSlot(content, localSlot); this.syncSlot(content, localSlot); return localSlot; } }, { key: "initLocalSlotBySharedSlot", value: function initLocalSlotBySharedSlot(content, localSlot) { var _this = this; var delta = content.toDelta(); var attrs = content.getAttributes(); Object.keys(attrs).forEach(function(key) { var attribute = _this.registry.getAttribute(key); if (attribute) { localSlot.setAttribute(attribute, attrs[key]); } }); var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; try { for(var _iterator = delta[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){ var action = _step.value; if (action.insert) { if (typeof action.insert === 'string') { var formats = remoteInsertFormatsToLocal(this.registry, action.attributes); localSlot.insert(action.insert, formats); } else { var sharedComponent = action.insert; var component = this.createLocalComponentBySharedComponent(sharedComponent); localSlot.insert(component, remoteInsertFormatsToLocal(this.registry, action.attributes)); } } else { throw collaborateErrorFn('unexpected delta action.'); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally{ try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally{ if (_didIteratorError) { throw _iteratorError; } } } } }, { key: "createSharedModelByLocalModel", value: function createSharedModelByLocalModel(localModel) { if (_instanceof$1(localModel, core.Slot)) { return this.createSharedSlotByLocalSlot(localModel); } if (Array.isArray(localModel)) { return this.createSharedArrayByLocalArray(localModel); } if ((typeof localModel === "undefined" ? "undefined" : _type_of$3(localModel)) === 'object' && localModel !== null) { return this.createSharedMapByLocalMap(localModel); } return localModel; } }, { key: "createLocalModelBySharedByModel", value: function createLocalModelBySharedByModel(sharedModel) { if (_instanceof$1(sharedModel, yjs.Map)) { return this.createLocalMapBySharedMap(sharedModel); } if (_instanceof$1(sharedModel, yjs.Array)) { return this.createLocalArrayBySharedArray(sharedModel); } if (_instanceof$1(sharedModel, yjs.Text)) { return this.createLocalSlotBySharedSlot(sharedModel); } return sharedModel; } }, { key: "createSharedComponentByLocalComponent", value: function createSharedComponentByLocalComponent(component) { var _this = this; var sharedComponent = new yjs.Map(); sharedComponent.set('name', component.name); if (_instanceof$1(component, core.AsyncComponent)) { sharedComponent.set('type', 'async'); var sharedMetadata = this.createSharedMapByLocalMap(component.metadata); sharedComponent.set('metadata', sharedMetadata); var state = component.state; var isDestroyed = false; state.__changeMarker__.addDetachCallback(function() { isDestroyed = true; }); this.subModelLoader.createSubModelByComponent(component).then(function(subDocument) { if (isDestroyed) { return; } var state = subDocument.getMap('state'); _this.syncComponent(subDocument, state, component); _this.addSubModelEvent.next({ yType: state, yDoc: subDocument }); _this.initSyncEvent(subDocument); component.loader.markAsLoaded(); }); return sharedComponent; } var sharedState = this.createSharedMapByLocalMap(component.state); sharedComponent.set('state', sharedState); sharedComponent.set('type', 'sync'); return sharedComponent; } }, { key: "createLocalComponentBySharedComponent", value: function createLocalComponentBySharedComponent(yMap) { var _this = this; var componentName = yMap.get('name'); var type = yMap.get('type'); var instance; if (type === 'async') { instance = this.registry.createComponentByData(componentName, {}, {}); if (_instanceof$1(instance, core.AsyncComponent)) { var sharedMetadata = yMap.get('metadata'); this.syncSharedMapToLocalMap(sharedMetadata, instance.metadata); var loadedSubDocument = this.subModelLoader.getLoadedModelByComponent(instance); if (loadedSubDocument) { var state = loadedSubDocument.getMap('state'); this.syncComponent(loadedSubDocument, state, instance); this.addSubModelEvent.next({ yType: state, yDoc: loadedSubDocument }); instance.loader.markAsLoaded(); return instance; } var state1 = instance.state; var isDestroyed = false; instance.loader.onRequestLoad.toPromise().then(function() { return _this.subModelLoader.loadSubModelByComponent(instance); }).then(function(subDocument) { if (isDestroyed) { return; } var state = subDocument.getMap('state'); _this.syncComponent(subDocument, state, instance); _this.addSubModelEvent.next({ yType: state, yDoc: subDocument }); instance.loader.markAsLoaded(); }); state1.__changeMarker__.addDetachCallback(function() { isDestroyed = true; }); } else if (_instanceof$1(instance, core.Component)) { throw collaborateErrorFn("component name `".concat(componentName, "` is not a async component.")); } } else { var sharedState = yMap.get('state'); var state2 = this.createLocalMapBySharedMap(sharedState); instance = this.registry.createComponentByData(componentName, state2); } if (instance) { return instance; } throw collaborateErrorFn("cannot find component factory `".concat(componentName, "`.")); } }, { key: "createArrayHoleXmlElement", value: function createArrayHoleXmlElement() { return new yjs.XmlElement(ARRAY_HOLE_ELEMENT_NODE); } }, { key: "isArrayHoleElement", value: function isArrayHoleElement(sharedModel) { return _instanceof$1(sharedModel, yjs.XmlElement) && sharedModel.nodeName === ARRAY_HOLE_ELEMENT_NODE; } }, { key: "sharedModelForArraySlot", value: /** * 仅用于 YArray ↔ 可