Skip to content

Commit

Permalink
Merge pull request #965 from drewlee/master
Browse files Browse the repository at this point in the history
  • Loading branch information
rwjblue authored Dec 18, 2020
2 parents 119e372 + 35f0e14 commit 25ef5b7
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 11 deletions.
23 changes: 16 additions & 7 deletions addon-test-support/@ember/test-helpers/dom/blur.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { assign } from '@ember/polyfills';
import getElement from './-get-element';
import fireEvent from './fire-event';
import settled from '../settled';
Expand All @@ -14,24 +15,32 @@ registerHook('blur', 'start', (target: Target) => {
/**
@private
@param {Element} element the element to trigger events on
@param {Element} relatedTarget the element that is focused after blur
*/
export function __blur__(element: HTMLElement | Element | Document | SVGElement): void {
export function __blur__(
element: HTMLElement | Element | Document | SVGElement,
relatedTarget: HTMLElement | Element | Document | SVGElement | null = null
): void {
if (!isFocusable(element)) {
throw new Error(`${element} is not focusable`);
}

let browserIsNotFocused = document.hasFocus && !document.hasFocus();
let needsCustomEventOptions = relatedTarget !== null;

// makes `document.activeElement` be `body`.
// If the browser is focused, it also fires a blur event
element.blur();
if (!needsCustomEventOptions) {
// makes `document.activeElement` be `body`.
// If the browser is focused, it also fires a blur event
element.blur();
}

// Chrome/Firefox does not trigger the `blur` event if the window
// does not have focus. If the document does not have focus then
// fire `blur` event via native event.
if (browserIsNotFocused) {
fireEvent(element, 'blur', { bubbles: false });
fireEvent(element, 'focusout');
if (browserIsNotFocused || needsCustomEventOptions) {
let options = { relatedTarget };
fireEvent(element, 'blur', assign({ bubbles: false }, options));
fireEvent(element, 'focusout', options);
}
}

Expand Down
7 changes: 5 additions & 2 deletions addon-test-support/@ember/test-helpers/dom/focus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ export function __focus__(element: HTMLElement | Element | Document | SVGElement

let browserIsNotFocused = document.hasFocus && !document.hasFocus();

// fire __blur__ manually with the correct relatedTarget when the browser is not
// already in focus and there was a previously focused element
if (
document.activeElement &&
document.activeElement !== element &&
isFocusable(document.activeElement)
isFocusable(document.activeElement) &&
browserIsNotFocused
) {
__blur__(document.activeElement);
__blur__(document.activeElement, element);
}

// makes `document.activeElement` be `element`. If the browser is focused, it also fires a focus event
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/dom/focus-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ module('DOM Helper: focus', function (hooks) {
const focusedElement = document.createElement('textarea');
insertElement(focusedElement);
focusedElement.focus();
instrumentElement(focusedElement, ['target']);
instrumentElement(focusedElement, ['target', 'relatedTarget']);

await focus(element);

assert.verifySteps([
...blurSteps.map(s => {
return `${s} [object HTMLTextAreaElement]`;
return `${s} [object HTMLTextAreaElement] [object HTMLInputElement]`;
}),
...focusSteps.map(s => {
return `${s} [object HTMLInputElement]`;
Expand Down

0 comments on commit 25ef5b7

Please sign in to comment.