focus-trap 6.9.4 → 7.1.0

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * focus-trap 6.9.4
2
+ * focus-trap 7.1.0
3
3
  * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
4
4
  */
5
5
  (function (global, factory) {
@@ -15,17 +15,14 @@
15
15
 
16
16
  function ownKeys(object, enumerableOnly) {
17
17
  var keys = Object.keys(object);
18
-
19
18
  if (Object.getOwnPropertySymbols) {
20
19
  var symbols = Object.getOwnPropertySymbols(object);
21
20
  enumerableOnly && (symbols = symbols.filter(function (sym) {
22
21
  return Object.getOwnPropertyDescriptor(object, sym).enumerable;
23
22
  })), keys.push.apply(keys, symbols);
24
23
  }
25
-
26
24
  return keys;
27
25
  }
28
-
29
26
  function _objectSpread2(target) {
30
27
  for (var i = 1; i < arguments.length; i++) {
31
28
  var source = null != arguments[i] ? arguments[i] : {};
@@ -35,10 +32,8 @@
35
32
  Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
36
33
  });
37
34
  }
38
-
39
35
  return target;
40
36
  }
41
-
42
37
  function _defineProperty(obj, key, value) {
43
38
  if (key in obj) {
44
39
  Object.defineProperty(obj, key, {
@@ -50,64 +45,52 @@
50
45
  } else {
51
46
  obj[key] = value;
52
47
  }
53
-
54
48
  return obj;
55
49
  }
56
50
 
57
- var activeFocusTraps = function () {
58
- var trapQueue = [];
59
- return {
60
- activateTrap: function activateTrap(trap) {
61
- if (trapQueue.length > 0) {
62
- var activeTrap = trapQueue[trapQueue.length - 1];
63
-
64
- if (activeTrap !== trap) {
65
- activeTrap.pause();
66
- }
67
- }
68
-
69
- var trapIndex = trapQueue.indexOf(trap);
70
-
71
- if (trapIndex === -1) {
72
- trapQueue.push(trap);
73
- } else {
74
- // move this existing trap to the front of the queue
75
- trapQueue.splice(trapIndex, 1);
76
- trapQueue.push(trap);
77
- }
78
- },
79
- deactivateTrap: function deactivateTrap(trap) {
80
- var trapIndex = trapQueue.indexOf(trap);
81
-
82
- if (trapIndex !== -1) {
83
- trapQueue.splice(trapIndex, 1);
84
- }
85
-
86
- if (trapQueue.length > 0) {
87
- trapQueue[trapQueue.length - 1].unpause();
51
+ var rooTrapStack = [];
52
+ var activeFocusTraps = {
53
+ activateTrap: function activateTrap(trapStack, trap) {
54
+ if (trapStack.length > 0) {
55
+ var activeTrap = trapStack[trapStack.length - 1];
56
+ if (activeTrap !== trap) {
57
+ activeTrap.pause();
88
58
  }
89
59
  }
90
- };
91
- }();
92
-
60
+ var trapIndex = trapStack.indexOf(trap);
61
+ if (trapIndex === -1) {
62
+ trapStack.push(trap);
63
+ } else {
64
+ // move this existing trap to the front of the queue
65
+ trapStack.splice(trapIndex, 1);
66
+ trapStack.push(trap);
67
+ }
68
+ },
69
+ deactivateTrap: function deactivateTrap(trapStack, trap) {
70
+ var trapIndex = trapStack.indexOf(trap);
71
+ if (trapIndex !== -1) {
72
+ trapStack.splice(trapIndex, 1);
73
+ }
74
+ if (trapStack.length > 0) {
75
+ trapStack[trapStack.length - 1].unpause();
76
+ }
77
+ }
78
+ };
93
79
  var isSelectableInput = function isSelectableInput(node) {
94
80
  return node.tagName && node.tagName.toLowerCase() === 'input' && typeof node.select === 'function';
95
81
  };
96
-
97
82
  var isEscapeEvent = function isEscapeEvent(e) {
98
83
  return e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27;
99
84
  };
100
-
101
85
  var isTabEvent = function isTabEvent(e) {
102
86
  return e.key === 'Tab' || e.keyCode === 9;
103
87
  };
104
-
105
88
  var delay = function delay(fn) {
106
89
  return setTimeout(fn, 0);
107
- }; // Array.find/findIndex() are not supported on IE; this replicates enough
108
- // of Array.findIndex() for our needs
109
-
90
+ };
110
91
 
92
+ // Array.find/findIndex() are not supported on IE; this replicates enough
93
+ // of Array.findIndex() for our needs
111
94
  var findIndex = function findIndex(arr, fn) {
112
95
  var idx = -1;
113
96
  arr.every(function (value, i) {
@@ -118,8 +101,10 @@
118
101
 
119
102
  return true; // next
120
103
  });
104
+
121
105
  return idx;
122
106
  };
107
+
123
108
  /**
124
109
  * Get an option's value when it could be a plain value, or a handler that provides
125
110
  * the value.
@@ -127,16 +112,12 @@
127
112
  * @param {...*} [params] Any parameters to pass to the handler, if `value` is a function.
128
113
  * @returns {*} The `value`, or the handler's returned value.
129
114
  */
130
-
131
-
132
115
  var valueOrHandler = function valueOrHandler(value) {
133
116
  for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
134
117
  params[_key - 1] = arguments[_key];
135
118
  }
136
-
137
119
  return typeof value === 'function' ? value.apply(void 0, params) : value;
138
120
  };
139
-
140
121
  var getActualTarget = function getActualTarget(event) {
141
122
  // NOTE: If the trap is _inside_ a shadow DOM, event.target will always be the
142
123
  // shadow host. However, event.target.composedPath() will be an array of
@@ -147,18 +128,16 @@
147
128
  // composedPath()[0] === event.target always).
148
129
  return event.target.shadowRoot && typeof event.composedPath === 'function' ? event.composedPath()[0] : event.target;
149
130
  };
150
-
151
131
  var createFocusTrap = function createFocusTrap(elements, userOptions) {
152
132
  // SSR: a live trap shouldn't be created in this type of environment so this
153
133
  // should be safe code to execute if the `document` option isn't specified
154
134
  var doc = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.document) || document;
155
-
135
+ var trapStack = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.trapStack) || rooTrapStack;
156
136
  var config = _objectSpread2({
157
137
  returnFocusOnDeactivate: true,
158
138
  escapeDeactivates: true,
159
139
  delayInitialFocus: true
160
140
  }, userOptions);
161
-
162
141
  var state = {
163
142
  // containers given to createFocusTrap()
164
143
  // @type {Array<HTMLElement>}
@@ -178,6 +157,7 @@
178
157
  // }>}
179
158
  containerGroups: [],
180
159
  // same order/length as `containers` list
160
+
181
161
  // references to objects in `containerGroups`, but only those that actually have
182
162
  // tabbable nodes in them
183
163
  // NOTE: same order as `containers` and `containerGroups`, but __not necessarily__
@@ -201,10 +181,10 @@
201
181
  * @param {string|undefined} [configOptionName] Name of option to use __instead of__ `optionName`
202
182
  * IIF `configOverrideOptions` is not defined. Otherwise, `optionName` is used.
203
183
  */
204
-
205
184
  var getOption = function getOption(configOverrideOptions, optionName, configOptionName) {
206
185
  return configOverrideOptions && configOverrideOptions[optionName] !== undefined ? configOverrideOptions[optionName] : config[configOptionName || optionName];
207
186
  };
187
+
208
188
  /**
209
189
  * Finds the index of the container that contains the element.
210
190
  * @param {HTMLElement} element
@@ -212,16 +192,15 @@
212
192
  * `state.containerGroups` (the order/length of these lists are the same); -1
213
193
  * if the element isn't found.
214
194
  */
215
-
216
-
217
195
  var findContainerIndex = function findContainerIndex(element) {
218
196
  // NOTE: search `containerGroups` because it's possible a group contains no tabbable
219
197
  // nodes, but still contains focusable nodes (e.g. if they all have `tabindex=-1`)
220
198
  // and we still need to find the element in there
221
199
  return state.containerGroups.findIndex(function (_ref) {
222
200
  var container = _ref.container,
223
- tabbableNodes = _ref.tabbableNodes;
224
- return container.contains(element) || // fall back to explicit tabbable search which will take into consideration any
201
+ tabbableNodes = _ref.tabbableNodes;
202
+ return container.contains(element) ||
203
+ // fall back to explicit tabbable search which will take into consideration any
225
204
  // web components if the `tabbableOptions.getShadowRoot` option was used for
226
205
  // the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't
227
206
  // look inside web components even if open)
@@ -230,6 +209,7 @@
230
209
  });
231
210
  });
232
211
  };
