refactor: editor codeblock -> Vue component
This commit is contained in:
parent
ebe288a5b2
commit
f577a8134e
161
.build/_tasks.js
Normal file
161
.build/_tasks.js
Normal file
@ -0,0 +1,161 @@
|
||||
'use strict'
|
||||
|
||||
const _ = require('lodash')
|
||||
const Promise = require('bluebird')
|
||||
const colors = require('colors/safe')
|
||||
const fs = Promise.promisifyAll(require('fs-extra'))
|
||||
const path = require('path')
|
||||
const uglify = require('uglify-es')
|
||||
|
||||
module.exports = Promise.mapSeries([
|
||||
/**
|
||||
* SimpleMDE
|
||||
*/
|
||||
() => {
|
||||
return fs.accessAsync('./assets/js/simplemde').then(() => {
|
||||
console.info(colors.white(' └── ') + colors.magenta('SimpleMDE directory already exists. Task aborted.'))
|
||||
return true
|
||||
}).catch(err => {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.info(colors.white(' └── ') + colors.green('Copy + Minify SimpleMDE to assets...'))
|
||||
return fs.copy('./node_modules/simplemde/dist/simplemde.min.js', './assets/js/simplemde/simplemde.min.js')
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* ACE Modes
|
||||
*/
|
||||
() => {
|
||||
return fs.accessAsync('./assets/js/ace').then(() => {
|
||||
console.info(colors.white(' └── ') + colors.magenta('ACE modes directory already exists. Task aborted.'))
|
||||
return true
|
||||
}).catch(err => {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.info(colors.white(' └── ') + colors.green('Copy + Minify ACE modes to assets...'))
|
||||
return fs.ensureDirAsync('./assets/js/ace').then(() => {
|
||||
return Promise.join(
|
||||
// Core
|
||||
Promise.all([
|
||||
fs.readFileAsync('./node_modules/brace/index.js', 'utf8'),
|
||||
fs.readFileAsync('./node_modules/brace/ext/modelist.js', 'utf8'),
|
||||
fs.readFileAsync('./node_modules/brace/theme/dawn.js', 'utf8'),
|
||||
fs.readFileAsync('./node_modules/brace/theme/tomorrow_night.js', 'utf8'),
|
||||
fs.readFileAsync('./node_modules/brace/mode/markdown.js', 'utf8')
|
||||
]).then(items => {
|
||||
console.info(colors.white(' ace.js'))
|
||||
let result = uglify.minify(items.join(';\n'), { output: { 'max_line_len': 1000000 } })
|
||||
return fs.writeFileAsync('./assets/js/ace/ace.js', result.code)
|
||||
}),
|
||||
// Modes
|
||||
fs.readdirAsync('./node_modules/brace/mode').then(modeList => {
|
||||
return Promise.map(modeList, mdFile => {
|
||||
return fs.readFileAsync(path.join('./node_modules/brace/mode', mdFile), 'utf8').then(modeCode => {
|
||||
console.info(colors.white(' mode-' + mdFile))
|
||||
let result = uglify.minify(modeCode, { output: { 'max_line_len': 1000000 } })
|
||||
return fs.writeFileAsync(path.join('./assets/js/ace', 'mode-' + mdFile), result.code)
|
||||
})
|
||||
}, { concurrency: 3 })
|
||||
})
|
||||
)
|
||||
})
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* MathJax
|
||||
*/
|
||||
() => {
|
||||
return fs.accessAsync('./assets/js/mathjax').then(() => {
|
||||
console.info(colors.white(' └── ') + colors.magenta('MathJax directory already exists. Task aborted.'))
|
||||
return true
|
||||
}).catch(err => {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.info(colors.white(' └── ') + colors.green('Copy MathJax dependencies to assets...'))
|
||||
return fs.ensureDirAsync('./assets/js/mathjax').then(() => {
|
||||
return fs.copyAsync('./node_modules/mathjax', './assets/js/mathjax', {
|
||||
filter: (src, dest) => {
|
||||
let srcNormalized = src.replace(/\\/g, '/')
|
||||
let shouldCopy = false
|
||||
console.info(colors.white(' ' + srcNormalized))
|
||||
_.forEach([
|
||||
'/node_modules/mathjax',
|
||||
'/node_modules/mathjax/jax',
|
||||
'/node_modules/mathjax/jax/input',
|
||||
'/node_modules/mathjax/jax/output'
|
||||
], chk => {
|
||||
if (srcNormalized.endsWith(chk)) {
|
||||
shouldCopy = true
|
||||
}
|
||||
})
|
||||
_.forEach([
|
||||
'/node_modules/mathjax/extensions',
|
||||
'/node_modules/mathjax/MathJax.js',
|
||||
'/node_modules/mathjax/jax/element',
|
||||
'/node_modules/mathjax/jax/input/MathML',
|
||||
'/node_modules/mathjax/jax/input/TeX',
|
||||
'/node_modules/mathjax/jax/output/SVG'
|
||||
], chk => {
|
||||
if (srcNormalized.indexOf(chk) > 0) {
|
||||
shouldCopy = true
|
||||
}
|
||||
})
|
||||
if (shouldCopy && srcNormalized.indexOf('/fonts/') > 0 && srcNormalized.indexOf('/STIX-Web') <= 1) {
|
||||
shouldCopy = false
|
||||
}
|
||||
return shouldCopy
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* i18n
|
||||
*/
|
||||
() => {
|
||||
console.info(colors.white(' └── ') + colors.green('Copying i18n client files...'))
|
||||
return fs.ensureDirAsync('./assets/js/i18n').then(() => {
|
||||
return fs.readJsonAsync('./server/locales/en/browser.json').then(enContent => {
|
||||
return fs.readdirAsync('./server/locales').then(langs => {
|
||||
return Promise.map(langs, lang => {
|
||||
console.info(colors.white(' ' + lang + '.json'))
|
||||
let outputPath = path.join('./assets/js/i18n', lang + '.json')
|
||||
return fs.readJsonAsync(path.join('./server/locales', lang + '.json'), 'utf8').then((content) => {
|
||||
return fs.outputJsonAsync(outputPath, _.defaultsDeep(content, enContent))
|
||||
}).catch(err => { // eslint-disable-line handle-callback-err
|
||||
return fs.outputJsonAsync(outputPath, enContent)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Bundle pre-init scripts
|
||||
*/
|
||||
() => {
|
||||
console.info(colors.white(' └── ') + colors.green('Bundling pre-init scripts...'))
|
||||
let preInitContent = ''
|
||||
return fs.readdirAsync('./client/js/pre-init').map(f => {
|
||||
let fPath = path.join('./client/js/pre-init/', f)
|
||||
return fs.readFileAsync(fPath, 'utf8').then(fContent => {
|
||||
preInitContent += fContent + ';\n'
|
||||
})
|
||||
}).then(() => {
|
||||
return fs.outputFileAsync('./.build/_preinit.js', preInitContent, 'utf8')
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Delete Fusebox cache
|
||||
*/
|
||||
() => {
|
||||
console.info(colors.white(' └── ') + colors.green('Clearing fuse-box cache...'))
|
||||
return fs.emptyDirAsync('./.fusebox')
|
||||
}
|
||||
], f => { return f() })
|
@ -6,9 +6,15 @@
|
||||
"jest": true
|
||||
},
|
||||
"globals": {
|
||||
// Client
|
||||
"document": false,
|
||||
"navigator": false,
|
||||
"window": false,
|
||||
"siteLang": false,
|
||||
"socket": true,
|
||||
"wikijs": true,
|
||||
"FuseBox": false,
|
||||
// Server
|
||||
"appconfig": true,
|
||||
"appdata": true,
|
||||
"ROOTPATH": true,
|
||||
|
@ -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')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
162
fuse.js
162
fuse.js
@ -6,14 +6,9 @@
|
||||
* Client & Server compiler / bundler / watcher
|
||||
*/
|
||||
|
||||
const _ = require('lodash')
|
||||
const Promise = require('bluebird')
|
||||
const colors = require('colors/safe')
|
||||
const fs = Promise.promisifyAll(require('fs-extra'))
|
||||
const fsbx = require('fuse-box')
|
||||
const nodemon = require('nodemon')
|
||||
const path = require('path')
|
||||
const uglify = require('uglify-es')
|
||||
|
||||
// ======================================================
|
||||
// Parse cmd arguments
|
||||
@ -77,157 +72,7 @@ const SHIMS = {
|
||||
// ======================================================
|
||||
|
||||
console.info(colors.white('└── ') + colors.green('Running global tasks...'))
|
||||
|
||||
let globalTasks = Promise.mapSeries([
|
||||
/**
|
||||
* SimpleMDE
|
||||
*/
|
||||
() => {
|
||||
return fs.accessAsync('./assets/js/simplemde').then(() => {
|
||||
console.info(colors.white(' └── ') + colors.magenta('SimpleMDE directory already exists. Task aborted.'))
|
||||
return true
|
||||
}).catch(err => {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.info(colors.white(' └── ') + colors.green('Copy + Minify SimpleMDE to assets...'))
|
||||
return fs.copy('./node_modules/simplemde/dist/simplemde.min.js', './assets/js/simplemde/simplemde.min.js')
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* ACE Modes
|
||||
*/
|
||||
() => {
|
||||
return fs.accessAsync('./assets/js/ace').then(() => {
|
||||
console.info(colors.white(' └── ') + colors.magenta('ACE modes directory already exists. Task aborted.'))
|
||||
return true
|
||||
}).catch(err => {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.info(colors.white(' └── ') + colors.green('Copy + Minify ACE modes to assets...'))
|
||||
return fs.ensureDirAsync('./assets/js/ace').then(() => {
|
||||
return Promise.join(
|
||||
// Core
|
||||
Promise.all([
|
||||
fs.readFileAsync('./node_modules/brace/index.js', 'utf8'),
|
||||
fs.readFileAsync('./node_modules/brace/theme/dawn.js', 'utf8'),
|
||||
fs.readFileAsync('./node_modules/brace/mode/markdown.js', 'utf8')
|
||||
]).then(items => {
|
||||
console.info(colors.white(' source-view.js'))
|
||||
let result = uglify.minify(items.join(';\n'), { output: { 'max_line_len': 1000000 } })
|
||||
return fs.writeFileAsync('./assets/js/ace/source-view.js', result.code)
|
||||
}),
|
||||
// Modes
|
||||
fs.readdirAsync('./node_modules/brace/mode').then(modeList => {
|
||||
return Promise.map(modeList, mdFile => {
|
||||
return fs.readFileAsync(path.join('./node_modules/brace/mode', mdFile), 'utf8').then(modeCode => {
|
||||
console.info(colors.white(' mode-' + mdFile))
|
||||
let result = uglify.minify(modeCode, { output: { 'max_line_len': 1000000 } })
|
||||
return fs.writeFileAsync(path.join('./assets/js/ace', 'mode-' + mdFile), result.code)
|
||||
})
|
||||
}, { concurrency: 3 })
|
||||
})
|
||||
)
|
||||
})
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* MathJax
|
||||
*/
|
||||
() => {
|
||||
return fs.accessAsync('./assets/js/mathjax').then(() => {
|
||||
console.info(colors.white(' └── ') + colors.magenta('MathJax directory already exists. Task aborted.'))
|
||||
return true
|
||||
}).catch(err => {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.info(colors.white(' └── ') + colors.green('Copy MathJax dependencies to assets...'))
|
||||
return fs.ensureDirAsync('./assets/js/mathjax').then(() => {
|
||||
return fs.copyAsync('./node_modules/mathjax', './assets/js/mathjax', {
|
||||
filter: (src, dest) => {
|
||||
let srcNormalized = src.replace(/\\/g, '/')
|
||||
let shouldCopy = false
|
||||
console.info(colors.white(' ' + srcNormalized))
|
||||
_.forEach([
|
||||
'/node_modules/mathjax',
|
||||
'/node_modules/mathjax/jax',
|
||||
'/node_modules/mathjax/jax/input',
|
||||
'/node_modules/mathjax/jax/output'
|
||||
], chk => {
|
||||
if (srcNormalized.endsWith(chk)) {
|
||||
shouldCopy = true
|
||||
}
|
||||
})
|
||||
_.forEach([
|
||||
'/node_modules/mathjax/extensions',
|
||||
'/node_modules/mathjax/MathJax.js',
|
||||
'/node_modules/mathjax/jax/element',
|
||||
'/node_modules/mathjax/jax/input/MathML',
|
||||
'/node_modules/mathjax/jax/input/TeX',
|
||||
'/node_modules/mathjax/jax/output/SVG'
|
||||
], chk => {
|
||||
if (srcNormalized.indexOf(chk) > 0) {
|
||||
shouldCopy = true
|
||||
}
|
||||
})
|
||||
if (shouldCopy && srcNormalized.indexOf('/fonts/') > 0 && srcNormalized.indexOf('/STIX-Web') <= 1) {
|
||||
shouldCopy = false
|
||||
}
|
||||
return shouldCopy
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* i18n
|
||||
*/
|
||||
() => {
|
||||
console.info(colors.white(' └── ') + colors.green('Copying i18n client files...'))
|
||||
return fs.ensureDirAsync('./assets/js/i18n').then(() => {
|
||||
return fs.readJsonAsync('./server/locales/en/browser.json').then(enContent => {
|
||||
return fs.readdirAsync('./server/locales').then(langs => {
|
||||
return Promise.map(langs, lang => {
|
||||
console.info(colors.white(' ' + lang + '.json'))
|
||||
let outputPath = path.join('./assets/js/i18n', lang + '.json')
|
||||
return fs.readJsonAsync(path.join('./server/locales', lang + '.json'), 'utf8').then((content) => {
|
||||
return fs.outputJsonAsync(outputPath, _.defaultsDeep(content, enContent))
|
||||
}).catch(err => { // eslint-disable-line handle-callback-err
|
||||
return fs.outputJsonAsync(outputPath, enContent)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Bundle pre-init scripts
|
||||
*/
|
||||
() => {
|
||||
console.info(colors.white(' └── ') + colors.green('Bundling pre-init scripts...'))
|
||||
let preInitContent = ''
|
||||
return fs.readdirAsync('./client/js/pre-init').map(f => {
|
||||
let fPath = path.join('./client/js/pre-init/', f)
|
||||
return fs.readFileAsync(fPath, 'utf8').then(fContent => {
|
||||
preInitContent += fContent + ';\n'
|
||||
})
|
||||
}).then(() => {
|
||||
return fs.outputFileAsync('./.build/_preinit.js', preInitContent, 'utf8')
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Delete Fusebox cache
|
||||
*/
|
||||
() => {
|
||||
console.info(colors.white(' └── ') + colors.green('Clearing fuse-box cache...'))
|
||||
return fs.emptyDirAsync('./.fusebox')
|
||||
}
|
||||
], f => { return f() })
|
||||
let globalTasks = require('./.build/_tasks')
|
||||
|
||||
// ======================================================
|
||||
// Fuse Tasks
|
||||
@ -243,7 +88,7 @@ globalTasks.then(() => {
|
||||
fsbx.EnvPlugin({ NODE_ENV: (dev) ? 'development' : 'production' }),
|
||||
fsbx.VuePlugin(),
|
||||
['.scss', fsbx.SassPlugin({ outputStyle: (dev) ? 'nested' : 'compressed' }), fsbx.CSSPlugin()],
|
||||
dev && fsbx.BabelPlugin({ comments: false, presets: ['es2015'] }),
|
||||
fsbx.BabelPlugin({ comments: false, presets: ['es2015'] }),
|
||||
fsbx.JSONPlugin(),
|
||||
!dev && fsbx.UglifyESPlugin({
|
||||
compress: { unused: false },
|
||||
@ -261,14 +106,11 @@ globalTasks.then(() => {
|
||||
})
|
||||
}
|
||||
|
||||
// const bundleLibs = fuse.bundle('libs').instructions('~ index.js - brace')
|
||||
// const bundleApp = fuse.bundle('app').instructions('!> [index.js]')
|
||||
const bundleApp = fuse.bundle('app').instructions('> index.js')
|
||||
const bundleSetup = fuse.bundle('configure').instructions('> configure.js')
|
||||
|
||||
switch (mode) {
|
||||
case 'dev':
|
||||
// bundleLibs.watch()
|
||||
bundleApp.watch()
|
||||
break
|
||||
case 'dev-configure':
|
||||
|
@ -90,7 +90,7 @@
|
||||
"moment": "^2.18.1",
|
||||
"moment-timezone": "^0.5.13",
|
||||
"mongodb": "^2.2.27",
|
||||
"mongoose": "^4.10.2",
|
||||
"mongoose": "^4.10.3",
|
||||
"multer": "^1.3.0",
|
||||
"node-graceful": "^0.2.3",
|
||||
"ora": "^1.2.0",
|
||||
@ -156,8 +156,8 @@
|
||||
"snyk": "latest",
|
||||
"twemoji-awesome": "^1.0.6",
|
||||
"typescript": "^2.3.3",
|
||||
"uglify-es": "^3.0.11",
|
||||
"vee-validate": "^2.0.0-rc.4",
|
||||
"uglify-es": "^3.0.12",
|
||||
"vee-validate": "^2.0.0-rc.5",
|
||||
"vue": "^2.3.3",
|
||||
"vue-clipboards": "^1.0.0",
|
||||
"vue-lodash": "^1.0.3",
|
||||
|
@ -87,7 +87,10 @@ app.use(mw.security)
|
||||
// ----------------------------------------
|
||||
|
||||
app.use(favicon(path.join(ROOTPATH, 'assets', 'favicon.ico')))
|
||||
app.use(express.static(path.join(ROOTPATH, 'assets')))
|
||||
app.use(express.static(path.join(ROOTPATH, 'assets'), {
|
||||
index: false,
|
||||
maxAge: '7d'
|
||||
}))
|
||||
|
||||
// ----------------------------------------
|
||||
// Passport Authentication
|
||||
|
@ -9,7 +9,7 @@ block rootNavRight
|
||||
a.button.is-outlined(v-on:click='$store.dispatch("modalDiscardPage/open")')
|
||||
i.icon-cross
|
||||
span= t('nav.discard')
|
||||
a.button(v-on:click='$root.$emit("editor-save")')
|
||||
a.button(v-on:click='$root.$emit("editor/save")')
|
||||
i.icon-check
|
||||
span= t('nav.savechanges')
|
||||
|
||||
@ -18,5 +18,6 @@ block content
|
||||
.editor-area
|
||||
textarea(ref='editorTextArea')= pageData.markdown
|
||||
|
||||
editor-codeblock
|
||||
modal-discard-page(mode='edit', current-path=pageData.meta.path)
|
||||
page-loader(text=t('loading.editor'))
|
||||
|
37
yarn.lock
37
yarn.lock
@ -4491,13 +4491,6 @@ moment@2.x.x, "moment@>= 2.9.0", moment@^2.10.6, moment@^2.15, moment@^2.16.1, m
|
||||
version "2.18.1"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f"
|
||||
|
||||
mongodb-core@2.1.10:
|
||||
version "2.1.10"
|
||||
resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.10.tgz#eb290681d196d3346a492161aa2ea0905e63151b"
|
||||
dependencies:
|
||||
bson "~1.0.4"
|
||||
require_optional "~1.0.0"
|
||||
|
||||
mongodb-core@2.1.11:
|
||||
version "2.1.11"
|
||||
resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.11.tgz#1c38776ceb174997a99c28860eed9028da9b3e1a"
|
||||
@ -4505,15 +4498,7 @@ mongodb-core@2.1.11:
|
||||
bson "~1.0.4"
|
||||
require_optional "~1.0.0"
|
||||
|
||||
mongodb@2.2.26:
|
||||
version "2.2.26"
|
||||
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.26.tgz#1bd50c557c277c98e1a05da38c9839c4922b034a"
|
||||
dependencies:
|
||||
es6-promise "3.2.1"
|
||||
mongodb-core "2.1.10"
|
||||
readable-stream "2.2.7"
|
||||
|
||||
"mongodb@>= 1.2.0 <3.0.0", mongodb@^2.2.27:
|
||||
mongodb@2.2.27, "mongodb@>= 1.2.0 <3.0.0", mongodb@^2.2.27:
|
||||
version "2.2.27"
|
||||
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.27.tgz#34122034db66d983bcf6ab5adb26a24a70fef6e6"
|
||||
dependencies:
|
||||
@ -4521,15 +4506,15 @@ mongodb@2.2.26:
|
||||
mongodb-core "2.1.11"
|
||||
readable-stream "2.2.7"
|
||||
|
||||
mongoose@*, mongoose@^4.10.2:
|
||||
version "4.10.2"
|
||||
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.10.2.tgz#c7473ebada5f985cdac8e4182d40776b1aaf5352"
|
||||
mongoose@*, mongoose@^4.10.3:
|
||||
version "4.10.3"
|
||||
resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.10.3.tgz#5fbcd6549e67191ef30cab259644ff75f77026f9"
|
||||
dependencies:
|
||||
async "2.1.4"
|
||||
bson "~1.0.4"
|
||||
hooks-fixed "2.0.0"
|
||||
kareem "1.4.1"
|
||||
mongodb "2.2.26"
|
||||
mongodb "2.2.27"
|
||||
mpath "0.2.1"
|
||||
mpromise "0.5.5"
|
||||
mquery "2.3.1"
|
||||
@ -6863,9 +6848,9 @@ uc.micro@^1.0.1, uc.micro@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192"
|
||||
|
||||
uglify-es@^3.0.11:
|
||||
version "3.0.11"
|
||||
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.0.11.tgz#acc51dfd2eb3681a3620d9c64881c29d9159ef85"
|
||||
uglify-es@^3.0.12:
|
||||
version "3.0.12"
|
||||
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.0.12.tgz#7734f9bb64bbf36dbb1e059358343c58553e52c1"
|
||||
dependencies:
|
||||
commander "~2.9.0"
|
||||
source-map "~0.5.1"
|
||||
@ -7065,9 +7050,9 @@ vasync@^1.6.4:
|
||||
dependencies:
|
||||
verror "1.6.0"
|
||||
|
||||
vee-validate@^2.0.0-rc.4:
|
||||
version "2.0.0-rc.4"
|
||||
resolved "https://registry.yarnpkg.com/vee-validate/-/vee-validate-2.0.0-rc.4.tgz#49234ee481488fad909ab68a3f39edbb87f7a656"
|
||||
vee-validate@^2.0.0-rc.5:
|
||||
version "2.0.0-rc.5"
|
||||
resolved "https://registry.yarnpkg.com/vee-validate/-/vee-validate-2.0.0-rc.5.tgz#1de41866ddab3f8bebae3f3db653ef2c1c782fa0"
|
||||
|
||||
verror@1.3.6:
|
||||
version "1.3.6"
|
||||
|
Loading…
Reference in New Issue
Block a user