diff --git a/src/editor/core/command/Command.ts b/src/editor/core/command/Command.ts index 1a48616..dec44f6 100644 --- a/src/editor/core/command/Command.ts +++ b/src/editor/core/command/Command.ts @@ -48,6 +48,8 @@ export class Command { private static cancelMergeTableCell: Function private static image: Function private static hyperlink: Function + private static deleteHyperlink: Function + private static cancelHyperlink: Function private static separator: Function private static pageBreak: Function private static addWatermark: Function @@ -107,6 +109,8 @@ export class Command { Command.cancelMergeTableCell = adapt.cancelMergeTableCell.bind(adapt) Command.image = adapt.image.bind(adapt) Command.hyperlink = adapt.hyperlink.bind(adapt) + Command.deleteHyperlink = adapt.deleteHyperlink.bind(adapt) + Command.cancelHyperlink = adapt.cancelHyperlink.bind(adapt) Command.separator = adapt.separator.bind(adapt) Command.pageBreak = adapt.pageBreak.bind(adapt) Command.addWatermark = adapt.addWatermark.bind(adapt) @@ -283,6 +287,14 @@ export class Command { return Command.hyperlink(payload) } + public executeDeleteHyperlink() { + return Command.deleteHyperlink() + } + + public executeCancelHyperlink() { + return Command.cancelHyperlink() + } + public executeImage(payload: IDrawImagePayload) { return Command.image(payload) } diff --git a/src/editor/core/command/CommandAdapt.ts b/src/editor/core/command/CommandAdapt.ts index 5c04925..deb0e09 100644 --- a/src/editor/core/command/CommandAdapt.ts +++ b/src/editor/core/command/CommandAdapt.ts @@ -1013,6 +1013,79 @@ export class CommandAdapt { this.draw.render({ curIndex }) } + public getHyperlinkRange(): [number, number] | null { + let leftIndex = -1 + let rightIndex = -1 + const { startIndex, endIndex } = this.range.getRange() + if (!~startIndex && !~endIndex) return null + const elementList = this.draw.getElementList() + const startElement = elementList[startIndex] + if (startElement.type !== ElementType.HYPERLINK) return null + // 向左查找 + let preIndex = startIndex + while (preIndex > 0) { + const preElement = elementList[preIndex] + if (preElement.hyperlinkId !== startElement.hyperlinkId) { + leftIndex = preIndex + break + } + preIndex-- + } + // 向右查找 + let nextIndex = startIndex + 1 + while (nextIndex < elementList.length) { + const nextElement = elementList[nextIndex] + if (nextElement.hyperlinkId !== startElement.hyperlinkId) { + rightIndex = nextIndex - 1 + break + } + nextIndex++ + } + // 控件在最后 + if (nextIndex === elementList.length) { + rightIndex = nextIndex - 1 + } + if (!~leftIndex || !~rightIndex) return null + return [leftIndex, rightIndex] + } + + public deleteHyperlink() { + // 获取超链接索引 + const hyperRange = this.getHyperlinkRange() + if (!hyperRange) return + const elementList = this.draw.getElementList() + const [leftIndex, rightIndex] = hyperRange + // 删除元素 + elementList.splice(leftIndex + 1, rightIndex - leftIndex) + // 重置画布 + this.range.setRange(leftIndex, leftIndex) + this.draw.render({ + curIndex: leftIndex + }) + } + + public cancelHyperlink() { + // 获取超链接索引 + const hyperRange = this.getHyperlinkRange() + if (!hyperRange) return + const elementList = this.draw.getElementList() + const [leftIndex, rightIndex] = hyperRange + // 删除属性 + for (let i = leftIndex; i <= rightIndex; i++) { + const element = elementList[i] + delete element.type + delete element.url + delete element.hyperlinkId + delete element.underline + } + // 重置画布 + const { endIndex } = this.range.getRange() + this.draw.render({ + curIndex: endIndex, + isComputeRowList: false + }) + } + public separator(payload: number[]) { const isReadonly = this.draw.isReadonly() if (isReadonly) return diff --git a/src/editor/core/contextmenu/ContextMenu.ts b/src/editor/core/contextmenu/ContextMenu.ts index 68bef9a..d57d6b7 100644 --- a/src/editor/core/contextmenu/ContextMenu.ts +++ b/src/editor/core/contextmenu/ContextMenu.ts @@ -8,6 +8,7 @@ import { Position } from '../position/Position' import { RangeManager } from '../range/RangeManager' import { controlMenus } from './menus/controlMenus' import { globalMenus } from './menus/globalMenus' +import { hyperlinkMenus } from './menus/hyperlinkMenus' import { imageMenus } from './menus/imageMenus' import { tableMenus } from './menus/tableMenus' @@ -40,7 +41,8 @@ export class ContextMenu { ...globalMenus, ...tableMenus, ...imageMenus, - ...controlMenus + ...controlMenus, + ...hyperlinkMenus ] this.contextMenuContainerList = [] this.contextMenuRelationShip = new Map() diff --git a/src/editor/core/contextmenu/menus/hyperlinkMenus.ts b/src/editor/core/contextmenu/menus/hyperlinkMenus.ts new file mode 100644 index 0000000..f459ead --- /dev/null +++ b/src/editor/core/contextmenu/menus/hyperlinkMenus.ts @@ -0,0 +1,24 @@ +import { ElementType } from '../../../dataset/enum/Element' +import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu' +import { Command } from '../../command/Command' + +export const hyperlinkMenus: IRegisterContextMenu[] = [ + { + name: '删除链接', + when: (payload) => { + return payload.startElement?.type === ElementType.HYPERLINK + }, + callback: (command: Command) => { + command.executeDeleteHyperlink() + } + }, + { + name: '取消链接', + when: (payload) => { + return payload.startElement?.type === ElementType.HYPERLINK + }, + callback: (command: Command) => { + command.executeCancelHyperlink() + } + } +] \ No newline at end of file