Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cmd+A doesn't select all on Mac #1313

Closed
JoelEinbinder opened this issue Nov 7, 2017 · 18 comments
Closed

Cmd+A doesn't select all on Mac #1313

JoelEinbinder opened this issue Nov 7, 2017 · 18 comments

Comments

@JoelEinbinder
Copy link
Contributor

There are two types of shortcuts: those handled by OS and those handled by Chrome

  • Alt-Tab is an example of a native shortcut
  • Shift-Left is an example of Chrome-handled shortcut

Puppeteer doesn't emulate native shortcuts because native shortcuts depend on the active window, which is out of control for puppeteer.

Certain shortcuts, such as "select all", are handled differently on different platforms:

  • On Win and Linux, Ctrl-A is handled by Chrome, and puppeteer does emulate this
  • On OS X, ⌘-A is handled by OS X, and puppeteer doesn't emulate this
@drorbiran
Copy link

drorbiran commented May 17, 2018

I'm also having an issue with simulating a paste from clipboard.
tried

 await this.page.keyboard.down('ControlLeft');
 await this.page.keyboard.down('V');

 await this.page.keyboard.up('V');
  await this.page.keyboard.up('ControlLeft');

@dragoroff
Copy link

dragoroff commented Nov 8, 2018

You can solve your problem by clicking 3 times in a row and then deleting your text.
await input.click({ clickCount: 3 }); await page.keyboard.press("Backspace");

@aadityataparia
Copy link

I'm also having an issue with simulating command click:

 await page.keyboard.down('Meta');
 await page.click('a');
 await page.keyboard.up('Meta');

It doesn't open a new tab.

@swissspidy
Copy link

Why exactly is this issue closed? 🤔

@voshond
Copy link

voshond commented Feb 26, 2019

Yes, I'm wondering too.

Unfortunately in some special cases the triple click does not select all the text, in my case the website has some weird handler where i cannot simply put the data as the value for the input box and then send, i actually have to type the input and before delete the original, probably due to some eventhandler listing to keyboard input.

@aduth
Copy link

aduth commented Mar 11, 2019

This is still a problem in my testing. I'd think the issue should be reopened.

In the meantime, what's worked for me as a viable alternative for "select all" is:

await page.evaluate( () => document.execCommand( 'selectall', false, null ) );

@swissspidy
Copy link

@JoelEinbinder @aslushnikov Can we reopen this?

@aslushnikov
Copy link
Contributor

@swissspidy it might be a little unclear, but the issue is stating the state of the world that's beyond our reach. The issue is closed since it's not actionable - the best we can do is to put this in our docs.

The workaround with selectall should be good-enough for the most usecases.

getdave added a commit to getdave/gutenberg that referenced this issue Mar 19, 2019
e2e tests were failing due to introduction of valign toolbar meaning that number of tab stops needed to be increased by 3 (the number of items in the new toolbar).

Also uncovered a bug with Pupeteer not handling Cmd + A to “Select All” on a Mac. This is a known issue (puppeteer/puppeteer#1313
) and it is now worked around using arrows and backspace.
getdave added a commit to WordPress/gutenberg that referenced this issue Mar 19, 2019
…#13899)

* Adds ability to valign all the columns via parent

Proof of concept demonstrating ability to change the valignment of columns with a parent column Block

* Adds ability to v-align individual Columns

* Adds ability to select individual Column Blocks to access Block Toolbar

Previously the ability to select an individual Column Block was disabled via CSS. This was because the Column itself was just a passthrough element with no UI or Tools of its own. Now we’ve introduced the v-align toolbar on the Column the Block needs to be selectable.

* Adds Material UI icons

@thomasguillot recommended using Material UI icons. Added dedicated icons file and implemented.

* Updates to add i18n to text strings

Ensure all text strings are translatable. Also reuse icon defs in parent Columns Block alignment settings

* Extracts reusable VAlignToolbar to DRY up implementation

