wicg-inert
Advanced tools
Comparing version 2.1.2 to 2.1.3
@@ -17,5 +17,11 @@ (function (global, factory) { | ||
// Convenience function for converting NodeLists. | ||
/** @type {function(number,number):Array} */ | ||
/** @type {typeof Array.prototype.slice} */ | ||
var slice = Array.prototype.slice; | ||
/** | ||
* IE has a non-standard name for "matches". | ||
* @type {typeof Element.prototype.matches} | ||
*/ | ||
var matches = Element.prototype.matches || Element.prototype.msMatchesSelector; | ||
/** @type {string} */ | ||
@@ -43,4 +49,4 @@ var _focusableElementsString = ['a[href]', 'area[href]', 'input:not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'iframe', 'object', 'embed', '[contenteditable]'].join(','); | ||
/** | ||
* @param {Element} rootElement The Element at the root of the inert subtree. | ||
* @param {InertManager} inertManager The global singleton InertManager object. | ||
* @param {!Element} rootElement The Element at the root of the inert subtree. | ||
* @param {!InertManager} inertManager The global singleton InertManager object. | ||
*/ | ||
@@ -50,17 +56,20 @@ function InertRoot(rootElement, inertManager) { | ||
/** @type {InertManager} */ | ||
/** @type {!InertManager} */ | ||
this._inertManager = inertManager; | ||
/** @type {Element} */ | ||
/** @type {!Element} */ | ||
this._rootElement = rootElement; | ||
/** | ||
* @type {Set<Node>} | ||
* @type {!Set<!InertNode>} | ||
* All managed focusable nodes in this InertRoot's subtree. | ||
*/ | ||
this._managedNodes = new Set([]); | ||
this._managedNodes = new Set(); | ||
// Make the subtree hidden from assistive technology | ||
if (this._rootElement.hasAttribute('aria-hidden')) { | ||
/** @type {?string} */ | ||
this._savedAriaHidden = this._rootElement.getAttribute('aria-hidden'); | ||
} else { | ||
this._savedAriaHidden = null; | ||
} | ||
@@ -91,7 +100,6 @@ this._rootElement.setAttribute('aria-hidden', 'true'); | ||
this._observer.disconnect(); | ||
this._observer = null; | ||
if (this._rootElement) { | ||
if (this.hasSavedAriaHidden) { | ||
this._rootElement.setAttribute('aria-hidden', this.savedAriaHidden); | ||
if (this._savedAriaHidden !== null) { | ||
this._rootElement.setAttribute('aria-hidden', this._savedAriaHidden); | ||
} else { | ||
@@ -101,3 +109,2 @@ this._rootElement.removeAttribute('aria-hidden'); | ||
} | ||
this._rootElement = null; | ||
@@ -108,9 +115,16 @@ this._managedNodes.forEach(function (inertNode) { | ||
this._managedNodes = null; | ||
this._inertManager = null; | ||
// Note we cast the nulls to the ANY type here because: | ||
// 1) We want the class properties to be declared as non-null, or else we | ||
// need even more casts throughout this code. All bets are off if an | ||
// instance has been destroyed and a method is called. | ||
// 2) We don't want to cast "this", because we want type-aware optimizations | ||
// to know which properties we're setting. | ||
this._observer = /** @type {?} */null; | ||
this._rootElement = /** @type {?} */null; | ||
this._managedNodes = /** @type {?} */null; | ||
this._inertManager = /** @type {?} */null; | ||
} | ||
/** | ||
* @return {Set<InertNode>} A copy of this InertRoot's managed nodes set. | ||
* @return {!Set<!InertNode>} A copy of this InertRoot's managed nodes set. | ||
*/ | ||
@@ -123,9 +137,9 @@ | ||
/** | ||
* @param {Node} startNode | ||
* @param {!Node} startNode | ||
*/ | ||
value: function _makeSubtreeUnfocusable(startNode) { | ||
var _this = this; | ||
var _this2 = this; | ||
composedTreeWalk(startNode, function (node) { | ||
return _this._visitNode(node); | ||
return _this2._visitNode(node); | ||
}); | ||
@@ -138,6 +152,7 @@ | ||
var node = startNode; | ||
/** @type {!ShadowRoot|undefined} */ | ||
var root = undefined; | ||
while (node) { | ||
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { | ||
root = node; | ||
root = /** @type {!ShadowRoot} */node; | ||
break; | ||
@@ -163,3 +178,3 @@ } | ||
/** | ||
* @param {Node} node | ||
* @param {!Node} node | ||
*/ | ||
@@ -173,11 +188,12 @@ | ||
} | ||
var element = /** @type {!Element} */node; | ||
// If a descendant inert root becomes un-inert, its descendants will still be inert because of | ||
// this inert root, so all of its managed nodes need to be adopted by this InertRoot. | ||
if (node !== this._rootElement && node.hasAttribute('inert')) { | ||
this._adoptInertRoot(node); | ||
if (element !== this._rootElement && element.hasAttribute('inert')) { | ||
this._adoptInertRoot(element); | ||
} | ||
if (node.matches(_focusableElementsString) || node.hasAttribute('tabindex')) { | ||
this._manageNode(node); | ||
if (matches.call(element, _focusableElementsString) || element.hasAttribute('tabindex')) { | ||
this._manageNode(element); | ||
} | ||
@@ -188,3 +204,3 @@ } | ||
* Register the given node with this InertRoot and with InertManager. | ||
* @param {Node} node | ||
* @param {!Node} node | ||
*/ | ||
@@ -201,3 +217,3 @@ | ||
* Unregister the given node with this InertRoot and with InertManager. | ||
* @param {Node} node | ||
* @param {!Node} node | ||
*/ | ||
@@ -216,3 +232,3 @@ | ||
* Unregister the entire subtree starting at `startNode`. | ||
* @param {Node} startNode | ||
* @param {!Node} startNode | ||
*/ | ||
@@ -223,6 +239,6 @@ | ||
value: function _unmanageSubtree(startNode) { | ||
var _this2 = this; | ||
var _this3 = this; | ||
composedTreeWalk(startNode, function (node) { | ||
return _this2._unmanageNode(node); | ||
return _this3._unmanageNode(node); | ||
}); | ||
@@ -233,3 +249,3 @@ } | ||
* If a descendant node is found with an `inert` attribute, adopt its managed nodes. | ||
* @param {Node} node | ||
* @param {!Element} node | ||
*/ | ||
@@ -256,4 +272,4 @@ | ||
* Callback used when mutation observer detects subtree additions, removals, or attribute changes. | ||
* @param {MutationRecord} records | ||
* @param {MutationObserver} self | ||
* @param {!Array<!MutationRecord>} records | ||
* @param {!MutationObserver} self | ||
*/ | ||
@@ -265,3 +281,3 @@ | ||
records.forEach(function (record) { | ||
var target = record.target; | ||
var target = /** @type {!Element} */record.target; | ||
if (record.type === 'childList') { | ||
@@ -306,6 +322,6 @@ // Manage added nodes | ||
get: function get() { | ||
return '_savedAriaHidden' in this; | ||
return this._savedAriaHidden !== null; | ||
} | ||
/** @param {string} ariaHidden */ | ||
/** @param {?string} ariaHidden */ | ||
@@ -318,3 +334,3 @@ }, { | ||
/** @return {string} */ | ||
/** @return {?string} */ | ||
, | ||
@@ -347,4 +363,4 @@ get: function get() { | ||
/** | ||
* @param {Node} node A focusable element to be made inert. | ||
* @param {InertRoot} inertRoot The inert root element associated with this inert node. | ||
* @param {!Node} node A focusable element to be made inert. | ||
* @param {!InertRoot} inertRoot The inert root element associated with this inert node. | ||
*/ | ||
@@ -354,3 +370,3 @@ function InertNode(node, inertRoot) { | ||
/** @type {Node} */ | ||
/** @type {!Node} */ | ||
this._node = node; | ||
@@ -362,3 +378,3 @@ | ||
/** | ||
* @type {Set<InertRoot>} The set of descendant inert roots. | ||
* @type {!Set<!InertRoot>} The set of descendant inert roots. | ||
* If and only if this set becomes empty, this node is no longer inert. | ||
@@ -368,2 +384,5 @@ */ | ||
/** @type {?number} */ | ||
this._savedTabIndex = null; | ||
/** @type {boolean} */ | ||
@@ -387,7 +406,8 @@ this._destroyed = false; | ||
if (this._node) { | ||
if (this.hasSavedTabIndex) { | ||
this._node.setAttribute('tabindex', this.savedTabIndex); | ||
if (this._node && this._node.nodeType === Node.ELEMENT_NODE) { | ||
var element = /** @type {!Element} */this._node; | ||
if (this._savedTabIndex !== null) { | ||
element.setAttribute('tabindex', this._savedTabIndex); | ||
} else { | ||
this._node.removeAttribute('tabindex'); | ||
element.removeAttribute('tabindex'); | ||
} | ||
@@ -397,8 +417,9 @@ | ||
if (this._overrodeFocusMethod) { | ||
delete this._node.focus; | ||
delete element.focus; | ||
} | ||
} | ||
this._node = null; | ||
this._inertRoots = null; | ||
// See note in InertRoot.destructor for why we cast these nulls to ANY. | ||
this._node = /** @type {?} */null; | ||
this._inertRoots = /** @type {?} */null; | ||
this._destroyed = true; | ||
@@ -433,19 +454,22 @@ } | ||
value: function ensureUntabbable() { | ||
var node = this.node; | ||
if (node.matches(_focusableElementsString)) { | ||
if (node.tabIndex === -1 && this.hasSavedTabIndex) { | ||
if (this.node.nodeType !== Node.ELEMENT_NODE) { | ||
return; | ||
} | ||
var element = /** @type {!Element} */this.node; | ||
if (matches.call(element, _focusableElementsString)) { | ||
if ( /** @type {!HTMLElement} */element.tabIndex === -1 && this.hasSavedTabIndex) { | ||
return; | ||
} | ||
if (node.hasAttribute('tabindex')) { | ||
this._savedTabIndex = node.tabIndex; | ||
if (element.hasAttribute('tabindex')) { | ||
this._savedTabIndex = /** @type {!HTMLElement} */element.tabIndex; | ||
} | ||
node.setAttribute('tabindex', '-1'); | ||
if (node.nodeType === Node.ELEMENT_NODE) { | ||
node.focus = function () {}; | ||
element.setAttribute('tabindex', '-1'); | ||
if (element.nodeType === Node.ELEMENT_NODE) { | ||
element.focus = function () {}; | ||
this._overrodeFocusMethod = true; | ||
} | ||
} else if (node.hasAttribute('tabindex')) { | ||
this._savedTabIndex = node.tabIndex; | ||
node.removeAttribute('tabindex'); | ||
} else if (element.hasAttribute('tabindex')) { | ||
this._savedTabIndex = /** @type {!HTMLElement} */element.tabIndex; | ||
element.removeAttribute('tabindex'); | ||
} | ||
@@ -456,3 +480,3 @@ } | ||
* Add another inert root to this inert node's set of managing inert roots. | ||
* @param {InertRoot} inertRoot | ||
* @param {!InertRoot} inertRoot | ||
*/ | ||
@@ -471,3 +495,3 @@ | ||
* so the object should be destroyed. | ||
* @param {InertRoot} inertRoot | ||
* @param {!InertRoot} inertRoot | ||
*/ | ||
@@ -487,3 +511,4 @@ | ||
get: function get() { | ||
return this._destroyed; | ||
return (/** @type {!InertNode} */this._destroyed | ||
); | ||
} | ||
@@ -493,6 +518,6 @@ }, { | ||
get: function get() { | ||
return '_savedTabIndex' in this; | ||
return this._savedTabIndex !== null; | ||
} | ||
/** @return {Node} */ | ||
/** @return {!Node} */ | ||
@@ -506,3 +531,3 @@ }, { | ||
/** @param {number} tabIndex */ | ||
/** @param {?number} tabIndex */ | ||
@@ -516,3 +541,3 @@ }, { | ||
/** @return {number} */ | ||
/** @return {?number} */ | ||
, | ||
@@ -541,3 +566,3 @@ get: function get() { | ||
/** | ||
* @param {Document} document | ||
* @param {!Document} document | ||
*/ | ||
@@ -551,3 +576,3 @@ function InertManager(document) { | ||
/** @type {Document} */ | ||
/** @type {!Document} */ | ||
this._document = document; | ||
@@ -557,3 +582,3 @@ | ||
* All managed nodes known to this InertManager. In a map to allow looking up by Node. | ||
* @type {Map<Node, InertNode>} | ||
* @type {!Map<!Node, !InertNode>} | ||
*/ | ||
@@ -564,3 +589,3 @@ this._managedNodes = new Map(); | ||
* All inert roots known to this InertManager. In a map to allow looking up by Node. | ||
* @type {Map<Node, InertRoot>} | ||
* @type {!Map<!Node, !InertRoot>} | ||
*/ | ||
@@ -571,3 +596,3 @@ this._inertRoots = new Map(); | ||
* Observer for mutations on `document.body`. | ||
* @type {MutationObserver} | ||
* @type {!MutationObserver} | ||
*/ | ||
@@ -589,3 +614,3 @@ this._observer = new MutationObserver(this._watchForInert.bind(this)); | ||
* Set whether the given element should be an inert root or not. | ||
* @param {Element} root | ||
* @param {!Element} root | ||
* @param {boolean} inert | ||
@@ -633,4 +658,4 @@ */ | ||
* Get the InertRoot object corresponding to the given inert root element, if any. | ||
* @param {Element} element | ||
* @return {InertRoot?} | ||
* @param {!Node} element | ||
* @return {!InertRoot|undefined} | ||
*/ | ||
@@ -648,5 +673,5 @@ | ||
* be added to its set of inert roots. | ||
* @param {Node} node | ||
* @param {InertRoot} inertRoot | ||
* @return {InertNode} inertNode | ||
* @param {!Node} node | ||
* @param {!InertRoot} inertRoot | ||
* @return {!InertNode} inertNode | ||
*/ | ||
@@ -675,5 +700,5 @@ | ||
* If the node is not currently managed, this is essentially a no-op. | ||
* @param {Node} node | ||
* @param {InertRoot} inertRoot | ||
* @return {InertNode?} The potentially destroyed InertNode associated with this node, if any. | ||
* @param {!Node} node | ||
* @param {!InertRoot} inertRoot | ||
* @return {?InertNode} The potentially destroyed InertNode associated with this node, if any. | ||
*/ | ||
@@ -716,4 +741,4 @@ | ||
* Callback used when mutation observer detects attribute changes. | ||
* @param {MutationRecord} records | ||
* @param {MutationObserver} self | ||
* @param {!Array<!MutationRecord>} records | ||
* @param {!MutationObserver} self | ||
*/ | ||
@@ -724,2 +749,3 @@ | ||
value: function _watchForInert(records, self) { | ||
var _this = this; | ||
records.forEach(function (record) { | ||
@@ -733,3 +759,3 @@ switch (record.type) { | ||
var inertElements = slice.call(node.querySelectorAll('[inert]')); | ||
if (node.matches('[inert]')) { | ||
if (matches.call(node, '[inert]')) { | ||
inertElements.unshift(node); | ||
@@ -739,4 +765,4 @@ } | ||
this.setInert(inertElement, true); | ||
}, this); | ||
}, this); | ||
}, _this); | ||
}, _this); | ||
break; | ||
@@ -747,5 +773,5 @@ case 'attributes': | ||
} | ||
var target = record.target; | ||
var target = /** @type {!Element} */record.target; | ||
var inert = target.hasAttribute('inert'); | ||
this.setInert(target, inert); | ||
_this.setInert(target, inert); | ||
break; | ||
@@ -762,6 +788,6 @@ } | ||
* Recursively walk the composed tree from |node|. | ||
* @param {Node} node | ||
* @param {(function (Element))=} callback Callback to be called for each element traversed, | ||
* @param {!Node} node | ||
* @param {(function (!Element))=} callback Callback to be called for each element traversed, | ||
* before descending into child nodes. | ||
* @param {ShadowRoot=} shadowRootAncestor The nearest ShadowRoot ancestor, if any. | ||
* @param {?ShadowRoot=} shadowRootAncestor The nearest ShadowRoot ancestor, if any. | ||
*/ | ||
@@ -772,3 +798,3 @@ | ||
if (node.nodeType == Node.ELEMENT_NODE) { | ||
var element = /** @type {Element} */node; | ||
var element = /** @type {!Element} */node; | ||
if (callback) { | ||
@@ -782,3 +808,3 @@ callback(element); | ||
// ShadowRoot. | ||
var shadowRoot = element.shadowRoot || element.webkitShadowRoot; | ||
var shadowRoot = /** @type {!HTMLElement} */element.shadowRoot; | ||
if (shadowRoot) { | ||
@@ -793,3 +819,3 @@ composedTreeWalk(shadowRoot, callback, shadowRoot); | ||
if (element.localName == 'content') { | ||
var content = /** @type {HTMLContentElement} */element; | ||
var content = /** @type {!HTMLContentElement} */element; | ||
// Verifies if ShadowDom v0 is supported. | ||
@@ -807,3 +833,3 @@ var distributedNodes = content.getDistributedNodes ? content.getDistributedNodes() : []; | ||
if (element.localName == 'slot') { | ||
var slot = /** @type {HTMLSlotElement} */element; | ||
var slot = /** @type {!HTMLSlotElement} */element; | ||
// Verify if ShadowDom v1 is supported. | ||
@@ -829,3 +855,3 @@ var _distributedNodes = slot.assignedNodes ? slot.assignedNodes({ flatten: true }) : []; | ||
* Adds a style element to the node containing the inert specific styles | ||
* @param {Node} node | ||
* @param {!Node} node | ||
*/ | ||
@@ -842,2 +868,3 @@ function addInertStyle(node) { | ||
/** @type {!InertManager} */ | ||
var inertManager = new InertManager(document); | ||
@@ -848,5 +875,7 @@ | ||
enumerable: true, | ||
/** @this {!Element} */ | ||
get: function get() { | ||
return this.hasAttribute('inert'); | ||
}, | ||
/** @this {!Element} */ | ||
set: function set(inert) { | ||
@@ -853,0 +882,0 @@ inertManager.setInert(this, inert); |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define("inert",t):t()}(0,function(){"use strict";var e=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 i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=Array.prototype.slice,t=["a[href]","area[href]","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","iframe","object","embed","[contenteditable]"].join(","),r=function(){function n(e,t){i(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._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 e(n,[{key:"destructor",value:function(){this._observer.disconnect(),this._observer=null,this._rootElement&&(this.hasSavedAriaHidden?this._rootElement.setAttribute("aria-hidden",this.savedAriaHidden):this._rootElement.removeAttribute("aria-hidden")),this._rootElement=null,this._managedNodes.forEach(function(e){this._unmanageNode(e.node)},this),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){e.nodeType===Node.ELEMENT_NODE&&(e!==this._rootElement&&e.hasAttribute("inert")&&this._adoptInertRoot(e),(e.matches(t)||e.hasAttribute("tabindex"))&&this._manageNode(e))}},{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"_savedAriaHidden"in this}},{key:"savedAriaHidden",set:function(e){this._savedAriaHidden=e},get:function(){return this._savedAriaHidden}}]),n}(),s=function(){function n(e,t){i(this,n),this._node=e,this._overrodeFocusMethod=!1,this._inertRoots=new Set([t]),this._destroyed=!1,this.ensureUntabbable()}return e(n,[{key:"destructor",value:function(){this._throwIfDestroyed(),this._node&&(this.hasSavedTabIndex?this._node.setAttribute("tabindex",this.savedTabIndex):this._node.removeAttribute("tabindex"),this._overrodeFocusMethod&&delete this._node.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;if(e.matches(t)){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"_savedTabIndex"in this}},{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}();function l(e,t,n){if(e.nodeType==Node.ELEMENT_NODE){var i=e;t&&t(i);var o=i.shadowRoot||i.webkitShadowRoot;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 a(e){if(!e.querySelector("style#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 user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n",e.appendChild(t)}}var n=new(function(){function t(e){if(i(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)),a(e.head||e.body||e.documentElement),"loading"===e.readyState?e.addEventListener("DOMContentLoaded",this._onDocumentLoaded.bind(this)):this._onDocumentLoaded()}return e(t,[{key:"setInert",value:function(e,t){if(t){if(this._inertRoots.has(e))return;var n=new r(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&&a(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 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,{attributes:!0,subtree:!0,childList:!0})}},{key:"_watchForInert",value:function(e,t){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]"));e.matches("[inert]")&&t.unshift(e),t.forEach(function(e){this.setInert(e,!0)},this)}},this);break;case"attributes":if("inert"!==e.attributeName)return;var t=e.target,n=t.hasAttribute("inert");this.setInert(t,n)}},this)}}]),t}())(document);Element.prototype.hasOwnProperty("inert")||Object.defineProperty(Element.prototype,"inert",{enumerable:!0,get:function(){return this.hasAttribute("inert")},set:function(e){n.setInert(this,e)}})}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define("inert",t):t()}(0,function(){"use strict";var e=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 i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var o=Array.prototype.slice,r=Element.prototype.matches||Element.prototype.msMatchesSelector,s=["a[href]","area[href]","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","iframe","object","embed","[contenteditable]"].join(","),a=function(){function n(e,t){i(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 e(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,s)||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}(),d=function(){function n(e,t){i(this,n),this._node=e,this._overrodeFocusMethod=!1,this._inertRoots=new Set([t]),this._savedTabIndex=null,this._destroyed=!1,this.ensureUntabbable()}return e(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,s)){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}();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 u(e){if(!e.querySelector("style#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 user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n",e.appendChild(t)}}var t=new(function(){function t(e){if(i(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)),u(e.head||e.body||e.documentElement),"loading"===e.readyState?e.addEventListener("DOMContentLoaded",this._onDocumentLoaded.bind(this)):this._onDocumentLoaded()}return e(t,[{key:"setInert",value:function(e,t){if(t){if(this._inertRoots.has(e))return;var n=new a(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&&u(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 d(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,{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}())(document);Element.prototype.hasOwnProperty("inert")||Object.defineProperty(Element.prototype,"inert",{enumerable:!0,get:function(){return this.hasAttribute("inert")},set:function(e){t.setInert(this,e)}})}); | ||
//# sourceMappingURL=inert.min.js.map |
- [Background](#background) | ||
- [Spec](#spec) | ||
* [Spec gaps](#spec-gaps) | ||
- [The case for `inert` as a primitive](#the-case-for--inert--as-a-primitive) | ||
- [The case for `inert` as a primitive](#the-case-for-inert-as-a-primitive) | ||
* [Use cases](#use-cases) | ||
- [Wouldn't this be better as...](#wouldn-t-this-be-better-as) | ||
- [Wouldn't this be better as...](#wouldnt-this-be-better-as) | ||
@@ -54,3 +54,3 @@ # Background | ||
- Furthermore, the spec is unclear as to whether the attribute applies into [shadow trees](https://dom.spec.whatwg.org/#concept-shadow-tree). | ||
Consistency with CSS attributes and with inheriting attributes like [`aria-hidden`](https://www.w3.org/TR/wai-aria/states_and_properties#aria-hidden) and [`lang`](http://w3c.github.io/html/dom.html#the-lang-and-xmllang-attributes) imply that it should. | ||
Consistency with CSS attributes and with inheriting attributes like [`aria-hidden`](https://www.w3.org/TR/wai-aria/#aria-hidden) and [`lang`](https://html.spec.whatwg.org/multipage/dom.html#the-lang-and-xml:lang-attributes) imply that it should. | ||
The polyfill assumes that it does so. | ||
@@ -67,3 +67,3 @@ - The [existing description of _inert_](https://html.spec.whatwg.org/multipage/interaction.html#inert) is not specific about where pointer events which would have been targeted to an element in an inert subtree should go. | ||
Consistency with `pointer-events` would suggest (ii). The polyfill uses `pointer-events: none` and so models its behaviour. | ||
- The spec is also not explicit about whether the attribute should be [reflected](http://w3c.github.io/html/infrastructure.html#reflection). The polyfill assumes that it is. | ||
- The spec is also not explicit about whether the attribute should be [reflected](https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes). The polyfill assumes that it is. | ||
- The spec does not explicitly state that inert content should be [hidden from assistive technology](https://www.w3.org/WAI/PF/aria-implementation/#exclude_elements2). | ||
@@ -146,3 +146,3 @@ However, typically, the HTML spec does not provide this type of information. The polyfill makes _inert_ content hidden from assistive technology (via `aria-hidden`). | ||
* a focus-trapping menu; | ||
* a [side nav](https://material.google.com/patterns/navigation-drawer.html). | ||
* a [side nav](https://material.io/design/components/navigation-drawer.html). | ||
@@ -149,0 +149,0 @@ + A slide show or "cover flow" style carousel may have non-active items partially visible, |
{ | ||
"name": "wicg-inert", | ||
"version": "2.1.2", | ||
"version": "2.1.3", | ||
"description": "A polyfill for the proposed inert API", | ||
@@ -5,0 +5,0 @@ "main": "dist/inert.js", |
219
src/inert.js
@@ -7,5 +7,12 @@ /** | ||
// Convenience function for converting NodeLists. | ||
/** @type {function(number,number):Array} */ | ||
/** @type {typeof Array.prototype.slice} */ | ||
const slice = Array.prototype.slice; | ||
/** | ||
* IE has a non-standard name for "matches". | ||
* @type {typeof Element.prototype.matches} | ||
*/ | ||
const matches = | ||
Element.prototype.matches || Element.prototype.msMatchesSelector; | ||
/** @type {string} */ | ||
@@ -41,21 +48,24 @@ const _focusableElementsString = ['a[href]', | ||
/** | ||
* @param {Element} rootElement The Element at the root of the inert subtree. | ||
* @param {InertManager} inertManager The global singleton InertManager object. | ||
* @param {!Element} rootElement The Element at the root of the inert subtree. | ||
* @param {!InertManager} inertManager The global singleton InertManager object. | ||
*/ | ||
constructor(rootElement, inertManager) { | ||
/** @type {InertManager} */ | ||
/** @type {!InertManager} */ | ||
this._inertManager = inertManager; | ||
/** @type {Element} */ | ||
/** @type {!Element} */ | ||
this._rootElement = rootElement; | ||
/** | ||
* @type {Set<Node>} | ||
* @type {!Set<!InertNode>} | ||
* All managed focusable nodes in this InertRoot's subtree. | ||
*/ | ||
this._managedNodes = new Set([]); | ||
this._managedNodes = new Set(); | ||
// Make the subtree hidden from assistive technology | ||
if (this._rootElement.hasAttribute('aria-hidden')) { | ||
/** @type {?string} */ | ||
this._savedAriaHidden = this._rootElement.getAttribute('aria-hidden'); | ||
} else { | ||
this._savedAriaHidden = null; | ||
} | ||
@@ -82,7 +92,6 @@ this._rootElement.setAttribute('aria-hidden', 'true'); | ||
this._observer.disconnect(); | ||
this._observer = null; | ||
if (this._rootElement) { | ||
if (this.hasSavedAriaHidden) { | ||
this._rootElement.setAttribute('aria-hidden', this.savedAriaHidden); | ||
if (this._savedAriaHidden !== null) { | ||
this._rootElement.setAttribute('aria-hidden', this._savedAriaHidden); | ||
} else { | ||
@@ -92,3 +101,2 @@ this._rootElement.removeAttribute('aria-hidden'); | ||
} | ||
this._rootElement = null; | ||
@@ -99,9 +107,16 @@ this._managedNodes.forEach(function(inertNode) { | ||
this._managedNodes = null; | ||
this._inertManager = null; | ||
// Note we cast the nulls to the ANY type here because: | ||
// 1) We want the class properties to be declared as non-null, or else we | ||
// need even more casts throughout this code. All bets are off if an | ||
// instance has been destroyed and a method is called. | ||
// 2) We don't want to cast "this", because we want type-aware optimizations | ||
// to know which properties we're setting. | ||
this._observer = /** @type {?} */ (null); | ||
this._rootElement = /** @type {?} */ (null); | ||
this._managedNodes = /** @type {?} */ (null); | ||
this._inertManager = /** @type {?} */ (null); | ||
} | ||
/** | ||
* @return {Set<InertNode>} A copy of this InertRoot's managed nodes set. | ||
* @return {!Set<!InertNode>} A copy of this InertRoot's managed nodes set. | ||
*/ | ||
@@ -114,6 +129,6 @@ get managedNodes() { | ||
get hasSavedAriaHidden() { | ||
return '_savedAriaHidden' in this; | ||
return this._savedAriaHidden !== null; | ||
} | ||
/** @param {string} ariaHidden */ | ||
/** @param {?string} ariaHidden */ | ||
set savedAriaHidden(ariaHidden) { | ||
@@ -123,3 +138,3 @@ this._savedAriaHidden = ariaHidden; | ||
/** @return {string} */ | ||
/** @return {?string} */ | ||
get savedAriaHidden() { | ||
@@ -130,3 +145,3 @@ return this._savedAriaHidden; | ||
/** | ||
* @param {Node} startNode | ||
* @param {!Node} startNode | ||
*/ | ||
@@ -141,6 +156,7 @@ _makeSubtreeUnfocusable(startNode) { | ||
let node = startNode; | ||
/** @type {!ShadowRoot|undefined} */ | ||
let root = undefined; | ||
while (node) { | ||
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { | ||
root = node; | ||
root = /** @type {!ShadowRoot} */ (node); | ||
break; | ||
@@ -166,3 +182,3 @@ } | ||
/** | ||
* @param {Node} node | ||
* @param {!Node} node | ||
*/ | ||
@@ -173,11 +189,12 @@ _visitNode(node) { | ||
} | ||
const element = /** @type {!Element} */ (node); | ||
// If a descendant inert root becomes un-inert, its descendants will still be inert because of | ||
// this inert root, so all of its managed nodes need to be adopted by this InertRoot. | ||
if (node !== this._rootElement && node.hasAttribute('inert')) { | ||
this._adoptInertRoot(node); | ||
if (element !== this._rootElement && element.hasAttribute('inert')) { | ||
this._adoptInertRoot(element); | ||
} | ||
if (node.matches(_focusableElementsString) || node.hasAttribute('tabindex')) { | ||
this._manageNode(node); | ||
if (matches.call(element, _focusableElementsString) || element.hasAttribute('tabindex')) { | ||
this._manageNode(element); | ||
} | ||
@@ -188,3 +205,3 @@ } | ||
* Register the given node with this InertRoot and with InertManager. | ||
* @param {Node} node | ||
* @param {!Node} node | ||
*/ | ||
@@ -198,3 +215,3 @@ _manageNode(node) { | ||
* Unregister the given node with this InertRoot and with InertManager. | ||
* @param {Node} node | ||
* @param {!Node} node | ||
*/ | ||
@@ -210,3 +227,3 @@ _unmanageNode(node) { | ||
* Unregister the entire subtree starting at `startNode`. | ||
* @param {Node} startNode | ||
* @param {!Node} startNode | ||
*/ | ||
@@ -219,3 +236,3 @@ _unmanageSubtree(startNode) { | ||
* If a descendant node is found with an `inert` attribute, adopt its managed nodes. | ||
* @param {Node} node | ||
* @param {!Element} node | ||
*/ | ||
@@ -239,8 +256,8 @@ _adoptInertRoot(node) { | ||
* Callback used when mutation observer detects subtree additions, removals, or attribute changes. | ||
* @param {MutationRecord} records | ||
* @param {MutationObserver} self | ||
* @param {!Array<!MutationRecord>} records | ||
* @param {!MutationObserver} self | ||
*/ | ||
_onMutation(records, self) { | ||
records.forEach(function(record) { | ||
const target = record.target; | ||
const target = /** @type {!Element} */ (record.target); | ||
if (record.type === 'childList') { | ||
@@ -294,7 +311,7 @@ // Manage added nodes | ||
/** | ||
* @param {Node} node A focusable element to be made inert. | ||
* @param {InertRoot} inertRoot The inert root element associated with this inert node. | ||
* @param {!Node} node A focusable element to be made inert. | ||
* @param {!InertRoot} inertRoot The inert root element associated with this inert node. | ||
*/ | ||
constructor(node, inertRoot) { | ||
/** @type {Node} */ | ||
/** @type {!Node} */ | ||
this._node = node; | ||
@@ -306,3 +323,3 @@ | ||
/** | ||
* @type {Set<InertRoot>} The set of descendant inert roots. | ||
* @type {!Set<!InertRoot>} The set of descendant inert roots. | ||
* If and only if this set becomes empty, this node is no longer inert. | ||
@@ -312,2 +329,5 @@ */ | ||
/** @type {?number} */ | ||
this._savedTabIndex = null; | ||
/** @type {boolean} */ | ||
@@ -327,7 +347,8 @@ this._destroyed = false; | ||
if (this._node) { | ||
if (this.hasSavedTabIndex) { | ||
this._node.setAttribute('tabindex', this.savedTabIndex); | ||
if (this._node && this._node.nodeType === Node.ELEMENT_NODE) { | ||
const element = /** @type {!Element} */ (this._node); | ||
if (this._savedTabIndex !== null) { | ||
element.setAttribute('tabindex', this._savedTabIndex); | ||
} else { | ||
this._node.removeAttribute('tabindex'); | ||
element.removeAttribute('tabindex'); | ||
} | ||
@@ -337,8 +358,9 @@ | ||
if (this._overrodeFocusMethod) { | ||
delete this._node.focus; | ||
delete element.focus; | ||
} | ||
} | ||
this._node = null; | ||
this._inertRoots = null; | ||
// See note in InertRoot.destructor for why we cast these nulls to ANY. | ||
this._node = /** @type {?} */ (null); | ||
this._inertRoots = /** @type {?} */ (null); | ||
this._destroyed = true; | ||
@@ -352,3 +374,3 @@ } | ||
get destroyed() { | ||
return this._destroyed; | ||
return /** @type {!InertNode} */ (this)._destroyed; | ||
} | ||
@@ -367,6 +389,6 @@ | ||
get hasSavedTabIndex() { | ||
return '_savedTabIndex' in this; | ||
return this._savedTabIndex !== null; | ||
} | ||
/** @return {Node} */ | ||
/** @return {!Node} */ | ||
get node() { | ||
@@ -377,3 +399,3 @@ this._throwIfDestroyed(); | ||
/** @param {number} tabIndex */ | ||
/** @param {?number} tabIndex */ | ||
set savedTabIndex(tabIndex) { | ||
@@ -384,3 +406,3 @@ this._throwIfDestroyed(); | ||
/** @return {number} */ | ||
/** @return {?number} */ | ||
get savedTabIndex() { | ||
@@ -393,19 +415,23 @@ this._throwIfDestroyed(); | ||
ensureUntabbable() { | ||
const node = this.node; | ||
if (node.matches(_focusableElementsString)) { | ||
if (node.tabIndex === -1 && this.hasSavedTabIndex) { | ||
if (this.node.nodeType !== Node.ELEMENT_NODE) { | ||
return; | ||
} | ||
const element = /** @type {!Element} */ (this.node); | ||
if (matches.call(element, _focusableElementsString)) { | ||
if (/** @type {!HTMLElement} */ (element).tabIndex === -1 && | ||
this.hasSavedTabIndex) { | ||
return; | ||
} | ||
if (node.hasAttribute('tabindex')) { | ||
this._savedTabIndex = node.tabIndex; | ||
if (element.hasAttribute('tabindex')) { | ||
this._savedTabIndex = /** @type {!HTMLElement} */ (element).tabIndex; | ||
} | ||
node.setAttribute('tabindex', '-1'); | ||
if (node.nodeType === Node.ELEMENT_NODE) { | ||
node.focus = function() {}; | ||
element.setAttribute('tabindex', '-1'); | ||
if (element.nodeType === Node.ELEMENT_NODE) { | ||
element.focus = function() {}; | ||
this._overrodeFocusMethod = true; | ||
} | ||
} else if (node.hasAttribute('tabindex')) { | ||
this._savedTabIndex = node.tabIndex; | ||
node.removeAttribute('tabindex'); | ||
} else if (element.hasAttribute('tabindex')) { | ||
this._savedTabIndex = /** @type {!HTMLElement} */ (element).tabIndex; | ||
element.removeAttribute('tabindex'); | ||
} | ||
@@ -416,3 +442,3 @@ } | ||
* Add another inert root to this inert node's set of managing inert roots. | ||
* @param {InertRoot} inertRoot | ||
* @param {!InertRoot} inertRoot | ||
*/ | ||
@@ -428,3 +454,3 @@ addInertRoot(inertRoot) { | ||
* so the object should be destroyed. | ||
* @param {InertRoot} inertRoot | ||
* @param {!InertRoot} inertRoot | ||
*/ | ||
@@ -451,3 +477,3 @@ removeInertRoot(inertRoot) { | ||
/** | ||
* @param {Document} document | ||
* @param {!Document} document | ||
*/ | ||
@@ -459,3 +485,3 @@ constructor(document) { | ||
/** @type {Document} */ | ||
/** @type {!Document} */ | ||
this._document = document; | ||
@@ -465,3 +491,3 @@ | ||
* All managed nodes known to this InertManager. In a map to allow looking up by Node. | ||
* @type {Map<Node, InertNode>} | ||
* @type {!Map<!Node, !InertNode>} | ||
*/ | ||
@@ -472,3 +498,3 @@ this._managedNodes = new Map(); | ||
* All inert roots known to this InertManager. In a map to allow looking up by Node. | ||
* @type {Map<Node, InertRoot>} | ||
* @type {!Map<!Node, !InertRoot>} | ||
*/ | ||
@@ -479,7 +505,6 @@ this._inertRoots = new Map(); | ||
* Observer for mutations on `document.body`. | ||
* @type {MutationObserver} | ||
* @type {!MutationObserver} | ||
*/ | ||
this._observer = new MutationObserver(this._watchForInert.bind(this)); | ||
// Add inert style. | ||
@@ -498,3 +523,3 @@ addInertStyle(document.head || document.body || document.documentElement); | ||
* Set whether the given element should be an inert root or not. | ||
* @param {Element} root | ||
* @param {!Element} root | ||
* @param {boolean} inert | ||
@@ -536,4 +561,4 @@ */ | ||
* Get the InertRoot object corresponding to the given inert root element, if any. | ||
* @param {Element} element | ||
* @return {InertRoot?} | ||
* @param {!Node} element | ||
* @return {!InertRoot|undefined} | ||
*/ | ||
@@ -548,5 +573,5 @@ getInertRoot(element) { | ||
* be added to its set of inert roots. | ||
* @param {Node} node | ||
* @param {InertRoot} inertRoot | ||
* @return {InertNode} inertNode | ||
* @param {!Node} node | ||
* @param {!InertRoot} inertRoot | ||
* @return {!InertNode} inertNode | ||
*/ | ||
@@ -571,5 +596,5 @@ register(node, inertRoot) { | ||
* If the node is not currently managed, this is essentially a no-op. | ||
* @param {Node} node | ||
* @param {InertRoot} inertRoot | ||
* @return {InertNode?} The potentially destroyed InertNode associated with this node, if any. | ||
* @param {!Node} node | ||
* @param {!InertRoot} inertRoot | ||
* @return {?InertNode} The potentially destroyed InertNode associated with this node, if any. | ||
*/ | ||
@@ -606,6 +631,7 @@ deregister(node, inertRoot) { | ||
* Callback used when mutation observer detects attribute changes. | ||
* @param {MutationRecord} records | ||
* @param {MutationObserver} self | ||
* @param {!Array<!MutationRecord>} records | ||
* @param {!MutationObserver} self | ||
*/ | ||
_watchForInert(records, self) { | ||
const _this = this; | ||
records.forEach(function(record) { | ||
@@ -619,3 +645,3 @@ switch (record.type) { | ||
const inertElements = slice.call(node.querySelectorAll('[inert]')); | ||
if (node.matches('[inert]')) { | ||
if (matches.call(node, '[inert]')) { | ||
inertElements.unshift(node); | ||
@@ -625,4 +651,4 @@ } | ||
this.setInert(inertElement, true); | ||
}, this); | ||
}, this); | ||
}, _this); | ||
}, _this); | ||
break; | ||
@@ -633,5 +659,5 @@ case 'attributes': | ||
} | ||
const target = record.target; | ||
const target = /** @type {!Element} */ (record.target); | ||
const inert = target.hasAttribute('inert'); | ||
this.setInert(target, inert); | ||
_this.setInert(target, inert); | ||
break; | ||
@@ -643,12 +669,12 @@ } | ||
/** | ||
* Recursively walk the composed tree from |node|. | ||
* @param {Node} node | ||
* @param {(function (Element))=} callback Callback to be called for each element traversed, | ||
* before descending into child nodes. | ||
* @param {ShadowRoot=} shadowRootAncestor The nearest ShadowRoot ancestor, if any. | ||
*/ | ||
/** | ||
* Recursively walk the composed tree from |node|. | ||
* @param {!Node} node | ||
* @param {(function (!Element))=} callback Callback to be called for each element traversed, | ||
* before descending into child nodes. | ||
* @param {?ShadowRoot=} shadowRootAncestor The nearest ShadowRoot ancestor, if any. | ||
*/ | ||
function composedTreeWalk(node, callback, shadowRootAncestor) { | ||
if (node.nodeType == Node.ELEMENT_NODE) { | ||
const element = /** @type {Element} */ (node); | ||
const element = /** @type {!Element} */ (node); | ||
if (callback) { | ||
@@ -662,3 +688,3 @@ callback(element); | ||
// ShadowRoot. | ||
const shadowRoot = element.shadowRoot || element.webkitShadowRoot; | ||
const shadowRoot = /** @type {!HTMLElement} */ (element).shadowRoot; | ||
if (shadowRoot) { | ||
@@ -673,3 +699,3 @@ composedTreeWalk(shadowRoot, callback, shadowRoot); | ||
if (element.localName == 'content') { | ||
const content = /** @type {HTMLContentElement} */ (element); | ||
const content = /** @type {!HTMLContentElement} */ (element); | ||
// Verifies if ShadowDom v0 is supported. | ||
@@ -688,3 +714,3 @@ const distributedNodes = content.getDistributedNodes ? | ||
if (element.localName == 'slot') { | ||
const slot = /** @type {HTMLSlotElement} */ (element); | ||
const slot = /** @type {!HTMLSlotElement} */ (element); | ||
// Verify if ShadowDom v1 is supported. | ||
@@ -711,3 +737,3 @@ const distributedNodes = slot.assignedNodes ? | ||
* Adds a style element to the node containing the inert specific styles | ||
* @param {Node} node | ||
* @param {!Node} node | ||
*/ | ||
@@ -735,2 +761,3 @@ function addInertStyle(node) { | ||
/** @type {!InertManager} */ | ||
const inertManager = new InertManager(document); | ||
@@ -741,5 +768,7 @@ | ||
enumerable: true, | ||
/** @this {!Element} */ | ||
get: function() { | ||
return this.hasAttribute('inert'); | ||
}, | ||
/** @this {!Element} */ | ||
set: function(inert) { | ||
@@ -746,0 +775,0 @@ inertManager.setInert(this, inert); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
141841
1979