implements basic menu functionalities

this includes standard block elements (headers, paragraphs, lists, rulers)
but not marks (bold, italic)
and for sure not special elements like the stat block
own-rich-text-solution
koehr 5 years ago
parent 42dfa704d7
commit 5986e599fd

@ -17,7 +17,7 @@
<script lang="ts"> <script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator' import { Component, Prop, Vue } from 'vue-property-decorator'
import { blocks, State } from '@/editor.ts' import { blocks, State } from '@/editor'
@Component @Component
export default class DeckCardEditorMenu extends Vue { export default class DeckCardEditorMenu extends Vue {
@ -50,7 +50,7 @@ export default class DeckCardEditorMenu extends Vue {
padding: .2rem 1rem; padding: .2rem 1rem;
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
transition: opacity 0.2s, visibility 0.2s; transition: opacity .3s .2s, visibility .3s .2s;
background-color: var(--highlight-color); background-color: var(--highlight-color);
z-index: 2; z-index: 2;
} }

@ -7,7 +7,7 @@
/> />
<div <div
:ref="content" ref="content"
class="card-content" class="card-content"
:contenteditable="active" :contenteditable="active"
@focus="start" @focus="start"
@ -30,13 +30,14 @@ import { Component, Prop, Vue } from 'vue-property-decorator'
import DeckCardEditorMenu from '@/components/deck-card-editor-menu.vue' import DeckCardEditorMenu from '@/components/deck-card-editor-menu.vue'
import { import {
elementNameToMenuState, elementNameToMenuState,
menuActionToCommand,
getElementAndParentName, getElementAndParentName,
marks, marks,
blocks, blocks,
State, State,
movementKeys, movementKeys,
controlSequenceKeys controlSequenceKeys
} from '@/editor.ts' } from '@/editor'
@Component({ @Component({
components: { DeckCardEditorMenu } components: { DeckCardEditorMenu }
@ -91,7 +92,13 @@ export default class DeckCardEditor extends Vue {
private editorAction (action: string) { private editorAction (action: string) {
console.log('action', action) console.log('action', action)
// const content = this.$refs.content const content = this.$refs.content as HTMLElement
content.focus()
const cmd = menuActionToCommand[action]
cmd()
this.$nextTick(() => this.syncMenuState())
} }
private syncMenuState () { private syncMenuState () {
@ -121,6 +128,8 @@ export default class DeckCardEditor extends Vue {
private start () { private start () {
this.contentInFocus = true this.contentInFocus = true
this.syncMenuState() this.syncMenuState()
// insert paragraphs instead of DIVs on enter
document.execCommand('defaultParagraphSeparator', false, 'p')
} }
private stop () { private stop () {
@ -129,7 +138,7 @@ export default class DeckCardEditor extends Vue {
} }
</script> </script>
<style scoped> <style>
.card-content p { .card-content p {
margin: 0; margin: 0;
line-height: 1.2; line-height: 1.2;

@ -1,5 +1,3 @@
export type State = KV<boolean>
export const movementKeys = [ export const movementKeys = [
'ArrowLeft', 'ArrowLeft',
'ArrowRight', 'ArrowRight',
@ -37,11 +35,3 @@ export const blocks = [
'separator', 'separator',
'statBlock' 'statBlock'
] ]
export function getElementAndParentName (el: Node) {
const element = el.nodeName === '#text' ? el.parentElement : el
return [
element?.nodeName,
element?.parentElement?.nodeName
]
}

@ -0,0 +1,40 @@
export type State = KV<boolean>
export {
movementKeys,
controlSequenceKeys,
elementNameToMenuState,
marks,
blocks
} from './constants'
function simpleAction (cmd: string, arg?: string): () => boolean {
return () => {
return document.execCommand(cmd, false, arg)
}
}
function insertHorizontalRule (): () => boolean {
return () => {
const hr = document.execCommand('insertHorizontalRule')
const p = document.execCommand('formatblock', false, 'P')
return hr && p
}
}
export const menuActionToCommand: KV<() => boolean> = {
paragraph: simpleAction('formatblock', 'P'),
heading1: simpleAction('formatblock', 'H1'),
heading2: simpleAction('formatblock', 'H2'),
heading3: simpleAction('formatblock', 'H3'),
bulletList: simpleAction('insertUnorderedList'),
numberedList: simpleAction('insertOrderedList'),
separator: insertHorizontalRule()
}
export function getElementAndParentName (el: Node) {
const element = el.nodeName === '#text' ? el.parentElement : el
return [
element?.nodeName,
element?.parentElement?.nodeName
]
}
Loading…
Cancel
Save