Skip to content

Commit 2c825ed

Browse files
authored
Merge pull request #943 from emberjs/fix-trigger-event
2 parents 2f3a0d3 + d8e2c37 commit 2c825ed

10 files changed

+92
-12
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import getElement from './-get-element';
2+
import Target, { isWindow } from './-target';
3+
4+
/**
5+
Used internally by the DOM interaction helpers to find either window or an element.
6+
7+
@private
8+
@param {string|Element} target the window, an element or selector to retrieve
9+
@returns {Element|Window} the target or selector
10+
*/
11+
export function getWindowOrElement(target: Target): Element | Document | Window | null {
12+
if (isWindow(target)) {
13+
return target as Window;
14+
}
15+
16+
return getElement(target);
17+
}

addon-test-support/@ember/test-helpers/dom/-is-focusable.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import isFormControl from './-is-form-control';
2-
import { isDocument, isContentEditable } from './-target';
2+
import { isDocument, isContentEditable, isWindow } from './-target';
33

44
const FOCUSABLE_TAGS = ['A'];
55

@@ -16,8 +16,12 @@ function isFocusableElement(element: Element): element is FocusableElement {
1616
@returns {boolean} `true` when the element is focusable, `false` otherwise
1717
*/
1818
export default function isFocusable(
19-
element: HTMLElement | SVGElement | Element | Document
19+
element: HTMLElement | SVGElement | Element | Document | Window
2020
): element is HTMLElement | SVGElement {
21+
if (isWindow(element)) {
22+
return false;
23+
}
24+
2125
if (isDocument(element)) {
2226
return false;
2327
}

addon-test-support/@ember/test-helpers/dom/-is-form-control.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isDocument } from './-target';
1+
import { isDocument, isWindow } from './-target';
22

33
const FORM_CONTROL_TAGS = ['INPUT', 'BUTTON', 'SELECT', 'TEXTAREA'];
44

@@ -13,8 +13,11 @@ export type FormControl =
1313
@param {Element} element the element to check
1414
@returns {boolean} `true` when the element is a form control, `false` otherwise
1515
*/
16-
export default function isFormControl(element: Element | Document): element is FormControl {
16+
export default function isFormControl(
17+
element: Element | Document | Window
18+
): element is FormControl {
1719
return (
20+
!isWindow(element) &&
1821
!isDocument(element) &&
1922
FORM_CONTROL_TAGS.indexOf(element.tagName) > -1 &&
2023
(element as HTMLInputElement).type !== 'hidden'

addon-test-support/@ember/test-helpers/dom/-target.ts

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export function isElement(target: any): target is Element {
1111
return target.nodeType === Node.ELEMENT_NODE;
1212
}
1313

14+
// eslint-disable-next-line require-jsdoc
15+
export function isWindow(target: Target): target is Window {
16+
return target instanceof Window;
17+
}
18+
1419
// eslint-disable-next-line require-jsdoc
1520
export function isDocument(target: any): target is Document {
1621
return target.nodeType === Node.DOCUMENT_NODE;

addon-test-support/@ember/test-helpers/dom/click.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { assign } from '@ember/polyfills';
2-
import getElement from './-get-element';
2+
import { getWindowOrElement } from './-get-window-or-element';
33
import fireEvent from './fire-event';
44
import { __focus__ } from './focus';
55
import settled from '../settled';
@@ -31,7 +31,7 @@ export const DEFAULT_CLICK_OPTIONS = {
3131
@param {Element} element the element to click on
3232
@param {MouseEventInit} options the options to be merged into the mouse events
3333
*/
34-
export function __click__(element: Element | Document, options: MouseEventInit): void {
34+
export function __click__(element: Element | Document | Window, options: MouseEventInit): void {
3535
fireEvent(element, 'mousedown', options);
3636

3737
if (isFocusable(element)) {
@@ -97,7 +97,7 @@ export default function click(target: Target, _options: MouseEventInit = {}): Pr
9797
throw new Error('Must pass an element or selector to `click`.');
9898
}
9999

100-
let element = getElement(target);
100+
let element = getWindowOrElement(target);
101101
if (!element) {
102102
throw new Error(`Element not found when calling \`click('${target}')\`.`);
103103
}

addon-test-support/@ember/test-helpers/dom/double-click.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { assign } from '@ember/polyfills';
2-
import getElement from './-get-element';
2+
import { getWindowOrElement } from './-get-window-or-element';
33
import fireEvent from './fire-event';
44
import { __focus__ } from './focus';
55
import settled from '../settled';
@@ -20,7 +20,10 @@ registerHook('doubleClick', 'start', (target: Target) => {
2020
@param {Element} element the element to double-click on
2121
@param {MouseEventInit} options the options to be merged into the mouse events
2222
*/
23-
export function __doubleClick__(element: Element | Document, options: MouseEventInit): void {
23+
export function __doubleClick__(
24+
element: Element | Document | Window,
25+
options: MouseEventInit
26+
): void {
2427
fireEvent(element, 'mousedown', options);
2528

2629
if (isFocusable(element)) {
@@ -98,7 +101,7 @@ export default function doubleClick(target: Target, _options: MouseEventInit = {
98101
throw new Error('Must pass an element or selector to `doubleClick`.');
99102
}
100103

101-
let element = getElement(target);
104+
let element = getWindowOrElement(target);
102105
if (!element) {
103106
throw new Error(`Element not found when calling \`doubleClick('${target}')\`.`);
104107
}

addon-test-support/@ember/test-helpers/dom/trigger-event.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import getElement from './-get-element';
1+
import { getWindowOrElement } from './-get-window-or-element';
22
import fireEvent from './fire-event';
33
import settled from '../settled';
44
import { nextTickPromise } from '../-utils';
@@ -72,7 +72,7 @@ export default function triggerEvent(
7272
throw new Error(`Must provide an \`eventType\` to \`triggerEvent\``);
7373
}
7474

75-
let element = getElement(target);
75+
let element = getWindowOrElement(target);
7676
if (!element) {
7777
throw new Error(`Element not found when calling \`triggerEvent('${target}', ...)\`.`);
7878
}

tests/unit/dom/click-test.js

+16
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,19 @@ module('DOM Helper: click', function (hooks) {
234234
});
235235
});
236236
});
237+
238+
module('DOM Helper: click with window', function () {
239+
test('clicking window without context set fires the given event type', async function (assert) {
240+
let listener = e => {
241+
assert.step('click');
242+
assert.ok(e instanceof Event, `click listener receives a native event`);
243+
};
244+
window.addEventListener('click', listener);
245+
246+
await click(window, 'click');
247+
248+
assert.verifySteps(['click']);
249+
250+
window.removeEventListener('click', listener);
251+
});
252+
});

tests/unit/dom/double-click-test.js

+16
Original file line numberDiff line numberDiff line change
@@ -278,3 +278,19 @@ module('DOM Helper: doubleClick', function (hooks) {
278278
});
279279
});
280280
});
281+
282+
module('DOM Helper: doubleClick with window', function () {
283+
test('double clicking window without context set fires the given event type', async function (assert) {
284+
let listener = e => {
285+
assert.step('click');
286+
assert.ok(e instanceof Event, `click listener receives a native event`);
287+
};
288+
window.addEventListener('click', listener);
289+
290+
await doubleClick(window, 'click');
291+
292+
assert.verifySteps(['click', 'click']);
293+
294+
window.removeEventListener('click', listener);
295+
});
296+
});

tests/unit/dom/trigger-event-test.js

+16
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,19 @@ module('DOM Helper: triggerEvent', function (hooks) {
171171
assert.verifySteps(['inner: mouseenter', 'outer: mouseenter', 'mouseenter']);
172172
});
173173
});
174+
175+
module('DOM Helper: triggerEvent with window', function () {
176+
test('triggering event via window without context set fires the given event type', async function (assert) {
177+
let listener = e => {
178+
assert.step('resize');
179+
assert.ok(e instanceof Event, `resize listener receives a native event`);
180+
};
181+
window.addEventListener('resize', listener);
182+
183+
await triggerEvent(window, 'resize');
184+
185+
assert.verifySteps(['resize']);
186+
187+
window.removeEventListener('resize', listener);
188+
});
189+
});

0 commit comments

Comments
 (0)