@instructure/ui-a11y-utils 8.33.2-snapshot-0 → 8.33.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -5
- package/es/FocusRegion.js +6 -40
- package/es/FocusRegionManager.js +10 -33
- package/es/KeyboardFocusRegion.js +4 -53
- package/es/ScreenReaderFocusRegion.js +1 -36
- package/es/hasVisibleChildren.js +1 -2
- package/es/index.js +1 -0
- package/es/scopeTab.js +8 -12
- package/lib/FocusRegion.js +6 -50
- package/lib/FocusRegionManager.js +10 -38
- package/lib/KeyboardFocusRegion.js +4 -66
- package/lib/ScreenReaderFocusRegion.js +1 -37
- package/lib/hasVisibleChildren.js +1 -8
- package/lib/index.js +0 -6
- package/lib/scopeTab.js +8 -17
- package/package.json +10 -10
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
-
import { logWarn as warn } from '@instructure/console';
|
|
25
24
|
|
|
25
|
+
import { logWarn as warn } from '@instructure/console';
|
|
26
26
|
class ScreenReaderFocusRegion {
|
|
27
27
|
constructor(element) {
|
|
28
28
|
let options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {
|
|
@@ -36,7 +36,6 @@ class ScreenReaderFocusRegion {
|
|
|
36
36
|
this._options = void 0;
|
|
37
37
|
this._observer = null;
|
|
38
38
|
this._attributes = [];
|
|
39
|
-
|
|
40
39
|
this.handleDOMMutation = records => {
|
|
41
40
|
records.forEach(record => {
|
|
42
41
|
const addedNodes = Array.from(record.addedNodes);
|
|
@@ -48,7 +47,6 @@ class ScreenReaderFocusRegion {
|
|
|
48
47
|
if (removedNode.tagName.toLowerCase() !== 'iframe') {
|
|
49
48
|
this.restoreNode(removedNode);
|
|
50
49
|
}
|
|
51
|
-
|
|
52
50
|
const iframeBodies = this.parseIframeBodies(removedNode);
|
|
53
51
|
iframeBodies.forEach(iframeBody => {
|
|
54
52
|
this.restoreNode(iframeBody);
|
|
@@ -56,17 +54,14 @@ class ScreenReaderFocusRegion {
|
|
|
56
54
|
});
|
|
57
55
|
});
|
|
58
56
|
};
|
|
59
|
-
|
|
60
57
|
const liveRegion = typeof options.liveRegion === 'function' ? options.liveRegion() : options.liveRegion;
|
|
61
58
|
this._liveRegion = Array.isArray(liveRegion) ? liveRegion : [liveRegion];
|
|
62
59
|
this._contextElement = element;
|
|
63
60
|
this._options = options;
|
|
64
61
|
}
|
|
65
|
-
|
|
66
62
|
updateElement(element) {
|
|
67
63
|
this._contextElement = element;
|
|
68
64
|
}
|
|
69
|
-
|
|
70
65
|
muteNode(node) {
|
|
71
66
|
if (node && node.tagName.toLowerCase() !== 'script') {
|
|
72
67
|
// When we are trapping screen reader focus on an element that
|
|
@@ -79,31 +74,24 @@ class ScreenReaderFocusRegion {
|
|
|
79
74
|
['role', 'aria-label', 'aria-hidden' // this should never happen right?
|
|
80
75
|
].forEach(attribute => {
|
|
81
76
|
const value = node.getAttribute(attribute);
|
|
82
|
-
|
|
83
77
|
if (value !== null) {
|
|
84
78
|
this._attributes.push([node, attribute, value]);
|
|
85
|
-
|
|
86
79
|
node.removeAttribute(attribute);
|
|
87
80
|
}
|
|
88
81
|
});
|
|
89
|
-
|
|
90
82
|
this._observer.observe(node, {
|
|
91
83
|
childList: true
|
|
92
84
|
});
|
|
93
85
|
}
|
|
94
86
|
}
|
|
95
|
-
|
|
96
87
|
hideNodes(nodes) {
|
|
97
88
|
nodes.forEach(node => {
|
|
98
89
|
var _node$getAttribute;
|
|
99
|
-
|
|
100
90
|
const ariaLive = typeof node.getAttribute === 'function' && ((_node$getAttribute = node.getAttribute('aria-live')) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.toLowerCase());
|
|
101
|
-
|
|
102
91
|
if (node && node.nodeType === 1 && node.tagName.toLowerCase() !== 'script' && ariaLive !== 'assertive' && ariaLive !== 'polite' && this._parents.indexOf(node) === -1 && this._nodes.indexOf(node) === -1 && this._liveRegion.indexOf(node) === -1 && !this._contextElement.contains(node)) {
|
|
103
92
|
if (node.tagName.toLowerCase() !== 'iframe') {
|
|
104
93
|
this.hideNode(node);
|
|
105
94
|
}
|
|
106
|
-
|
|
107
95
|
const iframeBodies = this.parseIframeBodies(node);
|
|
108
96
|
iframeBodies.forEach(iframeBody => {
|
|
109
97
|
this.hideNode(iframeBody);
|
|
@@ -111,29 +99,22 @@ class ScreenReaderFocusRegion {
|
|
|
111
99
|
}
|
|
112
100
|
});
|
|
113
101
|
}
|
|
114
|
-
|
|
115
102
|
hideNode(node) {
|
|
116
103
|
if (node.getAttribute('aria-hidden') !== 'true') {
|
|
117
104
|
node.setAttribute('aria-hidden', 'true');
|
|
118
|
-
|
|
119
105
|
this._nodes.push(node);
|
|
120
106
|
}
|
|
121
107
|
}
|
|
122
|
-
|
|
123
108
|
restoreNode(removedNode) {
|
|
124
109
|
const index = this._nodes.indexOf(removedNode);
|
|
125
|
-
|
|
126
110
|
if (index >= 0) {
|
|
127
111
|
removedNode.removeAttribute('aria-hidden');
|
|
128
|
-
|
|
129
112
|
this._nodes.splice(index, 1);
|
|
130
113
|
}
|
|
131
114
|
}
|
|
132
|
-
|
|
133
115
|
parseIframeBodies(node) {
|
|
134
116
|
if (!node) return [];
|
|
135
117
|
let iframes = [];
|
|
136
|
-
|
|
137
118
|
if (node.tagName.toLowerCase() === 'iframe') {
|
|
138
119
|
iframes.push(node);
|
|
139
120
|
} else {
|
|
@@ -141,38 +122,29 @@ class ScreenReaderFocusRegion {
|
|
|
141
122
|
iframes = Array.from(node.getElementsByTagName('iframe'));
|
|
142
123
|
}
|
|
143
124
|
}
|
|
144
|
-
|
|
145
125
|
return iframes.map(iframe => {
|
|
146
126
|
let body = null;
|
|
147
|
-
|
|
148
127
|
try {
|
|
149
128
|
body = iframe.contentDocument.body;
|
|
150
129
|
} catch (e) {
|
|
151
130
|
warn(false, `[ui-a11y] could not find a document for iframe: ${e} ${iframe}`);
|
|
152
131
|
}
|
|
153
|
-
|
|
154
132
|
return body;
|
|
155
133
|
}).filter(body => body !== null);
|
|
156
134
|
}
|
|
157
|
-
|
|
158
135
|
activate() {
|
|
159
136
|
if (!this._options.shouldContainFocus) {
|
|
160
137
|
return;
|
|
161
138
|
}
|
|
162
|
-
|
|
163
139
|
this._observer = new MutationObserver(this.handleDOMMutation);
|
|
164
140
|
let node = this._contextElement;
|
|
165
|
-
|
|
166
141
|
while (node && node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() !== 'body') {
|
|
167
142
|
const parent = node.parentElement;
|
|
168
|
-
|
|
169
143
|
if (parent) {
|
|
170
144
|
this._parents.push(parent);
|
|
171
|
-
|
|
172
145
|
this.muteNode(parent);
|
|
173
146
|
this.hideNodes(Array.prototype.slice.call(parent.childNodes));
|
|
174
147
|
}
|
|
175
|
-
|
|
176
148
|
node = node.parentNode; // should never be null, will default to doc element
|
|
177
149
|
}
|
|
178
150
|
}
|
|
@@ -180,26 +152,19 @@ class ScreenReaderFocusRegion {
|
|
|
180
152
|
deactivate() {
|
|
181
153
|
if (this._observer) {
|
|
182
154
|
this._observer.disconnect();
|
|
183
|
-
|
|
184
155
|
this._observer = null;
|
|
185
156
|
}
|
|
186
|
-
|
|
187
157
|
this._nodes.forEach(node => {
|
|
188
158
|
node.removeAttribute('aria-hidden');
|
|
189
159
|
});
|
|
190
|
-
|
|
191
160
|
this._nodes = [];
|
|
192
|
-
|
|
193
161
|
this._attributes.forEach(attribute => {
|
|
194
162
|
attribute[0].setAttribute(attribute[1], attribute[2] || '');
|
|
195
163
|
});
|
|
196
|
-
|
|
197
164
|
this._attributes = [];
|
|
198
165
|
this._parents = [];
|
|
199
166
|
}
|
|
200
|
-
|
|
201
167
|
}
|
|
202
|
-
|
|
203
168
|
export default ScreenReaderFocusRegion;
|
|
204
169
|
export {
|
|
205
170
|
/**
|
package/es/hasVisibleChildren.js
CHANGED
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
+
|
|
24
25
|
import React from 'react';
|
|
25
26
|
import { matchComponentTypes } from '@instructure/ui-react-utils';
|
|
26
27
|
import { ScreenReaderContent } from '@instructure/ui-a11y-content';
|
|
27
|
-
|
|
28
28
|
function hasVisibleChildren(children) {
|
|
29
29
|
let visible = false;
|
|
30
30
|
React.Children.forEach(children, child => {
|
|
@@ -34,7 +34,6 @@ function hasVisibleChildren(children) {
|
|
|
34
34
|
});
|
|
35
35
|
return visible;
|
|
36
36
|
}
|
|
37
|
-
|
|
38
37
|
export default hasVisibleChildren;
|
|
39
38
|
export {
|
|
40
39
|
/**
|
package/es/index.js
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
+
|
|
24
25
|
export { FocusRegion } from './FocusRegion';
|
|
25
26
|
export { FocusRegionManager } from './FocusRegionManager';
|
|
26
27
|
export { hasVisibleChildren } from './hasVisibleChildren';
|
package/es/scopeTab.js
CHANGED
|
@@ -21,43 +21,39 @@
|
|
|
21
21
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
-
import { findDOMNode, findTabbable, isActiveElement, containsActiveElement, getActiveElement } from '@instructure/ui-dom-utils';
|
|
25
24
|
|
|
25
|
+
import { findDOMNode, findTabbable, isActiveElement, containsActiveElement, getActiveElement } from '@instructure/ui-dom-utils';
|
|
26
26
|
function scopeTab(element, event, onLeavingFinalTabbable) {
|
|
27
27
|
const node = findDOMNode(element);
|
|
28
28
|
const tabbable = findTabbable(node);
|
|
29
|
-
|
|
30
29
|
if (!tabbable.length) {
|
|
31
30
|
event.preventDefault();
|
|
32
31
|
return;
|
|
33
|
-
}
|
|
34
|
-
// (a case that happens with Menu for KO a11y)
|
|
35
|
-
|
|
32
|
+
}
|
|
36
33
|
|
|
34
|
+
// Account for a changing tabindex of the active element
|
|
35
|
+
// (a case that happens with Menu for KO a11y)
|
|
37
36
|
if (containsActiveElement(element)) {
|
|
38
37
|
const activeElement = getActiveElement();
|
|
39
|
-
|
|
40
38
|
if (activeElement && tabbable.indexOf(activeElement) === -1) {
|
|
41
39
|
tabbable.push(activeElement);
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
|
-
|
|
45
42
|
const finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1];
|
|
46
|
-
const leavingFinalTabbable = isActiveElement(finalTabbable) ||
|
|
47
|
-
|
|
43
|
+
const leavingFinalTabbable = isActiveElement(finalTabbable) ||
|
|
44
|
+
// handle immediate shift+tab after opening with mouse
|
|
45
|
+
isActiveElement(node) ||
|
|
46
|
+
// already left final tabbable
|
|
48
47
|
!containsActiveElement(element);
|
|
49
48
|
if (!leavingFinalTabbable) return;
|
|
50
|
-
|
|
51
49
|
if (typeof onLeavingFinalTabbable === 'function') {
|
|
52
50
|
onLeavingFinalTabbable();
|
|
53
51
|
return;
|
|
54
52
|
}
|
|
55
|
-
|
|
56
53
|
event.preventDefault();
|
|
57
54
|
const target = tabbable[event.shiftKey ? tabbable.length - 1 : 0];
|
|
58
55
|
target.focus();
|
|
59
56
|
}
|
|
60
|
-
|
|
61
57
|
export default scopeTab;
|
|
62
58
|
export {
|
|
63
59
|
/**
|
package/lib/FocusRegion.js
CHANGED
|
@@ -1,30 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
-
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports.default = exports.FocusRegion = void 0;
|
|
9
|
-
|
|
10
8
|
var _keycode = _interopRequireDefault(require("keycode"));
|
|
11
|
-
|
|
12
9
|
var _contains = require("@instructure/ui-dom-utils/lib/contains.js");
|
|
13
|
-
|
|
14
10
|
var _addEventListener = require("@instructure/ui-dom-utils/lib/addEventListener.js");
|
|
15
|
-
|
|
16
11
|
var _ownerDocument = require("@instructure/ui-dom-utils/lib/ownerDocument.js");
|
|
17
|
-
|
|
18
12
|
var _findTabbable = require("@instructure/ui-dom-utils/lib/findTabbable.js");
|
|
19
|
-
|
|
20
13
|
var _uid = require("@instructure/uid");
|
|
21
|
-
|
|
22
14
|
var _console = require("@instructure/console");
|
|
23
|
-
|
|
24
15
|
var _ScreenReaderFocusRegion = require("./ScreenReaderFocusRegion");
|
|
25
|
-
|
|
26
16
|
var _KeyboardFocusRegion = require("./KeyboardFocusRegion");
|
|
27
|
-
|
|
28
17
|
/*
|
|
29
18
|
* The MIT License (MIT)
|
|
30
19
|
*
|
|
@@ -48,6 +37,7 @@ var _KeyboardFocusRegion = require("./KeyboardFocusRegion");
|
|
|
48
37
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
49
38
|
* SOFTWARE.
|
|
50
39
|
*/
|
|
40
|
+
|
|
51
41
|
class FocusRegion {
|
|
52
42
|
constructor(element, options) {
|
|
53
43
|
this._contextElement = null;
|
|
@@ -58,37 +48,30 @@ class FocusRegion {
|
|
|
58
48
|
this._id = void 0;
|
|
59
49
|
this._listeners = [];
|
|
60
50
|
this._active = false;
|
|
61
|
-
|
|
62
51
|
this.handleDismiss = (event, documentClick) => {
|
|
63
52
|
var _this$_options$onDism, _this$_options;
|
|
64
|
-
|
|
65
53
|
(_this$_options$onDism = (_this$_options = this._options).onDismiss) === null || _this$_options$onDism === void 0 ? void 0 : _this$_options$onDism.call(_this$_options, event, documentClick);
|
|
66
54
|
};
|
|
67
|
-
|
|
68
55
|
this.captureDocumentClick = event => {
|
|
69
56
|
const target = event.target;
|
|
70
57
|
this._preventCloseOnDocumentClick = event.button !== 0 || (0, _contains.contains)(this._contextElement, target);
|
|
71
58
|
};
|
|
72
|
-
|
|
73
59
|
this.handleDocumentClick = event => {
|
|
74
60
|
if (this._options.shouldCloseOnDocumentClick && !this._preventCloseOnDocumentClick) {
|
|
75
61
|
this.handleDismiss(event, true);
|
|
76
62
|
}
|
|
77
63
|
};
|
|
78
|
-
|
|
79
64
|
this.handleFrameClick = (event, frame) => {
|
|
80
65
|
if (!(0, _contains.contains)(this._contextElement, frame)) {
|
|
81
66
|
// dismiss if frame is not within the region
|
|
82
67
|
this.handleDismiss(event, true);
|
|
83
68
|
}
|
|
84
69
|
};
|
|
85
|
-
|
|
86
70
|
this.handleKeyUp = event => {
|
|
87
71
|
if (this._options.shouldCloseOnEscape && event.keyCode === _keycode.default.codes.esc && !event.defaultPrevented) {
|
|
88
72
|
this.handleDismiss(event);
|
|
89
73
|
}
|
|
90
74
|
};
|
|
91
|
-
|
|
92
75
|
this._options = options || {
|
|
93
76
|
shouldCloseOnDocumentClick: true,
|
|
94
77
|
shouldCloseOnEscape: true
|
|
@@ -98,54 +81,41 @@ class FocusRegion {
|
|
|
98
81
|
this._keyboardFocusRegion = new _KeyboardFocusRegion.KeyboardFocusRegion(element, options);
|
|
99
82
|
this._id = (0, _uid.uid)();
|
|
100
83
|
}
|
|
101
|
-
|
|
102
84
|
updateElement(element, options) {
|
|
103
85
|
this._contextElement = element;
|
|
104
|
-
|
|
105
86
|
if (options) {
|
|
106
87
|
this._options = options;
|
|
107
88
|
}
|
|
108
|
-
|
|
109
89
|
if (this._keyboardFocusRegion) {
|
|
110
90
|
this._keyboardFocusRegion.updateElement(element);
|
|
111
91
|
}
|
|
112
|
-
|
|
113
92
|
if (this._screenReaderFocusRegion) {
|
|
114
93
|
this._screenReaderFocusRegion.updateElement(element);
|
|
115
94
|
}
|
|
116
95
|
}
|
|
117
|
-
|
|
118
96
|
get id() {
|
|
119
97
|
return this._id;
|
|
120
|
-
}
|
|
121
|
-
// is inconsistent across browsers (Safari/Firefox do not focus elements on click)
|
|
122
|
-
|
|
98
|
+
}
|
|
123
99
|
|
|
100
|
+
// Focused returns when the focus region is active. Checking focused with the active element
|
|
101
|
+
// is inconsistent across browsers (Safari/Firefox do not focus elements on click)
|
|
124
102
|
get focused() {
|
|
125
103
|
return this._active;
|
|
126
104
|
}
|
|
127
|
-
|
|
128
105
|
get keyboardFocusable() {
|
|
129
106
|
return ((0, _findTabbable.findTabbable)(this._contextElement) || []).length > 0;
|
|
130
107
|
}
|
|
131
|
-
|
|
132
108
|
activate() {
|
|
133
109
|
if (!this._active) {
|
|
134
110
|
const doc = (0, _ownerDocument.ownerDocument)(this._contextElement);
|
|
135
|
-
|
|
136
111
|
this._keyboardFocusRegion.activate();
|
|
137
|
-
|
|
138
112
|
this._screenReaderFocusRegion.activate();
|
|
139
|
-
|
|
140
113
|
if (this._options.shouldCloseOnDocumentClick) {
|
|
141
114
|
this._listeners.push((0, _addEventListener.addEventListener)(doc, 'click', this.captureDocumentClick, true));
|
|
142
|
-
|
|
143
115
|
this._listeners.push((0, _addEventListener.addEventListener)(doc, 'click', this.handleDocumentClick));
|
|
144
|
-
|
|
145
116
|
Array.from(doc.getElementsByTagName('iframe')).forEach(el => {
|
|
146
117
|
// listen for mouseup events on any iframes in the document
|
|
147
118
|
const frameDoc = el.contentDocument;
|
|
148
|
-
|
|
149
119
|
if (frameDoc) {
|
|
150
120
|
this._listeners.push((0, _addEventListener.addEventListener)(frameDoc, 'mouseup', event => {
|
|
151
121
|
this.handleFrameClick(event, el);
|
|
@@ -153,51 +123,37 @@ class FocusRegion {
|
|
|
153
123
|
}
|
|
154
124
|
});
|
|
155
125
|
}
|
|
156
|
-
|
|
157
126
|
if (this._options.shouldCloseOnEscape) {
|
|
158
127
|
this._listeners.push((0, _addEventListener.addEventListener)(doc, 'keyup', this.handleKeyUp));
|
|
159
128
|
}
|
|
160
|
-
|
|
161
129
|
this._active = true;
|
|
162
130
|
}
|
|
163
131
|
}
|
|
164
|
-
|
|
165
132
|
deactivate() {
|
|
166
133
|
let _ref = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {},
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
134
|
+
_ref$keyboard = _ref.keyboard,
|
|
135
|
+
keyboard = _ref$keyboard === void 0 ? true : _ref$keyboard;
|
|
170
136
|
if (this._active) {
|
|
171
137
|
this._listeners.forEach(listener => {
|
|
172
138
|
listener.remove();
|
|
173
139
|
});
|
|
174
|
-
|
|
175
140
|
this._listeners = [];
|
|
176
|
-
|
|
177
141
|
if (keyboard) {
|
|
178
142
|
this._keyboardFocusRegion.deactivate();
|
|
179
143
|
}
|
|
180
|
-
|
|
181
144
|
this._screenReaderFocusRegion.deactivate();
|
|
182
|
-
|
|
183
145
|
this._active = false;
|
|
184
146
|
}
|
|
185
147
|
}
|
|
186
|
-
|
|
187
148
|
focus() {
|
|
188
149
|
(0, _console.logError)(this._active, `[FocusRegion] Cannot call '.focus()' on a region that is not currently active.`);
|
|
189
|
-
|
|
190
150
|
this._keyboardFocusRegion.focus();
|
|
191
151
|
}
|
|
192
|
-
|
|
193
152
|
blur() {
|
|
194
153
|
(0, _console.logError)(!this._active, `[FocusRegion] Cannot call '.blur()' on a region that is currently active.`);
|
|
195
|
-
|
|
196
154
|
this._keyboardFocusRegion.blur();
|
|
197
155
|
}
|
|
198
|
-
|
|
199
156
|
}
|
|
200
|
-
|
|
201
157
|
exports.FocusRegion = FocusRegion;
|
|
202
158
|
var _default = FocusRegion;
|
|
203
159
|
exports.default = _default;
|
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.FocusRegionManager = void 0;
|
|
7
|
-
|
|
8
7
|
var _console = require("@instructure/console");
|
|
9
|
-
|
|
10
8
|
var _FocusRegion = require("./FocusRegion");
|
|
11
|
-
|
|
12
9
|
/*
|
|
13
10
|
* The MIT License (MIT)
|
|
14
11
|
*
|
|
@@ -32,62 +29,49 @@ var _FocusRegion = require("./FocusRegion");
|
|
|
32
29
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
33
30
|
* SOFTWARE.
|
|
34
31
|
*/
|
|
35
|
-
let ENTRIES = [];
|
|
36
32
|
|
|
33
|
+
let ENTRIES = [];
|
|
37
34
|
class FocusRegionManager {}
|
|
38
|
-
|
|
39
35
|
exports.FocusRegionManager = FocusRegionManager;
|
|
40
|
-
|
|
41
36
|
FocusRegionManager.focusRegion = function (element) {
|
|
42
37
|
let idOrOptions = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
43
38
|
let entry;
|
|
44
|
-
|
|
45
39
|
if (typeof idOrOptions === 'string') {
|
|
46
40
|
entry = FocusRegionManager.getEntry(element, idOrOptions);
|
|
47
41
|
} else {
|
|
48
42
|
entry = FocusRegionManager.addEntry(element, idOrOptions);
|
|
49
43
|
}
|
|
50
|
-
|
|
51
44
|
if (entry && entry.region && typeof entry.region.focus === 'function') {
|
|
52
45
|
entry.region.focus();
|
|
53
46
|
return entry.region;
|
|
54
47
|
} else {
|
|
55
48
|
(0, _console.logError)(false, `[FocusRegionManager] Could not focus region with element: ${element}`);
|
|
56
49
|
}
|
|
57
|
-
|
|
58
50
|
return;
|
|
59
51
|
};
|
|
60
|
-
|
|
61
52
|
FocusRegionManager.activateRegion = (element, options) => {
|
|
62
53
|
const _FocusRegionManager$a = FocusRegionManager.addEntry(element, options),
|
|
63
|
-
|
|
64
|
-
|
|
54
|
+
region = _FocusRegionManager$a.region;
|
|
65
55
|
return region;
|
|
66
56
|
};
|
|
67
|
-
|
|
68
57
|
FocusRegionManager.getActiveEntry = () => {
|
|
69
58
|
return ENTRIES.find(_ref => {
|
|
70
59
|
let region = _ref.region;
|
|
71
60
|
return region.focused;
|
|
72
61
|
});
|
|
73
62
|
};
|
|
74
|
-
|
|
75
63
|
FocusRegionManager.findEntry = (element, id) => {
|
|
76
64
|
let index;
|
|
77
|
-
|
|
78
65
|
if (id) {
|
|
79
66
|
index = ENTRIES.findIndex(entry => entry.id === id);
|
|
80
67
|
} else {
|
|
81
68
|
index = ENTRIES.findIndex(entry => entry.element === element);
|
|
82
69
|
}
|
|
83
|
-
|
|
84
70
|
return index;
|
|
85
71
|
};
|
|
86
|
-
|
|
87
72
|
FocusRegionManager.getEntry = (element, id) => {
|
|
88
73
|
return ENTRIES[FocusRegionManager.findEntry(element, id)];
|
|
89
74
|
};
|
|
90
|
-
|
|
91
75
|
FocusRegionManager.addEntry = function (element) {
|
|
92
76
|
let options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
93
77
|
const region = new _FocusRegion.FocusRegion(element, options);
|
|
@@ -95,7 +79,6 @@ FocusRegionManager.addEntry = function (element) {
|
|
|
95
79
|
const keyboardFocusable = region.keyboardFocusable;
|
|
96
80
|
ENTRIES.forEach(_ref2 => {
|
|
97
81
|
let region = _ref2.region;
|
|
98
|
-
|
|
99
82
|
if (region) {
|
|
100
83
|
// If the active region is triggering a new focus region that does not have
|
|
101
84
|
// keyboard focusable content, don't deactivate the active region's keyboard
|
|
@@ -107,11 +90,9 @@ FocusRegionManager.addEntry = function (element) {
|
|
|
107
90
|
}
|
|
108
91
|
});
|
|
109
92
|
region.activate();
|
|
110
|
-
|
|
111
93
|
if (options.shouldFocusOnOpen) {
|
|
112
94
|
region.focus();
|
|
113
95
|
}
|
|
114
|
-
|
|
115
96
|
const entry = {
|
|
116
97
|
id: region.id,
|
|
117
98
|
element,
|
|
@@ -120,63 +101,54 @@ FocusRegionManager.addEntry = function (element) {
|
|
|
120
101
|
parent: activeEntry
|
|
121
102
|
};
|
|
122
103
|
ENTRIES.push(entry);
|
|
123
|
-
|
|
124
104
|
if (activeEntry) {
|
|
125
105
|
activeEntry.children.push(entry);
|
|
126
106
|
}
|
|
127
|
-
|
|
128
107
|
return entry;
|
|
129
108
|
};
|
|
130
|
-
|
|
131
109
|
FocusRegionManager.removeEntry = (element, id) => {
|
|
132
110
|
const index = FocusRegionManager.findEntry(element, id);
|
|
133
111
|
const entry = ENTRIES[index];
|
|
134
|
-
|
|
135
112
|
if (index > -1) {
|
|
136
113
|
ENTRIES.splice(index, 1);
|
|
137
114
|
}
|
|
138
|
-
|
|
139
115
|
return entry;
|
|
140
116
|
};
|
|
141
|
-
|
|
142
117
|
FocusRegionManager.isFocused = (element, id) => {
|
|
143
118
|
const entry = FocusRegionManager.getActiveEntry();
|
|
144
|
-
|
|
145
119
|
if (id) {
|
|
146
120
|
return entry && entry.region && entry.id === id;
|
|
147
121
|
} else {
|
|
148
122
|
return entry && entry.region && entry.element === element;
|
|
149
123
|
}
|
|
150
124
|
};
|
|
151
|
-
|
|
152
125
|
FocusRegionManager.clearEntries = () => {
|
|
153
126
|
ENTRIES = [];
|
|
154
127
|
};
|
|
155
|
-
|
|
156
128
|
FocusRegionManager.blurRegion = (element, id) => {
|
|
157
129
|
const entry = FocusRegionManager.removeEntry(element, id);
|
|
158
|
-
|
|
159
130
|
if (entry) {
|
|
160
131
|
const children = entry.children,
|
|
161
|
-
|
|
162
|
-
|
|
132
|
+
region = entry.region,
|
|
133
|
+
parent = entry.parent;
|
|
163
134
|
|
|
164
|
-
|
|
135
|
+
// deactivate the region...
|
|
136
|
+
region && region.deactivate();
|
|
165
137
|
|
|
138
|
+
// and any regions created from it
|
|
166
139
|
if (children) {
|
|
167
140
|
children.forEach(_ref3 => {
|
|
168
141
|
let id = _ref3.id,
|
|
169
|
-
|
|
142
|
+
element = _ref3.element;
|
|
170
143
|
const entry = FocusRegionManager.removeEntry(element, id);
|
|
171
144
|
entry && entry.region && entry.region.deactivate();
|
|
172
145
|
});
|
|
173
|
-
}
|
|
174
|
-
|
|
146
|
+
}
|
|
175
147
|
|
|
148
|
+
// activate the region's parent if it exists
|
|
176
149
|
parent && parent.region && parent.region.activate();
|
|
177
150
|
region && region.blur(); // this should focus the parent region
|
|
178
151
|
}
|
|
179
152
|
};
|
|
180
|
-
|
|
181
153
|
var _default = FocusRegionManager;
|
|
182
154
|
exports.default = _default;
|