diff --git a/docs/api.md b/docs/api.md index 71a463b9f2d..3817fdc0909 100644 --- a/docs/api.md +++ b/docs/api.md @@ -63,7 +63,6 @@ + [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options) * [class: Keyboard](#class-keyboard) + [keyboard.down(key[, options])](#keyboarddownkey-options) - + [keyboard.modifiers()](#keyboardmodifiers) + [keyboard.sendCharacter(char)](#keyboardsendcharacterchar) + [keyboard.up(key)](#keyboardupkey) * [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). -#### 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) - `char` <[string]> Character to send into the page. - returns: <[Promise]> diff --git a/lib/Keyboard.js b/lib/Input.js similarity index 62% rename from lib/Keyboard.js rename to lib/Input.js index 534bbdbad65..0c244d3fa49 100644 --- a/lib/Keyboard.js +++ b/lib/Input.js @@ -22,8 +22,7 @@ class Keyboard { */ constructor(client) { this._client = client; - /** @type {!Set} */ - this._keys = new Set(); + this._modifiers = 0; } /** @@ -33,10 +32,10 @@ class Keyboard { */ async down(key, options) { let {text} = options || {}; - this._keys.add(key); + this._modifiers |= this._modifierBit(key); await this._client.send('Input.dispatchKeyEvent', { type: text ? 'keyDown' : 'rawKeyDown', - modifiers: this._modifiersMask(), + modifiers: this._modifiers, windowsVirtualKeyCode: codeForKey(key), key: key, text: text, @@ -45,15 +44,19 @@ class Keyboard { } /** - * @param {{Shift: boolean, Alt: boolean, Meta: boolean, Control: boolean}} + * @param {string} key + * @return {number} */ - modifiers() { - return { - Shift: this._keys.has('Shift'), - Alt: this._keys.has('Alt'), - Meta: this._keys.has('Meta'), - Control: this._keys.has('Control') - }; + _modifierBit(key) { + if (key === 'Alt') + return 1; + if (key === 'Control') + return 2; + if (key === 'Meta') + return 4; + if (key === 'Shift') + return 8; + return 0; } /** @@ -61,10 +64,10 @@ class Keyboard { * @return {!Promise} */ async up(key) { - this._keys.delete(key); + this._modifiers &= ~this._modifierBit(key); await this._client.send('Input.dispatchKeyEvent', { type: 'keyUp', - modifiers: this._modifiersMask(), + modifiers: this._modifiers, key, windowsVirtualKeyCode: codeForKey(key), }); @@ -77,27 +80,83 @@ class Keyboard { async sendCharacter(char) { await this._client.send('Input.dispatchKeyEvent', { type: 'char', - modifiers: this._modifiersMask(), + modifiers: this._modifiers, text: char, key: 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() { - let modifiers = 0; - if (this._keys.has('Alt')) - modifiers += 1; - if (this._keys.has('Control')) - modifiers += 2; - if (this._keys.has('Meta')) - modifiers += 4; - if (this._keys.has('Shift')) - modifiers += 8; - return modifiers; + 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._keyboard._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; } -module.exports = Keyboard; +module.exports = {Keyboard, Mouse}; helper.tracePublicAPI(Keyboard); +helper.tracePublicAPI(Mouse); diff --git a/lib/Mouse.js b/lib/Mouse.js deleted file mode 100644 index 6826b17bdd1..00000000000 --- a/lib/Mouse.js +++ /dev/null @@ -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; \ No newline at end of file diff --git a/lib/Page.js b/lib/Page.js index 27e36404785..37d1818f237 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -22,8 +22,7 @@ let NavigatorWatcher = require('./NavigatorWatcher'); let Dialog = require('./Dialog'); let EmulationManager = require('./EmulationManager'); let FrameManager = require('./FrameManager'); -let Keyboard = require('./Keyboard'); -let Mouse = require('./Mouse'); +let {Keyboard, Mouse} = require('./Input'); let helper = require('./helper'); class Page extends EventEmitter { @@ -39,11 +38,11 @@ class Page extends EventEmitter { client.send('Runtime.enable', {}), client.send('Security.enable', {}), ]); - let keyboard = new Keyboard(client); - let mouse = new Mouse(client, keyboard); - let frameManager = await FrameManager.create(client, mouse); - let networkManager = new NetworkManager(client); - let page = new Page(client, frameManager, networkManager, screenshotTaskQueue, mouse, keyboard); + const keyboard = new Keyboard(client); + const mouse = new Mouse(client, keyboard); + const frameManager = await FrameManager.create(client, mouse); + const networkManager = new NetworkManager(client); + const page = new Page(client, frameManager, networkManager, screenshotTaskQueue, mouse, keyboard); // Initialize default page size. await page.setViewport({width: 400, height: 300}); return page; diff --git a/test/test.js b/test/test.js index 39ea690cd81..e887dc33a55 100644 --- a/test/test.js +++ b/test/test.js @@ -888,16 +888,14 @@ describe('Puppeteer', function() { })); it('keyboard.modifiers()', SX(async function(){ let keyboard = page.keyboard; - expect(keyboard.modifiers().Shift).toBe(false); - expect(keyboard.modifiers().Meta).toBe(false); - expect(keyboard.modifiers().Alt).toBe(false); - expect(keyboard.modifiers().Control).toBe(false); + expect(keyboard._modifiers).toBe(0); keyboard.down('Shift'); - expect(keyboard.modifiers().Shift).toBe(true); - expect(keyboard.modifiers().Alt).toBe(false); + expect(keyboard._modifiers).toBe(8); + keyboard.down('Alt'); + expect(keyboard._modifiers).toBe(9); keyboard.up('Shift'); - expect(keyboard.modifiers().Shift).toBe(false); - expect(keyboard.modifiers().Alt).toBe(false); + keyboard.up('Alt'); + expect(keyboard._modifiers).toBe(0); })); it('should resize the textarea', SX(async function(){ await page.navigate(PREFIX + '/input/textarea.html');