vdc-editor 0.1.233 → 0.1.235
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/{BulkSpellChecker-DCitRq-u.mjs → BulkSpellChecker-Btu4LaPx.mjs} +2 -2
- package/lib/{BulkSpellChecker-DCitRq-u.mjs.map → BulkSpellChecker-Btu4LaPx.mjs.map} +1 -1
- package/lib/{index-c5vBpBBl.mjs → index-DIfPrW2K.mjs} +23 -16
- package/lib/{index-c5vBpBBl.mjs.map → index-DIfPrW2K.mjs.map} +1 -1
- package/lib/src/components/editor/ArticleCompareEditor.vue.d.ts +0 -3
- package/lib/style.css +1 -1
- package/lib/vdc-editor.mjs +1 -1
- package/lib/vdc-editor.umd.js +2 -2
- package/lib/vdc-editor.umd.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as Z, a as Y, C as be, P as Ce, b as ve, D as ye, d as Ee, _ as Se, e as we, f as Te, S as oe, o as Ie, g as Re, h as Oe, i as Ne, j as We, k as Me, l as He, m as Ae, n as $e } from "./index-
|
|
1
|
+
import { c as Z, a as Y, C as be, P as Ce, b as ve, D as ye, d as Ee, _ as Se, e as we, f as Te, S as oe, o as Ie, g as Re, h as Oe, i as Ne, j as We, k as Me, l as He, m as Ae, n as $e } from "./index-DIfPrW2K.mjs";
|
|
2
2
|
import { defineComponent as P, createElementBlock as v, openBlock as m, createVNode as E, createElementVNode as h, unref as s, ref as L, onMounted as ee, nextTick as le, createCommentVNode as ie, normalizeClass as z, withModifiers as te, toDisplayString as G, normalizeStyle as ae, Fragment as K, renderList as q, createTextVNode as V, createBlock as B, createStaticVNode as Le, withCtx as $, reactive as ce, computed as se, watch as ue, normalizeProps as De, guardReactiveProps as Pe, renderSlot as Be, onUnmounted as re, resolveDynamicComponent as ze } from "vue";
|
|
3
3
|
import { useWindowSize as je, useEventListener as Ge } from "@vueuse/core";
|
|
4
4
|
const U = {
|
|
@@ -684,4 +684,4 @@ const vt = /* @__PURE__ */ Se(kt, [["render", Ct]]), yt = { class: "text-xs py-4
|
|
|
684
684
|
export {
|
|
685
685
|
Mt as default
|
|
686
686
|
};
|
|
687
|
-
//# sourceMappingURL=BulkSpellChecker-
|
|
687
|
+
//# sourceMappingURL=BulkSpellChecker-Btu4LaPx.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BulkSpellChecker-DCitRq-u.mjs","sources":["../src/constants/bulkSpellChecker.ts","../node_modules/lucide-vue-next/dist/esm/icons/arrow-left-right.js","../node_modules/lucide-vue-next/dist/esm/icons/circle-alert.js","../node_modules/lucide-vue-next/dist/esm/icons/circle-check.js","../src/components/BulkSpellCheckerHelpText.vue","../src/utils/bulkSpellchecker.ts","../src/components/BulkSpellCheckerWrongWordList.vue","../src/components/ui/SpinnerIcon.vue","../src/components/BulkSpellCheckerLoading.vue","../src/components/BulkSpellCheckerContent.vue","../src/hooks/useBulkSpellCheckerStore.ts","../src/components/ui/dialog/DialogTrigger.vue","../src/components/BulkSpellChecker.vue"],"sourcesContent":["export const ERROR_TYPE = {\n SPACING: 1,\n SPELLING: 2,\n}\n\nexport const SPELL_CHECK_CODE = {\n NOTHING_TO_CHANGE: 'NOTHING_TO_CHANGE',\n} as const\n\nexport const SPELL_CHECK_STATUS = {\n LOADING: 'loading',\n HAS_ERROR: 'hasError',\n NO_ERROR: 'noError',\n FAIL: 'fail',\n} as const\n\nexport type SpellCheckStatus = (typeof SPELL_CHECK_STATUS)[keyof typeof SPELL_CHECK_STATUS]\n\nexport const EDITOR_NAME = {\n EDITOR_COMMENT: 'editorComment',\n EDITOR_CONTENT: 'editorContent',\n} as const\n\nexport type EditorName = (typeof EDITOR_NAME)[keyof typeof EDITOR_NAME]\n","/**\n * @license lucide-vue-next v0.439.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ArrowLeftRight = createLucideIcon(\"ArrowLeftRightIcon\", [\n [\"path\", { d: \"M8 3 4 7l4 4\", key: \"9rb6wj\" }],\n [\"path\", { d: \"M4 7h16\", key: \"6tx8e3\" }],\n [\"path\", { d: \"m16 21 4-4-4-4\", key: \"siv7j2\" }],\n [\"path\", { d: \"M20 17H4\", key: \"h6l3hr\" }]\n]);\n\nexport { ArrowLeftRight as default };\n//# sourceMappingURL=arrow-left-right.js.map\n","/**\n * @license lucide-vue-next v0.439.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleAlert = createLucideIcon(\"CircleAlertIcon\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"8\", y2: \"12\", key: \"1pkeuh\" }],\n [\"line\", { x1: \"12\", x2: \"12.01\", y1: \"16\", y2: \"16\", key: \"4dfq90\" }]\n]);\n\nexport { CircleAlert as default };\n//# sourceMappingURL=circle-alert.js.map\n","/**\n * @license lucide-vue-next v0.439.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleCheck = createLucideIcon(\"CircleCheckIcon\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"m9 12 2 2 4-4\", key: \"dzmm74\" }]\n]);\n\nexport { CircleCheck as default };\n//# sourceMappingURL=circle-check.js.map\n","<script setup lang=\"ts\">\nimport { cn } from '@/utils'\nimport { ChevronDown } from 'lucide-vue-next'\n\ninterface Props {\n text: string\n}\nconst props = defineProps<Props>()\n\nconst expanded = ref(false)\nconst showButton = ref(false)\nconst helpRef = ref<HTMLElement | null>(null)\n\nfunction toggle() {\n expanded.value = !expanded.value\n}\n\nonMounted(async () => {\n await nextTick()\n if (helpRef.value && helpRef.value.scrollHeight > 32) {\n showButton.value = true\n }\n})\n</script>\n\n<template>\n <div class=\"relative\">\n <div\n ref=\"helpRef\"\n class=\"text-gray-700 dark:text-gray-400 transition-all\"\n :class=\"expanded ? 'max-h-none' : 'max-h-[32px] overflow-hidden'\"\n v-html=\"text\"\n ></div>\n\n <div\n v-if=\"showButton\"\n class=\"\"\n :class=\"\n cn(\n 'w-32 flex items-end justify-end bg-gradient-to-l from-white via-white to-transparent dark:from-ed-background dark:via-ed-background',\n expanded ? 'ml-auto opacity-60' : 'absolute bottom-0 right-0'\n )\n \"\n >\n <button class=\"flex items-center gap-1\" @click.stop=\"toggle\">\n <span class=\"border-b border-gray-500\">{{ expanded ? '접기' : '자세히' }}</span>\n <ChevronDown class=\"w-4 h-4 transition-transform\" :class=\"expanded ? 'rotate-180' : ''\" />\n </button>\n </div>\n </div>\n</template>\n","import { ERROR_TYPE } from '@/constants'\nimport { WrongWordItem } from '@/type'\nimport { Editor } from '@tiptap/core'\nimport { Plugin, PluginKey } from 'prosemirror-state'\nimport { Decoration, DecorationSet } from 'prosemirror-view'\n\nconst HIGHLIGHT_KEY = new PluginKey('bulk-spellcheck-highlight')\n\nfunction createHighlightPlugin(editor: Editor, errors: WrongWordItem[], blockSeparator = '\\n') {\n return new Plugin({\n key: HIGHLIGHT_KEY,\n props: {\n decorations(state) {\n const decos: Decoration[] = []\n const errorColorMap = {\n [ERROR_TYPE.SPACING]: 'bulk-highlight text-blue-500 border-b-2 border-blue-500',\n [ERROR_TYPE.SPELLING]: 'bulk-highlight text-red-500 border-b-2 border-red-500',\n }\n\n errors.forEach(item => {\n const from = findDocPosFromOffset(editor, item.startIndex, blockSeparator)\n const to = findDocPosFromOffset(editor, item.endIndex - 1, blockSeparator) + 1\n\n const errorType = item.errorHelpDtos?.[0]?.errorType\n const className = errorColorMap[errorType ?? -1] || 'bulk-highlight text-green-500 border-b-2 border-green-500' // type integrated\n\n const safeFrom = Math.max(0, Math.min(from, state.doc.content.size))\n const safeTo = Math.max(0, Math.min(to, state.doc.content.size))\n if (safeFrom < safeTo) {\n decos.push(Decoration.inline(safeFrom, safeTo, { class: className }))\n }\n })\n\n return DecorationSet.create(state.doc, decos)\n },\n },\n })\n}\n\nexport function applyHighlights(editor: Editor, errors: WrongWordItem[]) {\n editor.unregisterPlugin(HIGHLIGHT_KEY)\n\n if (!errors.length) return\n\n const plugin = createHighlightPlugin(editor, errors)\n editor.registerPlugin(plugin)\n}\n\nexport function clearHighlights(editor: Editor) {\n if (!editor) return\n\n editor.unregisterPlugin(HIGHLIGHT_KEY)\n}\n\nexport function buildPlainIndexToDocPosMap(editor: Editor, blockSeparator = '\\n') {\n const map: (number | null)[] = []\n let plainIndex = 0\n let firstBlock = true\n\n editor.state.doc.descendants((node, pos) => {\n if (node.isText && node.text) {\n for (let i = 0; i < node.text.length; i++) {\n map[plainIndex++] = pos + i\n }\n }\n\n const nodeName = node.type && (node.type as any).name\n const isHardBreak = nodeName === 'hardBreak' || nodeName === 'hard_break' || nodeName === 'br'\n if (isHardBreak && blockSeparator.length > 0) {\n for (let k = 0; k < blockSeparator.length; k++) {\n map[plainIndex++] = pos\n }\n }\n\n if (node.isBlock) {\n if (!firstBlock && blockSeparator.length > 0) {\n for (let k = 0; k < blockSeparator.length; k++) {\n map[plainIndex++] = pos \n }\n }\n firstBlock = false\n }\n\n return true\n })\n\n return map\n}\n\nexport function findDocPosFromOffset(editor: Editor,offset: number, blockSeparator = '\\n') {\n const map = buildPlainIndexToDocPosMap(editor, blockSeparator)\n if (offset < 0) offset = 0\n if (offset >= map.length) {\n return editor.state.doc.content.size\n }\n const mapped = map[offset]\n if (mapped == null) {\n for (let i = offset; i < map.length; i++) if (map[i] != null) return map[i] as number\n for (let i = offset - 1; i >= 0; i--) if (map[i] != null) return map[i] as number\n return editor.state.doc.content.size\n }\n return mapped as number\n}\n","<script setup lang=\"ts\">\nimport { EDITOR_NAME, EditorName, ERROR_TYPE } from '@/constants'\nimport { ArrowLeftRight } from 'lucide-vue-next'\nimport { Editor } from '@tiptap/core'\nimport { EditorsState, WrongWordItem } from '@/type'\nimport { applyHighlights, findDocPosFromOffset } from '@/utils/bulkSpellchecker'\n\ninterface Props {\n editorsState: EditorsState\n}\nconst props = defineProps<Props>()\n\nfunction getErrorColor(errorType?: number) {\n const errorColorMap = {\n [ERROR_TYPE.SPACING]: 'bg-blue-500',\n [ERROR_TYPE.SPELLING]: 'bg-red-500',\n }\n return errorColorMap[errorType ?? -1] || 'bg-green-500' // integrated\n}\n\nfunction getNoSuggestionText(editor: Editor) {\n return editor?.extensionStorage?.spellchecker?.spellchecker?.uiStrings?.uiStrings || 'No suggestions found'\n}\n\nfunction resetHightlightSection(key: EditorName) {\n if (key === EDITOR_NAME.EDITOR_COMMENT) {\n props.editorsState[EDITOR_NAME.EDITOR_CONTENT].editor?.commands.setTextSelection(0)\n return\n }\n\n if (key === EDITOR_NAME.EDITOR_CONTENT) {\n props.editorsState[EDITOR_NAME.EDITOR_COMMENT].editor?.commands.setTextSelection(0)\n return\n }\n}\n\nfunction scrollToError(key: EditorName, editor: Editor, item: WrongWordItem) {\n if (!editor) return\n\n resetHightlightSection(key)\n\n const from = findDocPosFromOffset(editor, item.startIndex)\n const to = findDocPosFromOffset(editor, item.endIndex - 1) + 1\n\n editor.chain().setTextSelection({ from, to }).focus().run()\n\n const mid = Math.max(0, Math.floor((from + to) / 2))\n const domAtPos = editor.view.domAtPos(mid)\n const maybeNode = domAtPos.node as unknown\n\n let el: HTMLElement | null = null\n\n if (maybeNode instanceof Element) {\n el = maybeNode as HTMLElement\n } else if (maybeNode instanceof Text) {\n el = maybeNode.parentElement\n } else {\n el = (maybeNode as any)?.parentElement ?? (editor.view.dom as HTMLElement)\n }\n\n if (el?.scrollIntoView) {\n el.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n}\n\nfunction replaceWithCorrectWord(editor: Editor, errors: WrongWordItem[], item: WrongWordItem, replacement: string) {\n if (!editor) return\n\n const from = findDocPosFromOffset(editor, item.startIndex)\n const to = findDocPosFromOffset(editor, item.endIndex - 1) + 1\n\n const tr = editor.state.tr.insertText(replacement, from, to)\n editor.view.dispatch(tr)\n editor.view.focus()\n\n const delta = replacement.length - (item.wrongWord?.length ?? 0)\n const origStart = item.startIndex\n const origEnd = item.endIndex\n\n for (let i = errors.length - 1; i >= 0; i--) {\n const err = errors[i]\n\n if (err.startIndex >= origStart && err.startIndex < origEnd) {\n errors.splice(i, 1)\n continue\n }\n\n if (err.startIndex > origStart) {\n err.startIndex += delta\n err.endIndex += delta\n }\n }\n\n const idx = errors.indexOf(item)\n if (idx !== -1) errors.splice(idx, 1)\n\n applyHighlights(editor, errors)\n}\n\nconst contentEl = ref<HTMLElement | null>(null)\nconst standardMaxHeight = 450\nconst maxHeight = ref(standardMaxHeight)\nconst { height: windowHeight } = useWindowSize()\n\nfunction computeMaxHeight() {\n const el = contentEl.value\n if (!el) return\n\n const gap = 80\n const rect = el.getBoundingClientRect()\n const availableViewportHeight = windowHeight.value - rect.top - gap\n\n maxHeight.value = standardMaxHeight > availableViewportHeight ? availableViewportHeight : standardMaxHeight\n}\n\nonMounted(() => {\n computeMaxHeight()\n useEventListener(window, 'resize', computeMaxHeight)\n})\n</script>\n\n<template>\n <div ref=\"contentEl\" :style=\"{ maxHeight: `${maxHeight}px` }\" class=\"pr-1 overflow-y-auto\">\n <template v-for=\"(editorData, key) in editorsState\" :key=\"key\">\n <div\n v-for=\"(item, idx) in editorData.wrongWords\"\n :key=\"idx\"\n class=\"border-b border-gray-400 dark:border-ed-muted pb-5 mb-5 cursor-pointer\"\n @click=\"scrollToError(key, editorsState[key].editor as Editor, item)\"\n >\n <div class=\"flex items-center mb-2\">\n <span class=\"w-16 font-medium\">입력 내용</span>\n <div class=\"flex items-center gap-2\">\n <span class=\"w-1.5 h-1.5 rounded-full\" :class=\"getErrorColor(item.errorHelpDtos[0]?.errorType)\"></span>\n <span class=\"break-all whitespace-normal\">{{ item.wrongWord }}</span>\n </div>\n </div>\n\n <div class=\"flex items-center mb-2\">\n <span class=\"w-16 font-medium\">대치어</span>\n <div v-if=\"item.correctWord.length\" class=\"flex-1 space-y-1\">\n <div\n v-for=\"(sub, sidx) in item.correctWord\"\n :key=\"sidx\"\n class=\"font-semibold px-3 py-1.5 rounded bg-gray-100 dark:bg-ed-muted flex items-center justify-between\"\n >\n <div class=\"text-sm\">\n {{ sub }}\n </div>\n <button\n class=\"flex items-center gap-1 text-blue-500\"\n @click.stop=\"replaceWithCorrectWord(editorData.editor as Editor, editorData.wrongWords, item, sub)\"\n >\n <ArrowLeftRight class=\"w-4 h-4\" /> <span>바꾸기</span>\n </button>\n </div>\n </div>\n <div v-else>\n {{ getNoSuggestionText(editorData.editor as Editor) }}\n </div>\n </div>\n\n <div class=\"flex\">\n <span class=\"w-16 font-medium\">도움말</span>\n <div class=\"flex-1\">\n <BulkSpellCheckerHelpText :text=\"item.errorHelpDtos[0]?.errorMessage\" />\n </div>\n </div>\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { cn } from '@/utils'\n\ninterface Props {\n fillWhite?: boolean\n class?: string\n}\nconst props = withDefaults(defineProps<Props>(), {\n fillWhite: false,\n class: '',\n})\n</script>\n\n<template>\n <svg :class=\"cn('animate-spin h-5 w-5 mr-0.5', props.class)\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle\n v-if=\"fillWhite\"\n class=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n fill=\"#ffffff\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n ></circle>\n <circle v-else class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path\n class=\"opacity-100\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n ></path>\n </svg>\n</template>\n\n<style scoped></style>\n","<template>\n <div class=\"min-h-[188px] flex flex-col items-center justify-center gap-y-2 text-sm\">\n <SpinnerIcon fill-white class=\"h-10 w-10 text-blue-500\" />\n <div>맞춤법 검사 중입니다</div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { SPELL_CHECK_STATUS, SpellCheckStatus } from '@/constants'\nimport { cn } from '@/utils'\nimport { EditorsState } from '@/type'\n\ninterface Props {\n editorsState: EditorsState,\n spellCheckStatus: SpellCheckStatus\n allWrongWordsMissSuggestions: boolean\n}\nconst props = defineProps<Props>()\n\nconst emit = defineEmits<{\n (e: 'close-modal'): void\n (e: 'run-spellcheck'): void\n (e: 'replace-all-editor-errors'): void\n}>()\n</script>\n\n<template>\n <div class=\"text-xs py-4 px-6\">\n <BulkSpellCheckerLoading v-if=\"spellCheckStatus === SPELL_CHECK_STATUS.LOADING\" />\n <BulkSpellCheckerWrongWordList v-else-if=\"spellCheckStatus === SPELL_CHECK_STATUS.HAS_ERROR\" :editorsState=\"editorsState\" />\n <BulkSpellCheckerNotWrongWord v-else-if=\"spellCheckStatus === SPELL_CHECK_STATUS.NO_ERROR\" />\n <BulkSpellCheckerFail v-else-if=\"spellCheckStatus === SPELL_CHECK_STATUS.FAIL\" />\n\n <div class=\"flex items-center justify-between mt-3\">\n <ul class=\"flex items-cente gap-x-4\">\n <li class=\"flex items-center gap-x-1\"><span class=\"w-1.5 h-1.5 rounded-full bg-red-500\"></span>맞춤법</li>\n <li class=\"flex items-center gap-x-1\"><span class=\"w-1.5 h-1.5 rounded-full bg-blue-500\"></span>띄어쓰기</li>\n <li class=\"flex items-center gap-x-1\"><span class=\"w-1.5 h-1.5 rounded-full bg-green-500\"></span>통합교정</li>\n </ul>\n\n <div class=\"flex gap-x-1\">\n <Button\n variant=\"outline\"\n :class=\"\n cn(\n 'border-blue-500 text-blue-500 text-xs px-3 py-2 h-auto hover:bg-white/80 hover:opacity-80 hover:text-blue-500 dark:text-dark-blue-100 dark:hover:bg-dark-blue-400 dark:hover:text-dark-blue-50 dark:hover:border-dark-blue-100',\n spellCheckStatus === SPELL_CHECK_STATUS.LOADING &&\n 'text-gray-300 bg-gray-100 border-gray-100 pointer-events-none dark:bg-ed-muted/70 dark:border-ed-muted/70 dark:text-gray-500'\n )\n \"\n @click=\"emit('run-spellcheck')\"\n >다시 검사하기</Button\n >\n\n <Button\n :class=\"\n cn(\n 'border-blue-500 text-white text-xs px-3 py-2 h-auto bg-blue-500 hover:bg-blue-500/80',\n (spellCheckStatus !== SPELL_CHECK_STATUS.HAS_ERROR || allWrongWordsMissSuggestions) &&\n 'text-gray-300 bg-gray-100 hover:bg-gray-100 pointer-events-none dark:bg-ed-muted/70 dark:text-gray-500'\n )\n \"\n @click=\"emit('replace-all-editor-errors')\"\n >모두 바꾸기</Button\n >\n </div>\n </div>\n </div>\n</template>\n","import { EDITOR_NAME, EditorName, SPELL_CHECK_CODE, SPELL_CHECK_STATUS, SpellCheckStatus } from '@/constants'\nimport { EditorsState, SpellCheckResponse, WrongWordItem } from '@/type'\nimport { Editor } from '@tiptap/core'\nimport axios from 'axios'\nimport { applyHighlights, clearHighlights, buildPlainIndexToDocPosMap } from '@/utils/bulkSpellchecker'\nimport { SPELLCHECKER_META_LIST } from '@/extensions/SpellChecker/spellchecker-extension'\n\nexport const useBulkSpellCheckerStore = () => {\n const editorsState: EditorsState = reactive({\n [EDITOR_NAME.EDITOR_COMMENT]: {\n editor: null,\n wrongWords: [],\n },\n [EDITOR_NAME.EDITOR_CONTENT]: {\n editor: null,\n wrongWords: [],\n },\n })\n\n function setEditor(editorKey: EditorName, editorInstance: Editor | null) {\n editorsState[editorKey].editor = editorInstance\n }\n\n const spellCheckStatus = ref<SpellCheckStatus>(SPELL_CHECK_STATUS.NO_ERROR)\n\n function resetAllEditorWrongWords() {\n Object.values(editorsState).forEach(editorState => {\n editorState.wrongWords = []\n })\n }\n\n function evaluateStatus(hasFail: boolean, hasError: boolean) {\n if (hasFail) return SPELL_CHECK_STATUS.FAIL\n if (hasError) return SPELL_CHECK_STATUS.HAS_ERROR\n return SPELL_CHECK_STATUS.NO_ERROR\n }\n\n async function handleRunSpellCheck() {\n spellCheckStatus.value = SPELL_CHECK_STATUS.LOADING\n\n let hasError = false\n let hasFail = false\n\n for (const [editorKey, { editor }] of Object.entries(editorsState)) {\n if (!editor) continue\n\n const apiUrl = editor?.extensionManager.extensions.find(ext => ext.name === 'spellchecker')?.options.proofreader\n .api\n const content = editor.getText({ blockSeparator: '\\n' })\n if (!apiUrl || !content) continue\n\n try {\n const { data: response } = await axios.post<SpellCheckResponse>(apiUrl, {\n value: content,\n })\n\n if (!response.success && response.code !== SPELL_CHECK_CODE.NOTHING_TO_CHANGE) {\n hasFail = true\n editorsState[editorKey].wrongWords = []\n continue\n }\n\n if (response.data?.wrongWordResponseDto) {\n hasError = true\n editorsState[editorKey].wrongWords = response.data.wrongWordResponseDto\n continue\n }\n\n editorsState[editorKey].wrongWords = []\n } catch (error) {\n console.error('handleRunSpellCheck error: ', error)\n hasFail = true\n }\n }\n\n spellCheckStatus.value = evaluateStatus(hasFail, hasError)\n }\n\n const countTotalWrongWords = computed(() => {\n return Object.values(editorsState).reduce((sum, { wrongWords }) => {\n return sum + wrongWords.length\n }, 0)\n })\n\n watch(countTotalWrongWords, newVal => {\n if (newVal === 0) {\n spellCheckStatus.value = evaluateStatus(false, false)\n }\n })\n\n const allWrongWordsMissSuggestions = computed(() => {\n const allWrongWords = Object.values(editorsState).flatMap(es => es.wrongWords)\n if (allWrongWords.length === 0) return false\n return allWrongWords.every(w => !Array.isArray(w.correctWord) || w.correctWord.length === 0)\n })\n\n function applyAllEditorHighlightErrors() {\n for (const [_, { editor, wrongWords }] of Object.entries(editorsState)) {\n if (!editor) continue\n applyHighlights(editor as Editor, wrongWords)\n }\n }\n\n function clearAllEditorHighlightErrors() {\n for (const [_, { editor }] of Object.entries(editorsState)) {\n if (!editor) continue\n clearHighlights(editor as Editor)\n }\n }\n\n async function reRunSpellCheckAndHighlight() {\n await handleRunSpellCheck()\n applyAllEditorHighlightErrors()\n }\n\n let isEnableCurrent = true\n function disableSpellCheckRealTime(isEnableSpellCheckRealTime: boolean) {\n isEnableCurrent = isEnableSpellCheckRealTime\n if (!isEnableSpellCheckRealTime) return\n\n for (const [_, { editor }] of Object.entries(editorsState)) {\n if (!editor) continue\n editor.extensionStorage.spellchecker.spellchecker.setEnabledProofreadText(false)\n editor.view.dispatch(editor.state.tr.setMeta(SPELLCHECKER_META_LIST.IS_ACTIVE_SPELLCHECK, false))\n }\n }\n\n function resetEnableSpellCheckRealTime() {\n if (!isEnableCurrent) return\n\n for (const [_, { editor }] of Object.entries(editorsState)) {\n if (!editor) continue\n editor.extensionStorage.spellchecker.spellchecker.setEnabledProofreadText(true)\n editor.view.dispatch(editor.state.tr.setMeta(SPELLCHECKER_META_LIST.IS_ACTIVE_SPELLCHECK, true))\n }\n }\n\n function replaceAllErrors(editor: Editor, errors: WrongWordItem[], blockSeparator = '\\n') {\n if (!editor) return\n if (!errors.length) return\n\n const map = buildPlainIndexToDocPosMap(editor, blockSeparator)\n\n function getMappedPos(offset: number) {\n if (offset < 0) offset = 0\n if (offset >= map.length) return editor.state.doc.content.size\n if (map[offset] != null) return map[offset] as number\n for (let i = offset; i < map.length; i++) if (map[i] != null) return map[i] as number\n for (let i = offset - 1; i >= 0; i--) if (map[i] != null) return map[i] as number\n return editor.state.doc.content.size\n }\n\n const replacements = errors.map(item => {\n const from = getMappedPos(item.startIndex)\n const to = getMappedPos(Math.max(0, item.endIndex - 1)) + 1\n const replacement = item.correctWord?.[0] ?? item.wrongWord\n return { item, from, to, replacement }\n })\n\n const validRepls = replacements.filter(r => typeof r.from === 'number' && typeof r.to === 'number' && r.from < r.to)\n\n if (!validRepls.length) return\n\n validRepls.sort((a, b) => b.from - a.from)\n\n const tr = editor.state.tr\n let lastAppliedFrom = Number.POSITIVE_INFINITY\n const appliedItems = new Set<WrongWordItem>()\n\n for (const r of validRepls) {\n if (r.to > lastAppliedFrom) {\n continue\n }\n\n tr.insertText(r.replacement, r.from, r.to)\n\n appliedItems.add(r.item)\n lastAppliedFrom = r.from\n }\n\n if (appliedItems.size > 0) {\n editor.view.dispatch(tr)\n editor.view.focus()\n }\n\n if (appliedItems.size > 0) {\n errors = errors.filter(e => ![...appliedItems].some(a => a === e))\n }\n\n applyHighlights(editor, errors)\n }\n\n function replaceAllEditorErrors() {\n for (const [_, { editor, wrongWords }] of Object.entries(editorsState)) {\n if (!editor) continue\n replaceAllErrors(editor as Editor, wrongWords)\n }\n }\n\n return {\n editorsState,\n spellCheckStatus,\n countTotalWrongWords,\n allWrongWordsMissSuggestions,\n setEditor,\n resetAllEditorWrongWords,\n disableSpellCheckRealTime,\n resetEnableSpellCheckRealTime,\n applyAllEditorHighlightErrors,\n clearAllEditorHighlightErrors,\n reRunSpellCheckAndHighlight,\n handleRunSpellCheck,\n replaceAllEditorErrors,\n }\n}\n","<script setup lang=\"ts\">\nimport { DialogTrigger, type DialogTriggerProps } from 'radix-vue'\n\nconst props = defineProps<DialogTriggerProps>()\n</script>\n\n<template>\n <DialogTrigger v-bind=\"props\">\n <slot />\n </DialogTrigger>\n</template>\n","<script setup lang=\"ts\">\nimport { EDITOR_NAME } from '@/constants'\nimport { useBulkSpellCheckerStore } from '@/hooks/useBulkSpellCheckerStore'\nimport { Editor } from '@tiptap/core'\nimport { DialogTrigger } from './ui/dialog'\n\ninterface Props {\n editor: Editor\n editorComment?: Editor\n isEnableSpellCheckRealTime: boolean\n}\nconst props = defineProps<Props>()\n\nconst {\n editorsState,\n countTotalWrongWords,\n spellCheckStatus,\n allWrongWordsMissSuggestions,\n setEditor,\n disableSpellCheckRealTime,\n resetEnableSpellCheckRealTime,\n handleRunSpellCheck,\n resetAllEditorWrongWords,\n applyAllEditorHighlightErrors,\n clearAllEditorHighlightErrors,\n reRunSpellCheckAndHighlight,\n replaceAllEditorErrors,\n} = useBulkSpellCheckerStore()\n\nconst isOpenModal = ref(false)\n\nconst dragOffset = reactive({ x: 0, y: 0 })\nconst dragging = ref(false)\nconst offset = { x: 0, y: 0 }\n\nconst onMouseDown = (e: MouseEvent) => {\n dragging.value = true\n offset.x = e.clientX - dragOffset.x\n offset.y = e.clientY - dragOffset.y\n document.addEventListener('mousemove', onMouseMove)\n document.addEventListener('mouseup', onMouseUp)\n}\n\nconst onMouseMove = (e: MouseEvent) => {\n if (!dragging.value) return\n dragOffset.x = e.clientX - offset.x\n dragOffset.y = e.clientY - offset.y\n}\n\nconst onMouseUp = () => {\n dragging.value = false\n document.removeEventListener('mousemove', onMouseMove)\n document.removeEventListener('mouseup', onMouseUp)\n}\n\nonUnmounted(() => {\n document.removeEventListener('mousemove', onMouseMove)\n document.removeEventListener('mouseup', onMouseUp)\n})\n\nconst triggerRef = ref<InstanceType<typeof DialogTrigger> | null>(null)\nconst position = ref({ top: 0, right: 0 })\n\nconst updatePosition = () => {\n if (triggerRef.value) {\n const rect = triggerRef.value.$el.getBoundingClientRect()\n\n position.value = {\n top: rect.bottom + window.scrollY + 5,\n right: window.innerWidth - rect.right - window.scrollX,\n }\n\n dragOffset.x = 0\n dragOffset.y = 0\n }\n}\n\nonMounted(async () => {\n if (props.editorComment) {\n setEditor(EDITOR_NAME.EDITOR_COMMENT, props.editorComment)\n }\n setEditor(EDITOR_NAME.EDITOR_CONTENT, props.editor)\n})\n\nonUnmounted(() => {\n setEditor(EDITOR_NAME.EDITOR_COMMENT, null)\n setEditor(EDITOR_NAME.EDITOR_CONTENT, null)\n})\n\nwatch(isOpenModal, async val => {\n if (val) {\n await nextTick()\n updatePosition()\n disableSpellCheckRealTime(props.isEnableSpellCheckRealTime)\n await handleRunSpellCheck()\n applyAllEditorHighlightErrors()\n } else {\n resetAllEditorWrongWords()\n resetEnableSpellCheckRealTime()\n clearAllEditorHighlightErrors()\n }\n})\n\nconst bulkSpellCheckerBtnConfig = props.editor?.extensionManager.extensions.find(e => e.name === 'spellchecker')\n ?.options.bulkSpellCheckerButton\n</script>\n\n<template>\n <Dialog :open=\"isOpenModal\">\n <DialogTrigger as-child ref=\"triggerRef\" @click=\"isOpenModal = !isOpenModal\">\n <button\n v-if=\"!bulkSpellCheckerBtnConfig\"\n class=\"border-blue-500 text-white text-xs text-nowrap px-3 py-2 h-auto bg-blue-500 hover:bg-blue-500/80 flex items-center rounded\"\n >\n <Icon name=\"checkUnderline\" />맞춤법 일괄 교정\n </button>\n\n <component\n v-else\n :is=\"bulkSpellCheckerBtnConfig.component\"\n :buttonName=\"bulkSpellCheckerBtnConfig.props.buttonName\"\n :icon=\"bulkSpellCheckerBtnConfig.props.icon\"\n :type=\"bulkSpellCheckerBtnConfig.props.type\"\n :disabled=\"bulkSpellCheckerBtnConfig.props.disabled\"\n :iconPosition=\"bulkSpellCheckerBtnConfig.props.iconPosition\"\n :buttonSize=\"bulkSpellCheckerBtnConfig.props.buttonSize\"\n :iconClass=\"bulkSpellCheckerBtnConfig.props.iconClass\"\n />\n </DialogTrigger>\n\n <DialogContent is-overlay-transparent class=\"p-0 gap-0 !animate-none !transition-none dark:border-ed-muted\" as-child>\n <div\n class=\"z-[70]\"\n :style=\"{\n transform: `translate(${dragOffset.x}px, ${dragOffset.y}px)`,\n top: `${position.top}px`,\n right: `${position.right}px`,\n left: 'auto',\n }\"\n >\n <DialogHeader\n class=\"bg-ed-blue-light py-3.5 px-6 rounded-t-[5px] cursor-move text-blue-500 dark:text-dark-blue-100 flex-row items-center justify-between\"\n @mousedown.prevent=\"onMouseDown\"\n >\n <DialogTitle class=\"text-base space-x-2\">\n <span>맞춤법/문법 오류</span>\n <Badge class=\"text-sm bg-blue-500 hover:bg-blue-500 dark:bg-dark-blue-100 px-2\">{{ countTotalWrongWords }}개</Badge></DialogTitle\n >\n\n <DialogClose @click=\"isOpenModal = false\" class=\"text-xs flex items-center gap-x-1\">\n <Icon name=\"Close\" class=\"w-4 h-4\" />{{ $t('editor.close') }}\n </DialogClose>\n </DialogHeader>\n\n <DialogDescription></DialogDescription>\n\n <BulkSpellCheckerContent\n :editorsState=\"editorsState\"\n :spellCheckStatus=\"spellCheckStatus\"\n :allWrongWordsMissSuggestions=\"allWrongWordsMissSuggestions\"\n @close-modal=\"isOpenModal = false\"\n @run-spellcheck=\"reRunSpellCheckAndHighlight\"\n @replace-all-editor-errors=\"(replaceAllEditorErrors(), (isOpenModal = false))\"\n />\n </div>\n </DialogContent>\n </Dialog>\n</template>\n\n<style scoped></style>\n"],"names":["ERROR_TYPE","SPELL_CHECK_CODE","SPELL_CHECK_STATUS","EDITOR_NAME","ArrowLeftRight","createLucideIcon","CircleAlert","CircleCheck","expanded","ref","showButton","helpRef","toggle","onMounted","nextTick","HIGHLIGHT_KEY","PluginKey","createHighlightPlugin","editor","errors","blockSeparator","Plugin","state","decos","errorColorMap","item","from","findDocPosFromOffset","to","errorType","_b","_a","className","safeFrom","safeTo","Decoration","DecorationSet","applyHighlights","plugin","clearHighlights","buildPlainIndexToDocPosMap","map","plainIndex","firstBlock","node","pos","i","nodeName","k","offset","mapped","standardMaxHeight","props","__props","getErrorColor","getNoSuggestionText","_d","_c","resetHightlightSection","key","scrollToError","mid","maybeNode","el","replaceWithCorrectWord","replacement","tr","delta","origStart","origEnd","err","idx","contentEl","maxHeight","windowHeight","useWindowSize","computeMaxHeight","gap","rect","availableViewportHeight","useEventListener","_openBlock","_createElementBlock","_hoisted_1","_createVNode","_component_SpinnerIcon","emit","__emit","useBulkSpellCheckerStore","editorsState","reactive","setEditor","editorKey","editorInstance","spellCheckStatus","resetAllEditorWrongWords","editorState","evaluateStatus","hasFail","hasError","handleRunSpellCheck","apiUrl","ext","content","response","axios","error","countTotalWrongWords","computed","sum","wrongWords","watch","newVal","allWrongWordsMissSuggestions","allWrongWords","es","w","applyAllEditorHighlightErrors","_","clearAllEditorHighlightErrors","reRunSpellCheckAndHighlight","isEnableCurrent","disableSpellCheckRealTime","isEnableSpellCheckRealTime","SPELLCHECKER_META_LIST","resetEnableSpellCheckRealTime","replaceAllErrors","getMappedPos","validRepls","r","a","b","lastAppliedFrom","appliedItems","e","replaceAllEditorErrors","isOpenModal","dragOffset","dragging","onMouseDown","onMouseMove","onMouseUp","onUnmounted","triggerRef","position","updatePosition","val","bulkSpellCheckerBtnConfig"],"mappings":"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","x_google_ignoreList":[1,2,3]}
|
|
1
|
+
{"version":3,"file":"BulkSpellChecker-Btu4LaPx.mjs","sources":["../src/constants/bulkSpellChecker.ts","../node_modules/lucide-vue-next/dist/esm/icons/arrow-left-right.js","../node_modules/lucide-vue-next/dist/esm/icons/circle-alert.js","../node_modules/lucide-vue-next/dist/esm/icons/circle-check.js","../src/components/BulkSpellCheckerHelpText.vue","../src/utils/bulkSpellchecker.ts","../src/components/BulkSpellCheckerWrongWordList.vue","../src/components/ui/SpinnerIcon.vue","../src/components/BulkSpellCheckerLoading.vue","../src/components/BulkSpellCheckerContent.vue","../src/hooks/useBulkSpellCheckerStore.ts","../src/components/ui/dialog/DialogTrigger.vue","../src/components/BulkSpellChecker.vue"],"sourcesContent":["export const ERROR_TYPE = {\n SPACING: 1,\n SPELLING: 2,\n}\n\nexport const SPELL_CHECK_CODE = {\n NOTHING_TO_CHANGE: 'NOTHING_TO_CHANGE',\n} as const\n\nexport const SPELL_CHECK_STATUS = {\n LOADING: 'loading',\n HAS_ERROR: 'hasError',\n NO_ERROR: 'noError',\n FAIL: 'fail',\n} as const\n\nexport type SpellCheckStatus = (typeof SPELL_CHECK_STATUS)[keyof typeof SPELL_CHECK_STATUS]\n\nexport const EDITOR_NAME = {\n EDITOR_COMMENT: 'editorComment',\n EDITOR_CONTENT: 'editorContent',\n} as const\n\nexport type EditorName = (typeof EDITOR_NAME)[keyof typeof EDITOR_NAME]\n","/**\n * @license lucide-vue-next v0.439.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ArrowLeftRight = createLucideIcon(\"ArrowLeftRightIcon\", [\n [\"path\", { d: \"M8 3 4 7l4 4\", key: \"9rb6wj\" }],\n [\"path\", { d: \"M4 7h16\", key: \"6tx8e3\" }],\n [\"path\", { d: \"m16 21 4-4-4-4\", key: \"siv7j2\" }],\n [\"path\", { d: \"M20 17H4\", key: \"h6l3hr\" }]\n]);\n\nexport { ArrowLeftRight as default };\n//# sourceMappingURL=arrow-left-right.js.map\n","/**\n * @license lucide-vue-next v0.439.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleAlert = createLucideIcon(\"CircleAlertIcon\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"8\", y2: \"12\", key: \"1pkeuh\" }],\n [\"line\", { x1: \"12\", x2: \"12.01\", y1: \"16\", y2: \"16\", key: \"4dfq90\" }]\n]);\n\nexport { CircleAlert as default };\n//# sourceMappingURL=circle-alert.js.map\n","/**\n * @license lucide-vue-next v0.439.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleCheck = createLucideIcon(\"CircleCheckIcon\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"m9 12 2 2 4-4\", key: \"dzmm74\" }]\n]);\n\nexport { CircleCheck as default };\n//# sourceMappingURL=circle-check.js.map\n","<script setup lang=\"ts\">\nimport { cn } from '@/utils'\nimport { ChevronDown } from 'lucide-vue-next'\n\ninterface Props {\n text: string\n}\nconst props = defineProps<Props>()\n\nconst expanded = ref(false)\nconst showButton = ref(false)\nconst helpRef = ref<HTMLElement | null>(null)\n\nfunction toggle() {\n expanded.value = !expanded.value\n}\n\nonMounted(async () => {\n await nextTick()\n if (helpRef.value && helpRef.value.scrollHeight > 32) {\n showButton.value = true\n }\n})\n</script>\n\n<template>\n <div class=\"relative\">\n <div\n ref=\"helpRef\"\n class=\"text-gray-700 dark:text-gray-400 transition-all\"\n :class=\"expanded ? 'max-h-none' : 'max-h-[32px] overflow-hidden'\"\n v-html=\"text\"\n ></div>\n\n <div\n v-if=\"showButton\"\n class=\"\"\n :class=\"\n cn(\n 'w-32 flex items-end justify-end bg-gradient-to-l from-white via-white to-transparent dark:from-ed-background dark:via-ed-background',\n expanded ? 'ml-auto opacity-60' : 'absolute bottom-0 right-0'\n )\n \"\n >\n <button class=\"flex items-center gap-1\" @click.stop=\"toggle\">\n <span class=\"border-b border-gray-500\">{{ expanded ? '접기' : '자세히' }}</span>\n <ChevronDown class=\"w-4 h-4 transition-transform\" :class=\"expanded ? 'rotate-180' : ''\" />\n </button>\n </div>\n </div>\n</template>\n","import { ERROR_TYPE } from '@/constants'\nimport { WrongWordItem } from '@/type'\nimport { Editor } from '@tiptap/core'\nimport { Plugin, PluginKey } from 'prosemirror-state'\nimport { Decoration, DecorationSet } from 'prosemirror-view'\n\nconst HIGHLIGHT_KEY = new PluginKey('bulk-spellcheck-highlight')\n\nfunction createHighlightPlugin(editor: Editor, errors: WrongWordItem[], blockSeparator = '\\n') {\n return new Plugin({\n key: HIGHLIGHT_KEY,\n props: {\n decorations(state) {\n const decos: Decoration[] = []\n const errorColorMap = {\n [ERROR_TYPE.SPACING]: 'bulk-highlight text-blue-500 border-b-2 border-blue-500',\n [ERROR_TYPE.SPELLING]: 'bulk-highlight text-red-500 border-b-2 border-red-500',\n }\n\n errors.forEach(item => {\n const from = findDocPosFromOffset(editor, item.startIndex, blockSeparator)\n const to = findDocPosFromOffset(editor, item.endIndex - 1, blockSeparator) + 1\n\n const errorType = item.errorHelpDtos?.[0]?.errorType\n const className = errorColorMap[errorType ?? -1] || 'bulk-highlight text-green-500 border-b-2 border-green-500' // type integrated\n\n const safeFrom = Math.max(0, Math.min(from, state.doc.content.size))\n const safeTo = Math.max(0, Math.min(to, state.doc.content.size))\n if (safeFrom < safeTo) {\n decos.push(Decoration.inline(safeFrom, safeTo, { class: className }))\n }\n })\n\n return DecorationSet.create(state.doc, decos)\n },\n },\n })\n}\n\nexport function applyHighlights(editor: Editor, errors: WrongWordItem[]) {\n editor.unregisterPlugin(HIGHLIGHT_KEY)\n\n if (!errors.length) return\n\n const plugin = createHighlightPlugin(editor, errors)\n editor.registerPlugin(plugin)\n}\n\nexport function clearHighlights(editor: Editor) {\n if (!editor) return\n\n editor.unregisterPlugin(HIGHLIGHT_KEY)\n}\n\nexport function buildPlainIndexToDocPosMap(editor: Editor, blockSeparator = '\\n') {\n const map: (number | null)[] = []\n let plainIndex = 0\n let firstBlock = true\n\n editor.state.doc.descendants((node, pos) => {\n if (node.isText && node.text) {\n for (let i = 0; i < node.text.length; i++) {\n map[plainIndex++] = pos + i\n }\n }\n\n const nodeName = node.type && (node.type as any).name\n const isHardBreak = nodeName === 'hardBreak' || nodeName === 'hard_break' || nodeName === 'br'\n if (isHardBreak && blockSeparator.length > 0) {\n for (let k = 0; k < blockSeparator.length; k++) {\n map[plainIndex++] = pos\n }\n }\n\n if (node.isBlock) {\n if (!firstBlock && blockSeparator.length > 0) {\n for (let k = 0; k < blockSeparator.length; k++) {\n map[plainIndex++] = pos \n }\n }\n firstBlock = false\n }\n\n return true\n })\n\n return map\n}\n\nexport function findDocPosFromOffset(editor: Editor,offset: number, blockSeparator = '\\n') {\n const map = buildPlainIndexToDocPosMap(editor, blockSeparator)\n if (offset < 0) offset = 0\n if (offset >= map.length) {\n return editor.state.doc.content.size\n }\n const mapped = map[offset]\n if (mapped == null) {\n for (let i = offset; i < map.length; i++) if (map[i] != null) return map[i] as number\n for (let i = offset - 1; i >= 0; i--) if (map[i] != null) return map[i] as number\n return editor.state.doc.content.size\n }\n return mapped as number\n}\n","<script setup lang=\"ts\">\nimport { EDITOR_NAME, EditorName, ERROR_TYPE } from '@/constants'\nimport { ArrowLeftRight } from 'lucide-vue-next'\nimport { Editor } from '@tiptap/core'\nimport { EditorsState, WrongWordItem } from '@/type'\nimport { applyHighlights, findDocPosFromOffset } from '@/utils/bulkSpellchecker'\n\ninterface Props {\n editorsState: EditorsState\n}\nconst props = defineProps<Props>()\n\nfunction getErrorColor(errorType?: number) {\n const errorColorMap = {\n [ERROR_TYPE.SPACING]: 'bg-blue-500',\n [ERROR_TYPE.SPELLING]: 'bg-red-500',\n }\n return errorColorMap[errorType ?? -1] || 'bg-green-500' // integrated\n}\n\nfunction getNoSuggestionText(editor: Editor) {\n return editor?.extensionStorage?.spellchecker?.spellchecker?.uiStrings?.uiStrings || 'No suggestions found'\n}\n\nfunction resetHightlightSection(key: EditorName) {\n if (key === EDITOR_NAME.EDITOR_COMMENT) {\n props.editorsState[EDITOR_NAME.EDITOR_CONTENT].editor?.commands.setTextSelection(0)\n return\n }\n\n if (key === EDITOR_NAME.EDITOR_CONTENT) {\n props.editorsState[EDITOR_NAME.EDITOR_COMMENT].editor?.commands.setTextSelection(0)\n return\n }\n}\n\nfunction scrollToError(key: EditorName, editor: Editor, item: WrongWordItem) {\n if (!editor) return\n\n resetHightlightSection(key)\n\n const from = findDocPosFromOffset(editor, item.startIndex)\n const to = findDocPosFromOffset(editor, item.endIndex - 1) + 1\n\n editor.chain().setTextSelection({ from, to }).focus().run()\n\n const mid = Math.max(0, Math.floor((from + to) / 2))\n const domAtPos = editor.view.domAtPos(mid)\n const maybeNode = domAtPos.node as unknown\n\n let el: HTMLElement | null = null\n\n if (maybeNode instanceof Element) {\n el = maybeNode as HTMLElement\n } else if (maybeNode instanceof Text) {\n el = maybeNode.parentElement\n } else {\n el = (maybeNode as any)?.parentElement ?? (editor.view.dom as HTMLElement)\n }\n\n if (el?.scrollIntoView) {\n el.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n}\n\nfunction replaceWithCorrectWord(editor: Editor, errors: WrongWordItem[], item: WrongWordItem, replacement: string) {\n if (!editor) return\n\n const from = findDocPosFromOffset(editor, item.startIndex)\n const to = findDocPosFromOffset(editor, item.endIndex - 1) + 1\n\n const tr = editor.state.tr.insertText(replacement, from, to)\n editor.view.dispatch(tr)\n editor.view.focus()\n\n const delta = replacement.length - (item.wrongWord?.length ?? 0)\n const origStart = item.startIndex\n const origEnd = item.endIndex\n\n for (let i = errors.length - 1; i >= 0; i--) {\n const err = errors[i]\n\n if (err.startIndex >= origStart && err.startIndex < origEnd) {\n errors.splice(i, 1)\n continue\n }\n\n if (err.startIndex > origStart) {\n err.startIndex += delta\n err.endIndex += delta\n }\n }\n\n const idx = errors.indexOf(item)\n if (idx !== -1) errors.splice(idx, 1)\n\n applyHighlights(editor, errors)\n}\n\nconst contentEl = ref<HTMLElement | null>(null)\nconst standardMaxHeight = 450\nconst maxHeight = ref(standardMaxHeight)\nconst { height: windowHeight } = useWindowSize()\n\nfunction computeMaxHeight() {\n const el = contentEl.value\n if (!el) return\n\n const gap = 80\n const rect = el.getBoundingClientRect()\n const availableViewportHeight = windowHeight.value - rect.top - gap\n\n maxHeight.value = standardMaxHeight > availableViewportHeight ? availableViewportHeight : standardMaxHeight\n}\n\nonMounted(() => {\n computeMaxHeight()\n useEventListener(window, 'resize', computeMaxHeight)\n})\n</script>\n\n<template>\n <div ref=\"contentEl\" :style=\"{ maxHeight: `${maxHeight}px` }\" class=\"pr-1 overflow-y-auto\">\n <template v-for=\"(editorData, key) in editorsState\" :key=\"key\">\n <div\n v-for=\"(item, idx) in editorData.wrongWords\"\n :key=\"idx\"\n class=\"border-b border-gray-400 dark:border-ed-muted pb-5 mb-5 cursor-pointer\"\n @click=\"scrollToError(key, editorsState[key].editor as Editor, item)\"\n >\n <div class=\"flex items-center mb-2\">\n <span class=\"w-16 font-medium\">입력 내용</span>\n <div class=\"flex items-center gap-2\">\n <span class=\"w-1.5 h-1.5 rounded-full\" :class=\"getErrorColor(item.errorHelpDtos[0]?.errorType)\"></span>\n <span class=\"break-all whitespace-normal\">{{ item.wrongWord }}</span>\n </div>\n </div>\n\n <div class=\"flex items-center mb-2\">\n <span class=\"w-16 font-medium\">대치어</span>\n <div v-if=\"item.correctWord.length\" class=\"flex-1 space-y-1\">\n <div\n v-for=\"(sub, sidx) in item.correctWord\"\n :key=\"sidx\"\n class=\"font-semibold px-3 py-1.5 rounded bg-gray-100 dark:bg-ed-muted flex items-center justify-between\"\n >\n <div class=\"text-sm\">\n {{ sub }}\n </div>\n <button\n class=\"flex items-center gap-1 text-blue-500\"\n @click.stop=\"replaceWithCorrectWord(editorData.editor as Editor, editorData.wrongWords, item, sub)\"\n >\n <ArrowLeftRight class=\"w-4 h-4\" /> <span>바꾸기</span>\n </button>\n </div>\n </div>\n <div v-else>\n {{ getNoSuggestionText(editorData.editor as Editor) }}\n </div>\n </div>\n\n <div class=\"flex\">\n <span class=\"w-16 font-medium\">도움말</span>\n <div class=\"flex-1\">\n <BulkSpellCheckerHelpText :text=\"item.errorHelpDtos[0]?.errorMessage\" />\n </div>\n </div>\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { cn } from '@/utils'\n\ninterface Props {\n fillWhite?: boolean\n class?: string\n}\nconst props = withDefaults(defineProps<Props>(), {\n fillWhite: false,\n class: '',\n})\n</script>\n\n<template>\n <svg :class=\"cn('animate-spin h-5 w-5 mr-0.5', props.class)\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle\n v-if=\"fillWhite\"\n class=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n fill=\"#ffffff\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n ></circle>\n <circle v-else class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path\n class=\"opacity-100\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n ></path>\n </svg>\n</template>\n\n<style scoped></style>\n","<template>\n <div class=\"min-h-[188px] flex flex-col items-center justify-center gap-y-2 text-sm\">\n <SpinnerIcon fill-white class=\"h-10 w-10 text-blue-500\" />\n <div>맞춤법 검사 중입니다</div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { SPELL_CHECK_STATUS, SpellCheckStatus } from '@/constants'\nimport { cn } from '@/utils'\nimport { EditorsState } from '@/type'\n\ninterface Props {\n editorsState: EditorsState,\n spellCheckStatus: SpellCheckStatus\n allWrongWordsMissSuggestions: boolean\n}\nconst props = defineProps<Props>()\n\nconst emit = defineEmits<{\n (e: 'close-modal'): void\n (e: 'run-spellcheck'): void\n (e: 'replace-all-editor-errors'): void\n}>()\n</script>\n\n<template>\n <div class=\"text-xs py-4 px-6\">\n <BulkSpellCheckerLoading v-if=\"spellCheckStatus === SPELL_CHECK_STATUS.LOADING\" />\n <BulkSpellCheckerWrongWordList v-else-if=\"spellCheckStatus === SPELL_CHECK_STATUS.HAS_ERROR\" :editorsState=\"editorsState\" />\n <BulkSpellCheckerNotWrongWord v-else-if=\"spellCheckStatus === SPELL_CHECK_STATUS.NO_ERROR\" />\n <BulkSpellCheckerFail v-else-if=\"spellCheckStatus === SPELL_CHECK_STATUS.FAIL\" />\n\n <div class=\"flex items-center justify-between mt-3\">\n <ul class=\"flex items-cente gap-x-4\">\n <li class=\"flex items-center gap-x-1\"><span class=\"w-1.5 h-1.5 rounded-full bg-red-500\"></span>맞춤법</li>\n <li class=\"flex items-center gap-x-1\"><span class=\"w-1.5 h-1.5 rounded-full bg-blue-500\"></span>띄어쓰기</li>\n <li class=\"flex items-center gap-x-1\"><span class=\"w-1.5 h-1.5 rounded-full bg-green-500\"></span>통합교정</li>\n </ul>\n\n <div class=\"flex gap-x-1\">\n <Button\n variant=\"outline\"\n :class=\"\n cn(\n 'border-blue-500 text-blue-500 text-xs px-3 py-2 h-auto hover:bg-white/80 hover:opacity-80 hover:text-blue-500 dark:text-dark-blue-100 dark:hover:bg-dark-blue-400 dark:hover:text-dark-blue-50 dark:hover:border-dark-blue-100',\n spellCheckStatus === SPELL_CHECK_STATUS.LOADING &&\n 'text-gray-300 bg-gray-100 border-gray-100 pointer-events-none dark:bg-ed-muted/70 dark:border-ed-muted/70 dark:text-gray-500'\n )\n \"\n @click=\"emit('run-spellcheck')\"\n >다시 검사하기</Button\n >\n\n <Button\n :class=\"\n cn(\n 'border-blue-500 text-white text-xs px-3 py-2 h-auto bg-blue-500 hover:bg-blue-500/80',\n (spellCheckStatus !== SPELL_CHECK_STATUS.HAS_ERROR || allWrongWordsMissSuggestions) &&\n 'text-gray-300 bg-gray-100 hover:bg-gray-100 pointer-events-none dark:bg-ed-muted/70 dark:text-gray-500'\n )\n \"\n @click=\"emit('replace-all-editor-errors')\"\n >모두 바꾸기</Button\n >\n </div>\n </div>\n </div>\n</template>\n","import { EDITOR_NAME, EditorName, SPELL_CHECK_CODE, SPELL_CHECK_STATUS, SpellCheckStatus } from '@/constants'\nimport { EditorsState, SpellCheckResponse, WrongWordItem } from '@/type'\nimport { Editor } from '@tiptap/core'\nimport axios from 'axios'\nimport { applyHighlights, clearHighlights, buildPlainIndexToDocPosMap } from '@/utils/bulkSpellchecker'\nimport { SPELLCHECKER_META_LIST } from '@/extensions/SpellChecker/spellchecker-extension'\n\nexport const useBulkSpellCheckerStore = () => {\n const editorsState: EditorsState = reactive({\n [EDITOR_NAME.EDITOR_COMMENT]: {\n editor: null,\n wrongWords: [],\n },\n [EDITOR_NAME.EDITOR_CONTENT]: {\n editor: null,\n wrongWords: [],\n },\n })\n\n function setEditor(editorKey: EditorName, editorInstance: Editor | null) {\n editorsState[editorKey].editor = editorInstance\n }\n\n const spellCheckStatus = ref<SpellCheckStatus>(SPELL_CHECK_STATUS.NO_ERROR)\n\n function resetAllEditorWrongWords() {\n Object.values(editorsState).forEach(editorState => {\n editorState.wrongWords = []\n })\n }\n\n function evaluateStatus(hasFail: boolean, hasError: boolean) {\n if (hasFail) return SPELL_CHECK_STATUS.FAIL\n if (hasError) return SPELL_CHECK_STATUS.HAS_ERROR\n return SPELL_CHECK_STATUS.NO_ERROR\n }\n\n async function handleRunSpellCheck() {\n spellCheckStatus.value = SPELL_CHECK_STATUS.LOADING\n\n let hasError = false\n let hasFail = false\n\n for (const [editorKey, { editor }] of Object.entries(editorsState)) {\n if (!editor) continue\n\n const apiUrl = editor?.extensionManager.extensions.find(ext => ext.name === 'spellchecker')?.options.proofreader\n .api\n const content = editor.getText({ blockSeparator: '\\n' })\n if (!apiUrl || !content) continue\n\n try {\n const { data: response } = await axios.post<SpellCheckResponse>(apiUrl, {\n value: content,\n })\n\n if (!response.success && response.code !== SPELL_CHECK_CODE.NOTHING_TO_CHANGE) {\n hasFail = true\n editorsState[editorKey].wrongWords = []\n continue\n }\n\n if (response.data?.wrongWordResponseDto) {\n hasError = true\n editorsState[editorKey].wrongWords = response.data.wrongWordResponseDto\n continue\n }\n\n editorsState[editorKey].wrongWords = []\n } catch (error) {\n console.error('handleRunSpellCheck error: ', error)\n hasFail = true\n }\n }\n\n spellCheckStatus.value = evaluateStatus(hasFail, hasError)\n }\n\n const countTotalWrongWords = computed(() => {\n return Object.values(editorsState).reduce((sum, { wrongWords }) => {\n return sum + wrongWords.length\n }, 0)\n })\n\n watch(countTotalWrongWords, newVal => {\n if (newVal === 0) {\n spellCheckStatus.value = evaluateStatus(false, false)\n }\n })\n\n const allWrongWordsMissSuggestions = computed(() => {\n const allWrongWords = Object.values(editorsState).flatMap(es => es.wrongWords)\n if (allWrongWords.length === 0) return false\n return allWrongWords.every(w => !Array.isArray(w.correctWord) || w.correctWord.length === 0)\n })\n\n function applyAllEditorHighlightErrors() {\n for (const [_, { editor, wrongWords }] of Object.entries(editorsState)) {\n if (!editor) continue\n applyHighlights(editor as Editor, wrongWords)\n }\n }\n\n function clearAllEditorHighlightErrors() {\n for (const [_, { editor }] of Object.entries(editorsState)) {\n if (!editor) continue\n clearHighlights(editor as Editor)\n }\n }\n\n async function reRunSpellCheckAndHighlight() {\n await handleRunSpellCheck()\n applyAllEditorHighlightErrors()\n }\n\n let isEnableCurrent = true\n function disableSpellCheckRealTime(isEnableSpellCheckRealTime: boolean) {\n isEnableCurrent = isEnableSpellCheckRealTime\n if (!isEnableSpellCheckRealTime) return\n\n for (const [_, { editor }] of Object.entries(editorsState)) {\n if (!editor) continue\n editor.extensionStorage.spellchecker.spellchecker.setEnabledProofreadText(false)\n editor.view.dispatch(editor.state.tr.setMeta(SPELLCHECKER_META_LIST.IS_ACTIVE_SPELLCHECK, false))\n }\n }\n\n function resetEnableSpellCheckRealTime() {\n if (!isEnableCurrent) return\n\n for (const [_, { editor }] of Object.entries(editorsState)) {\n if (!editor) continue\n editor.extensionStorage.spellchecker.spellchecker.setEnabledProofreadText(true)\n editor.view.dispatch(editor.state.tr.setMeta(SPELLCHECKER_META_LIST.IS_ACTIVE_SPELLCHECK, true))\n }\n }\n\n function replaceAllErrors(editor: Editor, errors: WrongWordItem[], blockSeparator = '\\n') {\n if (!editor) return\n if (!errors.length) return\n\n const map = buildPlainIndexToDocPosMap(editor, blockSeparator)\n\n function getMappedPos(offset: number) {\n if (offset < 0) offset = 0\n if (offset >= map.length) return editor.state.doc.content.size\n if (map[offset] != null) return map[offset] as number\n for (let i = offset; i < map.length; i++) if (map[i] != null) return map[i] as number\n for (let i = offset - 1; i >= 0; i--) if (map[i] != null) return map[i] as number\n return editor.state.doc.content.size\n }\n\n const replacements = errors.map(item => {\n const from = getMappedPos(item.startIndex)\n const to = getMappedPos(Math.max(0, item.endIndex - 1)) + 1\n const replacement = item.correctWord?.[0] ?? item.wrongWord\n return { item, from, to, replacement }\n })\n\n const validRepls = replacements.filter(r => typeof r.from === 'number' && typeof r.to === 'number' && r.from < r.to)\n\n if (!validRepls.length) return\n\n validRepls.sort((a, b) => b.from - a.from)\n\n const tr = editor.state.tr\n let lastAppliedFrom = Number.POSITIVE_INFINITY\n const appliedItems = new Set<WrongWordItem>()\n\n for (const r of validRepls) {\n if (r.to > lastAppliedFrom) {\n continue\n }\n\n tr.insertText(r.replacement, r.from, r.to)\n\n appliedItems.add(r.item)\n lastAppliedFrom = r.from\n }\n\n if (appliedItems.size > 0) {\n editor.view.dispatch(tr)\n editor.view.focus()\n }\n\n if (appliedItems.size > 0) {\n errors = errors.filter(e => ![...appliedItems].some(a => a === e))\n }\n\n applyHighlights(editor, errors)\n }\n\n function replaceAllEditorErrors() {\n for (const [_, { editor, wrongWords }] of Object.entries(editorsState)) {\n if (!editor) continue\n replaceAllErrors(editor as Editor, wrongWords)\n }\n }\n\n return {\n editorsState,\n spellCheckStatus,\n countTotalWrongWords,\n allWrongWordsMissSuggestions,\n setEditor,\n resetAllEditorWrongWords,\n disableSpellCheckRealTime,\n resetEnableSpellCheckRealTime,\n applyAllEditorHighlightErrors,\n clearAllEditorHighlightErrors,\n reRunSpellCheckAndHighlight,\n handleRunSpellCheck,\n replaceAllEditorErrors,\n }\n}\n","<script setup lang=\"ts\">\nimport { DialogTrigger, type DialogTriggerProps } from 'radix-vue'\n\nconst props = defineProps<DialogTriggerProps>()\n</script>\n\n<template>\n <DialogTrigger v-bind=\"props\">\n <slot />\n </DialogTrigger>\n</template>\n","<script setup lang=\"ts\">\nimport { EDITOR_NAME } from '@/constants'\nimport { useBulkSpellCheckerStore } from '@/hooks/useBulkSpellCheckerStore'\nimport { Editor } from '@tiptap/core'\nimport { DialogTrigger } from './ui/dialog'\n\ninterface Props {\n editor: Editor\n editorComment?: Editor\n isEnableSpellCheckRealTime: boolean\n}\nconst props = defineProps<Props>()\n\nconst {\n editorsState,\n countTotalWrongWords,\n spellCheckStatus,\n allWrongWordsMissSuggestions,\n setEditor,\n disableSpellCheckRealTime,\n resetEnableSpellCheckRealTime,\n handleRunSpellCheck,\n resetAllEditorWrongWords,\n applyAllEditorHighlightErrors,\n clearAllEditorHighlightErrors,\n reRunSpellCheckAndHighlight,\n replaceAllEditorErrors,\n} = useBulkSpellCheckerStore()\n\nconst isOpenModal = ref(false)\n\nconst dragOffset = reactive({ x: 0, y: 0 })\nconst dragging = ref(false)\nconst offset = { x: 0, y: 0 }\n\nconst onMouseDown = (e: MouseEvent) => {\n dragging.value = true\n offset.x = e.clientX - dragOffset.x\n offset.y = e.clientY - dragOffset.y\n document.addEventListener('mousemove', onMouseMove)\n document.addEventListener('mouseup', onMouseUp)\n}\n\nconst onMouseMove = (e: MouseEvent) => {\n if (!dragging.value) return\n dragOffset.x = e.clientX - offset.x\n dragOffset.y = e.clientY - offset.y\n}\n\nconst onMouseUp = () => {\n dragging.value = false\n document.removeEventListener('mousemove', onMouseMove)\n document.removeEventListener('mouseup', onMouseUp)\n}\n\nonUnmounted(() => {\n document.removeEventListener('mousemove', onMouseMove)\n document.removeEventListener('mouseup', onMouseUp)\n})\n\nconst triggerRef = ref<InstanceType<typeof DialogTrigger> | null>(null)\nconst position = ref({ top: 0, right: 0 })\n\nconst updatePosition = () => {\n if (triggerRef.value) {\n const rect = triggerRef.value.$el.getBoundingClientRect()\n\n position.value = {\n top: rect.bottom + window.scrollY + 5,\n right: window.innerWidth - rect.right - window.scrollX,\n }\n\n dragOffset.x = 0\n dragOffset.y = 0\n }\n}\n\nonMounted(async () => {\n if (props.editorComment) {\n setEditor(EDITOR_NAME.EDITOR_COMMENT, props.editorComment)\n }\n setEditor(EDITOR_NAME.EDITOR_CONTENT, props.editor)\n})\n\nonUnmounted(() => {\n setEditor(EDITOR_NAME.EDITOR_COMMENT, null)\n setEditor(EDITOR_NAME.EDITOR_CONTENT, null)\n})\n\nwatch(isOpenModal, async val => {\n if (val) {\n await nextTick()\n updatePosition()\n disableSpellCheckRealTime(props.isEnableSpellCheckRealTime)\n await handleRunSpellCheck()\n applyAllEditorHighlightErrors()\n } else {\n resetAllEditorWrongWords()\n resetEnableSpellCheckRealTime()\n clearAllEditorHighlightErrors()\n }\n})\n\nconst bulkSpellCheckerBtnConfig = props.editor?.extensionManager.extensions.find(e => e.name === 'spellchecker')\n ?.options.bulkSpellCheckerButton\n</script>\n\n<template>\n <Dialog :open=\"isOpenModal\">\n <DialogTrigger as-child ref=\"triggerRef\" @click=\"isOpenModal = !isOpenModal\">\n <button\n v-if=\"!bulkSpellCheckerBtnConfig\"\n class=\"border-blue-500 text-white text-xs text-nowrap px-3 py-2 h-auto bg-blue-500 hover:bg-blue-500/80 flex items-center rounded\"\n >\n <Icon name=\"checkUnderline\" />맞춤법 일괄 교정\n </button>\n\n <component\n v-else\n :is=\"bulkSpellCheckerBtnConfig.component\"\n :buttonName=\"bulkSpellCheckerBtnConfig.props.buttonName\"\n :icon=\"bulkSpellCheckerBtnConfig.props.icon\"\n :type=\"bulkSpellCheckerBtnConfig.props.type\"\n :disabled=\"bulkSpellCheckerBtnConfig.props.disabled\"\n :iconPosition=\"bulkSpellCheckerBtnConfig.props.iconPosition\"\n :buttonSize=\"bulkSpellCheckerBtnConfig.props.buttonSize\"\n :iconClass=\"bulkSpellCheckerBtnConfig.props.iconClass\"\n />\n </DialogTrigger>\n\n <DialogContent is-overlay-transparent class=\"p-0 gap-0 !animate-none !transition-none dark:border-ed-muted\" as-child>\n <div\n class=\"z-[70]\"\n :style=\"{\n transform: `translate(${dragOffset.x}px, ${dragOffset.y}px)`,\n top: `${position.top}px`,\n right: `${position.right}px`,\n left: 'auto',\n }\"\n >\n <DialogHeader\n class=\"bg-ed-blue-light py-3.5 px-6 rounded-t-[5px] cursor-move text-blue-500 dark:text-dark-blue-100 flex-row items-center justify-between\"\n @mousedown.prevent=\"onMouseDown\"\n >\n <DialogTitle class=\"text-base space-x-2\">\n <span>맞춤법/문법 오류</span>\n <Badge class=\"text-sm bg-blue-500 hover:bg-blue-500 dark:bg-dark-blue-100 px-2\">{{ countTotalWrongWords }}개</Badge></DialogTitle\n >\n\n <DialogClose @click=\"isOpenModal = false\" class=\"text-xs flex items-center gap-x-1\">\n <Icon name=\"Close\" class=\"w-4 h-4\" />{{ $t('editor.close') }}\n </DialogClose>\n </DialogHeader>\n\n <DialogDescription></DialogDescription>\n\n <BulkSpellCheckerContent\n :editorsState=\"editorsState\"\n :spellCheckStatus=\"spellCheckStatus\"\n :allWrongWordsMissSuggestions=\"allWrongWordsMissSuggestions\"\n @close-modal=\"isOpenModal = false\"\n @run-spellcheck=\"reRunSpellCheckAndHighlight\"\n @replace-all-editor-errors=\"(replaceAllEditorErrors(), (isOpenModal = false))\"\n />\n </div>\n </DialogContent>\n </Dialog>\n</template>\n\n<style scoped></style>\n"],"names":["ERROR_TYPE","SPELL_CHECK_CODE","SPELL_CHECK_STATUS","EDITOR_NAME","ArrowLeftRight","createLucideIcon","CircleAlert","CircleCheck","expanded","ref","showButton","helpRef","toggle","onMounted","nextTick","HIGHLIGHT_KEY","PluginKey","createHighlightPlugin","editor","errors","blockSeparator","Plugin","state","decos","errorColorMap","item","from","findDocPosFromOffset","to","errorType","_b","_a","className","safeFrom","safeTo","Decoration","DecorationSet","applyHighlights","plugin","clearHighlights","buildPlainIndexToDocPosMap","map","plainIndex","firstBlock","node","pos","i","nodeName","k","offset","mapped","standardMaxHeight","props","__props","getErrorColor","getNoSuggestionText","_d","_c","resetHightlightSection","key","scrollToError","mid","maybeNode","el","replaceWithCorrectWord","replacement","tr","delta","origStart","origEnd","err","idx","contentEl","maxHeight","windowHeight","useWindowSize","computeMaxHeight","gap","rect","availableViewportHeight","useEventListener","_openBlock","_createElementBlock","_hoisted_1","_createVNode","_component_SpinnerIcon","emit","__emit","useBulkSpellCheckerStore","editorsState","reactive","setEditor","editorKey","editorInstance","spellCheckStatus","resetAllEditorWrongWords","editorState","evaluateStatus","hasFail","hasError","handleRunSpellCheck","apiUrl","ext","content","response","axios","error","countTotalWrongWords","computed","sum","wrongWords","watch","newVal","allWrongWordsMissSuggestions","allWrongWords","es","w","applyAllEditorHighlightErrors","_","clearAllEditorHighlightErrors","reRunSpellCheckAndHighlight","isEnableCurrent","disableSpellCheckRealTime","isEnableSpellCheckRealTime","SPELLCHECKER_META_LIST","resetEnableSpellCheckRealTime","replaceAllErrors","getMappedPos","validRepls","r","a","b","lastAppliedFrom","appliedItems","e","replaceAllEditorErrors","isOpenModal","dragOffset","dragging","onMouseDown","onMouseMove","onMouseUp","onUnmounted","triggerRef","position","updatePosition","val","bulkSpellCheckerBtnConfig"],"mappings":"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","x_google_ignoreList":[1,2,3]}
|
|
@@ -31804,7 +31804,7 @@ const dG = { class: "flex gap-2 items-center overflow-x-auto overflow-y-hidden [
|
|
|
31804
31804
|
customClassToolbar: {}
|
|
31805
31805
|
},
|
|
31806
31806
|
setup(t) {
|
|
31807
|
-
const e = gL(() => import("./BulkSpellChecker-
|
|
31807
|
+
const e = gL(() => import("./BulkSpellChecker-Btu4LaPx.mjs")), { t: n } = Qt(), o = t, r = jt("isEditable", z(!0)), i = ["fontSize", "fontFamily", "superText", "spellchecker", "fontSizeIncreaseDecrease"], s = X(() => {
|
|
31808
31808
|
const f = [...o.editor.extensionManager.extensions].sort((g, b) => g.name === "superText" ? 1 : b.name === "superText" ? -1 : 0);
|
|
31809
31809
|
let h = [];
|
|
31810
31810
|
for (const g of f) {
|
|
@@ -54364,7 +54364,7 @@ const uae = { class: "flex flex-1" }, ny = /* @__PURE__ */ W({
|
|
|
54364
54364
|
disabled: { type: Boolean, default: !1 },
|
|
54365
54365
|
mode: {},
|
|
54366
54366
|
activeExtensions: { default: () => [] },
|
|
54367
|
-
threshold: { default:
|
|
54367
|
+
threshold: { default: 5 }
|
|
54368
54368
|
},
|
|
54369
54369
|
setup(t) {
|
|
54370
54370
|
const { t: e } = Qt(), n = t, o = [
|
|
@@ -54400,8 +54400,10 @@ const uae = { class: "flex flex-1" }, ny = /* @__PURE__ */ W({
|
|
|
54400
54400
|
b.push({ button: C, divider: x, spacer: E, id: `${v.name}` });
|
|
54401
54401
|
}
|
|
54402
54402
|
return n.activeExtensions.length ? b.filter((v) => v.id && n.activeExtensions.includes(v.id)) : (o.length && (b = b.filter((v) => v.id && !o.includes(v.id))), b = b.map((v) => {
|
|
54403
|
-
const w = ["videoUpload", "heading", "strike", "color", "fontSize", "fontFamily"], x = ["redo"], E =
|
|
54404
|
-
|
|
54403
|
+
const w = ["videoUpload", "heading", "strike", "color", "fontSize", "fontFamily"], x = ["redo"], E = b.some((T) => T.id === "imageUpload"), S = b.some((T) => T.id === "videoUpload");
|
|
54404
|
+
S || w.push("imageUpload"), !E && !S && w.push("link");
|
|
54405
|
+
const C = w.includes(v.id ?? "") || x.includes(v.buttonName ?? "");
|
|
54406
|
+
return { ...v, separator: C };
|
|
54405
54407
|
}), b);
|
|
54406
54408
|
}), i = (h) => h.id === "spellchecker" ? "!text-ed-blue !bg-white !font-normal rounded [&>div>svg]:w-[19px] [&>div>svg]:h-[19px] h-[26px] gap-x-1 whitespace-nowrap" : h.button.componentProps.customClass, s = (h) => h.id === "spellchecker" ? "Spellchecker" : h.button.componentProps.icon, a = z(null), l = z(!1), u = z(!1);
|
|
54407
54409
|
function d() {
|
|
@@ -54415,7 +54417,7 @@ const uae = { class: "flex flex-1" }, ny = /* @__PURE__ */ W({
|
|
|
54415
54417
|
const x = g <= n.threshold, E = g + v >= b - n.threshold;
|
|
54416
54418
|
l.value = !x, u.value = !E;
|
|
54417
54419
|
}
|
|
54418
|
-
const f = TL(d,
|
|
54420
|
+
const f = TL(d, 10);
|
|
54419
54421
|
return lp(a, "scroll", f), kL(a, f), lp(window, "resize", f), (h, g) => (O(), ae("div", {
|
|
54420
54422
|
id: "tool-bar-format",
|
|
54421
54423
|
class: He(
|
|
@@ -54855,7 +54857,7 @@ const uae = { class: "flex flex-1" }, ny = /* @__PURE__ */ W({
|
|
|
54855
54857
|
const x = Qc;
|
|
54856
54858
|
return O(), H(m(k0), {
|
|
54857
54859
|
horizontal: "",
|
|
54858
|
-
class: He(m(Be)("flex-1"
|
|
54860
|
+
class: He(m(Be)("flex-1 text-sm"))
|
|
54859
54861
|
}, {
|
|
54860
54862
|
default: N(() => [
|
|
54861
54863
|
m(b) ? (O(), H(m(pi), {
|
|
@@ -54864,7 +54866,8 @@ const uae = { class: "flex flex-1" }, ny = /* @__PURE__ */ W({
|
|
|
54864
54866
|
m(Be)(
|
|
54865
54867
|
"!overflow-y-auto border border-ed-gray rounded-md",
|
|
54866
54868
|
!v.isEditorViewSplitContent && "border-none",
|
|
54867
|
-
!m(d) && "scrollbar-thumb-transparent"
|
|
54869
|
+
!m(d) && "scrollbar-thumb-transparent",
|
|
54870
|
+
v.contentTextStyle
|
|
54868
54871
|
)
|
|
54869
54872
|
),
|
|
54870
54873
|
onScroll: m(f)
|
|
@@ -54927,7 +54930,11 @@ const uae = { class: "flex flex-1" }, ny = /* @__PURE__ */ W({
|
|
|
54927
54930
|
v.isEditorViewSplitContent ? (O(), H(m(pi), {
|
|
54928
54931
|
key: 1,
|
|
54929
54932
|
class: He(
|
|
54930
|
-
m(Be)(
|
|
54933
|
+
m(Be)(
|
|
54934
|
+
"!overflow-y-auto border border-ed-gray rounded-md",
|
|
54935
|
+
!m(d) && "scrollbar-thumb-transparent",
|
|
54936
|
+
v.contentTextStyle
|
|
54937
|
+
)
|
|
54931
54938
|
),
|
|
54932
54939
|
onScroll: m(f)
|
|
54933
54940
|
}, {
|
|
@@ -55084,7 +55091,7 @@ const uae = { class: "flex flex-1" }, ny = /* @__PURE__ */ W({
|
|
|
55084
55091
|
d.hasClipboard ? (O(), ae("button", {
|
|
55085
55092
|
key: 1,
|
|
55086
55093
|
class: "bubble-menu-item",
|
|
55087
|
-
onClick: f[1] || (f[1] = (v) => d.editor.chain().focus().pasteContent().run())
|
|
55094
|
+
onClick: f[1] || (f[1] = (v) => (d.editor.chain().focus().pasteContent().run(), o("close-long-press-menu")))
|
|
55088
55095
|
}, Le(m(r)("editor.paste")), 1)) : be("", !0),
|
|
55089
55096
|
ee("button", {
|
|
55090
55097
|
class: "bubble-menu-item",
|
|
@@ -55113,7 +55120,7 @@ const uae = { class: "flex flex-1" }, ny = /* @__PURE__ */ W({
|
|
|
55113
55120
|
], 64);
|
|
55114
55121
|
};
|
|
55115
55122
|
}
|
|
55116
|
-
}), _ae = /* @__PURE__ */ is(Sae, [["__scopeId", "data-v-
|
|
55123
|
+
}), _ae = /* @__PURE__ */ is(Sae, [["__scopeId", "data-v-b4e2ce28"]]);
|
|
55117
55124
|
class M7 {
|
|
55118
55125
|
isNativeWebViewAvailable() {
|
|
55119
55126
|
return window.ReactNativeWebView !== void 0;
|
|
@@ -55628,7 +55635,7 @@ const Nae = { class: "flex justify-between items-center relative" }, Cc = /* @__
|
|
|
55628
55635
|
disableSuperInput: { type: Boolean, default: !1 },
|
|
55629
55636
|
fontSizeDefault: { default: "" },
|
|
55630
55637
|
fontFamilyDefault: { default: "" },
|
|
55631
|
-
contentTextStyle: { default: "
|
|
55638
|
+
contentTextStyle: { default: "" },
|
|
55632
55639
|
isOpenSuperView: { type: Boolean },
|
|
55633
55640
|
output: { default: "html" },
|
|
55634
55641
|
dark: { type: Boolean, default: void 0 },
|
|
@@ -56004,7 +56011,7 @@ const Nae = { class: "flex justify-between items-center relative" }, Cc = /* @__
|
|
|
56004
56011
|
To(ee("div", {
|
|
56005
56012
|
class: He(
|
|
56006
56013
|
m(Be)(
|
|
56007
|
-
"flex-1 !overflow-y-auto overflow-x-hidden basis-0 flex h-full flex-col",
|
|
56014
|
+
"flex-1 !overflow-y-auto overflow-x-hidden basis-0 flex h-full flex-col text-sm",
|
|
56008
56015
|
!m(nt) && "scrollbar-thumb-transparent",
|
|
56009
56016
|
I.contentClass,
|
|
56010
56017
|
I.contentTextStyle
|
|
@@ -56120,7 +56127,7 @@ const Nae = { class: "flex justify-between items-center relative" }, Cc = /* @__
|
|
|
56120
56127
|
}, 8, ["disabled"])) : be("", !0)
|
|
56121
56128
|
]),
|
|
56122
56129
|
To(ee("div", {
|
|
56123
|
-
class: He(m(Be)("flex-1 basis-0 flex flex-col relative", I.contentClass, I.contentTextStyle))
|
|
56130
|
+
class: He(m(Be)("flex-1 basis-0 flex flex-col relative text-sm", I.contentClass, I.contentTextStyle))
|
|
56124
56131
|
}, [
|
|
56125
56132
|
P(m(_o), {
|
|
56126
56133
|
id: "editor-panel",
|
|
@@ -56696,7 +56703,7 @@ const Lae = /* @__PURE__ */ UH(Iae), q5 = (t, e, n) => {
|
|
|
56696
56703
|
extensions: {},
|
|
56697
56704
|
editorClass: {},
|
|
56698
56705
|
isCompare: { type: Boolean, default: !0 },
|
|
56699
|
-
contentTextStyle: {
|
|
56706
|
+
contentTextStyle: {}
|
|
56700
56707
|
},
|
|
56701
56708
|
setup(t) {
|
|
56702
56709
|
const e = t, n = X(() => [...e.extensions, I7]), o = z(!1), r = X(() => !e.originalData || !e.changedData ? {
|
|
@@ -56854,7 +56861,7 @@ const Lae = /* @__PURE__ */ UH(Iae), q5 = (t, e, n) => {
|
|
|
56854
56861
|
], 2);
|
|
56855
56862
|
};
|
|
56856
56863
|
}
|
|
56857
|
-
}), Ble = /* @__PURE__ */ is(Xae, [["__scopeId", "data-v-
|
|
56864
|
+
}), Ble = /* @__PURE__ */ is(Xae, [["__scopeId", "data-v-4bdb50a2"]]), Jae = /* @__PURE__ */ W({
|
|
56858
56865
|
__name: "SuperViewMobileSuperEditor",
|
|
56859
56866
|
props: {
|
|
56860
56867
|
isMobile: { type: Boolean },
|
|
@@ -57807,4 +57814,4 @@ export {
|
|
|
57807
57814
|
ple as y,
|
|
57808
57815
|
ale as z
|
|
57809
57816
|
};
|
|
57810
|
-
//# sourceMappingURL=index-
|
|
57817
|
+
//# sourceMappingURL=index-DIfPrW2K.mjs.map
|