Переглянути джерело

feat: markdown editor process markers

NGPixel 4 роки тому
батько
коміт
f4502ccef7

+ 66 - 17
client/components/editor/editor-markdown.vue

@@ -436,17 +436,8 @@ export default {
       this.helpShown = false
     },
     onCmInput: _.debounce(function (newContent) {
-      linesMap = []
-      this.$store.set('editor/content', newContent)
-      this.previewHTML = DOMPurify.sanitize(md.render(newContent))
-      this.$nextTick(() => {
-        tabsetHelper.format()
-        this.renderMermaidDiagrams()
-        Prism.highlightAllUnder(this.$refs.editorPreview)
-        Array.from(this.$refs.editorPreview.querySelectorAll('pre.line-numbers')).forEach(pre => pre.classList.add('prismjs'))
-        this.scrollSync(this.cm)
-      })
-    }, 500),
+      this.processContent(newContent)
+    }, 600),
     onCmPaste (cm, ev) {
       // const clipItems = (ev.clipboardData || ev.originalEvent.clipboardData).items
       // for (let clipItem of clipItems) {
@@ -464,6 +455,19 @@ export default {
       //   }
       // }
     },
+    processContent (newContent) {
+      linesMap = []
+      // this.$store.set('editor/content', newContent)
+      this.processMarkers(this.cm.firstLine(), this.cm.lastLine())
+      this.previewHTML = DOMPurify.sanitize(md.render(newContent))
+      this.$nextTick(() => {
+        tabsetHelper.format()
+        this.renderMermaidDiagrams()
+        Prism.highlightAllUnder(this.$refs.editorPreview)
+        Array.from(this.$refs.editorPreview.querySelectorAll('pre.line-numbers')).forEach(pre => pre.classList.add('prismjs'))
+        this.scrollSync(this.cm)
+      })
+    },
     /**
      * Update cursor state
      */
@@ -658,6 +662,52 @@ export default {
       this.insertAtCursor({
         content: siteLangs.length > 0 ? `[${lastPart}](/${locale}/${path})` : `[${lastPart}](/${path})`
       })
+    },
+    processMarkers (from, to) {
+      let found = null
+      let foundStart = 0
+      this.cm.doc.getAllMarks().forEach(mk => {
+        if (mk.__kind) {
+          mk.clear()
+        }
+      })
+      this.cm.eachLine(from, to, ln => {
+        const line = ln.lineNo()
+        if (ln.text.startsWith('```diagram')) {
+          found = 'diagram'
+          foundStart = line
+        } else if (ln.text === '```' && found) {
+          switch (found) {
+            case 'diagram': {
+              this.addMarker({
+                kind: 'diagram',
+                from: { line: foundStart, ch: 3 },
+                to: { line: foundStart, ch: 10 },
+                text: 'Edit Diagram',
+                action: ((start, end) => {
+                  return (ev) => {
+                    this.cm.doc.setSelection({ line: start, ch: 0 }, { line: end, ch: 3 })
+                    // this.$store.set('editor/activeModalData', )
+                    this.toggleModal(`editorModalDrawio`)
+                  }
+                })(foundStart, line)
+              })
+              if (ln.height > 0) {
+                this.cm.foldCode(foundStart)
+              }
+              break
+            }
+          }
+          found = null
+        }
+      })
+    },
+    addMarker ({ kind, from, to, text, action }) {
+      const markerElm = document.createElement('span')
+      markerElm.appendChild(document.createTextNode(text))
+      markerElm.className = 'CodeMirror-buttonmarker'
+      markerElm.addEventListener('click', action)
+      this.cm.markText(from, to, { replacedWith: markerElm, __kind: kind })
     }
   },
   mounted() {
@@ -755,7 +805,7 @@ export default {
 
     // Render initial preview
 
-    this.onCmInput(this.$store.get('editor/content'))
+    this.processContent(this.$store.get('editor/content'))
     this.refresh()
 
     this.$root.$on('editorInsert', opts => {
@@ -775,11 +825,10 @@ export default {
           })
           break
         case 'DIAGRAM':
-          const foldLine = this.cm.getCursor().line
-          this.insertAtCursor({
-            content: '```diagram\n' + opts.text + '\n```'
-          })
-          this.cm.foldCode(foldLine)
+          const selStartLine = this.cm.getCursor('from').line
+          const selEndLine = this.cm.getCursor('to').line + 1
+          this.cm.doc.replaceSelection('```diagram\n' + opts.text + '\n```\n', 'start')
+          this.processMarkers(selStartLine, selEndLine)
           break
       }
     })

+ 11 - 0
client/scss/components/codemirror.scss

@@ -87,3 +87,14 @@
   border-radius: 5px;
   text-shadow: none;
 }
+
+.cm-s-wikijs-dark .CodeMirror-buttonmarker {
+  display: inline-block;
+  background-color: rgba(mc('blue', '500'), .3);
+  border: 1px solid mc('blue', '800');
+  padding: 1px 10px;
+  color: mc('blue', '200') !important;
+  border-radius: 5px;
+  margin-left: 5px;
+  cursor: pointer;
+}

+ 1 - 0
client/store/editor.js

@@ -6,6 +6,7 @@ const state = {
   content: '',
   mode: 'create',
   activeModal: '',
+  activeModalData: null,
   media: {
     folderTree: [],
     currentFolderId: 0,