refactor: Pre-render TeX + MathML server-side to SVG
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
/* global $ */
|
||||
/* global $, siteRoot */
|
||||
/* eslint-disable no-new */
|
||||
|
||||
import Vue from 'vue'
|
||||
@@ -64,6 +64,7 @@ import colorPickerComponent from './components/color-picker.vue'
|
||||
import editorCodeblockComponent from './components/editor-codeblock.vue'
|
||||
import editorFileComponent from './components/editor-file.vue'
|
||||
import editorVideoComponent from './components/editor-video.vue'
|
||||
import historyComponent from './components/history.vue'
|
||||
import loadingSpinnerComponent from './components/loading-spinner.vue'
|
||||
import modalCreatePageComponent from './components/modal-create-page.vue'
|
||||
import modalCreateUserComponent from './components/modal-create-user.vue'
|
||||
@@ -130,7 +131,7 @@ i18next
|
||||
.use(i18nextXHR)
|
||||
.init({
|
||||
backend: {
|
||||
loadPath: '/js/i18n/{{lng}}.json'
|
||||
loadPath: siteRoot + '/js/i18n/{{lng}}.json'
|
||||
},
|
||||
lng: siteLang,
|
||||
fallbackLng: siteLang
|
||||
@@ -176,6 +177,7 @@ $(() => {
|
||||
editorCodeblock: editorCodeblockComponent,
|
||||
editorFile: editorFileComponent,
|
||||
editorVideo: editorVideoComponent,
|
||||
history: historyComponent,
|
||||
loadingSpinner: loadingSpinnerComponent,
|
||||
modalCreatePage: modalCreatePageComponent,
|
||||
modalCreateUser: modalCreateUserComponent,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
/* global $ */
|
||||
/* global $, siteRoot */
|
||||
|
||||
let mde
|
||||
|
||||
@@ -30,7 +30,7 @@ export default {
|
||||
return resp.json()
|
||||
}).then(resp => {
|
||||
if (resp.ok) {
|
||||
window.location.assign('/' + self.currentPath)
|
||||
window.location.assign(siteRoot + '/' + self.currentPath)
|
||||
} else {
|
||||
self.$store.dispatch('alert', {
|
||||
style: 'red',
|
||||
|
41
client/js/components/history.vue
Normal file
41
client/js/components/history.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template lang="pug">
|
||||
div {{ currentPath }}
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'history',
|
||||
props: ['currentPath'],
|
||||
data() {
|
||||
return {
|
||||
tree: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetch(basePath) {
|
||||
let self = this
|
||||
self.$store.dispatch('startLoading')
|
||||
self.$nextTick(() => {
|
||||
socket.emit('treeFetch', { basePath }, (data) => {
|
||||
if (self.tree.length > 0) {
|
||||
let branch = self._.last(self.tree)
|
||||
branch.hasChildren = true
|
||||
self._.find(branch.pages, { _id: basePath }).isActive = true
|
||||
}
|
||||
self.tree.push({
|
||||
hasChildren: false,
|
||||
pages: data
|
||||
})
|
||||
self.$store.dispatch('stopLoading')
|
||||
})
|
||||
})
|
||||
},
|
||||
goto(entryPath) {
|
||||
window.location.assign(siteRoot + '/' + entryPath)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -10,7 +10,7 @@
|
||||
li(v-if='searchres.length === 0')
|
||||
a: em {{ $t('search.nomatch') }}
|
||||
li(v-for='sres in searchres', v-bind:class='{ "is-active": searchmovekey === "res." + sres.entryPath }')
|
||||
a(v-bind:href='"/" + sres.entryPath') {{ sres.title }}
|
||||
a(v-bind:href='siteRoot + "/" + sres.entryPath') {{ sres.title }}
|
||||
p.searchresults-label(v-if='searchsuggest.length > 0') {{ $t('search.didyoumean') }}
|
||||
ul.searchresults-list(v-if='searchsuggest.length > 0')
|
||||
li(v-for='sug in searchsuggest', v-bind:class='{ "is-active": searchmovekey === "sug." + sug }')
|
||||
@@ -18,81 +18,81 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
searchq: '',
|
||||
searchres: [],
|
||||
searchsuggest: [],
|
||||
searchload: 0,
|
||||
searchactive: false,
|
||||
searchmoveidx: 0,
|
||||
searchmovekey: '',
|
||||
searchmovearr: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
searchq: function (val, oldVal) {
|
||||
let self = this
|
||||
self.searchmoveidx = 0
|
||||
if (val.length >= 3) {
|
||||
self.searchactive = true
|
||||
self.searchload++
|
||||
socket.emit('search', { terms: val }, (data) => {
|
||||
self.searchres = data.match
|
||||
self.searchsuggest = data.suggest
|
||||
self.searchmovearr = self._.concat([], self.searchres, self.searchsuggest)
|
||||
if (self.searchload > 0) { self.searchload-- }
|
||||
})
|
||||
} else {
|
||||
self.searchactive = false
|
||||
self.searchres = []
|
||||
self.searchsuggest = []
|
||||
self.searchmovearr = []
|
||||
self.searchload = 0
|
||||
}
|
||||
},
|
||||
searchmoveidx: function (val, oldVal) {
|
||||
if (val > 0) {
|
||||
this.searchmovekey = (this.searchmovearr[val - 1])
|
||||
? 'res.' + this.searchmovearr[val - 1].entryPath
|
||||
: 'sug.' + this.searchmovearr[val - 1]
|
||||
} else {
|
||||
this.searchmovekey = ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
useSuggestion: function (sug) {
|
||||
this.searchq = sug
|
||||
},
|
||||
closeSearch: function() {
|
||||
this.searchq = ''
|
||||
},
|
||||
moveSelectSearch: function () {
|
||||
if (this.searchmoveidx < 1) { return }
|
||||
let i = this.searchmoveidx - 1
|
||||
|
||||
if (this.searchmovearr[i]) {
|
||||
window.location.assign('/' + this.searchmovearr[i].entryPath)
|
||||
} else {
|
||||
this.searchq = this.searchmovearr[i]
|
||||
}
|
||||
},
|
||||
moveDownSearch: function () {
|
||||
if (this.searchmoveidx < this.searchmovearr.length) {
|
||||
this.searchmoveidx++
|
||||
}
|
||||
},
|
||||
moveUpSearch: function () {
|
||||
if (this.searchmoveidx > 0) {
|
||||
this.searchmoveidx--
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
let self = this
|
||||
$('main').on('click', self.closeSearch)
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
searchq: '',
|
||||
searchres: [],
|
||||
searchsuggest: [],
|
||||
searchload: 0,
|
||||
searchactive: false,
|
||||
searchmoveidx: 0,
|
||||
searchmovekey: '',
|
||||
searchmovearr: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
searchq: function (val, oldVal) {
|
||||
let self = this
|
||||
self.searchmoveidx = 0
|
||||
if (val.length >= 3) {
|
||||
self.searchactive = true
|
||||
self.searchload++
|
||||
socket.emit('search', { terms: val }, (data) => {
|
||||
self.searchres = data.match
|
||||
self.searchsuggest = data.suggest
|
||||
self.searchmovearr = self._.concat([], self.searchres, self.searchsuggest)
|
||||
if (self.searchload > 0) { self.searchload-- }
|
||||
})
|
||||
} else {
|
||||
self.searchactive = false
|
||||
self.searchres = []
|
||||
self.searchsuggest = []
|
||||
self.searchmovearr = []
|
||||
self.searchload = 0
|
||||
}
|
||||
},
|
||||
searchmoveidx: function (val, oldVal) {
|
||||
if (val > 0) {
|
||||
this.searchmovekey = (this.searchmovearr[val - 1])
|
||||
? 'res.' + this.searchmovearr[val - 1].entryPath
|
||||
: 'sug.' + this.searchmovearr[val - 1]
|
||||
} else {
|
||||
this.searchmovekey = ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
useSuggestion: function (sug) {
|
||||
this.searchq = sug
|
||||
},
|
||||
closeSearch: function () {
|
||||
this.searchq = ''
|
||||
},
|
||||
moveSelectSearch: function () {
|
||||
if (this.searchmoveidx < 1) { return }
|
||||
let i = this.searchmoveidx - 1
|
||||
|
||||
if (this.searchmovearr[i]) {
|
||||
window.location.assign(siteRoot + '/' + this.searchmovearr[i].entryPath)
|
||||
} else {
|
||||
this.searchq = this.searchmovearr[i]
|
||||
}
|
||||
},
|
||||
moveDownSearch: function () {
|
||||
if (this.searchmoveidx < this.searchmovearr.length) {
|
||||
this.searchmoveidx++
|
||||
}
|
||||
},
|
||||
moveUpSearch: function () {
|
||||
if (this.searchmoveidx > 0) {
|
||||
this.searchmoveidx--
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
let self = this
|
||||
$('main').on('click', self.closeSearch)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: '',
|
||||
name: 'tree',
|
||||
data () {
|
||||
return {
|
||||
tree: []
|
||||
|
@@ -2,8 +2,6 @@
|
||||
|
||||
/* global $ */
|
||||
|
||||
import MathJax from 'mathjax'
|
||||
|
||||
export default {
|
||||
name: 'content-view',
|
||||
data() {
|
||||
@@ -19,23 +17,5 @@ export default {
|
||||
return false
|
||||
})
|
||||
})
|
||||
MathJax.Hub.Config({
|
||||
jax: ['input/TeX', 'input/MathML', 'output/SVG'],
|
||||
extensions: ['tex2jax.js', 'mml2jax.js'],
|
||||
TeX: {
|
||||
extensions: ['AMSmath.js', 'AMSsymbols.js', 'noErrors.js', 'noUndefined.js']
|
||||
},
|
||||
SVG: {
|
||||
scale: 120,
|
||||
font: 'STIX-Web'
|
||||
},
|
||||
tex2jax: {
|
||||
preview: 'none'
|
||||
},
|
||||
showMathMenu: false,
|
||||
showProcessingMessages: false,
|
||||
messageStyle: 'none'
|
||||
})
|
||||
MathJax.Hub.Configured()
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,7 @@
|
||||
'use strict'
|
||||
|
||||
/* global siteRoot */
|
||||
|
||||
export default {
|
||||
name: 'source-view',
|
||||
data() {
|
||||
@@ -7,7 +9,7 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
let self = this
|
||||
FuseBox.import('/js/ace/ace.js', (ace) => {
|
||||
FuseBox.import(siteRoot + '/js/ace/ace.js', (ace) => {
|
||||
let scEditor = ace.edit('source-display')
|
||||
scEditor.setTheme('ace/theme/dawn')
|
||||
scEditor.getSession().setMode('ace/mode/markdown')
|
||||
|
@@ -1,4 +0,0 @@
|
||||
window.MathJax = {
|
||||
root: '/js/mathjax',
|
||||
delayStartupUntil: 'configured'
|
||||
}
|
Reference in New Issue
Block a user