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

115 lines
3.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();
2020-10-01 17:10:40 +08:00
this.BSN = {
2020-09-02 03:50:17 +08:00
Dropdown: function(element) {
let menu, menuItems = [];
const self = this,
parent = element.parentNode,
preventEmptyAnchor = e => {
const t = e.target, href = t.href || (t.parentNode && t.parentNode.href);
(href && href.slice(-1) === '#') && e.preventDefault();
},
toggleEvents = () => {
2020-10-01 17:10:40 +08:00
let action = (element.open ? 'add' : 'remove') + 'EventListener';
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 => {
let eventTarget = e.target,
inside = menu.contains(eventTarget),
hasData = eventTarget && (
(eventTarget.getAttribute && eventTarget.getAttribute('data-toggle'))
2020-09-02 03:50:17 +08:00
|| (eventTarget.parentNode && eventTarget.parentNode.getAttribute('data-toggle')));
2020-10-01 17:10:40 +08:00
if (!(hasData && inside)
&& !(e.type === 'focus' && (inside || eventTarget === element))
2020-09-02 03:50:17 +08:00
) {
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);
},
2020-10-01 17:10:40 +08:00
preventScroll = e => (e.key === 'ArrowUp' || e.key === 'ArrowDown') && e.preventDefault(),
2020-09-02 03:50:17 +08:00
keyHandler = e => {
if (e.key === 'Escape') {
2020-09-02 03:50:17 +08:00
self.toggle();
} else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
let activeItem = doc.activeElement,
isMenuButton = activeItem === element,
idx = isMenuButton ? 0 : menuItems.indexOf(activeItem);
if (parent.contains(activeItem)) {
if (!isMenuButton) {
idx = e.key === 'ArrowUp' ? (idx > 1 ? idx-1 : 0)
: e.key === 'ArrowDown' ? (idx < menuItems.length-1 ? idx+1 : idx) : 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');
menu.classList.add('show');
parent.classList.add('show');
element.setAttribute('aria-expanded',true);
element.open = true;
2020-10-01 17:10:40 +08:00
element.removeEventListener('click',clickHandler);
2020-09-02 03:50:17 +08:00
setTimeout(() => {
setFocus( menu.getElementsByTagName('INPUT')[0] || element );
toggleEvents();
},1);
};
2020-09-02 03:50:17 +08:00
self.hide = () => {
menu.classList.remove('show');
parent.classList.remove('show');
element.setAttribute('aria-expanded',false);
element.open = false;
toggleEvents();
2020-09-02 03:50:17 +08:00
setFocus(element);
2020-10-01 17:10:40 +08:00
setTimeout(() => element.Dropdown && element.addEventListener('click',clickHandler), 1);
2020-09-02 03:50:17 +08:00
};
self.toggle = () => element.open ? self.hide() : self.show();
2020-10-01 17:10:40 +08:00
element.addEventListener('click',clickHandler);
element.open = false;
2020-09-02 03:50:17 +08:00
element.Dropdown = self;
},
2020-09-02 03:50:17 +08:00
Tab: class {
constructor(element) {
this.element = element
element.Tab = this;
2020-10-01 17:10:40 +08:00
element.addEventListener('click', e => {
e.preventDefault();
this.show();
});
2020-09-02 03:50:17 +08:00
}
2020-09-02 03:50:17 +08:00
show() {
const el = this.element, li = el.closest('li');
if (!li.classList.contains('active')) {
const previous = el.closest('ul').querySelector('.active a');
previous.closest('li').classList.remove('active');
doc.querySelector(previous.getAttribute('href')).classList.remove('active');
li.classList.add('active');
doc.querySelector(el.getAttribute('href')).classList.add('active');
}
}
}
};
2020-10-01 17:10:40 +08:00
})(document);