diff --git a/src/editor/core/command/CommandAdapt.ts b/src/editor/core/command/CommandAdapt.ts index 4756a58..bd4bc49 100644 --- a/src/editor/core/command/CommandAdapt.ts +++ b/src/editor/core/command/CommandAdapt.ts @@ -270,14 +270,14 @@ export class CommandAdapt { public applyPainterStyle() { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return this.canvasEvent.applyPainterStyle() } public format() { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getSelectionElementList() // 选区设置或设置换行处样式 @@ -310,7 +310,7 @@ export class CommandAdapt { public font(payload: string) { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getSelectionElementList() if (selection?.length) { @@ -333,7 +333,7 @@ export class CommandAdapt { const { minSize, maxSize, defaultSize } = this.options if (payload < minSize || payload > maxSize) return const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return // 选区设置或设置换行处样式 let renderOption: IDrawOption = {} @@ -370,7 +370,7 @@ export class CommandAdapt { public sizeAdd() { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getTextLikeSelectionElementList() // 选区设置或设置换行处样式 @@ -410,7 +410,7 @@ export class CommandAdapt { public sizeMinus() { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getTextLikeSelectionElementList() // 选区设置或设置换行处样式 @@ -450,7 +450,7 @@ export class CommandAdapt { public bold() { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getSelectionElementList() if (selection?.length) { @@ -472,7 +472,7 @@ export class CommandAdapt { public italic() { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getSelectionElementList() if (selection?.length) { @@ -494,7 +494,7 @@ export class CommandAdapt { public underline(textDecoration?: ITextDecoration) { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getSelectionElementList() if (selection?.length) { @@ -533,7 +533,7 @@ export class CommandAdapt { public strikeout() { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getSelectionElementList() if (selection?.length) { @@ -558,7 +558,7 @@ export class CommandAdapt { public superscript() { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getSelectionElementList() if (!selection) return @@ -588,7 +588,7 @@ export class CommandAdapt { public subscript() { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getSelectionElementList() if (!selection) return @@ -618,7 +618,7 @@ export class CommandAdapt { public color(payload: string | null) { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getSelectionElementList() if (selection?.length) { @@ -650,7 +650,7 @@ export class CommandAdapt { public highlight(payload: string | null) { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const selection = this.range.getSelectionElementList() if (selection?.length) { @@ -1782,7 +1782,7 @@ export class CommandAdapt { public image(payload: IDrawImagePayload) { const isDisabled = - this.draw.isReadonly() || this.control.isDisabledControl() + this.draw.isReadonly() || this.control.getIsDisabledControl() if (isDisabled) return const { startIndex, endIndex } = this.range.getRange() if (!~startIndex && !~endIndex) return diff --git a/src/editor/core/draw/Draw.ts b/src/editor/core/draw/Draw.ts index 613f447..409f34e 100644 --- a/src/editor/core/draw/Draw.ts +++ b/src/editor/core/draw/Draw.ts @@ -290,7 +290,7 @@ export class Draw { case EditorMode.PRINT: return true case EditorMode.FORM: - return !this.control.isRangeWithinControl() + return !this.control.getIsRangeWithinControl() default: return false } @@ -551,9 +551,7 @@ export class Draw { } public insertElementList(payload: IElement[]) { - if (!payload.length) return - const isRangeCanInput = this.control.isRangeCanInput() - if (!isRangeCanInput) return + if (!payload.length || !this.range.getIsCanInput()) return const { startIndex, endIndex } = this.range.getRange() if (!~startIndex && !~endIndex) return formatElementList(payload, { @@ -564,11 +562,11 @@ export class Draw { // 判断是否在控件内 let activeControl = this.control.getActiveControl() // 光标在控件内如果当前没有被激活,需要手动激活 - if (!activeControl && this.control.isRangeWithinControl()) { + if (!activeControl && this.control.getIsRangeWithinControl()) { this.control.initControl() activeControl = this.control.getActiveControl() } - if (activeControl && !this.control.isRangInPostfix()) { + if (activeControl && this.control.getIsRangeWithinControl()) { curIndex = activeControl.setValue(payload, undefined, { isIgnoreDisabledRule: true }) diff --git a/src/editor/core/draw/control/Control.ts b/src/editor/core/draw/control/Control.ts index acec9f6..56f8134 100644 --- a/src/editor/core/draw/control/Control.ts +++ b/src/editor/core/draw/control/Control.ts @@ -116,16 +116,26 @@ export class Control { }) } - // 判断选区部分在控件边界外 - public isPartRangeInControlOutside(): boolean { + // 是否属于控件可以捕获事件的选区 + public getIsRangeCanCaptureEvent(): boolean { + if (!this.activeControl) return false const { startIndex, endIndex } = this.getRange() if (!~startIndex && !~endIndex) return false const elementList = this.getElementList() const startElement = elementList[startIndex] + // 闭合光标在后缀处 + if ( + startIndex === endIndex && + startElement.controlComponent === ControlComponent.POSTFIX + ) { + return true + } + // 在控件内 const endElement = elementList[endIndex] if ( startElement.controlId && - startElement.controlId !== endElement.controlId + startElement.controlId === endElement.controlId && + endElement.controlComponent !== ControlComponent.POSTFIX ) { return true } @@ -133,7 +143,7 @@ export class Control { } // 判断选区是否在后缀处 - public isRangInPostfix(): boolean { + public getIsRangeInPostfix(): boolean { if (!this.activeControl) return false const { startIndex, endIndex } = this.getRange() if (startIndex !== endIndex) return false @@ -143,7 +153,7 @@ export class Control { } // 判断选区是否在控件内 - public isRangeWithinControl(): boolean { + public getIsRangeWithinControl(): boolean { const { startIndex, endIndex } = this.getRange() if (!~startIndex && !~endIndex) return false const elementList = this.getElementList() @@ -159,27 +169,7 @@ export class Control { return false } - // 判断是否在控件可输入的地方 - public isRangeCanInput(): boolean { - const { startIndex, endIndex } = this.getRange() - if (!~startIndex && !~endIndex) return false - if (startIndex === endIndex) return true - const elementList = this.getElementList() - const startElement = elementList[startIndex] - const endElement = elementList[endIndex] - // 选区前后不是控件 || 选区前不在控件内&&选区后是后缀 || 选区前是控件&&选区后在控件内 - return ( - (!startElement.controlId && !endElement.controlId) || - ((!startElement.controlId || - startElement.controlComponent === ControlComponent.POSTFIX) && - endElement.controlComponent === ControlComponent.POSTFIX) || - (!!startElement.controlId && - endElement.controlId === startElement.controlId && - endElement.controlComponent !== ControlComponent.POSTFIX) - ) - } - - public isDisabledControl(): boolean { + public getIsDisabledControl(): boolean { return !!this.activeControl?.getElement().control?.disabled } diff --git a/src/editor/core/draw/control/checkbox/CheckboxControl.ts b/src/editor/core/draw/control/checkbox/CheckboxControl.ts index d1d55d2..a6a245f 100644 --- a/src/editor/core/draw/control/checkbox/CheckboxControl.ts +++ b/src/editor/core/draw/control/checkbox/CheckboxControl.ts @@ -73,7 +73,7 @@ export class CheckboxControl implements IControlInstance { options: IControlRuleOption = {} ) { // 校验是否可以设置 - if (!options.isIgnoreDisabledRule && this.control.isDisabledControl()) { + if (!options.isIgnoreDisabledRule && this.control.getIsDisabledControl()) { return } const { control } = this.element @@ -117,7 +117,7 @@ export class CheckboxControl implements IControlInstance { } public keydown(evt: KeyboardEvent): number | null { - if (this.control.isDisabledControl()) { + if (this.control.getIsDisabledControl()) { return null } const range = this.control.getRange() diff --git a/src/editor/core/draw/control/select/SelectControl.ts b/src/editor/core/draw/control/select/SelectControl.ts index 3751a97..c53aa72 100644 --- a/src/editor/core/draw/control/select/SelectControl.ts +++ b/src/editor/core/draw/control/select/SelectControl.ts @@ -81,7 +81,7 @@ export class SelectControl implements IControlInstance { } public keydown(evt: KeyboardEvent): number | null { - if (this.control.isDisabledControl()) { + if (this.control.getIsDisabledControl()) { return null } const elementList = this.control.getElementList() @@ -134,7 +134,7 @@ export class SelectControl implements IControlInstance { } public cut(): number { - if (this.control.isDisabledControl()) { + if (this.control.getIsDisabledControl()) { return -1 } this.control.shrinkBoundary() @@ -151,7 +151,7 @@ export class SelectControl implements IControlInstance { options: IControlRuleOption = {} ): number { // 校验是否可以设置 - if (!options.isIgnoreDisabledRule && this.control.isDisabledControl()) { + if (!options.isIgnoreDisabledRule && this.control.getIsDisabledControl()) { return -1 } const elementList = context.elementList || this.control.getElementList() @@ -201,7 +201,7 @@ export class SelectControl implements IControlInstance { options: IControlRuleOption = {} ) { // 校验是否可以设置 - if (!options.isIgnoreDisabledRule && this.control.isDisabledControl()) { + if (!options.isIgnoreDisabledRule && this.control.getIsDisabledControl()) { return } const control = this.element.control! @@ -291,7 +291,7 @@ export class SelectControl implements IControlInstance { } public awake() { - if (this.isPopup || this.control.isDisabledControl()) return + if (this.isPopup || this.control.getIsDisabledControl()) return const { startIndex } = this.control.getRange() const elementList = this.control.getElementList() if (elementList[startIndex + 1]?.controlId !== this.element.controlId) { diff --git a/src/editor/core/draw/control/text/TextControl.ts b/src/editor/core/draw/control/text/TextControl.ts index d75bf73..1ac4231 100644 --- a/src/editor/core/draw/control/text/TextControl.ts +++ b/src/editor/core/draw/control/text/TextControl.ts @@ -68,7 +68,7 @@ export class TextControl implements IControlInstance { options: IControlRuleOption = {} ): number { // 校验是否可以设置 - if (!options.isIgnoreDisabledRule && this.control.isDisabledControl()) { + if (!options.isIgnoreDisabledRule && this.control.getIsDisabledControl()) { return -1 } const elementList = context.elementList || this.control.getElementList() @@ -111,7 +111,7 @@ export class TextControl implements IControlInstance { options: IControlRuleOption = {} ): number { // 校验是否可以设置 - if (!options.isIgnoreDisabledRule && this.control.isDisabledControl()) { + if (!options.isIgnoreDisabledRule && this.control.getIsDisabledControl()) { return -1 } const elementList = context.elementList || this.control.getElementList() @@ -128,7 +128,7 @@ export class TextControl implements IControlInstance { } public keydown(evt: KeyboardEvent): number | null { - if (this.control.isDisabledControl()) { + if (this.control.getIsDisabledControl()) { return null } const elementList = this.control.getElementList() @@ -209,7 +209,7 @@ export class TextControl implements IControlInstance { } public cut(): number { - if (this.control.isDisabledControl()) { + if (this.control.getIsDisabledControl()) { return -1 } this.control.shrinkBoundary() diff --git a/src/editor/core/event/handlers/cut.ts b/src/editor/core/event/handlers/cut.ts index 7196c6b..41b737c 100644 --- a/src/editor/core/event/handlers/cut.ts +++ b/src/editor/core/event/handlers/cut.ts @@ -6,12 +6,8 @@ export function cut(host: CanvasEvent) { const rangeManager = draw.getRange() const { startIndex, endIndex } = rangeManager.getRange() if (!~startIndex && !~startIndex) return - const isReadonly = draw.isReadonly() - if (isReadonly) return - const control = draw.getControl() - const isPartRangeInControlOutside = control.isPartRangeInControlOutside() - if (isPartRangeInControlOutside) return - const activeControl = control.getActiveControl() + if (draw.isReadonly() || !rangeManager.getIsCanInput()) return + const elementList = draw.getElementList() let start = startIndex let end = endIndex @@ -37,8 +33,9 @@ export function cut(host: CanvasEvent) { const options = draw.getOptions() // 写入粘贴板 writeElementList(elementList.slice(start + 1, end + 1), options) + const control = draw.getControl() let curIndex: number - if (activeControl) { + if (control.getActiveControl() && control.getIsRangeWithinControl()) { curIndex = control.cut() } else { draw.spliceElementList(elementList, start + 1, end - start) diff --git a/src/editor/core/event/handlers/input.ts b/src/editor/core/event/handlers/input.ts index 27ce6f1..c2abcdf 100644 --- a/src/editor/core/event/handlers/input.ts +++ b/src/editor/core/event/handlers/input.ts @@ -8,19 +8,15 @@ import { CanvasEvent } from '../CanvasEvent' export function input(data: string, host: CanvasEvent) { const draw = host.getDraw() - const isReadonly = draw.isReadonly() - if (isReadonly) return + if (draw.isReadonly()) return const position = draw.getPosition() const cursorPosition = position.getCursorPosition() if (!data || !cursorPosition) return const isComposing = host.isComposing // 正在合成文本进行非输入操作 if (isComposing && host.compositionInfo?.value === data) return - const control = draw.getControl() - if (control.isPartRangeInControlOutside()) { - // 忽略选区部分在控件的输入 - return - } + const rangeManager = draw.getRange() + if (!rangeManager.getIsCanInput()) return // 移除合成输入 removeComposingInput(host) if (!isComposing) { @@ -29,7 +25,6 @@ export function input(data: string, host: CanvasEvent) { } const { TEXT, HYPERLINK, SUBSCRIPT, SUPERSCRIPT, DATE } = ElementType const text = data.replaceAll(`\n`, ZERO) - const rangeManager = draw.getRange() const { startIndex, endIndex } = rangeManager.getRange() // 格式化元素 const elementList = draw.getElementList() @@ -63,8 +58,9 @@ export function input(data: string, host: CanvasEvent) { return newElement }) // 控件-移除placeholder + const control = draw.getControl() let curIndex: number - if (control.getActiveControl() && !control.isRangInPostfix()) { + if (control.getActiveControl() && control.getIsRangeWithinControl()) { curIndex = control.setValue(inputData) } else { const start = startIndex + 1 diff --git a/src/editor/core/event/handlers/keydown/backspace.ts b/src/editor/core/event/handlers/keydown/backspace.ts index 044ac15..39058ac 100644 --- a/src/editor/core/event/handlers/keydown/backspace.ts +++ b/src/editor/core/event/handlers/keydown/backspace.ts @@ -3,15 +3,13 @@ import { CanvasEvent } from '../../CanvasEvent' export function backspace(evt: KeyboardEvent, host: CanvasEvent) { const draw = host.getDraw() - const isReadonly = draw.isReadonly() - if (isReadonly) return - // 控件整体性验证 - const control = draw.getControl() - const activeControl = control.getActiveControl() - if (control.isPartRangeInControlOutside()) return + if (draw.isReadonly()) return + // 可输入性验证 const rangeManager = draw.getRange() + if (!rangeManager.getIsCanInput()) return + const control = draw.getControl() let curIndex: number | null - if (activeControl) { + if (control.getActiveControl() && control.getIsRangeCanCaptureEvent()) { // 光标在控件内 curIndex = control.keydown(evt) } else { diff --git a/src/editor/core/event/handlers/keydown/delete.ts b/src/editor/core/event/handlers/keydown/delete.ts index b831b51..34b4cf1 100644 --- a/src/editor/core/event/handlers/keydown/delete.ts +++ b/src/editor/core/event/handlers/keydown/delete.ts @@ -2,17 +2,15 @@ import { CanvasEvent } from '../../CanvasEvent' export function del(evt: KeyboardEvent, host: CanvasEvent) { const draw = host.getDraw() - const isReadonly = draw.isReadonly() - if (isReadonly) return - // 控件整体性验证 - const control = draw.getControl() - const activeControl = control.getActiveControl() - if (control.isPartRangeInControlOutside()) return + if (draw.isReadonly()) return + // 可输入性验证 const rangeManager = draw.getRange() + if (!rangeManager.getIsCanInput()) return const { startIndex, endIndex } = rangeManager.getRange() const elementList = draw.getElementList() + const control = draw.getControl() let curIndex: number | null - if (activeControl) { + if (control.getActiveControl() && control.getIsRangeWithinControl()) { // 光标在控件内 curIndex = control.keydown(evt) } else if (elementList[endIndex + 1]?.controlId) { diff --git a/src/editor/core/event/handlers/keydown/enter.ts b/src/editor/core/event/handlers/keydown/enter.ts index 657f053..8780b6e 100644 --- a/src/editor/core/event/handlers/keydown/enter.ts +++ b/src/editor/core/event/handlers/keydown/enter.ts @@ -12,10 +12,9 @@ import { CanvasEvent } from '../../CanvasEvent' export function enter(evt: KeyboardEvent, host: CanvasEvent) { const draw = host.getDraw() - const isReadonly = draw.isReadonly() - const control = draw.getControl() - if (isReadonly || control.isPartRangeInControlOutside()) return + if (draw.isReadonly()) return const rangeManager = draw.getRange() + if (!rangeManager.getIsCanInput()) return const { startIndex, endIndex } = rangeManager.getRange() const isCollapsed = rangeManager.getIsCollapsed() const elementList = draw.getElementList() @@ -59,9 +58,10 @@ export function enter(evt: KeyboardEvent, host: CanvasEvent) { }) } // 控件或文档插入换行元素 + const control = draw.getControl() const activeControl = control.getActiveControl() let curIndex: number - if (activeControl && !control.isRangInPostfix()) { + if (activeControl && control.getIsRangeWithinControl()) { curIndex = control.setValue([enterText]) } else { const position = draw.getPosition() diff --git a/src/editor/core/range/RangeManager.ts b/src/editor/core/range/RangeManager.ts index 3ff6b4f..b0b0686 100644 --- a/src/editor/core/range/RangeManager.ts +++ b/src/editor/core/range/RangeManager.ts @@ -292,6 +292,26 @@ export class RangeManager { return rangeList } + public getIsCanInput(): boolean { + const { startIndex, endIndex } = this.getRange() + if (!~startIndex && !~endIndex) return false + if (startIndex === endIndex) return true + const elementList = this.draw.getElementList() + const startElement = elementList[startIndex] + const endElement = elementList[endIndex] + // 选区前后不是控件 || 选区前不是控件或是后缀&&选区后不是控件或是后缀 || 选区在控件内 + return ( + (!startElement.controlId && !endElement.controlId) || + ((!startElement.controlId || + startElement.controlComponent === ControlComponent.POSTFIX) && + (!endElement.controlId || + endElement.controlComponent === ControlComponent.POSTFIX)) || + (!!startElement.controlId && + endElement.controlId === startElement.controlId && + endElement.controlComponent !== ControlComponent.POSTFIX) + ) + } + public setRange( startIndex: number, endIndex: number,