snappymail/vendors/bootstrap/js/bootstrap.native.js

92 lines
2.8 KiB
JavaScript
Raw Normal View History

/*!
* Native JavaScript for Bootstrap v3.0.10 (https://thednp.github.io/bootstrap.native/)
* Copyright 2015-2020 © dnp_theme
* Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE)
*/
2020-10-01 17:10:40 +08:00
(doc => {
const
setFocus = element => element.focus ? element.focus() : element.setActive(),
isArrow = e => 'ArrowUp' === e.key || 'ArrowDown' === e.key;
2020-10-01 17:10:40 +08:00
this.BSN = {
2021-09-14 16:06:38 +08:00
Dropdown: function(toggleBtn) {
2020-09-02 03:50:17 +08:00
let menu, menuItems = [];
const self = this,
2021-09-14 16:06:38 +08:00
parent = toggleBtn.parentNode,
2020-09-02 03:50:17 +08:00
preventEmptyAnchor = e => {
const t = e.target;
('#' === (t.href || t.parentNode?.href)?.slice(-1)) && e.preventDefault();
2020-09-02 03:50:17 +08:00
},
open = bool => {
menu?.classList.toggle('show', bool);
parent.classList.toggle('show', bool);
2021-09-14 16:06:38 +08:00
toggleBtn.setAttribute('aria-expanded', bool);
toggleBtn.open = bool;
if (bool) {
2021-09-14 16:06:38 +08:00
toggleBtn.removeEventListener('click',clickHandler);
} else {
2021-09-14 16:06:38 +08:00
setTimeout(() => toggleBtn.addEventListener('click',clickHandler), 1);
}
},
2020-09-02 03:50:17 +08:00
toggleEvents = () => {
const action = (toggleBtn.open ? 'add' : 'remove') + 'EventListener';
2020-10-01 17:10:40 +08:00
doc[action]('click',dismissHandler);
doc[action]('keydown',preventScroll);
doc[action]('keyup',keyHandler);
doc[action]('focus',dismissHandler);
2020-09-02 03:50:17 +08:00
},
dismissHandler = e => {
const eventTarget = e.target;
2021-09-14 16:06:38 +08:00
if ((!menu.contains(eventTarget) && !toggleBtn.contains(eventTarget)) || e.type !== 'focus') {
2020-10-01 17:10:40 +08:00
self.hide();
preventEmptyAnchor(e);
2020-09-02 03:50:17 +08:00
}
},
clickHandler = e => {
self.show();
preventEmptyAnchor(e);
},
preventScroll = e => isArrow(e) && e.preventDefault(),
2020-09-02 03:50:17 +08:00
keyHandler = e => {
if ('Escape' === e.key) {
2020-09-02 03:50:17 +08:00
self.toggle();
} else if (isArrow(e)) {
let activeItem = doc.activeElement,
2021-09-14 16:06:38 +08:00
isMenuButton = activeItem === toggleBtn,
idx = isMenuButton ? 0 : menuItems.indexOf(activeItem);
if (parent.contains(activeItem)) {
if (!isMenuButton) {
idx = 'ArrowUp' === e.key
? (idx > 1 ? idx-1 : 0)
: (idx < menuItems.length-1 ? idx+1 : idx);
}
menuItems[idx] && setFocus(menuItems[idx]);
} else {
console.log('activeElement not in menu');
}
2020-09-02 03:50:17 +08:00
}
};
self.show = () => {
menu = parent.querySelector('.dropdown-menu');
menuItems = [...menu.querySelectorAll('A')].filter(item => 'none' != item.parentNode.style.display);
2020-09-02 03:50:17 +08:00
!('tabindex' in menu) && menu.setAttribute('tabindex', '0');
open(true);
2020-09-02 03:50:17 +08:00
setTimeout(() => {
2021-09-14 16:06:38 +08:00
setFocus( menu.getElementsByTagName('INPUT')[0] || toggleBtn );
2020-09-02 03:50:17 +08:00
toggleEvents();
},1);
};
2020-09-02 03:50:17 +08:00
self.hide = () => {
open(false);
toggleEvents();
2021-09-14 16:06:38 +08:00
setFocus(toggleBtn);
2020-09-02 03:50:17 +08:00
};
2021-09-14 16:06:38 +08:00
self.toggle = () => toggleBtn.open ? self.hide() : self.show();
open(false);
2021-09-14 16:06:38 +08:00
toggleBtn.Dropdown = self;
}
};
2020-10-01 17:10:40 +08:00
})(document);