fix(keyboard): hotkey unbind incorrect (#353)

This commit is contained in:
Whitewater
2022-09-01 17:34:19 +08:00
committed by GitHub
parent 6397c3ef3f
commit f9bd53aaca
2 changed files with 68 additions and 55 deletions

View File

@@ -45,7 +45,7 @@ export class Editor implements Virgo {
private _cacheManager = new Map<string, Promise<AsyncBlock | null>>(); private _cacheManager = new Map<string, Promise<AsyncBlock | null>>();
public mouseManager = new MouseManager(this); public mouseManager = new MouseManager(this);
public selectionManager = new SelectionManager(this); public selectionManager = new SelectionManager(this);
public keyboardManager = new KeyboardManager(this); public keyboardManager: KeyboardManager;
public scrollManager = new ScrollManager(this); public scrollManager = new ScrollManager(this);
public dragDropManager = new DragDropManager(this); public dragDropManager = new DragDropManager(this);
public commands = new EditorCommands(this); public commands = new EditorCommands(this);
@@ -83,6 +83,8 @@ export class Editor implements Virgo {
if (props.isEdgeless) { if (props.isEdgeless) {
this.isEdgeless = true; this.isEdgeless = true;
} }
// Wait for rootId/isEdgeless set
this.keyboardManager = new KeyboardManager(this);
for (const [name, block] of Object.entries(props.views)) { for (const [name, block] of Object.entries(props.views)) {
services.api.editorBlock.registerContentExporter( services.api.editorBlock.registerContentExporter(
this.workspace, this.workspace,

View File

@@ -2,19 +2,19 @@ import HotKeys from 'hotkeys-js';
import { uaHelper } from '@toeverything/utils'; import { uaHelper } from '@toeverything/utils';
import { Protocol } from '@toeverything/datasource/db-service';
import { AsyncBlock, BlockEditor } from '../..'; import { AsyncBlock, BlockEditor } from '../..';
import { supportChildren } from '../../utils';
import { SelectionManager } from '../selection'; import { SelectionManager } from '../selection';
import { import {
HotKeyTypes,
HotkeyMap,
MacHotkeyMap,
WinHotkeyMap,
GlobalHotkeyMap, GlobalHotkeyMap,
GlobalMacHotkeyMap, GlobalMacHotkeyMap,
GlobalWinHotkeyMap, GlobalWinHotkeyMap,
HotkeyMap,
HotKeyTypes,
MacHotkeyMap,
WinHotkeyMap,
} from './hotkey-map'; } from './hotkey-map';
import { supportChildren } from '../../utils';
import { Protocol } from '@toeverything/datasource/db-service';
type KeyboardEventHandler = (event: KeyboardEvent) => void; type KeyboardEventHandler = (event: KeyboardEvent) => void;
export class KeyboardManager { export class KeyboardManager {
private _editor: BlockEditor; private _editor: BlockEditor;
@@ -22,8 +22,20 @@ export class KeyboardManager {
private hotkeys: HotkeyMap; private hotkeys: HotkeyMap;
private global_hotkeys: GlobalHotkeyMap; private global_hotkeys: GlobalHotkeyMap;
private handler_map: { [k: string]: Array<KeyboardEventHandler> }; private handler_map: { [k: string]: Array<KeyboardEventHandler> };
/**
* Every editor should have its own hotkey scope,
* but edgeless had multiple editor instances,
* all edgeless editors should have shared scope
*/
private hotkeyScope: string;
constructor(editor: BlockEditor) { constructor(editor: BlockEditor) {
if (editor.isEdgeless) {
// edgeless editors should have shared scope
this.hotkeyScope = 'whiteboard';
} else {
this.hotkeyScope = 'editor_' + editor.getRootBlockId();
}
this._editor = editor; this._editor = editor;
this.selection_manager = this._editor.selectionManager; this.selection_manager = this._editor.selectionManager;
if (uaHelper.isMacOs) { if (uaHelper.isMacOs) {
@@ -35,7 +47,7 @@ export class KeyboardManager {
} }
this.handler_map = {}; this.handler_map = {};
HotKeys.setScope('editor'); HotKeys.setScope(this.hotkeyScope);
// this.init_common_shortcut_cb(); // this.init_common_shortcut_cb();
this.bind_hot_key_handlers(); this.bind_hot_key_handlers();
@@ -44,43 +56,63 @@ export class KeyboardManager {
private bind_hot_key_handlers() { private bind_hot_key_handlers() {
this.bind_hotkey( this.bind_hotkey(
this.hotkeys.selectAll, this.hotkeys.selectAll,
'editor', this.hotkeyScope,
this.handle_select_all this.handle_select_all
); );
this.bind_hotkey(this.hotkeys.undo, 'editor', this.handle_undo); this.bind_hotkey(this.hotkeys.undo, this.hotkeyScope, this.handle_undo);
this.bind_hotkey(this.hotkeys.redo, 'editor', this.handle_redo); this.bind_hotkey(this.hotkeys.redo, this.hotkeyScope, this.handle_redo);
this.bind_hotkey(this.hotkeys.remove, 'editor', this.handle_remove); this.bind_hotkey(this.hotkeys.remove, 'all', this.handle_remove);
this.bind_hotkey( this.bind_hotkey(
this.hotkeys.checkUncheck, this.hotkeys.checkUncheck,
'editor', this.hotkeyScope,
this.handle_check_uncheck this.handle_check_uncheck
); );
this.bind_hotkey( this.bind_hotkey(
this.hotkeys.preExpendSelect, this.hotkeys.preExpendSelect,
'editor', this.hotkeyScope,
this.handle_pre_expend_select this.handle_pre_expend_select
); );
this.bind_hotkey( this.bind_hotkey(
this.hotkeys.nextExpendSelect, this.hotkeys.nextExpendSelect,
'editor', this.hotkeyScope,
this.handle_next_expend_select this.handle_next_expend_select
); );
this.bind_hotkey(this.hotkeys.up, 'editor', this.handle_click_up); this.bind_hotkey(
this.bind_hotkey(this.hotkeys.down, 'editor', this.handleClickDown); this.hotkeys.up,
this.bind_hotkey(this.hotkeys.left, 'editor', this.handle_click_up); this.hotkeyScope,
this.bind_hotkey(this.hotkeys.right, 'editor', this.handleClickDown); this.handle_click_up
this.bind_hotkey(this.hotkeys.mergeGroup, 'editor', this.mergeGroup); );
this.bind_hotkey(
this.hotkeys.down,
this.hotkeyScope,
this.handleClickDown
);
this.bind_hotkey(
this.hotkeys.left,
this.hotkeyScope,
this.handle_click_up
);
this.bind_hotkey(
this.hotkeys.right,
this.hotkeyScope,
this.handleClickDown
);
this.bind_hotkey(
this.hotkeys.mergeGroup,
this.hotkeyScope,
this.mergeGroup
);
this.bind_hotkey(this.hotkeys.enter, 'all', this.handleEnter); this.bind_hotkey(this.hotkeys.enter, 'all', this.handleEnter);
this.bind_hotkey(this.global_hotkeys.search, 'all', this.handle_search); this.bind_hotkey(this.global_hotkeys.search, 'all', this.handle_search);
this.bind_hotkey( this.bind_hotkey(
this.hotkeys.mergeGroupDown, this.hotkeys.mergeGroupDown,
'editor', this.hotkeyScope,
this.mergeGroupDown this.mergeGroupDown
); );
this.bind_hotkey( this.bind_hotkey(
this.hotkeys.mergeGroupUp, this.hotkeys.mergeGroupUp,
'editor', this.hotkeyScope,
this.mergeGroupUp this.mergeGroupUp
); );
} }
@@ -93,24 +125,12 @@ export class KeyboardManager {
handler.forEach(h => { handler.forEach(h => {
HotKeys(key, scope, h); HotKeys(key, scope, h);
if (!this.handler_map[key]) { if (!this.handler_map[key]) {
this.handler_map[key] = [h]; this.handler_map[key] = [];
} else {
this.handler_map[key].push(h);
} }
this.handler_map[key].push(h);
}); });
} }
/**
*
* bind global shortcut event
* @param {HotkeyMapKeys} type
* @param {KeyboardEventHandler} handler
* @memberof KeyboardManager
*/
public bind(type: HotKeyTypes, handler: KeyboardEventHandler) {
this.bind_hotkey(this.hotkeys[type], 'editor', handler);
}
/** /**
* *
* emit a shortcut event, * emit a shortcut event,
@@ -127,21 +147,12 @@ export class KeyboardManager {
} }
} }
/**
*
* unbind keyboard event
* @param {HotKeyTypes} key
* @param {KeyboardEventHandler} cb
* @memberof KeyboardManager
*/
public unbind(key: HotKeyTypes, cb: KeyboardEventHandler) {
HotKeys.unbind(key, 'editor', cb);
}
public dispose() { public dispose() {
Object.keys(this.handler_map).map(key => HotKeys.unbind(key, 'editor')); Object.entries(this.handler_map).forEach(([key, fns]) =>
fns.forEach(fn => HotKeys.unbind(key, fn))
);
this.handler_map = {}; this.handler_map = {};
HotKeys.deleteScope(this.hotkeyScope);
} }
private handle_select_all = (event: KeyboardEvent) => { private handle_select_all = (event: KeyboardEvent) => {
@@ -228,20 +239,20 @@ export class KeyboardManager {
); );
} else { } else {
// suspend(true) // suspend(true)
let textBlock = await this._editor.createBlock('text'); const textBlock = await this._editor.createBlock('text');
await selectedNode.after(textBlock); await selectedNode.after(textBlock);
this._editor.selectionManager.setActivatedNodeId(textBlock.id); this._editor.selectionManager.setActivatedNodeId(textBlock.id);
} }
} }
}; };
private mergeGroup = async (event: Event) => { private mergeGroup = async (event: Event) => {
let selectedGroup = await this.getSelectedGroups(); const selectedGroup = await this.getSelectedGroups();
this._editor.commands.blockCommands.mergeGroup(...selectedGroup); this._editor.commands.blockCommands.mergeGroup(...selectedGroup);
}; };
private mergeGroupDown = async (event: Event) => { private mergeGroupDown = async (event: Event) => {
let selectedGroup = await this.getSelectedGroups(); const selectedGroup = await this.getSelectedGroups();
if (selectedGroup.length) { if (selectedGroup.length) {
let nextGroup = await selectedGroup[ const nextGroup = await selectedGroup[
selectedGroup.length - 1 selectedGroup.length - 1
].nextSibling(); ].nextSibling();
if (nextGroup?.type === Protocol.Block.Type.group) { if (nextGroup?.type === Protocol.Block.Type.group) {
@@ -253,9 +264,9 @@ export class KeyboardManager {
} }
}; };
private mergeGroupUp = async (event: Event) => { private mergeGroupUp = async (event: Event) => {
let selectedGroup = await this.getSelectedGroups(); const selectedGroup = await this.getSelectedGroups();
if (selectedGroup.length) { if (selectedGroup.length) {
let preGroup = await selectedGroup[0].previousSibling(); const preGroup = await selectedGroup[0].previousSibling();
if (preGroup?.type === Protocol.Block.Type.group) { if (preGroup?.type === Protocol.Block.Type.group) {
this._editor.commands.blockCommands.mergeGroup( this._editor.commands.blockCommands.mergeGroup(
preGroup, preGroup,