Simplify keyboard modifiers handling (#129)
This commit is contained in:
parent
0007809305
commit
eca0d7fe53
10
docs/api.md
10
docs/api.md
@ -63,7 +63,6 @@
|
|||||||
+ [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options)
|
+ [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options)
|
||||||
* [class: Keyboard](#class-keyboard)
|
* [class: Keyboard](#class-keyboard)
|
||||||
+ [keyboard.down(key[, options])](#keyboarddownkey-options)
|
+ [keyboard.down(key[, options])](#keyboarddownkey-options)
|
||||||
+ [keyboard.modifiers()](#keyboardmodifiers)
|
|
||||||
+ [keyboard.sendCharacter(char)](#keyboardsendcharacterchar)
|
+ [keyboard.sendCharacter(char)](#keyboardsendcharacterchar)
|
||||||
+ [keyboard.up(key)](#keyboardupkey)
|
+ [keyboard.up(key)](#keyboardupkey)
|
||||||
* [class: Mouse](#class-mouse)
|
* [class: Mouse](#class-mouse)
|
||||||
@ -662,15 +661,6 @@ This will not send input events unless `text` is specified.
|
|||||||
|
|
||||||
If `key` is a modifier key, `Shift`, `Meta`, `Control`, or `Alt`, subsequent key presses will be sent with that modifier active. To release the modifier key, use [`keyboard.up`](#keyboardupkey).
|
If `key` is a modifier key, `Shift`, `Meta`, `Control`, or `Alt`, subsequent key presses will be sent with that modifier active. To release the modifier key, use [`keyboard.up`](#keyboardupkey).
|
||||||
|
|
||||||
#### keyboard.modifiers()
|
|
||||||
- returns: <[Object]>
|
|
||||||
- `Shift` <[boolean]>
|
|
||||||
- `Meta` <[boolean]>
|
|
||||||
- `Control` <[boolean]>
|
|
||||||
- `Alt` <[boolean]>
|
|
||||||
|
|
||||||
Returns which modifier keys are currently active. Use [`keyboard.down`](#keyboarddownkey) to activate a modifier key.
|
|
||||||
|
|
||||||
#### keyboard.sendCharacter(char)
|
#### keyboard.sendCharacter(char)
|
||||||
- `char` <[string]> Character to send into the page.
|
- `char` <[string]> Character to send into the page.
|
||||||
- returns: <[Promise]>
|
- returns: <[Promise]>
|
||||||
|
@ -22,8 +22,7 @@ class Keyboard {
|
|||||||
*/
|
*/
|
||||||
constructor(client) {
|
constructor(client) {
|
||||||
this._client = client;
|
this._client = client;
|
||||||
/** @type {!Set<string>} */
|
this._modifiers = 0;
|
||||||
this._keys = new Set();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,10 +32,10 @@ class Keyboard {
|
|||||||
*/
|
*/
|
||||||
async down(key, options) {
|
async down(key, options) {
|
||||||
let {text} = options || {};
|
let {text} = options || {};
|
||||||
this._keys.add(key);
|
this._modifiers |= this._modifierBit(key);
|
||||||
await this._client.send('Input.dispatchKeyEvent', {
|
await this._client.send('Input.dispatchKeyEvent', {
|
||||||
type: text ? 'keyDown' : 'rawKeyDown',
|
type: text ? 'keyDown' : 'rawKeyDown',
|
||||||
modifiers: this._modifiersMask(),
|
modifiers: this._modifiers,
|
||||||
windowsVirtualKeyCode: codeForKey(key),
|
windowsVirtualKeyCode: codeForKey(key),
|
||||||
key: key,
|
key: key,
|
||||||
text: text,
|
text: text,
|
||||||
@ -45,15 +44,19 @@ class Keyboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {{Shift: boolean, Alt: boolean, Meta: boolean, Control: boolean}}
|
* @param {string} key
|
||||||
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
modifiers() {
|
_modifierBit(key) {
|
||||||
return {
|
if (key === 'Alt')
|
||||||
Shift: this._keys.has('Shift'),
|
return 1;
|
||||||
Alt: this._keys.has('Alt'),
|
if (key === 'Control')
|
||||||
Meta: this._keys.has('Meta'),
|
return 2;
|
||||||
Control: this._keys.has('Control')
|
if (key === 'Meta')
|
||||||
};
|
return 4;
|
||||||
|
if (key === 'Shift')
|
||||||
|
return 8;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,10 +64,10 @@ class Keyboard {
|
|||||||
* @return {!Promise}
|
* @return {!Promise}
|
||||||
*/
|
*/
|
||||||
async up(key) {
|
async up(key) {
|
||||||
this._keys.delete(key);
|
this._modifiers &= ~this._modifierBit(key);
|
||||||
await this._client.send('Input.dispatchKeyEvent', {
|
await this._client.send('Input.dispatchKeyEvent', {
|
||||||
type: 'keyUp',
|
type: 'keyUp',
|
||||||
modifiers: this._modifiersMask(),
|
modifiers: this._modifiers,
|
||||||
key,
|
key,
|
||||||
windowsVirtualKeyCode: codeForKey(key),
|
windowsVirtualKeyCode: codeForKey(key),
|
||||||
});
|
});
|
||||||
@ -77,27 +80,83 @@ class Keyboard {
|
|||||||
async sendCharacter(char) {
|
async sendCharacter(char) {
|
||||||
await this._client.send('Input.dispatchKeyEvent', {
|
await this._client.send('Input.dispatchKeyEvent', {
|
||||||
type: 'char',
|
type: 'char',
|
||||||
modifiers: this._modifiersMask(),
|
modifiers: this._modifiers,
|
||||||
text: char,
|
text: char,
|
||||||
key: char,
|
key: char,
|
||||||
unmodifiedText: char
|
unmodifiedText: char
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Mouse {
|
||||||
|
/**
|
||||||
|
* @param {!Connection} client
|
||||||
|
* @param {!Keyboard} keyboard
|
||||||
|
*/
|
||||||
|
constructor(client, keyboard) {
|
||||||
|
this._client = client;
|
||||||
|
this._keyboard = keyboard;
|
||||||
|
this._x = 0;
|
||||||
|
this._y = 0;
|
||||||
|
this._button = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {number}
|
* @param {number} x
|
||||||
|
* @param {number} y
|
||||||
|
* @return {!Promise}
|
||||||
*/
|
*/
|
||||||
_modifiersMask() {
|
async move(x, y) {
|
||||||
let modifiers = 0;
|
this._x = x;
|
||||||
if (this._keys.has('Alt'))
|
this._y = y;
|
||||||
modifiers += 1;
|
await this._client.send('Input.dispatchMouseEvent', {
|
||||||
if (this._keys.has('Control'))
|
type: 'mouseMoved',
|
||||||
modifiers += 2;
|
button: this._button,
|
||||||
if (this._keys.has('Meta'))
|
x, y,
|
||||||
modifiers += 4;
|
modifiers: this._keyboard._modifiers
|
||||||
if (this._keys.has('Shift'))
|
});
|
||||||
modifiers += 8;
|
}
|
||||||
return modifiers;
|
|
||||||
|
/**
|
||||||
|
* @param {!Object=} options
|
||||||
|
*/
|
||||||
|
async press(options) {
|
||||||
|
await this.down(options);
|
||||||
|
await this.up(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!Object=} options
|
||||||
|
*/
|
||||||
|
async down(options) {
|
||||||
|
if (!options)
|
||||||
|
options = {};
|
||||||
|
this._button = (options.button || 'left');
|
||||||
|
await this._client.send('Input.dispatchMouseEvent', {
|
||||||
|
type: 'mousePressed',
|
||||||
|
button: this._button,
|
||||||
|
x: this._x,
|
||||||
|
y: this._y,
|
||||||
|
modifiers: this._keyboard._modifiers,
|
||||||
|
clickCount: (options.clickCount || 1)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {!Object=} options
|
||||||
|
*/
|
||||||
|
async up(options) {
|
||||||
|
if (!options)
|
||||||
|
options = {};
|
||||||
|
this._button = 'none';
|
||||||
|
await this._client.send('Input.dispatchMouseEvent', {
|
||||||
|
type: 'mouseReleased',
|
||||||
|
button: (options.button || 'left'),
|
||||||
|
x: this._x,
|
||||||
|
y: this._y,
|
||||||
|
modifiers: this._keyboard._modifiers,
|
||||||
|
clickCount: (options.clickCount || 1)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,5 +275,6 @@ function codeForKey(key) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Keyboard;
|
module.exports = {Keyboard, Mouse};
|
||||||
helper.tracePublicAPI(Keyboard);
|
helper.tracePublicAPI(Keyboard);
|
||||||
|
helper.tracePublicAPI(Mouse);
|
106
lib/Mouse.js
106
lib/Mouse.js
@ -1,106 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2017 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Mouse {
|
|
||||||
/**
|
|
||||||
* @param {!Connection} client
|
|
||||||
* @param {!Keyboard} keyboard
|
|
||||||
*/
|
|
||||||
constructor(client, keyboard) {
|
|
||||||
this._client = client;
|
|
||||||
this._keyboard = keyboard;
|
|
||||||
this._x = 0;
|
|
||||||
this._y = 0;
|
|
||||||
this._button = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} x
|
|
||||||
* @param {number} y
|
|
||||||
* @return {!Promise}
|
|
||||||
*/
|
|
||||||
async move(x, y) {
|
|
||||||
this._x = x;
|
|
||||||
this._y = y;
|
|
||||||
await this._client.send('Input.dispatchMouseEvent', {
|
|
||||||
type: 'mouseMoved',
|
|
||||||
button: this._button,
|
|
||||||
x, y,
|
|
||||||
modifiers: this._modifiersMask()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {!Object=} options
|
|
||||||
*/
|
|
||||||
async press(options) {
|
|
||||||
await this.down(options);
|
|
||||||
await this.up(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {!Object=} options
|
|
||||||
*/
|
|
||||||
async down(options) {
|
|
||||||
if (!options)
|
|
||||||
options = {};
|
|
||||||
this._button = (options.button || 'left');
|
|
||||||
await this._client.send('Input.dispatchMouseEvent', {
|
|
||||||
type: 'mousePressed',
|
|
||||||
button: this._button,
|
|
||||||
x: this._x,
|
|
||||||
y: this._y,
|
|
||||||
modifiers: this._modifiersMask(),
|
|
||||||
clickCount: (options.clickCount || 1)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {!Object=} options
|
|
||||||
*/
|
|
||||||
async up(options) {
|
|
||||||
if (!options)
|
|
||||||
options = {};
|
|
||||||
this._button = 'none';
|
|
||||||
await this._client.send('Input.dispatchMouseEvent', {
|
|
||||||
type: 'mouseReleased',
|
|
||||||
button: (options.button || 'left'),
|
|
||||||
x: this._x,
|
|
||||||
y: this._y,
|
|
||||||
modifiers: this._modifiersMask(),
|
|
||||||
clickCount: (options.clickCount || 1)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {number}
|
|
||||||
*/
|
|
||||||
_modifiersMask() {
|
|
||||||
let modifiers = this._keyboard.modifiers();
|
|
||||||
let mask = 0;
|
|
||||||
if (modifiers.Alt)
|
|
||||||
mask += 1;
|
|
||||||
if (modifiers.Control)
|
|
||||||
mask += 2;
|
|
||||||
if (modifiers.Meta)
|
|
||||||
mask += 4;
|
|
||||||
if (modifiers.Shift)
|
|
||||||
mask += 8;
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Mouse;
|
|
13
lib/Page.js
13
lib/Page.js
@ -22,8 +22,7 @@ let NavigatorWatcher = require('./NavigatorWatcher');
|
|||||||
let Dialog = require('./Dialog');
|
let Dialog = require('./Dialog');
|
||||||
let EmulationManager = require('./EmulationManager');
|
let EmulationManager = require('./EmulationManager');
|
||||||
let FrameManager = require('./FrameManager');
|
let FrameManager = require('./FrameManager');
|
||||||
let Keyboard = require('./Keyboard');
|
let {Keyboard, Mouse} = require('./Input');
|
||||||
let Mouse = require('./Mouse');
|
|
||||||
let helper = require('./helper');
|
let helper = require('./helper');
|
||||||
|
|
||||||
class Page extends EventEmitter {
|
class Page extends EventEmitter {
|
||||||
@ -39,11 +38,11 @@ class Page extends EventEmitter {
|
|||||||
client.send('Runtime.enable', {}),
|
client.send('Runtime.enable', {}),
|
||||||
client.send('Security.enable', {}),
|
client.send('Security.enable', {}),
|
||||||
]);
|
]);
|
||||||
let keyboard = new Keyboard(client);
|
const keyboard = new Keyboard(client);
|
||||||
let mouse = new Mouse(client, keyboard);
|
const mouse = new Mouse(client, keyboard);
|
||||||
let frameManager = await FrameManager.create(client, mouse);
|
const frameManager = await FrameManager.create(client, mouse);
|
||||||
let networkManager = new NetworkManager(client);
|
const networkManager = new NetworkManager(client);
|
||||||
let page = new Page(client, frameManager, networkManager, screenshotTaskQueue, mouse, keyboard);
|
const page = new Page(client, frameManager, networkManager, screenshotTaskQueue, mouse, keyboard);
|
||||||
// Initialize default page size.
|
// Initialize default page size.
|
||||||
await page.setViewport({width: 400, height: 300});
|
await page.setViewport({width: 400, height: 300});
|
||||||
return page;
|
return page;
|
||||||
|
14
test/test.js
14
test/test.js
@ -888,16 +888,14 @@ describe('Puppeteer', function() {
|
|||||||
}));
|
}));
|
||||||
it('keyboard.modifiers()', SX(async function(){
|
it('keyboard.modifiers()', SX(async function(){
|
||||||
let keyboard = page.keyboard;
|
let keyboard = page.keyboard;
|
||||||
expect(keyboard.modifiers().Shift).toBe(false);
|
expect(keyboard._modifiers).toBe(0);
|
||||||
expect(keyboard.modifiers().Meta).toBe(false);
|
|
||||||
expect(keyboard.modifiers().Alt).toBe(false);
|
|
||||||
expect(keyboard.modifiers().Control).toBe(false);
|
|
||||||
keyboard.down('Shift');
|
keyboard.down('Shift');
|
||||||
expect(keyboard.modifiers().Shift).toBe(true);
|
expect(keyboard._modifiers).toBe(8);
|
||||||
expect(keyboard.modifiers().Alt).toBe(false);
|
keyboard.down('Alt');
|
||||||
|
expect(keyboard._modifiers).toBe(9);
|
||||||
keyboard.up('Shift');
|
keyboard.up('Shift');
|
||||||
expect(keyboard.modifiers().Shift).toBe(false);
|
keyboard.up('Alt');
|
||||||
expect(keyboard.modifiers().Alt).toBe(false);
|
expect(keyboard._modifiers).toBe(0);
|
||||||
}));
|
}));
|
||||||
it('should resize the textarea', SX(async function(){
|
it('should resize the textarea', SX(async function(){
|
||||||
await page.navigate(PREFIX + '/input/textarea.html');
|
await page.navigate(PREFIX + '/input/textarea.html');
|
||||||
|
Loading…
Reference in New Issue
Block a user