refactor: editor codeblock -> Vue component
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
/* global siteLang */
|
||||
/* eslint-disable no-new */
|
||||
|
||||
import $ from 'jquery'
|
||||
@@ -147,7 +146,7 @@ $(() => {
|
||||
// ====================================
|
||||
|
||||
const i18n = new VueI18Next(i18next)
|
||||
new Vue({
|
||||
window.wikijs = new Vue({
|
||||
mixins: [helpers],
|
||||
components: {
|
||||
alert: alertComponent,
|
||||
|
@@ -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
|
||||
}
|
@@ -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>
|
||||
|
@@ -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')
|
||||
})
|
||||
}
|
||||
|
@@ -1,7 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
/* global FuseBox */
|
||||
|
||||
export default {
|
||||
name: 'source-view',
|
||||
data() {
|
||||
@@ -9,13 +7,14 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
let self = this
|
||||
FuseBox.import('/js/ace/source-view.js', (ace) => {
|
||||
FuseBox.import('/js/ace/ace.js', (ace) => {
|
||||
let scEditor = ace.edit('source-display')
|
||||
scEditor.setTheme('ace/theme/dawn')
|
||||
scEditor.getSession().setMode('ace/mode/markdown')
|
||||
scEditor.setOption('fontSize', '14px')
|
||||
scEditor.setOption('hScrollBarAlwaysVisible', false)
|
||||
scEditor.setOption('wrap', true)
|
||||
scEditor.setOption('showPrintMargin', false)
|
||||
scEditor.setReadOnly(true)
|
||||
scEditor.renderer.updateFull()
|
||||
scEditor.renderer.on('afterRender', () => {
|
||||
|
@@ -3,14 +3,20 @@
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
shown: false
|
||||
shown: false,
|
||||
content: ''
|
||||
},
|
||||
getters: {},
|
||||
mutations: {
|
||||
shownChange: (state, shownState) => { state.shown = shownState }
|
||||
shownChange: (state, shownState) => { state.shown = shownState },
|
||||
contentChange: (state, newContent) => { state.content = newContent }
|
||||
},
|
||||
actions: {
|
||||
open({ commit }) { commit('shownChange', true) },
|
||||
open({ commit }, opts) {
|
||||
commit('shownChange', true)
|
||||
commit('contentChange', opts.initialContent || '')
|
||||
wikijs.$emit('editorCodeblock/init')
|
||||
},
|
||||
close({ commit }) { commit('shownChange', false) }
|
||||
}
|
||||
}
|
||||
|
@@ -2,8 +2,21 @@
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {},
|
||||
state: {
|
||||
busy: false,
|
||||
insertContent: ''
|
||||
},
|
||||
getters: {},
|
||||
mutations: {},
|
||||
actions: {}
|
||||
mutations: {
|
||||
busyChange: (state, busyState) => { state.shown = busyState },
|
||||
insertContentChange: (state, newContent) => { state.insertContent = newContent }
|
||||
},
|
||||
actions: {
|
||||
busyStart({ commit }) { commit('busyChange', true) },
|
||||
busyStop({ commit }) { commit('busyChange', false) },
|
||||
insert({ commit }, content) {
|
||||
commit('insertContentChange', content)
|
||||
wikijs.$emit('editor/insert')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user