@krainovsd/markdown-editor 0.4.10 → 0.5.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/{index-DwJFpp84.js → index-CqwA5IW6.js} +27 -33
- package/lib/cjs/index-CqwA5IW6.js.map +1 -0
- package/lib/cjs/{index-B2b3XrJr.js → index-U3sHhzTm.js} +2 -2
- package/lib/cjs/{index-B2b3XrJr.js.map → index-U3sHhzTm.js.map} +1 -1
- package/lib/cjs/index.js +1 -1
- package/lib/esm/extensions/markdown/image/image-widget.js +0 -1
- package/lib/esm/extensions/markdown/image/image-widget.js.map +1 -1
- package/lib/esm/extensions/markdown/link/link-widget.js +0 -1
- package/lib/esm/extensions/markdown/link/link-widget.js.map +1 -1
- package/lib/esm/extensions/theme/themes/get-theme-template.js +0 -2
- package/lib/esm/extensions/theme/themes/get-theme-template.js.map +1 -1
- package/lib/esm/lib/utils/overlap-mark.js +0 -1
- package/lib/esm/lib/utils/overlap-mark.js.map +1 -1
- package/lib/esm/module/Editor/Editor.js +25 -26
- package/lib/esm/module/Editor/Editor.js.map +1 -1
- package/lib/index.d.ts +4 -3
- package/package.json +3 -2
- package/lib/cjs/index-DwJFpp84.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-U3sHhzTm.js","sources":["../../src/extensions/markdown/mention/mention-parser.ts","../../src/extensions/markdown/markdown-parser.ts","../../src/extensions/markdown/init-markdown.ts"],"sourcesContent":["import type { MarkdownConfig } from \"@lezer/markdown\";\nimport {\n CODE_OF_LINE_BREAK,\n CODE_OF_SPACE,\n CODE_OF_START_MENTION,\n NAME_OF_MENTION,\n} from \"./mention-constants\";\n\nexport const mentionParser: MarkdownConfig = {\n defineNodes: [{ name: NAME_OF_MENTION }],\n parseInline: [\n {\n name: NAME_OF_MENTION,\n parse(cx, code, pos) {\n if (code != CODE_OF_START_MENTION) return -1;\n const nextCode = cx.char(pos + 1);\n if (nextCode === -1 || nextCode === CODE_OF_SPACE || nextCode === CODE_OF_LINE_BREAK)\n return -1;\n\n let end: number = pos + 1;\n for (let i = pos + 1; i < cx.end; i++) {\n const nextCode = cx.char(i);\n if (nextCode === -1 || nextCode === CODE_OF_SPACE || nextCode === CODE_OF_LINE_BREAK)\n break;\n end++;\n }\n\n return cx.addElement(cx.elt(NAME_OF_MENTION, pos, end));\n },\n },\n ],\n};\n","import type { MarkdownExtension } from \"@lezer/markdown\";\nimport { mentionParser } from \"./mention\";\n\nexport const markdownParserPlugin: MarkdownExtension = [mentionParser];\n","import { markdown, markdownLanguage } from \"@codemirror/lang-markdown\";\nimport { type Extension } from \"@codemirror/state\";\nimport { markdownDecorationPlugin } from \"./markdown-decoration\";\nimport { markdownParserPlugin } from \"./markdown-parser\";\nimport { markdownState } from \"./markdown-state\";\nimport type { InitMarkdownOptions } from \"./markdown-types\";\n\nexport const initMarkdown = ({ languages, imageSrcGetter }: InitMarkdownOptions): Extension => {\n return [\n markdownState,\n markdown({\n base: markdownLanguage,\n codeLanguages: languages,\n addKeymap: true,\n extensions: [markdownParserPlugin],\n }),\n markdownDecorationPlugin({ imageSrcGetter }),\n ];\n};\n"],"names":["NAME_OF_MENTION","CODE_OF_START_MENTION","CODE_OF_SPACE","CODE_OF_LINE_BREAK","markdownState","markdown","markdownLanguage","markdownDecorationPlugin"],"mappings":";;;;;;;;;;;;;;;AAQO,MAAM,aAAa,GAAmB;AAC3C,IAAA,WAAW,EAAE,CAAC,EAAE,IAAI,EAAEA,qBAAe,EAAE,CAAC;AACxC,IAAA,WAAW,EAAE;AACX,QAAA;AACE,YAAA,IAAI,EAAEA,qBAAe;AACrB,YAAA,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAA;gBACjB,IAAI,IAAI,IAAIC,2BAAqB;oBAAE,OAAO,EAAE;gBAC5C,MAAM,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;gBACjC,IAAI,QAAQ,KAAK,EAAE,IAAI,QAAQ,KAAKC,mBAAa,IAAI,QAAQ,KAAKC,wBAAkB;oBAClF,OAAO,EAAE;AAEX,gBAAA,IAAI,GAAG,GAAW,GAAG,GAAG,CAAC;AACzB,gBAAA,KAAK,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;oBACrC,MAAM,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;oBAC3B,IAAI,QAAQ,KAAK,EAAE,IAAI,QAAQ,KAAKD,mBAAa,IAAI,QAAQ,KAAKC,wBAAkB;wBAClF;AACF,oBAAA,GAAG,EAAE;;AAGP,gBAAA,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAACH,qBAAe,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;aACxD;AACF,SAAA;AACF,KAAA;CACF;;AC5BM,MAAM,oBAAoB,GAAsB,CAAC,aAAa,CAAC;;ACIzD,MAAA,YAAY,GAAG,CAAC,EAAE,SAAS,EAAE,cAAc,EAAuB,KAAe;IAC5F,OAAO;QACLI,mBAAa;AACb,QAAAC,qBAAQ,CAAC;AACP,YAAA,IAAI,EAAEC,6BAAgB;AACtB,YAAA,aAAa,EAAE,SAAS;AACxB,YAAA,SAAS,EAAE,IAAI;YACf,UAAU,EAAE,CAAC,oBAAoB,CAAC;SACnC,CAAC;AACF,QAAAC,8BAAwB,CAAC,EAAE,cAAc,EAAE,CAAC;KAC7C;AACH;;;;"}
|
package/lib/cjs/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
|
|
5
|
-
const index = require('./index-
|
|
5
|
+
const index = require('./index-CqwA5IW6.js');
|
|
6
6
|
require('@codemirror/autocomplete');
|
|
7
7
|
require('@codemirror/commands');
|
|
8
8
|
require('@codemirror/view');
|
|
@@ -4,7 +4,6 @@ import { openedImageEffect } from '../markdown-state.js';
|
|
|
4
4
|
import styles from '../styles.module.scss.js';
|
|
5
5
|
import { CODE_OF_START_IMAGE_URL } from './image-constants.js';
|
|
6
6
|
|
|
7
|
-
/* eslint-disable max-params */
|
|
8
7
|
const IMAGE_NODES = {};
|
|
9
8
|
const INTERVAL_DELAY = 10000;
|
|
10
9
|
const EXISTING_WIDGETS = new Set();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-widget.js","sources":["../../../../../src/extensions/markdown/image/image-widget.ts"],"sourcesContent":["/* eslint-disable max-params */\nimport { type EditorView, WidgetType } from \"@codemirror/view\";\nimport { saveDispatch } from \"@/lib/utils\";\nimport { openedImageEffect } from \"../markdown-state\";\nimport styles from \"../styles.module.scss\";\nimport { CODE_OF_START_IMAGE_URL } from \"./image-constants\";\n\nconst IMAGE_NODES: Record<string, ImageContainerElement | undefined> = {};\nconst INTERVAL_DELAY = 10000;\nconst EXISTING_WIDGETS = new Set<string>();\nlet interval: NodeJS.Timeout | null = null;\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 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] = container;\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 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 interval ??= setInterval(garbageCollectorInterval, INTERVAL_DELAY);\n\n return container;\n }\n\n destroy(): void {\n EXISTING_WIDGETS.delete(this.key);\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/** for disable cache */\nfunction garbageCollectorInterval() {\n for (const [key, node] of Object.entries(IMAGE_NODES)) {\n if (EXISTING_WIDGETS.has(key) || !node) continue;\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 if (startPosition === 0 && endPosition === 0) {\n const content = node.textContent;\n if (!content) return;\n let startPosition = 0;\n let pos = 0;\n\n while (pos < content.length) {\n if (content.codePointAt(pos) !== CODE_OF_START_IMAGE_URL) {\n pos++;\n } else {\n startPosition = pos + 1;\n break;\n }\n }\n\n const range = document.createRange();\n range.setStart(node, startPosition);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n\n return;\n }\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\";\nimport { CODE_OF_START_IMAGE_URL } from \"./image-constants\";\n\nconst IMAGE_NODES: Record<string, ImageContainerElement | undefined> = {};\nconst INTERVAL_DELAY = 10000;\nconst EXISTING_WIDGETS = new Set<string>();\nlet interval: NodeJS.Timeout | null = null;\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 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] = container;\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 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 interval ??= setInterval(garbageCollectorInterval, INTERVAL_DELAY);\n\n return container;\n }\n\n destroy(): void {\n EXISTING_WIDGETS.delete(this.key);\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/** for disable cache */\nfunction garbageCollectorInterval() {\n for (const [key, node] of Object.entries(IMAGE_NODES)) {\n if (EXISTING_WIDGETS.has(key) || !node) continue;\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 if (startPosition === 0 && endPosition === 0) {\n const content = node.textContent;\n if (!content) return;\n let startPosition = 0;\n let pos = 0;\n\n while (pos < content.length) {\n if (content.codePointAt(pos) !== CODE_OF_START_IMAGE_URL) {\n pos++;\n } else {\n startPosition = pos + 1;\n break;\n }\n }\n\n const range = document.createRange();\n range.setStart(node, startPosition);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n\n return;\n }\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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"}
|
|
@@ -8,7 +8,6 @@ import { openedLinkEffect } from '../markdown-state.js';
|
|
|
8
8
|
import styles from '../styles.module.scss.js';
|
|
9
9
|
import { CODE_OF_START_LINK_URL } from './link-constants.js';
|
|
10
10
|
|
|
11
|
-
/* eslint-disable max-params */
|
|
12
11
|
const LINK_NODES = {};
|
|
13
12
|
class LinkWidget extends WidgetType {
|
|
14
13
|
text;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-widget.js","sources":["../../../../../src/extensions/markdown/link/link-widget.ts"],"sourcesContent":["/* eslint-disable max-params */\nimport { 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\";\nimport { CODE_OF_START_LINK_URL } from \"./link-constants\";\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\", (event) => event.preventDefault(), {\n signal: abortController.signal,\n });\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 if (startPosition === 0 && endPosition === 0) {\n const content = node.textContent;\n if (!content) return;\n let startPosition = 0;\n let pos = 0;\n\n while (pos < content.length) {\n if (content.codePointAt(pos) !== CODE_OF_START_LINK_URL) {\n pos++;\n } else {\n startPosition = pos + 1;\n break;\n }\n }\n\n const range = document.createRange();\n range.setStart(node, startPosition);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n\n return;\n }\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\";\nimport { CODE_OF_START_LINK_URL } from \"./link-constants\";\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\", (event) => event.preventDefault(), {\n signal: abortController.signal,\n });\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 if (startPosition === 0 && endPosition === 0) {\n const content = node.textContent;\n if (!content) return;\n let startPosition = 0;\n let pos = 0;\n\n while (pos < content.length) {\n if (content.codePointAt(pos) !== CODE_OF_START_LINK_URL) {\n pos++;\n } else {\n startPosition = pos + 1;\n break;\n }\n }\n\n const range = document.createRange();\n range.setStart(node, startPosition);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n\n return;\n }\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-theme-template.js","sources":["../../../../../src/extensions/theme/themes/get-theme-template.ts"],"sourcesContent":["import { EditorView } from \"@codemirror/view\";\nimport { CLASSES } from \"../theme-constants\";\nimport type { ThemeConfig } from \"../theme-types\";\n\nexport function getThemeTemplate(dark: boolean, config: Required<ThemeConfig>) {\n return EditorView.theme(\n {\n \"&\": {\n color: config.color,\n backgroundColor: config.background,\n },\n \".cm-content\": {\n fontFamily: config.fontFamily || \"Montserrat\",\n },\n \"&.cm-focused > .cm-scroller > .cm-selectionLayer > .cm-selectionBackground\": {\n background: config.vimSelectionFocused,\n },\n \"& .cm-selectionBackground\": {\n background: config.vimSelection,\n },\n \"&.cm-editor.cm-focused\": { outline: \"none\" },\n \"&.cm-editor\": {\n height: \"100%\",\n width: \"100%\",\n },\n [`.${CLASSES.listCommon}:after`]: {\n background: config.color,\n },\n [`.${CLASSES.code}`]: {\n background: config.codeBackground,\n color: config.codeColor,\n
|
|
1
|
+
{"version":3,"file":"get-theme-template.js","sources":["../../../../../src/extensions/theme/themes/get-theme-template.ts"],"sourcesContent":["import { EditorView } from \"@codemirror/view\";\nimport { CLASSES } from \"../theme-constants\";\nimport type { ThemeConfig } from \"../theme-types\";\n\nexport function getThemeTemplate(dark: boolean, config: Required<ThemeConfig>) {\n return EditorView.theme(\n {\n \"&\": {\n color: config.color,\n backgroundColor: config.background,\n },\n \".cm-content\": {\n fontFamily: config.fontFamily || \"Montserrat\",\n },\n \"&.cm-focused > .cm-scroller > .cm-selectionLayer > .cm-selectionBackground\": {\n background: config.vimSelectionFocused,\n },\n \"& .cm-selectionBackground\": {\n background: config.vimSelection,\n },\n \"&.cm-editor.cm-focused\": { outline: \"none\" },\n \"&.cm-editor\": {\n height: \"100%\",\n width: \"100%\",\n },\n [`.${CLASSES.listCommon}:after`]: {\n background: config.color,\n },\n [`.${CLASSES.code}`]: {\n background: config.codeBackground,\n color: config.codeColor,\n fontFamily: config.codeFontFamily,\n },\n\n [`.${CLASSES.horizontal}`]: {\n borderBottomColor: config.horizontalColor,\n },\n [`.${CLASSES.link}`]: {\n color: config.linkColor,\n },\n [`.${CLASSES.blockquote}`]: {\n borderLeftColor: config.blockquoteColor,\n },\n [`.${CLASSES.blockquoteInner}:before`]: {\n borderLeftColor: config.blockquoteColor,\n },\n [`.${CLASSES.codeButton}`]: {\n color: config.codeButtonColor,\n },\n [`.${CLASSES.codeButton}:hover`]: {\n background: config.codeButtonBackground,\n },\n [`.${CLASSES.codeButtonSuccess}:after`]: {\n borderColor: config.codeButtonColor,\n },\n [`.${CLASSES.codeButtonFail}:after`]: {\n background: config.codeButtonColor,\n },\n [`.${CLASSES.codeButtonFail}:before`]: {\n background: config.codeButtonColor,\n },\n [`.${CLASSES.codeButtonPending}:before`]: {\n borderColor: config.codeBackground,\n borderTopColor: config.codeButtonColor,\n },\n [`.${CLASSES.mention}`]: {\n color: config.mentionColor,\n },\n [`.${CLASSES.codeBlockLine}`]: {\n borderColor: config.codeBlockBorderColor,\n },\n [`.${CLASSES.codeBlock}`]: {\n background: config.codeBlockBackground,\n },\n },\n { dark },\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -26,7 +26,6 @@ function overlapMark({ marks, shift, state, requireMatched }) {
|
|
|
26
26
|
originalText: text.substring(shiftBeforeOuter, text.length - shiftAfterOuter),
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
-
// eslint-disable-next-line max-params
|
|
30
29
|
function findMarkIndex(text, marks, requireMatched, direction = "right") {
|
|
31
30
|
if (text.length === 0)
|
|
32
31
|
return -1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlap-mark.js","sources":["../../../../src/lib/utils/overlap-mark.ts"],"sourcesContent":["import type { EditorState } from \"@/module\";\n\ntype OverlapMarkOptions = {\n state: EditorState;\n shift: number;\n marks: (number | undefined)[];\n requireMatched: number[];\n};\n\nexport function overlapMark({ marks, shift, state, requireMatched }: OverlapMarkOptions) {\n const { from, to, shiftAfterInner, shiftAfterOuter, shiftBeforeInner, shiftBeforeOuter, text } =\n processShiftContent(state, shift, marks);\n\n const startIndex = findMarkIndex(\n text.substring(0, shiftBeforeInner + shiftBeforeOuter),\n marks,\n requireMatched,\n \"right\",\n );\n const endIndex = findMarkIndex(\n text.substring(text.length - shiftAfterInner - shiftAfterOuter),\n marks,\n requireMatched,\n \"left\",\n );\n\n const start = ~startIndex ? from - shiftBeforeOuter + startIndex : -1;\n const end = ~endIndex ? to - shiftAfterInner + endIndex : -1;\n\n // console.log({\n // from,\n // to,\n // shiftAfterInner,\n // shiftAfterOuter,\n // shiftBeforeInner,\n // shiftBeforeOuter,\n // text,\n // textStart: text.substring(0, shiftBeforeInner + shiftBeforeOuter),\n // textEnd: text.substring(text.length - shiftAfterInner - shiftAfterOuter),\n // startIndex,\n // endIndex,\n // end,\n // start,\n // });\n\n return {\n start,\n end,\n marked: Boolean(~start || ~end),\n originalText: text.substring(shiftBeforeOuter, text.length - shiftAfterOuter),\n };\n}\n\n// eslint-disable-next-line max-params\nfunction findMarkIndex(\n text: string,\n marks: (number | undefined)[],\n requireMatched: number[],\n direction: \"right\" | \"left\" = \"right\",\n) {\n if (text.length === 0) return -1;\n\n const maxRequired = Math.max(...requireMatched);\n const minRequired = Math.min(...requireMatched);\n\n let pos = 0;\n let matched = 0;\n let start = -1;\n\n for (const mark of marks) {\n if (!mark) continue;\n\n while (pos < text.length) {\n if (text.codePointAt(pos) === mark) matched++;\n else {\n if (\n // eslint-disable-next-line no-loop-func -- https://eslint.org/docs/latest/rules/no-loop-func#known-limitations\n requireMatched.some((rm) => rm === matched) &&\n ((direction === \"right\" && pos - matched > start) ||\n (direction === \"left\" && (pos - matched < start || start === -1)))\n ) {\n start = direction === \"right\" ? pos - minRequired : pos - matched;\n // console.log({ pos, matched, start, minRequired, maxRequired, direction });\n } else if (maxRequired < matched) {\n const posMin = pos - minRequired;\n const posMax = pos - matched;\n\n // console.log({ posMin, posMax, pos, minRequired, maxRequired, direction, matched });\n\n // eslint-disable-next-line max-depth\n if (direction === \"right\" && posMin > start) start = posMin;\n // eslint-disable-next-line max-depth\n if (direction === \"left\" && (posMax < start || start === -1)) start = posMax;\n }\n matched = 0;\n }\n pos++;\n }\n\n if (\n // eslint-disable-next-line no-loop-func -- https://eslint.org/docs/latest/rules/no-loop-func#known-limitations\n requireMatched.some((rm) => rm === matched) &&\n ((direction === \"right\" && pos - matched > start) ||\n (direction === \"left\" && (pos - matched < start || start === -1)))\n ) {\n start = direction === \"right\" ? pos - minRequired : pos - matched;\n // console.log({ pos, matched, start, minRequired, maxRequired, direction });\n } else if (maxRequired < matched) {\n const posMin = pos - minRequired;\n const posMax = pos - matched;\n\n // console.log({ posMin, posMax, pos, minRequired, maxRequired, direction, matched });\n\n if (direction === \"right\" && posMin > start) start = posMin;\n if (direction === \"left\" && (posMax < start || start === -1)) start = posMax;\n }\n\n pos = 0;\n matched = 0;\n }\n\n return start;\n}\n\nfunction processShiftContent(state: EditorState, shift: number, marks: (number | undefined)[]) {\n const { from, to } = state.selection.ranges[0];\n const linePoint = state.lineBreak.codePointAt(0);\n let pos = 0;\n\n /** processing outer shifts */\n const initialTextBefore = state.sliceDoc(from - shift, from);\n let shiftBeforeOuter = 0;\n pos = initialTextBefore.length - 1;\n\n while (pos > -1) {\n if (initialTextBefore.codePointAt(pos) === linePoint) break;\n shiftBeforeOuter++;\n pos--;\n }\n\n const initialTextAfter = state.sliceDoc(to, to + shift);\n let shiftAfterOuter = 0;\n pos = 0;\n\n while (pos < initialTextAfter.length) {\n if (initialTextAfter.codePointAt(pos) === linePoint) break;\n shiftAfterOuter++;\n pos++;\n }\n\n /** processing inner shifts */\n const initialText = state.sliceDoc(from, to);\n let shiftBeforeInner = 0;\n pos = 0;\n\n if (initialText.length > 1)\n while (pos < initialText.length) {\n // eslint-disable-next-line no-loop-func -- https://eslint.org/docs/latest/rules/no-loop-func#known-limitations\n if (marks.some((mark) => mark === initialText.codePointAt(pos))) shiftBeforeInner++;\n else break;\n\n pos++;\n }\n\n const initialTextWithoutBeforeShift = initialText.substring(shiftBeforeInner + 1);\n let shiftAfterInner = 0;\n pos = initialTextWithoutBeforeShift.length - 1;\n\n if (initialText.length > 1 || shiftBeforeInner > 0)\n while (pos > -1) {\n // eslint-disable-next-line no-loop-func -- https://eslint.org/docs/latest/rules/no-loop-func#known-limitations\n if (marks.some((mark) => mark === initialTextWithoutBeforeShift.codePointAt(pos)))\n shiftAfterInner++;\n else break;\n\n pos--;\n }\n\n const text = state.sliceDoc(from - shiftBeforeOuter, to + shiftAfterOuter);\n\n return {\n from,\n to,\n shiftBeforeOuter,\n shiftBeforeInner,\n shiftAfterOuter,\n shiftAfterInner,\n text,\n };\n}\n"],"names":[],"mappings":"AASM,SAAU,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,EAAsB,EAAA;IACrF,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,IAAI,EAAE,GAC5F,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAE1C,MAAM,UAAU,GAAG,aAAa,CAC9B,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,CAAC,EACtD,KAAK,EACL,cAAc,EACd,OAAO,CACR;IACD,MAAM,QAAQ,GAAG,aAAa,CAC5B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,eAAe,GAAG,eAAe,CAAC,EAC/D,KAAK,EACL,cAAc,EACd,MAAM,CACP;AAED,IAAA,MAAM,KAAK,GAAG,CAAC,UAAU,GAAG,IAAI,GAAG,gBAAgB,GAAG,UAAU,GAAG,EAAE;AACrE,IAAA,MAAM,GAAG,GAAG,CAAC,QAAQ,GAAG,EAAE,GAAG,eAAe,GAAG,QAAQ,GAAG,EAAE;;;;;;;;;;;;;;;;IAkB5D,OAAO;QACL,KAAK;QACL,GAAG;QACH,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC;AAC/B,QAAA,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC;KAC9E;AACH;AAEA;AACA,SAAS,aAAa,CACpB,IAAY,EACZ,KAA6B,EAC7B,cAAwB,EACxB,SAAA,GAA8B,OAAO,EAAA;AAErC,IAAA,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE;IAEhC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC;IAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC;IAE/C,IAAI,GAAG,GAAG,CAAC;IACX,IAAI,OAAO,GAAG,CAAC;AACf,IAAA,IAAI,KAAK,GAAG,EAAE;AAEd,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACxB,QAAA,IAAI,CAAC,IAAI;YAAE;AAEX,QAAA,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE;AACxB,YAAA,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,IAAI;AAAE,gBAAA,OAAO,EAAE;iBACxC;AACH,gBAAA;;gBAEE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC;qBAC1C,CAAC,SAAS,KAAK,OAAO,IAAI,GAAG,GAAG,OAAO,GAAG,KAAK;AAC9C,yBAAC,SAAS,KAAK,MAAM,KAAK,GAAG,GAAG,OAAO,GAAG,KAAK,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EACpE;AACA,oBAAA,KAAK,GAAG,SAAS,KAAK,OAAO,GAAG,GAAG,GAAG,WAAW,GAAG,GAAG,GAAG,OAAO;;;AAE5D,qBAAA,IAAI,WAAW,GAAG,OAAO,EAAE;AAChC,oBAAA,MAAM,MAAM,GAAG,GAAG,GAAG,WAAW;AAChC,oBAAA,MAAM,MAAM,GAAG,GAAG,GAAG,OAAO;;;AAK5B,oBAAA,IAAI,SAAS,KAAK,OAAO,IAAI,MAAM,GAAG,KAAK;wBAAE,KAAK,GAAG,MAAM;;AAE3D,oBAAA,IAAI,SAAS,KAAK,MAAM,KAAK,MAAM,GAAG,KAAK,IAAI,KAAK,KAAK,EAAE,CAAC;wBAAE,KAAK,GAAG,MAAM;;gBAE9E,OAAO,GAAG,CAAC;;AAEb,YAAA,GAAG,EAAE;;AAGP,QAAA;;QAEE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC;aAC1C,CAAC,SAAS,KAAK,OAAO,IAAI,GAAG,GAAG,OAAO,GAAG,KAAK;AAC9C,iBAAC,SAAS,KAAK,MAAM,KAAK,GAAG,GAAG,OAAO,GAAG,KAAK,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EACpE;AACA,YAAA,KAAK,GAAG,SAAS,KAAK,OAAO,GAAG,GAAG,GAAG,WAAW,GAAG,GAAG,GAAG,OAAO;;;AAE5D,aAAA,IAAI,WAAW,GAAG,OAAO,EAAE;AAChC,YAAA,MAAM,MAAM,GAAG,GAAG,GAAG,WAAW;AAChC,YAAA,MAAM,MAAM,GAAG,GAAG,GAAG,OAAO;;AAI5B,YAAA,IAAI,SAAS,KAAK,OAAO,IAAI,MAAM,GAAG,KAAK;gBAAE,KAAK,GAAG,MAAM;AAC3D,YAAA,IAAI,SAAS,KAAK,MAAM,KAAK,MAAM,GAAG,KAAK,IAAI,KAAK,KAAK,EAAE,CAAC;gBAAE,KAAK,GAAG,MAAM;;QAG9E,GAAG,GAAG,CAAC;QACP,OAAO,GAAG,CAAC;;AAGb,IAAA,OAAO,KAAK;AACd;AAEA,SAAS,mBAAmB,CAAC,KAAkB,EAAE,KAAa,EAAE,KAA6B,EAAA;AAC3F,IAAA,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC;IAChD,IAAI,GAAG,GAAG,CAAC;;AAGX,IAAA,MAAM,iBAAiB,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC;IAC5D,IAAI,gBAAgB,GAAG,CAAC;AACxB,IAAA,GAAG,GAAG,iBAAiB,CAAC,MAAM,GAAG,CAAC;AAElC,IAAA,OAAO,GAAG,GAAG,EAAE,EAAE;AACf,QAAA,IAAI,iBAAiB,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE;AACtD,QAAA,gBAAgB,EAAE;AAClB,QAAA,GAAG,EAAE;;AAGP,IAAA,MAAM,gBAAgB,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC;IACvD,IAAI,eAAe,GAAG,CAAC;IACvB,GAAG,GAAG,CAAC;AAEP,IAAA,OAAO,GAAG,GAAG,gBAAgB,CAAC,MAAM,EAAE;AACpC,QAAA,IAAI,gBAAgB,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE;AACrD,QAAA,eAAe,EAAE;AACjB,QAAA,GAAG,EAAE;;;IAIP,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;IAC5C,IAAI,gBAAgB,GAAG,CAAC;IACxB,GAAG,GAAG,CAAC;AAEP,IAAA,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;AACxB,QAAA,OAAO,GAAG,GAAG,WAAW,CAAC,MAAM,EAAE;;AAE/B,YAAA,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,KAAK,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;AAAE,gBAAA,gBAAgB,EAAE;;gBAC9E;AAEL,YAAA,GAAG,EAAE;;IAGT,MAAM,6BAA6B,GAAG,WAAW,CAAC,SAAS,CAAC,gBAAgB,GAAG,CAAC,CAAC;IACjF,IAAI,eAAe,GAAG,CAAC;AACvB,IAAA,GAAG,GAAG,6BAA6B,CAAC,MAAM,GAAG,CAAC;IAE9C,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,gBAAgB,GAAG,CAAC;AAChD,QAAA,OAAO,GAAG,GAAG,EAAE,EAAE;;AAEf,YAAA,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,KAAK,6BAA6B,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;AAC/E,gBAAA,eAAe,EAAE;;gBACd;AAEL,YAAA,GAAG,EAAE;;AAGT,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,GAAG,gBAAgB,EAAE,EAAE,GAAG,eAAe,CAAC;IAE1E,OAAO;QACL,IAAI;QACJ,EAAE;QACF,gBAAgB;QAChB,gBAAgB;QAChB,eAAe;QACf,eAAe;QACf,IAAI;KACL;AACH;;;;"}
|
|
1
|
+
{"version":3,"file":"overlap-mark.js","sources":["../../../../src/lib/utils/overlap-mark.ts"],"sourcesContent":["import type { EditorState } from \"@/module\";\n\ntype OverlapMarkOptions = {\n state: EditorState;\n shift: number;\n marks: (number | undefined)[];\n requireMatched: number[];\n};\n\nexport function overlapMark({ marks, shift, state, requireMatched }: OverlapMarkOptions) {\n const { from, to, shiftAfterInner, shiftAfterOuter, shiftBeforeInner, shiftBeforeOuter, text } =\n processShiftContent(state, shift, marks);\n\n const startIndex = findMarkIndex(\n text.substring(0, shiftBeforeInner + shiftBeforeOuter),\n marks,\n requireMatched,\n \"right\",\n );\n const endIndex = findMarkIndex(\n text.substring(text.length - shiftAfterInner - shiftAfterOuter),\n marks,\n requireMatched,\n \"left\",\n );\n\n const start = ~startIndex ? from - shiftBeforeOuter + startIndex : -1;\n const end = ~endIndex ? to - shiftAfterInner + endIndex : -1;\n\n // console.log({\n // from,\n // to,\n // shiftAfterInner,\n // shiftAfterOuter,\n // shiftBeforeInner,\n // shiftBeforeOuter,\n // text,\n // textStart: text.substring(0, shiftBeforeInner + shiftBeforeOuter),\n // textEnd: text.substring(text.length - shiftAfterInner - shiftAfterOuter),\n // startIndex,\n // endIndex,\n // end,\n // start,\n // });\n\n return {\n start,\n end,\n marked: Boolean(~start || ~end),\n originalText: text.substring(shiftBeforeOuter, text.length - shiftAfterOuter),\n };\n}\n\nfunction findMarkIndex(\n text: string,\n marks: (number | undefined)[],\n requireMatched: number[],\n direction: \"right\" | \"left\" = \"right\",\n) {\n if (text.length === 0) return -1;\n\n const maxRequired = Math.max(...requireMatched);\n const minRequired = Math.min(...requireMatched);\n\n let pos = 0;\n let matched = 0;\n let start = -1;\n\n for (const mark of marks) {\n if (!mark) continue;\n\n while (pos < text.length) {\n if (text.codePointAt(pos) === mark) matched++;\n else {\n if (\n // eslint-disable-next-line no-loop-func -- https://eslint.org/docs/latest/rules/no-loop-func#known-limitations\n requireMatched.some((rm) => rm === matched) &&\n ((direction === \"right\" && pos - matched > start) ||\n (direction === \"left\" && (pos - matched < start || start === -1)))\n ) {\n start = direction === \"right\" ? pos - minRequired : pos - matched;\n // console.log({ pos, matched, start, minRequired, maxRequired, direction });\n } else if (maxRequired < matched) {\n const posMin = pos - minRequired;\n const posMax = pos - matched;\n\n // console.log({ posMin, posMax, pos, minRequired, maxRequired, direction, matched });\n\n // eslint-disable-next-line max-depth\n if (direction === \"right\" && posMin > start) start = posMin;\n // eslint-disable-next-line max-depth\n if (direction === \"left\" && (posMax < start || start === -1)) start = posMax;\n }\n matched = 0;\n }\n pos++;\n }\n\n if (\n // eslint-disable-next-line no-loop-func -- https://eslint.org/docs/latest/rules/no-loop-func#known-limitations\n requireMatched.some((rm) => rm === matched) &&\n ((direction === \"right\" && pos - matched > start) ||\n (direction === \"left\" && (pos - matched < start || start === -1)))\n ) {\n start = direction === \"right\" ? pos - minRequired : pos - matched;\n // console.log({ pos, matched, start, minRequired, maxRequired, direction });\n } else if (maxRequired < matched) {\n const posMin = pos - minRequired;\n const posMax = pos - matched;\n\n // console.log({ posMin, posMax, pos, minRequired, maxRequired, direction, matched });\n\n if (direction === \"right\" && posMin > start) start = posMin;\n if (direction === \"left\" && (posMax < start || start === -1)) start = posMax;\n }\n\n pos = 0;\n matched = 0;\n }\n\n return start;\n}\n\nfunction processShiftContent(state: EditorState, shift: number, marks: (number | undefined)[]) {\n const { from, to } = state.selection.ranges[0];\n const linePoint = state.lineBreak.codePointAt(0);\n let pos = 0;\n\n /** processing outer shifts */\n const initialTextBefore = state.sliceDoc(from - shift, from);\n let shiftBeforeOuter = 0;\n pos = initialTextBefore.length - 1;\n\n while (pos > -1) {\n if (initialTextBefore.codePointAt(pos) === linePoint) break;\n shiftBeforeOuter++;\n pos--;\n }\n\n const initialTextAfter = state.sliceDoc(to, to + shift);\n let shiftAfterOuter = 0;\n pos = 0;\n\n while (pos < initialTextAfter.length) {\n if (initialTextAfter.codePointAt(pos) === linePoint) break;\n shiftAfterOuter++;\n pos++;\n }\n\n /** processing inner shifts */\n const initialText = state.sliceDoc(from, to);\n let shiftBeforeInner = 0;\n pos = 0;\n\n if (initialText.length > 1)\n while (pos < initialText.length) {\n // eslint-disable-next-line no-loop-func -- https://eslint.org/docs/latest/rules/no-loop-func#known-limitations\n if (marks.some((mark) => mark === initialText.codePointAt(pos))) shiftBeforeInner++;\n else break;\n\n pos++;\n }\n\n const initialTextWithoutBeforeShift = initialText.substring(shiftBeforeInner + 1);\n let shiftAfterInner = 0;\n pos = initialTextWithoutBeforeShift.length - 1;\n\n if (initialText.length > 1 || shiftBeforeInner > 0)\n while (pos > -1) {\n // eslint-disable-next-line no-loop-func -- https://eslint.org/docs/latest/rules/no-loop-func#known-limitations\n if (marks.some((mark) => mark === initialTextWithoutBeforeShift.codePointAt(pos)))\n shiftAfterInner++;\n else break;\n\n pos--;\n }\n\n const text = state.sliceDoc(from - shiftBeforeOuter, to + shiftAfterOuter);\n\n return {\n from,\n to,\n shiftBeforeOuter,\n shiftBeforeInner,\n shiftAfterOuter,\n shiftAfterInner,\n text,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -16,14 +16,28 @@ class Editor {
|
|
|
16
16
|
provider;
|
|
17
17
|
arguments;
|
|
18
18
|
yText;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
19
|
+
init = async (options) => {
|
|
20
|
+
const editor = await initEditor(options);
|
|
21
|
+
this.view = editor.view;
|
|
22
|
+
this.provider = editor.provider;
|
|
23
|
+
this.yText = editor.multiCursorText;
|
|
25
24
|
this.arguments = options;
|
|
26
|
-
}
|
|
25
|
+
};
|
|
26
|
+
destroy = () => {
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
saveDispatch(() => {
|
|
29
|
+
this.view?.destroy?.();
|
|
30
|
+
this.provider?.destroy?.();
|
|
31
|
+
resolve(true);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
reset = async () => {
|
|
36
|
+
await this.destroy();
|
|
37
|
+
if (!this.arguments)
|
|
38
|
+
return;
|
|
39
|
+
return this.init(this.arguments);
|
|
40
|
+
};
|
|
27
41
|
focus = () => {
|
|
28
42
|
if (!this.view)
|
|
29
43
|
return;
|
|
@@ -54,10 +68,6 @@ class Editor {
|
|
|
54
68
|
});
|
|
55
69
|
};
|
|
56
70
|
replaceContent = (content) => {
|
|
57
|
-
// if (!this.yText) return;
|
|
58
|
-
// this.yText.delete(0, this.yText.length);
|
|
59
|
-
// this.yText.insert(0, content);
|
|
60
|
-
// return;
|
|
61
71
|
if (!this.view)
|
|
62
72
|
return;
|
|
63
73
|
const transaction = this.view.state.update({
|
|
@@ -85,11 +95,11 @@ class Editor {
|
|
|
85
95
|
this.view.dispatch({
|
|
86
96
|
effects: ThemeCompartment.reconfigure(theme === "dark"
|
|
87
97
|
? getDarkTheme({
|
|
88
|
-
dark: this.arguments
|
|
89
|
-
light: this.arguments
|
|
98
|
+
dark: this.arguments?.dark,
|
|
99
|
+
light: this.arguments?.light})
|
|
90
100
|
: getLightTheme({
|
|
91
|
-
dark: this.arguments
|
|
92
|
-
light: this.arguments
|
|
101
|
+
dark: this.arguments?.dark,
|
|
102
|
+
light: this.arguments?.light})),
|
|
93
103
|
});
|
|
94
104
|
});
|
|
95
105
|
};
|
|
@@ -110,17 +120,6 @@ class Editor {
|
|
|
110
120
|
return;
|
|
111
121
|
this.provider.awareness.setLocalStateField("user", { name, color });
|
|
112
122
|
};
|
|
113
|
-
destroy = () => {
|
|
114
|
-
saveDispatch(() => {
|
|
115
|
-
if (!this.view)
|
|
116
|
-
return;
|
|
117
|
-
this.view.destroy();
|
|
118
|
-
});
|
|
119
|
-
saveDispatch(() => {
|
|
120
|
-
if (this.provider)
|
|
121
|
-
this.provider.destroy();
|
|
122
|
-
});
|
|
123
|
-
};
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
export { Editor };
|
|
@@ -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 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
|
|
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 | undefined;\n\n yText: Text | undefined;\n\n init = async (options: EditorArguments) => {\n const editor = await initEditor(options);\n this.view = editor.view;\n this.provider = editor.provider;\n this.yText = editor.multiCursorText;\n this.arguments = options;\n };\n\n destroy = () => {\n return new Promise((resolve) => {\n saveDispatch(() => {\n this.view?.destroy?.();\n this.provider?.destroy?.();\n resolve(true);\n });\n });\n };\n\n reset = async () => {\n await this.destroy();\n if (!this.arguments) return;\n return this.init(this.arguments);\n };\n\n focus = () => {\n if (!this.view) return;\n this.view.focus();\n };\n\n getContent = () => {\n if (!this.view) return;\n return this.view.state.doc.toString();\n };\n\n setContent = (content: string, position?: number) => {\n if (!this.view) return;\n if (position == undefined) {\n const cursor = this.view.state.selection.main.head;\n position = cursor;\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.view) return;\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 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 const { vim } = await import(\"@replit/codemirror-vim\");\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 this.provider.awareness.setLocalStateField(\"user\", { name, color });\n };\n}\n\nexport type EditorInterface = typeof Editor;\n"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
CHANGED
|
@@ -157,9 +157,11 @@ type ProviderStatusEvent = {
|
|
|
157
157
|
declare class Editor {
|
|
158
158
|
view: EditorView$1 | undefined;
|
|
159
159
|
provider: WebsocketProvider | undefined;
|
|
160
|
-
arguments: EditorArguments;
|
|
160
|
+
arguments: EditorArguments | undefined;
|
|
161
161
|
yText: Text | undefined;
|
|
162
|
-
|
|
162
|
+
init: (options: EditorArguments) => Promise<void>;
|
|
163
|
+
destroy: () => Promise<unknown>;
|
|
164
|
+
reset: () => Promise<void>;
|
|
163
165
|
focus: () => void;
|
|
164
166
|
getContent: () => string | undefined;
|
|
165
167
|
setContent: (content: string, position?: number) => void;
|
|
@@ -168,7 +170,6 @@ declare class Editor {
|
|
|
168
170
|
setTheme: (theme?: EditorTheme) => void;
|
|
169
171
|
setVimMode: (mode: boolean) => Promise<void>;
|
|
170
172
|
setUserProvider: (name?: string, color?: string) => void;
|
|
171
|
-
destroy: () => void;
|
|
172
173
|
}
|
|
173
174
|
type EditorInterface = typeof Editor;
|
|
174
175
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@krainovsd/markdown-editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0-beta.2",
|
|
4
4
|
"description": "Krainov markdown-editor",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "KrainovSD <denislosev48@gmail.com>",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
31
|
"publish-package": "npm run lint && npm run build && npm publish",
|
|
32
|
+
"publish-package-beta": "npm run lint && npm run build && npm publish --tag beta",
|
|
32
33
|
"dev": "vite --host",
|
|
33
34
|
"clear": "rm -rf ./lib",
|
|
34
35
|
"build": "npm run clear && npm run build:types && npm run build:js",
|
|
@@ -43,7 +44,7 @@
|
|
|
43
44
|
"build:types": "tspc -p tsconfig.build.json"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
|
-
"@krainovsd/presets": "0.
|
|
47
|
+
"@krainovsd/presets": "0.4.0",
|
|
47
48
|
"rollup": "4.34.9",
|
|
48
49
|
"prettier": "3.6.1",
|
|
49
50
|
"eslint": "9.29.0",
|