212
+
233
213
  /**
234
214
  * Gets the node for the given option, which is expected to be an option that
235
215
  * can be either a DOM node, a string that is a selector to get a node, `false`
@@ -243,19 +223,14 @@
243
223
  * @throws {Error} If the option is set, not `false`, and is not, or does not
244
224
  * resolve to a node.
245
225
  */
246
-
247
-
248
226
  var getNodeForOption = function getNodeForOption(optionName) {
249
227
  var optionValue = config[optionName];
250
-
251
228
  if (typeof optionValue === 'function') {
252
229
  for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
253
230
  params[_key2 - 1] = arguments[_key2];
254
231
  }
255
-
256
232
  optionValue = optionValue.apply(void 0, params);
257
233
  }
258
-
259
234
  if (optionValue === true) {
260
235
  optionValue = undefined; // use default value
261
236
  }
@@ -263,56 +238,51 @@
263
238
  if (!optionValue) {
264
239
  if (optionValue === undefined || optionValue === false) {
265
240
  return optionValue;
266
- } // else, empty string (invalid), null (invalid), 0 (invalid)
267
-
241
+ }
242
+ // else, empty string (invalid), null (invalid), 0 (invalid)
268
243
 
269
244
  throw new Error("`".concat(optionName, "` was specified but was not a node, or did not return a node"));
