refactor: editor codeblock -> Vue component

This commit is contained in:
NGPixel
2017-05-28 14:34:50 -04:00
parent ebe288a5b2
commit f577a8134e
14 changed files with 295 additions and 303 deletions

View File

@@ -1,87 +0,0 @@
'use strict'
import $ from 'jquery'
import Vue from 'vue'
import _ from 'lodash'
import * as ace from 'brace'
import 'brace/theme/tomorrow_night'
import 'brace/mode/markdown'
import 'brace-ext-modelist'
let codeEditor = null
// ACE - Mode Loader
let modelistLoaded = []
let loadAceMode = (m) => {
return $.ajax({
url: '/js/ace/mode-' + m + '.js',
dataType: 'script',
cache: true,
beforeSend: () => {
if (_.includes(modelistLoaded, m)) {
return false
}
},
success: () => {
modelistLoaded.push(m)
}
})
}
// Vue Code Block instance
module.exports = (mde, mdeModalOpenState) => {
let modelist = ace.acequire('ace/ext/modelist')
let vueCodeBlock = new Vue({
el: '#modal-editor-codeblock',
data: {
modes: modelist.modesByName,
modeSelected: 'text',
initContent: ''
},
watch: {
modeSelected: (val, oldVal) => {
loadAceMode(val).done(() => {
ace.acequire('ace/mode/' + val)
codeEditor.getSession().setMode('ace/mode/' + val)
})
}
},
methods: {
open: (ev) => {
mdeModalOpenState = true
$('#modal-editor-codeblock').addClass('is-active')
_.delay(() => {
codeEditor = ace.edit('codeblock-editor')
codeEditor.setTheme('ace/theme/tomorrow_night')
codeEditor.getSession().setMode('ace/mode/' + vueCodeBlock.modeSelected)
codeEditor.setOption('fontSize', '14px')
codeEditor.setOption('hScrollBarAlwaysVisible', false)
codeEditor.setOption('wrap', true)
codeEditor.setValue(vueCodeBlock.initContent)
codeEditor.focus()
codeEditor.renderer.updateFull()
}, 300)
},
cancel: (ev) => {
mdeModalOpenState = false // eslint-disable-line no-undef
$('#modal-editor-codeblock').removeClass('is-active')
vueCodeBlock.initContent = ''
},
insertCode: (ev) => {
if (mde.codemirror.doc.somethingSelected()) {
mde.codemirror.execCommand('singleSelection')
}
let codeBlockText = '\n```' + vueCodeBlock.modeSelected + '\n' + codeEditor.getValue() + '\n```\n'
mde.codemirror.doc.replaceSelection(codeBlockText)
vueCodeBlock.cancel()
}
}
})
return vueCodeBlock
}

View File

@@ -24,28 +24,85 @@
</template>
<script>
let codeEditor
let ace
export default {
name: 'editor-codeblock',
data () {
return {}
return {
modes: [],
modeSelected: 'text',
modelistLoaded: []
}
},
computed: {
content () {
return this.$store.state.editorCodeblock.content
},
isShown () {
return this.$store.state.editorCodeblock.shown
}
},
watch: {
modeSelected(val, oldVal) {
this.loadMode(val)
}
},
methods: {
init () {
let self = this
self._.delay(() => {
codeEditor = ace.edit('codeblock-editor')
codeEditor.setTheme('ace/theme/tomorrow_night')
codeEditor.getSession().setMode('ace/mode/' + self.modeSelected)
codeEditor.setOption('fontSize', '14px')
codeEditor.setOption('hScrollBarAlwaysVisible', false)
codeEditor.setOption('wrap', true)
codeEditor.setOption('showPrintMargin', false)
codeEditor.setValue(self.content)
codeEditor.focus()
codeEditor.renderer.updateFull()
}, 100)
},
loadMode (m) {
let self = this
if (self._.includes(self.modelistLoaded, m)) {
codeEditor.getSession().setMode('ace/mode/' + m)
} else {
self.$http.get('/js/ace/mode-' + m + '.js').then(resp => {
if(resp.ok) {
eval(resp.bodyText)
self.modelistLoaded.push(m)
ace.acequire('ace/mode/' + m)
codeEditor.getSession().setMode('ace/mode/' + m)
}
})
}
},
cancel () {
this.$store.dispatch('editorCodeBlock/close')
codeEditor.destroy()
this.$store.dispatch('editorCodeblock/close')
},
insertCode () {
let codeBlockText = '\n```' + this.modeSelected + '\n' + codeEditor.getValue() + '\n```\n'
this.$store.dispatch('editor/insert', codeBlockText)
this.$store.dispatch('alert', {
style: 'pink',
style: 'blue',
icon: 'inbox',
msg: 'Your code block has been inserted.'
})
this.cancel()
}
},
mounted() {
FuseBox.import('/js/ace/ace.js', (acePkg) => {
ace = acePkg
this.modes = ace.acequire('ace/ext/modelist').modesByName
})
this.$root.$on('editorCodeblock/init', this.init)
}
}
</script>

View File

@@ -1,7 +1,5 @@
'use strict'
/* global FuseBox */
import filesize from 'filesize.js'
import $ from 'jquery'
@@ -18,7 +16,18 @@ export default {
data() {
return {}
},
computed: {
insertContent() {
return this.$store.state.editor.insertContent
}
},
methods: {
insert(content) {
if (mde.codemirror.doc.somethingSelected()) {
mde.codemirror.execCommand('singleSelection')
}
mde.codemirror.doc.replaceSelection(this.insertContent)
},
save() {
let self = this
this.$http.put(window.location.href, {
@@ -177,13 +186,9 @@ export default {
{
name: 'code-block',
action: (editor) => {
// if (!mdeModalOpenState) {
// if (mde.codemirror.doc.somethingSelected()) {
// vueCodeBlock.initContent = mde.codemirror.doc.getSelection()
// }
// vueCodeBlock.open()
// }
self.$store.dispatch('editorCodeblock/open', {
initialContent: (mde.codemirror.doc.somethingSelected()) ? mde.codemirror.doc.getSelection() : ''
})
},
className: 'icon-code',
title: 'Code Block'
@@ -212,8 +217,6 @@ export default {
})
// Save
this.$root.$on('editor-save', this.save)
$(window).bind('keydown', (ev) => {
if (ev.ctrlKey || ev.metaKey) {
switch (String.fromCharCode(ev.which).toLowerCase()) {
@@ -225,6 +228,10 @@ export default {
}
})
// Listeners
this.$root.$on('editor/save', this.save)
this.$root.$on('editor/insert', this.insert)
this.$store.dispatch('pageLoader/complete')
})
}