-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.js
139 lines (115 loc) · 4.68 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
'use strict';
/**
* function that will add a style block that will hide the focus
* outlines while a user is using the mouse to navigate the application,
* once we detect that a user is using keyboard navigation (tab) we remove
* this style block so that the real focus outlines will be visible again.
*/
(function (root, factory) {
if(typeof define === 'function' && define.amd) { // eslint-disable-line
define(factory); // eslint-disable-line
} else if(typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root.smartOutline = factory();
}
}(this, function() {
var defaultDomId = 'bbbx-a11y-fix';
var defaultHideFocusCSS = '*:focus {outline:0 !important;}::-moz-focus-inner{border:0;}';
var defaultHtmlClass = 'so-keyboard-user';
var options = null;
var KEYCODE_TAB = 9;
var KEYCODE_SPACE = 39;
var KEYCODE_LEFT = 37;
var KEYCODE_UP = 38;
var KEYCODE_RIGHT = 39;
var KEYCODE_DOWN = 40;
function ensureInitCalled() {
if(options === null)
throw new Error('Smart Outline is not initialized yet. Make sure to call `.init()` first.');
}
var smartOutline = {
getStyleEl: function() {
var opts = options || {};
return document.getElementById(opts.domId || defaultDomId);
},
setCSS: function(css) {
this.getStyleEl().innerHTML = css;
},
setHtmlClass: function(cssClass) {
document.documentElement.classList.add(cssClass);
},
removeHtmlClass: function(cssClass) {
document.documentElement.classList.remove(cssClass);
},
_clickListener: function() {
smartOutline.setCSS(options.hideFocusCSS);
smartOutline.removeHtmlClass(options.htmlClass);
window.removeEventListener('click', smartOutline._clickListener, false);
window.addEventListener('keydown', smartOutline._keyDownListener); // eslint-disable-line
},
_keyDownListener: function(evt) {
// only remove the outline if the user is using one of the keyboard
// navigation keys
if(
evt.keyCode !== KEYCODE_TAB &&
evt.keyCode !== KEYCODE_SPACE &&
evt.keyCode !== KEYCODE_LEFT &&
evt.keyCode !== KEYCODE_RIGHT &&
evt.keyCode !== KEYCODE_UP &&
evt.keyCode !== KEYCODE_DOWN
)
return;
smartOutline.setCSS('');
smartOutline.setHtmlClass(options.htmlClass);
window.removeEventListener('keydown', smartOutline._keyDownListener, false);
window.addEventListener('click', smartOutline._clickListener);
},
getOptions: function() {
ensureInitCalled();
return options;
},
isKeyboardUser: function() {
ensureInitCalled();
return this.getStyleEl().innerHTML === '';
},
isEnabled: function() {
var el = smartOutline.getStyleEl();
return el ? true : false;
},
init: function(userOptions) {
// create options were user options overwrites default options
userOptions = userOptions || {};
options = {
domId: userOptions.domId || defaultDomId,
hideFocusCSS: userOptions.hideFocusCSS || defaultHideFocusCSS,
htmlClass: userOptions.htmlClass || defaultHtmlClass
};
// only add style element if it doesn't exist yet
if(this.getStyleEl())
return this.getStyleEl();
// only bind the click handler if there is no a11y style element yet
window.addEventListener('click', smartOutline._clickListener);
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.id = options.domId;
style.type = 'text/css';
if (userOptions.nonce)
style.nonce = userOptions.nonce;
if(!head)
return false;
return head.appendChild(style);
},
destroy: function() {
var el = smartOutline.getStyleEl();
if(el) {
var head = document.head || document.getElementsByTagName('head')[0];
head.removeChild(el);
options = null;
window.removeEventListener('keydown', smartOutline._keyDownListener, false);
window.removeEventListener('click', smartOutline._clickListener, false);
}
}
};
return smartOutline;
}));