From 88400b92b6e01f8dfd6e34a7874e7cc7b2e1a013 Mon Sep 17 00:00:00 2001 From: lijinke666 Date: Wed, 28 Feb 2024 19:01:33 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=95=B0=E5=80=BC?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=A0=BC=E5=86=85=E7=9A=84=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=20icon=20=E7=82=B9=E5=87=BB=E6=97=B6=E4=BC=9A?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E5=8D=95=E5=85=83=E6=A0=BC=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../s2-core/__tests__/bugs/issue-1520-spec.ts | 4 +- .../s2-core/__tests__/bugs/issue-292-spec.ts | 3 +- .../s2-core/__tests__/bugs/issue-368-spec.ts | 7 +-- .../s2-core/__tests__/bugs/issue-446-spec.ts | 3 +- .../s2-core/__tests__/bugs/issue-507-spec.ts | 6 +-- .../s2-core/__tests__/bugs/issue-511-spec.ts | 3 +- .../s2-core/__tests__/bugs/issue-868-spec.ts | 3 +- .../unit/interaction/event-controller-spec.ts | 51 +++++++++++++++++++ .../src/common/constant/events/basic.ts | 2 +- packages/s2-core/src/common/icons/gui-icon.ts | 1 - .../src/interaction/event-controller.ts | 36 ++++++------- 11 files changed, 88 insertions(+), 31 deletions(-) diff --git a/packages/s2-core/__tests__/bugs/issue-1520-spec.ts b/packages/s2-core/__tests__/bugs/issue-1520-spec.ts index 5c39453962..42529edc0d 100644 --- a/packages/s2-core/__tests__/bugs/issue-1520-spec.ts +++ b/packages/s2-core/__tests__/bugs/issue-1520-spec.ts @@ -6,9 +6,9 @@ import { getContainer } from '../util/helpers'; import * as mockDataConfig from '../data/data-issue-1520.json'; import { PivotSheet, SpreadSheet } from '@/sheet-type'; -import { GuiIcon } from '@/common'; +import { GuiIcon, type S2Options } from '@/common'; -const s2Options = { +const s2Options: S2Options = { width: 800, height: 600, conditions: { diff --git a/packages/s2-core/__tests__/bugs/issue-292-spec.ts b/packages/s2-core/__tests__/bugs/issue-292-spec.ts index c594f41c6d..6e9075ebda 100644 --- a/packages/s2-core/__tests__/bugs/issue-292-spec.ts +++ b/packages/s2-core/__tests__/bugs/issue-292-spec.ts @@ -6,9 +6,10 @@ */ import { getContainer } from '../util/helpers'; import * as mockDataConfig from '../data/data-issue-292.json'; +import type { S2Options } from '../../src'; import { PivotSheet } from '@/sheet-type'; -const s2Options = { +const s2Options: S2Options = { width: 800, height: 600, }; diff --git a/packages/s2-core/__tests__/bugs/issue-368-spec.ts b/packages/s2-core/__tests__/bugs/issue-368-spec.ts index 13811f313c..816ca548b1 100644 --- a/packages/s2-core/__tests__/bugs/issue-368-spec.ts +++ b/packages/s2-core/__tests__/bugs/issue-368-spec.ts @@ -4,11 +4,12 @@ * Wrong style when show the totals in multi-value mode * */ +import type { S2Options } from '../../src'; import * as mockDataConfig from '../data/data-issue-368.json'; import { getContainer } from '../util/helpers'; import { PivotSheet, SpreadSheet } from '@/sheet-type'; -const s2Options = { +const s2Options: S2Options = { width: 800, height: 600, totals: { @@ -32,7 +33,7 @@ const s2Options = { describe('Total Cells Rendering Test', () => { let s2: SpreadSheet; - beforeAll(async () => { + beforeEach(async () => { s2 = new PivotSheet(getContainer(), mockDataConfig, s2Options); await s2.render(); @@ -66,7 +67,7 @@ describe('Total Cells Rendering Test', () => { totals: { ...s2Options.totals, row: { - ...s2Options.totals.row, + ...s2Options.totals!.row, subTotalsDimensions: ['row0'], }, }, diff --git a/packages/s2-core/__tests__/bugs/issue-446-spec.ts b/packages/s2-core/__tests__/bugs/issue-446-spec.ts index a3c838222b..f168ed5553 100644 --- a/packages/s2-core/__tests__/bugs/issue-446-spec.ts +++ b/packages/s2-core/__tests__/bugs/issue-446-spec.ts @@ -6,10 +6,11 @@ */ import { getContainer } from '../util/helpers'; import * as mockDataConfig from '../data/data-issue-446.json'; +import type { S2Options } from '../../src'; import { TableSheet } from '@/sheet-type'; import { asyncGetAllPlainData } from '@/utils'; -const s2Options = { +const s2Options: S2Options = { width: 800, height: 600, seriesNumber: { diff --git a/packages/s2-core/__tests__/bugs/issue-507-spec.ts b/packages/s2-core/__tests__/bugs/issue-507-spec.ts index e46ca13207..e05898ce9b 100644 --- a/packages/s2-core/__tests__/bugs/issue-507-spec.ts +++ b/packages/s2-core/__tests__/bugs/issue-507-spec.ts @@ -57,15 +57,15 @@ describe('Spreadsheet Empty Test', () => { }); test('should render skeleton when tree sheet in the valueInCols mode', async () => { - const valueInColstreeS2 = new PivotSheet( + const valueInColsTreeS2 = new PivotSheet( getContainer(), valueInCols, treeOptions, ); - await valueInColstreeS2.render(); + await valueInColsTreeS2.render(); - const layoutResult = valueInColstreeS2.facet.getLayoutResult(); + const layoutResult = valueInColsTreeS2.facet.getLayoutResult(); expect(layoutResult.colNodes).toHaveLength(5); expect(layoutResult.rowNodes).toBeEmpty(); diff --git a/packages/s2-core/__tests__/bugs/issue-511-spec.ts b/packages/s2-core/__tests__/bugs/issue-511-spec.ts index fba061bcd8..6da5de900b 100644 --- a/packages/s2-core/__tests__/bugs/issue-511-spec.ts +++ b/packages/s2-core/__tests__/bugs/issue-511-spec.ts @@ -5,9 +5,10 @@ */ import { getContainer } from '../util/helpers'; import * as mockDataConfig from '../data/data-issue-511.json'; +import type { S2Options } from '../../src'; import { PivotSheet } from '@/sheet-type'; -const s2Options = { +const s2Options: S2Options = { width: 800, height: 600, }; diff --git a/packages/s2-core/__tests__/bugs/issue-868-spec.ts b/packages/s2-core/__tests__/bugs/issue-868-spec.ts index 10c4552a4d..9b7cac6a4c 100644 --- a/packages/s2-core/__tests__/bugs/issue-868-spec.ts +++ b/packages/s2-core/__tests__/bugs/issue-868-spec.ts @@ -6,9 +6,10 @@ import { getContainer } from '../util/helpers'; import * as mockDataConfig from '../data/data-issue-868.json'; +import type { S2Options } from '../../src'; import { PivotSheet } from '@/sheet-type'; -const s2Options = { +const s2Options: S2Options = { width: 800, height: 600, }; diff --git a/packages/s2-core/__tests__/unit/interaction/event-controller-spec.ts b/packages/s2-core/__tests__/unit/interaction/event-controller-spec.ts index a884abaad5..53fe0ac806 100644 --- a/packages/s2-core/__tests__/unit/interaction/event-controller-spec.ts +++ b/packages/s2-core/__tests__/unit/interaction/event-controller-spec.ts @@ -874,6 +874,8 @@ describe('Interaction Event Controller Tests', () => { { cellType: CellType.ROW_CELL, event: S2Event.ROW_CELL_CLICK }, { cellType: CellType.COL_CELL, event: S2Event.COL_CELL_CLICK }, { cellType: CellType.CORNER_CELL, event: S2Event.CORNER_CELL_CLICK }, + { cellType: CellType.DATA_CELL, event: S2Event.DATA_CELL_CLICK }, + { cellType: CellType.MERGED_CELL, event: S2Event.MERGED_CELLS_CLICK }, ])( 'should not trigger click event if event target is gui icon image shape for event %o', async ({ cellType, event }) => { @@ -881,6 +883,7 @@ describe('Interaction Event Controller Tests', () => { ({ cellType, getMeta: () => {}, + getConditionIconShapes: () => [], }) as any; const handler = jest.fn(); @@ -926,6 +929,8 @@ describe('Interaction Event Controller Tests', () => { { cellType: CellType.ROW_CELL, event: S2Event.ROW_CELL_CLICK }, { cellType: CellType.COL_CELL, event: S2Event.COL_CELL_CLICK }, { cellType: CellType.CORNER_CELL, event: S2Event.CORNER_CELL_CLICK }, + { cellType: CellType.DATA_CELL, event: S2Event.DATA_CELL_CLICK }, + { cellType: CellType.MERGED_CELL, event: S2Event.MERGED_CELLS_CLICK }, ])( 'should trigger click event if event target is custom image shape for event %o', ({ cellType, event }) => { @@ -933,6 +938,7 @@ describe('Interaction Event Controller Tests', () => { ({ cellType, getMeta: () => {}, + getConditionIconShapes: () => [], }) as any; const handler = jest.fn(); @@ -961,6 +967,51 @@ describe('Interaction Event Controller Tests', () => { }, ); + test.each([ + { cellType: CellType.ROW_CELL, event: S2Event.ROW_CELL_CLICK }, + { cellType: CellType.COL_CELL, event: S2Event.COL_CELL_CLICK }, + { cellType: CellType.CORNER_CELL, event: S2Event.CORNER_CELL_CLICK }, + { cellType: CellType.DATA_CELL, event: S2Event.DATA_CELL_CLICK }, + { cellType: CellType.MERGED_CELL, event: S2Event.MERGED_CELLS_CLICK }, + ])( + 'should trigger click event if event target is condition icon image shape for event %o', + async ({ cellType, event }) => { + const guiIcon = new GuiIcon({ + name: 'SortUp', + width: 10, + height: 10, + }); + + spreadsheet.getCell = () => + ({ + cellType, + getMeta: () => {}, + // 模拟当前的 target 是字段标记的 icon + getConditionIconShapes: () => [guiIcon], + }) as any; + + const handler = jest.fn(); + + await sleep(200); // 图片加载 + + spreadsheet.container.appendChild(guiIcon); // 加入 g 渲染树才有事件传递 + spreadsheet.once(event, handler); + + // 内部的 GuiIcon + const { iconImageShape } = guiIcon; + + Object.defineProperty(eventController, 'target', { + value: iconImageShape, + writable: true, + }); + iconImageShape.dispatchEvent( + createFederatedPointerEvent(spreadsheet, OriginEventType.POINTER_UP), + ); + + expect(handler).toHaveBeenCalledTimes(1); + }, + ); + // https://github.com/antvis/S2/issues/2170 test('should not reset if tooltip content clicked', () => { const reset = jest.fn(); diff --git a/packages/s2-core/src/common/constant/events/basic.ts b/packages/s2-core/src/common/constant/events/basic.ts index fcda31b006..d48bfe21bb 100644 --- a/packages/s2-core/src/common/constant/events/basic.ts +++ b/packages/s2-core/src/common/constant/events/basic.ts @@ -56,7 +56,7 @@ export enum S2Event { MERGED_CELLS_HOVER = 'merged-cells:hover', MERGED_CELLS_CLICK = 'merged-cells:click', MERGED_CELLS_DOUBLE_CLICK = 'merged-cells:double-click', - MERGED_CELLS_CONTEXT_MENU = 'merged-cell:context-menu', + MERGED_CELLS_CONTEXT_MENU = 'merged-cells:context-menu', MERGED_CELLS_MOUSE_DOWN = 'merged-cells:mouse-down', MERGED_CELLS_MOUSE_UP = 'merged-cells:mouse-up', MERGED_CELLS_MOUSE_MOVE = 'merged-cells:mouse-move', diff --git a/packages/s2-core/src/common/icons/gui-icon.ts b/packages/s2-core/src/common/icons/gui-icon.ts index fbadf71bf6..590e57ad6e 100644 --- a/packages/s2-core/src/common/icons/gui-icon.ts +++ b/packages/s2-core/src/common/icons/gui-icon.ts @@ -56,7 +56,6 @@ export class GuiIcon extends Group { const img = new Image(); - // 成功 img.onload = () => { ImageCache[cacheKey] = img; resolve(img); diff --git a/packages/s2-core/src/interaction/event-controller.ts b/packages/s2-core/src/interaction/event-controller.ts index 56e753b24f..4a93b3b6c2 100644 --- a/packages/s2-core/src/interaction/event-controller.ts +++ b/packages/s2-core/src/interaction/event-controller.ts @@ -15,7 +15,7 @@ import { S2Event, SHAPE_STYLE_MAP, } from '../common/constant'; -import type { EmitterType, ResizeInfo } from '../common/interface'; +import type { EmitterType, ResizeInfo, S2CellType } from '../common/interface'; import { CustomImage } from '../engine'; import type { SpreadSheet } from '../sheet-type'; import { getSelectedData } from '../utils/export/copy'; @@ -118,6 +118,15 @@ export class EventController { return target instanceof CustomImage && target.imgType === GuiIcon.type; }; + private isConditionIconShape = ( + target: CanvasEvent['target'], + cell: S2CellType, + ) => { + return cell + .getConditionIconShapes() + .some((shape) => shape?.name === (target as Group)?.attributes?.name); + }; + // Windows and Mac OS private onKeyboardCopy(event: KeyboardEvent) { const { copy } = this.spreadsheet.options.interaction!; @@ -469,34 +478,27 @@ export class EventController { if (cell) { const cellType = cell.cellType; - // target相同,说明是一个cell内的 click 事件 + // target 相同,说明是一个 cell 内的 click 事件 if (this.target === event.target) { - const isGuiIconShape = this.isGuiIconShape(event.target); + // 屏蔽 actionIcons 的点击,字段标记增加的 icon 除外. + if ( + this.isGuiIconShape(event.target) && + !this.isConditionIconShape(event.target, cell) + ) { + return; + } switch (cellType) { case CellType.DATA_CELL: this.spreadsheet.emit(S2Event.DATA_CELL_CLICK, event); break; case CellType.ROW_CELL: - // 屏蔽 actionIcons 的点击,只有 HeaderCells 需要, DataCell 有状态类 icon, 不需要屏蔽 - if (isGuiIconShape) { - break; - } - this.spreadsheet.emit(S2Event.ROW_CELL_CLICK, event); break; case CellType.COL_CELL: - if (isGuiIconShape) { - break; - } - this.spreadsheet.emit(S2Event.COL_CELL_CLICK, event); break; case CellType.CORNER_CELL: - if (isGuiIconShape) { - break; - } - this.spreadsheet.emit(S2Event.CORNER_CELL_CLICK, event); break; case CellType.MERGED_CELL: @@ -507,7 +509,7 @@ export class EventController { } } - // 通用的mouseup事件 + // 通用的 mouseup 事件 switch (cellType) { case CellType.DATA_CELL: this.spreadsheet.emit(S2Event.DATA_CELL_MOUSE_UP, event);