UNPKG

alinea

Version:
1,540 lines (1,532 loc) 82 kB
import { FloatingMenuPlugin } from "../../chunks/chunk-3DIW62EI.js"; import { Editor, Extension, Fragment, Node, NodeView, Plugin, PluginKey, Slice, TextSelection, getRenderedAttributes, mergeAttributes } from "../../chunks/chunk-FKWEJTSK.js"; import { dist_default } from "../../chunks/chunk-A5O3N2GS.js"; import { ContentFormat, ContentString, ContentType, Doc, Item, RelativePosition, Snapshot, UndoManager, YText, YXmlElement, YXmlText, applyUpdateV2, createAbsolutePositionFromRelativePosition, createDeleteSet, createID, createRelativePositionFromTypeIndex, createSnapshot, doc, findRootTypeKey, isBrowser, isDeleted, isParentOf, iterateDeletedStructs, keys, oneOf, snapshot, timeout, typeListToArraySnapshot } from "../../chunks/chunk-QUIANN6B.js"; import { create, max, methodUnimplemented, min, unexpectedCase } from "../../chunks/chunk-AJJSW27C.js"; import "../../chunks/chunk-NZLE2WMY.js"; // node_modules/lib0/mutex.js var createMutex = () => { let token = true; return (f, g) => { if (token) { token = false; try { f(); } finally { token = true; } } else if (g !== void 0) { g(); } }; }; // node_modules/lib0/diff.js var highSurrogateRegex = /[\uD800-\uDBFF]/; var lowSurrogateRegex = /[\uDC00-\uDFFF]/; var simpleDiffString = (a, b) => { let left = 0; let right = 0; while (left < a.length && left < b.length && a[left] === b[left]) { left++; } if (left > 0 && highSurrogateRegex.test(a[left - 1])) left--; while (right + left < a.length && right + left < b.length && a[a.length - right - 1] === b[b.length - right - 1]) { right++; } if (right > 0 && lowSurrogateRegex.test(a[a.length - right])) right--; return { index: left, remove: a.length - left - right, insert: b.slice(left, b.length - right) }; }; var simpleDiff = simpleDiffString; // node_modules/y-prosemirror/src/plugins/keys.js var ySyncPluginKey = new PluginKey("y-sync"); var yUndoPluginKey = new PluginKey("y-undo"); var yCursorPluginKey = new PluginKey("yjs-cursor"); // node_modules/y-prosemirror/src/plugins/sync-plugin.js var isVisible = (item, snapshot2) => snapshot2 === void 0 ? !item.deleted : snapshot2.sv.has(item.id.client) && /** @type {number} */ snapshot2.sv.get(item.id.client) > item.id.clock && !isDeleted(snapshot2.ds, item.id); var defaultColors = [{ light: "#ecd44433", dark: "#ecd444" }]; var getUserColor = (colorMapping, colors, user) => { if (!colorMapping.has(user)) { if (colorMapping.size < colors.length) { const usedColors = create(); colorMapping.forEach((color) => usedColors.add(color)); colors = colors.filter((color) => !usedColors.has(color)); } colorMapping.set(user, oneOf(colors)); } return ( /** @type {ColorDef} */ colorMapping.get(user) ); }; var ySyncPlugin = (yXmlFragment, { colors = defaultColors, colorMapping = /* @__PURE__ */ new Map(), permanentUserData = null, onFirstRender = () => { }, mapping } = {}) => { let initialContentChanged = false; const binding = new ProsemirrorBinding(yXmlFragment, mapping); const plugin = new Plugin({ props: { editable: (state) => { const syncState = ySyncPluginKey.getState(state); return syncState.snapshot == null && syncState.prevSnapshot == null; } }, key: ySyncPluginKey, state: { /** * @returns {any} */ init: (_initargs, _state) => { return { type: yXmlFragment, doc: yXmlFragment.doc, binding, snapshot: null, prevSnapshot: null, isChangeOrigin: false, isUndoRedoOperation: false, addToHistory: true, colors, colorMapping, permanentUserData }; }, apply: (tr, pluginState) => { const change = tr.getMeta(ySyncPluginKey); if (change !== void 0) { pluginState = Object.assign({}, pluginState); for (const key in change) { pluginState[key] = change[key]; } } pluginState.addToHistory = tr.getMeta("addToHistory") !== false; pluginState.isChangeOrigin = change !== void 0 && !!change.isChangeOrigin; pluginState.isUndoRedoOperation = change !== void 0 && !!change.isChangeOrigin && !!change.isUndoRedoOperation; if (binding.prosemirrorView !== null) { if (change !== void 0 && (change.snapshot != null || change.prevSnapshot != null)) { timeout(0, () => { if (binding.prosemirrorView == null) { return; } if (change.restore == null) { binding._renderSnapshot( change.snapshot, change.prevSnapshot, pluginState ); } else { binding._renderSnapshot( change.snapshot, change.snapshot, pluginState ); delete pluginState.restore; delete pluginState.snapshot; delete pluginState.prevSnapshot; binding.mux(() => { binding._prosemirrorChanged( binding.prosemirrorView.state.doc ); }); } }); } } return pluginState; } }, view: (view) => { binding.initView(view); if (mapping == null) { binding._forceRerender(); } onFirstRender(); return { update: () => { const pluginState = plugin.getState(view.state); if (pluginState.snapshot == null && pluginState.prevSnapshot == null) { if ( // If the content doesn't change initially, we don't render anything to Yjs // If the content was cleared by a user action, we want to catch the change and // represent it in Yjs initialContentChanged || view.state.doc.content.findDiffStart( view.state.doc.type.createAndFill().content ) !== null ) { initialContentChanged = true; if (pluginState.addToHistory === false && !pluginState.isChangeOrigin) { const yUndoPluginState = yUndoPluginKey.getState(view.state); const um = yUndoPluginState && yUndoPluginState.undoManager; if (um) { um.stopCapturing(); } } binding.mux(() => { pluginState.doc.transact((tr) => { tr.meta.set("addToHistory", pluginState.addToHistory); binding._prosemirrorChanged(view.state.doc); }, ySyncPluginKey); }); } } }, destroy: () => { binding.destroy(); } }; } }); return plugin; }; var restoreRelativeSelection = (tr, relSel, binding) => { if (relSel !== null && relSel.anchor !== null && relSel.head !== null) { const anchor = relativePositionToAbsolutePosition( binding.doc, binding.type, relSel.anchor, binding.mapping ); const head = relativePositionToAbsolutePosition( binding.doc, binding.type, relSel.head, binding.mapping ); if (anchor !== null && head !== null) { tr = tr.setSelection(TextSelection.create(tr.doc, anchor, head)); } } }; var getRelativeSelection = (pmbinding, state) => ({ anchor: absolutePositionToRelativePosition( state.selection.anchor, pmbinding.type, pmbinding.mapping ), head: absolutePositionToRelativePosition( state.selection.head, pmbinding.type, pmbinding.mapping ) }); var ProsemirrorBinding = class { /** * @param {Y.XmlFragment} yXmlFragment The bind source * @param {ProsemirrorMapping} mapping */ constructor(yXmlFragment, mapping = /* @__PURE__ */ new Map()) { this.type = yXmlFragment; this.prosemirrorView = null; this.mux = createMutex(); this.mapping = mapping; this._observeFunction = this._typeChanged.bind(this); this.doc = yXmlFragment.doc; this.beforeTransactionSelection = null; this.beforeAllTransactions = () => { if (this.beforeTransactionSelection === null && this.prosemirrorView != null) { this.beforeTransactionSelection = getRelativeSelection( this, this.prosemirrorView.state ); } }; this.afterAllTransactions = () => { this.beforeTransactionSelection = null; }; this._domSelectionInView = null; } /** * Create a transaction for changing the prosemirror state. * * @returns */ get _tr() { return this.prosemirrorView.state.tr.setMeta("addToHistory", false); } _isLocalCursorInView() { if (!this.prosemirrorView.hasFocus()) return false; if (isBrowser && this._domSelectionInView === null) { timeout(0, () => { this._domSelectionInView = null; }); this._domSelectionInView = this._isDomSelectionInView(); } return this._domSelectionInView; } _isDomSelectionInView() { const selection = this.prosemirrorView._root.getSelection(); if (selection == null || selection.anchorNode == null) return false; const range = this.prosemirrorView._root.createRange(); range.setStart(selection.anchorNode, selection.anchorOffset); range.setEnd(selection.focusNode, selection.focusOffset); const rects = range.getClientRects(); if (rects.length === 0) { if (range.startContainer && range.collapsed) { range.selectNodeContents(range.startContainer); } } const bounding = range.getBoundingClientRect(); const documentElement = doc.documentElement; return bounding.bottom >= 0 && bounding.right >= 0 && bounding.left <= (window.innerWidth || documentElement.clientWidth || 0) && bounding.top <= (window.innerHeight || documentElement.clientHeight || 0); } /** * @param {Y.Snapshot} snapshot * @param {Y.Snapshot} prevSnapshot */ renderSnapshot(snapshot2, prevSnapshot) { if (!prevSnapshot) { prevSnapshot = createSnapshot(createDeleteSet(), /* @__PURE__ */ new Map()); } this.prosemirrorView.dispatch( this._tr.setMeta(ySyncPluginKey, { snapshot: snapshot2, prevSnapshot }) ); } unrenderSnapshot() { this.mapping.clear(); this.mux(() => { const fragmentContent = this.type.toArray().map( (t) => createNodeFromYElement( /** @type {Y.XmlElement} */ t, this.prosemirrorView.state.schema, this.mapping ) ).filter((n) => n !== null); const tr = this._tr.replace( 0, this.prosemirrorView.state.doc.content.size, new Slice(Fragment.from(fragmentContent), 0, 0) ); tr.setMeta(ySyncPluginKey, { snapshot: null, prevSnapshot: null }); this.prosemirrorView.dispatch(tr); }); } _forceRerender() { this.mapping.clear(); this.mux(() => { const sel = this.beforeTransactionSelection !== null ? null : this.prosemirrorView.state.selection; const fragmentContent = this.type.toArray().map( (t) => createNodeFromYElement( /** @type {Y.XmlElement} */ t, this.prosemirrorView.state.schema, this.mapping ) ).filter((n) => n !== null); const tr = this._tr.replace( 0, this.prosemirrorView.state.doc.content.size, new Slice(Fragment.from(fragmentContent), 0, 0) ); if (sel) { const clampedAnchor = min(max(sel.anchor, 0), tr.doc.content.size); const clampedHead = min(max(sel.head, 0), tr.doc.content.size); tr.setSelection(TextSelection.create(tr.doc, clampedAnchor, clampedHead)); } this.prosemirrorView.dispatch( tr.setMeta(ySyncPluginKey, { isChangeOrigin: true, binding: this }) ); }); } /** * @param {Y.Snapshot|Uint8Array} snapshot * @param {Y.Snapshot|Uint8Array} prevSnapshot * @param {Object} pluginState */ _renderSnapshot(snapshot2, prevSnapshot, pluginState) { let historyDoc = this.doc; if (!snapshot2) { snapshot2 = snapshot(this.doc); } if (snapshot2 instanceof Uint8Array || prevSnapshot instanceof Uint8Array) { if (!(snapshot2 instanceof Uint8Array) || !(prevSnapshot instanceof Uint8Array)) { unexpectedCase(); } historyDoc = new Doc({ gc: false }); applyUpdateV2(historyDoc, prevSnapshot); prevSnapshot = snapshot(historyDoc); applyUpdateV2(historyDoc, snapshot2); snapshot2 = snapshot(historyDoc); } this.mapping.clear(); this.mux(() => { historyDoc.transact((transaction) => { const pud = pluginState.permanentUserData; if (pud) { pud.dss.forEach((ds) => { iterateDeletedStructs(transaction, ds, (_item) => { }); }); } const computeYChange = (type, id) => { const user = type === "added" ? pud.getUserByClientId(id.client) : pud.getUserByDeletedId(id); return { user, type, color: getUserColor( pluginState.colorMapping, pluginState.colors, user ) }; }; const fragmentContent = typeListToArraySnapshot( this.type, new Snapshot(prevSnapshot.ds, snapshot2.sv) ).map((t) => { if (!t._item.deleted || isVisible(t._item, snapshot2) || isVisible(t._item, prevSnapshot)) { return createNodeFromYElement( t, this.prosemirrorView.state.schema, /* @__PURE__ */ new Map(), snapshot2, prevSnapshot, computeYChange ); } else { return null; } }).filter((n) => n !== null); const tr = this._tr.replace( 0, this.prosemirrorView.state.doc.content.size, new Slice(Fragment.from(fragmentContent), 0, 0) ); this.prosemirrorView.dispatch( tr.setMeta(ySyncPluginKey, { isChangeOrigin: true }) ); }, ySyncPluginKey); }); } /** * @param {Array<Y.YEvent<any>>} events * @param {Y.Transaction} transaction */ _typeChanged(events, transaction) { if (this.prosemirrorView == null) return; const syncState = ySyncPluginKey.getState(this.prosemirrorView.state); if (events.length === 0 || syncState.snapshot != null || syncState.prevSnapshot != null) { this.renderSnapshot(syncState.snapshot, syncState.prevSnapshot); return; } this.mux(() => { const delType = (_, type) => this.mapping.delete(type); iterateDeletedStructs( transaction, transaction.deleteSet, (struct) => { if (struct.constructor === Item) { const type = ( /** @type {Y.ContentType} */ /** @type {Y.Item} */ struct.content.type ); type && this.mapping.delete(type); } } ); transaction.changed.forEach(delType); transaction.changedParentTypes.forEach(delType); const fragmentContent = this.type.toArray().map( (t) => createNodeIfNotExists( /** @type {Y.XmlElement | Y.XmlHook} */ t, this.prosemirrorView.state.schema, this.mapping ) ).filter((n) => n !== null); let tr = this._tr.replace( 0, this.prosemirrorView.state.doc.content.size, new Slice(Fragment.from(fragmentContent), 0, 0) ); restoreRelativeSelection(tr, this.beforeTransactionSelection, this); tr = tr.setMeta(ySyncPluginKey, { isChangeOrigin: true, isUndoRedoOperation: transaction.origin instanceof UndoManager }); if (this.beforeTransactionSelection !== null && this._isLocalCursorInView()) { tr.scrollIntoView(); } this.prosemirrorView.dispatch(tr); }); } _prosemirrorChanged(doc2) { this.doc.transact(() => { updateYFragment(this.doc, this.type, doc2, this.mapping); this.beforeTransactionSelection = getRelativeSelection( this, this.prosemirrorView.state ); }, ySyncPluginKey); } /** * View is ready to listen to changes. Register observers. * @param {any} prosemirrorView */ initView(prosemirrorView) { if (this.prosemirrorView != null) this.destroy(); this.prosemirrorView = prosemirrorView; this.doc.on("beforeAllTransactions", this.beforeAllTransactions); this.doc.on("afterAllTransactions", this.afterAllTransactions); this.type.observeDeep(this._observeFunction); } destroy() { if (this.prosemirrorView == null) return; this.prosemirrorView = null; this.type.unobserveDeep(this._observeFunction); this.doc.off("beforeAllTransactions", this.beforeAllTransactions); this.doc.off("afterAllTransactions", this.afterAllTransactions); } }; var createNodeIfNotExists = (el, schema, mapping, snapshot2, prevSnapshot, computeYChange) => { const node = ( /** @type {PModel.Node} */ mapping.get(el) ); if (node === void 0) { if (el instanceof YXmlElement) { return createNodeFromYElement( el, schema, mapping, snapshot2, prevSnapshot, computeYChange ); } else { throw methodUnimplemented(); } } return node; }; var createNodeFromYElement = (el, schema, mapping, snapshot2, prevSnapshot, computeYChange) => { const children = []; const createChildren = (type) => { if (type.constructor === YXmlElement) { const n = createNodeIfNotExists( type, schema, mapping, snapshot2, prevSnapshot, computeYChange ); if (n !== null) { children.push(n); } } else { const nextytext = type._item.right?.content.type; if (nextytext instanceof YText && !nextytext._item.deleted && nextytext._item.id.client === nextytext.doc.clientID) { type.applyDelta([ { retain: type.length }, ...nextytext.toDelta() ]); nextytext.doc.transact((tr) => { nextytext._item.delete(tr); }); } const ns = createTextNodesFromYText( type, schema, mapping, snapshot2, prevSnapshot, computeYChange ); if (ns !== null) { ns.forEach((textchild) => { if (textchild !== null) { children.push(textchild); } }); } } }; if (snapshot2 === void 0 || prevSnapshot === void 0) { el.toArray().forEach(createChildren); } else { typeListToArraySnapshot(el, new Snapshot(prevSnapshot.ds, snapshot2.sv)).forEach(createChildren); } try { const attrs = el.getAttributes(snapshot2); if (snapshot2 !== void 0) { if (!isVisible( /** @type {Y.Item} */ el._item, snapshot2 )) { attrs.ychange = computeYChange ? computeYChange( "removed", /** @type {Y.Item} */ el._item.id ) : { type: "removed" }; } else if (!isVisible( /** @type {Y.Item} */ el._item, prevSnapshot )) { attrs.ychange = computeYChange ? computeYChange( "added", /** @type {Y.Item} */ el._item.id ) : { type: "added" }; } } const node = schema.node(el.nodeName, attrs, children); mapping.set(el, node); return node; } catch (e) { el.doc.transact((transaction) => { el._item.delete(transaction); }, ySyncPluginKey); mapping.delete(el); return null; } }; var createTextNodesFromYText = (text, schema, _mapping, snapshot2, prevSnapshot, computeYChange) => { const nodes = []; const deltas = text.toDelta(snapshot2, prevSnapshot, computeYChange); try { for (let i = 0; i < deltas.length; i++) { const delta = deltas[i]; const marks = []; for (const markName in delta.attributes) { marks.push(schema.mark(markName, delta.attributes[markName])); } nodes.push(schema.text(delta.insert, marks)); } } catch (e) { text.doc.transact((transaction) => { text._item.delete(transaction); }, ySyncPluginKey); return null; } return nodes; }; var createTypeFromTextNodes = (nodes, mapping) => { const type = new YXmlText(); const delta = nodes.map((node) => ({ // @ts-ignore insert: node.text, attributes: marksToAttributes(node.marks) })); type.applyDelta(delta); mapping.set(type, nodes); return type; }; var createTypeFromElementNode = (node, mapping) => { const type = new YXmlElement(node.type.name); for (const key in node.attrs) { const val = node.attrs[key]; if (val !== null && key !== "ychange") { type.setAttribute(key, val); } } type.insert( 0, normalizePNodeContent(node).map( (n) => createTypeFromTextOrElementNode(n, mapping) ) ); mapping.set(type, node); return type; }; var createTypeFromTextOrElementNode = (node, mapping) => node instanceof Array ? createTypeFromTextNodes(node, mapping) : createTypeFromElementNode(node, mapping); var isObject = (val) => typeof val === "object" && val !== null; var equalAttrs = (pattrs, yattrs) => { const keys2 = Object.keys(pattrs).filter((key) => pattrs[key] !== null); let eq = keys2.length === Object.keys(yattrs).filter((key) => yattrs[key] !== null).length; for (let i = 0; i < keys2.length && eq; i++) { const key = keys2[i]; const l = pattrs[key]; const r = yattrs[key]; eq = key === "ychange" || l === r || isObject(l) && isObject(r) && equalAttrs(l, r); } return eq; }; var normalizePNodeContent = (pnode) => { const c = pnode.content.content; const res = []; for (let i = 0; i < c.length; i++) { const n = c[i]; if (n.isText) { const textNodes = []; for (let tnode = c[i]; i < c.length && tnode.isText; tnode = c[++i]) { textNodes.push(tnode); } i--; res.push(textNodes); } else { res.push(n); } } return res; }; var equalYTextPText = (ytext, ptexts) => { const delta = ytext.toDelta(); return delta.length === ptexts.length && delta.every( (d, i) => d.insert === /** @type {any} */ ptexts[i].text && keys(d.attributes || {}).length === ptexts[i].marks.length && ptexts[i].marks.every( (mark) => equalAttrs(d.attributes[mark.type.name] || {}, mark.attrs) ) ); }; var equalYTypePNode = (ytype, pnode) => { if (ytype instanceof YXmlElement && !(pnode instanceof Array) && matchNodeName(ytype, pnode)) { const normalizedContent = normalizePNodeContent(pnode); return ytype._length === normalizedContent.length && equalAttrs(ytype.getAttributes(), pnode.attrs) && ytype.toArray().every( (ychild, i) => equalYTypePNode(ychild, normalizedContent[i]) ); } return ytype instanceof YXmlText && pnode instanceof Array && equalYTextPText(ytype, pnode); }; var mappedIdentity = (mapped, pcontent) => mapped === pcontent || mapped instanceof Array && pcontent instanceof Array && mapped.length === pcontent.length && mapped.every( (a, i) => pcontent[i] === a ); var computeChildEqualityFactor = (ytype, pnode, mapping) => { const yChildren = ytype.toArray(); const pChildren = normalizePNodeContent(pnode); const pChildCnt = pChildren.length; const yChildCnt = yChildren.length; const minCnt = min(yChildCnt, pChildCnt); let left = 0; let right = 0; let foundMappedChild = false; for (; left < minCnt; left++) { const leftY = yChildren[left]; const leftP = pChildren[left]; if (mappedIdentity(mapping.get(leftY), leftP)) { foundMappedChild = true; } else if (!equalYTypePNode(leftY, leftP)) { break; } } for (; left + right < minCnt; right++) { const rightY = yChildren[yChildCnt - right - 1]; const rightP = pChildren[pChildCnt - right - 1]; if (mappedIdentity(mapping.get(rightY), rightP)) { foundMappedChild = true; } else if (!equalYTypePNode(rightY, rightP)) { break; } } return { equalityFactor: left + right, foundMappedChild }; }; var ytextTrans = (ytext) => { let str = ""; let n = ytext._start; const nAttrs = {}; while (n !== null) { if (!n.deleted) { if (n.countable && n.content instanceof ContentString) { str += n.content.str; } else if (n.content instanceof ContentFormat) { nAttrs[n.content.key] = null; } } n = n.right; } return { str, nAttrs }; }; var updateYText = (ytext, ptexts, mapping) => { mapping.set(ytext, ptexts); const { nAttrs, str } = ytextTrans(ytext); const content = ptexts.map((p) => ({ insert: ( /** @type {any} */ p.text ), attributes: Object.assign({}, nAttrs, marksToAttributes(p.marks)) })); const { insert, remove, index } = simpleDiff( str, content.map((c) => c.insert).join("") ); ytext.delete(index, remove); ytext.insert(index, insert); ytext.applyDelta( content.map((c) => ({ retain: c.insert.length, attributes: c.attributes })) ); }; var marksToAttributes = (marks) => { const pattrs = {}; marks.forEach((mark) => { if (mark.type.name !== "ychange") { pattrs[mark.type.name] = mark.attrs; } }); return pattrs; }; var updateYFragment = (y, yDomFragment, pNode, mapping) => { if (yDomFragment instanceof YXmlElement && yDomFragment.nodeName !== pNode.type.name) { throw new Error("node name mismatch!"); } mapping.set(yDomFragment, pNode); if (yDomFragment instanceof YXmlElement) { const yDomAttrs = yDomFragment.getAttributes(); const pAttrs = pNode.attrs; for (const key in pAttrs) { if (pAttrs[key] !== null) { if (yDomAttrs[key] !== pAttrs[key] && key !== "ychange") { yDomFragment.setAttribute(key, pAttrs[key]); } } else { yDomFragment.removeAttribute(key); } } for (const key in yDomAttrs) { if (pAttrs[key] === void 0) { yDomFragment.removeAttribute(key); } } } const pChildren = normalizePNodeContent(pNode); const pChildCnt = pChildren.length; const yChildren = yDomFragment.toArray(); const yChildCnt = yChildren.length; const minCnt = min(pChildCnt, yChildCnt); let left = 0; let right = 0; for (; left < minCnt; left++) { const leftY = yChildren[left]; const leftP = pChildren[left]; if (!mappedIdentity(mapping.get(leftY), leftP)) { if (equalYTypePNode(leftY, leftP)) { mapping.set(leftY, leftP); } else { break; } } } for (; right + left + 1 < minCnt; right++) { const rightY = yChildren[yChildCnt - right - 1]; const rightP = pChildren[pChildCnt - right - 1]; if (!mappedIdentity(mapping.get(rightY), rightP)) { if (equalYTypePNode(rightY, rightP)) { mapping.set(rightY, rightP); } else { break; } } } y.transact(() => { while (yChildCnt - left - right > 0 && pChildCnt - left - right > 0) { const leftY = yChildren[left]; const leftP = pChildren[left]; const rightY = yChildren[yChildCnt - right - 1]; const rightP = pChildren[pChildCnt - right - 1]; if (leftY instanceof YXmlText && leftP instanceof Array) { if (!equalYTextPText(leftY, leftP)) { updateYText(leftY, leftP, mapping); } left += 1; } else { let updateLeft = leftY instanceof YXmlElement && matchNodeName(leftY, leftP); let updateRight = rightY instanceof YXmlElement && matchNodeName(rightY, rightP); if (updateLeft && updateRight) { const equalityLeft = computeChildEqualityFactor( /** @type {Y.XmlElement} */ leftY, /** @type {PModel.Node} */ leftP, mapping ); const equalityRight = computeChildEqualityFactor( /** @type {Y.XmlElement} */ rightY, /** @type {PModel.Node} */ rightP, mapping ); if (equalityLeft.foundMappedChild && !equalityRight.foundMappedChild) { updateRight = false; } else if (!equalityLeft.foundMappedChild && equalityRight.foundMappedChild) { updateLeft = false; } else if (equalityLeft.equalityFactor < equalityRight.equalityFactor) { updateLeft = false; } else { updateRight = false; } } if (updateLeft) { updateYFragment( y, /** @type {Y.XmlFragment} */ leftY, /** @type {PModel.Node} */ leftP, mapping ); left += 1; } else if (updateRight) { updateYFragment( y, /** @type {Y.XmlFragment} */ rightY, /** @type {PModel.Node} */ rightP, mapping ); right += 1; } else { mapping.delete(yDomFragment.get(left)); yDomFragment.delete(left, 1); yDomFragment.insert(left, [ createTypeFromTextOrElementNode(leftP, mapping) ]); left += 1; } } } const yDelLen = yChildCnt - left - right; if (yChildCnt === 1 && pChildCnt === 0 && yChildren[0] instanceof YXmlText) { mapping.delete(yChildren[0]); yChildren[0].delete(0, yChildren[0].length); } else if (yDelLen > 0) { yDomFragment.slice(left, left + yDelLen).forEach((type) => mapping.delete(type)); yDomFragment.delete(left, yDelLen); } if (left + right < pChildCnt) { const ins = []; for (let i = left; i < pChildCnt - right; i++) { ins.push(createTypeFromTextOrElementNode(pChildren[i], mapping)); } yDomFragment.insert(left, ins); } }, ySyncPluginKey); }; var matchNodeName = (yElement, pNode) => !(pNode instanceof Array) && yElement.nodeName === pNode.type.name; // node_modules/y-prosemirror/src/lib.js var absolutePositionToRelativePosition = (pos, type, mapping) => { if (pos === 0) { return createRelativePositionFromTypeIndex(type, 0, -1); } let n = type._first === null ? null : ( /** @type {Y.ContentType} */ type._first.content.type ); while (n !== null && type !== n) { if (n instanceof YXmlText) { if (n._length >= pos) { return createRelativePositionFromTypeIndex(n, pos, -1); } else { pos -= n._length; } if (n._item !== null && n._item.next !== null) { n = /** @type {Y.ContentType} */ n._item.next.content.type; } else { do { n = n._item === null ? null : n._item.parent; pos--; } while (n !== type && n !== null && n._item !== null && n._item.next === null); if (n !== null && n !== type) { n = n._item === null ? null : ( /** @type {Y.ContentType} */ /** @type Y.Item */ n._item.next.content.type ); } } } else { const pNodeSize = ( /** @type {any} */ (mapping.get(n) || { nodeSize: 0 }).nodeSize ); if (n._first !== null && pos < pNodeSize) { n = /** @type {Y.ContentType} */ n._first.content.type; pos--; } else { if (pos === 1 && n._length === 0 && pNodeSize > 1) { return new RelativePosition(n._item === null ? null : n._item.id, n._item === null ? findRootTypeKey(n) : null, null); } pos -= pNodeSize; if (n._item !== null && n._item.next !== null) { n = /** @type {Y.ContentType} */ n._item.next.content.type; } else { if (pos === 0) { n = n._item === null ? n : n._item.parent; return new RelativePosition(n._item === null ? null : n._item.id, n._item === null ? findRootTypeKey(n) : null, null); } do { n = /** @type {Y.Item} */ n._item.parent; pos--; } while (n !== type && /** @type {Y.Item} */ n._item.next === null); if (n !== type) { n = /** @type {Y.ContentType} */ /** @type {Y.Item} */ /** @type {Y.Item} */ n._item.next.content.type; } } } } if (n === null) { throw unexpectedCase(); } if (pos === 0 && n.constructor !== YXmlText && n !== type) { return createRelativePosition(n._item.parent, n._item); } } return createRelativePositionFromTypeIndex(type, type._length, -1); }; var createRelativePosition = (type, item) => { let typeid = null; let tname = null; if (type._item === null) { tname = findRootTypeKey(type); } else { typeid = createID(type._item.id.client, type._item.id.clock); } return new RelativePosition(typeid, tname, item.id); }; var relativePositionToAbsolutePosition = (y, documentType, relPos, mapping) => { const decodedPos = createAbsolutePositionFromRelativePosition(relPos, y); if (decodedPos === null || decodedPos.type !== documentType && !isParentOf(documentType, decodedPos.type._item)) { return null; } let type = decodedPos.type; let pos = 0; if (type.constructor === YXmlText) { pos = decodedPos.index; } else if (type._item === null || !type._item.deleted) { let n = type._first; let i = 0; while (i < type._length && i < decodedPos.index && n !== null) { if (!n.deleted) { const t = ( /** @type {Y.ContentType} */ n.content.type ); i++; if (t instanceof YXmlText) { pos += t._length; } else { pos += /** @type {any} */ mapping.get(t).nodeSize; } } n = /** @type {Y.Item} */ n.right; } pos += 1; } while (type !== documentType && type._item !== null) { const parent = type._item.parent; if (parent._item === null || !parent._item.deleted) { pos += 1; let n = ( /** @type {Y.AbstractType} */ parent._first ); while (n !== null) { const contentType = ( /** @type {Y.ContentType} */ n.content.type ); if (contentType === type) { break; } if (!n.deleted) { if (contentType instanceof YXmlText) { pos += contentType._length; } else { pos += /** @type {any} */ mapping.get(contentType).nodeSize; } } n = n.right; } } type = /** @type {Y.AbstractType} */ parent; } return pos - 1; }; function yXmlFragmentToProsemirrorJSON(xmlFragment) { const items = xmlFragment.toArray(); function serialize(item) { let response; if (!item.nodeName) { const delta = item.toDelta(); response = delta.map((d) => { const text = { type: "text", text: d.insert }; if (d.attributes) { text.marks = Object.keys(d.attributes).map((type) => { const attrs = d.attributes[type]; const mark = { type }; if (Object.keys(attrs)) { mark.attrs = attrs; } return mark; }); } return text; }); } else { response = { type: item.nodeName }; const attrs = item.getAttributes(); if (Object.keys(attrs).length) { response.attrs = attrs; } const children = item.toArray(); if (children.length) { response.content = children.map(serialize).flat(); } } return response; } return { type: "doc", content: items.map(serialize) }; } // node_modules/y-prosemirror/src/plugins/undo-plugin.js var undo = (state) => { const undoManager = yUndoPluginKey.getState(state).undoManager; if (undoManager != null) { undoManager.undo(); return true; } }; var redo = (state) => { const undoManager = yUndoPluginKey.getState(state).undoManager; if (undoManager != null) { undoManager.redo(); return true; } }; var defaultProtectedNodes = /* @__PURE__ */ new Set(["paragraph"]); var defaultDeleteFilter = (item, protectedNodes) => !(item instanceof Item) || !(item.content instanceof ContentType) || !(item.content.type instanceof YText || item.content.type instanceof YXmlElement && protectedNodes.has(item.content.type.nodeName)) || item.content.type._length === 0; var yUndoPlugin = ({ protectedNodes = defaultProtectedNodes, trackedOrigins = [], undoManager = null } = {}) => new Plugin({ key: yUndoPluginKey, state: { init: (initargs, state) => { const ystate = ySyncPluginKey.getState(state); const _undoManager = undoManager || new UndoManager(ystate.type, { trackedOrigins: new Set([ySyncPluginKey].concat(trackedOrigins)), deleteFilter: (item) => defaultDeleteFilter(item, protectedNodes), captureTransaction: (tr) => tr.meta.get("addToHistory") !== false }); return { undoManager: _undoManager, prevSel: null, hasUndoOps: _undoManager.undoStack.length > 0, hasRedoOps: _undoManager.redoStack.length > 0 }; }, /** * @returns {any} */ apply: (tr, val, oldState, state) => { const binding = ySyncPluginKey.getState(state).binding; const undoManager2 = val.undoManager; const hasUndoOps = undoManager2.undoStack.length > 0; const hasRedoOps = undoManager2.redoStack.length > 0; if (binding) { return { undoManager: undoManager2, prevSel: getRelativeSelection(binding, oldState), hasUndoOps, hasRedoOps }; } else { if (hasUndoOps !== val.hasUndoOps || hasRedoOps !== val.hasRedoOps) { return Object.assign({}, val, { hasUndoOps: undoManager2.undoStack.length > 0, hasRedoOps: undoManager2.redoStack.length > 0 }); } else { return val; } } } }, view: (view) => { const ystate = ySyncPluginKey.getState(view.state); const undoManager2 = yUndoPluginKey.getState(view.state).undoManager; undoManager2.on("stack-item-added", ({ stackItem }) => { const binding = ystate.binding; if (binding) { stackItem.meta.set(binding, yUndoPluginKey.getState(view.state).prevSel); } }); undoManager2.on("stack-item-popped", ({ stackItem }) => { const binding = ystate.binding; if (binding) { binding.beforeTransactionSelection = stackItem.meta.get(binding) || binding.beforeTransactionSelection; } }); return { destroy: () => { undoManager2.destroy(); } }; } }); // node_modules/@tiptap/extension-collaboration/dist/index.js var Collaboration = Extension.create({ name: "collaboration", priority: 1e3, addOptions() { return { document: null, field: "default", fragment: null }; }, addStorage() { return { isDisabled: false }; }, onCreate() { if (this.editor.extensionManager.extensions.find((extension) => extension.name === "history")) { console.warn('[tiptap warn]: "@tiptap/extension-collaboration" comes with its own history support and is not compatible with "@tiptap/extension-history".'); } }, addCommands() { return { undo: () => ({ tr, state, dispatch }) => { tr.setMeta("preventDispatch", true); const undoManager = yUndoPluginKey.getState(state).undoManager; if (undoManager.undoStack.length === 0) { return false; } if (!dispatch) { return true; } return undo(state); }, redo: () => ({ tr, state, dispatch }) => { tr.setMeta("preventDispatch", true); const undoManager = yUndoPluginKey.getState(state).undoManager; if (undoManager.redoStack.length === 0) { return false; } if (!dispatch) { return true; } return redo(state); } }; }, addKeyboardShortcuts() { return { "Mod-z": () => this.editor.commands.undo(), "Mod-y": () => this.editor.commands.redo(), "Shift-Mod-z": () => this.editor.commands.redo() }; }, addProseMirrorPlugins() { var _a; const fragment = this.options.fragment ? this.options.fragment : this.options.document.getXmlFragment(this.options.field); const yUndoPluginInstance = yUndoPlugin(this.options.yUndoOptions); const originalUndoPluginView = yUndoPluginInstance.spec.view; yUndoPluginInstance.spec.view = (view) => { const { undoManager } = yUndoPluginKey.getState(view.state); if (undoManager.restore) { undoManager.restore(); undoManager.restore = () => { }; } const viewRet = originalUndoPluginView ? originalUndoPluginView(view) : void 0; return { destroy: () => { const hasUndoManSelf = undoManager.trackedOrigins.has(undoManager); const observers = undoManager._observers; undoManager.restore = () => { if (hasUndoManSelf) { undoManager.trackedOrigins.add(undoManager); } undoManager.doc.on("afterTransaction", undoManager.afterTransactionHandler); undoManager._observers = observers; }; if (viewRet === null || viewRet === void 0 ? void 0 : viewRet.destroy) { viewRet.destroy(); } } }; }; const ySyncPluginOptions = { ...this.options.ySyncOptions, onFirstRender: this.options.onFirstRender }; const ySyncPluginInstance = ySyncPlugin(fragment, ySyncPluginOptions); if (this.editor.options.enableContentCheck) { (_a = fragment.doc) === null || _a === void 0 ? void 0 : _a.on("beforeTransaction", () => { try { const jsonContent = yXmlFragmentToProsemirrorJSON(fragment); if (jsonContent.content.length === 0) { return; } this.editor.schema.nodeFromJSON(jsonContent).check(); } catch (error) { this.editor.emit("contentError", { error, editor: this.editor, disableCollaboration: () => { var _a2; (_a2 = fragment.doc) === null || _a2 === void 0 ? void 0 : _a2.destroy(); this.storage.isDisabled = true; } }); return false; } }); } return [ ySyncPluginInstance, yUndoPluginInstance, // Only add the filterInvalidContent plugin if content checking is enabled this.editor.options.enableContentCheck && new Plugin({ key: new PluginKey("filterInvalidContent"), filterTransaction: () => { var _a2; if (this.storage.isDisabled) { (_a2 = fragment.doc) === null || _a2 === void 0 ? void 0 : _a2.destroy(); return true; } return true; } }) ].filter(Boolean); } }); // node_modules/@tiptap/react/dist/index.js import React, { forwardRef, useState, useDebugValue, useLayoutEffect, useEffect, useRef, createContext, useContext } from "react"; import ReactDOM, { flushSync } from "react-dom"; var shim = { exports: {} }; var useSyncExternalStoreShim_production_min = {}; var hasRequiredUseSyncExternalStoreShim_production_min; function requireUseSyncExternalStoreShim_production_min() { if (hasRequiredUseSyncExternalStoreShim_production_min) return useSyncExternalStoreShim_production_min; hasRequiredUseSyncExternalStoreShim_production_min = 1; var e = React; function h(a, b) { return a === b && (0 !== a || 1 / a === 1 / b) || a !== a && b !== b; } var k = "function" === typeof Object.is ? Object.is : h, l = e.useState, m = e.useEffect, n = e.useLayoutEffect, p = e.useDebugValue; function q(a, b) { var d = b(), f = l({ inst: { value: d, getSnapshot: b } }), c = f[0].inst, g = f[1]; n(function() { c.value = d; c.getSnapshot = b; r(c) && g({ inst: c }); }, [a, d, b]); m(function() { r(c) && g({ inst: c }); return a(function() { r(c) && g({ inst: c }); }); }, [a]); p(d); return d; } function r(a) { var b = a.getSnapshot; a = a.value; try { var d = b(); return !k(a, d); } catch (f) { return true; } } function t(a, b) { return b(); } var u = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? t : q; useSyncExternalStoreShim_production_min.useSyncExternalStore = void 0 !== e.useSyncExternalStore ? e.useSyncExternalStore : u; return useSyncExternalStoreShim_production_min; } var useSyncExternalStoreShim_development = {}; var hasRequiredUseSyncExternalStoreShim_development; function requireUseSyncExternalStoreShim_development() { if (hasRequiredUseSyncExternalStoreShim_development) return useSyncExternalStoreShim_development; hasRequiredUseSyncExternalStoreShim_development = 1; if (process.env.NODE_ENV !== "production") { (function() { if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") { __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); } var React$1 = React; var ReactSharedInternals = React$1.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; function error(format) { { { for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { args[_key2 - 1] = arguments[_key2]; } printWarning("error", format, args); } } } function printWarning(level, format, args) { { var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; var stack = ReactDebugCurrentFrame.getStackAddendum(); if (stack !== "") { format += "%s"; args = args.concat([stack]); } var argsWithFormat = args.map(function(item) { return String(item); }); argsWithFormat.unshift("Warning: " + format); Function.prototype.apply.call(console[level], console, argsWithFormat); } } function is(x, y) { return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y; } var objectIs = typeof Object.is === "function" ? Object.is : is; var useState3 = React$1.useState, useEffect3 = React$1.useEffect, useLayoutEffect2 = React$1.useLayoutEffect, useDebugValue2 = React$1.useDebugValue; var didWarnOld18Alpha = false; var didWarnUncachedGetSnapshot = false; function useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { { if (!didWarnOld18Alpha) { if (React$1.startTransition !== void 0) { didWarnOld18Alpha = true; error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."); } } } var value = getSnapshot(); { if (!didWarnUncachedGetSnapshot) { var cachedValue = getSnapshot(); if (!objectIs(value, cachedValue)) { error("The result of getSnapshot should be cached to avoid an infinite loop"); didWarnUncachedGetSnapshot = true; } } } var _useState = useState3({ inst: { value, getSnapshot } }), inst = _useState[0].inst, forceUpdate = _useState[1]; useLayoutEffect2(function() { inst.value = value; inst.getSnapshot = getSnapshot; if (checkIfSnapshotChanged(inst)) { forceUpdate({ inst }); } }, [subscribe, value, getSnapshot]); useEffect3(function() { if (checkIfSnapshotChanged(inst)) { forceUpdate({ inst }); } var handleStoreChange = function() { if (checkIfSnapshotChanged(inst)) { forceUpdate({ inst }); } }; return subscribe(handleStoreChange); }, [subscribe]); useDebugValue2(value); return value; } function checkIfSnapshotChanged(inst) { var latestGetSnapshot = inst.getSnapshot; var prevValue = inst.value; try { var nextValue = latestGetSnapshot(); return !objectIs(prevValue, nextValue); } catch (error2) { return true; } } function useSyncExternalStore$1(subscribe, getSnapshot, getServerSnapshot) { return getSnapshot(); } var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined"); var isServerEnvironment = !canUseDOM; var shim2 = isServerEnvironment ? useSyncExternalStore$1 : useSyncExternalStore; var useSyncExternalStore$2 = React$1.useSyncExternalStore !== void 0 ? React$1.useSyncExternalStore : shim2; useSyncExternalStoreShim_development.useSyncExternalStore = useSyncExternalStore$2; if (typeof __REACT_DEVTOOL