diff --git a/src/editor/core/command/Command.ts b/src/editor/core/command/Command.ts index 3065e2e..33e4ec2 100644 --- a/src/editor/core/command/Command.ts +++ b/src/editor/core/command/Command.ts @@ -49,6 +49,7 @@ export class Command { private static hyperlink: CommandAdapt['hyperlink'] private static deleteHyperlink: CommandAdapt['deleteHyperlink'] private static cancelHyperlink: CommandAdapt['cancelHyperlink'] + private static editHyperlink: CommandAdapt['editHyperlink'] private static separator: CommandAdapt['separator'] private static pageBreak: CommandAdapt['pageBreak'] private static addWatermark: CommandAdapt['addWatermark'] @@ -110,6 +111,7 @@ export class Command { Command.hyperlink = adapt.hyperlink.bind(adapt) Command.deleteHyperlink = adapt.deleteHyperlink.bind(adapt) Command.cancelHyperlink = adapt.cancelHyperlink.bind(adapt) + Command.editHyperlink = adapt.editHyperlink.bind(adapt) Command.separator = adapt.separator.bind(adapt) Command.pageBreak = adapt.pageBreak.bind(adapt) Command.addWatermark = adapt.addWatermark.bind(adapt) @@ -294,6 +296,10 @@ export class Command { return Command.cancelHyperlink() } + public executeEditHyperlink(payload: string) { + return Command.editHyperlink(payload) + } + 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 07faa9e..a77e2df 100644 --- a/src/editor/core/command/CommandAdapt.ts +++ b/src/editor/core/command/CommandAdapt.ts @@ -1026,7 +1026,7 @@ export class CommandAdapt { while (preIndex > 0) { const preElement = elementList[preIndex] if (preElement.hyperlinkId !== startElement.hyperlinkId) { - leftIndex = preIndex + leftIndex = preIndex + 1 break } preIndex-- @@ -1056,12 +1056,13 @@ export class CommandAdapt { const elementList = this.draw.getElementList() const [leftIndex, rightIndex] = hyperRange // 删除元素 - elementList.splice(leftIndex + 1, rightIndex - leftIndex) + elementList.splice(leftIndex, rightIndex - leftIndex + 1) this.draw.getHyperlinkParticle().clearHyperlinkPopup() // 重置画布 - this.range.setRange(leftIndex, leftIndex) + const newIndex = leftIndex - 1 + this.range.setRange(newIndex, newIndex) this.draw.render({ - curIndex: leftIndex + curIndex: newIndex }) } @@ -1088,6 +1089,26 @@ export class CommandAdapt { }) } + public editHyperlink(payload: string) { + // 获取超链接索引 + const hyperRange = this.getHyperlinkRange() + if (!hyperRange) return + const elementList = this.draw.getElementList() + const [leftIndex, rightIndex] = hyperRange + // 替换url + for (let i = leftIndex; i <= rightIndex; i++) { + const element = elementList[i] + element.url = payload + } + this.draw.getHyperlinkParticle().clearHyperlinkPopup() + // 重置画布 + 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 d57d6b7..d0cada5 100644 --- a/src/editor/core/contextmenu/ContextMenu.ts +++ b/src/editor/core/contextmenu/ContextMenu.ts @@ -29,6 +29,7 @@ export class ContextMenu { private contextMenuList: IRegisterContextMenu[] private contextMenuContainerList: HTMLDivElement[] private contextMenuRelationShip: Map + private context: IContextMenuContext | null constructor(draw: Draw, command: Command) { this.draw = draw @@ -36,6 +37,7 @@ export class ContextMenu { this.range = draw.getRange() this.position = draw.getPosition() this.container = draw.getContainer() + this.context = null // 内部菜单 this.contextMenuList = [ ...globalMenus, @@ -53,7 +55,7 @@ export class ContextMenu { } private _proxyContextMenuEvent(evt: MouseEvent) { - const context = this._getContext() + this.context = this._getContext() const renderList: IRegisterContextMenu[] = [] let isRegisterContextMenu = false for (let c = 0; c < this.contextMenuList.length; c++) { @@ -61,7 +63,7 @@ export class ContextMenu { if (menu.isDivider) { renderList.push(menu) } else { - const isMatch = menu.when?.(context) + const isMatch = menu.when?.(this.context) if (isMatch) { renderList.push(menu) isRegisterContextMenu = true @@ -186,8 +188,8 @@ export class ContextMenu { this._setHoverStatus(menuItem, false) } menuItem.onclick = () => { - if (menu.callback) { - menu.callback(this.command) + if (menu.callback && this.context) { + menu.callback(this.command, this.context) } this.dispose() } diff --git a/src/editor/core/contextmenu/menus/hyperlinkMenus.ts b/src/editor/core/contextmenu/menus/hyperlinkMenus.ts index f459ead..c3ef26c 100644 --- a/src/editor/core/contextmenu/menus/hyperlinkMenus.ts +++ b/src/editor/core/contextmenu/menus/hyperlinkMenus.ts @@ -1,5 +1,5 @@ import { ElementType } from '../../../dataset/enum/Element' -import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu' +import { IContextMenuContext, IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu' import { Command } from '../../command/Command' export const hyperlinkMenus: IRegisterContextMenu[] = [ @@ -20,5 +20,17 @@ export const hyperlinkMenus: IRegisterContextMenu[] = [ callback: (command: Command) => { command.executeCancelHyperlink() } + }, + { + name: '编辑链接', + when: (payload) => { + return payload.startElement?.type === ElementType.HYPERLINK + }, + callback: (command: Command, context: IContextMenuContext) => { + const url = window.prompt('编辑链接', context.startElement?.url) + if (url) { + command.executeEditHyperlink(url) + } + } } ] \ No newline at end of file diff --git a/src/editor/interface/contextmenu/ContextMenu.ts b/src/editor/interface/contextmenu/ContextMenu.ts index 8f25fa2..aeb4934 100644 --- a/src/editor/interface/contextmenu/ContextMenu.ts +++ b/src/editor/interface/contextmenu/ContextMenu.ts @@ -1,3 +1,4 @@ +import { Command } from '../../core/command/Command' import { IElement } from '../Element' export interface IContextMenuContext { @@ -16,6 +17,6 @@ export interface IRegisterContextMenu { name?: string; shortCut?: string; when?: (payload: IContextMenuContext) => boolean; - callback?: Function; + callback?: (command: Command, context: IContextMenuContext) => any; childMenus?: IRegisterContextMenu[]; } \ No newline at end of file