wicg-inert 3.1.1 → 3.1.3

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/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  language: node_js
2
2
  node_js:
3
- - '8'
3
+ # 10 is good enough
4
4
  - '10'
5
5
  before_install:
6
6
  # package-lock.json was introduced in npm@5
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  All Reports in this Repository are licensed by Contributors
2
2
  under the
3
- [W3C Software and Document License](http://www.w3.org/Consortium/Legal/2015/copyright-software-and-document).
3
+ [W3C Software and Document License](https://www.w3.org/Consortium/Legal/2023/software-license.html).
4
4
 
5
5
  Contributions to Specifications are made under the
6
6
  [W3C CLA](https://www.w3.org/community/about/agreements/cla/).
package/README.md CHANGED
@@ -1,5 +1,3 @@
1
- [![Build Status](https://travis-ci.org/WICG/inert.svg?branch=master)](https://travis-ci.org/WICG/inert)
2
-
3
1
  The `inert` attribute/property allows web authors to mark parts of the DOM tree
4
2
  as [inert](https://html.spec.whatwg.org/multipage/interaction.html#inert):
5
3
 
@@ -31,9 +29,7 @@ ensure the version you're using is stable and thoroughly tested.
31
29
  This project provides two versions of the polyfill in `package.json`.
32
30
 
33
31
  - `main`: Points at `dist/inert.js` which is transpiled to ES3.
34
- - `module`: Points at `src/inert.js` which is _not_ transpiled and uses modern
35
- JavaScript. See [#136](https://github.com/WICG/inert/issues/136) if
36
- you would like to tell webpack to use the version in `main`.
32
+ - `module`: Points at `dist/inert.esm.js` which is transpiled to ES3.
37
33
 
38
34
  _If you do want to build from source, make sure you clone the latest tag!_
39
35
 
@@ -74,12 +70,12 @@ In accordance with the W3C's new [polyfill
74
70
  guidance](https://www.w3.org/2001/tag/doc/polyfills/#don-t-serve-unnecessary-polyfills),
75
71
  the `inert` polyfill does not bundle other polyfills.
76
72
 
77
- You can use a service like [Polyfill.io](https://polyfill.io/v2/docs/examples)
73
+ You can use a service like [https://cdnjs.cloudflare.com/polyfill](https://cdnjs.cloudflare.com/polyfill)
78
74
  to download only the polyfills needed by the current browser. Just add the
79
75
  following line to the start of your page:
80
76
 
81
77
  ```html
82
- <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Map,Set,Element.prototype.matches,Node.prototype.contains"></script>
78
+ <script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?version=4.8.0&features=Map%2CSet%2CElement.prototype.matches%2CNode.prototype.contains"></script>
83
79
  ```
84
80
 
85
81
  ### Strict Content Security Policy
@@ -106,7 +102,6 @@ The stylesheet should include the following rules:
106
102
  [inert], [inert] * {
107
103
  user-select: none;
108
104
  -webkit-user-select: none;
109
- -moz-user-select: none;
110
105
  -ms-user-select: none;
111
106
  }
112
107
  ```
@@ -149,7 +144,7 @@ Promise.resolve().then(() => {
149
144
  Tests are written using ES5 syntax. This is to avoid needing to transpile them
150
145
  for older browsers. There are a few modern features they rely upon, e.g.
151
146
  `Array.from` and `Promises`. These are polyfilled for the tests using
152
- [Polyfill.io](http://polyfill.io/). For a list of polyfilled features, check out
147
+ [https://cdnjs.cloudflare.com/polyfill](https://cdnjs.cloudflare.com/polyfill). For a list of polyfilled features, check out
153
148
  the `polyfill` section in `karma.conf.js`.
154
149
 
155
150
  ### Big Thanks
package/demo/index.html CHANGED
@@ -132,7 +132,7 @@ This work is licensed under the W3C Software and Document License
132
132
  </div>
133
133
  </section>
134
134
 
135
- <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Map,Set,Element.prototype.matches,Node.prototype.contains"></script>
135
+ <script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?version=4.8.0&features=Map%2CSet%2CElement.prototype.matches%2CNode.prototype.contains"></script>
136
136
  <script src="https://unpkg.com/wicg-inert"></script>
137
137
  <script>
138
138
  var toggler = document.querySelector('#toggle');
package/dist/inert.esm.js CHANGED
@@ -9,7 +9,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
9
9
 
10
10
  (function () {
11
11
  // Return early if we're not running inside of the browser.
12
- if (typeof window === 'undefined') {
12
+ if (typeof window === 'undefined' || typeof Element === 'undefined') {
13
13
  return;
14
14
  }
15
15
 
@@ -24,7 +24,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
24
24
  var matches = Element.prototype.matches || Element.prototype.msMatchesSelector;
25
25
 
26
26
  /** @type {string} */
27
- var _focusableElementsString = ['a[href]', 'area[href]', 'input:not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'details', 'summary', 'iframe', 'object', 'embed', '[contenteditable]'].join(',');
27
+ var _focusableElementsString = ['a[href]', 'area[href]', 'input:not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'details', 'summary', 'iframe', 'object', 'embed', 'video', '[contenteditable]'].join(',');
28
28
 
29
29
  /**
30
30
  * `InertRoot` manages a single inert subtree, i.e. a DOM subtree whose root element has an `inert`
@@ -45,7 +45,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
45
45
 
46
46
  var InertRoot = function () {
47
47
  /**
48
- * @param {!Element} rootElement The Element at the root of the inert subtree.
48
+ * @param {!HTMLElement} rootElement The HTMLElement at the root of the inert subtree.
49
49
  * @param {!InertManager} inertManager The global singleton InertManager object.
50
50
  */
51
51
  function InertRoot(rootElement, inertManager) {
@@ -54,7 +54,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
54
54
  /** @type {!InertManager} */
55
55
  this._inertManager = inertManager;
56
56
 
57
- /** @type {!Element} */
57
+ /** @type {!HTMLElement} */
58
58
  this._rootElement = rootElement;
59
59
 
60
60
  /**
@@ -176,7 +176,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
176
176
  if (node.nodeType !== Node.ELEMENT_NODE) {
177
177
  return;
178
178
  }
179
- var element = /** @type {!Element} */node;
179
+ var element = /** @type {!HTMLElement} */node;
180
180
 
181
181
  // If a descendant inert root becomes un-inert, its descendants will still be inert because of
182
182
  // this inert root, so all of its managed nodes need to be adopted by this InertRoot.
@@ -232,7 +232,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
232
232
 
233
233
  /**
234
234
  * If a descendant node is found with an `inert` attribute, adopt its managed nodes.
235
- * @param {!Element} node
235
+ * @param {!HTMLElement} node
236
236
  */
237
237
 
238
238
  }, {
@@ -262,7 +262,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
262
262
  key: '_onMutation',
263
263
  value: function _onMutation(records, self) {
264
264
  records.forEach(function (record) {
265
- var target = /** @type {!Element} */record.target;
265
+ var target = /** @type {!HTMLElement} */record.target;
266
266
  if (record.type === 'childList') {
267
267
  // Manage added nodes
268
268
  slice.call(record.addedNodes).forEach(function (node) {
@@ -381,7 +381,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
381
381
  this._throwIfDestroyed();
382
382
 
383
383
  if (this._node && this._node.nodeType === Node.ELEMENT_NODE) {
384
- var element = /** @type {!Element} */this._node;
384
+ var element = /** @type {!HTMLElement} */this._node;
385
385
  if (this._savedTabIndex !== null) {
386
386
  element.setAttribute('tabindex', this._savedTabIndex);
387
387
  } else {
@@ -429,7 +429,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
429
429
  if (this.node.nodeType !== Node.ELEMENT_NODE) {
430
430
  return;
431
431
  }
432
- var element = /** @type {!Element} */this.node;
432
+ var element = /** @type {!HTMLElement} */this.node;
433
433
  if (matches.call(element, _focusableElementsString)) {
434
434
  if ( /** @type {!HTMLElement} */element.tabIndex === -1 && this.hasSavedTabIndex) {
435
435
  return;
@@ -574,7 +574,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
574
574
 
575
575
  /**
576
576
  * Set whether the given element should be an inert root or not.
577
- * @param {!Element} root
577
+ * @param {!HTMLElement} root
578
578
  * @param {boolean} inert
579
579
  */
580
580
 
@@ -725,7 +725,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
725
725
  if (record.attributeName !== 'inert') {
726
726
  return;
727
727
  }
728
- var target = /** @type {!Element} */record.target;
728
+ var target = /** @type {!HTMLElement} */record.target;
729
729
  var inert = target.hasAttribute('inert');
730
730
  _this.setInert(target, inert);
731
731
  break;
@@ -740,7 +740,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
740
740
  /**
741
741
  * Recursively walk the composed tree from |node|.
742
742
  * @param {!Node} node
743
- * @param {(function (!Element))=} callback Callback to be called for each element traversed,
743
+ * @param {(function (!HTMLElement))=} callback Callback to be called for each element traversed,
744
744
  * before descending into child nodes.
745
745
  * @param {?ShadowRoot=} shadowRootAncestor The nearest ShadowRoot ancestor, if any.
746
746
  */
@@ -748,7 +748,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
748
748
 
749
749
  function composedTreeWalk(node, callback, shadowRootAncestor) {
750
750
  if (node.nodeType == Node.ELEMENT_NODE) {
751
- var element = /** @type {!Element} */node;
751
+ var element = /** @type {!HTMLElement} */node;
752
752
  if (callback) {
753
753
  callback(element);
754
754
  }
@@ -813,17 +813,17 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
813
813
  node.appendChild(style);
814
814
  }
815
815
 
816
- if (!Element.prototype.hasOwnProperty('inert')) {
816
+ if (!HTMLElement.prototype.hasOwnProperty('inert')) {
817
817
  /** @type {!InertManager} */
818
818
  var inertManager = new InertManager(document);
819
819
 
820
- Object.defineProperty(Element.prototype, 'inert', {
820
+ Object.defineProperty(HTMLElement.prototype, 'inert', {
821
821
  enumerable: true,
822
- /** @this {!Element} */
822
+ /** @this {!HTMLElement} */
823
823
  get: function get() {
824
824
  return this.hasAttribute('inert');
825
825
  },
826
- /** @this {!Element} */
826
+ /** @this {!HTMLElement} */
827
827
  set: function set(inert) {
828
828
  inertManager.setInert(this, inert);
829
829
  }
package/dist/inert.js CHANGED
@@ -15,7 +15,7 @@
15
15
 
16
16
  (function () {
17
17
  // Return early if we're not running inside of the browser.
18
- if (typeof window === 'undefined') {
18
+ if (typeof window === 'undefined' || typeof Element === 'undefined') {
19
19
  return;
20
20
  }
21
21
 
@@ -30,7 +30,7 @@
30
30
  var matches = Element.prototype.matches || Element.prototype.msMatchesSelector;
31
31
 
32
32
  /** @type {string} */
33
- var _focusableElementsString = ['a[href]', 'area[href]', 'input:not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'details', 'summary', 'iframe', 'object', 'embed', '[contenteditable]'].join(',');
33
+ var _focusableElementsString = ['a[href]', 'area[href]', 'input:not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'details', 'summary', 'iframe', 'object', 'embed', 'video', '[contenteditable]'].join(',');
34
34
 
35
35
  /**
36
36
  * `InertRoot` manages a single inert subtree, i.e. a DOM subtree whose root element has an `inert`
@@ -51,7 +51,7 @@
51
51
 
52
52
  var InertRoot = function () {
53
53
  /**
54
- * @param {!Element} rootElement The Element at the root of the inert subtree.
54
+ * @param {!HTMLElement} rootElement The HTMLElement at the root of the inert subtree.
55
55
  * @param {!InertManager} inertManager The global singleton InertManager object.
56
56
  */
57
57
  function InertRoot(rootElement, inertManager) {
@@ -60,7 +60,7 @@
60
60
  /** @type {!InertManager} */
61
61
  this._inertManager = inertManager;
62
62
 
63
- /** @type {!Element} */
63
+ /** @type {!HTMLElement} */
64
64
  this._rootElement = rootElement;
65
65
 
66
66
  /**
@@ -182,7 +182,7 @@
182
182
  if (node.nodeType !== Node.ELEMENT_NODE) {
183
183
  return;
184
184
  }
185
- var element = /** @type {!Element} */node;
185
+ var element = /** @type {!HTMLElement} */node;
186
186
 
187
187
  // If a descendant inert root becomes un-inert, its descendants will still be inert because of
188
188
  // this inert root, so all of its managed nodes need to be adopted by this InertRoot.
@@ -238,7 +238,7 @@
238
238
 
239
239
  /**
240
240
  * If a descendant node is found with an `inert` attribute, adopt its managed nodes.
241
- * @param {!Element} node
241
+ * @param {!HTMLElement} node
242
242
  */
243
243
 
244
244
  }, {
@@ -268,7 +268,7 @@
268
268
  key: '_onMutation',
269
269
  value: function _onMutation(records, self) {
270
270
  records.forEach(function (record) {
271
- var target = /** @type {!Element} */record.target;
271
+ var target = /** @type {!HTMLElement} */record.target;
272
272
  if (record.type === 'childList') {
273
273
  // Manage added nodes
274
274
  slice.call(record.addedNodes).forEach(function (node) {
@@ -387,7 +387,7 @@
387
387
  this._throwIfDestroyed();
388
388
 
389
389
  if (this._node && this._node.nodeType === Node.ELEMENT_NODE) {
390
- var element = /** @type {!Element} */this._node;
390
+ var element = /** @type {!HTMLElement} */this._node;
391
391
  if (this._savedTabIndex !== null) {
392
392
  element.setAttribute('tabindex', this._savedTabIndex);
393
393
  } else {
@@ -435,7 +435,7 @@
435
435
  if (this.node.nodeType !== Node.ELEMENT_NODE) {
436
436
  return;
437
437
  }
438
- var element = /** @type {!Element} */this.node;
438
+ var element = /** @type {!HTMLElement} */this.node;
439
439
  if (matches.call(element, _focusableElementsString)) {
440
440
  if ( /** @type {!HTMLElement} */element.tabIndex === -1 && this.hasSavedTabIndex) {
441
441
  return;
@@ -580,7 +580,7 @@
580
580
 
581
581
  /**
582
582
  * Set whether the given element should be an inert root or not.
583
- * @param {!Element} root
583
+ * @param {!HTMLElement} root
584
584
  * @param {boolean} inert
585
585
  */
586
586
 
@@ -731,7 +731,7 @@
731
731
  if (record.attributeName !== 'inert') {
732
732
  return;
733
733
  }
734
- var target = /** @type {!Element} */record.target;
734
+ var target = /** @type {!HTMLElement} */record.target;
735
735
  var inert = target.hasAttribute('inert');
736
736
  _this.setInert(target, inert);
737
737
  break;
@@ -746,7 +746,7 @@
746
746
  /**
747
747
  * Recursively walk the composed tree from |node|.
748
748
  * @param {!Node} node
749
- * @param {(function (!Element))=} callback Callback to be called for each element traversed,
749
+ * @param {(function (!HTMLElement))=} callback Callback to be called for each element traversed,
750
750
  * before descending into child nodes.
751
751
  * @param {?ShadowRoot=} shadowRootAncestor The nearest ShadowRoot ancestor, if any.
752
752
  */
@@ -754,7 +754,7 @@
754
754
 
755
755
  function composedTreeWalk(node, callback, shadowRootAncestor) {
756
756
  if (node.nodeType == Node.ELEMENT_NODE) {
757
- var element = /** @type {!Element} */node;
757
+ var element = /** @type {!HTMLElement} */node;
758
758
  if (callback) {
759
759
  callback(element);
760
760
  }
@@ -819,17 +819,17 @@
819
819
  node.appendChild(style);
820
820
  }
821
821
 
822
- if (!Element.prototype.hasOwnProperty('inert')) {
822
+ if (!HTMLElement.prototype.hasOwnProperty('inert')) {
823
823
  /** @type {!InertManager} */
824
824
  var inertManager = new InertManager(document);
825
825
 
826
- Object.defineProperty(Element.prototype, 'inert', {
826
+ Object.defineProperty(HTMLElement.prototype, 'inert', {
827
827
  enumerable: true,
828
- /** @this {!Element} */
828
+ /** @this {!HTMLElement} */
829
829
  get: function get() {
830
830
  return this.hasAttribute('inert');
831
831
  },
832
- /** @this {!Element} */
832
+ /** @this {!HTMLElement} */
833
833
  set: function set(inert) {
834
834
  inertManager.setInert(this, inert);
835
835
  }
package/dist/inert.min.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define("inert",t):t()}(0,function(){"use strict";var u=function(){function i(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(e,t,n){return t&&i(e.prototype,t),n&&i(e,n),e}}();function h(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}!function(){if("undefined"!=typeof window){var o=Array.prototype.slice,r=Element.prototype.matches||Element.prototype.msMatchesSelector,i=["a[href]","area[href]","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","details","summary","iframe","object","embed","[contenteditable]"].join(","),s=function(){function n(e,t){h(this,n),this._inertManager=t,this._rootElement=e,this._managedNodes=new Set,this._rootElement.hasAttribute("aria-hidden")?this._savedAriaHidden=this._rootElement.getAttribute("aria-hidden"):this._savedAriaHidden=null,this._rootElement.setAttribute("aria-hidden","true"),this._makeSubtreeUnfocusable(this._rootElement),this._observer=new MutationObserver(this._onMutation.bind(this)),this._observer.observe(this._rootElement,{attributes:!0,childList:!0,subtree:!0})}return u(n,[{key:"destructor",value:function(){this._observer.disconnect(),this._rootElement&&(null!==this._savedAriaHidden?this._rootElement.setAttribute("aria-hidden",this._savedAriaHidden):this._rootElement.removeAttribute("aria-hidden")),this._managedNodes.forEach(function(e){this._unmanageNode(e.node)},this),this._observer=null,this._rootElement=null,this._managedNodes=null,this._inertManager=null}},{key:"_makeSubtreeUnfocusable",value:function(e){var t=this;l(e,function(e){return t._visitNode(e)});var n=document.activeElement;if(!document.body.contains(e)){for(var i=e,o=void 0;i;){if(i.nodeType===Node.DOCUMENT_FRAGMENT_NODE){o=i;break}i=i.parentNode}o&&(n=o.activeElement)}e.contains(n)&&(n.blur(),n===document.activeElement&&document.body.focus())}},{key:"_visitNode",value:function(e){if(e.nodeType===Node.ELEMENT_NODE){var t=e;t!==this._rootElement&&t.hasAttribute("inert")&&this._adoptInertRoot(t),(r.call(t,i)||t.hasAttribute("tabindex"))&&this._manageNode(t)}}},{key:"_manageNode",value:function(e){var t=this._inertManager.register(e,this);this._managedNodes.add(t)}},{key:"_unmanageNode",value:function(e){var t=this._inertManager.deregister(e,this);t&&this._managedNodes.delete(t)}},{key:"_unmanageSubtree",value:function(e){var t=this;l(e,function(e){return t._unmanageNode(e)})}},{key:"_adoptInertRoot",value:function(e){var t=this._inertManager.getInertRoot(e);t||(this._inertManager.setInert(e,!0),t=this._inertManager.getInertRoot(e)),t.managedNodes.forEach(function(e){this._manageNode(e.node)},this)}},{key:"_onMutation",value:function(e,t){e.forEach(function(e){var t=e.target;if("childList"===e.type)o.call(e.addedNodes).forEach(function(e){this._makeSubtreeUnfocusable(e)},this),o.call(e.removedNodes).forEach(function(e){this._unmanageSubtree(e)},this);else if("attributes"===e.type)if("tabindex"===e.attributeName)this._manageNode(t);else if(t!==this._rootElement&&"inert"===e.attributeName&&t.hasAttribute("inert")){this._adoptInertRoot(t);var n=this._inertManager.getInertRoot(t);this._managedNodes.forEach(function(e){t.contains(e.node)&&n._manageNode(e.node)})}},this)}},{key:"managedNodes",get:function(){return new Set(this._managedNodes)}},{key:"hasSavedAriaHidden",get:function(){return null!==this._savedAriaHidden}},{key:"savedAriaHidden",set:function(e){this._savedAriaHidden=e},get:function(){return this._savedAriaHidden}}]),n}(),a=function(){function n(e,t){h(this,n),this._node=e,this._overrodeFocusMethod=!1,this._inertRoots=new Set([t]),this._savedTabIndex=null,this._destroyed=!1,this.ensureUntabbable()}return u(n,[{key:"destructor",value:function(){if(this._throwIfDestroyed(),this._node&&this._node.nodeType===Node.ELEMENT_NODE){var e=this._node;null!==this._savedTabIndex?e.setAttribute("tabindex",this._savedTabIndex):e.removeAttribute("tabindex"),this._overrodeFocusMethod&&delete e.focus}this._node=null,this._inertRoots=null,this._destroyed=!0}},{key:"_throwIfDestroyed",value:function(){if(this.destroyed)throw new Error("Trying to access destroyed InertNode")}},{key:"ensureUntabbable",value:function(){if(this.node.nodeType===Node.ELEMENT_NODE){var e=this.node;if(r.call(e,i)){if(-1===e.tabIndex&&this.hasSavedTabIndex)return;e.hasAttribute("tabindex")&&(this._savedTabIndex=e.tabIndex),e.setAttribute("tabindex","-1"),e.nodeType===Node.ELEMENT_NODE&&(e.focus=function(){},this._overrodeFocusMethod=!0)}else e.hasAttribute("tabindex")&&(this._savedTabIndex=e.tabIndex,e.removeAttribute("tabindex"))}}},{key:"addInertRoot",value:function(e){this._throwIfDestroyed(),this._inertRoots.add(e)}},{key:"removeInertRoot",value:function(e){this._throwIfDestroyed(),this._inertRoots.delete(e),0===this._inertRoots.size&&this.destructor()}},{key:"destroyed",get:function(){return this._destroyed}},{key:"hasSavedTabIndex",get:function(){return null!==this._savedTabIndex}},{key:"node",get:function(){return this._throwIfDestroyed(),this._node}},{key:"savedTabIndex",set:function(e){this._throwIfDestroyed(),this._savedTabIndex=e},get:function(){return this._throwIfDestroyed(),this._savedTabIndex}}]),n}(),e=function(){function t(e){if(h(this,t),!e)throw new Error("Missing required argument; InertManager needs to wrap a document.");this._document=e,this._managedNodes=new Map,this._inertRoots=new Map,this._observer=new MutationObserver(this._watchForInert.bind(this)),d(e.head||e.body||e.documentElement),"loading"===e.readyState?e.addEventListener("DOMContentLoaded",this._onDocumentLoaded.bind(this)):this._onDocumentLoaded()}return u(t,[{key:"setInert",value:function(e,t){if(t){if(this._inertRoots.has(e))return;var n=new s(e,this);if(e.setAttribute("inert",""),this._inertRoots.set(e,n),!this._document.body.contains(e))for(var i=e.parentNode;i;)11===i.nodeType&&d(i),i=i.parentNode}else{if(!this._inertRoots.has(e))return;this._inertRoots.get(e).destructor(),this._inertRoots.delete(e),e.removeAttribute("inert")}}},{key:"getInertRoot",value:function(e){return this._inertRoots.get(e)}},{key:"register",value:function(e,t){var n=this._managedNodes.get(e);return void 0!==n?n.addInertRoot(t):n=new a(e,t),this._managedNodes.set(e,n),n}},{key:"deregister",value:function(e,t){var n=this._managedNodes.get(e);return n?(n.removeInertRoot(t),n.destroyed&&this._managedNodes.delete(e),n):null}},{key:"_onDocumentLoaded",value:function(){o.call(this._document.querySelectorAll("[inert]")).forEach(function(e){this.setInert(e,!0)},this),this._observer.observe(this._document.body||this._document.documentElement,{attributes:!0,subtree:!0,childList:!0})}},{key:"_watchForInert",value:function(e,t){var i=this;e.forEach(function(e){switch(e.type){case"childList":o.call(e.addedNodes).forEach(function(e){if(e.nodeType===Node.ELEMENT_NODE){var t=o.call(e.querySelectorAll("[inert]"));r.call(e,"[inert]")&&t.unshift(e),t.forEach(function(e){this.setInert(e,!0)},i)}},i);break;case"attributes":if("inert"!==e.attributeName)return;var t=e.target,n=t.hasAttribute("inert");i.setInert(t,n)}},this)}}]),t}();if(!Element.prototype.hasOwnProperty("inert")){var t=new e(document);Object.defineProperty(Element.prototype,"inert",{enumerable:!0,get:function(){return this.hasAttribute("inert")},set:function(e){t.setInert(this,e)}})}}function l(e,t,n){if(e.nodeType==Node.ELEMENT_NODE){var i=e;t&&t(i);var o=i.shadowRoot;if(o)return void l(o,t,o);if("content"==i.localName){for(var r=i,s=r.getDistributedNodes?r.getDistributedNodes():[],a=0;a<s.length;a++)l(s[a],t,n);return}if("slot"==i.localName){for(var d=i,u=d.assignedNodes?d.assignedNodes({flatten:!0}):[],h=0;h<u.length;h++)l(u[h],t,n);return}}for(var c=e.firstChild;null!=c;)l(c,t,n),c=c.nextSibling}function d(e){if(!e.querySelector("style#inert-style, link#inert-style")){var t=document.createElement("style");t.setAttribute("id","inert-style"),t.textContent="\n[inert] {\n pointer-events: none;\n cursor: default;\n}\n\n[inert], [inert] * {\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n",e.appendChild(t)}}}()});
1
+ !function(e){("object"!=typeof exports||"undefined"==typeof module)&&"function"==typeof define&&define.amd?define("inert",e):e()}(function(){"use strict";var o,r,t,i,s,n,e=function(e,t,n){return t&&a(e.prototype,t),n&&a(e,n),e};function a(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function d(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function u(e,t){d(this,u),this._inertManager=t,this._rootElement=e,this._managedNodes=new Set,this._rootElement.hasAttribute("aria-hidden")?this._savedAriaHidden=this._rootElement.getAttribute("aria-hidden"):this._savedAriaHidden=null,this._rootElement.setAttribute("aria-hidden","true"),this._makeSubtreeUnfocusable(this._rootElement),this._observer=new MutationObserver(this._onMutation.bind(this)),this._observer.observe(this._rootElement,{attributes:!0,childList:!0,subtree:!0})}function h(e,t){d(this,h),this._node=e,this._overrodeFocusMethod=!1,this._inertRoots=new Set([t]),this._savedTabIndex=null,this._destroyed=!1,this.ensureUntabbable()}function l(e){if(d(this,l),!e)throw new Error("Missing required argument; InertManager needs to wrap a document.");this._document=e,this._managedNodes=new Map,this._inertRoots=new Map,this._observer=new MutationObserver(this._watchForInert.bind(this)),_(e.head||e.body||e.documentElement),"loading"===e.readyState?e.addEventListener("DOMContentLoaded",this._onDocumentLoaded.bind(this)):this._onDocumentLoaded()}function c(e,t,n){if(e.nodeType==Node.ELEMENT_NODE){var i=e,o=(t&&t(i),i.shadowRoot);if(o)return void c(o,t,o);if("content"==i.localName){for(var o=i,r=o.getDistributedNodes?o.getDistributedNodes():[],s=0;s<r.length;s++)c(r[s],t,n);return}if("slot"==i.localName){for(var o=i,a=o.assignedNodes?o.assignedNodes({flatten:!0}):[],d=0;d<a.length;d++)c(a[d],t,n);return}}for(var u=e.firstChild;null!=u;)c(u,t,n),u=u.nextSibling}function _(e){var t;e.querySelector("style#inert-style, link#inert-style")||((t=document.createElement("style")).setAttribute("id","inert-style"),t.textContent="\n[inert] {\n pointer-events: none;\n cursor: default;\n}\n\n[inert], [inert] * {\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n",e.appendChild(t))}"undefined"!=typeof window&&"undefined"!=typeof Element&&(o=Array.prototype.slice,r=Element.prototype.matches||Element.prototype.msMatchesSelector,t=["a[href]","area[href]","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","details","summary","iframe","object","embed","video","[contenteditable]"].join(","),e(u,[{key:"destructor",value:function(){this._observer.disconnect(),this._rootElement&&(null!==this._savedAriaHidden?this._rootElement.setAttribute("aria-hidden",this._savedAriaHidden):this._rootElement.removeAttribute("aria-hidden")),this._managedNodes.forEach(function(e){this._unmanageNode(e.node)},this),this._observer=null,this._rootElement=null,this._managedNodes=null,this._inertManager=null}},{key:"_makeSubtreeUnfocusable",value:function(e){var t=this,n=(c(e,function(e){return t._visitNode(e)}),document.activeElement);if(!document.body.contains(e)){for(var i=e,o=void 0;i;){if(i.nodeType===Node.DOCUMENT_FRAGMENT_NODE){o=i;break}i=i.parentNode}o&&(n=o.activeElement)}e.contains(n)&&(n.blur(),n===document.activeElement&&document.body.focus())}},{key:"_visitNode",value:function(e){e.nodeType===Node.ELEMENT_NODE&&((e=e)!==this._rootElement&&e.hasAttribute("inert")&&this._adoptInertRoot(e),(r.call(e,t)||e.hasAttribute("tabindex"))&&this._manageNode(e))}},{key:"_manageNode",value:function(e){e=this._inertManager.register(e,this);this._managedNodes.add(e)}},{key:"_unmanageNode",value:function(e){e=this._inertManager.deregister(e,this);e&&this._managedNodes.delete(e)}},{key:"_unmanageSubtree",value:function(e){var t=this;c(e,function(e){return t._unmanageNode(e)})}},{key:"_adoptInertRoot",value:function(e){var t=this._inertManager.getInertRoot(e);t||(this._inertManager.setInert(e,!0),t=this._inertManager.getInertRoot(e)),t.managedNodes.forEach(function(e){this._manageNode(e.node)},this)}},{key:"_onMutation",value:function(e,t){e.forEach(function(e){var t,n=e.target;"childList"===e.type?(o.call(e.addedNodes).forEach(function(e){this._makeSubtreeUnfocusable(e)},this),o.call(e.removedNodes).forEach(function(e){this._unmanageSubtree(e)},this)):"attributes"===e.type&&("tabindex"===e.attributeName?this._manageNode(n):n!==this._rootElement&&"inert"===e.attributeName&&n.hasAttribute("inert")&&(this._adoptInertRoot(n),t=this._inertManager.getInertRoot(n),this._managedNodes.forEach(function(e){n.contains(e.node)&&t._manageNode(e.node)})))},this)}},{key:"managedNodes",get:function(){return new Set(this._managedNodes)}},{key:"hasSavedAriaHidden",get:function(){return null!==this._savedAriaHidden}},{key:"savedAriaHidden",set:function(e){this._savedAriaHidden=e},get:function(){return this._savedAriaHidden}}]),i=u,e(h,[{key:"destructor",value:function(){var e;this._throwIfDestroyed(),this._node&&this._node.nodeType===Node.ELEMENT_NODE&&(e=this._node,null!==this._savedTabIndex?e.setAttribute("tabindex",this._savedTabIndex):e.removeAttribute("tabindex"),this._overrodeFocusMethod&&delete e.focus),this._node=null,this._inertRoots=null,this._destroyed=!0}},{key:"_throwIfDestroyed",value:function(){if(this.destroyed)throw new Error("Trying to access destroyed InertNode")}},{key:"ensureUntabbable",value:function(){var e;this.node.nodeType===Node.ELEMENT_NODE&&(e=this.node,r.call(e,t)?-1===e.tabIndex&&this.hasSavedTabIndex||(e.hasAttribute("tabindex")&&(this._savedTabIndex=e.tabIndex),e.setAttribute("tabindex","-1"),e.nodeType===Node.ELEMENT_NODE&&(e.focus=function(){},this._overrodeFocusMethod=!0)):e.hasAttribute("tabindex")&&(this._savedTabIndex=e.tabIndex,e.removeAttribute("tabindex")))}},{key:"addInertRoot",value:function(e){this._throwIfDestroyed(),this._inertRoots.add(e)}},{key:"removeInertRoot",value:function(e){this._throwIfDestroyed(),this._inertRoots.delete(e),0===this._inertRoots.size&&this.destructor()}},{key:"destroyed",get:function(){return this._destroyed}},{key:"hasSavedTabIndex",get:function(){return null!==this._savedTabIndex}},{key:"node",get:function(){return this._throwIfDestroyed(),this._node}},{key:"savedTabIndex",set:function(e){this._throwIfDestroyed(),this._savedTabIndex=e},get:function(){return this._throwIfDestroyed(),this._savedTabIndex}}]),s=h,e(l,[{key:"setInert",value:function(e,t){if(t){if(!this._inertRoots.has(e)){t=new i(e,this);if(e.setAttribute("inert",""),this._inertRoots.set(e,t),!this._document.body.contains(e))for(var n=e.parentNode;n;)11===n.nodeType&&_(n),n=n.parentNode}}else this._inertRoots.has(e)&&(this._inertRoots.get(e).destructor(),this._inertRoots.delete(e),e.removeAttribute("inert"))}},{key:"getInertRoot",value:function(e){return this._inertRoots.get(e)}},{key:"register",value:function(e,t){var n=this._managedNodes.get(e);return void 0!==n?n.addInertRoot(t):n=new s(e,t),this._managedNodes.set(e,n),n}},{key:"deregister",value:function(e,t){var n=this._managedNodes.get(e);return n?(n.removeInertRoot(t),n.destroyed&&this._managedNodes.delete(e),n):null}},{key:"_onDocumentLoaded",value:function(){o.call(this._document.querySelectorAll("[inert]")).forEach(function(e){this.setInert(e,!0)},this),this._observer.observe(this._document.body||this._document.documentElement,{attributes:!0,subtree:!0,childList:!0})}},{key:"_watchForInert",value:function(e,t){var i=this;e.forEach(function(e){switch(e.type){case"childList":o.call(e.addedNodes).forEach(function(e){var t;e.nodeType===Node.ELEMENT_NODE&&(t=o.call(e.querySelectorAll("[inert]")),r.call(e,"[inert]")&&t.unshift(e),t.forEach(function(e){this.setInert(e,!0)},i))},i);break;case"attributes":if("inert"!==e.attributeName)return;var t=e.target,n=t.hasAttribute("inert");i.setInert(t,n)}},this)}}]),e=l,HTMLElement.prototype.hasOwnProperty("inert")||(n=new e(document),Object.defineProperty(HTMLElement.prototype,"inert",{enumerable:!0,get:function(){return this.hasAttribute("inert")},set:function(e){n.setInert(this,e)}})))});
2
2
  //# sourceMappingURL=inert.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"inert.min.js","sources":["../src/inert.js"],"sourcesContent":["/**\n * This work is licensed under the W3C Software and Document License\n * (http://www.w3.org/Consortium/Legal/2015/copyright-software-and-document).\n */\n\n(function() {\n // Return early if we're not running inside of the browser.\n if (typeof window === 'undefined') {\n return;\n }\n\n // Convenience function for converting NodeLists.\n /** @type {typeof Array.prototype.slice} */\n const slice = Array.prototype.slice;\n\n /**\n * IE has a non-standard name for \"matches\".\n * @type {typeof Element.prototype.matches}\n */\n const matches =\n Element.prototype.matches || Element.prototype.msMatchesSelector;\n\n /** @type {string} */\n const _focusableElementsString = ['a[href]',\n 'area[href]',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n 'button:not([disabled])',\n 'details',\n 'summary',\n 'iframe',\n 'object',\n 'embed',\n '[contenteditable]'].join(',');\n\n /**\n * `InertRoot` manages a single inert subtree, i.e. a DOM subtree whose root element has an `inert`\n * attribute.\n *\n * Its main functions are:\n *\n * - to create and maintain a set of managed `InertNode`s, including when mutations occur in the\n * subtree. The `makeSubtreeUnfocusable()` method handles collecting `InertNode`s via registering\n * each focusable node in the subtree with the singleton `InertManager` which manages all known\n * focusable nodes within inert subtrees. `InertManager` ensures that a single `InertNode`\n * instance exists for each focusable node which has at least one inert root as an ancestor.\n *\n * - to notify all managed `InertNode`s when this subtree stops being inert (i.e. when the `inert`\n * attribute is removed from the root node). This is handled in the destructor, which calls the\n * `deregister` method on `InertManager` for each managed inert node.\n */\n class InertRoot {\n /**\n * @param {!Element} rootElement The Element at the root of the inert subtree.\n * @param {!InertManager} inertManager The global singleton InertManager object.\n */\n constructor(rootElement, inertManager) {\n /** @type {!InertManager} */\n this._inertManager = inertManager;\n\n /** @type {!Element} */\n this._rootElement = rootElement;\n\n /**\n * @type {!Set<!InertNode>}\n * All managed focusable nodes in this InertRoot's subtree.\n */\n this._managedNodes = new Set();\n\n // Make the subtree hidden from assistive technology\n if (this._rootElement.hasAttribute('aria-hidden')) {\n /** @type {?string} */\n this._savedAriaHidden = this._rootElement.getAttribute('aria-hidden');\n } else {\n this._savedAriaHidden = null;\n }\n this._rootElement.setAttribute('aria-hidden', 'true');\n\n // Make all focusable elements in the subtree unfocusable and add them to _managedNodes\n this._makeSubtreeUnfocusable(this._rootElement);\n\n // Watch for:\n // - any additions in the subtree: make them unfocusable too\n // - any removals from the subtree: remove them from this inert root's managed nodes\n // - attribute changes: if `tabindex` is added, or removed from an intrinsically focusable\n // element, make that node a managed node.\n this._observer = new MutationObserver(this._onMutation.bind(this));\n this._observer.observe(this._rootElement, {attributes: true, childList: true, subtree: true});\n }\n\n /**\n * Call this whenever this object is about to become obsolete. This unwinds all of the state\n * stored in this object and updates the state of all of the managed nodes.\n */\n destructor() {\n this._observer.disconnect();\n\n if (this._rootElement) {\n if (this._savedAriaHidden !== null) {\n this._rootElement.setAttribute('aria-hidden', this._savedAriaHidden);\n } else {\n this._rootElement.removeAttribute('aria-hidden');\n }\n }\n\n this._managedNodes.forEach(function(inertNode) {\n this._unmanageNode(inertNode.node);\n }, this);\n\n // Note we cast the nulls to the ANY type here because:\n // 1) We want the class properties to be declared as non-null, or else we\n // need even more casts throughout this code. All bets are off if an\n // instance has been destroyed and a method is called.\n // 2) We don't want to cast \"this\", because we want type-aware optimizations\n // to know which properties we're setting.\n this._observer = /** @type {?} */ (null);\n this._rootElement = /** @type {?} */ (null);\n this._managedNodes = /** @type {?} */ (null);\n this._inertManager = /** @type {?} */ (null);\n }\n\n /**\n * @return {!Set<!InertNode>} A copy of this InertRoot's managed nodes set.\n */\n get managedNodes() {\n return new Set(this._managedNodes);\n }\n\n /** @return {boolean} */\n get hasSavedAriaHidden() {\n return this._savedAriaHidden !== null;\n }\n\n /** @param {?string} ariaHidden */\n set savedAriaHidden(ariaHidden) {\n this._savedAriaHidden = ariaHidden;\n }\n\n /** @return {?string} */\n get savedAriaHidden() {\n return this._savedAriaHidden;\n }\n\n /**\n * @param {!Node} startNode\n */\n _makeSubtreeUnfocusable(startNode) {\n composedTreeWalk(startNode, (node) => this._visitNode(node));\n\n let activeElement = document.activeElement;\n\n if (!document.body.contains(startNode)) {\n // startNode may be in shadow DOM, so find its nearest shadowRoot to get the activeElement.\n let node = startNode;\n /** @type {!ShadowRoot|undefined} */\n let root = undefined;\n while (node) {\n if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n root = /** @type {!ShadowRoot} */ (node);\n break;\n }\n node = node.parentNode;\n }\n if (root) {\n activeElement = root.activeElement;\n }\n }\n if (startNode.contains(activeElement)) {\n activeElement.blur();\n // In IE11, if an element is already focused, and then set to tabindex=-1\n // calling blur() will not actually move the focus.\n // To work around this we call focus() on the body instead.\n if (activeElement === document.activeElement) {\n document.body.focus();\n }\n }\n }\n\n /**\n * @param {!Node} node\n */\n _visitNode(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return;\n }\n const element = /** @type {!Element} */ (node);\n\n // If a descendant inert root becomes un-inert, its descendants will still be inert because of\n // this inert root, so all of its managed nodes need to be adopted by this InertRoot.\n if (element !== this._rootElement && element.hasAttribute('inert')) {\n this._adoptInertRoot(element);\n }\n\n if (matches.call(element, _focusableElementsString) || element.hasAttribute('tabindex')) {\n this._manageNode(element);\n }\n }\n\n /**\n * Register the given node with this InertRoot and with InertManager.\n * @param {!Node} node\n */\n _manageNode(node) {\n const inertNode = this._inertManager.register(node, this);\n this._managedNodes.add(inertNode);\n }\n\n /**\n * Unregister the given node with this InertRoot and with InertManager.\n * @param {!Node} node\n */\n _unmanageNode(node) {\n const inertNode = this._inertManager.deregister(node, this);\n if (inertNode) {\n this._managedNodes.delete(inertNode);\n }\n }\n\n /**\n * Unregister the entire subtree starting at `startNode`.\n * @param {!Node} startNode\n */\n _unmanageSubtree(startNode) {\n composedTreeWalk(startNode, (node) => this._unmanageNode(node));\n }\n\n /**\n * If a descendant node is found with an `inert` attribute, adopt its managed nodes.\n * @param {!Element} node\n */\n _adoptInertRoot(node) {\n let inertSubroot = this._inertManager.getInertRoot(node);\n\n // During initialisation this inert root may not have been registered yet,\n // so register it now if need be.\n if (!inertSubroot) {\n this._inertManager.setInert(node, true);\n inertSubroot = this._inertManager.getInertRoot(node);\n }\n\n inertSubroot.managedNodes.forEach(function(savedInertNode) {\n this._manageNode(savedInertNode.node);\n }, this);\n }\n\n /**\n * Callback used when mutation observer detects subtree additions, removals, or attribute changes.\n * @param {!Array<!MutationRecord>} records\n * @param {!MutationObserver} self\n */\n _onMutation(records, self) {\n records.forEach(function(record) {\n const target = /** @type {!Element} */ (record.target);\n if (record.type === 'childList') {\n // Manage added nodes\n slice.call(record.addedNodes).forEach(function(node) {\n this._makeSubtreeUnfocusable(node);\n }, this);\n\n // Un-manage removed nodes\n slice.call(record.removedNodes).forEach(function(node) {\n this._unmanageSubtree(node);\n }, this);\n } else if (record.type === 'attributes') {\n if (record.attributeName === 'tabindex') {\n // Re-initialise inert node if tabindex changes\n this._manageNode(target);\n } else if (target !== this._rootElement &&\n record.attributeName === 'inert' &&\n target.hasAttribute('inert')) {\n // If a new inert root is added, adopt its managed nodes and make sure it knows about the\n // already managed nodes from this inert subroot.\n this._adoptInertRoot(target);\n const inertSubroot = this._inertManager.getInertRoot(target);\n this._managedNodes.forEach(function(managedNode) {\n if (target.contains(managedNode.node)) {\n inertSubroot._manageNode(managedNode.node);\n }\n });\n }\n }\n }, this);\n }\n }\n\n /**\n * `InertNode` initialises and manages a single inert node.\n * A node is inert if it is a descendant of one or more inert root elements.\n *\n * On construction, `InertNode` saves the existing `tabindex` value for the node, if any, and\n * either removes the `tabindex` attribute or sets it to `-1`, depending on whether the element\n * is intrinsically focusable or not.\n *\n * `InertNode` maintains a set of `InertRoot`s which are descendants of this `InertNode`. When an\n * `InertRoot` is destroyed, and calls `InertManager.deregister()`, the `InertManager` notifies the\n * `InertNode` via `removeInertRoot()`, which in turn destroys the `InertNode` if no `InertRoot`s\n * remain in the set. On destruction, `InertNode` reinstates the stored `tabindex` if one exists,\n * or removes the `tabindex` attribute if the element is intrinsically focusable.\n */\n class InertNode {\n /**\n * @param {!Node} node A focusable element to be made inert.\n * @param {!InertRoot} inertRoot The inert root element associated with this inert node.\n */\n constructor(node, inertRoot) {\n /** @type {!Node} */\n this._node = node;\n\n /** @type {boolean} */\n this._overrodeFocusMethod = false;\n\n /**\n * @type {!Set<!InertRoot>} The set of descendant inert roots.\n * If and only if this set becomes empty, this node is no longer inert.\n */\n this._inertRoots = new Set([inertRoot]);\n\n /** @type {?number} */\n this._savedTabIndex = null;\n\n /** @type {boolean} */\n this._destroyed = false;\n\n // Save any prior tabindex info and make this node untabbable\n this.ensureUntabbable();\n }\n\n /**\n * Call this whenever this object is about to become obsolete.\n * This makes the managed node focusable again and deletes all of the previously stored state.\n */\n destructor() {\n this._throwIfDestroyed();\n\n if (this._node && this._node.nodeType === Node.ELEMENT_NODE) {\n const element = /** @type {!Element} */ (this._node);\n if (this._savedTabIndex !== null) {\n element.setAttribute('tabindex', this._savedTabIndex);\n } else {\n element.removeAttribute('tabindex');\n }\n\n // Use `delete` to restore native focus method.\n if (this._overrodeFocusMethod) {\n delete element.focus;\n }\n }\n\n // See note in InertRoot.destructor for why we cast these nulls to ANY.\n this._node = /** @type {?} */ (null);\n this._inertRoots = /** @type {?} */ (null);\n this._destroyed = true;\n }\n\n /**\n * @type {boolean} Whether this object is obsolete because the managed node is no longer inert.\n * If the object has been destroyed, any attempt to access it will cause an exception.\n */\n get destroyed() {\n return /** @type {!InertNode} */ (this)._destroyed;\n }\n\n /**\n * Throw if user tries to access destroyed InertNode.\n */\n _throwIfDestroyed() {\n if (this.destroyed) {\n throw new Error('Trying to access destroyed InertNode');\n }\n }\n\n /** @return {boolean} */\n get hasSavedTabIndex() {\n return this._savedTabIndex !== null;\n }\n\n /** @return {!Node} */\n get node() {\n this._throwIfDestroyed();\n return this._node;\n }\n\n /** @param {?number} tabIndex */\n set savedTabIndex(tabIndex) {\n this._throwIfDestroyed();\n this._savedTabIndex = tabIndex;\n }\n\n /** @return {?number} */\n get savedTabIndex() {\n this._throwIfDestroyed();\n return this._savedTabIndex;\n }\n\n /** Save the existing tabindex value and make the node untabbable and unfocusable */\n ensureUntabbable() {\n if (this.node.nodeType !== Node.ELEMENT_NODE) {\n return;\n }\n const element = /** @type {!Element} */ (this.node);\n if (matches.call(element, _focusableElementsString)) {\n if (/** @type {!HTMLElement} */ (element).tabIndex === -1 &&\n this.hasSavedTabIndex) {\n return;\n }\n\n if (element.hasAttribute('tabindex')) {\n this._savedTabIndex = /** @type {!HTMLElement} */ (element).tabIndex;\n }\n element.setAttribute('tabindex', '-1');\n if (element.nodeType === Node.ELEMENT_NODE) {\n element.focus = function() {};\n this._overrodeFocusMethod = true;\n }\n } else if (element.hasAttribute('tabindex')) {\n this._savedTabIndex = /** @type {!HTMLElement} */ (element).tabIndex;\n element.removeAttribute('tabindex');\n }\n }\n\n /**\n * Add another inert root to this inert node's set of managing inert roots.\n * @param {!InertRoot} inertRoot\n */\n addInertRoot(inertRoot) {\n this._throwIfDestroyed();\n this._inertRoots.add(inertRoot);\n }\n\n /**\n * Remove the given inert root from this inert node's set of managing inert roots.\n * If the set of managing inert roots becomes empty, this node is no longer inert,\n * so the object should be destroyed.\n * @param {!InertRoot} inertRoot\n */\n removeInertRoot(inertRoot) {\n this._throwIfDestroyed();\n this._inertRoots.delete(inertRoot);\n if (this._inertRoots.size === 0) {\n this.destructor();\n }\n }\n }\n\n /**\n * InertManager is a per-document singleton object which manages all inert roots and nodes.\n *\n * When an element becomes an inert root by having an `inert` attribute set and/or its `inert`\n * property set to `true`, the `setInert` method creates an `InertRoot` object for the element.\n * The `InertRoot` in turn registers itself as managing all of the element's focusable descendant\n * nodes via the `register()` method. The `InertManager` ensures that a single `InertNode` instance\n * is created for each such node, via the `_managedNodes` map.\n */\n class InertManager {\n /**\n * @param {!Document} document\n */\n constructor(document) {\n if (!document) {\n throw new Error('Missing required argument; InertManager needs to wrap a document.');\n }\n\n /** @type {!Document} */\n this._document = document;\n\n /**\n * All managed nodes known to this InertManager. In a map to allow looking up by Node.\n * @type {!Map<!Node, !InertNode>}\n */\n this._managedNodes = new Map();\n\n /**\n * All inert roots known to this InertManager. In a map to allow looking up by Node.\n * @type {!Map<!Node, !InertRoot>}\n */\n this._inertRoots = new Map();\n\n /**\n * Observer for mutations on `document.body`.\n * @type {!MutationObserver}\n */\n this._observer = new MutationObserver(this._watchForInert.bind(this));\n\n // Add inert style.\n addInertStyle(document.head || document.body || document.documentElement);\n\n // Wait for document to be loaded.\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', this._onDocumentLoaded.bind(this));\n } else {\n this._onDocumentLoaded();\n }\n }\n\n /**\n * Set whether the given element should be an inert root or not.\n * @param {!Element} root\n * @param {boolean} inert\n */\n setInert(root, inert) {\n if (inert) {\n if (this._inertRoots.has(root)) { // element is already inert\n return;\n }\n\n const inertRoot = new InertRoot(root, this);\n root.setAttribute('inert', '');\n this._inertRoots.set(root, inertRoot);\n // If not contained in the document, it must be in a shadowRoot.\n // Ensure inert styles are added there.\n if (!this._document.body.contains(root)) {\n let parent = root.parentNode;\n while (parent) {\n if (parent.nodeType === 11) {\n addInertStyle(parent);\n }\n parent = parent.parentNode;\n }\n }\n } else {\n if (!this._inertRoots.has(root)) { // element is already non-inert\n return;\n }\n\n const inertRoot = this._inertRoots.get(root);\n inertRoot.destructor();\n this._inertRoots.delete(root);\n root.removeAttribute('inert');\n }\n }\n\n /**\n * Get the InertRoot object corresponding to the given inert root element, if any.\n * @param {!Node} element\n * @return {!InertRoot|undefined}\n */\n getInertRoot(element) {\n return this._inertRoots.get(element);\n }\n\n /**\n * Register the given InertRoot as managing the given node.\n * In the case where the node has a previously existing inert root, this inert root will\n * be added to its set of inert roots.\n * @param {!Node} node\n * @param {!InertRoot} inertRoot\n * @return {!InertNode} inertNode\n */\n register(node, inertRoot) {\n let inertNode = this._managedNodes.get(node);\n if (inertNode !== undefined) { // node was already in an inert subtree\n inertNode.addInertRoot(inertRoot);\n } else {\n inertNode = new InertNode(node, inertRoot);\n }\n\n this._managedNodes.set(node, inertNode);\n\n return inertNode;\n }\n\n /**\n * De-register the given InertRoot as managing the given inert node.\n * Removes the inert root from the InertNode's set of managing inert roots, and remove the inert\n * node from the InertManager's set of managed nodes if it is destroyed.\n * If the node is not currently managed, this is essentially a no-op.\n * @param {!Node} node\n * @param {!InertRoot} inertRoot\n * @return {?InertNode} The potentially destroyed InertNode associated with this node, if any.\n */\n deregister(node, inertRoot) {\n const inertNode = this._managedNodes.get(node);\n if (!inertNode) {\n return null;\n }\n\n inertNode.removeInertRoot(inertRoot);\n if (inertNode.destroyed) {\n this._managedNodes.delete(node);\n }\n\n return inertNode;\n }\n\n /**\n * Callback used when document has finished loading.\n */\n _onDocumentLoaded() {\n // Find all inert roots in document and make them actually inert.\n const inertElements = slice.call(this._document.querySelectorAll('[inert]'));\n inertElements.forEach(function(inertElement) {\n this.setInert(inertElement, true);\n }, this);\n\n // Comment this out to use programmatic API only.\n this._observer.observe(this._document.body || this._document.documentElement, {attributes: true, subtree: true, childList: true});\n }\n\n /**\n * Callback used when mutation observer detects attribute changes.\n * @param {!Array<!MutationRecord>} records\n * @param {!MutationObserver} self\n */\n _watchForInert(records, self) {\n const _this = this;\n records.forEach(function(record) {\n switch (record.type) {\n case 'childList':\n slice.call(record.addedNodes).forEach(function(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return;\n }\n const inertElements = slice.call(node.querySelectorAll('[inert]'));\n if (matches.call(node, '[inert]')) {\n inertElements.unshift(node);\n }\n inertElements.forEach(function(inertElement) {\n this.setInert(inertElement, true);\n }, _this);\n }, _this);\n break;\n case 'attributes':\n if (record.attributeName !== 'inert') {\n return;\n }\n const target = /** @type {!Element} */ (record.target);\n const inert = target.hasAttribute('inert');\n _this.setInert(target, inert);\n break;\n }\n }, this);\n }\n }\n\n /**\n * Recursively walk the composed tree from |node|.\n * @param {!Node} node\n * @param {(function (!Element))=} callback Callback to be called for each element traversed,\n * before descending into child nodes.\n * @param {?ShadowRoot=} shadowRootAncestor The nearest ShadowRoot ancestor, if any.\n */\n function composedTreeWalk(node, callback, shadowRootAncestor) {\n if (node.nodeType == Node.ELEMENT_NODE) {\n const element = /** @type {!Element} */ (node);\n if (callback) {\n callback(element);\n }\n\n // Descend into node:\n // If it has a ShadowRoot, ignore all child elements - these will be picked\n // up by the <content> or <shadow> elements. Descend straight into the\n // ShadowRoot.\n const shadowRoot = /** @type {!HTMLElement} */ (element).shadowRoot;\n if (shadowRoot) {\n composedTreeWalk(shadowRoot, callback, shadowRoot);\n return;\n }\n\n // If it is a <content> element, descend into distributed elements - these\n // are elements from outside the shadow root which are rendered inside the\n // shadow DOM.\n if (element.localName == 'content') {\n const content = /** @type {!HTMLContentElement} */ (element);\n // Verifies if ShadowDom v0 is supported.\n const distributedNodes = content.getDistributedNodes ?\n content.getDistributedNodes() : [];\n for (let i = 0; i < distributedNodes.length; i++) {\n composedTreeWalk(distributedNodes[i], callback, shadowRootAncestor);\n }\n return;\n }\n\n // If it is a <slot> element, descend into assigned nodes - these\n // are elements from outside the shadow root which are rendered inside the\n // shadow DOM.\n if (element.localName == 'slot') {\n const slot = /** @type {!HTMLSlotElement} */ (element);\n // Verify if ShadowDom v1 is supported.\n const distributedNodes = slot.assignedNodes ?\n slot.assignedNodes({flatten: true}) : [];\n for (let i = 0; i < distributedNodes.length; i++) {\n composedTreeWalk(distributedNodes[i], callback, shadowRootAncestor);\n }\n return;\n }\n }\n\n // If it is neither the parent of a ShadowRoot, a <content> element, a <slot>\n // element, nor a <shadow> element recurse normally.\n let child = node.firstChild;\n while (child != null) {\n composedTreeWalk(child, callback, shadowRootAncestor);\n child = child.nextSibling;\n }\n }\n\n /**\n * Adds a style element to the node containing the inert specific styles\n * @param {!Node} node\n */\n function addInertStyle(node) {\n if (node.querySelector('style#inert-style, link#inert-style')) {\n return;\n }\n const style = document.createElement('style');\n style.setAttribute('id', 'inert-style');\n style.textContent = '\\n'+\n '[inert] {\\n' +\n ' pointer-events: none;\\n' +\n ' cursor: default;\\n' +\n '}\\n' +\n '\\n' +\n '[inert], [inert] * {\\n' +\n ' -webkit-user-select: none;\\n' +\n ' -moz-user-select: none;\\n' +\n ' -ms-user-select: none;\\n' +\n ' user-select: none;\\n' +\n '}\\n';\n node.appendChild(style);\n }\n\n if (!Element.prototype.hasOwnProperty('inert')) {\n /** @type {!InertManager} */\n const inertManager = new InertManager(document);\n \n Object.defineProperty(Element.prototype, 'inert', {\n enumerable: true,\n /** @this {!Element} */\n get: function() {\n return this.hasAttribute('inert');\n },\n /** @this {!Element} */\n set: function(inert) {\n inertManager.setInert(this, inert);\n },\n });\n }\n})();\n"],"names":["window","slice","Array","prototype","matches","Element","msMatchesSelector","_focusableElementsString","join","InertRoot","rootElement","inertManager","_inertManager","_rootElement","_managedNodes","Set","this","hasAttribute","_savedAriaHidden","getAttribute","setAttribute","_makeSubtreeUnfocusable","_observer","MutationObserver","_onMutation","bind","observe","attributes","childList","subtree","disconnect","removeAttribute","forEach","inertNode","_unmanageNode","node","startNode","_this2","_visitNode","activeElement","document","body","contains","root","undefined","nodeType","Node","DOCUMENT_FRAGMENT_NODE","parentNode","blur","focus","ELEMENT_NODE","element","_adoptInertRoot","call","_manageNode","register","add","deregister","_this3","inertSubroot","getInertRoot","setInert","managedNodes","savedInertNode","records","self","record","target","type","addedNodes","removedNodes","_unmanageSubtree","attributeName","managedNode","ariaHidden","InertNode","inertRoot","_node","_overrodeFocusMethod","_inertRoots","_savedTabIndex","_destroyed","ensureUntabbable","_throwIfDestroyed","destroyed","Error","tabIndex","hasSavedTabIndex","size","destructor","InertManager","_document","Map","_watchForInert","head","documentElement","readyState","addEventListener","_onDocumentLoaded","inert","has","set","parent","get","addInertRoot","removeInertRoot","querySelectorAll","inertElement","_this","inertElements","unshift","hasOwnProperty","defineProperty","composedTreeWalk","callback","shadowRootAncestor","shadowRoot","localName","content","distributedNodes","getDistributedNodes","i","length","slot","assignedNodes","flatten","child","firstChild","nextSibling","addInertStyle","querySelector","style","createElement","textContent","appendChild"],"mappings":"ufAKA,cAEwB,oBAAXA,YAMLC,EAAQC,MAAMC,UAAUF,MAMxBG,EACFC,QAAQF,UAAUC,SAAWC,QAAQF,UAAUG,kBAG7CC,EAA2B,CAAC,UACA,aACA,wBACA,yBACA,2BACA,yBACA,UACA,UACA,SACA,SACA,QACA,qBAAqBC,KAAK,KAkBtDC,wBAKQC,EAAaC,kBAElBC,cAAgBD,OAGhBE,aAAeH,OAMfI,cAAgB,IAAIC,IAGrBC,KAAKH,aAAaI,aAAa,oBAE5BC,iBAAmBF,KAAKH,aAAaM,aAAa,oBAElDD,iBAAmB,UAErBL,aAAaO,aAAa,cAAe,aAGzCC,wBAAwBL,KAAKH,mBAO7BS,UAAY,IAAIC,iBAAiBP,KAAKQ,YAAYC,KAAKT,YACvDM,UAAUI,QAAQV,KAAKH,aAAc,CAACc,YAAY,EAAMC,WAAW,EAAMC,SAAS,wDAQlFP,UAAUQ,aAEXd,KAAKH,eACuB,OAA1BG,KAAKE,sBACFL,aAAaO,aAAa,cAAeJ,KAAKE,uBAE9CL,aAAakB,gBAAgB,qBAIjCjB,cAAckB,QAAQ,SAASC,QAC7BC,cAAcD,EAAUE,OAC5BnB,WAQEM,UAA8B,UAC9BT,aAAiC,UACjCC,cAAkC,UAClCF,cAAkC,qDA4BjBwB,gBACLA,EAAW,SAACD,UAASE,EAAKC,WAAWH,SAElDI,EAAgBC,SAASD,kBAExBC,SAASC,KAAKC,SAASN,GAAY,SAElCD,EAAOC,EAEPO,OAAOC,EACJT,GAAM,IACPA,EAAKU,WAAaC,KAAKC,uBAAwB,GACdZ,UAG9BA,EAAKa,WAEVL,MACcA,EAAKJ,eAGrBH,EAAUM,SAASH,OACPU,OAIVV,IAAkBC,SAASD,wBACpBE,KAAKS,4CAQTf,MACLA,EAAKU,WAAaC,KAAKK,kBAGrBC,EAAmCjB,EAIrCiB,IAAYpC,KAAKH,cAAgBuC,EAAQnC,aAAa,eACnDoC,gBAAgBD,IAGnBhD,EAAQkD,KAAKF,EAAS7C,IAA6B6C,EAAQnC,aAAa,mBACrEsC,YAAYH,wCAQTjB,OACJF,EAAYjB,KAAKJ,cAAc4C,SAASrB,EAAMnB,WAC/CF,cAAc2C,IAAIxB,yCAOXE,OACNF,EAAYjB,KAAKJ,cAAc8C,WAAWvB,EAAMnB,MAClDiB,QACGnB,qBAAqBmB,4CAQbG,gBACEA,EAAW,SAACD,UAASwB,EAAKzB,cAAcC,6CAO3CA,OACVyB,EAAe5C,KAAKJ,cAAciD,aAAa1B,GAI9CyB,SACEhD,cAAckD,SAAS3B,GAAM,KACnBnB,KAAKJ,cAAciD,aAAa1B,MAGpC4B,aAAa/B,QAAQ,SAASgC,QACpCT,YAAYS,EAAe7B,OAC/BnB,0CAQOiD,EAASC,KACXlC,QAAQ,SAASmC,OACjBC,EAAkCD,EAAOC,UAC3B,cAAhBD,EAAOE,OAEHf,KAAKa,EAAOG,YAAYtC,QAAQ,SAASG,QACxCd,wBAAwBc,IAC5BnB,QAGGsC,KAAKa,EAAOI,cAAcvC,QAAQ,SAASG,QAC1CqC,iBAAiBrC,IACrBnB,WACE,GAAoB,eAAhBmD,EAAOE,QACa,aAAzBF,EAAOM,mBAEJlB,YAAYa,QACZ,GAAIA,IAAWpD,KAAKH,cACQ,UAAzBsD,EAAOM,eACPL,EAAOnD,aAAa,SAAU,MAGjCoC,gBAAgBe,OACfR,EAAe5C,KAAKJ,cAAciD,aAAaO,QAChDtD,cAAckB,QAAQ,SAAS0C,GAC9BN,EAAO1B,SAASgC,EAAYvC,SACjBoB,YAAYmB,EAAYvC,UAK5CnB,kDA5JI,IAAID,IAAIC,KAAKF,iEAKa,OAA1BE,KAAKE,uDAIMyD,QACbzD,iBAAmByD,yBAKjB3D,KAAKE,0BA+JV0D,wBAKQzC,EAAM0C,kBAEXC,MAAQ3C,OAGR4C,sBAAuB,OAMvBC,YAAc,IAAIjE,IAAI,CAAC8D,SAGvBI,eAAiB,UAGjBC,YAAa,OAGbC,0EAQAC,oBAEDpE,KAAK8D,OAAS9D,KAAK8D,MAAMjC,WAAaC,KAAKK,aAAc,KACrDC,EAAmCpC,KAAK8D,MAClB,OAAxB9D,KAAKiE,iBACC7D,aAAa,WAAYJ,KAAKiE,kBAE9BlD,gBAAgB,YAItBf,KAAK+D,6BACA3B,EAAQF,WAKd4B,MAA0B,UAC1BE,YAAgC,UAChCE,YAAa,iDAedlE,KAAKqE,gBACD,IAAIC,MAAM,sFA6BdtE,KAAKmB,KAAKU,WAAaC,KAAKK,kBAG1BC,EAAmCpC,KAAKmB,QAC1C/B,EAAQkD,KAAKF,EAAS7C,GAA2B,KACK,IAAvB6C,EAASmC,UACtCvE,KAAKwE,wBAILpC,EAAQnC,aAAa,mBAClBgE,eAA8C7B,EAASmC,YAEtDnE,aAAa,WAAY,MAC7BgC,EAAQP,WAAaC,KAAKK,iBACpBD,MAAQ,kBACX6B,sBAAuB,QAErB3B,EAAQnC,aAAa,mBACzBgE,eAA8C7B,EAASmC,WACpDxD,gBAAgB,mDAQf8C,QACNO,yBACAJ,YAAYvB,IAAIoB,2CASPA,QACTO,yBACAJ,mBAAmBH,GACM,IAA1B7D,KAAKgE,YAAYS,WACdC,sDAhF2B1E,gEAcH,OAAxBA,KAAKiE,wDAKPG,oBACEpE,KAAK8D,0CAIIS,QACXH,yBACAH,eAAiBM,8BAKjBH,oBACEpE,KAAKiE,wBA8DVU,wBAIQnD,iBACLA,QACG,IAAI8C,MAAM,0EAIbM,UAAYpD,OAMZ1B,cAAgB,IAAI+E,SAMpBb,YAAc,IAAIa,SAMlBvE,UAAY,IAAIC,iBAAiBP,KAAK8E,eAAerE,KAAKT,SAGjDwB,EAASuD,MAAQvD,EAASC,MAAQD,EAASwD,iBAG7B,YAAxBxD,EAASyD,aACFC,iBAAiB,mBAAoBlF,KAAKmF,kBAAkB1E,KAAKT,YAErEmF,+DASAxD,EAAMyD,MACTA,EAAO,IACLpF,KAAKgE,YAAYqB,IAAI1D,cAInBkC,EAAY,IAAIpE,EAAUkC,EAAM3B,WACjCI,aAAa,QAAS,SACtB4D,YAAYsB,IAAI3D,EAAMkC,IAGtB7D,KAAK4E,UAAUnD,KAAKC,SAASC,WAC5B4D,EAAS5D,EAAKK,WACXuD,GACmB,KAApBA,EAAO1D,YACK0D,KAEPA,EAAOvD,eAGf,KACAhC,KAAKgE,YAAYqB,IAAI1D,UAIR3B,KAAKgE,YAAYwB,IAAI7D,GAC7B+C,kBACLV,mBAAmBrC,KACnBZ,gBAAgB,+CASZqB,UACJpC,KAAKgE,YAAYwB,IAAIpD,oCAWrBjB,EAAM0C,OACT5C,EAAYjB,KAAKF,cAAc0F,IAAIrE,eACrBS,IAAdX,IACQwE,aAAa5B,KAEX,IAAID,EAAUzC,EAAM0C,QAG7B/D,cAAcwF,IAAInE,EAAMF,GAEtBA,qCAYEE,EAAM0C,OACT5C,EAAYjB,KAAKF,cAAc0F,IAAIrE,UACpCF,KAIKyE,gBAAgB7B,GACtB5C,EAAUoD,gBACPvE,qBAAqBqB,GAGrBF,GARE,iDAgBahC,EAAMqD,KAAKtC,KAAK4E,UAAUe,iBAAiB,YACnD3E,QAAQ,SAAS4E,QACxB9C,SAAS8C,GAAc,IAC3B5F,WAGEM,UAAUI,QAAQV,KAAK4E,UAAUnD,MAAQzB,KAAK4E,UAAUI,gBAAiB,CAACrE,YAAY,EAAME,SAAS,EAAMD,WAAW,2CAQ9GqC,EAASC,OAChB2C,EAAQ7F,OACNgB,QAAQ,SAASmC,UACfA,EAAOE,UACV,cACGf,KAAKa,EAAOG,YAAYtC,QAAQ,SAASG,MACzCA,EAAKU,WAAaC,KAAKK,kBAGrB2D,EAAgB7G,EAAMqD,KAAKnB,EAAKwE,iBAAiB,YACnDvG,EAAQkD,KAAKnB,EAAM,cACP4E,QAAQ5E,KAEVH,QAAQ,SAAS4E,QACxB9C,SAAS8C,GAAc,IAC3BC,KACFA,aAEA,gBAC0B,UAAzB1C,EAAOM,yBAGLL,EAAkCD,EAAOC,OACzCgC,EAAQhC,EAAOnD,aAAa,WAC5B6C,SAASM,EAAQgC,KAGxBpF,mBA2FFX,QAAQF,UAAU6G,eAAe,SAAU,KAExCrG,EAAe,IAAIgF,EAAanD,iBAE/ByE,eAAe5G,QAAQF,UAAW,QAAS,aACpC,MAEP,kBACIa,KAAKC,aAAa,cAGtB,SAASmF,KACCtC,SAAS9C,KAAMoF,gBA5FzBc,EAAiB/E,EAAMgF,EAAUC,MACpCjF,EAAKU,UAAYC,KAAKK,aAAc,KAChCC,EAAmCjB,EACrCgF,KACO/D,OAOLiE,EAA0CjE,EAASiE,cACrDA,gBACeA,EAAYF,EAAUE,MAOhB,WAArBjE,EAAQkE,UAAwB,SAC5BC,EAA8CnE,EAE9CoE,EAAmBD,EAAQE,oBAC/BF,EAAQE,sBAAwB,GACzBC,EAAI,EAAGA,EAAIF,EAAiBG,OAAQD,MAC1BF,EAAiBE,GAAIP,EAAUC,aAQ3B,QAArBhE,EAAQkE,UAAqB,SACzBM,EAAwCxE,EAExCoE,EAAmBI,EAAKC,cAC5BD,EAAKC,cAAc,CAACC,SAAS,IAAS,GAC/BJ,EAAI,EAAGA,EAAIF,EAAiBG,OAAQD,MAC1BF,EAAiBE,GAAIP,EAAUC,mBAQlDW,EAAQ5F,EAAK6F,WACD,MAATD,KACYA,EAAOZ,EAAUC,KAC1BW,EAAME,qBAQTC,EAAc/F,OACjBA,EAAKgG,cAAc,4CAGjBC,EAAQ5F,SAAS6F,cAAc,WAC/BjH,aAAa,KAAM,iBACnBkH,YAAc,sMAYfC,YAAYH,KA1sBrB"}
1
+ {"version":3,"file":"inert.min.js","sources":["../src/inert.js"],"sourcesContent":["/**\n * This work is licensed under the W3C Software and Document License\n * (http://www.w3.org/Consortium/Legal/2015/copyright-software-and-document).\n */\n\n(function() {\n // Return early if we're not running inside of the browser.\n if (typeof window === 'undefined' || typeof Element === 'undefined') {\n return;\n }\n\n // Convenience function for converting NodeLists.\n /** @type {typeof Array.prototype.slice} */\n const slice = Array.prototype.slice;\n\n /**\n * IE has a non-standard name for \"matches\".\n * @type {typeof Element.prototype.matches}\n */\n const matches =\n Element.prototype.matches || Element.prototype.msMatchesSelector;\n\n /** @type {string} */\n const _focusableElementsString = ['a[href]',\n 'area[href]',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n 'button:not([disabled])',\n 'details',\n 'summary',\n 'iframe',\n 'object',\n 'embed',\n 'video',\n '[contenteditable]'].join(',');\n\n /**\n * `InertRoot` manages a single inert subtree, i.e. a DOM subtree whose root element has an `inert`\n * attribute.\n *\n * Its main functions are:\n *\n * - to create and maintain a set of managed `InertNode`s, including when mutations occur in the\n * subtree. The `makeSubtreeUnfocusable()` method handles collecting `InertNode`s via registering\n * each focusable node in the subtree with the singleton `InertManager` which manages all known\n * focusable nodes within inert subtrees. `InertManager` ensures that a single `InertNode`\n * instance exists for each focusable node which has at least one inert root as an ancestor.\n *\n * - to notify all managed `InertNode`s when this subtree stops being inert (i.e. when the `inert`\n * attribute is removed from the root node). This is handled in the destructor, which calls the\n * `deregister` method on `InertManager` for each managed inert node.\n */\n class InertRoot {\n /**\n * @param {!HTMLElement} rootElement The HTMLElement at the root of the inert subtree.\n * @param {!InertManager} inertManager The global singleton InertManager object.\n */\n constructor(rootElement, inertManager) {\n /** @type {!InertManager} */\n this._inertManager = inertManager;\n\n /** @type {!HTMLElement} */\n this._rootElement = rootElement;\n\n /**\n * @type {!Set<!InertNode>}\n * All managed focusable nodes in this InertRoot's subtree.\n */\n this._managedNodes = new Set();\n\n // Make the subtree hidden from assistive technology\n if (this._rootElement.hasAttribute('aria-hidden')) {\n /** @type {?string} */\n this._savedAriaHidden = this._rootElement.getAttribute('aria-hidden');\n } else {\n this._savedAriaHidden = null;\n }\n this._rootElement.setAttribute('aria-hidden', 'true');\n\n // Make all focusable elements in the subtree unfocusable and add them to _managedNodes\n this._makeSubtreeUnfocusable(this._rootElement);\n\n // Watch for:\n // - any additions in the subtree: make them unfocusable too\n // - any removals from the subtree: remove them from this inert root's managed nodes\n // - attribute changes: if `tabindex` is added, or removed from an intrinsically focusable\n // element, make that node a managed node.\n this._observer = new MutationObserver(this._onMutation.bind(this));\n this._observer.observe(this._rootElement, {attributes: true, childList: true, subtree: true});\n }\n\n /**\n * Call this whenever this object is about to become obsolete. This unwinds all of the state\n * stored in this object and updates the state of all of the managed nodes.\n */\n destructor() {\n this._observer.disconnect();\n\n if (this._rootElement) {\n if (this._savedAriaHidden !== null) {\n this._rootElement.setAttribute('aria-hidden', this._savedAriaHidden);\n } else {\n this._rootElement.removeAttribute('aria-hidden');\n }\n }\n\n this._managedNodes.forEach(function(inertNode) {\n this._unmanageNode(inertNode.node);\n }, this);\n\n // Note we cast the nulls to the ANY type here because:\n // 1) We want the class properties to be declared as non-null, or else we\n // need even more casts throughout this code. All bets are off if an\n // instance has been destroyed and a method is called.\n // 2) We don't want to cast \"this\", because we want type-aware optimizations\n // to know which properties we're setting.\n this._observer = /** @type {?} */ (null);\n this._rootElement = /** @type {?} */ (null);\n this._managedNodes = /** @type {?} */ (null);\n this._inertManager = /** @type {?} */ (null);\n }\n\n /**\n * @return {!Set<!InertNode>} A copy of this InertRoot's managed nodes set.\n */\n get managedNodes() {\n return new Set(this._managedNodes);\n }\n\n /** @return {boolean} */\n get hasSavedAriaHidden() {\n return this._savedAriaHidden !== null;\n }\n\n /** @param {?string} ariaHidden */\n set savedAriaHidden(ariaHidden) {\n this._savedAriaHidden = ariaHidden;\n }\n\n /** @return {?string} */\n get savedAriaHidden() {\n return this._savedAriaHidden;\n }\n\n /**\n * @param {!Node} startNode\n */\n _makeSubtreeUnfocusable(startNode) {\n composedTreeWalk(startNode, (node) => this._visitNode(node));\n\n let activeElement = document.activeElement;\n\n if (!document.body.contains(startNode)) {\n // startNode may be in shadow DOM, so find its nearest shadowRoot to get the activeElement.\n let node = startNode;\n /** @type {!ShadowRoot|undefined} */\n let root = undefined;\n while (node) {\n if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n root = /** @type {!ShadowRoot} */ (node);\n break;\n }\n node = node.parentNode;\n }\n if (root) {\n activeElement = root.activeElement;\n }\n }\n if (startNode.contains(activeElement)) {\n activeElement.blur();\n // In IE11, if an element is already focused, and then set to tabindex=-1\n // calling blur() will not actually move the focus.\n // To work around this we call focus() on the body instead.\n if (activeElement === document.activeElement) {\n document.body.focus();\n }\n }\n }\n\n /**\n * @param {!Node} node\n */\n _visitNode(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return;\n }\n const element = /** @type {!HTMLElement} */ (node);\n\n // If a descendant inert root becomes un-inert, its descendants will still be inert because of\n // this inert root, so all of its managed nodes need to be adopted by this InertRoot.\n if (element !== this._rootElement && element.hasAttribute('inert')) {\n this._adoptInertRoot(element);\n }\n\n if (matches.call(element, _focusableElementsString) || element.hasAttribute('tabindex')) {\n this._manageNode(element);\n }\n }\n\n /**\n * Register the given node with this InertRoot and with InertManager.\n * @param {!Node} node\n */\n _manageNode(node) {\n const inertNode = this._inertManager.register(node, this);\n this._managedNodes.add(inertNode);\n }\n\n /**\n * Unregister the given node with this InertRoot and with InertManager.\n * @param {!Node} node\n */\n _unmanageNode(node) {\n const inertNode = this._inertManager.deregister(node, this);\n if (inertNode) {\n this._managedNodes.delete(inertNode);\n }\n }\n\n /**\n * Unregister the entire subtree starting at `startNode`.\n * @param {!Node} startNode\n */\n _unmanageSubtree(startNode) {\n composedTreeWalk(startNode, (node) => this._unmanageNode(node));\n }\n\n /**\n * If a descendant node is found with an `inert` attribute, adopt its managed nodes.\n * @param {!HTMLElement} node\n */\n _adoptInertRoot(node) {\n let inertSubroot = this._inertManager.getInertRoot(node);\n\n // During initialisation this inert root may not have been registered yet,\n // so register it now if need be.\n if (!inertSubroot) {\n this._inertManager.setInert(node, true);\n inertSubroot = this._inertManager.getInertRoot(node);\n }\n\n inertSubroot.managedNodes.forEach(function(savedInertNode) {\n this._manageNode(savedInertNode.node);\n }, this);\n }\n\n /**\n * Callback used when mutation observer detects subtree additions, removals, or attribute changes.\n * @param {!Array<!MutationRecord>} records\n * @param {!MutationObserver} self\n */\n _onMutation(records, self) {\n records.forEach(function(record) {\n const target = /** @type {!HTMLElement} */ (record.target);\n if (record.type === 'childList') {\n // Manage added nodes\n slice.call(record.addedNodes).forEach(function(node) {\n this._makeSubtreeUnfocusable(node);\n }, this);\n\n // Un-manage removed nodes\n slice.call(record.removedNodes).forEach(function(node) {\n this._unmanageSubtree(node);\n }, this);\n } else if (record.type === 'attributes') {\n if (record.attributeName === 'tabindex') {\n // Re-initialise inert node if tabindex changes\n this._manageNode(target);\n } else if (target !== this._rootElement &&\n record.attributeName === 'inert' &&\n target.hasAttribute('inert')) {\n // If a new inert root is added, adopt its managed nodes and make sure it knows about the\n // already managed nodes from this inert subroot.\n this._adoptInertRoot(target);\n const inertSubroot = this._inertManager.getInertRoot(target);\n this._managedNodes.forEach(function(managedNode) {\n if (target.contains(managedNode.node)) {\n inertSubroot._manageNode(managedNode.node);\n }\n });\n }\n }\n }, this);\n }\n }\n\n /**\n * `InertNode` initialises and manages a single inert node.\n * A node is inert if it is a descendant of one or more inert root elements.\n *\n * On construction, `InertNode` saves the existing `tabindex` value for the node, if any, and\n * either removes the `tabindex` attribute or sets it to `-1`, depending on whether the element\n * is intrinsically focusable or not.\n *\n * `InertNode` maintains a set of `InertRoot`s which are descendants of this `InertNode`. When an\n * `InertRoot` is destroyed, and calls `InertManager.deregister()`, the `InertManager` notifies the\n * `InertNode` via `removeInertRoot()`, which in turn destroys the `InertNode` if no `InertRoot`s\n * remain in the set. On destruction, `InertNode` reinstates the stored `tabindex` if one exists,\n * or removes the `tabindex` attribute if the element is intrinsically focusable.\n */\n class InertNode {\n /**\n * @param {!Node} node A focusable element to be made inert.\n * @param {!InertRoot} inertRoot The inert root element associated with this inert node.\n */\n constructor(node, inertRoot) {\n /** @type {!Node} */\n this._node = node;\n\n /** @type {boolean} */\n this._overrodeFocusMethod = false;\n\n /**\n * @type {!Set<!InertRoot>} The set of descendant inert roots.\n * If and only if this set becomes empty, this node is no longer inert.\n */\n this._inertRoots = new Set([inertRoot]);\n\n /** @type {?number} */\n this._savedTabIndex = null;\n\n /** @type {boolean} */\n this._destroyed = false;\n\n // Save any prior tabindex info and make this node untabbable\n this.ensureUntabbable();\n }\n\n /**\n * Call this whenever this object is about to become obsolete.\n * This makes the managed node focusable again and deletes all of the previously stored state.\n */\n destructor() {\n this._throwIfDestroyed();\n\n if (this._node && this._node.nodeType === Node.ELEMENT_NODE) {\n const element = /** @type {!HTMLElement} */ (this._node);\n if (this._savedTabIndex !== null) {\n element.setAttribute('tabindex', this._savedTabIndex);\n } else {\n element.removeAttribute('tabindex');\n }\n\n // Use `delete` to restore native focus method.\n if (this._overrodeFocusMethod) {\n delete element.focus;\n }\n }\n\n // See note in InertRoot.destructor for why we cast these nulls to ANY.\n this._node = /** @type {?} */ (null);\n this._inertRoots = /** @type {?} */ (null);\n this._destroyed = true;\n }\n\n /**\n * @type {boolean} Whether this object is obsolete because the managed node is no longer inert.\n * If the object has been destroyed, any attempt to access it will cause an exception.\n */\n get destroyed() {\n return /** @type {!InertNode} */ (this)._destroyed;\n }\n\n /**\n * Throw if user tries to access destroyed InertNode.\n */\n _throwIfDestroyed() {\n if (this.destroyed) {\n throw new Error('Trying to access destroyed InertNode');\n }\n }\n\n /** @return {boolean} */\n get hasSavedTabIndex() {\n return this._savedTabIndex !== null;\n }\n\n /** @return {!Node} */\n get node() {\n this._throwIfDestroyed();\n return this._node;\n }\n\n /** @param {?number} tabIndex */\n set savedTabIndex(tabIndex) {\n this._throwIfDestroyed();\n this._savedTabIndex = tabIndex;\n }\n\n /** @return {?number} */\n get savedTabIndex() {\n this._throwIfDestroyed();\n return this._savedTabIndex;\n }\n\n /** Save the existing tabindex value and make the node untabbable and unfocusable */\n ensureUntabbable() {\n if (this.node.nodeType !== Node.ELEMENT_NODE) {\n return;\n }\n const element = /** @type {!HTMLElement} */ (this.node);\n if (matches.call(element, _focusableElementsString)) {\n if (/** @type {!HTMLElement} */ (element).tabIndex === -1 &&\n this.hasSavedTabIndex) {\n return;\n }\n\n if (element.hasAttribute('tabindex')) {\n this._savedTabIndex = /** @type {!HTMLElement} */ (element).tabIndex;\n }\n element.setAttribute('tabindex', '-1');\n if (element.nodeType === Node.ELEMENT_NODE) {\n element.focus = function() {};\n this._overrodeFocusMethod = true;\n }\n } else if (element.hasAttribute('tabindex')) {\n this._savedTabIndex = /** @type {!HTMLElement} */ (element).tabIndex;\n element.removeAttribute('tabindex');\n }\n }\n\n /**\n * Add another inert root to this inert node's set of managing inert roots.\n * @param {!InertRoot} inertRoot\n */\n addInertRoot(inertRoot) {\n this._throwIfDestroyed();\n this._inertRoots.add(inertRoot);\n }\n\n /**\n * Remove the given inert root from this inert node's set of managing inert roots.\n * If the set of managing inert roots becomes empty, this node is no longer inert,\n * so the object should be destroyed.\n * @param {!InertRoot} inertRoot\n */\n removeInertRoot(inertRoot) {\n this._throwIfDestroyed();\n this._inertRoots.delete(inertRoot);\n if (this._inertRoots.size === 0) {\n this.destructor();\n }\n }\n }\n\n /**\n * InertManager is a per-document singleton object which manages all inert roots and nodes.\n *\n * When an element becomes an inert root by having an `inert` attribute set and/or its `inert`\n * property set to `true`, the `setInert` method creates an `InertRoot` object for the element.\n * The `InertRoot` in turn registers itself as managing all of the element's focusable descendant\n * nodes via the `register()` method. The `InertManager` ensures that a single `InertNode` instance\n * is created for each such node, via the `_managedNodes` map.\n */\n class InertManager {\n /**\n * @param {!Document} document\n */\n constructor(document) {\n if (!document) {\n throw new Error('Missing required argument; InertManager needs to wrap a document.');\n }\n\n /** @type {!Document} */\n this._document = document;\n\n /**\n * All managed nodes known to this InertManager. In a map to allow looking up by Node.\n * @type {!Map<!Node, !InertNode>}\n */\n this._managedNodes = new Map();\n\n /**\n * All inert roots known to this InertManager. In a map to allow looking up by Node.\n * @type {!Map<!Node, !InertRoot>}\n */\n this._inertRoots = new Map();\n\n /**\n * Observer for mutations on `document.body`.\n * @type {!MutationObserver}\n */\n this._observer = new MutationObserver(this._watchForInert.bind(this));\n\n // Add inert style.\n addInertStyle(document.head || document.body || document.documentElement);\n\n // Wait for document to be loaded.\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', this._onDocumentLoaded.bind(this));\n } else {\n this._onDocumentLoaded();\n }\n }\n\n /**\n * Set whether the given element should be an inert root or not.\n * @param {!HTMLElement} root\n * @param {boolean} inert\n */\n setInert(root, inert) {\n if (inert) {\n if (this._inertRoots.has(root)) { // element is already inert\n return;\n }\n\n const inertRoot = new InertRoot(root, this);\n root.setAttribute('inert', '');\n this._inertRoots.set(root, inertRoot);\n // If not contained in the document, it must be in a shadowRoot.\n // Ensure inert styles are added there.\n if (!this._document.body.contains(root)) {\n let parent = root.parentNode;\n while (parent) {\n if (parent.nodeType === 11) {\n addInertStyle(parent);\n }\n parent = parent.parentNode;\n }\n }\n } else {\n if (!this._inertRoots.has(root)) { // element is already non-inert\n return;\n }\n\n const inertRoot = this._inertRoots.get(root);\n inertRoot.destructor();\n this._inertRoots.delete(root);\n root.removeAttribute('inert');\n }\n }\n\n /**\n * Get the InertRoot object corresponding to the given inert root element, if any.\n * @param {!Node} element\n * @return {!InertRoot|undefined}\n */\n getInertRoot(element) {\n return this._inertRoots.get(element);\n }\n\n /**\n * Register the given InertRoot as managing the given node.\n * In the case where the node has a previously existing inert root, this inert root will\n * be added to its set of inert roots.\n * @param {!Node} node\n * @param {!InertRoot} inertRoot\n * @return {!InertNode} inertNode\n */\n register(node, inertRoot) {\n let inertNode = this._managedNodes.get(node);\n if (inertNode !== undefined) { // node was already in an inert subtree\n inertNode.addInertRoot(inertRoot);\n } else {\n inertNode = new InertNode(node, inertRoot);\n }\n\n this._managedNodes.set(node, inertNode);\n\n return inertNode;\n }\n\n /**\n * De-register the given InertRoot as managing the given inert node.\n * Removes the inert root from the InertNode's set of managing inert roots, and remove the inert\n * node from the InertManager's set of managed nodes if it is destroyed.\n * If the node is not currently managed, this is essentially a no-op.\n * @param {!Node} node\n * @param {!InertRoot} inertRoot\n * @return {?InertNode} The potentially destroyed InertNode associated with this node, if any.\n */\n deregister(node, inertRoot) {\n const inertNode = this._managedNodes.get(node);\n if (!inertNode) {\n return null;\n }\n\n inertNode.removeInertRoot(inertRoot);\n if (inertNode.destroyed) {\n this._managedNodes.delete(node);\n }\n\n return inertNode;\n }\n\n /**\n * Callback used when document has finished loading.\n */\n _onDocumentLoaded() {\n // Find all inert roots in document and make them actually inert.\n const inertElements = slice.call(this._document.querySelectorAll('[inert]'));\n inertElements.forEach(function(inertElement) {\n this.setInert(inertElement, true);\n }, this);\n\n // Comment this out to use programmatic API only.\n this._observer.observe(this._document.body || this._document.documentElement, {attributes: true, subtree: true, childList: true});\n }\n\n /**\n * Callback used when mutation observer detects attribute changes.\n * @param {!Array<!MutationRecord>} records\n * @param {!MutationObserver} self\n */\n _watchForInert(records, self) {\n const _this = this;\n records.forEach(function(record) {\n switch (record.type) {\n case 'childList':\n slice.call(record.addedNodes).forEach(function(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return;\n }\n const inertElements = slice.call(node.querySelectorAll('[inert]'));\n if (matches.call(node, '[inert]')) {\n inertElements.unshift(node);\n }\n inertElements.forEach(function(inertElement) {\n this.setInert(inertElement, true);\n }, _this);\n }, _this);\n break;\n case 'attributes':\n if (record.attributeName !== 'inert') {\n return;\n }\n const target = /** @type {!HTMLElement} */ (record.target);\n const inert = target.hasAttribute('inert');\n _this.setInert(target, inert);\n break;\n }\n }, this);\n }\n }\n\n /**\n * Recursively walk the composed tree from |node|.\n * @param {!Node} node\n * @param {(function (!HTMLElement))=} callback Callback to be called for each element traversed,\n * before descending into child nodes.\n * @param {?ShadowRoot=} shadowRootAncestor The nearest ShadowRoot ancestor, if any.\n */\n function composedTreeWalk(node, callback, shadowRootAncestor) {\n if (node.nodeType == Node.ELEMENT_NODE) {\n const element = /** @type {!HTMLElement} */ (node);\n if (callback) {\n callback(element);\n }\n\n // Descend into node:\n // If it has a ShadowRoot, ignore all child elements - these will be picked\n // up by the <content> or <shadow> elements. Descend straight into the\n // ShadowRoot.\n const shadowRoot = /** @type {!HTMLElement} */ (element).shadowRoot;\n if (shadowRoot) {\n composedTreeWalk(shadowRoot, callback, shadowRoot);\n return;\n }\n\n // If it is a <content> element, descend into distributed elements - these\n // are elements from outside the shadow root which are rendered inside the\n // shadow DOM.\n if (element.localName == 'content') {\n const content = /** @type {!HTMLContentElement} */ (element);\n // Verifies if ShadowDom v0 is supported.\n const distributedNodes = content.getDistributedNodes ?\n content.getDistributedNodes() : [];\n for (let i = 0; i < distributedNodes.length; i++) {\n composedTreeWalk(distributedNodes[i], callback, shadowRootAncestor);\n }\n return;\n }\n\n // If it is a <slot> element, descend into assigned nodes - these\n // are elements from outside the shadow root which are rendered inside the\n // shadow DOM.\n if (element.localName == 'slot') {\n const slot = /** @type {!HTMLSlotElement} */ (element);\n // Verify if ShadowDom v1 is supported.\n const distributedNodes = slot.assignedNodes ?\n slot.assignedNodes({flatten: true}) : [];\n for (let i = 0; i < distributedNodes.length; i++) {\n composedTreeWalk(distributedNodes[i], callback, shadowRootAncestor);\n }\n return;\n }\n }\n\n // If it is neither the parent of a ShadowRoot, a <content> element, a <slot>\n // element, nor a <shadow> element recurse normally.\n let child = node.firstChild;\n while (child != null) {\n composedTreeWalk(child, callback, shadowRootAncestor);\n child = child.nextSibling;\n }\n }\n\n /**\n * Adds a style element to the node containing the inert specific styles\n * @param {!Node} node\n */\n function addInertStyle(node) {\n if (node.querySelector('style#inert-style, link#inert-style')) {\n return;\n }\n const style = document.createElement('style');\n style.setAttribute('id', 'inert-style');\n style.textContent = '\\n'+\n '[inert] {\\n' +\n ' pointer-events: none;\\n' +\n ' cursor: default;\\n' +\n '}\\n' +\n '\\n' +\n '[inert], [inert] * {\\n' +\n ' -webkit-user-select: none;\\n' +\n ' -moz-user-select: none;\\n' +\n ' -ms-user-select: none;\\n' +\n ' user-select: none;\\n' +\n '}\\n';\n node.appendChild(style);\n }\n\n if (!HTMLElement.prototype.hasOwnProperty('inert')) {\n /** @type {!InertManager} */\n const inertManager = new InertManager(document);\n \n Object.defineProperty(HTMLElement.prototype, 'inert', {\n enumerable: true,\n /** @this {!HTMLElement} */\n get: function() {\n return this.hasAttribute('inert');\n },\n /** @this {!HTMLElement} */\n set: function(inert) {\n inertManager.setInert(this, inert);\n },\n });\n }\n})();\n"],"names":["slice","matches","_focusableElementsString","InertRoot","InertNode","inertManager","rootElement","_inertManager","_rootElement","_managedNodes","Set","this","hasAttribute","_savedAriaHidden","getAttribute","setAttribute","_makeSubtreeUnfocusable","_observer","MutationObserver","_onMutation","bind","observe","attributes","childList","subtree","node","inertRoot","_node","_overrodeFocusMethod","_inertRoots","_savedTabIndex","_destroyed","ensureUntabbable","document","Error","_document","Map","_watchForInert","head","body","documentElement","readyState","addEventListener","_onDocumentLoaded","composedTreeWalk","callback","shadowRootAncestor","nodeType","Node","ELEMENT_NODE","element","shadowRoot","localName","content","distributedNodes","getDistributedNodes","i","length","slot","assignedNodes","flatten","child","firstChild","nextSibling","addInertStyle","style","querySelector","createElement","textContent","appendChild","window","Element","Array","prototype","msMatchesSelector","join","disconnect","removeAttribute","forEach","inertNode","_unmanageNode","startNode","activeElement","_this2","_visitNode","contains","root","undefined","DOCUMENT_FRAGMENT_NODE","parentNode","blur","focus","_adoptInertRoot","call","_manageNode","register","add","deregister","_this3","inertSubroot","getInertRoot","setInert","managedNodes","savedInertNode","records","self","record","target","type","addedNodes","removedNodes","_unmanageSubtree","attributeName","managedNode","ariaHidden","_throwIfDestroyed","destroyed","tabIndex","hasSavedTabIndex","size","destructor","inert","has","set","parent","get","addInertRoot","removeInertRoot","querySelectorAll","inertElement","_this","inertElements","unshift","InertManager","HTMLElement","hasOwnProperty","defineProperty"],"mappings":"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"}
package/explainer.md CHANGED
@@ -120,6 +120,7 @@ implementers may get useful functionality into the hands of developers sooner wh
120
120
  + rendering content, such as a menu, offscreen, before having it animate on-screen;
121
121
  + similarly, for content like a menu which may be repeatedly shown to the user,
122
122
  avoiding re-rendering this content each time;
123
+ + disabling an element as you fade it in or out, without needing to rely on `transitionend` events;
123
124
  + a carousel or other type of content cycler (such as a "tweet cycler")
124
125
  which visually hides non-current items by placing them at a lower z-index than the active item,
125
126
  or by setting their `opacity` to zero,
package/karma.conf.js CHANGED
@@ -16,7 +16,7 @@ module.exports = function(config) {
16
16
  ],
17
17
  // Change this to 'Chrome' if you would like to debug.
18
18
  // Can also add additional local browsers like 'Firefox'.
19
- browsers: ['ChromeHeadless'],
19
+ browsers: ['FirefoxHeadless'],
20
20
  // Set this to false to leave the browser open for debugging.
21
21
  // You'll probably also need to remove the afterEach block in your tests
22
22
  // so the content is not removed from the page you're trying to debug.
@@ -24,10 +24,10 @@ module.exports = function(config) {
24
24
  // https://mochajs.org/#exclusive-tests
25
25
  singleRun: true,
26
26
  // Use the mocha test framework with chai assertions.
27
- // Use polyfills loaded from Polyfill.io.
27
+ // Use polyfills loaded
28
28
  // Use an html fixture loader.
29
29
  frameworks: ['mocha', 'chai', 'polyfill', 'fixture'],
30
- // List of polyfills to load from Polyfill.io.
30
+ // List of polyfills to load
31
31
  polyfill: [
32
32
  'Array.from', // Used in tests.
33
33
  'Promise',
@@ -57,82 +57,24 @@ module.exports = function(config) {
57
57
  if (process.env.TRAVIS || process.env.SAUCE) {
58
58
  // List of browsers to test on SauceLabs.
59
59
  // To add more browsers, use:
60
- // https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/
61
- // This set of browsers was copied from:
62
- // https://github.com/angular/angular.js/blob/master/karma-shared.conf.js#L42-L116
60
+ // https://docs.saucelabs.com/visual/e2e-testing/supported-browsers/#browser-versions-supported
63
61
  const customLaunchers = {
64
62
  'SL_Chrome': {
65
63
  base: 'SauceLabs',
66
64
  browserName: 'chrome',
67
- version: 'latest',
68
- },
69
- 'SL_Chrome-1': {
70
- base: 'SauceLabs',
71
- browserName: 'chrome',
72
- version: 'latest-1',
65
+ version: '100',
73
66
  },
74
67
  'SL_Firefox': {
75
68
  base: 'SauceLabs',
76
69
  browserName: 'firefox',
77
- version: 'latest',
78
- },
79
- 'SL_Firefox-1': {
80
- base: 'SauceLabs',
81
- browserName: 'firefox',
82
- version: 'latest-1',
83
- },
84
- 'SL_Safari-1': {
85
- base: 'SauceLabs',
86
- browserName: 'safari',
87
- platform: 'OS X 10.12',
88
- version: 'latest-1',
70
+ version: '100',
89
71
  },
90
72
  'SL_Safari': {
91
73
  base: 'SauceLabs',
92
74
  browserName: 'safari',
93
- platform: 'OS X 10.13',
94
- version: 'latest',
95
- },
96
- // 'SL_IE_9': {
97
- // base: 'SauceLabs',
98
- // browserName: 'internet explorer',
99
- // platform: 'Windows 2008',
100
- // version: '9',
101
- // },
102
- // 'SL_IE_10': {
103
- // base: 'SauceLabs',
104
- // browserName: 'internet explorer',
105
- // platform: 'Windows 2012',
106
- // version: '10',
107
- // },
108
- 'SL_IE_11': {
109
- base: 'SauceLabs',
110
- browserName: 'internet explorer',
111
- platform: 'Windows 8.1',
112
- version: '11',
113
- },
114
- 'SL_EDGE': {
115
- base: 'SauceLabs',
116
- browserName: 'microsoftedge',
117
- platform: 'Windows 10',
118
- version: 'latest',
119
- },
120
- 'SL_EDGE-1': {
121
- base: 'SauceLabs',
122
- browserName: 'microsoftedge',
123
- platform: 'Windows 10',
124
- version: 'latest-1',
75
+ platform: 'OS X 11.00',
76
+ version: '14',
125
77
  },
126
- // 'SL_iOS_10': {
127
- // base: 'SauceLabs',
128
- // browserName: 'iphone',
129
- // version: '10.3',
130
- // },
131
- // 'SL_iOS_11': {
132
- // base: 'SauceLabs',
133
- // browserName: 'iphone',
134
- // version: '11',
135
- // },
136
78
  };
137
79
 
138
80
  config.set({
package/package.json CHANGED
@@ -1,13 +1,11 @@
1
1
  {
2
2
  "name": "wicg-inert",
3
- "version": "3.1.1",
3
+ "version": "3.1.3",
4
4
  "description": "A polyfill for the proposed inert API",
5
5
  "main": "dist/inert.js",
6
6
  "module": "dist/inert.esm.js",
7
7
  "scripts": {
8
- "build": "rollup -c",
9
- "prepublishOnly": "SAUCE=true npm run test",
10
- "test": "npm run build && karma start"
8
+ "build": "rollup -c"
11
9
  },
12
10
  "repository": {
13
11
  "type": "git",
@@ -38,21 +36,23 @@
38
36
  "eslint-config-google": "^0.9.1",
39
37
  "eslint-plugin-es5": "^1.3.1",
40
38
  "husky": "^0.14.3",
41
- "karma": "^3.0.0",
39
+ "karma": "^6.3.20",
42
40
  "karma-chai": "^0.1.0",
43
41
  "karma-chrome-launcher": "^2.2.0",
44
42
  "karma-firefox-launcher": "^1.1.0",
45
43
  "karma-fixture": "^0.2.6",
46
44
  "karma-html2js-preprocessor": "^1.1.0",
47
- "karma-mocha": "^1.3.0",
45
+ "karma-mocha": "^2.0.1",
48
46
  "karma-polyfill": "^1.0.0",
47
+ "karma-safari-launcher": "^1.0.0",
49
48
  "karma-sauce-launcher": "^1.2.0",
50
49
  "karma-sourcemap-loader": "^0.3.7",
51
50
  "karma-spec-reporter": "0.0.32",
52
51
  "lint-staged": "^7.0.0",
53
- "mocha": "^5.0.0",
52
+ "mocha": "^10.0.0",
54
53
  "rollup": "^0.65.0",
55
54
  "rollup-plugin-babel": "^3.0.4",
56
55
  "rollup-plugin-uglify": "^4.0.0"
57
- }
56
+ },
57
+ "license": "W3C-20150513"
58
58
  }
@@ -0,0 +1,90 @@
1
+ # [Self-Review Questionnaire: Security and Privacy](https://w3ctag.github.io/security-questionnaire/)
2
+
3
+ > 01. What information might this feature expose to Web sites or other parties,
4
+ and for what purposes is that exposure necessary?
5
+
6
+ None.
7
+
8
+ > 02. Do features in your specification expose the minimum amount of information
9
+ necessary to enable their intended uses?
10
+
11
+ Yes.
12
+
13
+ > 03. How do the features in your specification deal with personal information,
14
+ personally-identifiable information (PII), or information derived from
15
+ them?
16
+
17
+ No PII is used.
18
+
19
+ > 04. How do the features in your specification deal with sensitive information?
20
+
21
+ No sensitive information is used.
22
+
23
+ > 05. Do the features in your specification introduce new state for an origin
24
+ that persists across browsing sessions?
25
+
26
+ No.
27
+
28
+ > 06. Do the features in your specification expose information about the
29
+ underlying platform to origins?
30
+
31
+ No.
32
+
33
+ > 07. Does this specification allow an origin to send data to the underlying
34
+ platform?
35
+
36
+ No.
37
+
38
+ > 08. Do features in this specification allow an origin access to sensors on a user’s
39
+ device
40
+
41
+ No.
42
+
43
+ > 09. What data do the features in this specification expose to an origin? Please
44
+ also document what data is identical to data exposed by other features, in the
45
+ same or different contexts.
46
+
47
+ No data is exposed to any origin.
48
+
49
+ > 10. Do feautres in this specification enable new script execution/loading
50
+ mechanisms?
51
+
52
+ No.
53
+
54
+ > 11. Do features in this specification allow an origin to access other devices?
55
+
56
+ No.
57
+
58
+ > 12. Do features in this specification allow an origin some measure of control over
59
+ a user agent's native UI?
60
+
61
+ No.
62
+
63
+ > 13. What temporary identifiers do the feautures in this specification create or
64
+ expose to the web?
65
+
66
+ None.
67
+
68
+ > 14. How does this specification distinguish between behavior in first-party and
69
+ third-party contexts?
70
+
71
+ It doesn't.
72
+
73
+ > 15. How do the features in this specification work in the context of a browser’s
74
+ Private Browsing or Incognito mode?
75
+
76
+ This feature behaves identically in any mode.
77
+
78
+ > 16. Does this specification have both "Security Considerations" and "Privacy
79
+ Considerations" sections?
80
+
81
+ No.
82
+
83
+ > 17. Do features in your specification enable origins to downgrade default
84
+ security protections?
85
+
86
+ No.
87
+
88
+ > 18. What should this questionnaire have asked?
89
+
90
+ 🤷
package/src/inert.js CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  (function() {
7
7
  // Return early if we're not running inside of the browser.
8
- if (typeof window === 'undefined') {
8
+ if (typeof window === 'undefined' || typeof Element === 'undefined') {
9
9
  return;
10
10
  }
11
11
 
@@ -32,6 +32,7 @@
32
32
  'iframe',
33
33
  'object',
34
34
  'embed',
35
+ 'video',
35
36
  '[contenteditable]'].join(',');
36
37
 
37
38
  /**
@@ -52,14 +53,14 @@
52
53
  */
53
54
  class InertRoot {
54
55
  /**
55
- * @param {!Element} rootElement The Element at the root of the inert subtree.
56
+ * @param {!HTMLElement} rootElement The HTMLElement at the root of the inert subtree.
56
57
  * @param {!InertManager} inertManager The global singleton InertManager object.
57
58
  */
58
59
  constructor(rootElement, inertManager) {
59
60
  /** @type {!InertManager} */
60
61
  this._inertManager = inertManager;
61
62
 
62
- /** @type {!Element} */
63
+ /** @type {!HTMLElement} */
63
64
  this._rootElement = rootElement;
64
65
 
65
66
  /**
@@ -184,7 +185,7 @@
184
185
  if (node.nodeType !== Node.ELEMENT_NODE) {
185
186
  return;
186
187
  }
187
- const element = /** @type {!Element} */ (node);
188
+ const element = /** @type {!HTMLElement} */ (node);
188
189
 
189
190
  // If a descendant inert root becomes un-inert, its descendants will still be inert because of
190
191
  // this inert root, so all of its managed nodes need to be adopted by this InertRoot.
@@ -227,7 +228,7 @@
227
228
 
228
229
  /**
229
230
  * If a descendant node is found with an `inert` attribute, adopt its managed nodes.
230
- * @param {!Element} node
231
+ * @param {!HTMLElement} node
231
232
  */
232
233
  _adoptInertRoot(node) {
233
234
  let inertSubroot = this._inertManager.getInertRoot(node);
@@ -251,7 +252,7 @@
251
252
  */
252
253
  _onMutation(records, self) {
253
254
  records.forEach(function(record) {
254
- const target = /** @type {!Element} */ (record.target);
255
+ const target = /** @type {!HTMLElement} */ (record.target);
255
256
  if (record.type === 'childList') {
256
257
  // Manage added nodes
257
258
  slice.call(record.addedNodes).forEach(function(node) {
@@ -334,7 +335,7 @@
334
335
  this._throwIfDestroyed();
335
336
 
336
337
  if (this._node && this._node.nodeType === Node.ELEMENT_NODE) {
337
- const element = /** @type {!Element} */ (this._node);
338
+ const element = /** @type {!HTMLElement} */ (this._node);
338
339
  if (this._savedTabIndex !== null) {
339
340
  element.setAttribute('tabindex', this._savedTabIndex);
340
341
  } else {
@@ -398,7 +399,7 @@
398
399
  if (this.node.nodeType !== Node.ELEMENT_NODE) {
399
400
  return;
400
401
  }
401
- const element = /** @type {!Element} */ (this.node);
402
+ const element = /** @type {!HTMLElement} */ (this.node);
402
403
  if (matches.call(element, _focusableElementsString)) {
403
404
  if (/** @type {!HTMLElement} */ (element).tabIndex === -1 &&
404
405
  this.hasSavedTabIndex) {
@@ -495,7 +496,7 @@
495
496
 
496
497
  /**
497
498
  * Set whether the given element should be an inert root or not.
498
- * @param {!Element} root
499
+ * @param {!HTMLElement} root
499
500
  * @param {boolean} inert
500
501
  */
501
502
  setInert(root, inert) {
@@ -624,7 +625,7 @@
624
625
  if (record.attributeName !== 'inert') {
625
626
  return;
626
627
  }
627
- const target = /** @type {!Element} */ (record.target);
628
+ const target = /** @type {!HTMLElement} */ (record.target);
628
629
  const inert = target.hasAttribute('inert');
629
630
  _this.setInert(target, inert);
630
631
  break;
@@ -636,13 +637,13 @@
636
637
  /**
637
638
  * Recursively walk the composed tree from |node|.
638
639
  * @param {!Node} node
639
- * @param {(function (!Element))=} callback Callback to be called for each element traversed,
640
+ * @param {(function (!HTMLElement))=} callback Callback to be called for each element traversed,
640
641
  * before descending into child nodes.
641
642
  * @param {?ShadowRoot=} shadowRootAncestor The nearest ShadowRoot ancestor, if any.
642
643
  */
643
644
  function composedTreeWalk(node, callback, shadowRootAncestor) {
644
645
  if (node.nodeType == Node.ELEMENT_NODE) {
645
- const element = /** @type {!Element} */ (node);
646
+ const element = /** @type {!HTMLElement} */ (node);
646
647
  if (callback) {
647
648
  callback(element);
648
649
  }
@@ -720,17 +721,17 @@
720
721
  node.appendChild(style);
721
722
  }
722
723
 
723
- if (!Element.prototype.hasOwnProperty('inert')) {
724
+ if (!HTMLElement.prototype.hasOwnProperty('inert')) {
724
725
  /** @type {!InertManager} */
725
726
  const inertManager = new InertManager(document);
726
727
 
727
- Object.defineProperty(Element.prototype, 'inert', {
728
+ Object.defineProperty(HTMLElement.prototype, 'inert', {
728
729
  enumerable: true,
729
- /** @this {!Element} */
730
+ /** @this {!HTMLElement} */
730
731
  get: function() {
731
732
  return this.hasAttribute('inert');
732
733
  },
733
- /** @this {!Element} */
734
+ /** @this {!HTMLElement} */
734
735
  set: function(inert) {
735
736
  inertManager.setInert(this, inert);
736
737
  },
@@ -1,5 +1,5 @@
1
- describe('Element.prototype', function() {
2
- it('should patch the Element prototype', function() {
3
- expect(Element.prototype.hasOwnProperty('inert')).to.be.ok;
1
+ describe('HTMLElement.prototype', function() {
2
+ it('should patch the HTMLElement prototype', function() {
3
+ expect(HTMLElement.prototype.hasOwnProperty('inert')).to.be.ok;
4
4
  });
5
5
  });
@@ -14,7 +14,7 @@ LOG.info = function() {
14
14
  * Check if an element is not focusable.
15
15
  * Note: This will be injected into the global scope by the test runner.
16
16
  * See the files array in karma.conf.js.
17
- * @param {Element} el
17
+ * @param {HTMLElement} el
18
18
  * @return {Boolean}
19
19
  */
20
20
  function isUnfocusable(el) { // eslint-disable-line no-unused-vars