chore(bidi): use original key name when computing bidi value
Use orignal key name from the API, to not lose information due to double mapping. We previously switched to using code for pw -> bidi mapping(https://github.com/microsoft/playwright/pull/34246), but it does not work for `H` and `h`: ``` ControlLeft => code:ControlLeft key:Control ControlRight => code:ControlRight key:Control H => code:KeyH key:H h => code:KeyH key:h ```
This commit is contained in:
parent
454b6f938d
commit
ef4b4043c3
|
|
@ -31,16 +31,15 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
|||
this._session = session;
|
||||
}
|
||||
|
||||
async keydown(modifiers: Set<types.KeyboardModifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void> {
|
||||
async keydown(modifiers: Set<types.KeyboardModifier>, keyName: string, description: input.KeyDescription, autoRepeat: boolean): Promise<void> {
|
||||
const actions: bidi.Input.KeySourceAction[] = [];
|
||||
actions.push({ type: 'keyDown', value: getBidiKeyValue(code) });
|
||||
// TODO: add modifiers?
|
||||
actions.push({ type: 'keyDown', value: getBidiKeyValue(keyName) });
|
||||
await this._performActions(actions);
|
||||
}
|
||||
|
||||
async keyup(modifiers: Set<types.KeyboardModifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise<void> {
|
||||
async keyup(modifiers: Set<types.KeyboardModifier>, keyName: string, description: input.KeyDescription): Promise<void> {
|
||||
const actions: bidi.Input.KeySourceAction[] = [];
|
||||
actions.push({ type: 'keyUp', value: getBidiKeyValue(code) });
|
||||
actions.push({ type: 'keyUp', value: getBidiKeyValue(keyName) });
|
||||
await this._performActions(actions);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,18 +7,18 @@
|
|||
|
||||
/* eslint-disable curly */
|
||||
|
||||
export const getBidiKeyValue = (code: string) => {
|
||||
switch (code) {
|
||||
export const getBidiKeyValue = (keyName: string) => {
|
||||
switch (keyName) {
|
||||
case '\r':
|
||||
case '\n':
|
||||
code = 'Enter';
|
||||
keyName = 'Enter';
|
||||
break;
|
||||
}
|
||||
// Measures the number of code points rather than UTF-16 code units.
|
||||
if ([...code].length === 1) {
|
||||
return code;
|
||||
if ([...keyName].length === 1) {
|
||||
return keyName;
|
||||
}
|
||||
switch (code) {
|
||||
switch (keyName) {
|
||||
case 'Cancel':
|
||||
return '\uE001';
|
||||
case 'Help':
|
||||
|
|
@ -228,6 +228,6 @@ export const getBidiKeyValue = (code: string) => {
|
|||
case 'Quote':
|
||||
return '"';
|
||||
default:
|
||||
throw new Error(`Unknown key: "${code}"`);
|
||||
throw new Error(`Unknown key: "${keyName}"`);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -50,14 +50,15 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
|||
return commands.map(c => c.substring(0, c.length - 1));
|
||||
}
|
||||
|
||||
async keydown(modifiers: Set<types.KeyboardModifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void> {
|
||||
async keydown(modifiers: Set<types.KeyboardModifier>, keyName: string, description: input.KeyDescription, autoRepeat: boolean): Promise<void> {
|
||||
const { code, key, location, text } = description;
|
||||
if (code === 'Escape' && await this._dragManger.cancelDrag())
|
||||
return;
|
||||
const commands = this._commandsForCode(code, modifiers);
|
||||
await this._client.send('Input.dispatchKeyEvent', {
|
||||
type: text ? 'keyDown' : 'rawKeyDown',
|
||||
modifiers: toModifiersMask(modifiers),
|
||||
windowsVirtualKeyCode: keyCodeWithoutLocation,
|
||||
windowsVirtualKeyCode: description.keyCodeWithoutLocation,
|
||||
code,
|
||||
commands,
|
||||
key,
|
||||
|
|
@ -69,12 +70,13 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
|||
});
|
||||
}
|
||||
|
||||
async keyup(modifiers: Set<types.KeyboardModifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise<void> {
|
||||
async keyup(modifiers: Set<types.KeyboardModifier>, keyName: string, description: input.KeyDescription): Promise<void> {
|
||||
const { code, key, location } = description;
|
||||
await this._client.send('Input.dispatchKeyEvent', {
|
||||
type: 'keyUp',
|
||||
modifiers: toModifiersMask(modifiers),
|
||||
key,
|
||||
windowsVirtualKeyCode: keyCodeWithoutLocation,
|
||||
windowsVirtualKeyCode: description.keyCodeWithoutLocation,
|
||||
code,
|
||||
location
|
||||
});
|
||||
|
|
|
|||
|
|
@ -61,13 +61,15 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
|||
this._client = client;
|
||||
}
|
||||
|
||||
async keydown(modifiers: Set<types.KeyboardModifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void> {
|
||||
async keydown(modifiers: Set<types.KeyboardModifier>, keyName: string, description: input.KeyDescription, autoRepeat: boolean): Promise<void> {
|
||||
let text = description.text;
|
||||
// Firefox will figure out Enter by itself
|
||||
if (text === '\r')
|
||||
text = '';
|
||||
const { code, key, location } = description;
|
||||
await this._client.send('Page.dispatchKeyEvent', {
|
||||
type: 'keydown',
|
||||
keyCode: keyCodeWithoutLocation,
|
||||
keyCode: description.keyCodeWithoutLocation,
|
||||
code,
|
||||
key,
|
||||
repeat: autoRepeat,
|
||||
|
|
@ -76,11 +78,12 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
|||
});
|
||||
}
|
||||
|
||||
async keyup(modifiers: Set<types.KeyboardModifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise<void> {
|
||||
async keyup(modifiers: Set<types.KeyboardModifier>, keyName: string, description: input.KeyDescription): Promise<void> {
|
||||
const { code, key, location } = description;
|
||||
await this._client.send('Page.dispatchKeyEvent', {
|
||||
type: 'keyup',
|
||||
key,
|
||||
keyCode: keyCodeWithoutLocation,
|
||||
keyCode: description.keyCodeWithoutLocation,
|
||||
code,
|
||||
location,
|
||||
repeat: false
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import type { CallMetadata } from './instrumentation';
|
|||
|
||||
export const keypadLocation = keyboardLayout.keypadLocation;
|
||||
|
||||
type KeyDescription = {
|
||||
export type KeyDescription = {
|
||||
keyCode: number,
|
||||
keyCodeWithoutLocation: number,
|
||||
key: string,
|
||||
|
|
@ -35,8 +35,8 @@ type KeyDescription = {
|
|||
const kModifiers: types.KeyboardModifier[] = ['Alt', 'Control', 'Meta', 'Shift'];
|
||||
|
||||
export interface RawKeyboard {
|
||||
keydown(modifiers: Set<types.KeyboardModifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void>;
|
||||
keyup(modifiers: Set<types.KeyboardModifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise<void>;
|
||||
keydown(modifiers: Set<types.KeyboardModifier>, keyName: string, description: KeyDescription, autoRepeat: boolean): Promise<void>;
|
||||
keyup(modifiers: Set<types.KeyboardModifier>, keyName: string, description: KeyDescription): Promise<void>;
|
||||
sendText(text: string): Promise<void>;
|
||||
}
|
||||
|
||||
|
|
@ -55,8 +55,7 @@ export class Keyboard {
|
|||
this._pressedKeys.add(description.code);
|
||||
if (kModifiers.includes(description.key as types.KeyboardModifier))
|
||||
this._pressedModifiers.add(description.key as types.KeyboardModifier);
|
||||
const text = description.text;
|
||||
await this._raw.keydown(this._pressedModifiers, description.code, description.keyCode, description.keyCodeWithoutLocation, description.key, description.location, autoRepeat, text);
|
||||
await this._raw.keydown(this._pressedModifiers, key, description, autoRepeat);
|
||||
}
|
||||
|
||||
private _keyDescriptionForString(str: string): KeyDescription {
|
||||
|
|
@ -77,7 +76,7 @@ export class Keyboard {
|
|||
if (kModifiers.includes(description.key as types.KeyboardModifier))
|
||||
this._pressedModifiers.delete(description.key as types.KeyboardModifier);
|
||||
this._pressedKeys.delete(description.code);
|
||||
await this._raw.keyup(this._pressedModifiers, description.code, description.keyCode, description.keyCodeWithoutLocation, description.key, description.location);
|
||||
await this._raw.keyup(this._pressedModifiers, key, description);
|
||||
}
|
||||
|
||||
async insertText(text: string) {
|
||||
|
|
|
|||
|
|
@ -59,12 +59,13 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
|||
this._session = session;
|
||||
}
|
||||
|
||||
async keydown(modifiers: Set<types.KeyboardModifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number, autoRepeat: boolean, text: string | undefined): Promise<void> {
|
||||
async keydown(modifiers: Set<types.KeyboardModifier>, keyName: string, description: input.KeyDescription, autoRepeat: boolean): Promise<void> {
|
||||
const parts = [];
|
||||
for (const modifier of (['Shift', 'Control', 'Alt', 'Meta']) as types.KeyboardModifier[]) {
|
||||
if (modifiers.has(modifier))
|
||||
parts.push(modifier);
|
||||
}
|
||||
const { code, keyCode, key, text } = description;
|
||||
parts.push(code);
|
||||
const shortcut = parts.join('+');
|
||||
let commands = macEditingCommands[shortcut];
|
||||
|
|
@ -80,18 +81,19 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
|||
unmodifiedText: text,
|
||||
autoRepeat,
|
||||
macCommands: commands,
|
||||
isKeypad: location === input.keypadLocation
|
||||
isKeypad: description.location === input.keypadLocation
|
||||
});
|
||||
}
|
||||
|
||||
async keyup(modifiers: Set<types.KeyboardModifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise<void> {
|
||||
async keyup(modifiers: Set<types.KeyboardModifier>, keyName: string, description: input.KeyDescription): Promise<void> {
|
||||
const { code, key } = description;
|
||||
await this._pageProxySession.send('Input.dispatchKeyEvent', {
|
||||
type: 'keyUp',
|
||||
modifiers: toModifiersMask(modifiers),
|
||||
key,
|
||||
windowsVirtualKeyCode: keyCode,
|
||||
windowsVirtualKeyCode: description.keyCode,
|
||||
code,
|
||||
isKeypad: location === input.keypadLocation
|
||||
isKeypad: description.location === input.keypadLocation
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue