From 0891f053d2279e0db816118e073be9a1e268460a Mon Sep 17 00:00:00 2001 From: Hufe921 Date: Tue, 24 Oct 2023 21:39:37 +0800 Subject: [PATCH] feat: add modify internal context menu interface #300 --- docs/en/guide/contextmenu-custom.md | 12 +++ docs/en/guide/option.md | 1 + docs/guide/contextmenu-custom.md | 12 +++ docs/guide/option.md | 3 +- src/editor/core/contextmenu/ContextMenu.ts | 92 ++++++++++++------- .../core/contextmenu/menus/controlMenus.ts | 5 + .../core/contextmenu/menus/globalMenus.ts | 9 ++ .../core/contextmenu/menus/hyperlinkMenus.ts | 7 ++ .../core/contextmenu/menus/imageMenus.ts | 9 ++ .../core/contextmenu/menus/tableMenus.ts | 57 +++++++++++- src/editor/core/register/Register.ts | 2 + src/editor/dataset/constant/ContextMenu.ts | 50 ++++++++++ src/editor/index.ts | 3 + src/editor/interface/Editor.ts | 1 + .../interface/contextmenu/ContextMenu.ts | 2 + 15 files changed, 231 insertions(+), 34 deletions(-) diff --git a/docs/en/guide/contextmenu-custom.md b/docs/en/guide/contextmenu-custom.md index 153c7e9..6eab72c 100644 --- a/docs/en/guide/contextmenu-custom.md +++ b/docs/en/guide/contextmenu-custom.md @@ -8,13 +8,25 @@ import Editor from "@hufe921/canvas-editor" const instance = new Editor(container, data, options) instance.register.contextMenuList([ { + key?: string; isDivider?: boolean; icon?: string; name?: string; // Use %s for selection text. Example: Search: %s shortCut?: string; + disable?: boolean; when?: (payload: IContextMenuContext) => boolean; callback?: (command: Command, context: IContextMenuContext) => any; childMenus?: IRegisterContextMenu[]; } ]) ``` + +## getContextMenuList + +Feature: Get context menu list + +Usage: + +```javascript +const contextMenuList = await instance.register.getContextMenuList() +``` diff --git a/docs/en/guide/option.md b/docs/en/guide/option.md index 22dd84c..52954e9 100644 --- a/docs/en/guide/option.md +++ b/docs/en/guide/option.md @@ -56,6 +56,7 @@ interface IEditorOption { printPixelRatio?: number // Print the pixel ratio (larger values are clearer, but larger sizes). default: 3 maskMargin?: IMargin // Masking margins above the editor(for example: menu bar, bottom toolbar)。default: [0, 0, 0, 0] letterClass? string[] // Alphabet class supported by typesetting. default: a-zA-Z. Built-in alternative alphabet class: LETTER_CLASS + contextMenuDisableKeys?: string[] // Disable context menu keys. default: [] wordBreak?: WordBreak // Word and punctuation breaks: No punctuation in the first line of the BREAK_WORD &The word is not split, and the line is folded after BREAK_ALL full according to the width of the character. default: BREAK_WORD watermark?: IWatermark // Watermark{data:string; color?:string; opacity?:number; size?:number; font?:string;} control?: IControlOption // Control {placeholderColor?:string; bracketColor?:string; prefix?:string; postfix?:string;} diff --git a/docs/guide/contextmenu-custom.md b/docs/guide/contextmenu-custom.md index ae66cf8..ee1004f 100644 --- a/docs/guide/contextmenu-custom.md +++ b/docs/guide/contextmenu-custom.md @@ -8,13 +8,25 @@ import Editor from "@hufe921/canvas-editor" const instance = new Editor(container, data, options) instance.register.contextMenuList([ { + key?: string; isDivider?: boolean; icon?: string; name?: string; // 使用%s代表选区文本。示例:搜索:%s shortCut?: string; + disable?: boolean; when?: (payload: IContextMenuContext) => boolean; callback?: (command: Command, context: IContextMenuContext) => any; childMenus?: IRegisterContextMenu[]; } ]) ``` + +## getContextMenuList + +功能:获取注册的右键菜单列表 + +用法: + +```javascript +const contextMenuList = await instance.register.getContextMenuList() +``` diff --git a/docs/guide/option.md b/docs/guide/option.md index 8a4f565..909ab50 100644 --- a/docs/guide/option.md +++ b/docs/guide/option.md @@ -55,7 +55,8 @@ interface IEditorOption { historyMaxRecordCount?: number // 历史(撤销重做)最大记录次数。默认:100次 printPixelRatio?: number // 打印像素比率(值越大越清晰,但尺寸越大)。默认:3 maskMargin?: IMargin // 编辑器上的遮盖边距(如悬浮到编辑器上的菜单栏、底部工具栏)。默认:[0, 0, 0, 0] - letterClass? string[] // 排版支持的字母类。默认:a-zA-Z。内置可选择的字母表类:LETTER_CLASS + letterClass?: string[] // 排版支持的字母类。默认:a-zA-Z。内置可选择的字母表类:LETTER_CLASS + contextMenuDisableKeys?: string[] // 禁用的右键菜单。默认:[] wordBreak?: WordBreak // 单词与标点断行:BREAK_WORD首行不出现标点&单词不拆分、BREAK_ALL按字符宽度撑满后折行。默认:BREAK_WORD watermark?: IWatermark // 水印信息。{data:string; color?:string; opacity?:number; size?:number; font?:string;} control?: IControlOption // 控件信息。 {placeholderColor?:string; bracketColor?:string; prefix?:string; postfix?:string;} diff --git a/src/editor/core/contextmenu/ContextMenu.ts b/src/editor/core/contextmenu/ContextMenu.ts index c4d80ba..df2a612 100644 --- a/src/editor/core/contextmenu/ContextMenu.ts +++ b/src/editor/core/contextmenu/ContextMenu.ts @@ -1,6 +1,8 @@ import { NAME_PLACEHOLDER } from '../../dataset/constant/ContextMenu' import { EDITOR_COMPONENT, EDITOR_PREFIX } from '../../dataset/constant/Editor' import { EditorComponent } from '../../dataset/enum/Editor' +import { DeepRequired } from '../../interface/Common' +import { IEditorOption } from '../../interface/Editor' import { IContextMenuContext, IRegisterContextMenu @@ -25,6 +27,7 @@ interface IRenderPayload { } export class ContextMenu { + private options: DeepRequired private draw: Draw private command: Command private range: RangeManager @@ -37,6 +40,7 @@ export class ContextMenu { private context: IContextMenuContext | null constructor(draw: Draw, command: Command) { + this.options = draw.getOptions() this.draw = draw this.command = command this.range = draw.getRange() @@ -57,6 +61,10 @@ export class ContextMenu { this._addEvent() } + public getContextMenuList(): IRegisterContextMenu[] { + return this.contextMenuList + } + private _addEvent() { // 菜单权限 this.container.addEventListener('contextmenu', this._proxyContextMenuEvent) @@ -72,22 +80,34 @@ export class ContextMenu { document.removeEventListener('mousedown', this._handleSideEffect) } - private _proxyContextMenuEvent = (evt: MouseEvent) => { - this.context = this._getContext() + private _filterMenuList( + menuList: IRegisterContextMenu[] + ): IRegisterContextMenu[] { + const { contextMenuDisableKeys } = this.options const renderList: IRegisterContextMenu[] = [] - let isRegisterContextMenu = false - for (let c = 0; c < this.contextMenuList.length; c++) { - const menu = this.contextMenuList[c] + for (let m = 0; m < menuList.length; m++) { + const menu = menuList[m] + if ( + menu.disable || + (menu.key && contextMenuDisableKeys.includes(menu.key)) + ) { + continue + } if (menu.isDivider) { renderList.push(menu) } else { - const isMatch = menu.when?.(this.context) - if (isMatch) { + if (menu.when?.(this.context!)) { renderList.push(menu) - isRegisterContextMenu = true } } } + return renderList + } + + private _proxyContextMenuEvent = (evt: MouseEvent) => { + this.context = this._getContext() + const renderList = this._filterMenuList(this.contextMenuList) + const isRegisterContextMenu = renderList.some(menu => !menu.isDivider) if (isRegisterContextMenu) { this.dispose() this._render({ @@ -180,8 +200,12 @@ export class ContextMenu { for (let c = 0; c < contextMenuList.length; c++) { const menu = contextMenuList[c] if (menu.isDivider) { - // 首尾分隔符不渲染 - if (c !== 0 && c !== contextMenuList.length - 1) { + // 分割线相邻 || 首尾分隔符时不渲染 + if ( + c !== 0 && + c !== contextMenuList.length - 1 && + !contextMenuList[c - 1]?.isDivider + ) { const divider = document.createElement('div') divider.classList.add(`${EDITOR_PREFIX}-contextmenu-divider`) contextMenuContent.append(divider) @@ -191,28 +215,32 @@ export class ContextMenu { menuItem.classList.add(`${EDITOR_PREFIX}-contextmenu-item`) // 菜单事件 if (menu.childMenus) { - menuItem.classList.add(`${EDITOR_PREFIX}-contextmenu-sub-item`) - menuItem.onmouseenter = () => { - this._setHoverStatus(menuItem, true) - this._removeSubMenu(contextMenuContainer) - // 子菜单 - const subMenuRect = menuItem.getBoundingClientRect() - const left = subMenuRect.left + subMenuRect.width - const top = subMenuRect.top - childMenuContainer = this._render({ - contextMenuList: menu.childMenus!, - left, - top, - parentMenuContainer: contextMenuContainer - }) - } - menuItem.onmouseleave = evt => { - // 移动到子菜单选项选中状态不变化 - if ( - !childMenuContainer || - !childMenuContainer.contains(evt.relatedTarget as Node) - ) { - this._setHoverStatus(menuItem, false) + const childMenus = this._filterMenuList(menu.childMenus) + const isRegisterContextMenu = childMenus.some(menu => !menu.isDivider) + if (isRegisterContextMenu) { + menuItem.classList.add(`${EDITOR_PREFIX}-contextmenu-sub-item`) + menuItem.onmouseenter = () => { + this._setHoverStatus(menuItem, true) + this._removeSubMenu(contextMenuContainer) + // 子菜单 + const subMenuRect = menuItem.getBoundingClientRect() + const left = subMenuRect.left + subMenuRect.width + const top = subMenuRect.top + childMenuContainer = this._render({ + contextMenuList: childMenus, + left, + top, + parentMenuContainer: contextMenuContainer + }) + } + menuItem.onmouseleave = evt => { + // 移动到子菜单选项选中状态不变化 + if ( + !childMenuContainer || + !childMenuContainer.contains(evt.relatedTarget as Node) + ) { + this._setHoverStatus(menuItem, false) + } } } } else { diff --git a/src/editor/core/contextmenu/menus/controlMenus.ts b/src/editor/core/contextmenu/menus/controlMenus.ts index 3ce3121..c7bb5a2 100644 --- a/src/editor/core/contextmenu/menus/controlMenus.ts +++ b/src/editor/core/contextmenu/menus/controlMenus.ts @@ -1,9 +1,14 @@ +import { INTERNAL_CONTEXT_MENU_KEY } from '../../../dataset/constant/ContextMenu' import { ElementType } from '../../../dataset/enum/Element' import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu' import { Command } from '../../command/Command' +const { + CONTROL: { DELETE } +} = INTERNAL_CONTEXT_MENU_KEY export const controlMenus: IRegisterContextMenu[] = [ { + key: DELETE, i18nPath: 'contextmenu.control.delete', when: payload => { return ( diff --git a/src/editor/core/contextmenu/menus/globalMenus.ts b/src/editor/core/contextmenu/menus/globalMenus.ts index fa79e49..c06610a 100644 --- a/src/editor/core/contextmenu/menus/globalMenus.ts +++ b/src/editor/core/contextmenu/menus/globalMenus.ts @@ -1,9 +1,14 @@ +import { INTERNAL_CONTEXT_MENU_KEY } from '../../../dataset/constant/ContextMenu' import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu' import { isApple } from '../../../utils/ua' import { Command } from '../../command/Command' +const { + GLOBAL: { CUT, COPY, PASTE, SELECT_ALL, PRINT } +} = INTERNAL_CONTEXT_MENU_KEY export const globalMenus: IRegisterContextMenu[] = [ { + key: CUT, i18nPath: 'contextmenu.global.cut', shortCut: `${isApple ? '⌘' : 'Ctrl'} + X`, when: payload => { @@ -14,6 +19,7 @@ export const globalMenus: IRegisterContextMenu[] = [ } }, { + key: COPY, i18nPath: 'contextmenu.global.copy', shortCut: `${isApple ? '⌘' : 'Ctrl'} + C`, when: payload => { @@ -24,6 +30,7 @@ export const globalMenus: IRegisterContextMenu[] = [ } }, { + key: PASTE, i18nPath: 'contextmenu.global.paste', shortCut: `${isApple ? '⌘' : 'Ctrl'} + V`, when: payload => { @@ -34,6 +41,7 @@ export const globalMenus: IRegisterContextMenu[] = [ } }, { + key: SELECT_ALL, i18nPath: 'contextmenu.global.selectAll', shortCut: `${isApple ? '⌘' : 'Ctrl'} + A`, when: payload => { @@ -47,6 +55,7 @@ export const globalMenus: IRegisterContextMenu[] = [ isDivider: true }, { + key: PRINT, i18nPath: 'contextmenu.global.print', icon: 'print', when: () => true, diff --git a/src/editor/core/contextmenu/menus/hyperlinkMenus.ts b/src/editor/core/contextmenu/menus/hyperlinkMenus.ts index d243f06..03e50fe 100644 --- a/src/editor/core/contextmenu/menus/hyperlinkMenus.ts +++ b/src/editor/core/contextmenu/menus/hyperlinkMenus.ts @@ -1,12 +1,17 @@ +import { INTERNAL_CONTEXT_MENU_KEY } from '../../../dataset/constant/ContextMenu' import { ElementType } from '../../../dataset/enum/Element' import { IContextMenuContext, IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu' import { Command } from '../../command/Command' +const { + HYPERLINK: { DELETE, CANCEL, EDIT } +} = INTERNAL_CONTEXT_MENU_KEY export const hyperlinkMenus: IRegisterContextMenu[] = [ { + key: DELETE, i18nPath: 'contextmenu.hyperlink.delete', when: payload => { return ( @@ -19,6 +24,7 @@ export const hyperlinkMenus: IRegisterContextMenu[] = [ } }, { + key: CANCEL, i18nPath: 'contextmenu.hyperlink.cancel', when: payload => { return ( @@ -31,6 +37,7 @@ export const hyperlinkMenus: IRegisterContextMenu[] = [ } }, { + key: EDIT, i18nPath: 'contextmenu.hyperlink.edit', when: payload => { return ( diff --git a/src/editor/core/contextmenu/menus/imageMenus.ts b/src/editor/core/contextmenu/menus/imageMenus.ts index c2b3ead..b2c6577 100644 --- a/src/editor/core/contextmenu/menus/imageMenus.ts +++ b/src/editor/core/contextmenu/menus/imageMenus.ts @@ -1,3 +1,4 @@ +import { INTERNAL_CONTEXT_MENU_KEY } from '../../../dataset/constant/ContextMenu' import { ImageDisplay } from '../../../dataset/enum/Control' import { ElementType } from '../../../dataset/enum/Element' import { @@ -5,9 +6,13 @@ import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu' import { Command } from '../../command/Command' +const { + IMAGE: { CHANGE, SAVE_AS, TEXT_WRAP, TEXT_WRAP_EMBED, TEXT_WRAP_UP_DOWN } +} = INTERNAL_CONTEXT_MENU_KEY export const imageMenus: IRegisterContextMenu[] = [ { + key: CHANGE, i18nPath: 'contextmenu.image.change', icon: 'image-change', when: payload => { @@ -36,6 +41,7 @@ export const imageMenus: IRegisterContextMenu[] = [ } }, { + key: SAVE_AS, i18nPath: 'contextmenu.image.saveAs', icon: 'image', when: payload => { @@ -49,6 +55,7 @@ export const imageMenus: IRegisterContextMenu[] = [ } }, { + key: TEXT_WRAP, i18nPath: 'contextmenu.image.textWrap', when: payload => { return ( @@ -59,6 +66,7 @@ export const imageMenus: IRegisterContextMenu[] = [ }, childMenus: [ { + key: TEXT_WRAP_EMBED, i18nPath: 'contextmenu.image.textWrapType.embed', when: () => true, callback: (command: Command, context: IContextMenuContext) => { @@ -69,6 +77,7 @@ export const imageMenus: IRegisterContextMenu[] = [ } }, { + key: TEXT_WRAP_UP_DOWN, i18nPath: 'contextmenu.image.textWrapType.upDown', when: () => true, callback: (command: Command, context: IContextMenuContext) => { diff --git a/src/editor/core/contextmenu/menus/tableMenus.ts b/src/editor/core/contextmenu/menus/tableMenus.ts index fa310de..da7599a 100644 --- a/src/editor/core/contextmenu/menus/tableMenus.ts +++ b/src/editor/core/contextmenu/menus/tableMenus.ts @@ -1,13 +1,46 @@ +import { INTERNAL_CONTEXT_MENU_KEY } from '../../../dataset/constant/ContextMenu' import { VerticalAlign } from '../../../dataset/enum/VerticalAlign' -import { TableBorder, TdBorder, TdSlash } from '../../../dataset/enum/table/Table' +import { + TableBorder, + TdBorder, + TdSlash +} from '../../../dataset/enum/table/Table' import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu' import { Command } from '../../command/Command' +const { + TABLE: { + BORDER, + BORDER_ALL, + BORDER_EMPTY, + BORDER_EXTERNAL, + BORDER_TD, + BORDER_TD_BOTTOM, + BORDER_TD_BACK, + BORDER_TD_FORWARD, + VERTICAL_ALIGN, + VERTICAL_ALIGN_TOP, + VERTICAL_ALIGN_MIDDLE, + VERTICAL_ALIGN_BOTTOM, + INSERT_ROW_COL, + INSERT_TOP_ROW, + INSERT_BOTTOM_ROW, + INSERT_LEFT_COL, + INSERT_RIGHT_COL, + DELETE_ROW_COL, + DELETE_ROW, + DELETE_COL, + DELETE_TABLE, + MERGE_CELL, + CANCEL_MERGE_CELL + } +} = INTERNAL_CONTEXT_MENU_KEY export const tableMenus: IRegisterContextMenu[] = [ { isDivider: true }, { + key: BORDER, i18nPath: 'contextmenu.table.border', icon: 'border-all', when: payload => { @@ -15,6 +48,7 @@ export const tableMenus: IRegisterContextMenu[] = [ }, childMenus: [ { + key: BORDER_ALL, i18nPath: 'contextmenu.table.borderAll', icon: 'border-all', when: () => true, @@ -23,6 +57,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: BORDER_EMPTY, i18nPath: 'contextmenu.table.borderEmpty', icon: 'border-empty', when: () => true, @@ -31,6 +66,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: BORDER_EXTERNAL, i18nPath: 'contextmenu.table.borderExternal', icon: 'border-external', when: () => true, @@ -39,11 +75,13 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: BORDER_TD, i18nPath: 'contextmenu.table.borderTd', icon: 'border-td', when: () => true, childMenus: [ { + key: BORDER_TD_BOTTOM, i18nPath: 'contextmenu.table.borderTdBottom', icon: 'border-td-bottom', when: () => true, @@ -52,6 +90,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: BORDER_TD_FORWARD, i18nPath: 'contextmenu.table.borderTdForward', icon: 'border-td-forward', when: () => true, @@ -60,6 +99,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: BORDER_TD_BACK, i18nPath: 'contextmenu.table.borderTdBack', icon: 'border-td-back', when: () => true, @@ -72,6 +112,7 @@ export const tableMenus: IRegisterContextMenu[] = [ ] }, { + key: VERTICAL_ALIGN, i18nPath: 'contextmenu.table.verticalAlign', icon: 'vertical-align', when: payload => { @@ -79,6 +120,7 @@ export const tableMenus: IRegisterContextMenu[] = [ }, childMenus: [ { + key: VERTICAL_ALIGN_TOP, i18nPath: 'contextmenu.table.verticalAlignTop', icon: 'vertical-align-top', when: () => true, @@ -87,6 +129,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: VERTICAL_ALIGN_MIDDLE, i18nPath: 'contextmenu.table.verticalAlignMiddle', icon: 'vertical-align-middle', when: () => true, @@ -95,6 +138,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: VERTICAL_ALIGN_BOTTOM, i18nPath: 'contextmenu.table.verticalAlignBottom', icon: 'vertical-align-bottom', when: () => true, @@ -105,6 +149,7 @@ export const tableMenus: IRegisterContextMenu[] = [ ] }, { + key: INSERT_ROW_COL, i18nPath: 'contextmenu.table.insertRowCol', icon: 'insert-row-col', when: payload => { @@ -112,6 +157,7 @@ export const tableMenus: IRegisterContextMenu[] = [ }, childMenus: [ { + key: INSERT_TOP_ROW, i18nPath: 'contextmenu.table.insertTopRow', icon: 'insert-top-row', when: () => true, @@ -120,6 +166,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: INSERT_BOTTOM_ROW, i18nPath: 'contextmenu.table.insertBottomRow', icon: 'insert-bottom-row', when: () => true, @@ -128,6 +175,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: INSERT_LEFT_COL, i18nPath: 'contextmenu.table.insertLeftCol', icon: 'insert-left-col', when: () => true, @@ -136,6 +184,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: INSERT_RIGHT_COL, i18nPath: 'contextmenu.table.insertRightCol', icon: 'insert-right-col', when: () => true, @@ -146,6 +195,7 @@ export const tableMenus: IRegisterContextMenu[] = [ ] }, { + key: DELETE_ROW_COL, i18nPath: 'contextmenu.table.deleteRowCol', icon: 'delete-row-col', when: payload => { @@ -153,6 +203,7 @@ export const tableMenus: IRegisterContextMenu[] = [ }, childMenus: [ { + key: DELETE_ROW, i18nPath: 'contextmenu.table.deleteRow', icon: 'delete-row', when: () => true, @@ -161,6 +212,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: DELETE_COL, i18nPath: 'contextmenu.table.deleteCol', icon: 'delete-col', when: () => true, @@ -169,6 +221,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: DELETE_TABLE, i18nPath: 'contextmenu.table.deleteTable', icon: 'delete-table', when: () => true, @@ -179,6 +232,7 @@ export const tableMenus: IRegisterContextMenu[] = [ ] }, { + key: MERGE_CELL, i18nPath: 'contextmenu.table.mergeCell', icon: 'merge-cell', when: payload => { @@ -189,6 +243,7 @@ export const tableMenus: IRegisterContextMenu[] = [ } }, { + key: CANCEL_MERGE_CELL, i18nPath: 'contextmenu.table.mergeCancelCell', icon: 'merge-cancel-cell', when: payload => { diff --git a/src/editor/core/register/Register.ts b/src/editor/core/register/Register.ts index c22278e..4401d52 100644 --- a/src/editor/core/register/Register.ts +++ b/src/editor/core/register/Register.ts @@ -14,12 +14,14 @@ interface IRegisterPayload { export class Register { public contextMenuList: (payload: IRegisterContextMenu[]) => void + public getContextMenuList: () => IRegisterContextMenu[] public shortcutList: (payload: IRegisterShortcut[]) => void public langMap: (locale: string, lang: DeepPartial) => void constructor(payload: IRegisterPayload) { const { contextMenu, shortcut, i18n } = payload this.contextMenuList = contextMenu.registerContextMenuList.bind(contextMenu) + this.getContextMenuList = contextMenu.getContextMenuList.bind(contextMenu) this.shortcutList = shortcut.registerShortcutList.bind(shortcut) this.langMap = i18n.registerLangMap.bind(i18n) } diff --git a/src/editor/dataset/constant/ContextMenu.ts b/src/editor/dataset/constant/ContextMenu.ts index 27df619..8d7931f 100644 --- a/src/editor/dataset/constant/ContextMenu.ts +++ b/src/editor/dataset/constant/ContextMenu.ts @@ -1,3 +1,53 @@ export const NAME_PLACEHOLDER = { SELECTED_TEXT: '%s' } + +export const INTERNAL_CONTEXT_MENU_KEY = { + GLOBAL: { + CUT: 'globalCut', + COPY: 'globalCopy', + PASTE: 'globalPaste', + SELECT_ALL: 'globalSelectAll', + PRINT: 'globalPrint' + }, + CONTROL: { + DELETE: 'controlDelete' + }, + HYPERLINK: { + DELETE: 'hyperlinkDelete', + CANCEL: 'hyperlinkCancel', + EDIT: 'hyperEdit' + }, + IMAGE: { + CHANGE: 'imageChange', + SAVE_AS: 'imageSaveAs', + TEXT_WRAP: 'imageTextWrap', + TEXT_WRAP_EMBED: 'imageTextWrapEmbed', + TEXT_WRAP_UP_DOWN: 'imageTextWrapUpDown' + }, + TABLE: { + BORDER: 'border', + BORDER_ALL: 'tableBorderAll', + BORDER_EMPTY: 'tableBorderEmpty', + BORDER_EXTERNAL: 'tableBorderExternal', + BORDER_TD: 'tableBorderTd', + BORDER_TD_BOTTOM: 'tableBorderTdBottom', + BORDER_TD_FORWARD: 'tableBorderTdForward', + BORDER_TD_BACK: 'tableBorderTdBack', + VERTICAL_ALIGN: 'tableVerticalAlign', + VERTICAL_ALIGN_TOP: 'tableVerticalAlignTop', + VERTICAL_ALIGN_MIDDLE: 'tableVerticalAlignMiddle', + VERTICAL_ALIGN_BOTTOM: 'tableVerticalAlignBottom', + INSERT_ROW_COL: 'tableInsertRowCol', + INSERT_TOP_ROW: 'tableInsertTopRow', + INSERT_BOTTOM_ROW: 'tableInsertBottomRow', + INSERT_LEFT_COL: 'tableInsertLeftCol', + INSERT_RIGHT_COL: 'tableInsertRightCol', + DELETE_ROW_COL: 'tableDeleteRowCol', + DELETE_ROW: 'tableDeleteRow', + DELETE_COL: 'tableDeleteCol', + DELETE_TABLE: 'tableDeleteTable', + MERGE_CELL: 'tableMergeCell', + CANCEL_MERGE_CELL: 'tableCancelMergeCell' + } +} diff --git a/src/editor/index.ts b/src/editor/index.ts index a38d6bf..6e7b261 100644 --- a/src/editor/index.ts +++ b/src/editor/index.ts @@ -66,6 +66,7 @@ import { Override } from './core/override/Override' import { defaultPageBreakOption } from './dataset/constant/PageBreak' import { IPageBreak } from './interface/PageBreak' import { LETTER_CLASS } from './dataset/constant/Common' +import { INTERNAL_CONTEXT_MENU_KEY } from './dataset/constant/ContextMenu' export default class Editor { public command: Command @@ -167,6 +168,7 @@ export default class Editor { printPixelRatio: 3, maskMargin: [0, 0, 0, 0], letterClass: [LETTER_CLASS.ENGLISH], + contextMenuDisableKeys: [], ...options, header: headerOptions, footer: footerOptions, @@ -248,6 +250,7 @@ export default class Editor { export { EDITOR_COMPONENT, LETTER_CLASS, + INTERNAL_CONTEXT_MENU_KEY, Editor, RowFlex, VerticalAlign, diff --git a/src/editor/interface/Editor.ts b/src/editor/interface/Editor.ts index aa905de..935ec1a 100644 --- a/src/editor/interface/Editor.ts +++ b/src/editor/interface/Editor.ts @@ -65,6 +65,7 @@ export interface IEditorOption { printPixelRatio?: number maskMargin?: IMargin letterClass?: string[] + contextMenuDisableKeys?: string[] wordBreak?: WordBreak header?: IHeader footer?: IFooter diff --git a/src/editor/interface/contextmenu/ContextMenu.ts b/src/editor/interface/contextmenu/ContextMenu.ts index 5eef5ed..cdcaa5e 100644 --- a/src/editor/interface/contextmenu/ContextMenu.ts +++ b/src/editor/interface/contextmenu/ContextMenu.ts @@ -14,11 +14,13 @@ export interface IContextMenuContext { } export interface IRegisterContextMenu { + key?: string i18nPath?: string isDivider?: boolean icon?: string name?: string shortCut?: string + disable?: boolean when?: (payload: IContextMenuContext) => boolean callback?: (command: Command, context: IContextMenuContext) => any childMenus?: IRegisterContextMenu[]