Hide elements that confirmation dialog covers from assistive technologies.
HFJ-1995pull/22/head
parent
10e1a7ba65
commit
8615deb23b
|
@ -161,6 +161,13 @@ H5P.ConfirmationDialog = (function (EventDispatcher) {
|
||||||
// Focus capturing
|
// Focus capturing
|
||||||
var focusPredator;
|
var focusPredator;
|
||||||
|
|
||||||
|
// Maintains hidden state of elements
|
||||||
|
var wrapperSiblingsHidden = [];
|
||||||
|
var popupSiblingsHidden = [];
|
||||||
|
|
||||||
|
// Element with focus before dialog
|
||||||
|
var previouslyFocused;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set parent of confirmation dialog
|
* Set parent of confirmation dialog
|
||||||
* @param {HTMLElement} wrapper
|
* @param {HTMLElement} wrapper
|
||||||
|
@ -182,6 +189,44 @@ H5P.ConfirmationDialog = (function (EventDispatcher) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide siblings of element from assistive technology
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} element
|
||||||
|
* @returns {Array} The previous hidden state of all siblings
|
||||||
|
*/
|
||||||
|
var hideSiblings = function (element) {
|
||||||
|
var hiddenSiblings = [];
|
||||||
|
var siblings = element.parentNode.children;
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < siblings.length; i += 1) {
|
||||||
|
// Preserve hidden state
|
||||||
|
hiddenSiblings[i] = siblings[i].getAttribute('aria-hidden') ?
|
||||||
|
true : false;
|
||||||
|
|
||||||
|
if (siblings[i] !== element) {
|
||||||
|
siblings[i].setAttribute('aria-hidden', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hiddenSiblings;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores assistive technology state of element's siblings
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} element
|
||||||
|
* @param {Array} hiddenSiblings Hidden state of all siblings
|
||||||
|
*/
|
||||||
|
var restoreSiblings = function (element, hiddenSiblings) {
|
||||||
|
var siblings = element.parentNode.children;
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < siblings.length; i += 1) {
|
||||||
|
if (siblings[i] !== element && !hiddenSiblings[i]) {
|
||||||
|
siblings[i].removeAttribute('aria-hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start capturing focus of parent and send it to dialog
|
* Start capturing focus of parent and send it to dialog
|
||||||
*/
|
*/
|
||||||
|
@ -194,9 +239,26 @@ H5P.ConfirmationDialog = (function (EventDispatcher) {
|
||||||
* Clean up event listener for capturing focus
|
* Clean up event listener for capturing focus
|
||||||
*/
|
*/
|
||||||
var stopCapturingFocus = function () {
|
var stopCapturingFocus = function () {
|
||||||
|
focusPredator.removeAttribute('aria-hidden');
|
||||||
focusPredator.removeEventListener('focus', captureFocus, true);
|
focusPredator.removeEventListener('focus', captureFocus, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide siblings in underlay from assistive technologies
|
||||||
|
*/
|
||||||
|
var disableUnderlay = function () {
|
||||||
|
wrapperSiblingsHidden = hideSiblings(wrapperElement);
|
||||||
|
popupSiblingsHidden = hideSiblings(popupBackground);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore state of underlay for assistive technologies
|
||||||
|
*/
|
||||||
|
var restoreUnderlay = function () {
|
||||||
|
restoreSiblings(wrapperElement, wrapperSiblingsHidden);
|
||||||
|
restoreSiblings(popupBackground, popupSiblingsHidden);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fit popup to container. Makes sure it doesn't overflow.
|
* Fit popup to container. Makes sure it doesn't overflow.
|
||||||
* @params {number} [offsetTop] Offset of popup
|
* @params {number} [offsetTop] Offset of popup
|
||||||
|
@ -227,8 +289,11 @@ H5P.ConfirmationDialog = (function (EventDispatcher) {
|
||||||
* @returns {H5P.ConfirmationDialog}
|
* @returns {H5P.ConfirmationDialog}
|
||||||
*/
|
*/
|
||||||
this.show = function (offsetTop) {
|
this.show = function (offsetTop) {
|
||||||
|
// Capture focused item
|
||||||
|
previouslyFocused = document.activeElement;
|
||||||
wrapperElement.appendChild(popupBackground);
|
wrapperElement.appendChild(popupBackground);
|
||||||
startCapturingFocus();
|
startCapturingFocus();
|
||||||
|
disableUnderlay();
|
||||||
popupBackground.classList.remove('hidden');
|
popupBackground.classList.remove('hidden');
|
||||||
fitToContainer(offsetTop);
|
fitToContainer(offsetTop);
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
|
@ -260,9 +325,13 @@ H5P.ConfirmationDialog = (function (EventDispatcher) {
|
||||||
this.hide = function () {
|
this.hide = function () {
|
||||||
popupBackground.classList.add('hiding');
|
popupBackground.classList.add('hiding');
|
||||||
popup.classList.add('hidden');
|
popup.classList.add('hidden');
|
||||||
|
|
||||||
|
// Restore focus
|
||||||
|
stopCapturingFocus();
|
||||||
|
previouslyFocused.focus();
|
||||||
|
restoreUnderlay();
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
popupBackground.classList.add('hidden');
|
popupBackground.classList.add('hidden');
|
||||||
stopCapturingFocus();
|
|
||||||
wrapperElement.removeChild(popupBackground);
|
wrapperElement.removeChild(popupBackground);
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue