feat:text control delete

pr675
Hufe921 4 years ago
parent 3602093d59
commit 6243a8e4ca

@ -1,6 +1,7 @@
import { ControlComponent, ControlType } from '../../../dataset/enum/Control'
import { ElementType } from '../../../dataset/enum/Element'
import { IControlInitOption, IControlInitResult, IControlInstance } from '../../../interface/Control'
import { IEditorOption } from '../../../interface/Editor'
import { IElement } from '../../../interface/Element'
import { RangeManager } from '../../range/RangeManager'
import { Draw } from '../Draw'
@ -14,14 +15,20 @@ export class Control {
private draw: Draw
private range: RangeManager
private options: Required<IEditorOption>
private activeControl: IControlInstance | null
constructor(draw: Draw) {
this.draw = draw
this.range = draw.getRange()
this.options = draw.getOptions()
this.activeControl = null
}
public getOptions(): Required<IEditorOption> {
return this.options
}
public getElementList(): IElement[] {
return this.draw.getElementList()
}
@ -146,4 +153,11 @@ export class Control {
return this.activeControl.setValue(data)
}
public keydown(evt: KeyboardEvent): number {
if (!this.activeControl) {
throw new Error('active control is null')
}
return this.activeControl.keydown(evt)
}
}

@ -1,5 +1,7 @@
import { ControlComponent } from '../../../../dataset/enum/Control'
import { IControlInstance } from '../../../../interface/Control'
import { ElementType } from '../../../../dataset/enum/Element'
import { KeyMap } from '../../../../dataset/enum/Keymap'
import { IControlInstance, IControlOption } from '../../../../interface/Control'
import { IElement } from '../../../../interface/Element'
import { IRange } from '../../../../interface/Range'
import { Control } from '../Control'
@ -7,9 +9,11 @@ import { Control } from '../Control'
export class TextControl implements IControlInstance {
private control: Control
private options: IControlOption
constructor(control: Control) {
this.control = control
this.options = control.getOptions().control
}
public shrinkBoundary(elementList: IElement[], range: IRange) {
@ -97,6 +101,94 @@ export class TextControl implements IControlInstance {
}
}
public removeControl(elementList: IElement[], range: IRange): number {
const { startIndex } = range
const startElement = elementList[startIndex]
let leftIndex = -1
let rightIndex = -1
// 向左查找
let preIndex = startIndex
while (preIndex > 0) {
const preElement = elementList[preIndex]
if (preElement.controlId !== startElement.controlId) {
leftIndex = preIndex
break
}
preIndex--
}
// 向右查找
let nextIndex = startIndex + 1
while (nextIndex < elementList.length) {
const nextElement = elementList[nextIndex]
if (nextElement.controlId !== startElement.controlId) {
rightIndex = nextIndex - 1
break
}
nextIndex++
}
if (!~leftIndex || !~rightIndex) return -1
// 删除元素
elementList.splice(leftIndex + 1, rightIndex - leftIndex)
// 清除实例
this.control.destroyControl()
return leftIndex
}
public addPlaceholder(elementList: IElement[], startIndex: number) {
const startElement = elementList[startIndex]
const control = startElement.control!
const placeholderStrList = control.placeholder.split('')
for (let p = 0; p < placeholderStrList.length; p++) {
const value = placeholderStrList[p]
elementList.splice(startIndex + p + 1, 0, {
value,
controlId: startElement.controlId,
type: ElementType.CONTROL,
control: startElement.control,
controlComponent: ControlComponent.PLACEHOLDER,
color: this.options.placeholderColor
})
}
}
public getValue(): IElement[] {
const elementList = this.control.getElementList()
const { startIndex } = this.control.getRange()
const startElement = elementList[startIndex]
const data: IElement[] = []
// 向左查找
let preIndex = startIndex
while (preIndex > 0) {
const preElement = elementList[preIndex]
if (
preElement.controlId !== startElement.controlId ||
preElement.controlComponent === ControlComponent.PREFIX
) {
break
}
if (preElement.controlComponent === ControlComponent.VALUE) {
data.unshift(preElement)
}
preIndex--
}
// 向右查找
let nextIndex = startIndex + 1
while (nextIndex < elementList.length) {
const nextElement = elementList[nextIndex]
if (
nextElement.controlId !== startElement.controlId ||
nextElement.controlComponent === ControlComponent.POSTFIX
) {
break
}
if (nextElement.controlComponent === ControlComponent.VALUE) {
data.push(nextElement)
}
nextIndex++
}
return data
}
public setValue(data: IElement[]): number {
const elementList = this.control.getElementList()
const range = this.control.getRange()
@ -123,4 +215,67 @@ export class TextControl implements IControlInstance {
return start + data.length - 1
}
public keydown(evt: KeyboardEvent): number {
const elementList = this.control.getElementList()
const range = this.control.getRange()
// 收缩边界到Value内
this.shrinkBoundary(elementList, range)
const { startIndex, endIndex } = range
const startElement = elementList[startIndex]
const endElement = elementList[endIndex]
// backspace
if (evt.key === KeyMap.Backspace) {
// 移除选区元素
if (startIndex !== endIndex) {
elementList.splice(startIndex + 1, endIndex - startIndex)
const value = this.getValue()
if (!value.length) {
this.addPlaceholder(elementList, startIndex)
}
return startIndex
} else {
if (startElement.controlComponent === ControlComponent.PREFIX) {
// 前缀
return this.removeControl(elementList, range)
} else if (endElement.controlComponent === ControlComponent.POSTFIX) {
// 后缀
return this.removeControl(elementList, range)
} else {
// 文本
elementList.splice(startIndex, 1)
const value = this.getValue()
if (!value.length) {
this.addPlaceholder(elementList, startIndex - 1)
}
return startIndex - 1
}
}
} else if (evt.key === KeyMap.Delete) {
// 移除选区元素
if (startIndex !== endIndex) {
elementList.splice(startIndex + 1, endIndex - startIndex)
const value = this.getValue()
if (!value.length) {
this.addPlaceholder(elementList, startIndex)
}
return startIndex
} else {
const endNextElement = elementList[endIndex + 1]
if (endNextElement.controlComponent === ControlComponent.POSTFIX) {
// 后缀
return this.removeControl(elementList, range)
} else {
// 文本
elementList.splice(startIndex + 1, 1)
const value = this.getValue()
if (!value.length) {
this.addPlaceholder(elementList, startIndex)
}
return startIndex
}
}
}
return -1
}
}

@ -187,6 +187,8 @@ export class CanvasEvent {
} else {
positionResult.index = newIndex
}
} else {
this.control.destroyControl()
}
const {
index,
@ -273,8 +275,15 @@ export class CanvasEvent {
const { index } = cursorPosition
const { startIndex, endIndex } = this.range.getRange()
const isCollapsed = startIndex === endIndex
// 当前激活控件
const isPartRangeInControlOutside = this.control.isPartRangeInControlOutside()
const activeControl = this.control.getActiveControl()
if (evt.key === KeyMap.Backspace) {
if (isReadonly) return
if (isReadonly || isPartRangeInControlOutside) return
let curIndex: number
if (activeControl) {
curIndex = this.control.keydown(evt)
} else {
// 判断是否允许删除
if (isCollapsed && elementList[index].value === ZERO && index === 0) {
evt.preventDefault()
@ -285,17 +294,23 @@ export class CanvasEvent {
} else {
elementList.splice(index, 1)
}
const curIndex = isCollapsed ? index - 1 : startIndex
curIndex = isCollapsed ? index - 1 : startIndex
}
this.range.setRange(curIndex, curIndex)
this.draw.render({ curIndex })
} else if (evt.key === KeyMap.Delete) {
if (isReadonly) return
if (isReadonly || isPartRangeInControlOutside) return
let curIndex: number
if (activeControl) {
curIndex = this.control.keydown(evt)
} else {
if (!isCollapsed) {
elementList.splice(startIndex + 1, endIndex - startIndex)
} else {
elementList.splice(index + 1, 1)
}
const curIndex = isCollapsed ? index : startIndex
curIndex = isCollapsed ? index : startIndex
}
this.range.setRange(curIndex, curIndex)
this.draw.render({ curIndex })
} else if (evt.key === KeyMap.Enter) {

@ -2,6 +2,7 @@ import { EDITOR_COMPONENT } from '../../dataset/constant/Editor'
import { IEditorOption } from '../../interface/Editor'
import { findParent } from '../../utils'
import { Cursor } from '../cursor/Cursor'
import { Control } from '../draw/control/Control'
import { Draw } from '../draw/Draw'
import { HyperlinkParticle } from '../draw/particle/HyperlinkParticle'
import { ImageParticle } from '../draw/particle/ImageParticle'
@ -20,6 +21,7 @@ export class GlobalEvent {
private imageParticle: ImageParticle
private tableTool: TableTool
private hyperlinkParticle: HyperlinkParticle
private control: Control
constructor(draw: Draw, canvasEvent: CanvasEvent) {
this.draw = draw
@ -31,6 +33,7 @@ export class GlobalEvent {
this.imageParticle = draw.getImageParticle()
this.tableTool = draw.getTableTool()
this.hyperlinkParticle = draw.getHyperlinkParticle()
this.control = draw.getControl()
}
public register() {
@ -74,6 +77,7 @@ export class GlobalEvent {
this.imageParticle.clearResizer()
this.tableTool.dispose()
this.hyperlinkParticle.clearHyperlinkPopup()
this.control.destroyControl()
}
public setDragState() {

@ -41,5 +41,9 @@ export interface IControlInitResult {
}
export interface IControlInstance {
getValue(): IElement[];
setValue(data: IElement[]): number;
keydown(evt: KeyboardEvent): number;
}
Loading…
Cancel
Save