UNPKG

alertifyjs

Version:

AlertifyJS is a javascript framework for developing pretty browser dialogs and notifications.

124 lines (118 loc) 5.46 kB
/** * Sets focus to proper dialog element * * @param {Object} instance The dilog instance. * @param {Node} [resetTarget=undefined] DOM element to reset focus to. * * @return {undefined} */ function setFocus(instance, resetTarget) { // reset target has already been determined. if (resetTarget) { resetTarget.focus(); } else { // current instance focus settings var focus = instance.__internal.focus; // the focus element. var element = focus.element; switch (typeof focus.element) { // a number means a button index case 'number': if (instance.__internal.buttons.length > focus.element) { //in basic view, skip focusing the buttons. if (instance.get('basic') === true) { element = instance.elements.reset[0]; } else { element = instance.__internal.buttons[focus.element].element; } } break; // a string means querySelector to select from dialog body contents. case 'string': element = instance.elements.body.querySelector(focus.element); break; // a function should return the focus element. case 'function': element = focus.element.call(instance); break; } // if no focus element, default to first reset element. if (instance.get('defaultFocusOff') === true || ((typeof element === 'undefined' || element === null) && instance.__internal.buttons.length === 0)) { element = instance.elements.reset[0]; } // focus if (element && element.focus) { element.focus(); // if selectable if (focus.select && element.select) { element.select(); } } } } /** * Focus event handler, attached to document.body and dialogs own reset links. * handles the focus for modal dialogs only. * * @param {Event} event DOM focus event object. * @param {Object} instance The dilog instance. * * @return {undefined} */ function onReset(event, instance) { // should work on last modal if triggered from document.body if (!instance) { for (var x = openDialogs.length - 1; x > -1; x -= 1) { if (openDialogs[x].isModal()) { instance = openDialogs[x]; break; } } } if(instance) { // if modal if (instance.isModal()) { // determine reset target to enable forward/backward tab cycle. var firstReset = instance.elements.reset[0], lastReset = instance.elements.reset[1], lastFocusedElement = event.relatedTarget, within = instance.elements.root.contains(lastFocusedElement), target = event.srcElement || event.target, resetTarget; //if the previous focused element element was outside the modal do nthing if( /*first show */ (target === firstReset && !within) || /*focus cycle */ (target === lastReset && lastFocusedElement === firstReset)){ return; }else if(target === lastReset || target === document.body){ resetTarget = firstReset; }else if(target === firstReset && lastFocusedElement === lastReset){ resetTarget = findTabbable(instance); }else if(target === firstReset && within){ resetTarget = findTabbable(instance, true); } // focus setFocus(instance, resetTarget); } } } function findTabbable(instance, last){ var tabbables = [].slice.call(instance.elements.dialog.querySelectorAll(defaults.tabbable)); if(last){ tabbables.reverse(); } for(var x=0;x<tabbables.length;x+=1){ var tabbable = tabbables[x]; //check if visible if(!!(tabbable.offsetParent || tabbable.offsetWidth || tabbable.offsetHeight || tabbable.getClientRects().length)){ return tabbable; } } } function recycleTab(event) { var instance = openDialogs[openDialogs.length - 1]; if (instance && event.shiftKey && event.keyCode === keys.TAB) { instance.elements.reset[1].focus(); } }