From 44ce56729f464e01595aea041e976abf71188ba3 Mon Sep 17 00:00:00 2001 From: XiNGRZ Date: Mon, 25 Mar 2024 18:55:29 +0800 Subject: [PATCH] [WIP] Migrate to CodeMirror --- package-lock.json | 133 +++++++++++++++++++++++-- package.json | 2 +- src/components/BSMap.vue | 13 ++- src/components/BSMap/BSCell.vue | 2 - src/components/BSMap/BSRow.vue | 10 +- src/components/BSMap/BSText.vue | 2 - src/components/Editor.vue | 92 ++++++++--------- src/composables/bindEditorScroll.ts | 30 +++--- src/composables/bindEditorSelection.ts | 78 +++++---------- src/composables/bindEditorValue.ts | 19 ++-- src/composables/onRefAssigned.ts | 9 -- src/composables/onRefUnassigned.ts | 9 -- src/composables/useClientSize.ts | 29 ------ src/editor/rdt.js | 57 ----------- src/types/selection.ts | 1 - 15 files changed, 230 insertions(+), 256 deletions(-) delete mode 100644 src/composables/onRefAssigned.ts delete mode 100644 src/composables/onRefUnassigned.ts delete mode 100644 src/composables/useClientSize.ts delete mode 100644 src/editor/rdt.js diff --git a/package-lock.json b/package-lock.json index 9ee4d5a..c74f281 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "rdt-editor", "version": "5.0", "dependencies": { - "brace": "^0.11.1", + "codemirror": "^6.0.1", "md5": "^2.3.0", "naive-ui": "^2.38.1", "pinia": "^2.1.7", @@ -61,6 +61,82 @@ "node": ">=6.9.0" } }, + "node_modules/@codemirror/autocomplete": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.15.0.tgz", + "integrity": "sha512-G2Zm0mXznxz97JhaaOdoEG2cVupn4JjPaS4AcNvZzhOsnnG9YVN68VzfoUw6dYTsIxT6a/cmoFEN47KAWhXaOg==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + }, + "peerDependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.3.tgz", + "integrity": "sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/language": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.1.tgz", + "integrity": "sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.1.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.5.0.tgz", + "integrity": "sha512-+5YyicIaaAZKU8K43IQi8TBy6mF6giGeWAH7N96Z5LC30Wm5JMjqxOYIE9mxwMG1NbhT2mA3l9hA4uuKUM3E5g==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/search": { + "version": "6.5.6", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz", + "integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/state": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz", + "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==" + }, + "node_modules/@codemirror/view": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.26.0.tgz", + "integrity": "sha512-nSSmzONpqsNzshPOxiKhK203R6BvABepugAe34QfQDbNDslyjkqBuKgrK5ZBvqNXpfxz5iLrlGTmEfhbQyH46A==", + "dependencies": { + "@codemirror/state": "^6.4.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, "node_modules/@css-render/plugin-bem": { "version": "0.15.12", "resolved": "https://registry.npmjs.org/@css-render/plugin-bem/-/plugin-bem-0.15.12.tgz", @@ -593,6 +669,27 @@ "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" }, + "node_modules/@lezer/common": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz", + "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==" + }, + "node_modules/@lezer/highlight": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz", + "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.0.tgz", + "integrity": "sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg==", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1294,11 +1391,6 @@ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "dev": true }, - "node_modules/brace": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/brace/-/brace-0.11.1.tgz", - "integrity": "sha1-SJb8ydVE7vRfS7dmDbMg07N5/lg=" - }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -1398,6 +1490,20 @@ "fsevents": "~2.3.2" } }, + "node_modules/codemirror": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", + "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1422,6 +1528,11 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3032,6 +3143,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/style-mod": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3269,6 +3385,11 @@ "vue": "^3.0.11" } }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index d3ff18a..c412d41 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "lint": "eslint --ext .ts,.vue src" }, "dependencies": { - "brace": "^0.11.1", + "codemirror": "^6.0.1", "md5": "^2.3.0", "naive-ui": "^2.38.1", "pinia": "^2.1.7", diff --git a/src/components/BSMap.vue b/src/components/BSMap.vue index f751841..0f419bc 100644 --- a/src/components/BSMap.vue +++ b/src/components/BSMap.vue @@ -1,6 +1,6 @@ @@ -18,11 +18,18 @@ const props = defineProps<{ size: number; }>(); -const rows = computed(() => props.content.split('\n')); +const rows = computed(() => { + let offset = 0; + return props.content.split('\n').map((row) => { + const o = offset; + offset += row.length + 1; + return { row, offset: o }; + }) +}); const cols = computed(() => { let cols = 0; - for (const row of rows.value) { + for (const { row } of rows.value) { const c = Math.max(cols, row.split('\\').length); if (c > cols) cols = c; } diff --git a/src/components/BSMap/BSCell.vue b/src/components/BSMap/BSCell.vue index b542bd5..f4f4dc8 100644 --- a/src/components/BSMap/BSCell.vue +++ b/src/components/BSMap/BSCell.vue @@ -19,7 +19,6 @@ import BSIcon from './BSIcon.vue'; const props = defineProps<{ content: string; - row: number; offset: number; }>(); @@ -41,7 +40,6 @@ const style = computed(() => ({ function handleClick(): void { editorStore.selection = { - row: props.row, offset: props.offset, length: props.content.length, }; diff --git a/src/components/BSMap/BSRow.vue b/src/components/BSMap/BSRow.vue index 3aa760c..a999ac3 100644 --- a/src/components/BSMap/BSRow.vue +++ b/src/components/BSMap/BSRow.vue @@ -3,12 +3,12 @@
+ :offset="offset" />
+ :align="align" :offset="offset" />
@@ -24,12 +24,13 @@ import BSText from './BSText.vue'; const props = defineProps<{ content: string; row: number; + offset: number; }>(); const editorStore = useEditorStore(); const parts = computed(() => { - let offset = 0; + let offset = props.offset; return props.content.split('~~').map((part) => { const o = offset; offset += part.length + 2; @@ -38,7 +39,7 @@ const parts = computed(() => { }); const cells = computed(() => { - let offset = 0; + let offset = props.offset; return parts.value[0].part.split('\\').map((cell) => { const o = offset; offset += cell.length + 1; @@ -57,7 +58,6 @@ function isFocused(row: number, offset: number, length: number): boolean { const { selection } = editorStore; return ( typeof selection != 'undefined' && - selection.row == row && selection.offset >= offset && selection.offset <= offset + length ); diff --git a/src/components/BSMap/BSText.vue b/src/components/BSMap/BSText.vue index b8e66da..d468101 100644 --- a/src/components/BSMap/BSText.vue +++ b/src/components/BSMap/BSText.vue @@ -10,7 +10,6 @@ import { useEditorStore } from '@/stores/editor'; const props = defineProps<{ content: string; align: number; - row: number; offset: number; }>(); @@ -18,7 +17,6 @@ const editorStore = useEditorStore(); function handleClick(): void { editorStore.selection = { - row: props.row, offset: props.offset, length: props.content.length, }; diff --git a/src/components/Editor.vue b/src/components/Editor.vue index 8cc80e1..6ad63e3 100644 --- a/src/components/Editor.vue +++ b/src/components/Editor.vue @@ -1,9 +1,5 @@