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;
|
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[] = [];
|
const actions: bidi.Input.KeySourceAction[] = [];
|
||||||
actions.push({ type: 'keyDown', value: getBidiKeyValue(code) });
|
actions.push({ type: 'keyDown', value: getBidiKeyValue(keyName) });
|
||||||
// TODO: add modifiers?
|
|
||||||
await this._performActions(actions);
|
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[] = [];
|
const actions: bidi.Input.KeySourceAction[] = [];
|
||||||
actions.push({ type: 'keyUp', value: getBidiKeyValue(code) });
|
actions.push({ type: 'keyUp', value: getBidiKeyValue(keyName) });
|
||||||
await this._performActions(actions);
|
await this._performActions(actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,18 +7,18 @@
|
||||||
|
|
||||||
/* eslint-disable curly */
|
/* eslint-disable curly */
|
||||||
|
|
||||||
export const getBidiKeyValue = (code: string) => {
|
export const getBidiKeyValue = (keyName: string) => {
|
||||||
switch (code) {
|
switch (keyName) {
|
||||||
case '\r':
|
case '\r':
|
||||||
case '\n':
|
case '\n':
|
||||||
code = 'Enter';
|
keyName = 'Enter';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Measures the number of code points rather than UTF-16 code units.
|
// Measures the number of code points rather than UTF-16 code units.
|
||||||
if ([...code].length === 1) {
|
if ([...keyName].length === 1) {
|
||||||
return code;
|
return keyName;
|
||||||
}
|
}
|
||||||
switch (code) {
|
switch (keyName) {
|
||||||
case 'Cancel':
|
case 'Cancel':
|
||||||
return '\uE001';
|
return '\uE001';
|
||||||
case 'Help':
|
case 'Help':
|
||||||
|
|
@ -228,6 +228,6 @@ export const getBidiKeyValue = (code: string) => {
|
||||||
case 'Quote':
|
case 'Quote':
|
||||||
return '"';
|
return '"';
|
||||||
default:
|
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));
|
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())
|
if (code === 'Escape' && await this._dragManger.cancelDrag())
|
||||||
return;
|
return;
|
||||||
const commands = this._commandsForCode(code, modifiers);
|
const commands = this._commandsForCode(code, modifiers);
|
||||||
await this._client.send('Input.dispatchKeyEvent', {
|
await this._client.send('Input.dispatchKeyEvent', {
|
||||||
type: text ? 'keyDown' : 'rawKeyDown',
|
type: text ? 'keyDown' : 'rawKeyDown',
|
||||||
modifiers: toModifiersMask(modifiers),
|
modifiers: toModifiersMask(modifiers),
|
||||||
windowsVirtualKeyCode: keyCodeWithoutLocation,
|
windowsVirtualKeyCode: description.keyCodeWithoutLocation,
|
||||||
code,
|
code,
|
||||||
commands,
|
commands,
|
||||||
key,
|
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', {
|
await this._client.send('Input.dispatchKeyEvent', {
|
||||||
type: 'keyUp',
|
type: 'keyUp',
|
||||||
modifiers: toModifiersMask(modifiers),
|
modifiers: toModifiersMask(modifiers),
|
||||||
key,
|
key,
|
||||||
windowsVirtualKeyCode: keyCodeWithoutLocation,
|
windowsVirtualKeyCode: description.keyCodeWithoutLocation,
|
||||||
code,
|
code,
|
||||||
location
|
location
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -61,13 +61,15 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
||||||
this._client = client;
|
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
|
// Firefox will figure out Enter by itself
|
||||||
if (text === '\r')
|
if (text === '\r')
|
||||||
text = '';
|
text = '';
|
||||||
|
const { code, key, location } = description;
|
||||||
await this._client.send('Page.dispatchKeyEvent', {
|
await this._client.send('Page.dispatchKeyEvent', {
|
||||||
type: 'keydown',
|
type: 'keydown',
|
||||||
keyCode: keyCodeWithoutLocation,
|
keyCode: description.keyCodeWithoutLocation,
|
||||||
code,
|
code,
|
||||||
key,
|
key,
|
||||||
repeat: autoRepeat,
|
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', {
|
await this._client.send('Page.dispatchKeyEvent', {
|
||||||
type: 'keyup',
|
type: 'keyup',
|
||||||
key,
|
key,
|
||||||
keyCode: keyCodeWithoutLocation,
|
keyCode: description.keyCodeWithoutLocation,
|
||||||
code,
|
code,
|
||||||
location,
|
location,
|
||||||
repeat: false
|
repeat: false
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import type { CallMetadata } from './instrumentation';
|
||||||
|
|
||||||
export const keypadLocation = keyboardLayout.keypadLocation;
|
export const keypadLocation = keyboardLayout.keypadLocation;
|
||||||
|
|
||||||
type KeyDescription = {
|
export type KeyDescription = {
|
||||||
keyCode: number,
|
keyCode: number,
|
||||||
keyCodeWithoutLocation: number,
|
keyCodeWithoutLocation: number,
|
||||||
key: string,
|
key: string,
|
||||||
|
|
@ -35,8 +35,8 @@ type KeyDescription = {
|
||||||
const kModifiers: types.KeyboardModifier[] = ['Alt', 'Control', 'Meta', 'Shift'];
|
const kModifiers: types.KeyboardModifier[] = ['Alt', 'Control', 'Meta', 'Shift'];
|
||||||
|
|
||||||
export interface RawKeyboard {
|
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>;
|
keydown(modifiers: Set<types.KeyboardModifier>, keyName: string, description: KeyDescription, autoRepeat: boolean): Promise<void>;
|
||||||
keyup(modifiers: Set<types.KeyboardModifier>, code: string, keyCode: number, keyCodeWithoutLocation: number, key: string, location: number): Promise<void>;
|
keyup(modifiers: Set<types.KeyboardModifier>, keyName: string, description: KeyDescription): Promise<void>;
|
||||||
sendText(text: string): Promise<void>;
|
sendText(text: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,8 +55,7 @@ export class Keyboard {
|
||||||
this._pressedKeys.add(description.code);
|
this._pressedKeys.add(description.code);
|
||||||
if (kModifiers.includes(description.key as types.KeyboardModifier))
|
if (kModifiers.includes(description.key as types.KeyboardModifier))
|
||||||
this._pressedModifiers.add(description.key as types.KeyboardModifier);
|
this._pressedModifiers.add(description.key as types.KeyboardModifier);
|
||||||
const text = description.text;
|
await this._raw.keydown(this._pressedModifiers, key, description, autoRepeat);
|
||||||
await this._raw.keydown(this._pressedModifiers, description.code, description.keyCode, description.keyCodeWithoutLocation, description.key, description.location, autoRepeat, text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _keyDescriptionForString(str: string): KeyDescription {
|
private _keyDescriptionForString(str: string): KeyDescription {
|
||||||
|
|
@ -77,7 +76,7 @@ export class Keyboard {
|
||||||
if (kModifiers.includes(description.key as types.KeyboardModifier))
|
if (kModifiers.includes(description.key as types.KeyboardModifier))
|
||||||
this._pressedModifiers.delete(description.key as types.KeyboardModifier);
|
this._pressedModifiers.delete(description.key as types.KeyboardModifier);
|
||||||
this._pressedKeys.delete(description.code);
|
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) {
|
async insertText(text: string) {
|
||||||
|
|
|
||||||
|
|
@ -59,12 +59,13 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
||||||
this._session = session;
|
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 = [];
|
const parts = [];
|
||||||
for (const modifier of (['Shift', 'Control', 'Alt', 'Meta']) as types.KeyboardModifier[]) {
|
for (const modifier of (['Shift', 'Control', 'Alt', 'Meta']) as types.KeyboardModifier[]) {
|
||||||
if (modifiers.has(modifier))
|
if (modifiers.has(modifier))
|
||||||
parts.push(modifier);
|
parts.push(modifier);
|
||||||
}
|
}
|
||||||
|
const { code, keyCode, key, text } = description;
|
||||||
parts.push(code);
|
parts.push(code);
|
||||||
const shortcut = parts.join('+');
|
const shortcut = parts.join('+');
|
||||||
let commands = macEditingCommands[shortcut];
|
let commands = macEditingCommands[shortcut];
|
||||||
|
|
@ -80,18 +81,19 @@ export class RawKeyboardImpl implements input.RawKeyboard {
|
||||||
unmodifiedText: text,
|
unmodifiedText: text,
|
||||||
autoRepeat,
|
autoRepeat,
|
||||||
macCommands: commands,
|
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', {
|
await this._pageProxySession.send('Input.dispatchKeyEvent', {
|
||||||
type: 'keyUp',
|
type: 'keyUp',
|
||||||
modifiers: toModifiersMask(modifiers),
|
modifiers: toModifiersMask(modifiers),
|
||||||
key,
|
key,
|
||||||
windowsVirtualKeyCode: keyCode,
|
windowsVirtualKeyCode: description.keyCode,
|
||||||
code,
|
code,
|
||||||
isKeypad: location === input.keypadLocation
|
isKeypad: description.location === input.keypadLocation
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue