Skip to content

Commit 6cb90f0

Browse files
committed
prevent double focus events
1 parent e748ace commit 6cb90f0

File tree

7 files changed

+78
-34
lines changed

7 files changed

+78
-34
lines changed

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

src/emulate-tab.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ function emulateTabFromSourceToTarget(source: HTMLElement, target: HTMLElement,
4444
if (ev === tabKeydown) {
4545
if (source instanceof HTMLElement) {
4646
source.blur();
47-
source.dispatchEvent(new FocusEvent('blur'));
4847
}
4948

5049
emulateEventsAtTabTarget(target, direction);
@@ -71,7 +70,6 @@ function emulateEventsAtTabTarget(target: HTMLElement, direction: TabDirection)
7170
if (target instanceof HTMLInputElement) {
7271
target.selectionStart = 0;
7372
}
74-
target.dispatchEvent(new FocusEvent('focus'));
7573

7674
const tabKeyup = createTabEvent('keyup', direction);
7775
target.dispatchEvent(tabKeyup);

test/in-plain-html-js/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
"start": "node -r ts-node/register src/app.ts",
88
"watch_start": "npm-watch start",
99
"test": "karma start",
10+
"install-emulate-tab": "npm i ../../tmp/emulate-tab.latest.tgz",
11+
"uninstall-emulate-tab": "npm i ../../tmp/emulate-tab.latest.tgz",
12+
"reinstall-emulate-tab": "npm run uninstall-emulate-tab",
13+
"postreinstall-emulate-tab": "npm run install-emulate-tab",
14+
"pretest:once": "npm run reinstall-emulate-tab",
1015
"test:once": "karma start --browsers=ChromeHeadless,FirefoxHeadless --single-run"
1116
},
1217
"watch": {

test/in-typescript-requirejs/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
"start": "node -r ts-node/register src/app.ts",
88
"watch_start": "npm-watch start",
99
"test": "karma start",
10+
"install-emulate-tab": "npm i ../../tmp/emulate-tab.latest.tgz",
11+
"uninstall-emulate-tab": "npm i ../../tmp/emulate-tab.latest.tgz",
12+
"reinstall-emulate-tab": "npm run uninstall-emulate-tab",
13+
"postreinstall-emulate-tab": "npm run install-emulate-tab",
14+
"precoverage": "npm run reinstall-emulate-tab",
1015
"coverage": "karma start --browsers=ChromeHeadless,FirefoxHeadless --single-run",
1116
"test-node-module": "karma start karma.node-module.conf.js --browsers=ChromeHeadless,FirefoxHeadless --single-run"
1217
},

test/in-typescript-requirejs/src/app.spec.ts

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,34 +31,4 @@ xdescribe('demo app', () => {
3131
describe('initially', () => {
3232
it('log should be empty', () => expect(getEventLog()).toEqual(''));
3333
});
34-
35-
describe('after write "a" into first input', () => {
36-
beforeEach(() => {
37-
const firstInput = eventCheck.view.firstInput;
38-
firstInput.value = 'a';
39-
const event = new KeyboardEvent('keydown', { code: 'keyA' });
40-
console.log('event', event);
41-
firstInput.dispatchEvent(event);
42-
return new Promise(done => setTimeout(done, 10));
43-
});
44-
45-
it('log should contain entries', () => expect(getEventLog()).toContain('keyA'));
46-
});
47-
48-
describe('after emulating tab', () => {
49-
beforeEach(() => {
50-
eventCheck.view.emulateTabButton.click();
51-
});
52-
53-
it('should trigger all events', () => {
54-
expect(getEventLog().split(/\s*\n\s*/)).toEqual(`
55-
first-input (keydown): Tab
56-
parent-of-first-input (keydown): Tab
57-
first-input (blur): blur
58-
second-input (focus): focus
59-
second-input (keyup): Tab
60-
parent-of-second-input (keyup): Tab
61-
`.split(/\s*\n\s*/).slice(1));
62-
})
63-
});
6434
});

test/in-typescript-requirejs/src/app.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as path from 'path';
33
import * as tsNode from 'ts-node';
44
import * as fs from 'fs';
55
import * as emulateTab from '../../../dist';
6+
import { Server } from 'http';
67

78
if (!emulateTab) {
89
throw new Error('no emulate tab???');
@@ -92,5 +93,5 @@ app.get('/favicon.ico',
9293
);
9394
app.get('/:filename', serveFiles('html', 'text/html'));
9495

95-
export const server = app.listen(port);
96+
export const server: Server = app.listen(port);
9697
console.log('app running on ' + port);
Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,77 @@
1+
import { EventCheck } from './event-check.model';
2+
13
describe('event check', () => {
4+
let eventCheck: EventCheck;
5+
let origLog: any;
6+
let logSpy: jasmine.Spy;
7+
8+
function getEventLog(): string {
9+
return eventCheck.view.eventLog.innerHTML;
10+
}
11+
212
beforeAll(() => {
313
fixture.setBase('src');
414
document.body.appendChild(fixture.el);
515
});
616

717
beforeEach(() => {
18+
origLog = console.log;
19+
logSpy = spyOn(console, 'log');
820
fixture.cleanup();
921
fixture.load('event-check.html');
22+
eventCheck = new EventCheck();
23+
eventCheck.init();
1024
});
1125

26+
afterEach(() => {
27+
console.log = origLog;
28+
})
29+
1230
it('should start', () => expect().nothing());
13-
});
31+
32+
describe('after write "a" into first input', () => {
33+
beforeEach(() => {
34+
const firstInput = eventCheck.view.firstInput;
35+
firstInput.value = 'a';
36+
const event = new KeyboardEvent('keydown', { code: 'keyA' });
37+
console.log('event', event);
38+
firstInput.dispatchEvent(event);
39+
return new Promise(done => setTimeout(done, 10));
40+
});
41+
42+
it('log should contain entries', () => expect(getEventLog()).toContain('keyA'));
43+
});
44+
45+
describe('after emulating tab', () => {
46+
beforeEach(() => {
47+
eventCheck.view.emulateTabButton.click();
48+
});
49+
50+
it('should have triggered all events', () => {
51+
const actualEventLog = normalizeEventLog(getEventLog());
52+
const expectedEventLog = normalizeEventLog(`
53+
first-input (focus): focus
54+
first-input (keydown): Tab
55+
parent-of-first-input (keydown): Tab
56+
first-input (blur): blur
57+
second-input (focus): focus
58+
second-input (keyup): Tab
59+
parent-of-second-input (keyup): Tab
60+
`);
61+
expect(actualEventLog).toEqual(expectedEventLog);
62+
expect(eventCount(actualEventLog)).toEqual(eventCount(expectedEventLog));
63+
})
64+
});
65+
});
66+
67+
function normalizeEventLog(log: string) {
68+
let normalized = log.split(/(\s*\n)+\s*/).join('');
69+
if (!normalized.startsWith('\n')) {
70+
normalized = '\n' + normalized;
71+
}
72+
return normalized;
73+
}
74+
75+
function eventCount(normalizedLog: string) {
76+
return normalizedLog.split('\n').length - 1;
77+
}

0 commit comments

Comments
 (0)