From cea0a564e793414897acdab821c3f1d247e4e141 Mon Sep 17 00:00:00 2001 From: doouding Date: Thu, 19 Dec 2024 06:38:37 +0000 Subject: [PATCH] fix: keyboard controller should attach event on document (#8801) --- .../widgets/pie-menu/pie-manager.ts | 9 ++-- .../framework/block-std/src/gfx/keyboard.ts | 28 +++++++----- tests/multiple-editors/edgeless.spec.ts | 43 +++++++++++++++++++ tests/utils/actions/edgeless.ts | 11 +++++ 4 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 tests/multiple-editors/edgeless.spec.ts diff --git a/packages/blocks/src/root-block/widgets/pie-menu/pie-manager.ts b/packages/blocks/src/root-block/widgets/pie-menu/pie-manager.ts index 79102ad9aecb..dacaecaa270b 100644 --- a/packages/blocks/src/root-block/widgets/pie-menu/pie-manager.ts +++ b/packages/blocks/src/root-block/widgets/pie-menu/pie-manager.ts @@ -1,4 +1,4 @@ -import { assertExists, assertNotExists } from '@blocksuite/global/utils'; +import { assertExists } from '@blocksuite/global/utils'; import { Slot } from '@blocksuite/store'; import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js'; @@ -53,10 +53,9 @@ export class PieManager { private static _register(schema: PieMenuSchema) { const { id } = schema; - assertNotExists( - this.registeredSchemas[id], - `Menu with id '${id}' already exists. Please provide a unique id` - ); + if (this.registeredSchemas[id]) { + return; + } this.registeredSchemas[id] = schema; } diff --git a/packages/framework/block-std/src/gfx/keyboard.ts b/packages/framework/block-std/src/gfx/keyboard.ts index dbce915d63ac..0eda0e4196ce 100644 --- a/packages/framework/block-std/src/gfx/keyboard.ts +++ b/packages/framework/block-std/src/gfx/keyboard.ts @@ -16,27 +16,35 @@ export class KeyboardController { private _init() { this._disposable.add( - this.std.event.add('keyDown', evt => { - const state = evt.get('keyboardState'); - - this.shiftKey$.value = state.raw.shiftKey && state.raw.key === 'Shift'; - this.spaceKey$.value = state.raw.code === 'Space'; + this._listenKeyboard('keydown', evt => { + this.shiftKey$.value = evt.shiftKey && evt.key === 'Shift'; + this.spaceKey$.value = evt.code === 'Space'; }) ); this._disposable.add( - this.std.event.add('keyUp', evt => { - const state = evt.get('keyboardState'); - - this.shiftKey$.value = state.raw.shiftKey && state.raw.key === 'Shift'; + this._listenKeyboard('keyup', evt => { + this.shiftKey$.value = + evt.shiftKey && evt.key === 'Shift' ? true : false; - if (state.raw.code === 'Space') { + if (evt.code === 'Space') { this.spaceKey$.value = false; } }) ); } + private _listenKeyboard( + event: 'keydown' | 'keyup', + callback: (keyboardEvt: KeyboardEvent) => void + ) { + document.addEventListener(event, callback, false); + + return () => { + document.removeEventListener(event, callback, false); + }; + } + dispose() { this._disposable.dispose(); } diff --git a/tests/multiple-editors/edgeless.spec.ts b/tests/multiple-editors/edgeless.spec.ts new file mode 100644 index 000000000000..fa3d88fb02b4 --- /dev/null +++ b/tests/multiple-editors/edgeless.spec.ts @@ -0,0 +1,43 @@ +import { expect } from '@playwright/test'; + +import { + switchMultipleEditorsMode, + toggleMultipleEditors, +} from '../utils/actions/edgeless.js'; +import { + enterPlaygroundRoom, + initEmptyEdgelessState, + initThreeParagraphs, + waitNextFrame, +} from '../utils/actions/misc.js'; +import { test } from '../utils/playwright.js'; + +test('the shift pressing status should effect all editors', async ({ + page, +}) => { + await enterPlaygroundRoom(page); + await initEmptyEdgelessState(page); + await initThreeParagraphs(page); + await toggleMultipleEditors(page); + await switchMultipleEditorsMode(page); + + await waitNextFrame(page, 5000); + + const getShiftPressedStatus = async () => { + return page.evaluate(() => { + const edgelessBlocks = document.querySelectorAll('affine-edgeless-root'); + + return Array.from(edgelessBlocks).map(edgelessRoot => { + return edgelessRoot.gfx.keyboard.shiftKey$.peek(); + }); + }); + }; + + await page.keyboard.down('Shift'); + const pressed = await getShiftPressedStatus(); + expect(pressed).toEqual([true, true]); + + await page.keyboard.up('Shift'); + const released = await getShiftPressedStatus(); + expect(released).toEqual([false, false]); +}); diff --git a/tests/utils/actions/edgeless.ts b/tests/utils/actions/edgeless.ts index 61b2b07d8212..100ac10ceed9 100644 --- a/tests/utils/actions/edgeless.ts +++ b/tests/utils/actions/edgeless.ts @@ -128,6 +128,17 @@ export async function switchEditorMode(page: Page) { await waitNextFrame(page); } +export async function switchMultipleEditorsMode(page: Page) { + await page.evaluate(() => { + const containers = document.querySelectorAll('affine-editor-container'); + const mode = containers[0].mode === 'edgeless' ? 'page' : 'edgeless'; + + containers.forEach(container => { + container.mode = mode; + }); + }); +} + export async function switchEditorEmbedMode(page: Page) { await page.click('sl-button:text("Test Operations")'); await page.click('sl-menu-item:text("Switch Offset Mode")');