* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import {
getCurrent,
insertNode,
selectNode,
getSchema,
POSITION,
removeNodeById,
allowInsert,
getConfigure,
clearHover,
hoverState
} from './container'
import { useHistory } from '@opentiny/tiny-engine-meta-register'
import { copyObject } from '../../common'
import { getClipboardSchema, setClipboardSchema } from './utils'
const KEY_Y = 89
const KEY_Z = 90
const KEY_RIGHT = 39
const KEY_LEFT = 37
const KEY_UP = 38
const KEY_DOWN = 40
const KEY_DEL = 46
function handlerLeft({ parent }) {
selectNode(parent?.id)
}
function handlerRight({ schema }) {
const id = schema.children?.[0]?.id
id && selectNode(id)
}
function handlerUp({ index, parent }) {
const id = (parent.children[index - 1] || parent)?.id
id && selectNode(id)
}
function handlerDown({ index, parent }) {
const id = parent.children[index + 1]?.id
id && selectNode(id)
}
function handlerDelete({ schema }) {
if (hoverState.id === schema.id) {
clearHover()
}
removeNodeById(schema.id)
}
const handlerArrow = (keyCode) => {
let { schema, parent } = getCurrent()
let index = null
if (schema) {
index = parent.children.indexOf(schema)
} else {
schema = getSchema()
}
let obj = {
[KEY_LEFT]: handlerLeft,
[KEY_RIGHT]: handlerRight,
[KEY_UP]: handlerUp,
[KEY_DOWN]: handlerDown,
[KEY_DEL]: handlerDelete
}
if (obj[keyCode]) {
obj[keyCode]({ index, schema, parent })
}
}
const handlerCtrl = (keyCode) => {
switch (keyCode) {
case KEY_Y:
useHistory().forward()
break
case KEY_Z:
useHistory().back()
break
default:
break
}
}
const handleClipboardCut = (event, schema) => {
if (setClipboardSchema(event, copyObject(schema))) {
removeNodeById(schema?.id)
}
}
const handleClipboardPaste = (node, schema, parent) => {
if (node?.componentName && schema?.componentName && allowInsert(getConfigure(schema.componentName), node)) {
insertNode({ parent, node: schema, data: { ...node } }, POSITION.IN)
}
}
const handlerClipboardEvent = (event) => {
const { schema, parent } = getCurrent()
const node = getClipboardSchema(event)
switch (event.type) {
case 'copy':
setClipboardSchema(event, copyObject(schema))
break
case 'paste':
handleClipboardPaste(node, schema, parent)
break
case 'cut':
handleClipboardCut(event, schema)
break
default:
break
}
}
const keyboardHandler = (event) => {
if (event.ctrlKey) {
getCurrent()?.schema && handlerCtrl(event.keyCode)
}
handlerArrow(event.keyCode)
}
const removeHostkeyEvent = (dom) => {
dom.removeEventListener('keydown', keyboardHandler)
dom.removeEventListener('copy', handlerClipboardEvent)
dom.removeEventListener('cut', handlerClipboardEvent)
dom.removeEventListener('paste', handlerClipboardEvent)
}
const registerHostkeyEvent = (dom) => {
removeHostkeyEvent(dom)
dom.addEventListener('keydown', keyboardHandler)
dom.addEventListener('copy', handlerClipboardEvent)
dom.addEventListener('cut', handlerClipboardEvent)
dom.addEventListener('paste', handlerClipboardEvent)
}
export { registerHostkeyEvent, removeHostkeyEvent }