Skip to content

Commit ed4e91d

Browse files
authored
refactor: cleanup fake event dispatch utilities (#19151)
Cleans up the fake event dispatch utiltities: 1. `dispatchMouseEvent` accepts an actual mouse event. This has been introduced with [this commit](04bf3d1). If a mouse event has already been created, then it can be just dispatched, but doesn't need to go through `dispatchMouseEvent` which primarily is a shorthand for creating an event and dispatching it. 2. `dispatchEvent` helper should use a generic so that we don't need to cast events unnecessarily. 3. `createMouseEvent` should not accept `x` and `y`. This is ambiguous. It's not clear what coordinates are expected. To improve this, parameters are now explicit, and a better comment has been added.
1 parent 70036cb commit ed4e91d

File tree

4 files changed

+29
-23
lines changed

4 files changed

+29
-23
lines changed

src/cdk/testing/testbed/fake-events/dispatch-events.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
* Utility to dispatch any event on a Node.
1919
* @docs-private
2020
*/
21-
export function dispatchEvent(node: Node | Window, event: Event): Event {
21+
export function dispatchEvent<T extends Event>(node: Node | Window, event: T): T {
2222
node.dispatchEvent(event);
2323
return event;
2424
}
@@ -38,16 +38,15 @@ export function dispatchFakeEvent(node: Node | Window, type: string, canBubble?:
3838
export function dispatchKeyboardEvent(node: Node, type: string, keyCode?: number, key?: string,
3939
target?: Element, modifiers?: ModifierKeys): KeyboardEvent {
4040
return dispatchEvent(node,
41-
createKeyboardEvent(type, keyCode, key, target, modifiers)) as KeyboardEvent;
41+
createKeyboardEvent(type, keyCode, key, target, modifiers));
4242
}
4343

4444
/**
4545
* Shorthand to dispatch a mouse event on the specified coordinates.
4646
* @docs-private
4747
*/
48-
export function dispatchMouseEvent(node: Node, type: string, x = 0, y = 0,
49-
event = createMouseEvent(type, x, y)): MouseEvent {
50-
return dispatchEvent(node, event) as MouseEvent;
48+
export function dispatchMouseEvent(node: Node, type: string, clientX = 0, clientY = 0): MouseEvent {
49+
return dispatchEvent(node, createMouseEvent(type, clientX, clientY));
5150
}
5251

5352
/**

src/cdk/testing/testbed/fake-events/event-objects.ts

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,32 @@ import {ModifierKeys} from '@angular/cdk/testing';
1212
* Creates a browser MouseEvent with the specified options.
1313
* @docs-private
1414
*/
15-
export function createMouseEvent(type: string, x = 0, y = 0, button = 0) {
15+
export function createMouseEvent(type: string, clientX = 0, clientY = 0, button = 0) {
1616
const event = document.createEvent('MouseEvent');
1717
const originalPreventDefault = event.preventDefault.bind(event);
1818

19+
// Note: We cannot determine the position of the mouse event based on the screen
20+
// because the dimensions and position of the browser window are not available
21+
// To provide reasonable `screenX` and `screenY` coordinates, we simply use the
22+
// client coordinates as if the browser is opened in fullscreen.
23+
const screenX = clientX;
24+
const screenY = clientY;
25+
1926
event.initMouseEvent(type,
20-
true, /* canBubble */
21-
true, /* cancelable */
22-
window, /* view */
23-
0, /* detail */
24-
x, /* screenX */
25-
y, /* screenY */
26-
x, /* clientX */
27-
y, /* clientY */
28-
false, /* ctrlKey */
29-
false, /* altKey */
30-
false, /* shiftKey */
31-
false, /* metaKey */
32-
button, /* button */
33-
null /* relatedTarget */);
27+
/* canBubble */ true,
28+
/* cancelable */ true,
29+
/* view */ window,
30+
/* detail */ 0,
31+
/* screenX */ screenX,
32+
/* screenY */ screenY,
33+
/* clientX */ clientX,
34+
/* clientY */ clientY,
35+
/* ctrlKey */ false,
36+
/* altKey */ false,
37+
/* shiftKey */ false,
38+
/* metaKey */ false,
39+
/* button */ button,
40+
/* relatedTarget */ null);
3441

3542
// `initMouseEvent` doesn't allow us to pass the `buttons` and
3643
// defaults it to 0 which looks like a fake event.

src/material-experimental/mdc-menu/menu.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2035,7 +2035,7 @@ describe('MDC-based MatMenu', () => {
20352035
Object.defineProperty(event, 'buttons', {get: () => 1});
20362036
event.preventDefault = jasmine.createSpy('preventDefault spy');
20372037

2038-
dispatchMouseEvent(overlay.querySelector('[mat-menu-item]')!, 'mousedown', 0, 0, event);
2038+
dispatchEvent(overlay.querySelector('[mat-menu-item]')!, event);
20392039
expect(event.preventDefault).toHaveBeenCalled();
20402040
});
20412041

src/material/menu/menu.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import {
1010
dispatchFakeEvent,
1111
dispatchKeyboardEvent,
1212
dispatchMouseEvent,
13-
patchElementFocus,
1413
MockNgZone,
14+
patchElementFocus,
1515
} from '@angular/cdk/testing/private';
1616
import {
1717
ChangeDetectionStrategy,
@@ -2031,7 +2031,7 @@ describe('MatMenu', () => {
20312031
Object.defineProperty(event, 'buttons', {get: () => 1});
20322032
event.preventDefault = jasmine.createSpy('preventDefault spy');
20332033

2034-
dispatchMouseEvent(overlay.querySelector('[mat-menu-item]')!, 'mousedown', 0, 0, event);
2034+
dispatchEvent(overlay.querySelector('[mat-menu-item]')!, event);
20352035
expect(event.preventDefault).toHaveBeenCalled();
20362036
});
20372037

0 commit comments

Comments
 (0)