* Fixes alignment attribute not updating

* Updates Toolbar API to observe Single Responsibility

Previously Toolbar was too aware of its context and assumed responsibility for updating parent Block’s attributes via setAttributes prop. Revised to utilise callback prop to propagate change events up to the parent. Now upto the consuming component to observe the change and handle it as required. This makes the VAlignToolbar easy to reuse in other locations.

Refactor Blocks to utilise new pattern.

* Extract deprecations for readability

This prepares deprecations for adding a new deprecation to handle the addition of the `verticalAlignment` attribute.

* Updates valignment default to no alignment specified

Previously we enforced a “top” valign on all columns. This seemed heavy handed given that Themes might wish to control this. Now we default to no valignment and allow user to optionally choose to specifiy a valignment.

* Adds ability to toggle alignment settings on and off

Previously once alignment had been set there was no way to disable it. Added ability to toggle each setting on and off.

* Adds editor preview of vertical alignment

* Adds reusable valign toolbar to editor package components

* Updates Columns Block to utilise new editor package toolbar component

Previously we utilised a bespoke toolbar for the Block. As this toolbar is also required in other components determined best to extract to a resuable component within the @wordpress/editor package.

Updates Block to utilise this new component. Removes old bespoke component.

See Slack convo: https://wordpress.slack.com/archives/C02QB2JS7/p1550657882430900

* Adds documentation to the BlockVerticalAlignmentToolbar

* Updates to use simplified arrow function syntax

* Fixes deprecation save definition back to original version

Previously the save definition of the deprecation was accidentally altered during testing. Restoring to the current state of `master` to ensure that we haven’t broken the existing deprecation when moving this block to a seperate file.

* Updates known classes to use simplified classnames util style

Resolves

* #13899 (comment)
* #13899 (comment)
* #13899 (comment)

* remove extraneous file with icons

* Fixes icon vars to use standard coding style

Resolves #13899 (comment)

* Updates test to use `it` instead of `test`

Resolves #13899 (comment)

* Fix spelling and grammatical errors

Resolves

* #13899 (comment)
* #13899 (comment)

* Removes duplicate dependencies comment

Resolves #13899 (comment)

* Updates code readability and self documentation

Previously the tenary to determine which icon to show when in “collapsed” mode wasn’t easy to comprehend.

Update to add clear variable names to make it more explicit about what happens when there is/isn’t a active alignment value set.

This address the concern raised in #13899 (comment) but looks to prefer code readability over absolutely succinct code.

* Consolidates selectors for improve readability/comprehension

Prevously nested of selectors was getting a little confusing. Pulled onto a single line to this unit of code in a single location.

Resolves #13899 (comment)

* Updates to consolidate similar CSS rules

Resolves #13899 (comment)

* Fixes spelling error

Resolves #13899 (comment)

* Removes unecessary type checking in favour of coercion rules

Previously we were explicitly checking the type of the `verticalAlignment` attr with `isNil()`. However this only checks for `undefined` or `null`. Other falsey values would have passed here which is undesirable. As `undefined` and `null` are both coerced to falsey we can remove the dep on `isNil` and simplify.

Resolves #13899 (comment)

* update icon sizes to match others in Toolbar

* Fixes bottom alignment on front end

Specificity overide to ensure margin is applied and preserved on last child to ensure that when columns are aligned to bottom they are are flush with each other

Resolves #13899 (comment)

* Fix failing e2e testing due to additional of toolbar

e2e tests were failing due to introduction of valign toolbar meaning that number of tab stops needed to be increased by 3 (the number of items in the new toolbar).

Also uncovered a bug with Pupeteer not handling Cmd + A to “Select All” on a Mac. This is a known issue (puppeteer/puppeteer#1313
) and it is now worked around using arrows and backspace.

* Fixes toolbar snapshot unit test

* Adds force update of child columns when parent setting changes

Previously it was possible to have a setting on the parent and individual settings on the individual columns. However the parent would still show an alignment setting even though not all of the child columns had that alignment.

