Skip to content

Commit 98926bc

Browse files
committedAug 28, 2020
Blur the previous active element on focus
1 parent e599e64 commit 98926bc

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
lines changed
 

‎addon-test-support/@ember/test-helpers/dom/focus.ts

+9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { nextTickPromise } from '../-utils';
66
import Target from './-target';
77
import { log } from '@ember/test-helpers/dom/-logging';
88
import { runHooks, registerHook } from '../-internal/helper-hooks';
9+
import { __blur__ } from './blur';
910

1011
registerHook('focus', 'start', (target: Target) => {
1112
log('focus', target);
@@ -22,6 +23,14 @@ export function __focus__(element: HTMLElement | Element | Document | SVGElement
2223

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

26+
if (
27+
document.activeElement &&
28+
document.activeElement !== element &&
29+
isFocusable(document.activeElement)
30+
) {
31+
__blur__(document.activeElement);
32+
}
33+
2534
// makes `document.activeElement` be `element`. If the browser is focused, it also fires a focus event
2635
element.focus();
2736

‎tests/unit/dom/focus-test.js

+47-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import { module, test } from 'qunit';
22
import { focus, setupContext, teardownContext, _registerHook } from '@ember/test-helpers';
3-
import { buildInstrumentedElement, insertElement } from '../../helpers/events';
4-
import { isIE11 } from '../../helpers/browser-detect';
3+
import { buildInstrumentedElement, insertElement, instrumentElement } from '../../helpers/events';
4+
import { isIE11, isEdge } from '../../helpers/browser-detect';
55
import hasEmberVersion from '@ember/test-helpers/has-ember-version';
66

77
let focusSteps = ['focus', 'focusin'];
8+
let blurSteps = ['blur', 'focusout'];
89

910
if (isIE11) {
1011
focusSteps = ['focusin', 'focus'];
12+
blurSteps = ['focusout', 'blur'];
13+
} else if (isEdge) {
14+
blurSteps = ['focusout', 'blur'];
1115
}
1216

1317
module('DOM Helper: focus', function (hooks) {
@@ -95,6 +99,43 @@ module('DOM Helper: focus', function (hooks) {
9599
assert.verifySteps(focusSteps);
96100
});
97101

102+
test('blurs the previous active element', async function (assert) {
103+
element = buildInstrumentedElement('input', ['target']);
104+
105+
const focusedElement = document.createElement('textarea');
106+
insertElement(focusedElement);
107+
focusedElement.focus();
108+
instrumentElement(focusedElement, ['target']);
109+
110+
await focus(element);
111+
112+
assert.verifySteps([
113+
...blurSteps.map(s => {
114+
return `${s} [object HTMLTextAreaElement]`;
115+
}),
116+
...focusSteps.map(s => {
117+
return `${s} [object HTMLInputElement]`;
118+
}),
119+
]);
120+
});
121+
122+
test('does not attempt to blur the previous element if it is not focusable', async function (assert) {
123+
element = buildInstrumentedElement('input', ['target']);
124+
125+
const focusedElement = document.createElement('div');
126+
insertElement(focusedElement);
127+
focusedElement.focus();
128+
instrumentElement(focusedElement, ['target']);
129+
130+
await focus(element);
131+
132+
assert.verifySteps([
133+
...focusSteps.map(s => {
134+
return `${s} [object HTMLInputElement]`;
135+
}),
136+
]);
137+
});
138+
98139
test('rejects if selector is not found', async function (assert) {
99140
element = buildInstrumentedElement('div');
100141

@@ -106,7 +147,7 @@ module('DOM Helper: focus', function (hooks) {
106147
);
107148
});
108149

109-
test('focusing a input via selector with context set', async function (assert) {
150+
test('focusing an input via selector with context set', async function (assert) {
110151
element = buildInstrumentedElement('input');
111152

112153
await setupContext(context);
@@ -116,7 +157,7 @@ module('DOM Helper: focus', function (hooks) {
116157
assert.strictEqual(document.activeElement, element, 'activeElement updated');
117158
});
118159

119-
test('focusing a input via element with context set', async function (assert) {
160+
test('focusing an input via element with context set', async function (assert) {
120161
element = buildInstrumentedElement('input');
121162

122163
await setupContext(context);
@@ -126,7 +167,7 @@ module('DOM Helper: focus', function (hooks) {
126167
assert.strictEqual(document.activeElement, element, 'activeElement updated');
127168
});
128169

129-
test('focusing a input via element without context set', async function (assert) {
170+
test('focusing an input via element without context set', async function (assert) {
130171
element = buildInstrumentedElement('input');
131172

132173
await focus(element);
@@ -135,7 +176,7 @@ module('DOM Helper: focus', function (hooks) {
135176
assert.strictEqual(document.activeElement, element, 'activeElement updated');
136177
});
137178

138-
test('focusing a input via selector without context set', async function (assert) {
179+
test('focusing an input via selector without context set', async function (assert) {
139180
element = buildInstrumentedElement('input');
140181

141182
assert.rejects(

0 commit comments

Comments
 (0)
Please sign in to comment.