a11y-dialog
Advanced tools
Comparing version 6.1.0 to 7.0.0-rc.1
@@ -23,6 +23,5 @@ var focusableSelectors = [ | ||
* @constructor | ||
* @param {Element} node | ||
* @param {(NodeList | Element | string)} targets | ||
* @param {Element} element | ||
*/ | ||
function A11yDialog(node, targets) { | ||
function A11yDialog(element) { | ||
// Prebind the functions that will be bound in addEventListener and | ||
@@ -34,17 +33,11 @@ // removeEventListener to avoid losing references | ||
this._bindKeypress = this._bindKeypress.bind(this); | ||
this.$el = element; | ||
this.shown = false; | ||
this._id = this.$el.getAttribute('data-a11y-dialog') || this.$el.id; | ||
this._previouslyFocused = null; | ||
// Keep a reference of the node and the actual dialog on the instance | ||
this.container = node; | ||
this.dialog = node.querySelector( | ||
'dialog, [role="dialog"], [role="alertdialog"]' | ||
); | ||
this.role = this.dialog.getAttribute('role') || 'dialog'; | ||
this.useDialog = 'show' in this.dialog; | ||
// Keep an object of listener types mapped to callback functions | ||
this._listeners = {}; | ||
// Initialise everything needed for the dialog to work properly | ||
this.create(targets); | ||
this.create(); | ||
} | ||
@@ -58,26 +51,8 @@ | ||
*/ | ||
A11yDialog.prototype.create = function (targets) { | ||
// Keep a collection of nodes to disable/enable when toggling the dialog | ||
this._targets = | ||
this._targets || collect(targets) || getSiblings(this.container); | ||
A11yDialog.prototype.create = function () { | ||
this.$el.setAttribute('aria-hidden', true); | ||
this.$el.setAttribute('aria-modal', true); | ||
// Set the `shown` property to match the status from the DOM | ||
this.shown = this.dialog.hasAttribute('open'); | ||
// Despite using a `<dialog>` element, `role="dialog"` is not necessarily | ||
// implied by all screen-readers (yet) | ||
// See: https://github.com/KittyGiraudel/a11y-dialog/commit/6ba711a777aed0dbda0719a18a02f742098c64d9#commitcomment-28694166 | ||
this.dialog.setAttribute('role', this.role); | ||
if (!this.useDialog) { | ||
if (this.shown) { | ||
this.container.removeAttribute('aria-hidden'); | ||
} else { | ||
this.container.setAttribute('aria-hidden', true); | ||
} | ||
} else { | ||
this.container.setAttribute('data-a11y-dialog-native', ''); | ||
// Remove initial `aria-hidden` from container | ||
// See: https://github.com/KittyGiraudel/a11y-dialog/pull/117#issuecomment-706056246 | ||
this.container.removeAttribute('aria-hidden'); | ||
if (!this.$el.hasAttribute('role')) { | ||
this.$el.setAttribute('role', 'dialog'); | ||
} | ||
@@ -87,3 +62,3 @@ | ||
// event listener to open the dialog | ||
this._openers = $$('[data-a11y-dialog-show="' + this.container.id + '"]'); | ||
this._openers = $$('[data-a11y-dialog-show="' + this._id + '"]'); | ||
this._openers.forEach( | ||
@@ -97,4 +72,4 @@ function (opener) { | ||
// event listener to close the dialog | ||
this._closers = $$('[data-a11y-dialog-hide]', this.container).concat( | ||
$$('[data-a11y-dialog-hide="' + this.container.id + '"]') | ||
this._closers = $$('[data-a11y-dialog-hide]', this.$el).concat( | ||
$$('[data-a11y-dialog-hide="' + this._id + '"]') | ||
); | ||
@@ -127,29 +102,10 @@ this._closers.forEach( | ||
this.shown = true; | ||
// Keep a reference to the currently focused element to be able to restore | ||
// it later | ||
this._previouslyFocused = document.activeElement; | ||
this.$el.removeAttribute('aria-hidden'); | ||
this.shown = true; | ||
if (this.useDialog) { | ||
this.dialog.showModal(event instanceof Event ? void 0 : event); | ||
} else { | ||
this.dialog.setAttribute('open', ''); | ||
this.container.removeAttribute('aria-hidden'); | ||
// Iterate over the targets to disable them by setting their `aria-hidden` | ||
// attribute to `true` and, if present, storing the current value of `aria-hidden` | ||
this._targets.forEach(function (target) { | ||
if (target.hasAttribute('aria-hidden')) { | ||
target.setAttribute( | ||
'data-a11y-dialog-original-aria-hidden', | ||
target.getAttribute('aria-hidden') | ||
); | ||
} | ||
target.setAttribute('aria-hidden', 'true'); | ||
}); | ||
} | ||
// Set the focus to the first focusable child of the dialog element | ||
setFocusToFirstItem(this.dialog); | ||
setFocusToFirstItem(this.$el); | ||
@@ -183,24 +139,4 @@ // Bind a focus event listener to the body element to make sure the focus | ||
this.shown = false; | ||
this.$el.setAttribute('aria-hidden', 'true'); | ||
if (this.useDialog) { | ||
this.dialog.close(event instanceof Event ? void 0 : event); | ||
} else { | ||
this.dialog.removeAttribute('open'); | ||
this.container.setAttribute('aria-hidden', 'true'); | ||
// Iterate over the targets to enable them by removing their `aria-hidden` | ||
// attribute or resetting it to its original value | ||
this._targets.forEach(function (target) { | ||
if (target.hasAttribute('data-a11y-dialog-original-aria-hidden')) { | ||
target.setAttribute( | ||
'aria-hidden', | ||
target.getAttribute('data-a11y-dialog-original-aria-hidden') | ||
); | ||
target.removeAttribute('data-a11y-dialog-original-aria-hidden'); | ||
} else { | ||
target.removeAttribute('aria-hidden'); | ||
} | ||
}); | ||
} | ||
// If there was a focused element before the dialog was opened (and it has a | ||
@@ -302,3 +238,3 @@ // `focus` method), restore the focus back to it | ||
function (listener) { | ||
listener(this.container, event); | ||
listener(this.$el, event); | ||
}.bind(this) | ||
@@ -318,3 +254,3 @@ ); | ||
// are only reacted to for the most recent one | ||
if (!this.dialog.contains(document.activeElement)) return | ||
if (!this.$el.contains(document.activeElement)) return | ||
@@ -324,3 +260,7 @@ // If the dialog is shown and the ESCAPE key is being pressed, prevent any | ||
// is 'alertdialog', which should be modal | ||
if (this.shown && event.which === ESCAPE_KEY && this.role !== 'alertdialog') { | ||
if ( | ||
this.shown && | ||
event.which === ESCAPE_KEY && | ||
this.$el.getAttribute('role') !== 'alertdialog' | ||
) { | ||
event.preventDefault(); | ||
@@ -333,3 +273,3 @@ this.hide(event); | ||
if (this.shown && event.which === TAB_KEY) { | ||
trapTabKey(this.dialog, event); | ||
trapTabKey(this.$el, event); | ||
} | ||
@@ -353,6 +293,6 @@ }; | ||
this.shown && | ||
!this.container.contains(event.target) && | ||
dialogTarget === this.container.id | ||
!this.$el.contains(event.target) && | ||
dialogTarget === this._id | ||
) { | ||
setFocusToFirstItem(this.container); | ||
setFocusToFirstItem(this.$el); | ||
} | ||
@@ -384,23 +324,2 @@ }; | ||
/** | ||
* Return an array of Element based on given argument (NodeList, Element or | ||
* string representing a selector) | ||
* | ||
* @param {(NodeList | Element | string)} target | ||
* @return {Array<Element>} | ||
*/ | ||
function collect(target) { | ||
if (NodeList.prototype.isPrototypeOf(target)) { | ||
return toArray(target) | ||
} | ||
if (Element.prototype.isPrototypeOf(target)) { | ||
return [target] | ||
} | ||
if (typeof target === 'string') { | ||
return $$(target) | ||
} | ||
} | ||
/** | ||
* Set the focus to the first element with `autofocus` or the first focusable | ||
@@ -464,19 +383,2 @@ * child of the given element | ||
/** | ||
* Retrieve siblings from given element | ||
* | ||
* @param {Element} node | ||
* @return {Array<Element>} | ||
*/ | ||
function getSiblings(node) { | ||
var nodes = toArray(node.parentNode.childNodes); | ||
var siblings = nodes.filter(function (node) { | ||
return node.nodeType === 1 | ||
}); | ||
siblings.splice(siblings.indexOf(node), 1); | ||
return siblings | ||
} | ||
function instantiateDialogs() { | ||
@@ -483,0 +385,0 @@ $$('[data-a11y-dialog]').forEach(function (node) { |
@@ -1,2 +0,2 @@ | ||
/*! a11y-dialog 6.1.0 — © Kitty Giraudel */ | ||
var t=['a[href]:not([tabindex^="-"])','area[href]:not([tabindex^="-"])','input:not([type="hidden"]):not([type="radio"]):not([disabled]):not([tabindex^="-"])','input[type="radio"]:not([disabled]):not([tabindex^="-"]):checked','select:not([disabled]):not([tabindex^="-"])','textarea:not([disabled]):not([tabindex^="-"])','button:not([disabled]):not([tabindex^="-"])','iframe:not([tabindex^="-"])','audio[controls]:not([tabindex^="-"])','video[controls]:not([tabindex^="-"])','[contenteditable]:not([tabindex^="-"])','[tabindex]:not([tabindex^="-"])'];function i(t,i){this._show=this.show.bind(this),this._hide=this.hide.bind(this),this._maintainFocus=this._maintainFocus.bind(this),this._bindKeypress=this._bindKeypress.bind(this),this._previouslyFocused=null,this.container=t,this.dialog=t.querySelector('dialog, [role="dialog"], [role="alertdialog"]'),this.role=this.dialog.getAttribute("role")||"dialog",this.useDialog="show"in this.dialog,this._listeners={},this.create(i)}function e(t){return Array.prototype.slice.call(t)}function n(t,i){return e((i||document).querySelectorAll(t))}function o(t){var i=s(t),e=t.querySelector("[autofocus]")||i[0];e&&e.focus()}function s(i){return n(t.join(","),i).filter((function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)}))}function r(){n("[data-a11y-dialog]").forEach((function(t){new i(t,t.getAttribute("data-a11y-dialog")||void 0)}))}i.prototype.create=function(t){var i,o;return this._targets=this._targets||function(t){if(NodeList.prototype.isPrototypeOf(t))return e(t);if(Element.prototype.isPrototypeOf(t))return[t];if("string"==typeof t)return n(t)}(t)||(i=this.container,(o=e(i.parentNode.childNodes).filter((function(t){return 1===t.nodeType}))).splice(o.indexOf(i),1),o),this.shown=this.dialog.hasAttribute("open"),this.dialog.setAttribute("role",this.role),this.useDialog?(this.container.setAttribute("data-a11y-dialog-native",""),this.container.removeAttribute("aria-hidden")):this.shown?this.container.removeAttribute("aria-hidden"):this.container.setAttribute("aria-hidden",!0),this._openers=n('[data-a11y-dialog-show="'+this.container.id+'"]'),this._openers.forEach(function(t){t.addEventListener("click",this._show)}.bind(this)),this._closers=n("[data-a11y-dialog-hide]",this.container).concat(n('[data-a11y-dialog-hide="'+this.container.id+'"]')),this._closers.forEach(function(t){t.addEventListener("click",this._hide)}.bind(this)),this._fire("create"),this},i.prototype.show=function(t){return this.shown||(this.shown=!0,this._previouslyFocused=document.activeElement,this.useDialog?this.dialog.showModal(t instanceof Event?void 0:t):(this.dialog.setAttribute("open",""),this.container.removeAttribute("aria-hidden"),this._targets.forEach((function(t){t.hasAttribute("aria-hidden")&&t.setAttribute("data-a11y-dialog-original-aria-hidden",t.getAttribute("aria-hidden")),t.setAttribute("aria-hidden","true")}))),o(this.dialog),document.body.addEventListener("focus",this._maintainFocus,!0),document.addEventListener("keydown",this._bindKeypress),this._fire("show",t)),this},i.prototype.hide=function(t){return this.shown?(this.shown=!1,this.useDialog?this.dialog.close(t instanceof Event?void 0:t):(this.dialog.removeAttribute("open"),this.container.setAttribute("aria-hidden","true"),this._targets.forEach((function(t){t.hasAttribute("data-a11y-dialog-original-aria-hidden")?(t.setAttribute("aria-hidden",t.getAttribute("data-a11y-dialog-original-aria-hidden")),t.removeAttribute("data-a11y-dialog-original-aria-hidden")):t.removeAttribute("aria-hidden")}))),this._previouslyFocused&&this._previouslyFocused.focus&&this._previouslyFocused.focus(),document.body.removeEventListener("focus",this._maintainFocus,!0),document.removeEventListener("keydown",this._bindKeypress),this._fire("hide",t),this):this},i.prototype.destroy=function(){return this.hide(),this._openers.forEach(function(t){t.removeEventListener("click",this._show)}.bind(this)),this._closers.forEach(function(t){t.removeEventListener("click",this._hide)}.bind(this)),this._fire("destroy"),this._listeners={},this},i.prototype.on=function(t,i){return void 0===this._listeners[t]&&(this._listeners[t]=[]),this._listeners[t].push(i),this},i.prototype.off=function(t,i){var e=(this._listeners[t]||[]).indexOf(i);return e>-1&&this._listeners[t].splice(e,1),this},i.prototype._fire=function(t,i){(this._listeners[t]||[]).forEach(function(t){t(this.container,i)}.bind(this))},i.prototype._bindKeypress=function(t){this.dialog.contains(document.activeElement)&&(this.shown&&27===t.which&&"alertdialog"!==this.role&&(t.preventDefault(),this.hide(t)),this.shown&&9===t.which&&function(t,i){var e=s(t),n=e.indexOf(document.activeElement);i.shiftKey&&0===n?(e[e.length-1].focus(),i.preventDefault()):i.shiftKey||n!==e.length-1||(e[0].focus(),i.preventDefault())}(this.dialog,t))},i.prototype._maintainFocus=function(t){var i=t.target.getAttribute("data-a11y-dialog-show");this.shown&&!this.container.contains(t.target)&&i===this.container.id&&o(this.container)},"undefined"!=typeof document&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",r):window.requestAnimationFrame?window.requestAnimationFrame(r):window.setTimeout(r,16));export default i; | ||
/*! a11y-dialog 7.0.0-rc.1 — © Kitty Giraudel */ | ||
var t=['a[href]:not([tabindex^="-"])','area[href]:not([tabindex^="-"])','input:not([type="hidden"]):not([type="radio"]):not([disabled]):not([tabindex^="-"])','input[type="radio"]:not([disabled]):not([tabindex^="-"]):checked','select:not([disabled]):not([tabindex^="-"])','textarea:not([disabled]):not([tabindex^="-"])','button:not([disabled]):not([tabindex^="-"])','iframe:not([tabindex^="-"])','audio[controls]:not([tabindex^="-"])','video[controls]:not([tabindex^="-"])','[contenteditable]:not([tabindex^="-"])','[tabindex]:not([tabindex^="-"])'];function e(t){this._show=this.show.bind(this),this._hide=this.hide.bind(this),this._maintainFocus=this._maintainFocus.bind(this),this._bindKeypress=this._bindKeypress.bind(this),this.$el=t,this.shown=!1,this._id=this.$el.getAttribute("data-a11y-dialog")||this.$el.id,this._previouslyFocused=null,this._listeners={},this.create()}function i(t,e){return i=(e||document).querySelectorAll(t),Array.prototype.slice.call(i);var i}function n(t){var e=s(t),i=t.querySelector("[autofocus]")||e[0];i&&i.focus()}function s(e){return i(t.join(","),e).filter((function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)}))}function o(){i("[data-a11y-dialog]").forEach((function(t){new e(t,t.getAttribute("data-a11y-dialog")||void 0)}))}e.prototype.create=function(){return this.$el.setAttribute("aria-hidden",!0),this.$el.setAttribute("aria-modal",!0),this.$el.hasAttribute("role")||this.$el.setAttribute("role","dialog"),this._openers=i('[data-a11y-dialog-show="'+this._id+'"]'),this._openers.forEach(function(t){t.addEventListener("click",this._show)}.bind(this)),this._closers=i("[data-a11y-dialog-hide]",this.$el).concat(i('[data-a11y-dialog-hide="'+this._id+'"]')),this._closers.forEach(function(t){t.addEventListener("click",this._hide)}.bind(this)),this._fire("create"),this},e.prototype.show=function(t){return this.shown||(this._previouslyFocused=document.activeElement,this.$el.removeAttribute("aria-hidden"),this.shown=!0,n(this.$el),document.body.addEventListener("focus",this._maintainFocus,!0),document.addEventListener("keydown",this._bindKeypress),this._fire("show",t)),this},e.prototype.hide=function(t){return this.shown?(this.shown=!1,this.$el.setAttribute("aria-hidden","true"),this._previouslyFocused&&this._previouslyFocused.focus&&this._previouslyFocused.focus(),document.body.removeEventListener("focus",this._maintainFocus,!0),document.removeEventListener("keydown",this._bindKeypress),this._fire("hide",t),this):this},e.prototype.destroy=function(){return this.hide(),this._openers.forEach(function(t){t.removeEventListener("click",this._show)}.bind(this)),this._closers.forEach(function(t){t.removeEventListener("click",this._hide)}.bind(this)),this._fire("destroy"),this._listeners={},this},e.prototype.on=function(t,e){return void 0===this._listeners[t]&&(this._listeners[t]=[]),this._listeners[t].push(e),this},e.prototype.off=function(t,e){var i=(this._listeners[t]||[]).indexOf(e);return i>-1&&this._listeners[t].splice(i,1),this},e.prototype._fire=function(t,e){(this._listeners[t]||[]).forEach(function(t){t(this.$el,e)}.bind(this))},e.prototype._bindKeypress=function(t){this.$el.contains(document.activeElement)&&(this.shown&&27===t.which&&"alertdialog"!==this.$el.getAttribute("role")&&(t.preventDefault(),this.hide(t)),this.shown&&9===t.which&&function(t,e){var i=s(t),n=i.indexOf(document.activeElement);e.shiftKey&&0===n?(i[i.length-1].focus(),e.preventDefault()):e.shiftKey||n!==i.length-1||(i[0].focus(),e.preventDefault())}(this.$el,t))},e.prototype._maintainFocus=function(t){var e=t.target.getAttribute("data-a11y-dialog-show");this.shown&&!this.$el.contains(t.target)&&e===this._id&&n(this.$el)},"undefined"!=typeof document&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",o):window.requestAnimationFrame?window.requestAnimationFrame(o):window.setTimeout(o,16));export default e; |
@@ -29,6 +29,5 @@ (function (global, factory) { | ||
* @constructor | ||
* @param {Element} node | ||
* @param {(NodeList | Element | string)} targets | ||
* @param {Element} element | ||
*/ | ||
function A11yDialog(node, targets) { | ||
function A11yDialog(element) { | ||
// Prebind the functions that will be bound in addEventListener and | ||
@@ -40,17 +39,11 @@ // removeEventListener to avoid losing references | ||
this._bindKeypress = this._bindKeypress.bind(this); | ||
this.$el = element; | ||
this.shown = false; | ||
this._id = this.$el.getAttribute('data-a11y-dialog') || this.$el.id; | ||
this._previouslyFocused = null; | ||
// Keep a reference of the node and the actual dialog on the instance | ||
this.container = node; | ||
this.dialog = node.querySelector( | ||
'dialog, [role="dialog"], [role="alertdialog"]' | ||
); | ||
this.role = this.dialog.getAttribute('role') || 'dialog'; | ||
this.useDialog = 'show' in this.dialog; | ||
// Keep an object of listener types mapped to callback functions | ||
this._listeners = {}; | ||
// Initialise everything needed for the dialog to work properly | ||
this.create(targets); | ||
this.create(); | ||
} | ||
@@ -64,26 +57,8 @@ | ||
*/ | ||
A11yDialog.prototype.create = function (targets) { | ||
// Keep a collection of nodes to disable/enable when toggling the dialog | ||
this._targets = | ||
this._targets || collect(targets) || getSiblings(this.container); | ||
A11yDialog.prototype.create = function () { | ||
this.$el.setAttribute('aria-hidden', true); | ||
this.$el.setAttribute('aria-modal', true); | ||
// Set the `shown` property to match the status from the DOM | ||
this.shown = this.dialog.hasAttribute('open'); | ||
// Despite using a `<dialog>` element, `role="dialog"` is not necessarily | ||
// implied by all screen-readers (yet) | ||
// See: https://github.com/KittyGiraudel/a11y-dialog/commit/6ba711a777aed0dbda0719a18a02f742098c64d9#commitcomment-28694166 | ||
this.dialog.setAttribute('role', this.role); | ||
if (!this.useDialog) { | ||
if (this.shown) { | ||
this.container.removeAttribute('aria-hidden'); | ||
} else { | ||
this.container.setAttribute('aria-hidden', true); | ||
} | ||
} else { | ||
this.container.setAttribute('data-a11y-dialog-native', ''); | ||
// Remove initial `aria-hidden` from container | ||
// See: https://github.com/KittyGiraudel/a11y-dialog/pull/117#issuecomment-706056246 | ||
this.container.removeAttribute('aria-hidden'); | ||
if (!this.$el.hasAttribute('role')) { | ||
this.$el.setAttribute('role', 'dialog'); | ||
} | ||
@@ -93,3 +68,3 @@ | ||
// event listener to open the dialog | ||
this._openers = $$('[data-a11y-dialog-show="' + this.container.id + '"]'); | ||
this._openers = $$('[data-a11y-dialog-show="' + this._id + '"]'); | ||
this._openers.forEach( | ||
@@ -103,4 +78,4 @@ function (opener) { | ||
// event listener to close the dialog | ||
this._closers = $$('[data-a11y-dialog-hide]', this.container).concat( | ||
$$('[data-a11y-dialog-hide="' + this.container.id + '"]') | ||
this._closers = $$('[data-a11y-dialog-hide]', this.$el).concat( | ||
$$('[data-a11y-dialog-hide="' + this._id + '"]') | ||
); | ||
@@ -133,29 +108,10 @@ this._closers.forEach( | ||
this.shown = true; | ||
// Keep a reference to the currently focused element to be able to restore | ||
// it later | ||
this._previouslyFocused = document.activeElement; | ||
this.$el.removeAttribute('aria-hidden'); | ||
this.shown = true; | ||
if (this.useDialog) { | ||
this.dialog.showModal(event instanceof Event ? void 0 : event); | ||
} else { | ||
this.dialog.setAttribute('open', ''); | ||
this.container.removeAttribute('aria-hidden'); | ||
// Iterate over the targets to disable them by setting their `aria-hidden` | ||
// attribute to `true` and, if present, storing the current value of `aria-hidden` | ||
this._targets.forEach(function (target) { | ||
if (target.hasAttribute('aria-hidden')) { | ||
target.setAttribute( | ||
'data-a11y-dialog-original-aria-hidden', | ||
target.getAttribute('aria-hidden') | ||
); | ||
} | ||
target.setAttribute('aria-hidden', 'true'); | ||
}); | ||
} | ||
// Set the focus to the first focusable child of the dialog element | ||
setFocusToFirstItem(this.dialog); | ||
setFocusToFirstItem(this.$el); | ||
@@ -189,24 +145,4 @@ // Bind a focus event listener to the body element to make sure the focus | ||
this.shown = false; | ||
this.$el.setAttribute('aria-hidden', 'true'); | ||
if (this.useDialog) { | ||
this.dialog.close(event instanceof Event ? void 0 : event); | ||
} else { | ||
this.dialog.removeAttribute('open'); | ||
this.container.setAttribute('aria-hidden', 'true'); | ||
// Iterate over the targets to enable them by removing their `aria-hidden` | ||
// attribute or resetting it to its original value | ||
this._targets.forEach(function (target) { | ||
if (target.hasAttribute('data-a11y-dialog-original-aria-hidden')) { | ||
target.setAttribute( | ||
'aria-hidden', | ||
target.getAttribute('data-a11y-dialog-original-aria-hidden') | ||
); | ||
target.removeAttribute('data-a11y-dialog-original-aria-hidden'); | ||
} else { | ||
target.removeAttribute('aria-hidden'); | ||
} | ||
}); | ||
} | ||
// If there was a focused element before the dialog was opened (and it has a | ||
@@ -308,3 +244,3 @@ // `focus` method), restore the focus back to it | ||
function (listener) { | ||
listener(this.container, event); | ||
listener(this.$el, event); | ||
}.bind(this) | ||
@@ -324,3 +260,3 @@ ); | ||
// are only reacted to for the most recent one | ||
if (!this.dialog.contains(document.activeElement)) return | ||
if (!this.$el.contains(document.activeElement)) return | ||
@@ -330,3 +266,7 @@ // If the dialog is shown and the ESCAPE key is being pressed, prevent any | ||
// is 'alertdialog', which should be modal | ||
if (this.shown && event.which === ESCAPE_KEY && this.role !== 'alertdialog') { | ||
if ( | ||
this.shown && | ||
event.which === ESCAPE_KEY && | ||
this.$el.getAttribute('role') !== 'alertdialog' | ||
) { | ||
event.preventDefault(); | ||
@@ -339,3 +279,3 @@ this.hide(event); | ||
if (this.shown && event.which === TAB_KEY) { | ||
trapTabKey(this.dialog, event); | ||
trapTabKey(this.$el, event); | ||
} | ||
@@ -359,6 +299,6 @@ }; | ||
this.shown && | ||
!this.container.contains(event.target) && | ||
dialogTarget === this.container.id | ||
!this.$el.contains(event.target) && | ||
dialogTarget === this._id | ||
) { | ||
setFocusToFirstItem(this.container); | ||
setFocusToFirstItem(this.$el); | ||
} | ||
@@ -390,23 +330,2 @@ }; | ||
/** | ||
* Return an array of Element based on given argument (NodeList, Element or | ||
* string representing a selector) | ||
* | ||
* @param {(NodeList | Element | string)} target | ||
* @return {Array<Element>} | ||
*/ | ||
function collect(target) { | ||
if (NodeList.prototype.isPrototypeOf(target)) { | ||
return toArray(target) | ||
} | ||
if (Element.prototype.isPrototypeOf(target)) { | ||
return [target] | ||
} | ||
if (typeof target === 'string') { | ||
return $$(target) | ||
} | ||
} | ||
/** | ||
* Set the focus to the first element with `autofocus` or the first focusable | ||
@@ -470,19 +389,2 @@ * child of the given element | ||
/** | ||
* Retrieve siblings from given element | ||
* | ||
* @param {Element} node | ||
* @return {Array<Element>} | ||
*/ | ||
function getSiblings(node) { | ||
var nodes = toArray(node.parentNode.childNodes); | ||
var siblings = nodes.filter(function (node) { | ||
return node.nodeType === 1 | ||
}); | ||
siblings.splice(siblings.indexOf(node), 1); | ||
return siblings | ||
} | ||
function instantiateDialogs() { | ||
@@ -489,0 +391,0 @@ $$('[data-a11y-dialog]').forEach(function (node) { |
@@ -1,2 +0,2 @@ | ||
/*! a11y-dialog 6.1.0 — © Kitty Giraudel */ | ||
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(t="undefined"!=typeof globalThis?globalThis:t||self).A11yDialog=i()}(this,(function(){"use strict";var t=['a[href]:not([tabindex^="-"])','area[href]:not([tabindex^="-"])','input:not([type="hidden"]):not([type="radio"]):not([disabled]):not([tabindex^="-"])','input[type="radio"]:not([disabled]):not([tabindex^="-"]):checked','select:not([disabled]):not([tabindex^="-"])','textarea:not([disabled]):not([tabindex^="-"])','button:not([disabled]):not([tabindex^="-"])','iframe:not([tabindex^="-"])','audio[controls]:not([tabindex^="-"])','video[controls]:not([tabindex^="-"])','[contenteditable]:not([tabindex^="-"])','[tabindex]:not([tabindex^="-"])'];function i(t,i){this._show=this.show.bind(this),this._hide=this.hide.bind(this),this._maintainFocus=this._maintainFocus.bind(this),this._bindKeypress=this._bindKeypress.bind(this),this._previouslyFocused=null,this.container=t,this.dialog=t.querySelector('dialog, [role="dialog"], [role="alertdialog"]'),this.role=this.dialog.getAttribute("role")||"dialog",this.useDialog="show"in this.dialog,this._listeners={},this.create(i)}function e(t){return Array.prototype.slice.call(t)}function n(t,i){return e((i||document).querySelectorAll(t))}function o(t){var i=s(t),e=t.querySelector("[autofocus]")||i[0];e&&e.focus()}function s(i){return n(t.join(","),i).filter((function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)}))}function r(){n("[data-a11y-dialog]").forEach((function(t){new i(t,t.getAttribute("data-a11y-dialog")||void 0)}))}return i.prototype.create=function(t){var i,o;return this._targets=this._targets||function(t){if(NodeList.prototype.isPrototypeOf(t))return e(t);if(Element.prototype.isPrototypeOf(t))return[t];if("string"==typeof t)return n(t)}(t)||(i=this.container,(o=e(i.parentNode.childNodes).filter((function(t){return 1===t.nodeType}))).splice(o.indexOf(i),1),o),this.shown=this.dialog.hasAttribute("open"),this.dialog.setAttribute("role",this.role),this.useDialog?(this.container.setAttribute("data-a11y-dialog-native",""),this.container.removeAttribute("aria-hidden")):this.shown?this.container.removeAttribute("aria-hidden"):this.container.setAttribute("aria-hidden",!0),this._openers=n('[data-a11y-dialog-show="'+this.container.id+'"]'),this._openers.forEach(function(t){t.addEventListener("click",this._show)}.bind(this)),this._closers=n("[data-a11y-dialog-hide]",this.container).concat(n('[data-a11y-dialog-hide="'+this.container.id+'"]')),this._closers.forEach(function(t){t.addEventListener("click",this._hide)}.bind(this)),this._fire("create"),this},i.prototype.show=function(t){return this.shown||(this.shown=!0,this._previouslyFocused=document.activeElement,this.useDialog?this.dialog.showModal(t instanceof Event?void 0:t):(this.dialog.setAttribute("open",""),this.container.removeAttribute("aria-hidden"),this._targets.forEach((function(t){t.hasAttribute("aria-hidden")&&t.setAttribute("data-a11y-dialog-original-aria-hidden",t.getAttribute("aria-hidden")),t.setAttribute("aria-hidden","true")}))),o(this.dialog),document.body.addEventListener("focus",this._maintainFocus,!0),document.addEventListener("keydown",this._bindKeypress),this._fire("show",t)),this},i.prototype.hide=function(t){return this.shown?(this.shown=!1,this.useDialog?this.dialog.close(t instanceof Event?void 0:t):(this.dialog.removeAttribute("open"),this.container.setAttribute("aria-hidden","true"),this._targets.forEach((function(t){t.hasAttribute("data-a11y-dialog-original-aria-hidden")?(t.setAttribute("aria-hidden",t.getAttribute("data-a11y-dialog-original-aria-hidden")),t.removeAttribute("data-a11y-dialog-original-aria-hidden")):t.removeAttribute("aria-hidden")}))),this._previouslyFocused&&this._previouslyFocused.focus&&this._previouslyFocused.focus(),document.body.removeEventListener("focus",this._maintainFocus,!0),document.removeEventListener("keydown",this._bindKeypress),this._fire("hide",t),this):this},i.prototype.destroy=function(){return this.hide(),this._openers.forEach(function(t){t.removeEventListener("click",this._show)}.bind(this)),this._closers.forEach(function(t){t.removeEventListener("click",this._hide)}.bind(this)),this._fire("destroy"),this._listeners={},this},i.prototype.on=function(t,i){return void 0===this._listeners[t]&&(this._listeners[t]=[]),this._listeners[t].push(i),this},i.prototype.off=function(t,i){var e=(this._listeners[t]||[]).indexOf(i);return e>-1&&this._listeners[t].splice(e,1),this},i.prototype._fire=function(t,i){(this._listeners[t]||[]).forEach(function(t){t(this.container,i)}.bind(this))},i.prototype._bindKeypress=function(t){this.dialog.contains(document.activeElement)&&(this.shown&&27===t.which&&"alertdialog"!==this.role&&(t.preventDefault(),this.hide(t)),this.shown&&9===t.which&&function(t,i){var e=s(t),n=e.indexOf(document.activeElement);i.shiftKey&&0===n?(e[e.length-1].focus(),i.preventDefault()):i.shiftKey||n!==e.length-1||(e[0].focus(),i.preventDefault())}(this.dialog,t))},i.prototype._maintainFocus=function(t){var i=t.target.getAttribute("data-a11y-dialog-show");this.shown&&!this.container.contains(t.target)&&i===this.container.id&&o(this.container)},"undefined"!=typeof document&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",r):window.requestAnimationFrame?window.requestAnimationFrame(r):window.setTimeout(r,16)),i})); | ||
/*! a11y-dialog 7.0.0-rc.1 — © Kitty Giraudel */ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).A11yDialog=e()}(this,(function(){"use strict";var t=['a[href]:not([tabindex^="-"])','area[href]:not([tabindex^="-"])','input:not([type="hidden"]):not([type="radio"]):not([disabled]):not([tabindex^="-"])','input[type="radio"]:not([disabled]):not([tabindex^="-"]):checked','select:not([disabled]):not([tabindex^="-"])','textarea:not([disabled]):not([tabindex^="-"])','button:not([disabled]):not([tabindex^="-"])','iframe:not([tabindex^="-"])','audio[controls]:not([tabindex^="-"])','video[controls]:not([tabindex^="-"])','[contenteditable]:not([tabindex^="-"])','[tabindex]:not([tabindex^="-"])'];function e(t){this._show=this.show.bind(this),this._hide=this.hide.bind(this),this._maintainFocus=this._maintainFocus.bind(this),this._bindKeypress=this._bindKeypress.bind(this),this.$el=t,this.shown=!1,this._id=this.$el.getAttribute("data-a11y-dialog")||this.$el.id,this._previouslyFocused=null,this._listeners={},this.create()}function i(t,e){return i=(e||document).querySelectorAll(t),Array.prototype.slice.call(i);var i}function n(t){var e=s(t),i=t.querySelector("[autofocus]")||e[0];i&&i.focus()}function s(e){return i(t.join(","),e).filter((function(t){return!!(t.offsetWidth||t.offsetHeight||t.getClientRects().length)}))}function o(){i("[data-a11y-dialog]").forEach((function(t){new e(t,t.getAttribute("data-a11y-dialog")||void 0)}))}return e.prototype.create=function(){return this.$el.setAttribute("aria-hidden",!0),this.$el.setAttribute("aria-modal",!0),this.$el.hasAttribute("role")||this.$el.setAttribute("role","dialog"),this._openers=i('[data-a11y-dialog-show="'+this._id+'"]'),this._openers.forEach(function(t){t.addEventListener("click",this._show)}.bind(this)),this._closers=i("[data-a11y-dialog-hide]",this.$el).concat(i('[data-a11y-dialog-hide="'+this._id+'"]')),this._closers.forEach(function(t){t.addEventListener("click",this._hide)}.bind(this)),this._fire("create"),this},e.prototype.show=function(t){return this.shown||(this._previouslyFocused=document.activeElement,this.$el.removeAttribute("aria-hidden"),this.shown=!0,n(this.$el),document.body.addEventListener("focus",this._maintainFocus,!0),document.addEventListener("keydown",this._bindKeypress),this._fire("show",t)),this},e.prototype.hide=function(t){return this.shown?(this.shown=!1,this.$el.setAttribute("aria-hidden","true"),this._previouslyFocused&&this._previouslyFocused.focus&&this._previouslyFocused.focus(),document.body.removeEventListener("focus",this._maintainFocus,!0),document.removeEventListener("keydown",this._bindKeypress),this._fire("hide",t),this):this},e.prototype.destroy=function(){return this.hide(),this._openers.forEach(function(t){t.removeEventListener("click",this._show)}.bind(this)),this._closers.forEach(function(t){t.removeEventListener("click",this._hide)}.bind(this)),this._fire("destroy"),this._listeners={},this},e.prototype.on=function(t,e){return void 0===this._listeners[t]&&(this._listeners[t]=[]),this._listeners[t].push(e),this},e.prototype.off=function(t,e){var i=(this._listeners[t]||[]).indexOf(e);return i>-1&&this._listeners[t].splice(i,1),this},e.prototype._fire=function(t,e){(this._listeners[t]||[]).forEach(function(t){t(this.$el,e)}.bind(this))},e.prototype._bindKeypress=function(t){this.$el.contains(document.activeElement)&&(this.shown&&27===t.which&&"alertdialog"!==this.$el.getAttribute("role")&&(t.preventDefault(),this.hide(t)),this.shown&&9===t.which&&function(t,e){var i=s(t),n=i.indexOf(document.activeElement);e.shiftKey&&0===n?(i[i.length-1].focus(),e.preventDefault()):e.shiftKey||n!==i.length-1||(i[0].focus(),e.preventDefault())}(this.$el,t))},e.prototype._maintainFocus=function(t){var e=t.target.getAttribute("data-a11y-dialog-show");this.shown&&!this.$el.contains(t.target)&&e===this._id&&n(this.$el)},"undefined"!=typeof document&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",o):window.requestAnimationFrame?window.requestAnimationFrame(o):window.setTimeout(o,16)),e})); |
{ | ||
"name": "a11y-dialog", | ||
"version": "6.1.0", | ||
"version": "7.0.0-rc.1", | ||
"description": "A tiny script to make dialog windows accessible to assistive technology users.", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/KittyGiraudel/a11y-dialog", |
# [A11y Dialog](https://a11y-dialog.netlify.app) | ||
This is a lightweight (1.6Kb) yet flexible script to create accessible dialog windows. | ||
This is a lightweight (1.3Kb) yet flexible script to create accessible dialog windows. | ||
@@ -10,3 +10,2 @@ - [Documentation ↗](https://a11y-dialog.netlify.app) | ||
- Leveraging the native `<dialog>` element if desired | ||
- Closing dialog on overlay click and <kbd>ESC</kbd> | ||
@@ -13,0 +12,0 @@ - Toggling `aria-*` attributes |
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
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
35044
733
1
16