@krainovsd/markdown-editor 0.2.0 → 0.3.1

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.
Files changed (26) hide show
  1. package/lib/cjs/{index-CDtGUxs-.js → index-DXevyHeZ.js} +2 -2
  2. package/lib/cjs/{index-CDtGUxs-.js.map → index-DXevyHeZ.js.map} +1 -1
  3. package/lib/cjs/{index-CiorogHq.js → index-nRNnOuav.js} +74 -42
  4. package/lib/cjs/index-nRNnOuav.js.map +1 -0
  5. package/lib/cjs/index.js +1 -1
  6. package/lib/esm/extensions/markdown/image/image-decoration.js +6 -2
  7. package/lib/esm/extensions/markdown/image/image-decoration.js.map +1 -1
  8. package/lib/esm/extensions/markdown/image/image-widget.js +25 -31
  9. package/lib/esm/extensions/markdown/image/image-widget.js.map +1 -1
  10. package/lib/esm/extensions/markdown/link/auto-link-decoration.js +3 -2
  11. package/lib/esm/extensions/markdown/link/auto-link-decoration.js.map +1 -1
  12. package/lib/esm/extensions/markdown/link/link-decoration.js +3 -2
  13. package/lib/esm/extensions/markdown/link/link-decoration.js.map +1 -1
  14. package/lib/esm/extensions/markdown/link/link-widget.js +4 -2
  15. package/lib/esm/extensions/markdown/link/link-widget.js.map +1 -1
  16. package/lib/esm/extensions/markdown/markdown-state.js +3 -0
  17. package/lib/esm/extensions/markdown/markdown-state.js.map +1 -1
  18. package/lib/esm/lib/utils/random-string.js +13 -0
  19. package/lib/esm/lib/utils/random-string.js.map +1 -0
  20. package/lib/esm/module/Editor/Editor.js +18 -0
  21. package/lib/esm/module/Editor/Editor.js.map +1 -1
  22. package/lib/esm/module/Editor/lib/init-editor.js +1 -1
  23. package/lib/esm/module/Editor/lib/init-editor.js.map +1 -1
  24. package/lib/index.d.ts +2 -0
  25. package/package.json +1 -1
  26. package/lib/cjs/index-CiorogHq.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"image-widget.js","sources":["../../../../../src/extensions/markdown/image/image-widget.ts"],"sourcesContent":["import { type EditorView, WidgetType } from \"@codemirror/view\";\nimport { saveDispatch } from \"@/lib/utils\";\nimport { openedImageEffect } from \"../markdown-state\";\nimport styles from \"../styles.module.scss\";\n\nconst INTERVAL_DELAY = 10000;\nconst IMAGE_NODES: Record<string, ImageElement | undefined> = {};\nconst EXISTING_WIDGETS: Set<string> = new Set();\nlet interval: NodeJS.Timeout | null = null;\n\ninterface ImageElement extends HTMLImageElement {\n clearListeners?: () => void;\n destroy?: () => void;\n}\n\nexport class ImageWidget extends WidgetType {\n constructor(\n private text: string,\n private link: string,\n private from: number,\n private to: number,\n private imageSrcGetter: ((src: string) => string) | undefined,\n private view: EditorView,\n ) {\n super();\n }\n\n get key() {\n return `${this.link}:${this.text}:${this.from}:${this.to}`;\n }\n\n get src() {\n return this.imageSrcGetter ? this.imageSrcGetter(this.link) : this.link;\n }\n\n eq(widget: ImageWidget): boolean {\n const image = IMAGE_NODES[this.key];\n\n if (!image) return false;\n\n delete IMAGE_NODES[this.key];\n EXISTING_WIDGETS.delete(this.key);\n\n if (image.src !== widget.src) image.src = widget.src;\n if (image.alt !== widget.text) image.alt = widget.text;\n\n this.link = widget.link;\n this.text = widget.text;\n this.from = widget.from;\n this.to = widget.to;\n\n this.registerListeners(image);\n IMAGE_NODES[this.key] = image;\n EXISTING_WIDGETS.add(this.key);\n\n return true;\n }\n\n updateDOM(): boolean {\n return true;\n }\n\n toDOM(): HTMLElement {\n EXISTING_WIDGETS.add(this.key);\n\n let image = IMAGE_NODES[this.key];\n if (image) {\n if (image.src !== this.src) {\n image.src = this.src;\n }\n if (image.alt !== this.text) image.alt = this.text;\n\n return image;\n }\n\n image = document.createElement(\"img\");\n image.classList.add(styles.image);\n image.alt = this.text;\n image.src = this.src;\n image.style.maxWidth = \"100%\";\n\n this.registerListeners(image);\n IMAGE_NODES[this.key] = image;\n\n if (!interval) interval = setInterval(garbageCollectorInterval, INTERVAL_DELAY);\n\n return image;\n }\n\n destroy(): void {\n EXISTING_WIDGETS.delete(this.key);\n }\n\n registerListeners(image: ImageElement) {\n image.clearListeners?.();\n const abortController = new AbortController();\n image.addEventListener(\n \"mousedown\",\n (event) => handleClick(this.view, this.text, this.link, this.key, event),\n { signal: abortController.signal },\n );\n image.clearListeners = () => {\n abortController.abort();\n };\n image.destroy = () => {\n image.clearListeners?.();\n image.remove();\n };\n }\n}\n\nfunction garbageCollectorInterval() {\n for (const [key, node] of Object.entries(IMAGE_NODES)) {\n if (EXISTING_WIDGETS.has(key) || !node) continue;\n\n delete IMAGE_NODES[key];\n node.destroy?.();\n }\n\n if (Object.keys(IMAGE_NODES).length === 0 && interval) {\n clearInterval(interval);\n interval = null;\n }\n}\n\n/** recursively find the link text node in line */\nfunction getTextNode(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): ChildNode | null {\n if (!line) return null;\n const textNodeContainer = getTextNodeContainer(text, link, key, line);\n if (!textNodeContainer) return null;\n\n for (const node of Array.from(textNodeContainer.childNodes)) {\n if (isCorrectNode(text, link, node)) {\n return node;\n }\n }\n\n return null;\n}\n\nfunction getTextNodeContainer(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): HTMLElement | null {\n if (!line) return null;\n\n for (const node of Array.from(line.childNodes)) {\n if (node instanceof HTMLElement && node.getAttribute(\"data-id\") === key) {\n return node;\n }\n\n if (node.nodeType !== 3) {\n const inner = getTextNodeContainer(text, link, key, node);\n if (inner) return inner;\n }\n }\n\n return null;\n}\n\nfunction isCorrectNode(\n text: string,\n link: string,\n node: ChildNode | Node | null | undefined,\n): node is ChildNode | Node {\n if (!node) return false;\n\n const textContent = node?.textContent;\n\n return Boolean(\n node &&\n textContent &&\n node.nodeType === 3 &&\n textContent.includes(link) &&\n textContent.includes(text),\n );\n}\n\ntype SelectLinkOptions = {\n node: ChildNode | Node;\n selection: Selection;\n start?: number;\n link: string;\n};\nfunction selectLink({ link, node, selection, start }: SelectLinkOptions) {\n const startPosition = start ?? (node.textContent?.indexOf?.(link) || 0);\n const endPosition = startPosition + link.length;\n\n const range = document.createRange();\n range.setStart(node, startPosition);\n range.setEnd(node, endPosition);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n\nfunction handleClick(\n view: EditorView | undefined,\n text: string,\n link: string,\n key: string,\n event: MouseEvent,\n) {\n const selection = window.getSelection();\n\n if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n const target = event.target as HTMLImageElement;\n const parent = target.parentNode;\n let line: HTMLElement | null = parent as HTMLElement | null;\n\n /** recursively find line that contains link */\n while (line && !line.classList.contains(\"cm-line\")) {\n line = line.parentNode as HTMLElement | null;\n }\n\n const editor = Array.from(document.querySelectorAll(\".cm-editor\")).find((element) =>\n element.contains(target),\n );\n\n if (!selection || !editor || !parent) return;\n\n const textNode = getTextNode(text, link, key, line);\n\n if (textNode) {\n return void selectLink({ selection, link, node: textNode });\n }\n\n saveDispatch(() => {\n if (!view) return;\n view.dispatch(view.state.update({ effects: openedImageEffect.of(key) }));\n\n const textNode = getTextNode(text, link, key, line);\n if (textNode) {\n selectLink({ selection, link, node: textNode });\n }\n\n requestAnimationFrame(() => {\n saveDispatch(() => {\n if (view) view.dispatch(view.state.update({ effects: openedImageEffect.of(undefined) }));\n });\n });\n });\n\n return false;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"image-widget.js","sources":["../../../../../src/extensions/markdown/image/image-widget.ts"],"sourcesContent":["import { type EditorView, WidgetType } from \"@codemirror/view\";\nimport { saveDispatch } from \"@/lib/utils\";\nimport { openedImageEffect } from \"../markdown-state\";\nimport styles from \"../styles.module.scss\";\n\nconst IMAGE_NODES: Record<string, ImageContainerElement | undefined> = {};\n\ninterface ImageContainerElement extends HTMLSpanElement {\n clearListeners?: () => void;\n destroy?: () => void;\n image?: HTMLImageElement;\n}\n\nexport class ImageWidget extends WidgetType {\n constructor(\n private text: string,\n private link: string,\n private from: number,\n private to: number,\n private uniqueId: string,\n private fullLine: boolean,\n private imageSrcGetter: ((src: string) => string) | undefined,\n private view: EditorView,\n ) {\n super();\n }\n\n get key() {\n return `${this.link}:${this.text}:${this.uniqueId}:${this.from}:${this.to}`;\n }\n\n get src() {\n return this.imageSrcGetter ? this.imageSrcGetter(this.link) : this.link;\n }\n\n eq(widget: ImageWidget): boolean {\n const container = IMAGE_NODES[this.key];\n const image = container?.image;\n\n if (!image) return false;\n\n delete IMAGE_NODES[this.key];\n\n if (image.src !== widget.src) image.src = widget.src;\n if (image.alt !== widget.text) image.alt = widget.text;\n\n this.link = widget.link;\n this.text = widget.text;\n this.from = widget.from;\n this.to = widget.to;\n\n this.registerListeners(image);\n IMAGE_NODES[this.key] = image;\n\n return true;\n }\n\n updateDOM(): boolean {\n return true;\n }\n\n toDOM(): HTMLElement {\n let container = IMAGE_NODES[this.key];\n let image = container?.image;\n\n if (image && container) {\n if (image.src !== this.src) {\n image.src = this.src;\n }\n if (image.alt !== this.text) image.alt = this.text;\n\n return container;\n }\n\n image = document.createElement(\"img\");\n image.classList.add(styles.image);\n image.alt = this.text;\n image.src = this.src;\n image.style.maxWidth = \"100%\";\n\n container = document.createElement(\"span\") as ImageContainerElement;\n container.appendChild(image);\n container.image = image;\n if (this.fullLine) {\n container.style.width = \"100%\";\n container.style.display = \"inline-block\";\n }\n\n this.registerListeners(container);\n IMAGE_NODES[this.key] = container;\n\n return container;\n }\n\n destroy(dom: ImageContainerElement): void {\n delete IMAGE_NODES[this.key];\n dom.destroy?.();\n }\n\n registerListeners(image: ImageContainerElement) {\n image.clearListeners?.();\n const abortController = new AbortController();\n image.addEventListener(\n \"mousedown\",\n (event) => handleClick(this.view, this.text, this.link, this.key, event),\n { signal: abortController.signal },\n );\n image.clearListeners = () => {\n abortController.abort();\n };\n image.destroy = () => {\n image.clearListeners?.();\n image.remove();\n };\n }\n}\n\n/** recursively find the link text node in line */\nfunction getTextNode(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): ChildNode | null {\n if (!line) return null;\n const textNodeContainer = getTextNodeContainer(text, link, key, line);\n if (!textNodeContainer) return null;\n\n for (const node of Array.from(textNodeContainer.childNodes)) {\n if (isCorrectNode(text, link, node)) {\n return node;\n }\n }\n\n return null;\n}\n\nfunction getTextNodeContainer(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): HTMLElement | null {\n if (!line) return null;\n\n for (const node of Array.from(line.childNodes)) {\n if (node instanceof HTMLElement && node.getAttribute(\"data-id\") === key) {\n return node;\n }\n\n if (node.nodeType !== 3) {\n const inner = getTextNodeContainer(text, link, key, node);\n if (inner) return inner;\n }\n }\n\n return null;\n}\n\nfunction isCorrectNode(\n text: string,\n link: string,\n node: ChildNode | Node | null | undefined,\n): node is ChildNode | Node {\n if (!node) return false;\n\n const textContent = node?.textContent;\n\n return Boolean(\n node &&\n textContent &&\n node.nodeType === 3 &&\n textContent.includes(link) &&\n textContent.includes(text),\n );\n}\n\ntype SelectLinkOptions = {\n node: ChildNode | Node;\n selection: Selection;\n start?: number;\n link: string;\n};\nfunction selectLink({ link, node, selection, start }: SelectLinkOptions) {\n const startPosition = start ?? (node.textContent?.indexOf?.(link) || 0);\n const endPosition = startPosition + link.length;\n\n const range = document.createRange();\n range.setStart(node, startPosition);\n range.setEnd(node, endPosition);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n\nfunction handleClick(\n view: EditorView | undefined,\n text: string,\n link: string,\n key: string,\n event: MouseEvent,\n) {\n const selection = window.getSelection();\n\n if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n const target = event.target as HTMLImageElement;\n const parent = target.parentNode;\n let line: HTMLElement | null = parent as HTMLElement | null;\n\n /** recursively find line that contains link */\n while (line && !line.classList.contains(\"cm-line\")) {\n line = line.parentNode as HTMLElement | null;\n }\n\n const editor = Array.from(document.querySelectorAll(\".cm-editor\")).find((element) =>\n element.contains(target),\n );\n\n if (!selection || !editor || !parent) return;\n\n const textNode = getTextNode(text, link, key, line);\n\n if (textNode) {\n return void selectLink({ selection, link, node: textNode });\n }\n\n saveDispatch(() => {\n if (!view) return;\n view.dispatch(view.state.update({ effects: openedImageEffect.of(key) }));\n\n const textNode = getTextNode(text, link, key, line);\n if (textNode) {\n selectLink({ selection, link, node: textNode });\n }\n\n requestAnimationFrame(() => {\n saveDispatch(() => {\n if (view) view.dispatch(view.state.update({ effects: openedImageEffect.of(undefined) }));\n });\n });\n });\n\n return false;\n}\n"],"names":[],"mappings":";;;;;AAKA,MAAM,WAAW,GAAsD,EAAE;AAQnE,MAAO,WAAY,SAAQ,UAAU,CAAA;AAE/B,IAAA,IAAA;AACA,IAAA,IAAA;AACA,IAAA,IAAA;AACA,IAAA,EAAA;AACA,IAAA,QAAA;AACA,IAAA,QAAA;AACA,IAAA,cAAA;AACA,IAAA,IAAA;AARV,IAAA,WAAA,CACU,IAAY,EACZ,IAAY,EACZ,IAAY,EACZ,EAAU,EACV,QAAgB,EAChB,QAAiB,EACjB,cAAqD,EACrD,IAAgB,EAAA;AAExB,QAAA,KAAK,EAAE;QATC,IAAI,CAAA,IAAA,GAAJ,IAAI;QACJ,IAAI,CAAA,IAAA,GAAJ,IAAI;QACJ,IAAI,CAAA,IAAA,GAAJ,IAAI;QACJ,IAAE,CAAA,EAAA,GAAF,EAAE;QACF,IAAQ,CAAA,QAAA,GAAR,QAAQ;QACR,IAAQ,CAAA,QAAA,GAAR,QAAQ;QACR,IAAc,CAAA,cAAA,GAAd,cAAc;QACd,IAAI,CAAA,IAAA,GAAJ,IAAI;;AAKd,IAAA,IAAI,GAAG,GAAA;QACL,OAAO,CAAA,EAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAI,CAAA,EAAA,IAAI,CAAC,QAAQ,CAAA,CAAA,EAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAA,CAAE;;AAG7E,IAAA,IAAI,GAAG,GAAA;QACL,OAAO,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI;;AAGzE,IAAA,EAAE,CAAC,MAAmB,EAAA;QACpB,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;AACvC,QAAA,MAAM,KAAK,GAAG,SAAS,EAAE,KAAK;AAE9B,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,KAAK;AAExB,QAAA,OAAO,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;AAE5B,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG;AAAE,YAAA,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG;AACpD,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,IAAI;AAAE,YAAA,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI;AAEtD,QAAA,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI;AACvB,QAAA,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI;AACvB,QAAA,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI;AACvB,QAAA,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE;AAEnB,QAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC;AAC7B,QAAA,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK;AAE7B,QAAA,OAAO,IAAI;;IAGb,SAAS,GAAA;AACP,QAAA,OAAO,IAAI;;IAGb,KAAK,GAAA;QACH,IAAI,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;AACrC,QAAA,IAAI,KAAK,GAAG,SAAS,EAAE,KAAK;AAE5B,QAAA,IAAI,KAAK,IAAI,SAAS,EAAE;YACtB,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,EAAE;AAC1B,gBAAA,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG;;AAEtB,YAAA,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,IAAI;AAAE,gBAAA,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI;AAElD,YAAA,OAAO,SAAS;;AAGlB,QAAA,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;QACrC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;AACjC,QAAA,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI;AACrB,QAAA,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG;AACpB,QAAA,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM;AAE7B,QAAA,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAA0B;AACnE,QAAA,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC;AAC5B,QAAA,SAAS,CAAC,KAAK,GAAG,KAAK;AACvB,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,YAAA,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM;AAC9B,YAAA,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG,cAAc;;AAG1C,QAAA,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC;AACjC,QAAA,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS;AAEjC,QAAA,OAAO,SAAS;;AAGlB,IAAA,OAAO,CAAC,GAA0B,EAAA;AAChC,QAAA,OAAO,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;AAC5B,QAAA,GAAG,CAAC,OAAO,IAAI;;AAGjB,IAAA,iBAAiB,CAAC,KAA4B,EAAA;AAC5C,QAAA,KAAK,CAAC,cAAc,IAAI;AACxB,QAAA,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE;AAC7C,QAAA,KAAK,CAAC,gBAAgB,CACpB,WAAW,EACX,CAAC,KAAK,KAAK,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,EACxE,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,CACnC;AACD,QAAA,KAAK,CAAC,cAAc,GAAG,MAAK;YAC1B,eAAe,CAAC,KAAK,EAAE;AACzB,SAAC;AACD,QAAA,KAAK,CAAC,OAAO,GAAG,MAAK;AACnB,YAAA,KAAK,CAAC,cAAc,IAAI;YACxB,KAAK,CAAC,MAAM,EAAE;AAChB,SAAC;;AAEJ;AAED;AACA,SAAS,WAAW,CAClB,IAAY,EACZ,IAAY,EACZ,GAAW,EACX,IAAyC,EAAA;AAEzC,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,IAAI;AACtB,IAAA,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC;AACrE,IAAA,IAAI,CAAC,iBAAiB;AAAE,QAAA,OAAO,IAAI;AAEnC,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE;QAC3D,IAAI,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;AACnC,YAAA,OAAO,IAAI;;;AAIf,IAAA,OAAO,IAAI;AACb;AAEA,SAAS,oBAAoB,CAC3B,IAAY,EACZ,IAAY,EACZ,GAAW,EACX,IAAyC,EAAA;AAEzC,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,IAAI;AAEtB,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;AAC9C,QAAA,IAAI,IAAI,YAAY,WAAW,IAAI,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE;AACvE,YAAA,OAAO,IAAI;;AAGb,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC,EAAE;AACvB,YAAA,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC;AACzD,YAAA,IAAI,KAAK;AAAE,gBAAA,OAAO,KAAK;;;AAI3B,IAAA,OAAO,IAAI;AACb;AAEA,SAAS,aAAa,CACpB,IAAY,EACZ,IAAY,EACZ,IAAyC,EAAA;AAEzC,IAAA,IAAI,CAAC,IAAI;AAAE,QAAA,OAAO,KAAK;AAEvB,IAAA,MAAM,WAAW,GAAG,IAAI,EAAE,WAAW;IAErC,OAAO,OAAO,CACZ,IAAI;QACF,WAAW;QACX,IAAI,CAAC,QAAQ,KAAK,CAAC;AACnB,QAAA,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC1B,QAAA,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAC7B;AACH;AAQA,SAAS,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAqB,EAAA;AACrE,IAAA,MAAM,aAAa,GAAG,KAAK,KAAK,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;AACvE,IAAA,MAAM,WAAW,GAAG,aAAa,GAAG,IAAI,CAAC,MAAM;AAE/C,IAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE;AACpC,IAAA,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;AACnC,IAAA,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC;IAC/B,SAAS,CAAC,eAAe,EAAE;AAC3B,IAAA,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC3B;AAEA,SAAS,WAAW,CAClB,IAA4B,EAC5B,IAAY,EACZ,IAAY,EACZ,GAAW,EACX,KAAiB,EAAA;AAEjB,IAAA,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE;AAEvC,IAAA,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE;QACpE;;IAGF,KAAK,CAAC,eAAe,EAAE;IACvB,KAAK,CAAC,cAAc,EAAE;AACtB,IAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAA0B;AAC/C,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU;IAChC,IAAI,IAAI,GAAuB,MAA4B;;AAG3D,IAAA,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;AAClD,QAAA,IAAI,GAAG,IAAI,CAAC,UAAgC;;AAG9C,IAAA,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,KAC9E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CACzB;AAED,IAAA,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM;QAAE;AAEtC,IAAA,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC;IAEnD,IAAI,QAAQ,EAAE;AACZ,QAAA,OAAO,KAAK,UAAU,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;;IAG7D,YAAY,CAAC,MAAK;AAChB,QAAA,IAAI,CAAC,IAAI;YAAE;QACX,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,iBAAiB,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAExE,QAAA,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC;QACnD,IAAI,QAAQ,EAAE;YACZ,UAAU,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;;QAGjD,qBAAqB,CAAC,MAAK;YACzB,YAAY,CAAC,MAAK;AAChB,gBAAA,IAAI,IAAI;oBAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,iBAAiB,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AAC1F,aAAC,CAAC;AACJ,SAAC,CAAC;AACJ,KAAC,CAAC;AAEF,IAAA,OAAO,KAAK;AACd;;;;"}