270
245
  }
271
-
272
246
  var node = optionValue; // could be HTMLElement, SVGElement, or non-empty string at this point
273
247
 
274
248
  if (typeof optionValue === 'string') {
275
249
  node = doc.querySelector(optionValue); // resolve to node, or null if fails
276
-
277
250
  if (!node) {
278
251
  throw new Error("`".concat(optionName, "` as selector refers to no known node"));
279
252
  }
280
253
  }
281
-
282
254
  return node;
283
255
  };
284
-
285
256
  var getInitialFocusNode = function getInitialFocusNode() {
286
- var node = getNodeForOption('initialFocus'); // false explicitly indicates we want no initialFocus at all
257
+ var node = getNodeForOption('initialFocus');
287
258
 
259
+ // false explicitly indicates we want no initialFocus at all
288
260
  if (node === false) {
289
261
  return false;
290
262
  }
291
-
292
263
  if (node === undefined) {
293
264
  // option not specified: use fallback options
294
265
  if (findContainerIndex(doc.activeElement) >= 0) {
295
266
  node = doc.activeElement;
296
267
  } else {
297
268
  var firstTabbableGroup = state.tabbableGroups[0];
298
- var firstTabbableNode = firstTabbableGroup && firstTabbableGroup.firstTabbableNode; // NOTE: `fallbackFocus` option function cannot return `false` (not supported)
269
+ var firstTabbableNode = firstTabbableGroup && firstTabbableGroup.firstTabbableNode;
299
270
 
271
+ // NOTE: `fallbackFocus` option function cannot return `false` (not supported)
300
272
  node = firstTabbableNode || getNodeForOption('fallbackFocus');
301
273
  }
302
274
  }
303
-
304
275
  if (!node) {
305
276
  throw new Error('Your focus-trap needs to have at least one focusable element');
306
277
  }
307
-
308
278
  return node;
309
279
  };
