@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
120 lines • 4.22 kB
JavaScript
export class InteractionInvalidation {
constructor(options = null) {
this.bypassElements = [];
this.bypassSelectors = [];
this.options = options || {};
return this;
}
setBypassElements(bypassElements) {
this.bypassElements = bypassElements;
}
setBypassSelector(bypassSelector) {
if (!Array.isArray(bypassSelector)) {
bypassSelector = [bypassSelector];
}
this.bypassSelectors = bypassSelector;
return this;
}
activate(targetElement = null) {
if (!this._nodesToInvalidate) {
this._runInvalidation(targetElement);
}
}
revert() {
this._revertInvalidation();
this._nodesToInvalidate = null;
}
_runInvalidation(targetElement) {
if (typeof document === 'undefined') {
return;
}
this._nodesToInvalidate = this.getNodesToInvalidate(targetElement);
if (!Array.isArray(this._nodesToInvalidate)) {
return;
}
for (const node of this._nodesToInvalidate) {
if (!node) {
continue;
}
if (this.options.tabIndex !== false) {
const tabIndex = node.getAttribute('tabindex');
if (tabIndex !== null && typeof node.__tabIndex === 'undefined') {
node.__tabIndex = tabIndex;
}
node.setAttribute('tabindex', '-1');
}
if (this.options.ariaHidden !== false) {
const ariaHidden = node.getAttribute('aria-hidden');
if (ariaHidden !== null && typeof node.__ariaHidden === 'undefined') {
node.__ariaHidden = ariaHidden;
}
node.setAttribute('aria-hidden', 'true');
}
}
}
_revertInvalidation() {
if (!Array.isArray(this._nodesToInvalidate)) {
return;
}
for (const node of this._nodesToInvalidate) {
if (!node) {
continue;
}
if (this.options.tabIndex !== false) {
if (typeof node.__tabIndex !== 'undefined') {
node.setAttribute('tabindex', node.__tabIndex);
delete node.__tabIndex;
} else {
node.removeAttribute('tabindex');
}
}
if (this.options.ariaHidden !== false) {
if (typeof node.__ariaHidden !== 'undefined') {
node.setAttribute('aria-hidden', node.__ariaHidden);
delete node.__ariaHidden;
} else {
node.removeAttribute('aria-hidden');
}
}
}
}
getNodesToInvalidate(targetElement = null) {
if (typeof document === 'undefined') {
return [];
}
if (typeof targetElement === 'string') {
targetElement = document.querySelector(targetElement);
}
const rootSelector = targetElement ? '*' : 'html *';
const elementSelector = this.bypassSelectors.map(s => `:not(${s})`).join('');
const selector = `${rootSelector} ${elementSelector}:not(script):not(style):not(path):not(head *)`;
if (process.env.NODE_ENV === 'test') {
const allNodes = Array.from((targetElement || document.documentElement).querySelectorAll('*'));
return allNodes.filter(node => {
if (node.tagName === 'SCRIPT' || node.tagName === 'STYLE' || node.tagName === 'PATH' || node.tagName === 'HEAD' || node.tagName === 'BODY') {
return false;
}
const bypassedByElement = this.bypassElements.includes(node);
const bypassedBySelector = this.bypassSelectors.some(selector => {
try {
if (selector.endsWith(' *')) {
const baseSelector = selector.replace(' *', '');
const baseElement = (targetElement || document.documentElement).querySelector(baseSelector);
return baseElement && baseElement.contains(node);
} else {
const matchingElement = (targetElement || document.documentElement).querySelector(selector);
return matchingElement && matchingElement.contains(node);
}
} catch (e) {
return false;
}
});
return !(bypassedByElement || bypassedBySelector);
});
}
try {
return Array.from((targetElement || document.documentElement).querySelectorAll(selector)).filter(node => !this.bypassElements.includes(node));
} catch (error) {}
}
}
//# sourceMappingURL=InteractionInvalidation.js.map