@syncfusion/ej2-spreadsheet
Version:
Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel
114 lines (94 loc) • 6.2 kB
Markdown
# Clipboard Module data flow
## What It Does
Provides cut/copy/paste support for the Spreadsheet including:
- Internal range copy/cut (cells, rows/cols, shapes/charts).
- External clipboard interoperability (HTML table, plain text, images).
- Paste special modes, copy-indicator UI, and integration with ribbon/context-menu.
- Maintains state for cut vs copy, handles move (cut) semantics and UI updates.
## Entry Points
**Clipboard Class**
- `constructor(parent: Spreadsheet)` — initializes clipboard input and listeners.
- `setCopiedInfo(args?, isCut?)` — record copied/cut range or shapes (creates `copiedInfo` / `copiedShapeInfo`).
- `cut(args?)`, `copy(args?)` — public triggers for cut/copy flows.
- `paste(args?)` — main paste entry, handles internal/external paste, paste special, and move semantics.
- `getExternalCells(args)`, `setExternalCells(args, isCut?)` — convert between Spreadsheet model and HTML/image clipboard formats.
- `generateCells(ele, pasteModelArgs)` — parse HTML table into `PasteModelArgs`.
- `imageToCanvas(src, height, width)`, `addImgToClipboard(src, height, width)` — image -> Blob -> write to system clipboard.
- UI helpers: `initCopyIndicator()`, `getCopyIndicator()`, `showDialog()`, `hidePaste()`, `clearCopiedInfo()`.
- Lifecycle: `addEventListener()`, `removeEventListener()`, `destroy()`.
## Core Logic Flow
```
User Action (Cut/Copy via keyboard/ribbon/context/menu/programmatic)
↓
setCopiedInfo() -> store copiedInfo or copiedShapeInfo + show copy indicator
↓
If external clipboard target requested -> setExternalCells() (serialize to HTML/table or image)
↓
User Action (Paste via keyboard/ribbon/context/menu/programmatic) OR external paste event
↓
paste():
- detect external vs internal (clipboardData vs copiedInfo)
- if external: getExternalCells() -> build PasteModelArgs
- if internal: use copiedInfo/copiedShapeInfo
- compute destination range, pasteType, repeat/transpose options
- validate (read-only, protected, merged, uncalculated formulas)
- apply cells via setCell() callback -> update workbook model
- handle cut semantics (remove source), update filters/conditional formats/merge
- UI refresh: selection, copy-indicator, paste-enabled state
↓
Complete (deferred/promises used for async operations like formula calc or image conversion)
```
## Operations Handled
1. Initialization & Event Wiring
- Create hidden editable clipboard input element.
- Hook native `cut/copy/paste` events and spreadsheet notifications (ribbon, context-menu, tab switch, contentLoaded, row/col changes, refreshClipboard).
2. Copy/Cut State Management
- `copiedInfo`: `{ range: number[], sId: number, isCut: boolean, ... }`.
- `copiedShapeInfo`: holds shape/chart element, dimensions, sheet index, isCut, copiedRange.
- Add/remove visual copy-indicator overlay; clear state on operations or navigation.
3. External Serialization (Spreadsheet -> Clipboard)
- `setExternalCells()` builds an HTML `<table>` with inline styles for selected range (values, formats, row heights, column widths).
- Support for full-row / full-column selections and shape/image copying.
- IE fallback vs modern Clipboard API path.
4. External Parsing (Clipboard -> Spreadsheet)
- `getExternalCells()` reads HTML or plain text from `clipboardData`, or files/images.
- `generateCells()` converts `<table>` DOM into `PasteModelArgs` (rows, cells, styles).
- `cellStyle()` / `generateStyles()` map inline CSS -> cell style objects.
5. Image Clipboard Support
- Convert image URLs to canvas, then to Blob (`imageToCanvas`) and write using `navigator.clipboard.write`.
- Accept pasted image files and insert into sheet.
6. Paste Orchestration
- Determine whether paste is internal/external; set `args.isInternal`.
- Compute paste destination (single cell, repeat, grid), handle paste special types (All/Values/Formats/etc).
- Respect sheet protection, read-only cells, merged ranges; show dialog/abort when invalid.
- Apply changes via `setCell` callback for each cell, using deferred promise for async formula evaluation.
7. Cut/Move Semantics & Post-Paste Updates
- For cuts, remove source cells after successful paste.
- Update dependent features: filters (`updateFilter()`), conditional formats (`setCF()`), merged ranges, charts/shapes positions, row/col sizes.
- Refresh clipboard state on insert/delete operations (`refreshOnInsertDelete`).
8. UX + Integration
- Enable/disable ribbon/context-menu paste items based on `copiedInfo`.
- Hide paste option on tab switch or when nothing copied.
- Show paste alert dialog for invalid operations.
## Validation & Safety
- Prevent operations while editing (`parent.isEdit`) or when modal overlays exist.
- Block cut/copy/paste on protected sheets or locked/read-only cells; show paste alert when needed.
- Detect and prevent multiple concurrent cut-paste sequences (internal vs external flags).
- Handle merged ranges carefully (prevent partial merges or abort with message).
- Check for uncalculated formulas before copying dependent ranges.
- Browser compatibility fallbacks for clipboard APIs (IE vs modern navigator.clipboard).
- Use promise/deferred flow for async tasks to avoid race conditions.
## Desired Outputs
User-Facing:
- Keyboard + context-menu + ribbon cut/copy/paste that behave like Excel.
- Paste Special options and enabled/disabled state per selection.
- Copy indicator highlight around copied range.
- Support for pasting external HTML tables and images.
- Informative dialog when paste is not allowed.
System-Level:
- `copiedInfo` and `copiedShapeInfo` state objects for internal moves/copies.
- HTML serialization format for external clipboard interoperability.
- `PasteModelArgs` structure produced by `getExternalCells()` / `generateCells()`.
- Notifications/hooks: paste/refreshClipboard, enableToolbarItems, setFilteredCollection (used during updates).
- Async-safe flows (Deferred/Promise) for formula evaluation and image conversion.
- Clean lifecycle: event registration, `destroy()` to remove listeners and DOM artifacts.