Now if the parent has an alignment setting it will be auto applied to the state of the child columns directly. If a child column changes it’s individual alignment to something which does not match the parent’s alignment setting then the parent’s alignment setting is removed. However the individual column alignments still stay “as is” because each individual column has the valign setting directly rather than pseudo inheried from the parent via CSS.

Addresses: #13899 (comment)

* Updates changelog with `BlockVerticalAlignmentToolbar` feature

* Adds valign feature to changelog for Block Library

* Creates dedicated files for large code blocks

Previously all code blocks were in a single large index file. This was becoming unwieldy and difficult to manage/edit. Extract each large block into it’s own file for readability and maintainability.

* Updates to avoid tests depending on erroneous _id prop

Previously the `_id` prop was included purely to make testing easier (more resilient). On reflection introducing code just for tests was a bad idea. Now depends on string comparison which is an acceptable compromise.

Resolves #13899 (comment)

* Removes usage of unused attribute introduced as experiment

This attribute was introduced as part of experimenting in e759315 and never removed. It’s unused and has been removed.

* Updates example to run without erroring due to missing var

Resolves #13899 (comment)

* Fixes comment to match coding style guidelines

Resolves #13899 (comment)

* Fixes to avoid mutation in render method

Previously in order to reset the Parent’s alignment when one of the child Columns set it’s own alignment, the render method of the Parent Columns mutated the attributes causing a re-render. To avoid this we now reset the Parent from the Child Column whose alignment changed.

Addresses #13899 (comment)

* Fixes single Column Block breadcrumb to RHS of boundary

Resolves point raised in #13899 (comment)

* Restores pass through click behaviour on single Column Block

