yh-codemirror 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/CodeMirror.vue +283 -287
  2. package/index.ts +0 -0
  3. package/package.json +26 -26
  4. package/util.ts +17 -17
package/CodeMirror.vue CHANGED
@@ -1,287 +1,283 @@
1
- <template>
2
- <div
3
- class="yh-code-mirror-container"
4
- ref="YhCodemirrorContainer"
5
- :style="codeMirrorStyle">
6
- <div class="code-slot">
7
- <slot name="pre-code"></slot>
8
- </div>
9
- <div
10
- class="codemirror-editor"
11
- ref="codeMirrorEditorRef"
12
- :style="codeMirrorEditorStyle"></div>
13
- <div class="code-slot">
14
- <slot name="next-code"></slot>
15
- </div>
16
- <div class="editor-operation-btn">
17
- <i
18
- title="全屏"
19
- class="iconfont icon-fullscreen"
20
- @click="fullscreen"></i>
21
- <i
22
- title="美化"
23
- class="iconfont icon-magic-stick"
24
- @click="onEditorBtnClick('beautify')"></i>
25
- <i
26
- title="全选"
27
- class="iconfont icon-check-square"
28
- @click="onEditorBtnClick('checkAll')"></i>
29
- <i
30
- title="复制"
31
- class="iconfont icon-document-copy"
32
- @click="onEditorBtnClick('copy')"></i>
33
- <i
34
- title="清空"
35
- class="iconfont icon-clear"
36
- @click="onEditorBtnClick('clear')"></i>
37
- <slot name="operation-btn"></slot>
38
- </div>
39
- </div>
40
- </template>
41
- <script setup lang="ts">
42
- import {ref, onMounted, toRaw} from 'vue';
43
- // @ts-ignore
44
- import type {Extension} from 'codemirror';
45
- import {EditorView, basicSetup} from 'codemirror';
46
- import {ViewUpdate} from '@codemirror/view';
47
- import {EditorState, EditorSelection} from '@codemirror/state';
48
- import {javascriptLanguage} from '@codemirror/lang-javascript';
49
- import {solarizedDark} from 'cm6-theme-solarized-dark';
50
- import {getCodeLanguagePlugin} from './util';
51
- import {watch, computed} from 'vue';
52
- // @ts-ignore
53
- import {js_beautify} from 'js-beautify';
54
- import {ElMessage} from 'element-plus';
55
-
56
- const YhCodemirrorContainer = ref();
57
- function fullscreen() {
58
- if (document.fullscreenElement && document.fullscreenElement === YhCodemirrorContainer.value) {
59
- document.exitFullscreen();
60
- } else {
61
- YhCodemirrorContainer.value.requestFullscreen();
62
- }
63
- }
64
-
65
- const codeMirrorEditorRef = ref();
66
-
67
- let view: null | EditorView = null;
68
- let state: null | EditorState = null;
69
- // js-beautify 自定义配置
70
- const codeBeautifyConfig = {
71
- indent_size: 2,
72
- };
73
-
74
- const props = withDefaults(
75
- defineProps<{
76
- modelValue: string;
77
- language?: string | string[];
78
- autocomplete?: any;
79
- height?: number;
80
- }>(),
81
- {
82
- modelValue: '',
83
- language: 'javascript',
84
- autocomplete: {},
85
- }
86
- );
87
-
88
- const codeMirrorStyle = computed(() => {
89
- let style: any = {};
90
- if (props.height !== undefined && !isNaN(props.height)) {
91
- style.height = `${props.height}px`;
92
- style.display = 'flex';
93
- style.flexDirection = 'column';
94
- }
95
- return style;
96
- });
97
-
98
- const codeMirrorEditorStyle = computed(() => {
99
- let style: any = {};
100
- if (props.height !== undefined && !isNaN(props.height)) {
101
- style.flex = `1`;
102
- style.overflow = 'auto';
103
- }
104
- return style;
105
- });
106
-
107
- watch(
108
- () => props.modelValue,
109
- (val) => {
110
- if (view && state && val != view.state.doc.toString()) {
111
- let end = view.state.doc.toString().length;
112
- view.dispatch({
113
- changes: [
114
- {
115
- from: 0,
116
- to: end,
117
- insert: val,
118
- },
119
- ],
120
- });
121
- }
122
- }
123
- );
124
-
125
- const emits = defineEmits(['update:modelValue']);
126
-
127
- // 代码编辑器操作按钮
128
- const onEditorBtnClick = (type) => {
129
- if (view) {
130
- const state = toRaw(view.state);
131
- const pos = state.doc.toString().length;
132
- if (type == 'beautify') {
133
- const beautifyCode = js_beautify(props.modelValue, codeBeautifyConfig);
134
- view.dispatch({
135
- changes: [
136
- {
137
- from: 0,
138
- to: pos,
139
- insert: beautifyCode,
140
- },
141
- ],
142
- });
143
- } else if (type == 'checkAll') {
144
- const tr = state.update({
145
- // selection: EditorSelection.cursor(pos), // 设置光标
146
- selection: EditorSelection.range(0, pos),
147
- scrollIntoView: true,
148
- });
149
- view.dispatch(tr);
150
- } else if (type == 'copy') {
151
- let selectedText = '';
152
- if (state.selection.ranges.some((range) => !range.empty)) {
153
- const selection = state.selection.ranges[0];
154
- selectedText = state.sliceDoc(selection.from, selection.to);
155
- } else {
156
- selectedText = state.doc.toString();
157
- }
158
- navigator.clipboard.writeText(selectedText);
159
- ElMessage({
160
- message: '复制成功!',
161
- type: 'success',
162
- });
163
- } else if (type == 'clear') {
164
- view.dispatch({
165
- changes: [
166
- {
167
- from: 0,
168
- to: pos,
169
- insert: '',
170
- },
171
- ],
172
- });
173
- }
174
- view.focus();
175
- }
176
- };
177
-
178
- onMounted(() => {
179
- const extensions: Extension[] = [
180
- basicSetup,
181
- solarizedDark,
182
- EditorView.lineWrapping,
183
- EditorView.updateListener.of((v: ViewUpdate) => {
184
- if (v.docChanged) {
185
- emits('update:modelValue', v.state.doc.toString());
186
- }
187
- }),
188
- ];
189
- const language = props.language;
190
- if (language) {
191
- if (Array.isArray(language)) {
192
- language.forEach((l) => {
193
- extensions.push(getCodeLanguagePlugin(l));
194
- if (props.autocomplete[l] && l === 'javascript') {
195
- extensions.push(
196
- javascriptLanguage.data.of({
197
- autocomplete: props.autocomplete[l],
198
- })
199
- );
200
- }
201
- });
202
- } else {
203
- extensions.push(getCodeLanguagePlugin(language));
204
- if (props.autocomplete[language] && language === 'javascript') {
205
- extensions.push(
206
- javascriptLanguage.data.of({
207
- autocomplete: props.autocomplete[language],
208
- })
209
- );
210
- }
211
- }
212
- }
213
- let doc = props.modelValue;
214
- if (typeof doc !== 'string') {
215
- doc = '';
216
- }
217
- state = EditorState.create({
218
- doc,
219
- extensions,
220
- });
221
- if (state) {
222
- view = new EditorView({
223
- state: state,
224
- parent: codeMirrorEditorRef.value,
225
- });
226
- }
227
- });
228
- </script>
229
- <style lang="scss">
230
- .yh-code-mirror-container {
231
- width: 100%;
232
- position: relative;
233
- background-color: #173541;
234
- min-height: 70px;
235
- .code-slot {
236
- width: 100%;
237
- font-family: 'Fira Code', 'Roboto Mono', Consolas, 'Microsoft Yahei';
238
- line-height: 25px;
239
- font-size: 16px;
240
- padding-left: 29.77px;
241
- color: #ffffff;
242
- }
243
- .cm-editor {
244
- .cm-line {
245
- font-size: 16px;
246
- line-height: 25px;
247
- font-family: 'Fira Code', 'Roboto Mono', Consolas, 'Microsoft Yahei';
248
- }
249
- }
250
- .codemirror-editor {
251
- &::-webkit-scrollbar {
252
- width: 6px;
253
- height: 6px;
254
- background-color: #173541;
255
- }
256
- &::-webkit-scrollbar-thumb {
257
- background-color: #f5f5f5;
258
- &:hover {
259
- background-color: #fff;
260
- }
261
- }
262
- }
263
- .editor-operation-btn {
264
- position: absolute;
265
- bottom: 1px;
266
- right: 1px;
267
- padding: 0 3px;
268
- display: flex;
269
- align-items: center;
270
- border-radius: 3px;
271
- opacity: 0.5;
272
- background: #409eff;
273
- transition: all 0.3s ease;
274
- i {
275
- font-size: 16px;
276
- color: #fff;
277
- margin: 0 5px;
278
- cursor: pointer;
279
- line-height: 24px;
280
- }
281
- &:hover {
282
- opacity: 1;
283
- background: #409eff;
284
- }
285
- }
286
- }
287
- </style>
1
+ <template>
2
+ <div
3
+ class="yh-code-mirror-container"
4
+ ref="YhCodemirrorContainer"
5
+ :style="codeMirrorStyle">
6
+ <div class="code-slot">
7
+ <slot name="pre-code"></slot>
8
+ </div>
9
+ <div
10
+ class="codemirror-editor"
11
+ ref="codeMirrorEditorRef"
12
+ :style="codeMirrorEditorStyle"></div>
13
+ <div class="code-slot">
14
+ <slot name="next-code"></slot>
15
+ </div>
16
+ <div class="editor-operation-btn">
17
+ <i
18
+ title="全屏"
19
+ class="iconfont icon-fullscreen"
20
+ @click="fullscreen"></i>
21
+ <i
22
+ title="美化"
23
+ class="iconfont icon-magic-stick"
24
+ @click="onEditorBtnClick('beautify')"></i>
25
+ <i
26
+ title="全选"
27
+ class="iconfont icon-check-square"
28
+ @click="onEditorBtnClick('checkAll')"></i>
29
+ <i
30
+ title="复制"
31
+ class="iconfont icon-document-copy"
32
+ @click="onEditorBtnClick('copy')"></i>
33
+ <i
34
+ title="清空"
35
+ class="iconfont icon-clear"
36
+ @click="onEditorBtnClick('clear')"></i>
37
+ <slot name="operation-btn"></slot>
38
+ </div>
39
+ </div>
40
+ </template>
41
+ <script setup lang="ts">
42
+ import {ref, onMounted, toRaw} from 'vue';
43
+ // @ts-ignore
44
+ import type {Extension} from 'codemirror';
45
+ import {EditorView, basicSetup} from 'codemirror';
46
+ import {ViewUpdate} from '@codemirror/view';
47
+ import {EditorState, EditorSelection} from '@codemirror/state';
48
+ import {javascriptLanguage} from '@codemirror/lang-javascript';
49
+ import {solarizedDark} from 'cm6-theme-solarized-dark';
50
+ import {getCodeLanguagePlugin} from './util';
51
+ import {watch, computed} from 'vue';
52
+ // @ts-ignore
53
+ import {js_beautify} from 'js-beautify';
54
+ import {ElMessage} from 'element-plus';
55
+
56
+ const YhCodemirrorContainer = ref();
57
+ function fullscreen() {
58
+ if (document.fullscreenElement && document.fullscreenElement === YhCodemirrorContainer.value) {
59
+ document.exitFullscreen();
60
+ } else {
61
+ YhCodemirrorContainer.value.requestFullscreen();
62
+ }
63
+ }
64
+
65
+ const codeMirrorEditorRef = ref();
66
+
67
+ let view: null | EditorView = null;
68
+ let state: null | EditorState = null;
69
+ // js-beautify 自定义配置
70
+ const codeBeautifyConfig = {
71
+ indent_size: 2,
72
+ };
73
+
74
+ const props = withDefaults(
75
+ defineProps<{
76
+ modelValue: string;
77
+ language?: string | string[];
78
+ autocomplete?: any;
79
+ height?: number;
80
+ }>(),
81
+ {
82
+ modelValue: '',
83
+ language: 'javascript',
84
+ autocomplete: {},
85
+ }
86
+ );
87
+
88
+ const codeMirrorStyle = computed(() => {
89
+ let style: any = {};
90
+ if (props.height !== undefined && !isNaN(props.height)) {
91
+ style.height = `${props.height}px`;
92
+ style.display = 'flex';
93
+ style.flexDirection = 'column';
94
+ }
95
+ return style;
96
+ });
97
+
98
+ const codeMirrorEditorStyle = computed(() => {
99
+ let style: any = {};
100
+ if (props.height !== undefined && !isNaN(props.height)) {
101
+ style.flex = `1`;
102
+ style.overflow = 'auto';
103
+ }
104
+ return style;
105
+ });
106
+
107
+ watch(
108
+ () => props.modelValue,
109
+ (val) => {
110
+ if (view && state && val != view.state.doc.toString()) {
111
+ let end = view.state.doc.toString().length;
112
+ view.dispatch({
113
+ changes: [
114
+ {
115
+ from: 0,
116
+ to: end,
117
+ insert: val,
118
+ },
119
+ ],
120
+ });
121
+ }
122
+ }
123
+ );
124
+
125
+ const emits = defineEmits(['update:modelValue']);
126
+
127
+ // 代码编辑器操作按钮
128
+ const onEditorBtnClick = (type) => {
129
+ if (view) {
130
+ const state = toRaw(view.state);
131
+ const pos = state.doc.toString().length;
132
+ if (type == 'beautify') {
133
+ const beautifyCode = js_beautify(props.modelValue, codeBeautifyConfig);
134
+ view.dispatch({
135
+ changes: [
136
+ {
137
+ from: 0,
138
+ to: pos,
139
+ insert: beautifyCode,
140
+ },
141
+ ],
142
+ });
143
+ } else if (type == 'checkAll') {
144
+ const tr = state.update({
145
+ // selection: EditorSelection.cursor(pos), // 设置光标
146
+ selection: EditorSelection.range(0, pos),
147
+ scrollIntoView: true,
148
+ });
149
+ view.dispatch(tr);
150
+ } else if (type == 'copy') {
151
+ let selectedText = '';
152
+ if (state.selection.ranges.some((range) => !range.empty)) {
153
+ const selection = state.selection.ranges[0];
154
+ selectedText = state.sliceDoc(selection.from, selection.to);
155
+ } else {
156
+ selectedText = state.doc.toString();
157
+ }
158
+ navigator.clipboard.writeText(selectedText);
159
+ ElMessage({
160
+ message: '复制成功!',
161
+ type: 'success',
162
+ });
163
+ } else if (type == 'clear') {
164
+ view.dispatch({
165
+ changes: [
166
+ {
167
+ from: 0,
168
+ to: pos,
169
+ insert: '',
170
+ },
171
+ ],
172
+ });
173
+ }
174
+ view.focus();
175
+ }
176
+ };
177
+
178
+ onMounted(() => {
179
+ const extensions: Extension[] = [
180
+ basicSetup,
181
+ solarizedDark,
182
+ EditorView.lineWrapping,
183
+ EditorView.updateListener.of((v: ViewUpdate) => {
184
+ if (v.docChanged) {
185
+ emits('update:modelValue', v.state.doc.toString());
186
+ }
187
+ }),
188
+ ];
189
+ const language = props.language;
190
+ if (language) {
191
+ if (Array.isArray(language)) {
192
+ language.forEach((l) => {
193
+ extensions.push(getCodeLanguagePlugin(l));
194
+ if (props.autocomplete[l] && l === 'javascript') {
195
+ extensions.push(
196
+ javascriptLanguage.data.of({
197
+ autocomplete: props.autocomplete[l],
198
+ })
199
+ );
200
+ }
201
+ });
202
+ } else {
203
+ extensions.push(getCodeLanguagePlugin(language));
204
+ if (props.autocomplete[language] && language === 'javascript') {
205
+ extensions.push(
206
+ javascriptLanguage.data.of({
207
+ autocomplete: props.autocomplete[language],
208
+ })
209
+ );
210
+ }
211
+ }
212
+ }
213
+
214
+ state = EditorState.create({
215
+ doc: props.modelValue,
216
+ extensions,
217
+ });
218
+ if (state) {
219
+ view = new EditorView({
220
+ state: state,
221
+ parent: codeMirrorEditorRef.value,
222
+ });
223
+ }
224
+ });
225
+ </script>
226
+ <style lang="scss">
227
+ .yh-code-mirror-container {
228
+ width: 100%;
229
+ position: relative;
230
+ background-color: #173541;
231
+ .code-slot {
232
+ width: 100%;
233
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, 'Microsoft Yahei';
234
+ line-height: 25px;
235
+ font-size: 12px;
236
+ padding-left: 29.77px;
237
+ color: #ffffff;
238
+ }
239
+ .cm-editor {
240
+ .cm-line {
241
+ font-size: 16px;
242
+ line-height: 25px;
243
+ font-family: 'Fira Code', 'Roboto Mono', Consolas, 'Microsoft Yahei';
244
+ }
245
+ }
246
+ .codemirror-editor {
247
+ &::-webkit-scrollbar {
248
+ width: 6px;
249
+ height: 6px;
250
+ background-color: #173541;
251
+ }
252
+ &::-webkit-scrollbar-thumb {
253
+ background-color: #f5f5f5;
254
+ &:hover {
255
+ background-color: #fff;
256
+ }
257
+ }
258
+ }
259
+ .editor-operation-btn {
260
+ position: absolute;
261
+ bottom: 1px;
262
+ right: 1px;
263
+ padding: 0 3px;
264
+ display: flex;
265
+ align-items: center;
266
+ border-radius: 3px;
267
+ opacity: 0.5;
268
+ background: #409eff;
269
+ transition: all 0.3s ease;
270
+ i {
271
+ font-size: 16px;
272
+ color: #fff;
273
+ margin: 0 5px;
274
+ cursor: pointer;
275
+ line-height: 24px;
276
+ }
277
+ &:hover {
278
+ opacity: 1;
279
+ background: #409eff;
280
+ }
281
+ }
282
+ }
283
+ </style>
package/index.ts CHANGED
File without changes
package/package.json CHANGED
@@ -1,27 +1,27 @@
1
- {
2
- "name": "yh-codemirror",
3
- "version": "1.0.4",
4
- "description": "wraper codemirror with vue3",
5
- "main": "index.js",
6
- "scripts": {
7
- "pub": "npm publish --registry https://registry.npmjs.org/ --no-git-checks && npm publish --registry https://packages.aliyun.com/60765e0161a945067837bb5f/npm/npm-registry/ --no-git-checks"
8
- },
9
- "dependencies": {
10
- "@codemirror/autocomplete": "^6.16.3",
11
- "@codemirror/lang-css": "^6.2.1",
12
- "@codemirror/lang-java": "^6.0.1",
13
- "@codemirror/lang-javascript": "^6.2.2",
14
- "@codemirror/lang-sql": "^6.7.0",
15
- "@codemirror/lang-html": "^6.4.9",
16
- "@codemirror/language": "^6.10.2",
17
- "@codemirror/view": "^6.28.2",
18
- "codemirror": "^6.0.1",
19
- "js-beautify": "^1.15.1"
20
- },
21
- "peerDependencies": {
22
- "vue-i18n": "9.8.0",
23
- "vue": "3.2.47",
24
- "element-plus": "2.3.8"
25
- },
26
- "author": "Liubin"
1
+ {
2
+ "name": "yh-codemirror",
3
+ "version": "1.0.6",
4
+ "description": "wraper codemirror with vue3",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "pub": "npm publish --registry https://registry.npmjs.org/ && npm publish --registry https://packages.aliyun.com/60765e0161a945067837bb5f/npm/npm-registry/"
8
+ },
9
+ "dependencies": {
10
+ "@codemirror/autocomplete": "^6.16.3",
11
+ "@codemirror/lang-css": "^6.2.1",
12
+ "@codemirror/lang-java": "^6.0.1",
13
+ "@codemirror/lang-javascript": "^6.2.2",
14
+ "@codemirror/lang-sql": "^6.7.0",
15
+ "@codemirror/lang-html": "^6.4.9",
16
+ "@codemirror/language": "^6.10.2",
17
+ "@codemirror/view": "^6.28.2",
18
+ "codemirror": "^6.0.1",
19
+ "js-beautify": "^1.15.1"
20
+ },
21
+ "peerDependencies": {
22
+ "vue-i18n": "^9.8.0",
23
+ "vue": "^3.0.0",
24
+ "element-plus": "^2.3.8"
25
+ },
26
+ "author": "Liubin"
27
27
  }
