Przeglądaj źródła

fix: set editor readonly on installation

Gerald 8 lat temu
rodzic
commit
d5f917c077

+ 2 - 1
package.json

@@ -65,6 +65,7 @@
     "codemirror": "^5.25.0",
     "core-js": "^2.4.1",
     "sync-promise-lite": "^0.2.3",
-    "vue": "^2.2.5"
+    "vue": "^2.2.5",
+    "vue-code": "^1.2.0"
   }
 }

+ 54 - 42
src/options/views/code.vue

@@ -1,8 +1,11 @@
 <template>
-  <div class="editor-code"></div>
+  <vue-code class="editor-code" ref="code"
+    :options="cmOptions" v-model="content" @ready="onReady"
+  />
 </template>
 
 <script>
+import VueCode from 'vue-code';
 import 'codemirror/lib/codemirror.css';
 import 'codemirror/theme/eclipse.css';
 import 'codemirror/mode/javascript/javascript';
@@ -41,56 +44,65 @@ function indentWithTab(cm) {
   CodeMirror.commands[key] = getHandler(key);
 });
 
+const cmOptions = {
+  continueComments: true,
+  matchBrackets: true,
+  autoCloseBrackets: true,
+  highlightSelectionMatches: true,
+  lineNumbers: true,
+  mode: 'javascript',
+  lineWrapping: true,
+  styleActiveLine: true,
+  foldGutter: true,
+  gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
+  theme: 'eclipse',
+};
+
 export default {
   props: [
     'readonly',
-    'content',
+    'value',
     'commands',
   ],
-  mounted() {
-    const cm = CodeMirror(this.$el, {
-      continueComments: true,
-      matchBrackets: true,
-      autoCloseBrackets: true,
-      highlightSelectionMatches: true,
-      lineNumbers: true,
-      mode: 'javascript',
-      lineWrapping: true,
-      styleActiveLine: true,
-      foldGutter: true,
-      gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
-      theme: 'eclipse',
-    });
-    this.cm = cm;
-    if (this.readonly) cm.setOption('readOnly', true);
-    cm.on('change', () => {
-      this.cachedContent = cm.getValue();
-      this.$emit('change', this.cachedContent);
-    });
-    cm.state.commands = this.commands;
-    cm.setOption('extraKeys', {
-      Esc: 'cancel',
-      Tab: indentWithTab,
-    });
-    cm.on('keyHandled', (_cm, _name, e) => {
-      e.stopPropagation();
-    });
-    this.setContent(this.content);
-    this.$emit('ready', cm);
+  components: {
+    VueCode,
+  },
+  data() {
+    return {
+      content: this.value,
+      cmOptions,
+    };
   },
   watch: {
-    content: 'setContent',
+    content(content) {
+      this.$emit('input', content);
+    },
+    value(value) {
+      if (value === this.content) return;
+      this.content = value;
+      const { cm } = this;
+      if (!cm) return;
+      cm.getDoc().clearHistory();
+      cm.focus();
+    },
+  },
+  mounted() {
+    // XXX vue-code does not emit `ready` in v1.2.0, call it directly
+    if (!this.cm) this.onReady(this.$refs.code.cm);
   },
   methods: {
-    setContent(content) {
-      if (content !== this.cachedContent) {
-        this.cachedContent = content;
-        const { cm } = this;
-        if (!cm) return;
-        cm.setValue(content);
-        cm.getDoc().clearHistory();
-        cm.focus();
-      }
+    onReady(cm) {
+      this.cm = cm;
+      if (this.readonly != null) cm.setOption('readOnly', true);
+      cm.state.commands = this.commands;
+      cm.setOption('extraKeys', {
+        Esc: 'cancel',
+        Tab: indentWithTab,
+      });
+      cm.on('keyHandled', (_cm, _name, e) => {
+        e.stopPropagation();
+      });
+      this.$emit('ready', cm);
     },
   },
 };

+ 1 - 1
src/options/views/confirm.vue

@@ -24,7 +24,7 @@
       <div class="ellipsis confirm-msg" v-text="message"></div>
     </div>
     <div class="frame-block flex-auto pos-rel">
-      <vm-code class="abs-full" readonly :content="code" :commands="commands" />
+      <vm-code class="abs-full" readonly v-model="code" :commands="commands" />
     </div>
   </div>
 </template>

+ 5 - 9
src/options/views/edit/index.vue

@@ -14,10 +14,8 @@
     </div>
     <div class="frame-block flex-auto pos-rel">
       <vm-code
-        v-show="nav === 'code'"
-        class="abs-full"
-        :content="code" :commands="commands"
-        @change="contentChange" @ready="initEditor"
+        v-show="nav === 'code'" class="abs-full"
+        v-model="code" :commands="commands" @ready="initEditor"
       />
       <vm-settings
         v-show="nav === 'settings'" class="abs-full"
@@ -148,6 +146,9 @@ export default {
     };
   },
   watch: {
+    code() {
+      this.canSave = true;
+    },
     settings: {
       deep: true,
       handler() {
@@ -265,13 +266,8 @@ export default {
     saveClose() {
       this.save().then(this.close);
     },
-    contentChange(code) {
-      this.code = code;
-      this.canSave = true;
-    },
     initEditor(cm) {
       this.cm = cm;
-      this.bindKeys();
     },
     find() {
       const { state } = this.search;