Repository URL to install this package:
|
Version:
3.12.20 ▾
|
import toArray from '@filerobot/utils/lib/toArray';
import getActiveOverlayEl from './getActiveOverlayEl';
import FOCUSABLE_ELEMENTS from '@filerobot/utils/lib//FOCUSABLE_ELEMENTS';
function focusOnFirstNode(event, nodes) {
var node = nodes[0];
if (node) {
node.focus();
event.preventDefault();
}
}
function focusOnLastNode(event, nodes) {
var node = nodes[nodes.length - 1];
if (node) {
node.focus();
event.preventDefault();
}
}
// ___Why not just use (focusedItemIndex === -1)?
// Firefox thinks <ul> is focusable, but we don't have <ul>s in our FOCUSABLE_ELEMENTS. Which means that if we tab into the <ul>, code will think that we are not in the active overlay, and we should focusOnFirstNode() of the currently active overlay!
// [Practical check] if we use (focusedItemIndex === -1), instagram provider in firefox will never get focus on its pics in the <ul>.
function isFocusInOverlay(activeOverlayEl) {
return activeOverlayEl.contains(document.activeElement);
}
function trapFocus(event, activeOverlayType, explorerEl) {
var activeOverlayEl = getActiveOverlayEl(explorerEl, activeOverlayType);
var focusableNodes = toArray(activeOverlayEl.querySelectorAll(FOCUSABLE_ELEMENTS));
var focusedItemIndex = focusableNodes.indexOf(document.activeElement);
// If we pressed tab, and focus is not yet within the current overlay - focus on the first element within the current overlay.
// This is a safety measure (for when user returns from another tab e.g.), most plugins will try to focus on some important element as it loads.
if (!isFocusInOverlay(activeOverlayEl)) {
focusOnFirstNode(event, focusableNodes);
// If we pressed shift + tab, and we're on the first element of a modal
} else if (event.shiftKey && focusedItemIndex === 0) {
focusOnLastNode(event, focusableNodes);
// If we pressed tab, and we're on the last element of the modal
} else if (!event.shiftKey && focusedItemIndex === focusableNodes.length - 1) {
focusOnFirstNode(event, focusableNodes);
}
}
export default {
// Traps focus inside of the currently open overlay (e.g. Explorer, or e.g. Instagram), never lets focus disappear from the modal.
forModal: function forModal(event, activeOverlayType, explorerEl) {
trapFocus(event, activeOverlayType, explorerEl);
},
// Traps focus inside of the currently open overlay, unless overlay is null - then let the user tab away.
forInline: function forInline(event, activeOverlayType, explorerEl) {
// ___When we're in the bare 'Drop files here, paste, browse or import from' screen
if (activeOverlayType === null) {
// Do nothing and let the browser handle it, user can tab away from Filerobot to other elements on the page
// ___When there is some overlay with 'Done' button
} else {
// Trap the focus inside this overlay!
// User can close the overlay (click 'Done') if they want to travel away from Filerobot.
trapFocus(event, activeOverlayType, explorerEl);
}
}
};