UNPKG

@syncfusion/ej2-spreadsheet

Version:

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

100 lines (80 loc) 8.05 kB
# Image Module data flow ## What It Does Image subsystem manages insertion, rendering, positioning, persistence and lifecycle of images in the workbook. The Spreadsheet layer handles file input, UI overlays, and user-driven operations (insert/delete/resize/move). The Workbook layer persists image metadata into cell models and reapplies images when the model is imported or deserialized. Primary implementation files: `src/spreadsheet/integrations/image.ts` (UI) and `src/workbook/integrations/image.ts` (Core/WorkbookImage). ## Entry Points (UI) **Class:** `SpreadsheetImage` - Listens: `insertImage`, `refreshImgCellObj`, `createImageElement`, `deleteImage`, `refreshImagePosition`. - Key handlers: - `renderImageUpload()` — create hidden `<input type="file">` host for image selection and wire `onchange` to `imageSelect()`. - `imageSelect()` — validate file type and call `insertImage()`. - `insertImage(args)` — read file as data URL (FileReader), then call `createImageElement()`. - `createImageElement(args)` — create overlay DOM element via overlay service, compute positioning (supports frozen panes), set backgroundImage, compute `ImageModel` metadata and call `parent.notify(setImage, ...)` to persist. - `refreshImgCellObj(args)` — update cell attachments when an image is moved/resized between cells (handles undo/redo and fires `actionComplete`). - `deleteImage(args)` — locate overlay element or model, remove DOM element, remove image metadata from `CellModel.image`, and notify `completeAction`/`actionComplete` accordingly. ## Entry Points (Core) **Class:** `WorkbookImage` - Listens: `setImage`, `importModelUpdate`. - Key handlers: - `setImage(args)` — normalize sheet/range, compute anchor indexes, attach image metadata to `CellModel.image` using `setCell()`, and return flags (e.g., `isElementRemoved`). - `updateImagesFromSheet()` — on import, iterate `sheet.imageColl` and attach `ExtendedImageModel` entries into `CellModel.image` arrays. ## ASCII Core Logic Flow User selects file → Spreadsheet `imageSelect()` → read file → `insertImage()``createImageElement()` → overlay inserted & positioned → `parent.notify(setImage, {...})` ↓ `WorkbookImage.setImage()` → attach `ImageModel` to `CellModel.image` via `setCell()` (persist metadata) ↓ UI `createImageElement()` receives confirmation → overlay shown; `actionComplete`/`beginAction`/`completeAction` events fired for undo/redo integration ↓ User moves/resizes/deletes → Spreadsheet notifies `setImage`/`refreshImgCellObj`/`deleteImage` → Core updates `CellModel.image` and UI updates DOM ## Operations (functions & responsibilities) - `renderImageUpload()` (UI) - Creates hidden file input (`{id}_imageUpload`) and sets `accept` to image types; `onchange` triggers `imageSelect()`. - `imageSelect()` (UI) - Validates file MIME type; shows localized unsupported-file dialog for non-image types; calls `insertImage({ file, isAction: true })`. - `insertImage()` (UI) - Reads file via `FileReader` and resolves an object containing `dataUrl`, `width`, `height`; calls `createImageElement()` with those values. - `createImageElement()` (UI) - Computes target `range` and `sheetIndex`; ensures unique overlay id (`getUniqueID`), guards against duplicates and read-only cells (`isReadOnlyCells`), and fires `actionBegin`/`beforeInsertImage` notifications. - Uses Overlay service `insertOverlayElement(id, range, sheetIndex)` to create a positioned overlay element and sets CSS `backgroundImage` to the data URL. - Computes `ImageModel` metadata: `src`, `id`, `height`, `width`, `top`, `left` (adjusted for frozen panes and DPR via `addDPRValue`). - Calls `parent.notify(setImage, { options: [imgData], range: sheet.name + '!' + range, isPositionChanged, isElementRemoved })` to persist through core. - On public actions, fires `actionComplete`/`actionComplete` events with `insertImage` payload to integrate undo/redo and telemetry. - `refreshImgCellObj()` (UI) - Handles image re-anchor when position changes: moves metadata from prev cell to curr cell, updates `CellModel.image` via `setCell()`, and emits `actionComplete` if not undo/redo. - `deleteImage()` (UI) - Determine image by DOM id or range; compute anchor cell; fire `beginAction` (allow cancel); remove DOM element; remove metadata from `CellModel.image` and call `setCell()`; notify `completeAction`/`actionComplete` with deletion info (address, id, imageData, width/height). - `setImage()` (Core) - Resolve sheet index and target `indexes` from range; compute `cell` and attach `ImageModel[]` to `cell.image` using `setCell(...)` (true to trigger necessary notifications). - When `importModelUpdate` occurs, `updateImagesFromSheet()` attaches `sheet.imageColl` entries to cell objects. ## Validation & Safety - File validation: only image MIME types accepted; non-image files trigger localized dialog (`UnsupportedFile`). - Readonly/protected cells: `createImageElement()` checks `isReadOnlyCells` and cancels with `readonlyAlert` when insertion is not allowed. - Duplicate overlay IDs: `createImageElement()` guards against creating overlays with existing ids or when sheet/panel conditions prevent insertion. - Event cancellation: `actionBegin`/`beginAction` allow external handlers to cancel insert/delete operations; handlers check `eventArgs.cancel` before proceeding. - Frozen panes & virtualization: positioning logic accounts for frozen rows/cols (different overlay placement) and uses `getRowIdxFromClientY`/`getColIdxFromClientX` notifications to translate client coords into cell indexes. - Undo/Redo: `isUndoRedo`, `isAction`, and `preventAction` flags propagate through events (`setImage`, `actionComplete`, `completeAction`) so host pipeline can record/replay operations. - Async safety: `FileReader` operations are promise-based and UI routines guard against missing `parent` in callbacks. ## Desired Outputs User-facing - Visual overlay images placed above the grid with drag/resize handles (overlay element with unique id, backgroundImage set to data URL). - Image insertion via file dialog, paste, or programmatic API; immediate visual feedback and persisted metadata. - Deletion and repositioning reflected in the UI and persisted model; undo/redo support for image operations. System-level - Events & Notifications: - UI → Core: `setImage` (persist image metadata) - Core → UI: `importModelUpdate` triggers `updateImagesFromSheet()` to reattach persisted images - Management: `insertImage` (UI entry), `createImageElement`, `refreshImgCellObj`, `deleteImage`, `refreshImagePosition` - Action pipeline: `actionBegin`/`beginAction`, `actionComplete`/`completeAction`, and `completeAction` used for recording and notifying operation results - Model artifacts: - `CellModel.image` array stores `ImageModel` entries attached to anchor cell: `{ src, id, height, width, top, left }`. - `ExtendedSheet.imageColl` used during import to hold images that will be attached on `importModelUpdate`. - DOM / CSS hooks: - Hidden file input id: `{id}_imageUpload` for file selection. - Overlay element ids generated via `getUniqueID('{id}_overlay_picture_')` and attached via the Overlay service; overlay element style includes `backgroundImage`, `height`, `width`, `top`, `left`. - Use notifications `getRowIdxFromClientY`, `getColIdxFromClientX` to map overlay positions to cell indexes. ## Implementation Notes (short) - Keep responsibilities split: Spreadsheet layer handles file I/O, overlay positioning and DOM; Workbook layer persists metadata and reattaches images on import. - Always run `parent.notify(setImage, ...)` after creating/updating overlay metadata so the core and serialization layers stay in sync. - Use `actionBegin`/`actionComplete` to integrate undo/redo and allow external cancellation or augmentation of image operations. - Guard against readonly/locked cells and frozen-pane placement edge cases when computing `top`/`left`. ---