UNPKG

@syncfusion/ej2-spreadsheet

Version:

Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel

106 lines (88 loc) 7.88 kB
# Context Menu Module data flow ## What It Does The Context Menu module provides the right-click menu for the Spreadsheet UI. It builds a contextual menu based on click target (cells, headers, sheet tabs, select-all), localizes items, validates actions (protection/readonly), dispatches commands via notifications, and exposes APIs to extend/modify menu items at runtime. Primary implementation file: `src/spreadsheet/integrations/context-menu.ts`. ## Entry Points (UI) **Class:** `ContextMenu` - Created during module init; initializes a `ContextMenuComponent` instance attached to a generated `<ul>` with id `${parent.element.id}_contextmenu` and CSS `e-spreadsheet-contextmenu`. - Listens to parent notifications/events: `addContextMenuItems`, `removeContextMenuItems`, `enableContextMenuItems`. - Key handlers: - `initContextMenu()` — construct DOM host and configure component callbacks (`select`, `beforeOpen`, `beforeClose`, `beforeItemRender`). - `beforeOpenHandler(args)` — determine target area (`Content`, `ColumnHeader`, `RowHeader`, `Footer`, `SelectAll`), compute items via `getDataSource()`, and abort if menu should not open. - `selectHandler(args)` — handle item selection by mapping item ids to notifications or internal actions (cut/copy/paste, insert/delete/move sheet, sort/filter, comments/notes, hyperlinks, protect, etc.). - `beforeCloseHandler(args)` — fires `contextMenuBeforeClose` and handles ESC key focus. - `addItemsHandler(args)`, `removeItemsHandler(args)`, `enableItemsHandler(args)` — runtime mutation APIs for the context menu. - `destroy()` — detach handlers and destroy the component. ## ASCII Core Logic Flow User right-click → browser event → `beforeOpenHandler()` ↓ Identify target area via DOM/notifications (`getRowIdxFromClientY`, `getColIdxFromClientX`) → `getDataSource(target)` ↓ Build localized `MenuItemModel[]` (clipboard, filter/sort, insert/delete, comments/notes, hyperlinks, sheet actions) → `contextMenuInstance.items = items` → open menu ↓ User selects item → `selectHandler()` validates (readonly/protection/etc.) → send workbook notifications (e.g. `cut`, `copy`, `paste`, `insertModel`, `removeSheetTab`, `hideSheet`, `updateSortCollection`) ↓ Target operation performed by other subsystems → potential `focus()`/UI updates and undo/redo handled by respective handlers ## Operations (functions & responsibilities) - `initContextMenu()` - Create `<ul>` host with id `${parent.element.id}_contextmenu` and append to `parent.element`. - Instantiate `ContextMenuComponent` with callbacks. - Ensure ARIA role `menu` and attach keyboard prevention handler. - `beforeOpenHandler(args)` - Determine whether menu can open by checking target element classes and z-index. - Compute `target` using `getTarget()` (maps DOM element → Content/RowHeader/ColumnHeader/Footer/SelectAll). - For header/footer targets, call `getRowIdxFromClientY`/`getColIdxFromClientX` notifications to resolve header vs content. - Call `getDataSource(target, targetEle)` to build item list for the target area. - Fire `cMenuBeforeOpen` notification and `contextMenuBeforeOpen` event for external customization. - `getDataSource(target, targetEle)` - Uses localization `L10n` and helper setters to build contextual items: - `setClipboardData()` — Cut/Copy/Paste/PasteSpecial - `setFilterItems()` / `setSortItems()` — filter and sort submenus - `setCommentsMenu()` / `setNotesMenu()` — comment/note items based on cell state - `setHyperLink()` — hyperlink options based on cell content - `setInsertDeleteItems()` / `setHideShowItems()` — for headers, respecting `allowInsert`/`allowDelete` and hidden counts - `setProtectSheetItems()` — footer sheet protect/unprotect - `selectHandler(args)` - Maps menu item id prefix `${parent.element.id}_cmenu` to concrete actions; performs validation (read-only cells via `isReadOnlyCells`, selection mode, protection) and sends notifications: - Clipboard: `cut`, `copy`, `paste` (with type flags) - Sheet actions: `insertModel`, `removeSheetTab`, `hideSheet`, `duplicateSheet`, `moveSheet` - Sort/Filter: `updateSortCollection`, `getFilteredColumn`, etc. - Notes/Comments: custom notifications for comment/note flows - Hyperlinks: `insertHyperlink` / `editHyperlink` / `removeHyperlink` (via notification paths present in code) - Some selections call library helpers (e.g., `duplicateSheet`, `moveSheet`) and call `focus(this.parent.element)` where appropriate. - Runtime mutation API - `addItemsHandler`, `removeItemsHandler`, `enableItemsHandler` are thin wrappers around `ContextMenuComponent` methods to allow dynamic extension by other modules. - `destroy()` - Removes event listeners, destroys `contextMenuInstance`, detaches the host `<ul>`, and clears references. ## Validation & Safety - Readonly/protection checks: `selectHandler` inspects rows/columns and calls `isReadOnlyCells`; if action is not allowed it cancels and triggers `readonlyAlert` notify. - Selection mode: respects `selectionSettings.mode === 'None'` to disable filter/insert options when appropriate. - Hidden rows/cols: `beforeOpenHandler` and `setHideShowItems` use `hiddenCount()` to avoid invalid hide/unhide operations. - UI gating: `beforeOpenHandler` cancels opening for targets outside supported areas. - Keyboard accessibility: `beforeCloseHandler` handles `Esc` to refocus and `preventKeyNavigation` blocks arrow keys when keyboard navigation is disabled. - Lifecycle: `destroy()` ensures event handlers and DOM nodes are cleaned up to avoid leaks. ## Desired Outputs User-facing - Contextual right-click menu tailored to the clicked area (Content, RowHeader, ColumnHeader, Footer, SelectAll). - Localized labels and icons; nested menus for filter/sort and paste special. - Dynamic enable/disable and insertion/removal of menu items by other modules. - Correct focus behavior and keyboard handling (ESC to close and refocus). System-level - Events & Notifications (used by this module): - Incoming: `addContextMenuItems`, `removeContextMenuItems`, `enableContextMenuItems` (for runtime mutation) - Outgoing / used notifications in `selectHandler`: `cut`, `copy`, `paste`, `insertModel`, `removeSheetTab`, `hideSheet`, `updateSortCollection`, `getFilteredColumn`, `renameSheetTab`, `getRowIdxFromClientY`, `getColIdxFromClientX`, `readonlyAlert`, and others mapped to specific menu actions. - Hooks for customization: `cMenuBeforeOpen` notification and `contextMenuBeforeOpen`, `contextMenuBeforeClose`, `contextMenuItemSelect` events. - DOM and CSS hooks: - Host element: `<ul id="${parent.element.id}_contextmenu">` with role `menu`. - Component CSS class: `e-spreadsheet-contextmenu`. - Item id prefix: `${parent.element.id}_cmenu`. - Integration contracts: - Consumer modules can add/remove/enable items via `addContextMenuItems`, `removeContextMenuItems`, `enableContextMenuItems` notifications. - Actions are performed by notifying existing workbook services; this module does not perform heavy state changes itself (it delegates). - Undo/Redo: operations triggered by menu items should integrate into the workbook action pipeline since underlying notifications (e.g., `insertModel`, `paste`) include `isAction`/undo hooks. ## Implementation Notes (short) - Prefer building `MenuItemModel[]` via helper setters (`setClipboardData`, `setFilterItems`, `setSortItems`, etc.) to keep `beforeOpenHandler()` concise. - Localize all visible labels using the `L10n` service. - Keep validation checks (read-only, allowInsert/allowDelete, hiddenCount) in `selectHandler` and `beforeOpenHandler` to prevent invalid commands. - Ensure `destroy()` cleans up `EventHandler` keyup listener and detaches the host `<ul>` to avoid leaks. ---