Skip to content

Commit

Permalink
Safari: prevent focus capturing caused by flex display (#66402)
Browse files Browse the repository at this point in the history
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: mcsf <mcsf@git.wordpress.org>
Co-authored-by: youknowriad <youknowriad@git.wordpress.org>
  • Loading branch information
4 people authored Nov 11, 2024
1 parent 249c0cf commit c80e6a8
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 18 deletions.
12 changes: 0 additions & 12 deletions packages/block-library/src/group/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,6 @@
}
}

// Reset user select, but the next rule should take precedence for nested
// groups.
:where([data-has-multi-selection]:not([contenteditable="true"]) .wp-block-group > *) {
user-select: initial;
}

// When we are not multi-selecting, prevent children from capturing the
// selection, which happens when the group is flex and children inlined.
:where([data-has-multi-selection]:not([contenteditable="true"]) .wp-block-group) {
user-select: none;
}

// Place block list appender in the same place content will appear.
[data-type="core/group"].is-selected {
.block-list-appender {
Expand Down
2 changes: 2 additions & 0 deletions packages/rich-text/src/component/event-listeners/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import formatBoundaries from './format-boundaries';
import deleteHandler from './delete';
import inputAndSelection from './input-and-selection';
import selectionChangeCompat from './selection-change-compat';
import { preventFocusCapture } from './prevent-focus-capture';

const allEventListeners = [
copyHandler,
Expand All @@ -21,6 +22,7 @@ const allEventListeners = [
deleteHandler,
inputAndSelection,
selectionChangeCompat,
preventFocusCapture,
];

export function useEventListeners( props ) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Prevents focus from being captured by the element when clicking _outside_
* around the element. This may happen when the parent element is flex.
* @see https://github.com/WordPress/gutenberg/pull/65857
* @see https://github.com/WordPress/gutenberg/pull/66402
*/
export function preventFocusCapture() {
return ( element ) => {
const { ownerDocument } = element;
const { defaultView } = ownerDocument;

let value = null;

function onPointerDown( event ) {
// Abort if the event is default prevented, we will not get a pointer up event.
if ( event.defaultPrevented ) {
return;
}
if ( event.target === element ) {
return;
}
if ( ! event.target.contains( element ) ) {
return;
}
value = element.getAttribute( 'contenteditable' );
element.setAttribute( 'contenteditable', 'false' );
defaultView.getSelection().removeAllRanges();
}

function onPointerUp() {
if ( value !== null ) {
element.setAttribute( 'contenteditable', value );
value = null;
}
}

defaultView.addEventListener( 'pointerdown', onPointerDown );
defaultView.addEventListener( 'pointerup', onPointerUp );
return () => {
defaultView.removeEventListener( 'pointerdown', onPointerDown );
defaultView.removeEventListener( 'pointerup', onPointerUp );
};
};
}
9 changes: 3 additions & 6 deletions test/e2e/specs/editor/various/multi-block-selection.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ test.describe( 'Multi-block selection (@firefox, @webkit)', () => {
] );
} );

test( 'should clear selection when clicking next to blocks (-firefox)', async ( {
test( 'should clear selection when clicking next to blocks', async ( {
page,
editor,
multiBlockSelectionUtils,
Expand All @@ -752,16 +752,13 @@ test.describe( 'Multi-block selection (@firefox, @webkit)', () => {
name: 'Block: Paragraph',
} )
.filter( { hasText: '1' } );
// For some reason in Chrome it requires two clicks, even though it
// doesn't when testing manually.
await paragraph1.click( {
position: { x: -1, y: 0 },
// Use force since it's outside the bounding box of the element.
force: true,
} );

await expect
.poll( multiBlockSelectionUtils.getSelectedFlatIndices )
.toEqual( [ 1 ] );

await paragraph1.click( {
position: { x: -1, y: 0 },
// Use force since it's outside the bounding box of the element.
Expand Down

1 comment on commit c80e6a8

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in c80e6a8.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/11781806084
📝 Reported issues:

Please sign in to comment.