yh-codemirror 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/CodeMirror.vue +174 -10
  2. package/package.json +26 -25
package/CodeMirror.vue CHANGED
@@ -1,16 +1,45 @@
1
1
  <template>
2
- <div class="yh-code-mirror-container">
2
+ <div
3
+ class="yh-code-mirror-container"
4
+ ref="YhCodemirrorContainer"
5
+ :style="codeMirrorStyle">
3
6
  <div class="code-slot">
4
7
  <slot name="pre-code"></slot>
5
8
  </div>
6
- <div ref="codeMirrorEditorRef"></div>
9
+ <div
10
+ class="codemirror-editor"
11
+ ref="codeMirrorEditorRef"
12
+ :style="codeMirrorEditorStyle"></div>
7
13
  <div class="code-slot">
8
14
  <slot name="next-code"></slot>
9
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>
10
39
  </div>
11
40
  </template>
12
41
  <script setup lang="ts">
13
- import { ref, onMounted } from "vue";
42
+ import { ref, onMounted, toRaw } from "vue";
14
43
  // @ts-ignore
15
44
  import type { Extension } from "codemirror";
16
45
  import { EditorView, basicSetup } from "codemirror";
@@ -19,17 +48,35 @@ import { EditorState, EditorSelection } from "@codemirror/state";
19
48
  import { javascriptLanguage } from "@codemirror/lang-javascript";
20
49
  import { solarizedDark } from "cm6-theme-solarized-dark";
21
50
  import { getCodeLanguagePlugin } from "./util";
22
- import { watch } from "vue";
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
+ }
23
64
 
24
65
  const codeMirrorEditorRef = ref();
66
+
25
67
  let view: null | EditorView = null;
26
68
  let state: null | EditorState = null;
69
+ // js-beautify 自定义配置
70
+ const codeBeautifyConfig = {
71
+ indent_size: 2,
72
+ };
27
73
 
28
74
  const props = withDefaults(
29
75
  defineProps<{
30
76
  modelValue: string;
31
77
  language?: string | string[];
32
78
  autocomplete?: any;
79
+ height?: number;
33
80
  }>(),
34
81
  {
35
82
  modelValue: "",
@@ -38,12 +85,31 @@ const props = withDefaults(
38
85
  }
39
86
  );
40
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 = "hidden";
103
+ }
104
+ return style;
105
+ });
106
+
41
107
  watch(
42
108
  () => props.modelValue,
43
109
  (val) => {
44
- if (state) {
45
- let end = state.doc.length;
46
- state.update({
110
+ if (view && state && val != view.state.doc.toString()) {
111
+ let end = view.state.doc.toString().length;
112
+ view.dispatch({
47
113
  changes: [
48
114
  {
49
115
  from: 0,
@@ -56,7 +122,58 @@ watch(
56
122
  }
57
123
  );
58
124
 
59
- const emits = defineEmits(["update:modelvalue"]);
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
+ };
60
177
 
61
178
  onMounted(() => {
62
179
  const extensions: Extension[] = [
@@ -64,7 +181,9 @@ onMounted(() => {
64
181
  solarizedDark,
65
182
  EditorView.lineWrapping,
66
183
  EditorView.updateListener.of((v: ViewUpdate) => {
67
- emits("update:modelvalue", v.state.doc.toString());
184
+ if (v.docChanged) {
185
+ emits("update:modelValue", v.state.doc.toString());
186
+ }
68
187
  }),
69
188
  ];
70
189
  const language = props.language;
@@ -107,13 +226,58 @@ onMounted(() => {
107
226
  <style lang="scss">
108
227
  .yh-code-mirror-container {
109
228
  width: 100%;
229
+ position: relative;
110
230
  .code-slot {
111
231
  width: 100%;
232
+ font-family: "Fira Code", "Roboto Mono", Consolas, "Microsoft Yahei";
112
233
  line-height: 25px;
113
- font-size: 14px;
234
+ font-size: 16px;
114
235
  padding-left: 29.77px;
115
236
  color: #ffffff;
116
237
  background-color: #173541;
117
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
+ }
118
282
  }
119
283
  </style>
package/package.json CHANGED
@@ -1,26 +1,27 @@
1
- {
2
- "name": "yh-codemirror",
3
- "version": "1.0.0",
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.9.0",
11
- "@codemirror/lang-css": "^6.2.1",
12
- "@codemirror/lang-java": "^6.0.1",
13
- "@codemirror/lang-javascript": "^6.1.8",
14
- "@codemirror/lang-sql": "^6.5.3",
15
- "@codemirror/lang-html": "^6.4.9",
16
- "@codemirror/language": "^6.9.0",
17
- "@codemirror/view": "^6.16.0",
18
- "codemirror": "^6.0.1"
19
- },
20
- "peerDependencies": {
21
- "vue-i18n": "9.8.0",
22
- "vue": "3.2.47",
23
- "element-plus": "2.3.8"
24
- },
25
- "author": "Liubin"
1
+ {
2
+ "name": "yh-codemirror",
3
+ "version": "1.0.2",
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"
26
27
  }