Skip to content

Commit

Permalink
perf(cdk/a11y): Don't trigger re-layout when detecting fake mousedown (
Browse files Browse the repository at this point in the history
…#28029)

(cherry picked from commit 737c7a8)
  • Loading branch information
mmalerba committed Nov 5, 2023
1 parent 78cf5dc commit c0b38de
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 14 deletions.
10 changes: 4 additions & 6 deletions src/cdk/a11y/fake-event-detection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@
/** Gets whether an event could be a faked `mousedown` event dispatched by a screen reader. */
export function isFakeMousedownFromScreenReader(event: MouseEvent): boolean {
// Some screen readers will dispatch a fake `mousedown` event when pressing enter or space on
// a clickable element. We can distinguish these events when both `offsetX` and `offsetY` are
// zero or `event.buttons` is zero, depending on the browser:
// a clickable element. We can distinguish these events when `event.buttons` is zero, or
// `event.detail` is zero depending on the browser:
// - `event.buttons` works on Firefox, but fails on Chrome.
// - `offsetX` and `offsetY` work on Chrome, but fail on Firefox.
// Note that there's an edge case where the user could click the 0x0 spot of the
// screen themselves, but that is unlikely to contain interactive elements.
return event.buttons === 0 || (event.offsetX === 0 && event.offsetY === 0);
// - `detail` works on Chrome, but fails on Firefox.
return event.buttons === 0 || event.detail === 0;
}

/** Gets whether an event could be a faked `touchstart` event dispatched by a screen reader. */
Expand Down
2 changes: 1 addition & 1 deletion src/cdk/a11y/focus-monitor/focus-monitor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ describe('FocusMonitor', () => {
// Simulate focus via a fake mousedown from a screen reader.
dispatchMouseEvent(buttonElement, 'mousedown');
const event = createMouseEvent('mousedown');
Object.defineProperties(event, {offsetX: {get: () => 0}, offsetY: {get: () => 0}});
Object.defineProperties(event, {detail: {get: () => 0}});
dispatchEvent(buttonElement, event);

buttonElement.focus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ describe('InputModalityDetector', () => {

// Create a fake screen-reader mouse event.
const event = createMouseEvent('mousedown');
Object.defineProperties(event, {offsetX: {get: () => 0}, offsetY: {get: () => 0}});
Object.defineProperties(event, {detail: {get: () => 0}});
dispatchEvent(document, event);

expect(detector.mostRecentModality).toBe('keyboard');
Expand Down
4 changes: 2 additions & 2 deletions src/cdk/drag-drop/directives/drag.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ describe('CdkDrag', () => {
const event = createMouseEvent('mousedown', 0, 0);

Object.defineProperties(event, {
offsetX: {get: () => 0},
offsetY: {get: () => 0},
buttons: {get: () => 0},
detail: {get: () => 0},
});

expect(dragElement.style.transform).toBeFalsy();
Expand Down
6 changes: 3 additions & 3 deletions src/cdk/testing/testbed/fake-events/event-objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export function createMouseEvent(
type: string,
clientX = 0,
clientY = 0,
offsetX = 1,
offsetY = 1,
offsetX = 0,
offsetY = 0,
button = 0,
modifiers: ModifierKeys = {},
) {
Expand All @@ -36,7 +36,7 @@ export function createMouseEvent(
cancelable: true,
composed: true, // Required for shadow DOM events.
view: window,
detail: 0,
detail: 1,
relatedTarget: null,
screenX,
screenY,
Expand Down
2 changes: 1 addition & 1 deletion src/material/core/ripple/ripple.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ describe('MatRipple', () => {

it('should ignore fake mouse events from screen readers', () => {
const event = createMouseEvent('mousedown');
Object.defineProperties(event, {offsetX: {get: () => 0}, offsetY: {get: () => 0}});
Object.defineProperties(event, {buttons: {get: () => 0}, detail: {get: () => 0}});

dispatchEvent(rippleTarget, event);

Expand Down

0 comments on commit c0b38de

Please sign in to comment.