feat: mk editor toolbar + help dialog + fixes
This commit is contained in:
parent
ca4e0ada30
commit
de1dddbc90
@ -126,6 +126,6 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-family: 'Source Sans Pro', sans-serif;
|
font-family: 'Roboto Mono', monospace;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
nav-header(dense)
|
nav-header(dense)
|
||||||
template(slot='mid')
|
template(slot='mid')
|
||||||
v-spacer
|
v-spacer
|
||||||
.subheading {{currentPageTitle}}
|
.subheading.grey--text {{currentPageTitle}}
|
||||||
v-spacer
|
v-spacer
|
||||||
template(slot='actions')
|
template(slot='actions')
|
||||||
v-btn(
|
v-btn(
|
||||||
@ -32,7 +32,7 @@
|
|||||||
v-icon(color='red', :left='$vuetify.breakpoint.lgAndUp') close
|
v-icon(color='red', :left='$vuetify.breakpoint.lgAndUp') close
|
||||||
span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('editor:close') }}
|
span.white--text(v-if='$vuetify.breakpoint.lgAndUp') {{ $t('editor:close') }}
|
||||||
v-content
|
v-content
|
||||||
component(:is='currentEditor')
|
component(:is='currentEditor', :save='save')
|
||||||
editor-modal-properties(v-model='dialogProps')
|
editor-modal-properties(v-model='dialogProps')
|
||||||
editor-modal-editorselect(v-model='dialogEditorSelector')
|
editor-modal-editorselect(v-model='dialogEditorSelector')
|
||||||
editor-modal-unsaved(v-model='dialogUnsaved', @discard='exitGo')
|
editor-modal-unsaved(v-model='dialogUnsaved', @discard='exitGo')
|
||||||
@ -199,7 +199,7 @@ export default {
|
|||||||
resp = _.get(resp, 'data.pages.create', {})
|
resp = _.get(resp, 'data.pages.create', {})
|
||||||
if (_.get(resp, 'responseResult.succeeded')) {
|
if (_.get(resp, 'responseResult.succeeded')) {
|
||||||
this.$store.commit('showNotification', {
|
this.$store.commit('showNotification', {
|
||||||
message: this.$t('editor:save.success'),
|
message: this.$t('editor:save.createSuccess'),
|
||||||
style: 'success',
|
style: 'success',
|
||||||
icon: 'check'
|
icon: 'check'
|
||||||
})
|
})
|
||||||
@ -234,7 +234,7 @@ export default {
|
|||||||
resp = _.get(resp, 'data.pages.update', {})
|
resp = _.get(resp, 'data.pages.update', {})
|
||||||
if (_.get(resp, 'responseResult.succeeded')) {
|
if (_.get(resp, 'responseResult.succeeded')) {
|
||||||
this.$store.commit('showNotification', {
|
this.$store.commit('showNotification', {
|
||||||
message: this.$t('editor:save.success'),
|
message: this.$t('editor:save.updateSuccess'),
|
||||||
style: 'success',
|
style: 'success',
|
||||||
icon: 'check'
|
icon: 'check'
|
||||||
})
|
})
|
||||||
|
@ -124,8 +124,8 @@
|
|||||||
v-icon crop_free
|
v-icon crop_free
|
||||||
span Distraction Free Mode
|
span Distraction Free Mode
|
||||||
v-tooltip(right, color='teal')
|
v-tooltip(right, color='teal')
|
||||||
v-btn(icon, slot='activator', dark, disabled).mx-0
|
v-btn(icon, slot='activator', dark, @click='toggleHelp').mx-0
|
||||||
v-icon help
|
v-icon(:color='helpShown ? `teal` : ``') help
|
||||||
span Markdown Formatting Help
|
span Markdown Formatting Help
|
||||||
.editor-markdown-editor
|
.editor-markdown-editor
|
||||||
.editor-markdown-editor-title(v-if='previewShown', @click='previewShown = false') Editor
|
.editor-markdown-editor-title(v-if='previewShown', @click='previewShown = false') Editor
|
||||||
@ -141,11 +141,16 @@
|
|||||||
.caption.px-3 /{{path}}
|
.caption.px-3 /{{path}}
|
||||||
v-spacer
|
v-spacer
|
||||||
.caption Markdown
|
.caption Markdown
|
||||||
|
v-spacer
|
||||||
|
.caption Ln {{cursorPos.line + 1}}, Col {{cursorPos.ch + 1}}
|
||||||
|
|
||||||
|
markdown-help(v-if='helpShown')
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { get, sync } from 'vuex-pathify'
|
import { get, sync } from 'vuex-pathify'
|
||||||
|
import markdownHelp from './markdown/help.vue'
|
||||||
|
|
||||||
// ========================================
|
// ========================================
|
||||||
// IMPORTS
|
// IMPORTS
|
||||||
@ -232,7 +237,13 @@ md.renderer.rules.heading_open = injectLineNumbers
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
codemirror
|
codemirror,
|
||||||
|
markdownHelp
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
save: {
|
||||||
|
type: Function
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -251,8 +262,10 @@ export default {
|
|||||||
},
|
},
|
||||||
viewportMargin: 50
|
viewportMargin: 50
|
||||||
},
|
},
|
||||||
|
cursorPos: { ch: 0, line: 1 },
|
||||||
previewShown: true,
|
previewShown: true,
|
||||||
previewHTML: ''
|
previewHTML: '',
|
||||||
|
helpShown: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -281,13 +294,34 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_.set(keyBindings, `${CtrlKey}-S`, cm => {
|
_.set(keyBindings, `${CtrlKey}-S`, cm => {
|
||||||
self.$parent.save()
|
this.save()
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
_.set(keyBindings, `${CtrlKey}-B`, cm => {
|
||||||
|
this.toggleMarkup({ start: `**` })
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
_.set(keyBindings, `${CtrlKey}-I`, cm => {
|
||||||
|
this.toggleMarkup({ start: `*` })
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
_.set(keyBindings, `${CtrlKey}-Alt-Right`, cm => {
|
||||||
|
let lvl = this.getHeaderLevel(cm)
|
||||||
|
if (lvl >= 6) { lvl = 5 }
|
||||||
|
this.setHeaderLine(lvl + 1)
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
_.set(keyBindings, `${CtrlKey}-Alt-Left`, cm => {
|
||||||
|
let lvl = this.getHeaderLevel(cm)
|
||||||
|
if (lvl <= 1) { lvl = 2 }
|
||||||
|
this.setHeaderLine(lvl - 1)
|
||||||
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
cm.setSize(null, 'calc(100vh - 112px - 24px)')
|
cm.setSize(null, 'calc(100vh - 112px - 24px)')
|
||||||
cm.setOption('extraKeys', keyBindings)
|
cm.setOption('extraKeys', keyBindings)
|
||||||
cm.on('cursorActivity', cm => {
|
cm.on('cursorActivity', cm => {
|
||||||
this.toolbarSync(cm)
|
this.positionSync(cm)
|
||||||
this.scrollSync(cm)
|
this.scrollSync(cm)
|
||||||
})
|
})
|
||||||
this.onCmInput(this.code)
|
this.onCmInput(this.code)
|
||||||
@ -298,20 +332,19 @@ export default {
|
|||||||
this.previewHTML = md.render(newContent)
|
this.previewHTML = md.render(newContent)
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
Prism.highlightAllUnder(this.$refs.editorPreview)
|
Prism.highlightAllUnder(this.$refs.editorPreview)
|
||||||
|
Array.from(this.$refs.editorPreview.querySelectorAll('pre.line-numbers')).map(pre => pre.classList.add('prismjs'))
|
||||||
this.scrollSync(this.cm)
|
this.scrollSync(this.cm)
|
||||||
})
|
})
|
||||||
}, 500),
|
}, 500),
|
||||||
/**
|
/**
|
||||||
* Update toolbar state
|
* Update cursor state
|
||||||
*/
|
*/
|
||||||
toolbarSync(cm) {
|
positionSync(cm) {
|
||||||
// const pos = cm.getCursor('start')
|
this.cursorPos = cm.getCursor('head')
|
||||||
// const token = cm.getTokenAt(pos)
|
|
||||||
|
|
||||||
// if (!token.type) { return }
|
|
||||||
|
|
||||||
// console.info(token)
|
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Wrap selection with start / end tags
|
||||||
|
*/
|
||||||
toggleMarkup({ start, end }) {
|
toggleMarkup({ start, end }) {
|
||||||
if (!end) { end = start }
|
if (!end) { end = start }
|
||||||
if (!this.cm.doc.somethingSelected()) {
|
if (!this.cm.doc.somethingSelected()) {
|
||||||
@ -323,6 +356,9 @@ export default {
|
|||||||
}
|
}
|
||||||
this.cm.doc.replaceSelections(this.cm.doc.getSelections().map(s => start + s + end))
|
this.cm.doc.replaceSelections(this.cm.doc.getSelections().map(s => start + s + end))
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Set current line as header
|
||||||
|
*/
|
||||||
setHeaderLine(lvl) {
|
setHeaderLine(lvl) {
|
||||||
const curLine = this.cm.doc.getCursor('head').line
|
const curLine = this.cm.doc.getCursor('head').line
|
||||||
let lineContent = this.cm.doc.getLine(curLine)
|
let lineContent = this.cm.doc.getLine(curLine)
|
||||||
@ -333,11 +369,31 @@ export default {
|
|||||||
lineContent = _.times(lvl, n => '#').join('') + ` ` + lineContent
|
lineContent = _.times(lvl, n => '#').join('') + ` ` + lineContent
|
||||||
this.cm.doc.replaceRange(lineContent, { line: curLine, ch: 0 }, { line: curLine, ch: lineLength })
|
this.cm.doc.replaceRange(lineContent, { line: curLine, ch: 0 }, { line: curLine, ch: lineLength })
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Get the header lever of the current line
|
||||||
|
*/
|
||||||
|
getHeaderLevel(cm) {
|
||||||
|
const curLine = this.cm.doc.getCursor('head').line
|
||||||
|
let lineContent = this.cm.doc.getLine(curLine)
|
||||||
|
let lvl = 0
|
||||||
|
|
||||||
|
const result = lineContent.match(/^(#+) /)
|
||||||
|
if (result) {
|
||||||
|
lvl = _.get(result, '[1]', '').length
|
||||||
|
}
|
||||||
|
return lvl
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Insert content after current line
|
||||||
|
*/
|
||||||
insertAfter({ content, newLine }) {
|
insertAfter({ content, newLine }) {
|
||||||
const curLine = this.cm.doc.getCursor('to').line
|
const curLine = this.cm.doc.getCursor('to').line
|
||||||
const lineLength = this.cm.doc.getLine(curLine).length
|
const lineLength = this.cm.doc.getLine(curLine).length
|
||||||
this.cm.doc.replaceRange(newLine ? `\n${content}\n` : content, { line: curLine, ch: lineLength + 1 })
|
this.cm.doc.replaceRange(newLine ? `\n${content}\n` : content, { line: curLine, ch: lineLength + 1 })
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Insert content before current line
|
||||||
|
*/
|
||||||
insertBeforeEachLine({ content, after }) {
|
insertBeforeEachLine({ content, after }) {
|
||||||
let lines = []
|
let lines = []
|
||||||
if (!this.cm.doc.somethingSelected()) {
|
if (!this.cm.doc.somethingSelected()) {
|
||||||
@ -381,8 +437,8 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 500),
|
}, 500),
|
||||||
toggleAround (before, after) {
|
toggleHelp () {
|
||||||
|
this.helpShown = !this.helpShown
|
||||||
},
|
},
|
||||||
toggleFullscreen () {
|
toggleFullscreen () {
|
||||||
this.cm.setOption('fullScreen', true)
|
this.cm.setOption('fullScreen', true)
|
||||||
|
335
client/components/editor/markdown/help.vue
Normal file
335
client/components/editor/markdown/help.vue
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
<template lang='pug'>
|
||||||
|
v-card.editor-markdown-help.animated.fadeInLeft(flat, tile)
|
||||||
|
v-container.pa-3(grid-list-lg, fluid)
|
||||||
|
v-layout(row, wrap)
|
||||||
|
v-flex(xs4)
|
||||||
|
v-card.radius-7.animated.fadeInUp(light)
|
||||||
|
v-card-text
|
||||||
|
.d-flex
|
||||||
|
v-toolbar.radius-7(color='teal lighten-5', dense, flat, height='44')
|
||||||
|
v-icon.mr-3(color='teal') info
|
||||||
|
.body-2.teal--text Markdown Reference
|
||||||
|
.body-2.mt-3 Bold
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div **Lorem ipsum**
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text
|
||||||
|
.caption: strong Lorem ipsum
|
||||||
|
.body-2.mt-3 Italic
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div *Lorem ipsum*
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text
|
||||||
|
.caption: em Lorem ipsum
|
||||||
|
.body-2.mt-3 Strikethrough
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div ~~Lorem ipsum~~
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text
|
||||||
|
.caption(style='text-decoration: line-through;') Lorem ipsum
|
||||||
|
.body-2.mt-3 Headers
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div # Header 1
|
||||||
|
div ## Header 2
|
||||||
|
div ### Header 3
|
||||||
|
div #### Header 4
|
||||||
|
div ##### Header 5
|
||||||
|
div ###### Header 6
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text
|
||||||
|
div(style='font-weight: 700; font-size: 24px;') Header 1
|
||||||
|
div(style='font-weight: 700; font-size: 22px;') Header 2
|
||||||
|
div(style='font-weight: 700; font-size: 20px;') Header 3
|
||||||
|
div(style='font-weight: 700; font-size: 18px;') Header 4
|
||||||
|
div(style='font-weight: 700; font-size: 16px;') Header 5
|
||||||
|
div(style='font-weight: 700; font-size: 14px;') Header 6
|
||||||
|
.body-2.mt-3 Unordered Lists
|
||||||
|
.caption.grey--text.text--darken-1: em You can also use the asterisk symbol instead of the dash.
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div - Unordered List Item 1
|
||||||
|
div - Unordered List Item 2
|
||||||
|
div - Unordered List Item 3
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text
|
||||||
|
ul
|
||||||
|
li Unordered List Item 1
|
||||||
|
li Unordered List Item 2
|
||||||
|
li Unordered List Item 3
|
||||||
|
.body-2.mt-3 Ordered Lists
|
||||||
|
.caption.grey--text.text--darken-1: em Even though we prefix all lines with #[strong 1.], the output will be correctly numbered automatically.
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div 1. Ordered List Item 1
|
||||||
|
div 1. Ordered List Item 2
|
||||||
|
div 1. Ordered List Item 3
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text
|
||||||
|
ol
|
||||||
|
li Unordered List Item 1
|
||||||
|
li Unordered List Item 2
|
||||||
|
li Unordered List Item 3
|
||||||
|
|
||||||
|
v-flex(xs4)
|
||||||
|
v-card.radius-7.animated.fadeInUp.wait-p1s(light)
|
||||||
|
v-card-text
|
||||||
|
.d-flex
|
||||||
|
v-toolbar.radius-7(color='teal lighten-5', dense, flat, height='44')
|
||||||
|
v-icon.mr-3(color='teal') info
|
||||||
|
.body-2.teal--text Markdown Reference (continued)
|
||||||
|
.body-2.mt-3 Superscript
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div Lorem ^ipsum^
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text
|
||||||
|
.caption Lorem #[sup ipsum]
|
||||||
|
.body-2.mt-3 Subscript
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div Lorem ~ipsum~
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text
|
||||||
|
.caption: em Lorem #[sub ipsum]
|
||||||
|
.body-2.mt-3 Horizontal Line
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div Lorem ipsum
|
||||||
|
div ---
|
||||||
|
div Dolor sit amet
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text
|
||||||
|
.caption Lorem ipsum
|
||||||
|
v-divider.my-2
|
||||||
|
.caption Dolor sit amet
|
||||||
|
.body-2.mt-3 Inline Code
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div Lorem `ipsum dolor sit` amet
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text
|
||||||
|
.caption Lorem #[code ipsum dolor sit] amet
|
||||||
|
.body-2.mt-3 Code Blocks
|
||||||
|
.caption.grey--text.text--darken-1: em In the example below, #[strong js] defines the syntax highlighting language to use. It can be omitted.
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div ```js
|
||||||
|
div function main () {
|
||||||
|
div.pl-3 echo 'Lorem ipsum'
|
||||||
|
div }
|
||||||
|
div ```
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text.contents
|
||||||
|
pre.prismjs.line-numbers.language-js
|
||||||
|
code.language-js
|
||||||
|
span.token.keyword function
|
||||||
|
span.token.function main
|
||||||
|
span.token.punctuation (
|
||||||
|
span.token.punctuation )
|
||||||
|
span.token.punctuation {#[br]
|
||||||
|
| echo
|
||||||
|
span.token.string 'Lorem ipsum'#[br]
|
||||||
|
span.token.punctuation }
|
||||||
|
span.line-numbers-rows(aria-hidden='true')
|
||||||
|
span
|
||||||
|
span
|
||||||
|
span
|
||||||
|
.body-2.mt-3 Blockquotes
|
||||||
|
v-layout(row)
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-source(flat)
|
||||||
|
v-card-text
|
||||||
|
div > Lorem ipsum
|
||||||
|
div > dolor sit amet
|
||||||
|
div > consectetur adipiscing elit
|
||||||
|
v-icon chevron_right
|
||||||
|
v-flex(xs6)
|
||||||
|
v-card.editor-markdown-help-result(flat)
|
||||||
|
v-card-text
|
||||||
|
blockquote(style='border: 1px solid #263238; border-radius: .5rem; padding: 1rem 24px;') Lorem ipsum#[br]dolor sit amet#[br]consectetur adipiscing elit
|
||||||
|
|
||||||
|
v-flex(xs4)
|
||||||
|
v-card.radius-7.animated.fadeInUp.wait-p2s(light)
|
||||||
|
v-card-text
|
||||||
|
v-toolbar.radius-7(color='teal lighten-5', dense, flat)
|
||||||
|
v-icon.mr-3(color='teal') keyboard
|
||||||
|
.body-2.teal--text Keyboard Shortcuts
|
||||||
|
v-list.editor-markdown-help-kbd(two-line, dense)
|
||||||
|
v-list-tile
|
||||||
|
v-list-tile-content.body-2 Bold
|
||||||
|
v-list-tile-action #[kbd {{ctrlKey}}] + #[kbd B]
|
||||||
|
v-divider
|
||||||
|
v-list-tile
|
||||||
|
v-list-tile-content.body-2 Italic
|
||||||
|
v-list-tile-action #[kbd {{ctrlKey}}] + #[kbd I]
|
||||||
|
v-divider
|
||||||
|
v-list-tile
|
||||||
|
v-list-tile-content.body-2 Increase Header Level
|
||||||
|
v-list-tile-action #[kbd {{ctrlKey}}] + #[kbd {{altKey}}] + #[kbd Right]
|
||||||
|
v-divider
|
||||||
|
v-list-tile
|
||||||
|
v-list-tile-content.body-2 Decrease Header Level
|
||||||
|
v-list-tile-action #[kbd {{ctrlKey}}] + #[kbd {{altKey}}] + #[kbd Left]
|
||||||
|
v-divider
|
||||||
|
v-list-tile
|
||||||
|
v-list-tile-content.body-2 Save
|
||||||
|
v-list-tile-action #[kbd {{ctrlKey}}] + #[kbd S]
|
||||||
|
v-divider
|
||||||
|
v-list-tile
|
||||||
|
v-list-tile-content.body-2 Undo
|
||||||
|
v-list-tile-action #[kbd {{ctrlKey}}] + #[kbd Z]
|
||||||
|
v-divider
|
||||||
|
v-list-tile
|
||||||
|
v-list-tile-content.body-2 Redo
|
||||||
|
v-list-tile-action #[kbd {{ctrlKey}}] + #[kbd Y]
|
||||||
|
v-divider
|
||||||
|
v-list-tile
|
||||||
|
v-list-tile-content
|
||||||
|
v-list-tile-title.body-2 Distraction Free Mode
|
||||||
|
v-list-tile-sub-title Press <kbd>Esc</kbd> to exit.
|
||||||
|
v-list-tile-action #[kbd F11]
|
||||||
|
|
||||||
|
v-card.radius-7.animated.fadeInUp.wait-p3s.mt-3(light)
|
||||||
|
v-card-text
|
||||||
|
v-toolbar.radius-7(color='teal lighten-5', dense, flat)
|
||||||
|
v-icon.mr-3(color='teal') mouse
|
||||||
|
.body-2.teal--text Multi-Selection
|
||||||
|
v-list.editor-markdown-help-kbd(two-line, dense)
|
||||||
|
v-list-tile
|
||||||
|
v-list-tile-content.body-2 Multiple Cursors
|
||||||
|
v-list-tile-action #[kbd {{ctrlKey}}] + Left Click
|
||||||
|
v-divider
|
||||||
|
v-list-tile
|
||||||
|
v-list-tile-content.body-2 Select Region
|
||||||
|
v-list-tile-action #[kbd {{ctrlKey}}] + #[kbd {{altKey}}] + Left Click
|
||||||
|
v-divider
|
||||||
|
v-list-tile
|
||||||
|
v-list-tile-content.body-2 Deselect
|
||||||
|
v-list-tile-action #[kbd Esc]
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
ctrlKey() { return /Mac/.test(navigator.platform) ? 'Cmd' : 'Ctrl' },
|
||||||
|
altKey() { return /Mac/.test(navigator.platform) ? 'Option' : 'Alt' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang='scss'>
|
||||||
|
.editor-markdown-help {
|
||||||
|
position: fixed;
|
||||||
|
top: 112px;
|
||||||
|
left: 64px;
|
||||||
|
z-index: 10;
|
||||||
|
width: calc(100vw - 64px - 17px);
|
||||||
|
height: calc(100vh - 112px - 24px);
|
||||||
|
background-color: rgba(darken(mc('grey', '900'), 3%), .9) !important;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
&-source {
|
||||||
|
background-color: mc('blue-grey', '900') !important;
|
||||||
|
border-radius: 7px;
|
||||||
|
font-family: 'Roboto Mono', monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #FFF !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-result {
|
||||||
|
background-color: mc('blue-grey', '50') !important;
|
||||||
|
border-radius: 7px;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
code {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: mc('pink', '50');
|
||||||
|
box-shadow: none;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents {
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prismjs {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-kbd {
|
||||||
|
.v-list__tile__action {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
margin: 0 5px;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0.1em 0.5em;
|
||||||
|
margin: 0 0.2em;
|
||||||
|
box-shadow: 0 1px 0px rgba(0, 0, 0, 0.2), 0 0 0 2px #fff inset;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
color: mc('grey', '700');
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-ref {
|
||||||
|
.v-list__tile__action {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -22,14 +22,6 @@
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Source Sans Pro';
|
|
||||||
src: url('/fonts/SourceSansPro-Bold.woff2') format('woff2'),
|
|
||||||
url('/fonts/SourceSansPro-Bold.woff') format('woff');
|
|
||||||
font-weight: bold;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Roboto';
|
font-family: 'Roboto';
|
||||||
src: url('/fonts/Roboto-Regular.woff2') format('woff2'),
|
src: url('/fonts/Roboto-Regular.woff2') format('woff2'),
|
||||||
@ -46,22 +38,6 @@
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Source Sans Pro';
|
|
||||||
src: url('/fonts/SourceSansPro-BoldItalic.woff2') format('woff2'),
|
|
||||||
url('/fonts/SourceSansPro-BoldItalic.woff') format('woff');
|
|
||||||
font-weight: bold;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Source Sans Pro';
|
|
||||||
src: url('/fonts/SourceSansPro-Regular.woff2') format('woff2'),
|
|
||||||
url('/fonts/SourceSansPro-Regular.woff') format('woff');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Roboto';
|
font-family: 'Roboto';
|
||||||
src: url('/fonts/Roboto-Medium.woff2') format('woff2'),
|
src: url('/fonts/Roboto-Medium.woff2') format('woff2'),
|
||||||
@ -71,9 +47,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Sans Pro';
|
font-family: 'Roboto Mono';
|
||||||
src: url('/fonts/SourceSansPro-Italic.woff2') format('woff2'),
|
src: url('/fonts/RobotoMono-Regular.woff2') format('woff2'),
|
||||||
url('/fonts/SourceSansPro-Italic.woff') format('woff');
|
url('/fonts/RobotoMono-Regular.woff') format('woff');
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: italic;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
BIN
client/static/fonts/RobotoMono-Regular.woff
Normal file
BIN
client/static/fonts/RobotoMono-Regular.woff
Normal file
Binary file not shown.
BIN
client/static/fonts/RobotoMono-Regular.woff2
Normal file
BIN
client/static/fonts/RobotoMono-Regular.woff2
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,80 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('Roboto-MediumItalic.woff2') format('woff2'),
|
|
||||||
url('Roboto-MediumItalic.woff') format('woff');
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('Roboto-Italic.woff2') format('woff2'),
|
|
||||||
url('Roboto-Italic.woff') format('woff');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('Roboto-Bold.woff2') format('woff2'),
|
|
||||||
url('Roboto-Bold.woff') format('woff');
|
|
||||||
font-weight: bold;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Source Sans Pro';
|
|
||||||
src: url('SourceSansPro-Bold.woff2') format('woff2'),
|
|
||||||
url('SourceSansPro-Bold.woff') format('woff');
|
|
||||||
font-weight: bold;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('Roboto-Regular.woff2') format('woff2'),
|
|
||||||
url('Roboto-Regular.woff') format('woff');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('Roboto-BoldItalic.woff2') format('woff2'),
|
|
||||||
url('Roboto-BoldItalic.woff') format('woff');
|
|
||||||
font-weight: bold;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Source Sans Pro';
|
|
||||||
src: url('SourceSansPro-BoldItalic.woff2') format('woff2'),
|
|
||||||
url('SourceSansPro-BoldItalic.woff') format('woff');
|
|
||||||
font-weight: bold;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Source Sans Pro';
|
|
||||||
src: url('SourceSansPro-Regular.woff2') format('woff2'),
|
|
||||||
url('SourceSansPro-Regular.woff') format('woff');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Roboto';
|
|
||||||
src: url('Roboto-Medium.woff2') format('woff2'),
|
|
||||||
url('Roboto-Medium.woff') format('woff');
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Source Sans Pro';
|
|
||||||
src: url('SourceSansPro-Italic.woff2') format('woff2'),
|
|
||||||
url('SourceSansPro-Italic.woff') format('woff');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
@ -256,7 +256,7 @@
|
|||||||
background-color: mc('indigo', '50');
|
background-color: mc('indigo', '50');
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
color: mc('indigo', '800');
|
color: mc('indigo', '800');
|
||||||
font-family: 'Source Code Pro', monospace;
|
font-family: 'Roboto Mono', monospace;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
@ -281,7 +281,7 @@
|
|||||||
box-shadow: initial;
|
box-shadow: initial;
|
||||||
display: block;
|
display: block;
|
||||||
font-size: .85rem;
|
font-size: .85rem;
|
||||||
font-family: 'Source Code Pro', monospace;
|
font-family: 'Roboto Mono', monospace;
|
||||||
|
|
||||||
&:after, &:before {
|
&:after, &:before {
|
||||||
content: initial;
|
content: initial;
|
||||||
|
Loading…
Reference in New Issue
Block a user