310
-
311
280
  var updateTabbableNodes = function updateTabbableNodes() {
312
281
  state.containerGroups = state.containers.map(function (container) {
313
- var tabbableNodes = tabbable.tabbable(container, config.tabbableOptions); // NOTE: if we have tabbable nodes, we must have focusable nodes; focusable nodes
314
- // are a superset of tabbable nodes
282
+ var tabbableNodes = tabbable.tabbable(container, config.tabbableOptions);
315
283
 
284
+ // NOTE: if we have tabbable nodes, we must have focusable nodes; focusable nodes
285
+ // are a superset of tabbable nodes
316
286
  var focusableNodes = tabbable.focusable(container, config.tabbableOptions);
317
287
  return {
318
288
  container: container,
@@ -320,7 +290,6 @@
320
290
  focusableNodes: focusableNodes,
321
291
  firstTabbableNode: tabbableNodes.length > 0 ? tabbableNodes[0] : null,
322
292
  lastTabbableNode: tabbableNodes.length > 0 ? tabbableNodes[tabbableNodes.length - 1] : null,
323
-
324
293
  /**
325
294
  * Finds the __tabbable__ node that follows the given node in the specified direction,
326
295
  * in this container, if any.
@@ -344,17 +313,14 @@
344
313
  var nodeIdx = focusableNodes.findIndex(function (n) {
345
314
  return n === node;
346
315
  });
347
-
348
316
  if (nodeIdx < 0) {
349
317
  return undefined;
350
318
  }
351
-
352
319
  if (forward) {
353
320
  return focusableNodes.slice(nodeIdx + 1).find(function (n) {
354
321
  return tabbable.isTabbable(n, config.tabbableOptions);
355
322
  });
356
323
  }
357
-
358
324
  return focusableNodes.slice(0, nodeIdx).reverse().find(function (n) {
359
325
  return tabbable.isTabbable(n, config.tabbableOptions);
360
326
  });
@@ -363,53 +329,46 @@
363
329
  });
364
330
  state.tabbableGroups = state.containerGroups.filter(function (group) {
365
331
  return group.tabbableNodes.length > 0;
366
- }); // throw if no groups have tabbable nodes and we don't have a fallback focus node either
332
+ });
367
333
 
334
+ // throw if no groups have tabbable nodes and we don't have a fallback focus node either
368
335
  if (state.tabbableGroups.length <= 0 && !getNodeForOption('fallbackFocus') // returning false not supported for this option
369
336
  ) {
370
337
  throw new Error('Your focus-trap must have at least one container with at least one tabbable node in it at all times');
371
338
  }
372
339
  };
373
-
374
340
  var tryFocus = function tryFocus(node) {
375
341
  if (node === false) {
376
342
  return;
377
343
  }
378
-
379
344
  if (node === doc.activeElement) {
380
345
  return;
381
346
  }
382
-
383
347
  if (!node || !node.focus) {
384
348
  tryFocus(getInitialFocusNode());
385
349
  return;
386
350
  }
387
-
388
351
  node.focus({
389
352
  preventScroll: !!config.preventScroll
390
353
  });
391
354
  state.mostRecentlyFocusedNode = node;
392
-
393
355
  if (isSelectableInput(node)) {
394
356
  node.select();
395
357
  }
396
358
  };
397
-
398
359
  var getReturnFocusNode = function getReturnFocusNode(previousActiveElement) {
399
360
  var node = getNodeForOption('setReturnFocus', previousActiveElement);
400
361
  return node ? node : node === false ? false : previousActiveElement;
401
- }; // This needs to be done on mousedown and touchstart instead of click
402
- // so that it precedes the focus event.
403
-
362
+ };
404
363
 
364
+ // This needs to be done on mousedown and touchstart instead of click
365
+ // so that it precedes the focus event.
405
366
  var checkPointerDown = function checkPointerDown(e) {
406
367
  var target = getActualTarget(e);
407
-
408
368
  if (findContainerIndex(target) >= 0) {
409
369
  // allow the click since it ocurred inside the trap
410
370
  return;
411
371
  }
412
-
413
372
  if (valueOrHandler(config.clickOutsideDeactivates, e)) {
414
373
  // immediately deactivate the trap
415
374
  trap.deactivate({
@@ -427,25 +386,26 @@
427
386
  returnFocus: config.returnFocusOnDeactivate && !tabbable.isFocusable(target, config.tabbableOptions)
428
387
  });
429
388
  return;
430
- } // This is needed for mobile devices.
389
+ }
390
+
391
+ // This is needed for mobile devices.
431
392
  // (If we'll only let `click` events through,
432
393
  // then on mobile they will be blocked anyways if `touchstart` is blocked.)
433
-
434
-
435
394
  if (valueOrHandler(config.allowOutsideClick, e)) {
436
395
  // allow the click outside the trap to take place
437
396
  return;
438
- } // otherwise, prevent the click
439
-
397
+ }
440
398
 
399
+ // otherwise, prevent the click
441
400
  e.preventDefault();
442
- }; // In case focus escapes the trap for some strange reason, pull it back in.
443
-
401
+ };
444
402
 
403
+ // In case focus escapes the trap for some strange reason, pull it back in.
445
404
  var checkFocusIn = function checkFocusIn(e) {
446
405
  var target = getActualTarget(e);
447
- var targetContained = findContainerIndex(target) >= 0; // In Firefox when you Tab out of an iframe the Document is briefly focused.
406
+ var targetContained = findContainerIndex(target) >= 0;
448
407
 
408
+ // In Firefox when you Tab out of an iframe the Document is briefly focused.
449
409
  if (targetContained || target instanceof Document) {
450
410
  if (targetContained) {
451
411
  state.mostRecentlyFocusedNode = target;
@@ -455,24 +415,22 @@
455
415
  e.stopImmediatePropagation();
456
416
  tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
457
417
  }
458
- }; // Hijack Tab events on the first and last focusable nodes of the trap,
418
+ };
419
+
420
+ // Hijack Tab events on the first and last focusable nodes of the trap,
459
421
  // in order to prevent focus from escaping. If it escapes for even a
460
422
  // moment it can end up scrolling the page and causing confusion so we
461
423
  // kind of need to capture the action at the keydown phase.
462
-
463
-
464
424
  var checkTab = function checkTab(e) {
465
425
  var target = getActualTarget(e);
466
426
  updateTabbableNodes();
467
427
  var destinationNode = null;
468
-
469
428
  if (state.tabbableGroups.length > 0) {
470
429
  // make sure the target is actually contained in a group
471
430
  // NOTE: the target may also be the container itself if it's focusable
472
431
  // with tabIndex='-1' and was given initial focus
473
432
  var containerIndex = findContainerIndex(target);
474
433
  var containerGroup = containerIndex >= 0 ? state.containerGroups[containerIndex] : undefined;
475
-
476
434
  if (containerIndex < 0) {
477
435
  // target not found in any group: quite possible focus has escaped the trap,
478
436
  // so bring it back in to...
@@ -485,12 +443,12 @@
485
443
  }
486
444
  } else if (e.shiftKey) {
487
445
  // REVERSE
446
+
488
447
  // is the target the first tabbable node in a group?
489
448
  var startOfGroupIndex = findIndex(state.tabbableGroups, function (_ref2) {
490
449
  var firstTabbableNode = _ref2.firstTabbableNode;
491
450
  return target === firstTabbableNode;
492
451
  });
493
-
494
452
  if (startOfGroupIndex < 0 && (containerGroup.container === target || tabbable.isFocusable(target, config.tabbableOptions) && !tabbable.isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) {
495
453
  // an exception case where the target is either the container itself, or
496
454
  // a non-tabbable node that was given focus (i.e. tabindex is negative
@@ -500,7 +458,6 @@
500
458
  // first tabbable node, and go to the last tabbable node of the LAST group
501
459
  startOfGroupIndex = containerIndex;
502
460
  }
503
-
504
461
  if (startOfGroupIndex >= 0) {
505
462
  // YES: then shift+tab should go to the last tabbable node in the
506
463
  // previous group (and wrap around to the last tabbable node of
@@ -511,12 +468,12 @@
511
468
  }
512
469
  } else {
513
470
  // FORWARD
471
+
514
472
  // is the target the last tabbable node in a group?
515
473
  var lastOfGroupIndex = findIndex(state.tabbableGroups, function (_ref3) {
516
474
  var lastTabbableNode = _ref3.lastTabbableNode;
517
475
  return target === lastTabbableNode;
518
476
  });
519
-
520
477
  if (lastOfGroupIndex < 0 && (containerGroup.container === target || tabbable.isFocusable(target, config.tabbableOptions) && !tabbable.isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) {
521
478
  // an exception case where the target is the container itself, or
522
479
  // a non-tabbable node that was given focus (i.e. tabindex is negative
@@ -526,13 +483,11 @@
526
483
  // last tabbable node, and go to the first tabbable node of the FIRST group
527
484
  lastOfGroupIndex = containerIndex;
528
485
  }
529
-
530
486
  if (lastOfGroupIndex >= 0) {
531
487
  // YES: then tab should go to the first tabbable node in the next
532
488
  // group (and wrap around to the first tabbable node of the FIRST
533
489
  // group if it's the last tabbable node of the LAST group)
534
490
  var _destinationGroupIndex = lastOfGroupIndex === state.tabbableGroups.length - 1 ? 0 : lastOfGroupIndex + 1;
535
-
536
491
  var _destinationGroup = state.tabbableGroups[_destinationGroupIndex];
537
492
  destinationNode = _destinationGroup.firstTabbableNode;
538
493
  }
@@ -541,12 +496,11 @@
541
496
  // NOTE: the fallbackFocus option does not support returning false to opt-out
542
497
  destinationNode = getNodeForOption('fallbackFocus');
543
498
  }
544
-
545
499
  if (destinationNode) {
546
500
  e.preventDefault();
547
501
  tryFocus(destinationNode);
548
- } // else, let the browser take care of [shift+]tab and move the focus
549
-
502
+ }
503
+ // else, let the browser take care of [shift+]tab and move the focus
550
504
  };
551
505
 
552
506
  var checkKey = function checkKey(e) {
@@ -555,44 +509,40 @@
555
509
  trap.deactivate();
556
510
  return;
557
511
  }
558
-
559
512
  if (isTabEvent(e)) {
560
513
  checkTab(e);
561
514
  return;
562
515
  }
563
516
  };
564
-
565
517
  var checkClick = function checkClick(e) {
566
518
  var target = getActualTarget(e);
567
-
568
519
  if (findContainerIndex(target) >= 0) {
569
520
  return;
570
521
  }
571
-
572
522
  if (valueOrHandler(config.clickOutsideDeactivates, e)) {
573
523
  return;
574
524
  }
575
-
576
525
  if (valueOrHandler(config.allowOutsideClick, e)) {
577
526
  return;
578
527
  }
579
-
580
528
  e.preventDefault();
581
529
  e.stopImmediatePropagation();
582
- }; //
530
+ };
531
+
532
+ //
583
533
  // EVENT LISTENERS
584
534
  //
585
535
 
586
-
587
536
  var addListeners = function addListeners() {
588
537
  if (!state.active) {
589
538
  return;
590
- } // There can be only one listening focus trap at a time
539
+ }
591
540
 
541
+ // There can be only one listening focus trap at a time
542
+ activeFocusTraps.activateTrap(trapStack, trap);
592
543
 
593
- activeFocusTraps.activateTrap(trap); // Delay ensures that the focused element doesn't capture the event
544
+ // Delay ensures that the focused element doesn't capture the event
594
545
  // that caused the focus trap activation.
595
-
596
546
  state.delayInitialFocusTimer = config.delayInitialFocus ? delay(function () {
597
547
  tryFocus(getInitialFocusNode());
598
548
  }) : tryFocus(getInitialFocusNode());
@@ -615,70 +565,58 @@
615
565
  });
616
566
  return trap;
617
567
  };
618
-
619
568
  var removeListeners = function removeListeners() {
620
569
  if (!state.active) {
621
570
  return;
622
571
  }
623
-
624
572
  doc.removeEventListener('focusin', checkFocusIn, true);
625
573
  doc.removeEventListener('mousedown', checkPointerDown, true);
626
574
  doc.removeEventListener('touchstart', checkPointerDown, true);
627
575
  doc.removeEventListener('click', checkClick, true);
628
576
  doc.removeEventListener('keydown', checkKey, true);
629
577
  return trap;
630
- }; //
578
+ };
579
+
580
+ //
631
581
  // TRAP DEFINITION
632
582
  //
633
583
 
634
-
635
584
  trap = {
636
585
  get active() {
637
586
  return state.active;
638
587
  },
639
-
640
588
  get paused() {
641
589
  return state.paused;
642
590
  },
643
-
644
591
  activate: function activate(activateOptions) {
645
592
  if (state.active) {
646
593
  return this;
647
594
  }
648
-
649
595
  var onActivate = getOption(activateOptions, 'onActivate');
650
596
  var onPostActivate = getOption(activateOptions, 'onPostActivate');
651
597
  var checkCanFocusTrap = getOption(activateOptions, 'checkCanFocusTrap');
652
-
653
598
  if (!checkCanFocusTrap) {
654
599
  updateTabbableNodes();
655
600
  }
656
-
657
601
  state.active = true;
658
602
  state.paused = false;
659
603
  state.nodeFocusedBeforeActivation = doc.activeElement;
660
-
661
604
  if (onActivate) {
662
605
  onActivate();
663
606
  }
664
-
665
607
  var finishActivation = function finishActivation() {
666
608
  if (checkCanFocusTrap) {
667
609
  updateTabbableNodes();
668
610
  }
669
-
670
611
  addListeners();
671
-
672
612
  if (onPostActivate) {
673
613
  onPostActivate();
674
614
  }
675
615
  };
676
-
677
616
  if (checkCanFocusTrap) {
678
617
  checkCanFocusTrap(state.containers.concat()).then(finishActivation, finishActivation);
679
618
  return this;
680
619
  }
681
-
682
620
  finishActivation();
683
621
  return this;
684
622
  },
@@ -686,46 +624,38 @@
686
624
  if (!state.active) {
687
625
  return this;
688
626
  }
689
-
690
627
  var options = _objectSpread2({
691
628
  onDeactivate: config.onDeactivate,
692
629
  onPostDeactivate: config.onPostDeactivate,
693
630
  checkCanReturnFocus: config.checkCanReturnFocus
694
631
  }, deactivateOptions);
695
-
696
632
  clearTimeout(state.delayInitialFocusTimer); // noop if undefined
697
-
698
633
  state.delayInitialFocusTimer = undefined;
699
634
  removeListeners();
700
635
  state.active = false;
701
636
  state.paused = false;
702
- activeFocusTraps.deactivateTrap(trap);
637
+ activeFocusTraps.deactivateTrap(trapStack, trap);
703
638
  var onDeactivate = getOption(options, 'onDeactivate');
704
639
  var onPostDeactivate = getOption(options, 'onPostDeactivate');
705
640
  var checkCanReturnFocus = getOption(options, 'checkCanReturnFocus');
706
641
  var returnFocus = getOption(options, 'returnFocus', 'returnFocusOnDeactivate');
707
-
708
642
  if (onDeactivate) {
709
643
  onDeactivate();
710
644
  }
711
-
712
645
  var finishDeactivation = function finishDeactivation() {
713
646
  delay(function () {
714
647
  if (returnFocus) {
715
648
  tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
716
649
  }
717
-
718
650
  if (onPostDeactivate) {
719
651
  onPostDeactivate();
720
652
  }
721
653
  });
722
654
  };
723
-
724
655
  if (returnFocus && checkCanReturnFocus) {
725
656
  checkCanReturnFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation)).then(finishDeactivation, finishDeactivation);
726
657
  return this;
727
658
  }
728
-
729
659
  finishDeactivation();
730
660
  return this;
731
661
  },
@@ -733,7 +663,6 @@
733
663
  if (state.paused || !state.active) {
734
664
  return this;
735
665
  }
736
-
737
666
  state.paused = true;
738
667
  removeListeners();
739
668
  return this;
@@ -742,7 +671,6 @@
742
671
  if (!state.paused || !state.active) {
743
672
  return this;
744
673
  }
745
-
746
674
  state.paused = false;
747
675
  updateTabbableNodes();
748
676
  addListeners();
@@ -753,15 +681,14 @@
753
681
  state.containers = elementsAsArray.map(function (element) {
754
682
  return typeof element === 'string' ? doc.querySelector(element) : element;
755
683
  });
756
-
757
684
  if (state.active) {
758
685
  updateTabbableNodes();
759
686
  }
760
-
761
687
  return this;
762
688
  }
763
- }; // initialize container elements
689
+ };
764
690
 
691
+ // initialize container elements
765
692
  trap.updateContainerElements(elements);
766
693
  return trap;
767
694
  };