package/util.ts CHANGED
@@ -1,17 +1,17 @@
1
- import { javascript } from "@codemirror/lang-javascript";
2
- import { java } from "@codemirror/lang-java";
3
- import { css } from "@codemirror/lang-css";
4
- import { sql } from "@codemirror/lang-sql";
5
- import { html } from "@codemirror/lang-html";
6
-
7
- const plugins = {
8
- javascript: () => javascript(),
9
- sql: () => sql(),
10
- css: () => css(),
11
- java: () => java(),
12
- html: () => html(),
13
- };
14
-
15
- export const getCodeLanguagePlugin = function (language) {
16
- return plugins[language]();
17
- };
1
+ import { javascript } from "@codemirror/lang-javascript";
2
+ import { java } from "@codemirror/lang-java";
3
+ import { css } from "@codemirror/lang-css";
4
+ import { sql } from "@codemirror/lang-sql";
5
+ import { html } from "@codemirror/lang-html";
6
+
7
+ const plugins = {
8
+ javascript: () => javascript(),
9
+ sql: () => sql(),
10
+ css: () => css(),
11
+ java: () => java(),
12
+ html: () => html(),
13
+ };
14
+
15
+ export const getCodeLanguagePlugin = function (language) {
16
+ return plugins[language]();
17
+ };