@@ -9,7 +9,8 @@ function getAutoLinkSelectionDecorations({ decorations, node, view, forceActive,
9
9
  return;
10
10
  const url = view.state.doc.sliceString(node.from + 1, node.to - 1);
11
11
  const openedLink = view.state.field(markdownState).openedLink;
12
- const key = `${url}:${url}:${node.from}:${node.to}`;
12
+ const uniqueId = view.state.field(markdownState).uniqueId;
13
+ const key = `${url}:${url}:${uniqueId}:${node.from}:${node.to}`;
13
14
  const isOpened = openedLink && openedLink === key;
14
15
  if (isOpened) {
15
16
  return void decorations.push(getMarkDecoration({
@@ -24,7 +25,7 @@ function getAutoLinkSelectionDecorations({ decorations, node, view, forceActive,
24
25
  !isInRange(view.state.selection.ranges, [node.from, node.to])) {
25
26
  decorations.push(getReplaceDecoration({
26
27
  range: [node.from, node.to],
27
- widget: new LinkWidget(url, url, node.from, node.to, view),
28
+ widget: new LinkWidget(url, url, node.from, node.to, uniqueId, view),
28
29
  }));
29
30
  }
30
31
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"auto-link-decoration.js","sources":["../../../../../src/extensions/markdown/link/auto-link-decoration.ts"],"sourcesContent":["import { utils } from \"@/lib\";\nimport { markdownState } from \"../markdown-state\";\nimport type { DecorationPlugin, GetSelectionDecorationOptions } from \"../markdown-types\";\nimport { NAME_OF_AUTO_LINK } from \"./link-constants\";\nimport { LinkWidget } from \"./link-widget\";\n\nfunction getAutoLinkSelectionDecorations({\n decorations,\n node,\n view,\n forceActive,\n}: GetSelectionDecorationOptions) {\n if (node.name !== NAME_OF_AUTO_LINK) return;\n\n const url = view.state.doc.sliceString(node.from + 1, node.to - 1);\n const openedLink = view.state.field(markdownState).openedLink;\n const key = `${url}:${url}:${node.from}:${node.to}`;\n const isOpened = openedLink && openedLink === key;\n\n if (isOpened) {\n return void decorations.push(\n utils.getMarkDecoration({\n range: [node.from, node.to],\n attributes: {\n \"data-id\": key,\n },\n }),\n );\n }\n\n if (\n forceActive ||\n !view.hasFocus ||\n !utils.isInRange(view.state.selection.ranges, [node.from, node.to])\n ) {\n decorations.push(\n utils.getReplaceDecoration({\n range: [node.from, node.to],\n widget: new LinkWidget(url, url, node.from, node.to, view),\n }),\n );\n } else {\n decorations.push(\n utils.getMarkDecoration({\n range: [node.from, node.to],\n attributes: {\n \"data-id\": key,\n },\n }),\n );\n }\n}\n\nexport const autoLinkDecorationPlugin: DecorationPlugin = {\n selectionDecorations: [getAutoLinkSelectionDecorations],\n};\n"],"names":["utils.getMarkDecoration","utils.isInRange","utils.getReplaceDecoration"],"mappings":";;;;;;AAMA,SAAS,+BAA+B,CAAC,EACvC,WAAW,EACX,IAAI,EACJ,IAAI,EACJ,WAAW,GACmB,EAAA;AAC9B,IAAA,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB;QAAE;IAErC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAClE,IAAA,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,UAAU;AAC7D,IAAA,MAAM,GAAG,GAAG,CAAG,EAAA,GAAG,IAAI,GAAG,CAAA,CAAA,EAAI,IAAI,CAAC,IAAI,CAAI,CAAA,EAAA,IAAI,CAAC,EAAE,EAAE;AACnD,IAAA,MAAM,QAAQ,GAAG,UAAU,IAAI,UAAU,KAAK,GAAG;IAEjD,IAAI,QAAQ,EAAE;QACZ,OAAO,KAAK,WAAW,CAAC,IAAI,CAC1BA,iBAAuB,CAAC;YACtB,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;AAC3B,YAAA,UAAU,EAAE;AACV,gBAAA,SAAS,EAAE,GAAG;AACf,aAAA;AACF,SAAA,CAAC,CACH;;AAGH,IAAA,IACE,WAAW;QACX,CAAC,IAAI,CAAC,QAAQ;QACd,CAACC,SAAe,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EACnE;AACA,QAAA,WAAW,CAAC,IAAI,CACdC,oBAA0B,CAAC;YACzB,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;AAC3B,YAAA,MAAM,EAAE,IAAI,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC;AAC3D,SAAA,CAAC,CACH;;SACI;AACL,QAAA,WAAW,CAAC,IAAI,CACdF,iBAAuB,CAAC;YACtB,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;AAC3B,YAAA,UAAU,EAAE;AACV,gBAAA,SAAS,EAAE,GAAG;AACf,aAAA;AACF,SAAA,CAAC,CACH;;AAEL;AAEa,MAAA,wBAAwB,GAAqB;IACxD,oBAAoB,EAAE,CAAC,+BAA+B,CAAC;;;;;"}
1
+ {"version":3,"file":"auto-link-decoration.js","sources":["../../../../../src/extensions/markdown/link/auto-link-decoration.ts"],"sourcesContent":["import { utils } from \"@/lib\";\nimport { markdownState } from \"../markdown-state\";\nimport type { DecorationPlugin, GetSelectionDecorationOptions } from \"../markdown-types\";\nimport { NAME_OF_AUTO_LINK } from \"./link-constants\";\nimport { LinkWidget } from \"./link-widget\";\n\nfunction getAutoLinkSelectionDecorations({\n decorations,\n node,\n view,\n forceActive,\n}: GetSelectionDecorationOptions) {\n if (node.name !== NAME_OF_AUTO_LINK) return;\n\n const url = view.state.doc.sliceString(node.from + 1, node.to - 1);\n const openedLink = view.state.field(markdownState).openedLink;\n const uniqueId = view.state.field(markdownState).uniqueId;\n const key = `${url}:${url}:${uniqueId}:${node.from}:${node.to}`;\n const isOpened = openedLink && openedLink === key;\n\n if (isOpened) {\n return void decorations.push(\n utils.getMarkDecoration({\n range: [node.from, node.to],\n attributes: {\n \"data-id\": key,\n },\n }),\n );\n }\n\n if (\n forceActive ||\n !view.hasFocus ||\n !utils.isInRange(view.state.selection.ranges, [node.from, node.to])\n ) {\n decorations.push(\n utils.getReplaceDecoration({\n range: [node.from, node.to],\n widget: new LinkWidget(url, url, node.from, node.to, uniqueId, view),\n }),\n );\n } else {\n decorations.push(\n utils.getMarkDecoration({\n range: [node.from, node.to],\n attributes: {\n \"data-id\": key,\n },\n }),\n );\n }\n}\n\nexport const autoLinkDecorationPlugin: DecorationPlugin = {\n selectionDecorations: [getAutoLinkSelectionDecorations],\n};\n"],"names":["utils.getMarkDecoration","utils.isInRange","utils.getReplaceDecoration"],"mappings":";;;;;;AAMA,SAAS,+BAA+B,CAAC,EACvC,WAAW,EACX,IAAI,EACJ,IAAI,EACJ,WAAW,GACmB,EAAA;AAC9B,IAAA,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB;QAAE;IAErC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAClE,IAAA,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,UAAU;AAC7D,IAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,QAAQ;AACzD,IAAA,MAAM,GAAG,GAAG,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,GAAG,CAAI,CAAA,EAAA,QAAQ,CAAI,CAAA,EAAA,IAAI,CAAC,IAAI,CAAA,CAAA,EAAI,IAAI,CAAC,EAAE,EAAE;AAC/D,IAAA,MAAM,QAAQ,GAAG,UAAU,IAAI,UAAU,KAAK,GAAG;IAEjD,IAAI,QAAQ,EAAE;QACZ,OAAO,KAAK,WAAW,CAAC,IAAI,CAC1BA,iBAAuB,CAAC;YACtB,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;AAC3B,YAAA,UAAU,EAAE;AACV,gBAAA,SAAS,EAAE,GAAG;AACf,aAAA;AACF,SAAA,CAAC,CACH;;AAGH,IAAA,IACE,WAAW;QACX,CAAC,IAAI,CAAC,QAAQ;QACd,CAACC,SAAe,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EACnE;AACA,QAAA,WAAW,CAAC,IAAI,CACdC,oBAA0B,CAAC;YACzB,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;AAC3B,YAAA,MAAM,EAAE,IAAI,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC;AACrE,SAAA,CAAC,CACH;;SACI;AACL,QAAA,WAAW,CAAC,IAAI,CACdF,iBAAuB,CAAC;YACtB,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;AAC3B,YAAA,UAAU,EAAE;AACV,gBAAA,SAAS,EAAE,GAAG;AACf,aAAA;AACF,SAAA,CAAC,CACH;;AAEL;AAEa,MAAA,wBAAwB,GAAqB;IACxD,oBAAoB,EAAE,CAAC,+BAA+B,CAAC;;;;;"}
@@ -36,7 +36,8 @@ function getLinkSelectionDecorations({ decorations, node, view, forceActive, })
36
36
  const text = content.substring(textCoordinates.from, textCoordinates.to);
37
37
  const url = content.substring(urlCoordinates.from, urlCoordinates.to);
38
38
  const openedLink = view.state.field(markdownState).openedLink;
39
- const key = `${url}:${text}:${node.from}:${node.to}`;
39
+ const uniqueId = view.state.field(markdownState).uniqueId;
40
+ const key = `${url}:${text}:${uniqueId}:${node.from}:${node.to}`;
40
41
  const isOpened = openedLink && openedLink === key;
41
42
  if (isOpened) {
42
43
  return void decorations.push(getMarkDecoration({
@@ -51,7 +52,7 @@ function getLinkSelectionDecorations({ decorations, node, view, forceActive, })
51
52
  !isInRange(view.state.selection.ranges, [node.from, node.to])) {
52
53
  decorations.push(getReplaceDecoration({
53
54
  range: [node.from, node.to],
54
- widget: new LinkWidget(text, url, node.from, node.to, view),
55
+ widget: new LinkWidget(text, url, node.from, node.to, uniqueId, view),
55
56
  }));
56
57
  }
57
58
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"link-decoration.js","sources":["../../../../../src/extensions/markdown/link/link-decoration.ts"],"sourcesContent":["import { utils } from \"@/lib\";\nimport { markdownState } from \"../markdown-state\";\nimport type { DecorationPlugin, GetSelectionDecorationOptions } from \"../markdown-types\";\nimport {\n CODE_OF_END_LINK_TEXT,\n CODE_OF_END_LINK_URL,\n CODE_OF_START_LINK_TEXT,\n CODE_OF_START_LINK_URL,\n NAME_OF_LINK,\n} from \"./link-constants\";\nimport { getLinkLabelSelectionDecoration } from \"./link-label-decoration\";\nimport { LinkWidget } from \"./link-widget\";\n\nfunction getLinkSelectionDecorations({\n decorations,\n node,\n view,\n forceActive,\n}: GetSelectionDecorationOptions) {\n if (node.name !== NAME_OF_LINK) {\n return;\n }\n\n const content = view.state.doc.sliceString(node.from, node.to);\n const textCoordinates = { from: -1, to: -1 };\n const urlCoordinates = { from: -1, to: -1 };\n let pos = -1;\n\n while (pos < content.length) {\n pos++;\n const code = content.charCodeAt(pos);\n\n if (textCoordinates.from === -1 && code === CODE_OF_START_LINK_TEXT)\n textCoordinates.from = pos + 1;\n else if (\n urlCoordinates.from === -1 &&\n textCoordinates.to !== -1 &&\n code === CODE_OF_START_LINK_URL\n )\n urlCoordinates.from = pos + 1;\n else if (\n textCoordinates.from !== -1 &&\n textCoordinates.to === -1 &&\n code === CODE_OF_END_LINK_TEXT\n )\n textCoordinates.to = pos;\n else if (\n urlCoordinates.from !== -1 &&\n urlCoordinates.to === -1 &&\n code === CODE_OF_END_LINK_URL\n )\n urlCoordinates.to = pos;\n }\n\n if (urlCoordinates.from === -1 || urlCoordinates.to === -1)\n return void getLinkLabelSelectionDecoration({ decorations, forceActive, node, view });\n\n const text = content.substring(textCoordinates.from, textCoordinates.to);\n const url = content.substring(urlCoordinates.from, urlCoordinates.to);\n\n const openedLink = view.state.field(markdownState).openedLink;\n const key = `${url}:${text}:${node.from}:${node.to}`;\n const isOpened = openedLink && openedLink === key;\n\n if (isOpened) {\n return void decorations.push(\n utils.getMarkDecoration({\n range: [node.from, node.to],\n attributes: {\n \"data-id\": key,\n },\n }),\n );\n }\n\n if (\n forceActive ||\n !view.hasFocus ||\n !utils.isInRange(view.state.selection.ranges, [node.from, node.to])\n ) {\n decorations.push(\n utils.getReplaceDecoration({\n range: [node.from, node.to],\n widget: new LinkWidget(text, url, node.from, node.to, view),\n }),\n );\n } else {\n decorations.push(\n utils.getMarkDecoration({\n range: [node.from, node.to],\n attributes: {\n \"data-id\": key,\n },\n }),\n );\n }\n}\n\nexport const linkDecorationPlugin: DecorationPlugin = {\n selectionDecorations: [getLinkSelectionDecorations],\n};\n"],"names":["utils.getMarkDecoration","utils.isInRange","utils.getReplaceDecoration"],"mappings":"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"}
1
+ {"version":3,"file":"link-decoration.js","sources":["../../../../../src/extensions/markdown/link/link-decoration.ts"],"sourcesContent":["import { utils } from \"@/lib\";\nimport { markdownState } from \"../markdown-state\";\nimport type { DecorationPlugin, GetSelectionDecorationOptions } from \"../markdown-types\";\nimport {\n CODE_OF_END_LINK_TEXT,\n CODE_OF_END_LINK_URL,\n CODE_OF_START_LINK_TEXT,\n CODE_OF_START_LINK_URL,\n NAME_OF_LINK,\n} from \"./link-constants\";\nimport { getLinkLabelSelectionDecoration } from \"./link-label-decoration\";\nimport { LinkWidget } from \"./link-widget\";\n\nfunction getLinkSelectionDecorations({\n decorations,\n node,\n view,\n forceActive,\n}: GetSelectionDecorationOptions) {\n if (node.name !== NAME_OF_LINK) {\n return;\n }\n\n const content = view.state.doc.sliceString(node.from, node.to);\n const textCoordinates = { from: -1, to: -1 };\n const urlCoordinates = { from: -1, to: -1 };\n let pos = -1;\n\n while (pos < content.length) {\n pos++;\n const code = content.charCodeAt(pos);\n\n if (textCoordinates.from === -1 && code === CODE_OF_START_LINK_TEXT)\n textCoordinates.from = pos + 1;\n else if (\n urlCoordinates.from === -1 &&\n textCoordinates.to !== -1 &&\n code === CODE_OF_START_LINK_URL\n )\n urlCoordinates.from = pos + 1;\n else if (\n textCoordinates.from !== -1 &&\n textCoordinates.to === -1 &&\n code === CODE_OF_END_LINK_TEXT\n )\n textCoordinates.to = pos;\n else if (\n urlCoordinates.from !== -1 &&\n urlCoordinates.to === -1 &&\n code === CODE_OF_END_LINK_URL\n )\n urlCoordinates.to = pos;\n }\n\n if (urlCoordinates.from === -1 || urlCoordinates.to === -1)\n return void getLinkLabelSelectionDecoration({ decorations, forceActive, node, view });\n\n const text = content.substring(textCoordinates.from, textCoordinates.to);\n const url = content.substring(urlCoordinates.from, urlCoordinates.to);\n\n const openedLink = view.state.field(markdownState).openedLink;\n const uniqueId = view.state.field(markdownState).uniqueId;\n const key = `${url}:${text}:${uniqueId}:${node.from}:${node.to}`;\n const isOpened = openedLink && openedLink === key;\n\n if (isOpened) {\n return void decorations.push(\n utils.getMarkDecoration({\n range: [node.from, node.to],\n attributes: {\n \"data-id\": key,\n },\n }),\n );\n }\n\n if (\n forceActive ||\n !view.hasFocus ||\n !utils.isInRange(view.state.selection.ranges, [node.from, node.to])\n ) {\n decorations.push(\n utils.getReplaceDecoration({\n range: [node.from, node.to],\n widget: new LinkWidget(text, url, node.from, node.to, uniqueId, view),\n }),\n );\n } else {\n decorations.push(\n utils.getMarkDecoration({\n range: [node.from, node.to],\n attributes: {\n \"data-id\": key,\n },\n }),\n );\n }\n}\n\nexport const linkDecorationPlugin: DecorationPlugin = {\n selectionDecorations: [getLinkSelectionDecorations],\n};\n"],"names":["utils.getMarkDecoration","utils.isInRange","utils.getReplaceDecoration"],"mappings":"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"}
@@ -13,17 +13,19 @@ class LinkWidget extends WidgetType {
13
13
  link;
14
14
  from;
15
15
  to;
16
+ uniqueId;
16
17
  view;
17
- constructor(text, link, from, to, view) {
18
+ constructor(text, link, from, to, uniqueId, view) {
18
19
  super();
19
20
  this.text = text;
20
21
  this.link = link;
21
22
  this.from = from;
22
23
  this.to = to;
24
+ this.uniqueId = uniqueId;
23
25
  this.view = view;
24
26
  }
25
27
  get key() {
26
- return `${this.link}:${this.text}:${this.from}:${this.to}`;
28
+ return `${this.link}:${this.text}:${this.uniqueId}:${this.from}:${this.to}`;
27
29
  }
28
30
  eq(widget) {
29
31
  const anchor = LINK_NODES[this.key];
@@ -1 +1 @@
1
- {"version":3,"file":"link-widget.js","sources":["../../../../../src/extensions/markdown/link/link-widget.ts"],"sourcesContent":["import { type EditorView, WidgetType } from \"@codemirror/view\";\nimport { CLASSES } from \"@/extensions/theme\";\nimport { saveDispatch } from \"@/lib/utils\";\nimport { openedLinkEffect } from \"../markdown-state\";\nimport styles from \"../styles.module.scss\";\n\nconst LINK_NODES: Record<string, AnchorElement | undefined> = {};\n\ninterface AnchorElement extends HTMLAnchorElement {\n clearListeners?: () => void;\n destroy?: () => void;\n}\nexport class LinkWidget extends WidgetType {\n constructor(\n private text: string,\n private link: string,\n private from: number,\n private to: number,\n private view: EditorView,\n ) {\n super();\n }\n\n get key() {\n return `${this.link}:${this.text}:${this.from}:${this.to}`;\n }\n\n eq(widget: LinkWidget): boolean {\n const anchor = LINK_NODES[this.key];\n if (!anchor) return false;\n delete LINK_NODES[this.key];\n\n if (anchor.href !== widget.link) anchor.href = widget.link;\n if (anchor.textContent !== widget.text) anchor.textContent = widget.text;\n\n this.link = widget.link;\n this.text = widget.text;\n this.from = widget.from;\n this.to = widget.to;\n\n this.registerListeners(anchor);\n LINK_NODES[this.key] = anchor;\n\n return true;\n }\n\n toDOM(): HTMLElement {\n const anchor = document.createElement(\"a\") as AnchorElement;\n anchor.classList.add(styles.link);\n anchor.classList.add(CLASSES.link);\n\n anchor.target = \"_blank\";\n anchor.textContent = this.text;\n anchor.href = this.link;\n\n this.registerListeners(anchor);\n\n LINK_NODES[this.key] = anchor;\n\n return anchor;\n }\n\n destroy(dom: AnchorElement): void {\n delete LINK_NODES[this.key];\n dom.destroy?.();\n }\n\n registerListeners(anchor: AnchorElement) {\n anchor.clearListeners?.();\n const abortController = new AbortController();\n anchor.addEventListener(\n \"mousedown\",\n (event) => handleClick(this.view, this.text, this.link, this.key, event),\n { signal: abortController.signal },\n );\n anchor.addEventListener(\"click\", (e) => e.preventDefault(), { signal: abortController.signal });\n anchor.clearListeners = () => {\n abortController.abort();\n };\n anchor.destroy = () => {\n anchor.clearListeners?.();\n anchor.remove();\n };\n }\n}\n\n/** recursively find the link text node in line */\nfunction getTextNode(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): ChildNode | null {\n if (!line) return null;\n const textNodeContainer = getTextNodeContainer(text, link, key, line);\n if (!textNodeContainer) return null;\n\n for (const node of Array.from(textNodeContainer.childNodes)) {\n if (isCorrectNode(text, link, node)) {\n return node;\n }\n }\n\n return null;\n}\n\nfunction getTextNodeContainer(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): HTMLElement | null {\n if (!line) return null;\n\n for (const node of Array.from(line.childNodes)) {\n if (node instanceof HTMLElement && node.getAttribute(\"data-id\") === key) {\n return node;\n }\n\n if (node.nodeType !== 3) {\n const inner = getTextNodeContainer(text, link, key, node);\n if (inner) return inner;\n }\n }\n\n return null;\n}\n\nfunction isCorrectNode(\n text: string,\n link: string,\n node: ChildNode | Node | null | undefined,\n): node is ChildNode | Node {\n if (!node) return false;\n\n const textContent = node?.textContent;\n\n return Boolean(\n node &&\n textContent &&\n node.nodeType === 3 &&\n textContent.includes(link) &&\n textContent.includes(text),\n );\n}\n\ntype SelectLinkOptions = {\n node: ChildNode | Node;\n selection: Selection;\n start?: number;\n link: string;\n};\nfunction selectLink({ link, node, selection, start }: SelectLinkOptions) {\n const startPosition = start ?? (node.textContent?.indexOf?.(link) || 0);\n const endPosition = startPosition + link.length;\n\n const range = document.createRange();\n range.setStart(node, startPosition);\n range.setEnd(node, endPosition);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n\nfunction handleClick(view: EditorView, text: string, link: string, key: string, event: MouseEvent) {\n /** open the link if has special key or the view is readonly */\n const contentEditable = view.contentDOM.getAttribute(\"contenteditable\");\n const forceActive = !contentEditable || contentEditable === \"false\";\n\n if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey || forceActive) {\n if (event.type === \"mousedown\") {\n const target = event.target as HTMLAnchorElement;\n window.open(target.href, \"_blank\");\n }\n\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n const target = event.target as HTMLImageElement;\n const parent = target.parentNode;\n let line: HTMLElement | null = parent as HTMLElement | null;\n\n /** recursively find line that contains link */\n while (line && !line.classList.contains(\"cm-line\")) {\n line = line.parentNode as HTMLElement | null;\n }\n\n const editor = Array.from(document.querySelectorAll(\".cm-editor\")).find((element) =>\n element.contains(target),\n );\n const selection = window.getSelection();\n\n if (!selection || !editor || !parent) return;\n\n const textNode = getTextNode(text, link, key, line);\n\n if (textNode) {\n return void selectLink({ selection, link, node: textNode });\n }\n\n saveDispatch(() => {\n if (!view) return;\n\n view.dispatch(view.state.update({ effects: openedLinkEffect.of(key) }));\n\n const textNode = getTextNode(text, link, key, line);\n if (textNode) {\n selectLink({ selection, link, node: textNode });\n }\n\n requestAnimationFrame(() => {\n saveDispatch(() => {\n if (view) view.dispatch(view.state.update({ effects: openedLinkEffect.of(undefined) }));\n });\n });\n });\n\n return false;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"link-widget.js","sources":["../../../../../src/extensions/markdown/link/link-widget.ts"],"sourcesContent":["import { type EditorView, WidgetType } from \"@codemirror/view\";\nimport { CLASSES } from \"@/extensions/theme\";\nimport { saveDispatch } from \"@/lib/utils\";\nimport { openedLinkEffect } from \"../markdown-state\";\nimport styles from \"../styles.module.scss\";\n\nconst LINK_NODES: Record<string, AnchorElement | undefined> = {};\n\ninterface AnchorElement extends HTMLAnchorElement {\n clearListeners?: () => void;\n destroy?: () => void;\n}\nexport class LinkWidget extends WidgetType {\n constructor(\n private text: string,\n private link: string,\n private from: number,\n private to: number,\n private uniqueId: string,\n private view: EditorView,\n ) {\n super();\n }\n\n get key() {\n return `${this.link}:${this.text}:${this.uniqueId}:${this.from}:${this.to}`;\n }\n\n eq(widget: LinkWidget): boolean {\n const anchor = LINK_NODES[this.key];\n if (!anchor) return false;\n delete LINK_NODES[this.key];\n\n if (anchor.href !== widget.link) anchor.href = widget.link;\n if (anchor.textContent !== widget.text) anchor.textContent = widget.text;\n\n this.link = widget.link;\n this.text = widget.text;\n this.from = widget.from;\n this.to = widget.to;\n\n this.registerListeners(anchor);\n LINK_NODES[this.key] = anchor;\n\n return true;\n }\n\n toDOM(): HTMLElement {\n const anchor = document.createElement(\"a\") as AnchorElement;\n anchor.classList.add(styles.link);\n anchor.classList.add(CLASSES.link);\n\n anchor.target = \"_blank\";\n anchor.textContent = this.text;\n anchor.href = this.link;\n\n this.registerListeners(anchor);\n\n LINK_NODES[this.key] = anchor;\n\n return anchor;\n }\n\n destroy(dom: AnchorElement): void {\n delete LINK_NODES[this.key];\n dom.destroy?.();\n }\n\n registerListeners(anchor: AnchorElement) {\n anchor.clearListeners?.();\n const abortController = new AbortController();\n anchor.addEventListener(\n \"mousedown\",\n (event) => handleClick(this.view, this.text, this.link, this.key, event),\n { signal: abortController.signal },\n );\n anchor.addEventListener(\"click\", (e) => e.preventDefault(), { signal: abortController.signal });\n anchor.clearListeners = () => {\n abortController.abort();\n };\n anchor.destroy = () => {\n anchor.clearListeners?.();\n anchor.remove();\n };\n }\n}\n\n/** recursively find the link text node in line */\nfunction getTextNode(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): ChildNode | null {\n if (!line) return null;\n const textNodeContainer = getTextNodeContainer(text, link, key, line);\n if (!textNodeContainer) return null;\n\n for (const node of Array.from(textNodeContainer.childNodes)) {\n if (isCorrectNode(text, link, node)) {\n return node;\n }\n }\n\n return null;\n}\n\nfunction getTextNodeContainer(\n text: string,\n link: string,\n key: string,\n line: ChildNode | Node | null | undefined,\n): HTMLElement | null {\n if (!line) return null;\n\n for (const node of Array.from(line.childNodes)) {\n if (node instanceof HTMLElement && node.getAttribute(\"data-id\") === key) {\n return node;\n }\n\n if (node.nodeType !== 3) {\n const inner = getTextNodeContainer(text, link, key, node);\n if (inner) return inner;\n }\n }\n\n return null;\n}\n\nfunction isCorrectNode(\n text: string,\n link: string,\n node: ChildNode | Node | null | undefined,\n): node is ChildNode | Node {\n if (!node) return false;\n\n const textContent = node?.textContent;\n\n return Boolean(\n node &&\n textContent &&\n node.nodeType === 3 &&\n textContent.includes(link) &&\n textContent.includes(text),\n );\n}\n\ntype SelectLinkOptions = {\n node: ChildNode | Node;\n selection: Selection;\n start?: number;\n link: string;\n};\nfunction selectLink({ link, node, selection, start }: SelectLinkOptions) {\n const startPosition = start ?? (node.textContent?.indexOf?.(link) || 0);\n const endPosition = startPosition + link.length;\n\n const range = document.createRange();\n range.setStart(node, startPosition);\n range.setEnd(node, endPosition);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n\nfunction handleClick(view: EditorView, text: string, link: string, key: string, event: MouseEvent) {\n /** open the link if has special key or the view is readonly */\n const contentEditable = view.contentDOM.getAttribute(\"contenteditable\");\n const forceActive = !contentEditable || contentEditable === \"false\";\n\n if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey || forceActive) {\n if (event.type === \"mousedown\") {\n const target = event.target as HTMLAnchorElement;\n window.open(target.href, \"_blank\");\n }\n\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n const target = event.target as HTMLImageElement;\n const parent = target.parentNode;\n let line: HTMLElement | null = parent as HTMLElement | null;\n\n /** recursively find line that contains link */\n while (line && !line.classList.contains(\"cm-line\")) {\n line = line.parentNode as HTMLElement | null;\n }\n\n const editor = Array.from(document.querySelectorAll(\".cm-editor\")).find((element) =>\n element.contains(target),\n );\n const selection = window.getSelection();\n\n if (!selection || !editor || !parent) return;\n\n const textNode = getTextNode(text, link, key, line);\n\n if (textNode) {\n return void selectLink({ selection, link, node: textNode });\n }\n\n saveDispatch(() => {\n if (!view) return;\n\n view.dispatch(view.state.update({ effects: openedLinkEffect.of(key) }));\n\n const textNode = getTextNode(text, link, key, line);\n if (textNode) {\n selectLink({ selection, link, node: textNode });\n }\n\n requestAnimationFrame(() => {\n saveDispatch(() => {\n if (view) view.dispatch(view.state.update({ effects: openedLinkEffect.of(undefined) }));\n });\n });\n });\n\n return false;\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  import { StateEffect, StateField } from '@codemirror/state';
2
+ import '@codemirror/view';
3
+ import { randomString } from '../../lib/utils/random-string.js';
2
4
 
3
5
  const openedImageEffect = StateEffect.define();
4
6
  const openedLinkEffect = StateEffect.define();
@@ -9,6 +11,7 @@ const markdownState = StateField.define({
9
11
  openedImage: undefined,
10
12
  imageSrcGetter: undefined,
11
13
  openedLink: undefined,
14
+ uniqueId: randomString(10),
12
15
  };
13
16
  },
14
17
  update(value, transaction) {
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-state.js","sources":["../../../../src/extensions/markdown/markdown-state.ts"],"sourcesContent":["import { StateEffect, StateField } from \"@codemirror/state\";\nimport type { MarkdownState } from \"./markdown-types\";\n\nexport const openedImageEffect = StateEffect.define<string | undefined>();\nexport const openedLinkEffect = StateEffect.define<string | undefined>();\nexport const imageSrcGetterEffect = StateEffect.define<((src: string) => string) | undefined>();\n\nexport const markdownState = StateField.define<MarkdownState>({\n create() {\n return {\n openedImage: undefined,\n imageSrcGetter: undefined,\n openedLink: undefined,\n };\n },\n\n update(value, transaction) {\n const newValue = { ...value };\n\n for (const effect of transaction.effects) {\n if (effect.is(openedImageEffect)) newValue.openedImage = effect.value;\n if (effect.is(imageSrcGetterEffect)) newValue.imageSrcGetter = effect.value;\n if (effect.is(openedLinkEffect)) newValue.openedLink = effect.value;\n }\n\n return newValue;\n },\n});\n"],"names":[],"mappings":";;MAGa,iBAAiB,GAAG,WAAW,CAAC,MAAM;MACtC,gBAAgB,GAAG,WAAW,CAAC,MAAM;MACrC,oBAAoB,GAAG,WAAW,CAAC,MAAM;AAEzC,MAAA,aAAa,GAAG,UAAU,CAAC,MAAM,CAAgB;IAC5D,MAAM,GAAA;QACJ,OAAO;AACL,YAAA,WAAW,EAAE,SAAS;AACtB,YAAA,cAAc,EAAE,SAAS;AACzB,YAAA,UAAU,EAAE,SAAS;SACtB;KACF;IAED,MAAM,CAAC,KAAK,EAAE,WAAW,EAAA;AACvB,QAAA,MAAM,QAAQ,GAAG,EAAE,GAAG,KAAK,EAAE;AAE7B,QAAA,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE;AACxC,YAAA,IAAI,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC;AAAE,gBAAA,QAAQ,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK;AACrE,YAAA,IAAI,MAAM,CAAC,EAAE,CAAC,oBAAoB,CAAC;AAAE,gBAAA,QAAQ,CAAC,cAAc,GAAG,MAAM,CAAC,KAAK;AAC3E,YAAA,IAAI,MAAM,CAAC,EAAE,CAAC,gBAAgB,CAAC;AAAE,gBAAA,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK;;AAGrE,QAAA,OAAO,QAAQ;KAChB;AACF,CAAA;;;;"}
1
+ {"version":3,"file":"markdown-state.js","sources":["../../../../src/extensions/markdown/markdown-state.ts"],"sourcesContent":["import { StateEffect, StateField } from \"@codemirror/state\";\nimport { randomString } from \"@/lib/utils\";\nimport type { MarkdownState } from \"./markdown-types\";\n\nexport const openedImageEffect = StateEffect.define<string | undefined>();\nexport const openedLinkEffect = StateEffect.define<string | undefined>();\nexport const imageSrcGetterEffect = StateEffect.define<((src: string) => string) | undefined>();\n\nexport const markdownState = StateField.define<MarkdownState>({\n create() {\n return {\n openedImage: undefined,\n imageSrcGetter: undefined,\n openedLink: undefined,\n uniqueId: randomString(10),\n };\n },\n\n update(value, transaction) {\n const newValue = { ...value };\n\n for (const effect of transaction.effects) {\n if (effect.is(openedImageEffect)) newValue.openedImage = effect.value;\n if (effect.is(imageSrcGetterEffect)) newValue.imageSrcGetter = effect.value;\n if (effect.is(openedLinkEffect)) newValue.openedLink = effect.value;\n }\n\n return newValue;\n },\n});\n"],"names":[],"mappings":";;;;MAIa,iBAAiB,GAAG,WAAW,CAAC,MAAM;MACtC,gBAAgB,GAAG,WAAW,CAAC,MAAM;MACrC,oBAAoB,GAAG,WAAW,CAAC,MAAM;AAEzC,MAAA,aAAa,GAAG,UAAU,CAAC,MAAM,CAAgB;IAC5D,MAAM,GAAA;QACJ,OAAO;AACL,YAAA,WAAW,EAAE,SAAS;AACtB,YAAA,cAAc,EAAE,SAAS;AACzB,YAAA,UAAU,EAAE,SAAS;AACrB,YAAA,QAAQ,EAAE,YAAY,CAAC,EAAE,CAAC;SAC3B;KACF;IAED,MAAM,CAAC,KAAK,EAAE,WAAW,EAAA;AACvB,QAAA,MAAM,QAAQ,GAAG,EAAE,GAAG,KAAK,EAAE;AAE7B,QAAA,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE;AACxC,YAAA,IAAI,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC;AAAE,gBAAA,QAAQ,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK;AACrE,YAAA,IAAI,MAAM,CAAC,EAAE,CAAC,oBAAoB,CAAC;AAAE,gBAAA,QAAQ,CAAC,cAAc,GAAG,MAAM,CAAC,KAAK;AAC3E,YAAA,IAAI,MAAM,CAAC,EAAE,CAAC,gBAAgB,CAAC;AAAE,gBAAA,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK;;AAGrE,QAAA,OAAO,QAAQ;KAChB;AACF,CAAA;;;;"}
@@ -0,0 +1,13 @@
1
+ function randomString(length = 10) {
2
+ const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
3
+ let result = "";
4
+ let counter = 0;
5
+ while (counter < length) {
6
+ result += characters.charAt(Math.floor(Math.random() * characters.length));
7
+ counter += 1;
8
+ }
9
+ return result;
10
+ }
11
+
12
+ export { randomString };
13
+ //# sourceMappingURL=random-string.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random-string.js","sources":["../../../../src/lib/utils/random-string.ts"],"sourcesContent":["export function randomString(length: number = 10) {\n const characters = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n let result = \"\";\n let counter = 0;\n\n while (counter < length) {\n result += characters.charAt(Math.floor(Math.random() * characters.length));\n counter += 1;\n }\n\n return result;\n}\n"],"names":[],"mappings":"AAAgB,SAAA,YAAY,CAAC,MAAA,GAAiB,EAAE,EAAA;IAC9C,MAAM,UAAU,GAAG,gEAAgE;IACnF,IAAI,MAAM,GAAG,EAAE;IACf,IAAI,OAAO,GAAG,CAAC;AAEf,IAAA,OAAO,OAAO,GAAG,MAAM,EAAE;AACvB,QAAA,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QAC1E,OAAO,IAAI,CAAC;;AAGd,IAAA,OAAO,MAAM;AACf;;;;"}
@@ -14,10 +14,12 @@ class Editor {
14
14
  view;
15
15
  provider;
16
16
  arguments;
17
+ yText;
17
18
  constructor(options) {
18
19
  void initEditor(options).then((editor) => {
19
20
  this.view = editor.view;
20
21
  this.provider = editor.provider;
22
+ this.yText = editor.multiCursorText;
21
23
  });
22
24
  this.arguments = options;
23
25
  }
@@ -50,6 +52,22 @@ class Editor {
50
52
  this.view.dispatch(transaction);
51
53
  });
52
54
  };
55
+ replaceContent = (content) => {
56
+ // if (!this.yText) return;
57
+ // this.yText.delete(0, this.yText.length);
58
+ // this.yText.insert(0, content);
59
+ // return;
60
+ if (!this.view)
61
+ return;
62
+ const transaction = this.view.state.update({
63
+ changes: { from: 0, to: this.view.state.doc.length, insert: content },
64
+ });
65
+ saveDispatch(() => {
66
+ if (!this.view)
67
+ return;
68
+ this.view.dispatch(transaction);
69
+ });
70
+ };
53
71
  setReadonly = (readonly) => {
54
72
  saveDispatch(() => {
55
73
  if (!this.view)
@@ -1 +1 @@
1
- {"version":3,"file":"Editor.js","sources":["../../../../src/module/Editor/Editor.ts"],"sourcesContent":["import { EditorView, drawSelection } from \"@codemirror/view\";\nimport type { WebsocketProvider } from \"y-websocket\";\nimport {\n type EditorTheme,\n ReadonlyCompartment,\n ThemeCompartment,\n VimModeCompartment,\n getDarkTheme,\n getLightTheme,\n} from \"@/extensions\";\nimport { saveDispatch } from \"@/lib/utils\";\nimport { type EditorArguments } from \"./Editor.types\";\nimport { initEditor } from \"./lib\";\n\nexport class Editor {\n view: EditorView | undefined;\n\n provider: WebsocketProvider | undefined;\n\n arguments: EditorArguments;\n\n constructor(options: EditorArguments) {\n void initEditor(options).then((editor) => {\n this.view = editor.view;\n this.provider = editor.provider;\n });\n\n this.arguments = options;\n }\n\n focus = () => {\n if (!this.view) return;\n\n this.view.focus();\n };\n\n getContent = () => {\n if (!this.view) return;\n\n return this.view.state.doc.toString();\n };\n\n setContent = (content: string, position?: number) => {\n if (!this.view) return;\n\n if (position == undefined) {\n const cursor = this.view.state.selection.main.head;\n position = cursor;\n }\n\n const transaction = this.view.state.update({\n changes: {\n from: position,\n insert: content,\n },\n });\n saveDispatch(() => {\n if (!this.view) return;\n\n this.view.dispatch(transaction);\n });\n };\n\n setReadonly = (readonly: boolean) => {\n saveDispatch(() => {\n if (!this.view) return;\n this.view.dispatch({\n effects: ReadonlyCompartment.reconfigure(EditorView.editable.of(!readonly)),\n });\n });\n };\n\n setTheme = (theme?: EditorTheme) => {\n saveDispatch(() => {\n if (!this.view) return;\n this.view.dispatch({\n effects: ThemeCompartment.reconfigure(\n theme === \"dark\"\n ? getDarkTheme({\n dark: this.arguments.dark,\n light: this.arguments.light,\n theme,\n })\n : getLightTheme({\n dark: this.arguments.dark,\n light: this.arguments.light,\n theme,\n }),\n ),\n });\n });\n };\n\n setVimMode = async (mode: boolean) => {\n if (!this.view) return;\n\n const { vim } = await import(\"@replit/codemirror-vim\");\n\n saveDispatch(() => {\n if (!this.view) return;\n this.view.dispatch({\n effects: VimModeCompartment.reconfigure(\n mode ? [vim({ status: true }), drawSelection()] : [],\n ),\n });\n });\n };\n\n setUserProvider = (name: string = \"Anonymous\", color: string = \"#000000\") => {\n if (!this.provider) return;\n\n this.provider.awareness.setLocalStateField(\"user\", { name, color });\n };\n\n destroy = () => {\n saveDispatch(() => {\n if (!this.view) return;\n this.view.destroy();\n });\n saveDispatch(() => {\n if (this.provider) this.provider.destroy();\n });\n };\n}\n\nexport type EditorInterface = typeof Editor;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Editor.js","sources":["../../../../src/module/Editor/Editor.ts"],"sourcesContent":["import { EditorView, drawSelection } from \"@codemirror/view\";\nimport type { WebsocketProvider } from \"y-websocket\";\nimport type { Text } from \"yjs\";\nimport {\n type EditorTheme,\n ReadonlyCompartment,\n ThemeCompartment,\n VimModeCompartment,\n getDarkTheme,\n getLightTheme,\n} from \"@/extensions\";\nimport { saveDispatch } from \"@/lib/utils\";\nimport { type EditorArguments } from \"./Editor.types\";\nimport { initEditor } from \"./lib\";\n\nexport class Editor {\n view: EditorView | undefined;\n\n provider: WebsocketProvider | undefined;\n\n arguments: EditorArguments;\n\n yText: Text | undefined;\n\n constructor(options: EditorArguments) {\n void initEditor(options).then((editor) => {\n this.view = editor.view;\n this.provider = editor.provider;\n this.yText = editor.multiCursorText;\n });\n\n this.arguments = options;\n }\n\n focus = () => {\n if (!this.view) return;\n\n this.view.focus();\n };\n\n getContent = () => {\n if (!this.view) return;\n\n return this.view.state.doc.toString();\n };\n\n setContent = (content: string, position?: number) => {\n if (!this.view) return;\n\n if (position == undefined) {\n const cursor = this.view.state.selection.main.head;\n position = cursor;\n }\n\n const transaction = this.view.state.update({\n changes: {\n from: position,\n insert: content,\n },\n });\n saveDispatch(() => {\n if (!this.view) return;\n\n this.view.dispatch(transaction);\n });\n };\n\n replaceContent = (content: string) => {\n // if (!this.yText) return;\n\n // this.yText.delete(0, this.yText.length);\n // this.yText.insert(0, content);\n\n // return;\n\n if (!this.view) return;\n\n const transaction = this.view.state.update({\n changes: { from: 0, to: this.view.state.doc.length, insert: content },\n });\n saveDispatch(() => {\n if (!this.view) return;\n\n this.view.dispatch(transaction);\n });\n };\n\n setReadonly = (readonly: boolean) => {\n saveDispatch(() => {\n if (!this.view) return;\n this.view.dispatch({\n effects: ReadonlyCompartment.reconfigure(EditorView.editable.of(!readonly)),\n });\n });\n };\n\n setTheme = (theme?: EditorTheme) => {\n saveDispatch(() => {\n if (!this.view) return;\n this.view.dispatch({\n effects: ThemeCompartment.reconfigure(\n theme === \"dark\"\n ? getDarkTheme({\n dark: this.arguments.dark,\n light: this.arguments.light,\n theme,\n })\n : getLightTheme({\n dark: this.arguments.dark,\n light: this.arguments.light,\n theme,\n }),\n ),\n });\n });\n };\n\n setVimMode = async (mode: boolean) => {\n if (!this.view) return;\n\n const { vim } = await import(\"@replit/codemirror-vim\");\n\n saveDispatch(() => {\n if (!this.view) return;\n this.view.dispatch({\n effects: VimModeCompartment.reconfigure(\n mode ? [vim({ status: true }), drawSelection()] : [],\n ),\n });\n });\n };\n\n setUserProvider = (name: string = \"Anonymous\", color: string = \"#000000\") => {\n if (!this.provider) return;\n\n this.provider.awareness.setLocalStateField(\"user\", { name, color });\n };\n\n destroy = () => {\n saveDispatch(() => {\n if (!this.view) return;\n this.view.destroy();\n });\n saveDispatch(() => {\n if (this.provider) this.provider.destroy();\n });\n };\n}\n\nexport type EditorInterface = typeof Editor;\n"],"names":[],"mappings":"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"}
@@ -21,7 +21,7 @@ async function initEditor({ multiCursor, root, initialText, ...rest }) {
21
21
  state,
22
22
  parent: root,
23
23
  });
24
- return { view, provider };
24
+ return { view, provider, multiCursorText };
25
25
  }
26
26
 
27
27
  export { initEditor };
@@ -1 +1 @@
1
- {"version":3,"file":"init-editor.js","sources":["../../../../../src/module/Editor/lib/init-editor.ts"],"sourcesContent":["import { EditorView } from \"@codemirror/view\";\nimport { type WebsocketProvider } from \"y-websocket\";\nimport type { Text } from \"yjs\";\nimport type { EditorArguments } from \"../Editor.types\";\nimport { initEditorProvider } from \"./init-editor-provider\";\nimport { initEditorState } from \"./init-editor-state\";\n\nexport async function initEditor({ multiCursor, root, initialText, ...rest }: EditorArguments) {\n let provider: WebsocketProvider | undefined;\n let multiCursorText: Text | undefined;\n\n if (multiCursor) {\n const editorProvider = await initEditorProvider({ ...multiCursor, initialText });\n provider = editorProvider.provider;\n multiCursorText = editorProvider.multiCursorText;\n }\n\n const state = await initEditorState({\n ...rest,\n text: initialText || \"\",\n provider,\n multiCursorText,\n });\n const view = new EditorView({\n state,\n parent: root,\n });\n\n return { view, provider };\n}\n"],"names":[],"mappings":";;;;;AAOO,eAAe,UAAU,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,IAAI,EAAmB,EAAA;AAC3F,IAAA,IAAI,QAAuC;AAC3C,IAAA,IAAI,eAAiC;IAErC,IAAI,WAAW,EAAE;AACf,QAAA,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,EAAE,GAAG,WAAW,EAAE,WAAW,EAAE,CAAC;AAChF,QAAA,QAAQ,GAAG,cAAc,CAAC,QAAQ;AAClC,QAAA,eAAe,GAAG,cAAc,CAAC,eAAe;;AAGlD,IAAA,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC;AAClC,QAAA,GAAG,IAAI;QACP,IAAI,EAAE,WAAW,IAAI,EAAE;QACvB,QAAQ;QACR,eAAe;AAChB,KAAA,CAAC;AACF,IAAA,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC;QAC1B,KAAK;AACL,QAAA,MAAM,EAAE,IAAI;AACb,KAAA,CAAC;AAEF,IAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE;AAC3B;;;;"}
1
+ {"version":3,"file":"init-editor.js","sources":["../../../../../src/module/Editor/lib/init-editor.ts"],"sourcesContent":["import { EditorView } from \"@codemirror/view\";\nimport { type WebsocketProvider } from \"y-websocket\";\nimport type { Text } from \"yjs\";\nimport type { EditorArguments } from \"../Editor.types\";\nimport { initEditorProvider } from \"./init-editor-provider\";\nimport { initEditorState } from \"./init-editor-state\";\n\nexport async function initEditor({ multiCursor, root, initialText, ...rest }: EditorArguments) {\n let provider: WebsocketProvider | undefined;\n let multiCursorText: Text | undefined;\n\n if (multiCursor) {\n const editorProvider = await initEditorProvider({ ...multiCursor, initialText });\n provider = editorProvider.provider;\n multiCursorText = editorProvider.multiCursorText;\n }\n\n const state = await initEditorState({\n ...rest,\n text: initialText || \"\",\n provider,\n multiCursorText,\n });\n const view = new EditorView({\n state,\n parent: root,\n });\n\n return { view, provider, multiCursorText };\n}\n"],"names":[],"mappings":";;;;;AAOO,eAAe,UAAU,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,IAAI,EAAmB,EAAA;AAC3F,IAAA,IAAI,QAAuC;AAC3C,IAAA,IAAI,eAAiC;IAErC,IAAI,WAAW,EAAE;AACf,QAAA,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,EAAE,GAAG,WAAW,EAAE,WAAW,EAAE,CAAC;AAChF,QAAA,QAAQ,GAAG,cAAc,CAAC,QAAQ;AAClC,QAAA,eAAe,GAAG,cAAc,CAAC,eAAe;;AAGlD,IAAA,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC;AAClC,QAAA,GAAG,IAAI;QACP,IAAI,EAAE,WAAW,IAAI,EAAE;QACvB,QAAQ;QACR,eAAe;AAChB,KAAA,CAAC;AACF,IAAA,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC;QAC1B,KAAK;AACL,QAAA,MAAM,EAAE,IAAI;AACb,KAAA,CAAC;AAEF,IAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,eAAe,EAAE;AAC5C;;;;"}
package/lib/index.d.ts CHANGED
@@ -123,10 +123,12 @@ declare class Editor {
123
123
  view: EditorView | undefined;
124
124
  provider: WebsocketProvider | undefined;
125
125
  arguments: EditorArguments;
126
+ yText: Text | undefined;
126
127
  constructor(options: EditorArguments);
127
128
  focus: () => void;
128
129
  getContent: () => string | undefined;
129
130
  setContent: (content: string, position?: number) => void;
131
+ replaceContent: (content: string) => void;
130
132
  setReadonly: (readonly: boolean) => void;
131
133
  setTheme: (theme?: EditorTheme) => void;
132
134
  setVimMode: (mode: boolean) => Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krainovsd/markdown-editor",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Krainov markdown-editor",
5
5
  "type": "module",
6
6
  "author": "KrainovSD <denislosev48@gmail.com>",