As discussed [here](#13899 (comment)) selection of parent/child Blocks is currently being worked on elsewhere. Therefore to get the vertical-alignment shipped, this commit reverts the change that made Columns individually selectable. Now reverts to original behaviour of only being selectable via the Block Inspector (or keyboard). This assumes that future PRs will land better Parent/Child selection behaviour. Also removes unwanted space within the Columns themselves.

* Updates to tidy CSS selectors for improved readability

* Updates to move VAlign Toolbar into Block Editor package

Previously the editor package container the toolbar. Now the new Block Editor should be the new home for the toolbar

* Automated README update

* Updates changlogs to reflect release status
@aduth
Copy link

aduth commented Apr 4, 2019

The workaround with selectall should be good-enough for the most usecases.

Expanding on my previous comment, it ultimately wasn't quite enough for our application which included more advanced handling to preventDefault the Cmd+A behavior under some conditions.

The full implementation ended up being just a bit more complex:

/**
 * Emulates a Ctrl+A SelectAll key combination by dispatching custom keyboard
 * events and using the results of those events to determine whether to call
 * `document.execCommand( 'selectall' );`. This is necessary because Puppeteer
 * does not emulate Ctrl+A SelectAll in macOS. Events are dispatched to ensure
 * that any `Event#preventDefault` which would have normally occurred in the
 * application as a result of Ctrl+A is respected.
 *
 * @link https://github.com/GoogleChrome/puppeteer/issues/1313
 * @link https://w3c.github.io/uievents/tools/key-event-viewer.html
 *
 * @return {Promise} Promise resolving once the SelectAll emulation completes.
 */
async function emulateSelectAll() {
	await page.evaluate( () => {
		const isMac = /Mac|iPod|iPhone|iPad/.test( window.navigator.platform );

		document.activeElement.dispatchEvent(
			new KeyboardEvent( 'keydown', {
				bubbles: true,
				cancelable: true,
				key: isMac ? 'Meta' : 'Control',
				code: isMac ? 'MetaLeft' : 'ControlLeft',
				location: window.KeyboardEvent.DOM_KEY_LOCATION_LEFT,
				getModifierState: ( keyArg ) => keyArg === ( isMac ? 'Meta' : 'Control' ),
				ctrlKey: ! isMac,
				metaKey: isMac,
				charCode: 0,
				keyCode: isMac ? 93 : 17,
				which: isMac ? 93 : 17,
			} )
		);

		const preventableEvent = new KeyboardEvent( 'keydown', {
			bubbles: true,
			cancelable: true,
			key: 'a',
			code: 'KeyA',
			location: window.KeyboardEvent.DOM_KEY_LOCATION_STANDARD,
			getModifierState: ( keyArg ) => keyArg === ( isMac ? 'Meta' : 'Control' ),
			ctrlKey: ! isMac,
			metaKey: isMac,
			charCode: 0,
			keyCode: 65,
			which: 65,
		} );

		const wasPrevented = (
			! document.activeElement.dispatchEvent( preventableEvent ) ||
			preventableEvent.defaultPrevented
		);

		if ( ! wasPrevented ) {
			document.execCommand( 'selectall', false, null );
		}

		document.activeElement.dispatchEvent(
			new KeyboardEvent( 'keyup', {
				bubbles: true,
				cancelable: true,
				key: isMac ? 'Meta' : 'Control',
				code: isMac ? 'MetaLeft' : 'ControlLeft',
				location: window.KeyboardEvent.DOM_KEY_LOCATION_LEFT,
				getModifierState: () => false,
				charCode: 0,
				keyCode: isMac ? 93 : 17,
				which: isMac ? 93 : 17,
			} ),
		);
	} );
}

mrnugget added a commit to sourcegraph/sourcegraph-public-snapshot that referenced this issue Aug 1, 2019
Pasting text was introduced in f2365a5
and doesn't work on my macOS machine.

Reading through puppeteer/puppeteer#1313
tells me that other people also couldn't get pasting via Meta+V to work
on macOS with Puppeteer.

This commit adds an override for macOS while leaving the existing
`paste` function as is.
mrnugget added a commit to sourcegraph/sourcegraph-public-snapshot that referenced this issue Aug 1, 2019
Pasting text was introduced in f2365a5
and doesn't work on my macOS machine.

Reading through puppeteer/puppeteer#1313
tells me that other people also couldn't get pasting via Meta+V to work
on macOS with Puppeteer.

This commit adds an override for macOS while leaving the existing
`paste` function as is.
@Jiang-Xuan
Copy link
Contributor

Command + v is not working on mac also, but i find a solution, https://stackoverflow.com/questions/11750447/performing-a-copy-and-paste-with-selenium-2#answer-41046276 . in my mac, i confirmed that it works.

@avalanche1
Copy link

avalanche1 commented Dec 16, 2019

What about
document.execCommand("selectAll");
?
maybe that won't work in headless mode...

@CurtisMorice
Copy link

CurtisMorice commented Jun 22, 2020

We are using Backbone.js so my code is a little different but I made it work with

{method: 'click',  value: '[tg-name=passcode_input]'},
{method: ['keyboard', 'down'],  value: 'Alt'},
{method: ['keyboard', 'press'], value: 'ArrowRight'},
{method: ['keyboard', 'down'],  value: 'Alt'},
{method: ['keyboard', 'down'],  value: 'Shift'},
{method: ['keyboard', 'press'], value: 'ArrowLeft'},
{method: ['keyboard', 'up'],    value: 'Alt'},
{method: ['keyboard', 'up'],    value: 'Shift'},
{method: ['keyboard', 'press'], value: 'Backspace'},

basically pressing/click into the input , then command (Alt) + ArrowRight, then command (Alt) + Shift + ArrowLeft, and then Backspace/Delete

Hope this is understood and works for you (anyone?)

blueboxd pushed a commit to blueboxd/chromium-legacy that referenced this issue Jun 22, 2020
Key events emulated with DevTools can now use the commands option
to send editing commands that will be executed if the event is not
canceled. This is important for shortcuts like Meta+A = SelectAll to
work on a Mac.

See puppeteer/puppeteer#1313
and microsoft/playwright#1067

Change-Id: Id258668bfc71ef9f7f47477ef9de3422ada1d4b5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2211929
Commit-Queue: Joel Einbinder <[email protected]>
Reviewed-by: Andrey Kosyakov <[email protected]>
Reviewed-by: Dmitry Gozman <[email protected]>
Reviewed-by: Yang Guo <[email protected]>
Cr-Commit-Position: refs/heads/master@{#780848}
@eeeeaaii
Copy link

eeeeaaii commented Aug 8, 2020

I get it that you can't hijack Alt on Linux/Windows machines but you CAN do this on a Mac (it's the Option key on a mac).

Likewise, on a Mac you can easily create browser behavior that uses the Option key, javascript that recognizes when the Option key is pressed, etc.

I feel like it would make more sense to have this be platform-dependent, right now the implemention on Mac is limited by windows/Linux compatibility issues that shouldn't affect it.

Even in the name of this bug it says "on the mac" so I'm not sure why it's closed, the problems cited for reasons for closing this bug aren't really relevant to the Mac.

@manatarms
Copy link

I need to do ⌘ + i on macOS. Has anyone been able to figure out how to trigger the meta shortcuts in macOS?

@GouravSingh2580
Copy link

GouravSingh2580 commented Feb 23, 2022

How can i cut cut withpage.keyboard.down("Control") on mac? page.keyboard.down("X") after that doesn't work

nickzylstra pushed a commit to nickzylstra/the_room that referenced this issue Apr 7, 2022
puppeteer/puppeteer#1313 appears to have
been sufficiently addressed to support mac command/meta key
mjfroman pushed a commit to mjfroman/moz-libwebrtc-third-party that referenced this issue Oct 14, 2022
Key events emulated with DevTools can now use the commands option
to send editing commands that will be executed if the event is not
canceled. This is important for shortcuts like Meta+A = SelectAll to
work on a Mac.

See puppeteer/puppeteer#1313
and microsoft/playwright#1067

Change-Id: Id258668bfc71ef9f7f47477ef9de3422ada1d4b5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2211929
Commit-Queue: Joel Einbinder <[email protected]>
Reviewed-by: Andrey Kosyakov <[email protected]>
Reviewed-by: Dmitry Gozman <[email protected]>
Reviewed-by: Yang Guo <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#780848}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 3d3ee67f6904c527aca96b54588cb1008a17b23e
Junyan added a commit to Junyan/puppeteer that referenced this issue Dec 3, 2022
Junyan added a commit to Junyan/puppeteer that referenced this issue Dec 3, 2022
Junyan added a commit to Junyan/puppeteer that referenced this issue Dec 3, 2022
Junyan added a commit to Junyan/puppeteer that referenced this issue Dec 3, 2022
OrKoN pushed a commit that referenced this issue Dec 3, 2022
Issue: #1313

<!-- Thanks for submitting a pull request! Please provide enough
information so that others can review your pull request. -->

**What kind of change does this PR introduce?**

Feature.

**Did you add tests for your changes?**

Yes.

**If relevant, did you update the documentation?**

Yes.

**Summary**

Supports keyboard shotcuts on MacOS. See Chrome Devtools Protocol
document:
https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-dispatchKeyEvent.
@wilsonssss
Copy link

wilsonssss commented Oct 18, 2023

You can solve your problem by clicking 3 times in a row and then deleting your text. await input.click({ clickCount: 3 }); await page.keyboard.press("Backspace");

This works for me, just change params from clickCount to count

await elementHandle.click({ count: 3 })
await page.keyboard.press('Backspace')

@alexey-sh
Copy link

The execCommand() is officially obsolete/deprecated but there's no alternative.

@richoandika
Copy link

if (!page.$(selector)) {
    return;
}
await page.click(selector, { clickCount: 3 });
await page.type(selector, '');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests