diff --git a/common/changes/@visactor/vtable/fix-5290-image-null-preview_2026-08-25-17-50.json b/common/changes/@visactor/vtable/fix-5290-image-null-preview_2026-08-25-17-50.json new file mode 100644 index 000000000..f2900f0db --- /dev/null +++ b/common/changes/@visactor/vtable/fix-5290-image-null-preview_2026-08-25-17-50.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "fix: prevent empty image, audio, and video cells from opening media previews (GitHub #5290)", + "type": "patch", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "108231307+dajiaohuang@users.noreply.github.com" +} diff --git a/packages/vtable/__tests__/media-click.test.ts b/packages/vtable/__tests__/media-click.test.ts new file mode 100644 index 000000000..72b7c908d --- /dev/null +++ b/packages/vtable/__tests__/media-click.test.ts @@ -0,0 +1,39 @@ +import { bindMediaClick } from '../src/event/media-click'; +import { Env, type EnvMode } from '../src/tools/env'; +import type { MousePointerCellEvent } from '../src/ts-types'; +import type { BaseTableAPI } from '../src/ts-types/base-table'; + +describe('bindMediaClick', () => { + let originalMode: EnvMode; + + beforeEach(() => { + originalMode = Env.mode; + Env.mode = 'browser'; + document.body.innerHTML = ''; + }); + + afterEach(() => { + Env.mode = originalMode; + document.body.innerHTML = ''; + }); + + test.each(['image', 'audio', 'video'] as const)('does not open a %s preview for an empty cell', cellType => { + let clickHandler: ((event: MousePointerCellEvent) => void) | undefined; + const table = { + addReleaseObj: jest.fn(), + on: jest.fn((_event: string, handler: (event: MousePointerCellEvent) => void) => { + clickHandler = handler; + }), + getCellType: jest.fn(() => cellType), + isHeader: jest.fn(() => false), + getBodyColumnDefine: jest.fn(() => ({ clickToPreview: true })), + getCellValue: jest.fn(() => null), + getCellOriginValue: jest.fn(() => null) + } as unknown as BaseTableAPI; + + bindMediaClick(table); + clickHandler?.({ col: 0, row: 0, target: { type: 'rect' } } as MousePointerCellEvent); + + expect(document.body.childElementCount).toBe(0); + }); +}); diff --git a/packages/vtable/src/event/media-click.ts b/packages/vtable/src/event/media-click.ts index 263489677..25819d5ca 100644 --- a/packages/vtable/src/event/media-click.ts +++ b/packages/vtable/src/event/media-click.ts @@ -339,6 +339,9 @@ export function bindMediaClick(table: BaseTableAPI): void { if (clickToPreview === false) { return; } + if (!cellValue) { + return; + } const previewManager = getMediaPreviewManager(table); // 开启蒙版 @@ -390,6 +393,9 @@ export function bindMediaClick(table: BaseTableAPI): void { if (clickToPreview === false) { return; } + if (!cellValue) { + return; + } const previewManager = getMediaPreviewManager(table); // 开启蒙版 @@ -431,6 +437,9 @@ export function bindMediaClick(table: BaseTableAPI): void { if (clickToPreview === false) { return; } + if (!cellValue) { + return; + } const previewManager = getMediaPreviewManager(table); // 开启蒙版