Created key bindings for `text` mode
This commit is contained in:
parent
e069d3f0b3
commit
1c37b303b9
|
@ -40,7 +40,10 @@ export default class CodeMode extends TextMode {
|
|||
}
|
||||
|
||||
render () {
|
||||
return h('div', {className: 'jsoneditor jsoneditor-mode-code'}, [
|
||||
return h('div', {
|
||||
className: 'jsoneditor jsoneditor-mode-code',
|
||||
onKeyDown: this.handleKeyDown
|
||||
}, [
|
||||
this.renderMenu(),
|
||||
|
||||
h('div', {key: 'contents', className: 'jsoneditor-contents'}, h(Ace, {
|
||||
|
|
|
@ -6,6 +6,9 @@ import { parseJSON } from '../utils/jsonUtils'
|
|||
import { escapeUnicodeChars } from '../utils/stringUtils'
|
||||
import { enrichSchemaError, limitErrors } from '../utils/schemaUtils'
|
||||
import { jsonToData, dataToJson, patchData } from '../jsonData'
|
||||
import { createFindKeyBinding } from '../utils/keyBindings'
|
||||
import { KEY_BINDINGS } from '../constants'
|
||||
|
||||
import ModeButton from './menu/ModeButton'
|
||||
|
||||
const AJV_OPTIONS = {
|
||||
|
@ -43,9 +46,17 @@ const AJV_OPTIONS = {
|
|||
export default class TextMode extends Component {
|
||||
state: Object
|
||||
|
||||
keyDownActions = {
|
||||
'format': (event) => this.handleCompact(),
|
||||
'compact': (event) => this.handleFormat()
|
||||
}
|
||||
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
// TODO: make key bindings customizable
|
||||
this.findKeyBinding = createFindKeyBinding(KEY_BINDINGS)
|
||||
|
||||
this.state = {
|
||||
text: '{}',
|
||||
compiledSchema: null
|
||||
|
@ -81,7 +92,10 @@ export default class TextMode extends Component {
|
|||
}
|
||||
|
||||
render () {
|
||||
return h('div', {className: 'jsoneditor jsoneditor-mode-text'}, [
|
||||
return h('div', {
|
||||
className: 'jsoneditor jsoneditor-mode-text',
|
||||
onKeyDown: this.handleKeyDown
|
||||
}, [
|
||||
this.renderMenu(),
|
||||
|
||||
h('div', {key: 'contents', className: 'jsoneditor-contents'},
|
||||
|
@ -243,6 +257,16 @@ export default class TextMode extends Component {
|
|||
// do nothing...
|
||||
}
|
||||
|
||||
handleKeyDown = (event) => {
|
||||
const keyBinding = this.findKeyBinding(event)
|
||||
const action = this.keyDownActions[keyBinding]
|
||||
|
||||
if (action) {
|
||||
event.preventDefault()
|
||||
action(event)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle changed text input in the textarea
|
||||
* @param {Event} event
|
||||
|
|
|
@ -26,7 +26,8 @@ import {
|
|||
moveUp, moveDown, moveLeft, moveRight, moveDownSibling, moveHome, moveEnd,
|
||||
findNode, selectFind, searchHasFocus, setSelection
|
||||
} from './utils/domSelector'
|
||||
import { keyComboFromEvent } from '../utils/keyBindings'
|
||||
import { createFindKeyBinding } from '../utils/keyBindings'
|
||||
import { KEY_BINDINGS } from '../constants'
|
||||
|
||||
import type { JSONData, JSONPatch } from '../types'
|
||||
|
||||
|
@ -40,29 +41,6 @@ const MAX_HISTORY_ITEMS = 1000 // maximum number of undo/redo items to be kept
|
|||
const SEARCH_DEBOUNCE = 300 // milliseconds
|
||||
const SCROLL_DURATION = 400 // milliseconds
|
||||
|
||||
// TODO: make key bindings configurable
|
||||
const KEY_BINDINGS = {
|
||||
'duplicate': ['Ctrl+D', 'Command+D'],
|
||||
'insert': ['Ctrl+Insert', 'Command+Insert'],
|
||||
'remove': ['Ctrl+Delete', 'Command+Delete'],
|
||||
'expand': ['Ctrl+E', 'Command+E'],
|
||||
'actionMenu': ['Ctrl+M', 'Command+M'],
|
||||
'undo': ['Ctrl+Z', 'Command+Z'],
|
||||
'redo': ['Ctrl+Shift+Z', 'Command+Shift+Z'],
|
||||
'find': ['Ctrl+F', 'Command+F'],
|
||||
'findNext': ['F3', 'Ctrl+G', 'Command+G'],
|
||||
'findPrevious': ['Shift+F3', 'Ctrl+Shift+G', 'Command+Shift+G'],
|
||||
'up': ['Alt+Up', 'Option+Up'],
|
||||
'down': ['Alt+Down', 'Option+Down'],
|
||||
'left': ['Alt+Left', 'Option+Left'],
|
||||
'right': ['Alt+Right', 'Option+Right'],
|
||||
'home': ['Alt+Home', 'Option+Home'],
|
||||
'end': ['Alt+End', 'Option+End'],
|
||||
'openUrl': ['Ctrl+Enter', 'Command+Enter']
|
||||
// TODO: implement Ctrl+Shift+Arrow Up/Down Select multiple fields
|
||||
// TODO: implement Shift+Alt+Arrows Move current field or selected fields up/down/left/right
|
||||
}
|
||||
|
||||
export default class TreeMode extends Component {
|
||||
id: number
|
||||
state: Object
|
||||
|
@ -88,6 +66,9 @@ export default class TreeMode extends Component {
|
|||
|
||||
this.id = Math.round(Math.random() * 1e5) // TODO: create a uuid here?
|
||||
|
||||
// TODO: make key bindings customizable
|
||||
this.findKeyBinding = createFindKeyBinding(KEY_BINDINGS)
|
||||
|
||||
this.state = {
|
||||
data,
|
||||
|
||||
|
@ -113,9 +94,7 @@ export default class TreeMode extends Component {
|
|||
search: {
|
||||
text: '',
|
||||
active: null // active search result
|
||||
},
|
||||
|
||||
keyCombos: this.bindingsByCombos (KEY_BINDINGS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,7 +160,7 @@ export default class TreeMode extends Component {
|
|||
|
||||
return h('div', {
|
||||
className: `jsoneditor jsoneditor-mode-${props.mode}`,
|
||||
'onKeyDown': this.handleKeyDown,
|
||||
onKeyDown: this.handleKeyDown,
|
||||
'data-jsoneditor': 'true'
|
||||
}, [
|
||||
this.renderMenu(searchResults),
|
||||
|
@ -276,27 +255,6 @@ export default class TreeMode extends Component {
|
|||
return h('div', {key: 'menu', className: 'jsoneditor-menu'}, items)
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn a map with key bindings by name into a map by combo
|
||||
* @param {Object.<String, Array.string>} keyBindings
|
||||
* @return {Object.<String, string>} Returns keyCombos
|
||||
*/
|
||||
bindingsByCombos (keyBindings) {
|
||||
const keyCombos = {}
|
||||
|
||||
Object.keys(keyBindings).forEach ((name) => {
|
||||
keyBindings[name].forEach(combo => keyCombos[combo.toUpperCase()] = name)
|
||||
})
|
||||
|
||||
return keyCombos
|
||||
}
|
||||
|
||||
findKeyBinding = (event) => {
|
||||
const keyCombo = keyComboFromEvent(event)
|
||||
|
||||
return this.state.keyCombos[keyCombo.toUpperCase()] || null
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the JSON against the configured JSON schema
|
||||
* Returns an array with the errors when not valid, returns an empty array
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
export const KEY_BINDINGS = {
|
||||
// tree mode
|
||||
'duplicate': ['Ctrl+D', 'Command+D'],
|
||||
'insert': ['Ctrl+Insert', 'Command+Insert'],
|
||||
'remove': ['Ctrl+Delete', 'Command+Delete'],
|
||||
'expand': ['Ctrl+E', 'Command+E'],
|
||||
'actionMenu': ['Ctrl+M', 'Command+M'],
|
||||
'undo': ['Ctrl+Z', 'Command+Z'],
|
||||
'redo': ['Ctrl+Shift+Z', 'Command+Shift+Z'],
|
||||
'find': ['Ctrl+F', 'Command+F'],
|
||||
'findNext': ['F3', 'Ctrl+G', 'Command+G'],
|
||||
'findPrevious': ['Shift+F3', 'Ctrl+Shift+G', 'Command+Shift+G'],
|
||||
'up': ['Alt+Up', 'Option+Up'],
|
||||
'down': ['Alt+Down', 'Option+Down'],
|
||||
'left': ['Alt+Left', 'Option+Left'],
|
||||
'right': ['Alt+Right', 'Option+Right'],
|
||||
'home': ['Alt+Home', 'Option+Home'],
|
||||
'end': ['Alt+End', 'Option+End'],
|
||||
'openUrl': ['Ctrl+Enter', 'Command+Enter'],
|
||||
// TODO: implement Ctrl+Shift+Arrow Up/Down Select multiple fields
|
||||
// TODO: implement Shift+Alt+Arrows Move current field or selected fields up/down/left/right
|
||||
|
||||
// text and code mode
|
||||
'compact': ['Ctrl+\\', 'Command+\\'],
|
||||
'format': ['Ctrl+Shift+\\', 'Command+Shift+\\'],
|
||||
}
|
|
@ -34,6 +34,27 @@ export function keyComboFromEvent (event) {
|
|||
return combi.join('+')
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a function which can quickly find a keyBinding from a set of
|
||||
* keyBindings.
|
||||
* @param {Object.<String, String[]>} keyBindings
|
||||
* @return {function} Returns a findKeyBinding function
|
||||
*/
|
||||
export function createFindKeyBinding (keyBindings) {
|
||||
// turn the map with key bindings by name (multiple per binding) into a map by key combo
|
||||
const keyCombos = {}
|
||||
Object.keys(keyBindings).forEach ((name) => {
|
||||
keyBindings[name].forEach(combo => keyCombos[combo.toUpperCase()] = name)
|
||||
})
|
||||
|
||||
return function findKeyBinding (event){
|
||||
const keyCombo = keyComboFromEvent(event)
|
||||
|
||||
return keyCombos[keyCombo.toUpperCase()] || null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0
|
||||
|
||||
const metaCodes = {
|
||||
|
|
Loading…
Reference in New Issue