diff --git dist/converse.js dist/converse.js index 072ebf1..7ebef4d 100644 --- dist/converse.js +++ dist/converse.js @@ -17098,1710 +17098,16 @@ module.exports = keys; __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else { var bsn; } })(this, function () { - /* Native Javascript for Bootstrap 4 | Internal Utility Functions - ----------------------------------------------------------------*/ - "use strict"; // globals - - var globalObject = typeof global !== 'undefined' ? global : this || window, - DOC = document, - HTML = DOC.documentElement, - body = 'body', - // allow the library to be used in
- // Native Javascript for Bootstrap Global Object - BSN = globalObject.BSN = {}, - supports = BSN.supports = [], - // function toggle attributes - dataToggle = 'data-toggle', - dataDismiss = 'data-dismiss', - dataSpy = 'data-spy', - dataRide = 'data-ride', - // components - stringAlert = 'Alert', - stringButton = 'Button', - stringCarousel = 'Carousel', - stringCollapse = 'Collapse', - stringDropdown = 'Dropdown', - stringModal = 'Modal', - stringPopover = 'Popover', - stringScrollSpy = 'ScrollSpy', - stringTab = 'Tab', - stringTooltip = 'Tooltip', - stringToast = 'Toast', - // options DATA API - dataAutohide = 'data-autohide', - databackdrop = 'data-backdrop', - dataKeyboard = 'data-keyboard', - dataTarget = 'data-target', - dataInterval = 'data-interval', - dataHeight = 'data-height', - dataPause = 'data-pause', - dataTitle = 'data-title', - dataOriginalTitle = 'data-original-title', - dataDismissible = 'data-dismissible', - dataTrigger = 'data-trigger', - dataAnimation = 'data-animation', - dataContainer = 'data-container', - dataPlacement = 'data-placement', - dataDelay = 'data-delay', - // option keys - backdrop = 'backdrop', - keyboard = 'keyboard', - delay = 'delay', - content = 'content', - target = 'target', - currentTarget = 'currentTarget', - interval = 'interval', - pause = 'pause', - animation = 'animation', - placement = 'placement', - container = 'container', - // box model - offsetTop = 'offsetTop', - offsetBottom = 'offsetBottom', - offsetLeft = 'offsetLeft', - scrollTop = 'scrollTop', - scrollLeft = 'scrollLeft', - clientWidth = 'clientWidth', - clientHeight = 'clientHeight', - offsetWidth = 'offsetWidth', - offsetHeight = 'offsetHeight', - innerWidth = 'innerWidth', - innerHeight = 'innerHeight', - scrollHeight = 'scrollHeight', - scrollWidth = 'scrollWidth', - height = 'height', - // aria - ariaExpanded = 'aria-expanded', - ariaHidden = 'aria-hidden', - ariaSelected = 'aria-selected', - // event names - clickEvent = 'click', - focusEvent = 'focus', - hoverEvent = 'hover', - keydownEvent = 'keydown', - keyupEvent = 'keyup', - resizeEvent = 'resize', - // passive - scrollEvent = 'scroll', - // passive - mouseHover = 'onmouseleave' in DOC ? ['mouseenter', 'mouseleave'] : ['mouseover', 'mouseout'], - // touch since 2.0.26 - touchEvents = { - start: 'touchstart', - end: 'touchend', - move: 'touchmove' - }, - // passive - // originalEvents - showEvent = 'show', - shownEvent = 'shown', - hideEvent = 'hide', - hiddenEvent = 'hidden', - closeEvent = 'close', - closedEvent = 'closed', - slidEvent = 'slid', - slideEvent = 'slide', - changeEvent = 'change', - // other - getAttribute = 'getAttribute', - setAttribute = 'setAttribute', - hasAttribute = 'hasAttribute', - createElement = 'createElement', - appendChild = 'appendChild', - innerHTML = 'innerHTML', - getElementsByTagName = 'getElementsByTagName', - preventDefault = 'preventDefault', - getBoundingClientRect = 'getBoundingClientRect', - querySelectorAll = 'querySelectorAll', - getElementsByCLASSNAME = 'getElementsByClassName', - getComputedStyle = 'getComputedStyle', - indexOf = 'indexOf', - parentNode = 'parentNode', - length = 'length', - toLowerCase = 'toLowerCase', - Transition = 'Transition', - Duration = 'Duration', - Webkit = 'Webkit', - style = 'style', - push = 'push', - tabindex = 'tabindex', - contains = 'contains', - active = 'active', - showClass = 'show', - collapsing = 'collapsing', - disabled = 'disabled', - loading = 'loading', - left = 'left', - right = 'right', - top = 'top', - bottom = 'bottom', - // tooltip / popover - tipPositions = /\b(top|bottom|left|right)+/, - // modal - modalOverlay = 0, - fixedTop = 'fixed-top', - fixedBottom = 'fixed-bottom', - // transitionEnd since 2.0.4 - supportTransitions = Webkit + Transition in HTML[style] || Transition[toLowerCase]() in HTML[style], - transitionEndEvent = Webkit + Transition in HTML[style] ? Webkit[toLowerCase]() + Transition + 'End' : Transition[toLowerCase]() + 'end', - transitionDuration = Webkit + Duration in HTML[style] ? Webkit[toLowerCase]() + Transition + Duration : Transition[toLowerCase]() + Duration, - // set new focus element since 2.0.3 - setFocus = function setFocus(element) { - element.focus ? element.focus() : element.setActive(); - }, - // class manipulation, since 2.0.0 requires polyfill.js - addClass = function addClass(element, classNAME) { - element.classList.add(classNAME); - }, - removeClass = function removeClass(element, classNAME) { - element.classList.remove(classNAME); - }, - hasClass = function hasClass(element, classNAME) { - // since 2.0.0 - return element.classList[contains](classNAME); - }, - // selection methods - getElementsByClassName = function getElementsByClassName(element, classNAME) { - // returns Array - return [].slice.call(element[getElementsByCLASSNAME](classNAME)); - }, - queryElement = function queryElement(selector, parent) { - var lookUp = parent ? parent : DOC; - return typeof selector === 'object' ? selector : lookUp.querySelector(selector); - }, - getClosest = function getClosest(element, selector) { - //element is the element and selector is for the closest parent element to find - // source http://gomakethings.com/climbing-up-and-down-the-dom-tree-with-vanilla-javascript/ - var firstChar = selector.charAt(0), - selectorSubstring = selector.substr(1); - - if (firstChar === '.') { - // If selector is a class - for (; element && element !== DOC; element = element[parentNode]) { - // Get closest match - if (queryElement(selector, element[parentNode]) !== null && hasClass(element, selectorSubstring)) { - return element; - } - } - } else if (firstChar === '#') { - // If selector is an ID - for (; element && element !== DOC; element = element[parentNode]) { - // Get closest match - if (element.id === selectorSubstring) { - return element; - } - } - } - - return false; - }, - // event attach jQuery style / trigger since 1.2.0 - on = function on(element, event, handler, options) { - options = options || false; - element.addEventListener(event, handler, options); - }, - off = function off(element, event, handler, options) { - options = options || false; - element.removeEventListener(event, handler, options); - }, - one = function one(element, event, handler, options) { - // one since 2.0.4 - on(element, event, function handlerWrapper(e) { - handler(e); - off(element, event, handlerWrapper, options); - }, options); - }, - // determine support for passive events - supportPassive = function () { - // Test via a getter in the options object to see if the passive property is accessed - var result = false; - - try { - var opts = Object.defineProperty({}, 'passive', { - get: function get() { - result = true; - } - }); - one(globalObject, 'testPassive', null, opts); - } catch (e) {} - - return result; - }(), - // event options - // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection - passiveHandler = supportPassive ? { - passive: true - } : false, - // transitions - getTransitionDurationFromElement = function getTransitionDurationFromElement(element) { - var duration = supportTransitions ? globalObject[getComputedStyle](element)[transitionDuration] : 0; - duration = parseFloat(duration); - duration = typeof duration === 'number' && !isNaN(duration) ? duration * 1000 : 0; - return duration; // we take a short offset to make sure we fire on the next frame after animation - }, - emulateTransitionEnd = function emulateTransitionEnd(element, handler) { - // emulateTransitionEnd since 2.0.4 - var called = 0, - duration = getTransitionDurationFromElement(element); - duration ? one(element, transitionEndEvent, function (e) { - !called && handler(e), called = 1; - }) : setTimeout(function () { - !called && handler(), called = 1; - }, 17); - }, - bootstrapCustomEvent = function bootstrapCustomEvent(eventName, componentName, related) { - var OriginalCustomEvent = new CustomEvent(eventName + '.bs.' + componentName); - OriginalCustomEvent.relatedTarget = related; - this.dispatchEvent(OriginalCustomEvent); - }, - // tooltip / popover stuff - getScroll = function getScroll() { - // also Affix and ScrollSpy uses it - return { - y: globalObject.pageYOffset || HTML[scrollTop], - x: globalObject.pageXOffset || HTML[scrollLeft] - }; - }, - styleTip = function styleTip(link, element, position, parent) { - // both popovers and tooltips (target,tooltip,placement,elementToAppendTo) - var elementDimensions = { - w: element[offsetWidth], - h: element[offsetHeight] - }, - windowWidth = HTML[clientWidth] || DOC[body][clientWidth], - windowHeight = HTML[clientHeight] || DOC[body][clientHeight], - rect = link[getBoundingClientRect](), - scroll = parent === DOC[body] ? getScroll() : { - x: parent[offsetLeft] + parent[scrollLeft], - y: parent[offsetTop] + parent[scrollTop] - }, - linkDimensions = { - w: rect[right] - rect[left], - h: rect[bottom] - rect[top] - }, - isPopover = hasClass(element, 'popover'), - topPosition, - leftPosition, - arrow = queryElement('.arrow', element), - arrowTop, - arrowLeft, - arrowWidth, - arrowHeight, - halfTopExceed = rect[top] + linkDimensions.h / 2 - elementDimensions.h / 2 < 0, - halfLeftExceed = rect[left] + linkDimensions.w / 2 - elementDimensions.w / 2 < 0, - halfRightExceed = rect[left] + elementDimensions.w / 2 + linkDimensions.w / 2 >= windowWidth, - halfBottomExceed = rect[top] + elementDimensions.h / 2 + linkDimensions.h / 2 >= windowHeight, - topExceed = rect[top] - elementDimensions.h < 0, - leftExceed = rect[left] - elementDimensions.w < 0, - bottomExceed = rect[top] + elementDimensions.h + linkDimensions.h >= windowHeight, - rightExceed = rect[left] + elementDimensions.w + linkDimensions.w >= windowWidth; // recompute position - - position = (position === left || position === right) && leftExceed && rightExceed ? top : position; // first, when both left and right limits are exceeded, we fall back to top|bottom - - position = position === top && topExceed ? bottom : position; - position = position === bottom && bottomExceed ? top : position; - position = position === left && leftExceed ? right : position; - position = position === right && rightExceed ? left : position; // update tooltip/popover class - - element.className[indexOf](position) === -1 && (element.className = element.className.replace(tipPositions, position)); // we check the computed width & height and update here - - arrowWidth = arrow[offsetWidth]; - arrowHeight = arrow[offsetHeight]; // apply styling to tooltip or popover - - if (position === left || position === right) { - // secondary|side positions - if (position === left) { - // LEFT - leftPosition = rect[left] + scroll.x - elementDimensions.w - (isPopover ? arrowWidth : 0); - } else { - // RIGHT - leftPosition = rect[left] + scroll.x + linkDimensions.w; - } // adjust top and arrow - - - if (halfTopExceed) { - topPosition = rect[top] + scroll.y; - arrowTop = linkDimensions.h / 2 - arrowWidth; - } else if (halfBottomExceed) { - topPosition = rect[top] + scroll.y - elementDimensions.h + linkDimensions.h; - arrowTop = elementDimensions.h - linkDimensions.h / 2 - arrowWidth; - } else { - topPosition = rect[top] + scroll.y - elementDimensions.h / 2 + linkDimensions.h / 2; - arrowTop = elementDimensions.h / 2 - (isPopover ? arrowHeight * 0.9 : arrowHeight / 2); - } - } else if (position === top || position === bottom) { - // primary|vertical positions - if (position === top) { - // TOP - topPosition = rect[top] + scroll.y - elementDimensions.h - (isPopover ? arrowHeight : 0); - } else { - // BOTTOM - topPosition = rect[top] + scroll.y + linkDimensions.h; - } // adjust left | right and also the arrow - - - if (halfLeftExceed) { - leftPosition = 0; - arrowLeft = rect[left] + linkDimensions.w / 2 - arrowWidth; - } else if (halfRightExceed) { - leftPosition = windowWidth - elementDimensions.w * 1.01; - arrowLeft = elementDimensions.w - (windowWidth - rect[left]) + linkDimensions.w / 2 - arrowWidth / 2; - } else { - leftPosition = rect[left] + scroll.x - elementDimensions.w / 2 + linkDimensions.w / 2; - arrowLeft = elementDimensions.w / 2 - (isPopover ? arrowWidth : arrowWidth / 2); - } - } // apply style to tooltip/popover and its arrow - - - element[style][top] = topPosition + 'px'; - element[style][left] = leftPosition + 'px'; - arrowTop && (arrow[style][top] = arrowTop + 'px'); - arrowLeft && (arrow[style][left] = arrowLeft + 'px'); - }; - - BSN.version = '2.0.27'; - /* Native Javascript for Bootstrap 4 | Alert - -------------------------------------------*/ - // ALERT DEFINITION - // ================ - - var Alert = function Alert(element) { - // initialization element - element = queryElement(element); // bind, target alert, duration and stuff - - var self = this, - component = 'alert', - alert = getClosest(element, '.' + component), - triggerHandler = function triggerHandler() { - hasClass(alert, 'fade') ? emulateTransitionEnd(alert, transitionEndHandler) : transitionEndHandler(); - }, - // handlers - clickHandler = function clickHandler(e) { - alert = getClosest(e[target], '.' + component); - element = queryElement('[' + dataDismiss + '="' + component + '"]', alert); - element && alert && (element === e[target] || element[contains](e[target])) && self.close(); - }, - transitionEndHandler = function transitionEndHandler() { - bootstrapCustomEvent.call(alert, closedEvent, component); - off(element, clickEvent, clickHandler); // detach it's listener - - alert[parentNode].removeChild(alert); - }; // public method - - - this.close = function () { - if (alert && element && hasClass(alert, showClass)) { - bootstrapCustomEvent.call(alert, closeEvent, component); - removeClass(alert, showClass); - alert && triggerHandler(); - } - }; // init - - - if (!(stringAlert in element)) { - // prevent adding event handlers twice - on(element, clickEvent, clickHandler); - } - - element[stringAlert] = self; - }; // ALERT DATA API - // ============== - - - supports[push]([stringAlert, Alert, '[' + dataDismiss + '="alert"]']); - /* Native Javascript for Bootstrap 4 | Button - ---------------------------------------------*/ - // BUTTON DEFINITION - // =================== - - var Button = function Button(element) { - // initialization element - element = queryElement(element); // constant - - var toggled = false, - // toggled makes sure to prevent triggering twice the change.bs.button events - // strings - component = 'button', - checked = 'checked', - LABEL = 'LABEL', - INPUT = 'INPUT', - // private methods - keyHandler = function keyHandler(e) { - var key = e.which || e.keyCode; - key === 32 && e[target] === DOC.activeElement && toggle(e); - }, - preventScroll = function preventScroll(e) { - var key = e.which || e.keyCode; - key === 32 && e[preventDefault](); - }, - toggle = function toggle(e) { - var label = e[target].tagName === LABEL ? e[target] : e[target][parentNode].tagName === LABEL ? e[target][parentNode] : null; // the .btn label - - if (!label) return; //react if a label or its immediate child is clicked - - var labels = getElementsByClassName(label[parentNode], 'btn'), - // all the button group buttons - input = label[getElementsByTagName](INPUT)[0]; - if (!input) return; // return if no input found - // manage the dom manipulation - - if (input.type === 'checkbox') { - //checkboxes - if (!input[checked]) { - addClass(label, active); - input[getAttribute](checked); - input[setAttribute](checked, checked); - input[checked] = true; - } else { - removeClass(label, active); - input[getAttribute](checked); - input.removeAttribute(checked); - input[checked] = false; - } - - if (!toggled) { - // prevent triggering the event twice - toggled = true; - bootstrapCustomEvent.call(input, changeEvent, component); //trigger the change for the input - - bootstrapCustomEvent.call(element, changeEvent, component); //trigger the change for the btn-group - } - } - - if (input.type === 'radio' && !toggled) { - // radio buttons - // don't trigger if already active (the OR condition is a hack to check if the buttons were selected with key press and NOT mouse click) - if (!input[checked] || e.screenX === 0 && e.screenY == 0) { - addClass(label, active); - addClass(label, focusEvent); - input[setAttribute](checked, checked); - input[checked] = true; - bootstrapCustomEvent.call(input, changeEvent, component); //trigger the change for the input - - bootstrapCustomEvent.call(element, changeEvent, component); //trigger the change for the btn-group - - toggled = true; - - for (var i = 0, ll = labels[length]; i < ll; i++) { - var otherLabel = labels[i], - otherInput = otherLabel[getElementsByTagName](INPUT)[0]; - - if (otherLabel !== label && hasClass(otherLabel, active)) { - removeClass(otherLabel, active); - otherInput.removeAttribute(checked); - otherInput[checked] = false; - bootstrapCustomEvent.call(otherInput, changeEvent, component); // trigger the change - } - } - } - } - - setTimeout(function () { - toggled = false; - }, 50); - }, - focusHandler = function focusHandler(e) { - addClass(e[target][parentNode], focusEvent); - }, - blurHandler = function blurHandler(e) { - removeClass(e[target][parentNode], focusEvent); - }; // init - - - if (!(stringButton in element)) { - // prevent adding event handlers twice - on(element, clickEvent, toggle); - on(element, keyupEvent, keyHandler), on(element, keydownEvent, preventScroll); - var allBtns = getElementsByClassName(element, 'btn'); - - for (var i = 0; i < allBtns.length; i++) { - var input = allBtns[i][getElementsByTagName](INPUT)[0]; - on(input, focusEvent, focusHandler), on(input, 'blur', blurHandler); - } - } // activate items on load - - - var labelsToACtivate = getElementsByClassName(element, 'btn'), - lbll = labelsToACtivate[length]; - - for (var i = 0; i < lbll; i++) { - !hasClass(labelsToACtivate[i], active) && queryElement('input:checked', labelsToACtivate[i]) && addClass(labelsToACtivate[i], active); - } - - element[stringButton] = this; - }; // BUTTON DATA API - // ================= - - - supports[push]([stringButton, Button, '[' + dataToggle + '="buttons"]']); - /* Native Javascript for Bootstrap 4 | Collapse - -----------------------------------------------*/ - // COLLAPSE DEFINITION - // =================== - - var Collapse = function Collapse(element, options) { - // initialization element - element = queryElement(element); // set options - - options = options || {}; // event targets and constants - - var accordion = null, - collapse = null, - self = this, - accordionData = element[getAttribute]('data-parent'), - activeCollapse, - activeElement, - // component strings - component = 'collapse', - collapsed = 'collapsed', - isAnimating = 'isAnimating', - // private methods - openAction = function openAction(collapseElement, toggle) { - bootstrapCustomEvent.call(collapseElement, showEvent, component); - collapseElement[isAnimating] = true; - addClass(collapseElement, collapsing); - removeClass(collapseElement, component); - collapseElement[style][height] = collapseElement[scrollHeight] + 'px'; - emulateTransitionEnd(collapseElement, function () { - collapseElement[isAnimating] = false; - collapseElement[setAttribute](ariaExpanded, 'true'); - toggle[setAttribute](ariaExpanded, 'true'); - removeClass(collapseElement, collapsing); - addClass(collapseElement, component); - addClass(collapseElement, showClass); - collapseElement[style][height] = ''; - bootstrapCustomEvent.call(collapseElement, shownEvent, component); - }); - }, - closeAction = function closeAction(collapseElement, toggle) { - bootstrapCustomEvent.call(collapseElement, hideEvent, component); - collapseElement[isAnimating] = true; - collapseElement[style][height] = collapseElement[scrollHeight] + 'px'; // set height first - - removeClass(collapseElement, component); - removeClass(collapseElement, showClass); - addClass(collapseElement, collapsing); - collapseElement[offsetWidth]; // force reflow to enable transition - - collapseElement[style][height] = '0px'; - emulateTransitionEnd(collapseElement, function () { - collapseElement[isAnimating] = false; - collapseElement[setAttribute](ariaExpanded, 'false'); - toggle[setAttribute](ariaExpanded, 'false'); - removeClass(collapseElement, collapsing); - addClass(collapseElement, component); - collapseElement[style][height] = ''; - bootstrapCustomEvent.call(collapseElement, hiddenEvent, component); - }); - }, - getTarget = function getTarget() { - var href = element.href && element[getAttribute]('href'), - parent = element[getAttribute](dataTarget), - id = href || parent && parent.charAt(0) === '#' && parent; - return id && queryElement(id); - }; // public methods - - - this.toggle = function (e) { - e[preventDefault](); - - if (!hasClass(collapse, showClass)) { - self.show(); - } else { - self.hide(); - } - }; - - this.hide = function () { - if (collapse[isAnimating]) return; - closeAction(collapse, element); - addClass(element, collapsed); - }; - - this.show = function () { - if (accordion) { - activeCollapse = queryElement('.' + component + '.' + showClass, accordion); - activeElement = activeCollapse && (queryElement('[' + dataTarget + '="#' + activeCollapse.id + '"]', accordion) || queryElement('[href="#' + activeCollapse.id + '"]', accordion)); - } - - if (!collapse[isAnimating] || activeCollapse && !activeCollapse[isAnimating]) { - if (activeElement && activeCollapse !== collapse) { - closeAction(activeCollapse, activeElement); - addClass(activeElement, collapsed); - } - - openAction(collapse, element); - removeClass(element, collapsed); - } - }; // init - - - if (!(stringCollapse in element)) { - // prevent adding event handlers twice - on(element, clickEvent, self.toggle); - } - - collapse = getTarget(); - collapse[isAnimating] = false; // when true it will prevent click handlers - - accordion = queryElement(options.parent) || accordionData && getClosest(element, accordionData); - element[stringCollapse] = self; - }; // COLLAPSE DATA API - // ================= - - - supports[push]([stringCollapse, Collapse, '[' + dataToggle + '="collapse"]']); - /* Native Javascript for Bootstrap 4 | Dropdown - ----------------------------------------------*/ - // DROPDOWN DEFINITION - // =================== - - var Dropdown = function Dropdown(element, option) { - // initialization element - element = queryElement(element); // set option - - this.persist = option === true || element[getAttribute]('data-persist') === 'true' || false; // constants, event targets, strings - - var self = this, - children = 'children', - parent = element[parentNode], - component = 'dropdown', - open = 'open', - relatedTarget = null, - menu = queryElement('.dropdown-menu', parent), - menuItems = function () { - var set = menu[children], - newSet = []; - - for (var i = 0; i < set[length]; i++) { - set[i][children][length] && set[i][children][0].tagName === 'A' && newSet[push](set[i][children][0]); - set[i].tagName === 'A' && newSet[push](set[i]); - } - - return newSet; - }(), - // preventDefault on empty anchor links - preventEmptyAnchor = function preventEmptyAnchor(anchor) { - (anchor.href && anchor.href.slice(-1) === '#' || anchor[parentNode] && anchor[parentNode].href && anchor[parentNode].href.slice(-1) === '#') && this[preventDefault](); - }, - // toggle dismissible events - toggleDismiss = function toggleDismiss() { - var type = element[open] ? on : off; - type(DOC, clickEvent, dismissHandler); - type(DOC, keydownEvent, preventScroll); - type(DOC, keyupEvent, keyHandler); - type(DOC, focusEvent, dismissHandler, true); - }, - // handlers - dismissHandler = function dismissHandler(e) { - var eventTarget = e[target], - hasData = eventTarget && (eventTarget[getAttribute](dataToggle) || eventTarget[parentNode] && getAttribute in eventTarget[parentNode] && eventTarget[parentNode][getAttribute](dataToggle)); - - if (e.type === focusEvent && (eventTarget === element || eventTarget === menu || menu[contains](eventTarget))) { - return; - } - - if ((eventTarget === menu || menu[contains](eventTarget)) && (self.persist || hasData)) { - return; - } else { - relatedTarget = eventTarget === element || element[contains](eventTarget) ? element : null; - hide(); - } - - preventEmptyAnchor.call(e, eventTarget); - }, - clickHandler = function clickHandler(e) { - relatedTarget = element; - show(); - preventEmptyAnchor.call(e, e[target]); - }, - preventScroll = function preventScroll(e) { - var key = e.which || e.keyCode; - - if (key === 38 || key === 40) { - e[preventDefault](); - } - }, - keyHandler = function keyHandler(e) { - var key = e.which || e.keyCode, - activeItem = DOC.activeElement, - idx = menuItems[indexOf](activeItem), - isSameElement = activeItem === element, - isInsideMenu = menu[contains](activeItem), - isMenuItem = activeItem[parentNode] === menu || activeItem[parentNode][parentNode] === menu; - - if (isMenuItem) { - // navigate up | down - idx = isSameElement ? 0 : key === 38 ? idx > 1 ? idx - 1 : 0 : key === 40 ? idx < menuItems[length] - 1 ? idx + 1 : idx : idx; - menuItems[idx] && setFocus(menuItems[idx]); - } - - if ((menuItems[length] && isMenuItem // menu has items - || !menuItems[length] && (isInsideMenu || isSameElement) // menu might be a form - || !isInsideMenu) && // or the focused element is not in the menu at all - element[open] && key === 27 // menu must be open - ) { - self.toggle(); - relatedTarget = null; - } - }, - // private methods - show = function show() { - bootstrapCustomEvent.call(parent, showEvent, component, relatedTarget); - addClass(menu, showClass); - addClass(parent, showClass); - element[setAttribute](ariaExpanded, true); - bootstrapCustomEvent.call(parent, shownEvent, component, relatedTarget); - element[open] = true; - off(element, clickEvent, clickHandler); - setTimeout(function () { - setFocus(menu[getElementsByTagName]('INPUT')[0] || element); // focus the first input item | element - - toggleDismiss(); - }, 1); - }, - hide = function hide() { - bootstrapCustomEvent.call(parent, hideEvent, component, relatedTarget); - removeClass(menu, showClass); - removeClass(parent, showClass); - element[setAttribute](ariaExpanded, false); - bootstrapCustomEvent.call(parent, hiddenEvent, component, relatedTarget); - element[open] = false; - toggleDismiss(); - setFocus(element); - setTimeout(function () { - on(element, clickEvent, clickHandler); - }, 1); - }; // set initial state to closed - - - element[open] = false; // public methods - - this.toggle = function () { - if (hasClass(parent, showClass) && element[open]) { - hide(); - } else { - show(); - } - }; // init - - - if (!(stringDropdown in element)) { - // prevent adding event handlers twice - !tabindex in menu && menu[setAttribute](tabindex, '0'); // Fix onblur on Chrome | Safari - - on(element, clickEvent, clickHandler); - } - - element[stringDropdown] = self; - }; // DROPDOWN DATA API - // ================= - - - supports[push]([stringDropdown, Dropdown, '[' + dataToggle + '="dropdown"]']); - /* Native Javascript for Bootstrap 4 | Modal - -------------------------------------------*/ - // MODAL DEFINITION - // =============== - - var Modal = function Modal(element, options) { - // element can be the modal/triggering button - // the modal (both JavaScript / DATA API init) / triggering button element (DATA API) - element = queryElement(element); // strings - - var component = 'modal', - staticString = 'static', - modalTrigger = 'modalTrigger', - paddingRight = 'paddingRight', - modalBackdropString = 'modal-backdrop', - isAnimating = 'isAnimating', - // determine modal, triggering element - btnCheck = element[getAttribute](dataTarget) || element[getAttribute]('href'), - checkModal = queryElement(btnCheck), - modal = hasClass(element, component) ? element : checkModal; - - if (hasClass(element, component)) { - element = null; - } // modal is now independent of it's triggering element - - - if (!modal) { - return; - } // invalidate - // set options - - - options = options || {}; - this[keyboard] = options[keyboard] === false || modal[getAttribute](dataKeyboard) === 'false' ? false : true; - this[backdrop] = options[backdrop] === staticString || modal[getAttribute](databackdrop) === staticString ? staticString : true; - this[backdrop] = options[backdrop] === false || modal[getAttribute](databackdrop) === 'false' ? false : this[backdrop]; - this[animation] = hasClass(modal, 'fade') ? true : false; - this[content] = options[content]; // JavaScript only - // set an initial state of the modal - - modal[isAnimating] = false; // bind, constants, event targets and other vars - - var self = this, - relatedTarget = null, - bodyIsOverflowing, - scrollBarWidth, - overlay, - overlayDelay, - modalTimer, - // also find fixed-top / fixed-bottom items - fixedItems = getElementsByClassName(HTML, fixedTop).concat(getElementsByClassName(HTML, fixedBottom)), - // private methods - getWindowWidth = function getWindowWidth() { - var htmlRect = HTML[getBoundingClientRect](); - return globalObject[innerWidth] || htmlRect[right] - Math.abs(htmlRect[left]); - }, - setScrollbar = function setScrollbar() { - var bodyStyle = globalObject[getComputedStyle](DOC[body]), - bodyPad = parseInt(bodyStyle[paddingRight], 10), - itemPad; - - if (bodyIsOverflowing) { - DOC[body][style][paddingRight] = bodyPad + scrollBarWidth + 'px'; - modal[style][paddingRight] = scrollBarWidth + 'px'; - - if (fixedItems[length]) { - for (var i = 0; i < fixedItems[length]; i++) { - itemPad = globalObject[getComputedStyle](fixedItems[i])[paddingRight]; - fixedItems[i][style][paddingRight] = parseInt(itemPad) + scrollBarWidth + 'px'; - } - } - } - }, - resetScrollbar = function resetScrollbar() { - DOC[body][style][paddingRight] = ''; - modal[style][paddingRight] = ''; - - if (fixedItems[length]) { - for (var i = 0; i < fixedItems[length]; i++) { - fixedItems[i][style][paddingRight] = ''; - } - } - }, - measureScrollbar = function measureScrollbar() { - // thx walsh - var scrollDiv = DOC[createElement]('div'), - widthValue; - scrollDiv.className = component + '-scrollbar-measure'; // this is here to stay - - DOC[body][appendChild](scrollDiv); - widthValue = scrollDiv[offsetWidth] - scrollDiv[clientWidth]; - DOC[body].removeChild(scrollDiv); - return widthValue; - }, - checkScrollbar = function checkScrollbar() { - bodyIsOverflowing = DOC[body][clientWidth] < getWindowWidth(); - scrollBarWidth = measureScrollbar(); - }, - createOverlay = function createOverlay() { - var newOverlay = DOC[createElement]('div'); - overlay = queryElement('.' + modalBackdropString); - - if (overlay === null) { - newOverlay[setAttribute]('class', modalBackdropString + (self[animation] ? ' fade' : '')); - overlay = newOverlay; - DOC[body][appendChild](overlay); - } - - modalOverlay = 1; - }, - removeOverlay = function removeOverlay() { - overlay = queryElement('.' + modalBackdropString); - - if (overlay && overlay !== null && typeof overlay === 'object') { - modalOverlay = 0; - DOC[body].removeChild(overlay); - overlay = null; - } - }, - // triggers - triggerShow = function triggerShow() { - setFocus(modal); - modal[isAnimating] = false; - bootstrapCustomEvent.call(modal, shownEvent, component, relatedTarget); - on(globalObject, resizeEvent, self.update, passiveHandler); - on(modal, clickEvent, dismissHandler); - on(DOC, keydownEvent, keyHandler); - }, - triggerHide = function triggerHide() { - modal[style].display = ''; - element && setFocus(element); - bootstrapCustomEvent.call(modal, hiddenEvent, component); - - (function () { - if (!getElementsByClassName(DOC, component + ' ' + showClass)[0]) { - resetScrollbar(); - removeClass(DOC[body], component + '-open'); - overlay && hasClass(overlay, 'fade') ? (removeClass(overlay, showClass), emulateTransitionEnd(overlay, removeOverlay)) : removeOverlay(); - off(globalObject, resizeEvent, self.update, passiveHandler); - off(modal, clickEvent, dismissHandler); - off(DOC, keydownEvent, keyHandler); - } - })(); - - modal[isAnimating] = false; - }, - // handlers - clickHandler = function clickHandler(e) { - if (modal[isAnimating]) return; - var clickTarget = e[target]; - clickTarget = clickTarget[hasAttribute](dataTarget) || clickTarget[hasAttribute]('href') ? clickTarget : clickTarget[parentNode]; - - if (clickTarget === element && !hasClass(modal, showClass)) { - modal[modalTrigger] = element; - relatedTarget = element; - self.show(); - e[preventDefault](); - } - }, - keyHandler = function keyHandler(e) { - if (modal[isAnimating]) return; - - if (self[keyboard] && e.which == 27 && hasClass(modal, showClass)) { - self.hide(); - } - }, - dismissHandler = function dismissHandler(e) { - if (modal[isAnimating]) return; - var clickTarget = e[target]; - - if (hasClass(modal, showClass) && (clickTarget[parentNode][getAttribute](dataDismiss) === component || clickTarget[getAttribute](dataDismiss) === component || clickTarget === modal && self[backdrop] !== staticString)) { - self.hide(); - relatedTarget = null; - e[preventDefault](); - } - }; // public methods - - - this.toggle = function () { - if (hasClass(modal, showClass)) { - this.hide(); - } else { - this.show(); - } - }; - - this.show = function () { - if (hasClass(modal, showClass) || modal[isAnimating]) { - return; - } - - clearTimeout(modalTimer); - modalTimer = setTimeout(function () { - modal[isAnimating] = true; - bootstrapCustomEvent.call(modal, showEvent, component, relatedTarget); // we elegantly hide any opened modal - - var currentOpen = getElementsByClassName(DOC, component + ' ' + showClass)[0]; - - if (currentOpen && currentOpen !== modal) { - modalTrigger in currentOpen && currentOpen[modalTrigger][stringModal].hide(); - stringModal in currentOpen && currentOpen[stringModal].hide(); - } - - if (self[backdrop]) { - !modalOverlay && !overlay && createOverlay(); - } - - if (overlay && !hasClass(overlay, showClass)) { - overlay[offsetWidth]; // force reflow to enable trasition - - overlayDelay = getTransitionDurationFromElement(overlay); - addClass(overlay, showClass); - } - - setTimeout(function () { - modal[style].display = 'block'; - checkScrollbar(); - setScrollbar(); - addClass(DOC[body], component + '-open'); - addClass(modal, showClass); - modal[setAttribute](ariaHidden, false); - hasClass(modal, 'fade') ? emulateTransitionEnd(modal, triggerShow) : triggerShow(); - }, supportTransitions && overlay && overlayDelay ? overlayDelay : 1); - }, 1); - }; - - this.hide = function () { - if (modal[isAnimating] || !hasClass(modal, showClass)) { - return; - } - - clearTimeout(modalTimer); - modalTimer = setTimeout(function () { - modal[isAnimating] = true; - bootstrapCustomEvent.call(modal, hideEvent, component); - overlay = queryElement('.' + modalBackdropString); - overlayDelay = overlay && getTransitionDurationFromElement(overlay); - removeClass(modal, showClass); - modal[setAttribute](ariaHidden, true); - setTimeout(function () { - hasClass(modal, 'fade') ? emulateTransitionEnd(modal, triggerHide) : triggerHide(); - }, supportTransitions && overlay && overlayDelay ? overlayDelay : 2); - }, 2); - }; - - this.setContent = function (content) { - queryElement('.' + component + '-content', modal)[innerHTML] = content; - }; - - this.update = function () { - if (hasClass(modal, showClass)) { - checkScrollbar(); - setScrollbar(); - } - }; // init - // prevent adding event handlers over and over - // modal is independent of a triggering element - - - if (!!element && !(stringModal in element)) { - on(element, clickEvent, clickHandler); - } - - if (!!self[content]) { - self.setContent(self[content]); - } - - if (element) { - element[stringModal] = self; - modal[modalTrigger] = element; - } else { - modal[stringModal] = self; - } - }; // DATA API - - - supports[push]([stringModal, Modal, '[' + dataToggle + '="modal"]']); - /* Native Javascript for Bootstrap 4 | Popover - ----------------------------------------------*/ - // POPOVER DEFINITION - // ================== - - var Popover = function Popover(element, options) { - // initialization element - element = queryElement(element); // set options - - options = options || {}; // DATA API - - var triggerData = element[getAttribute](dataTrigger), - // click / hover / focus - animationData = element[getAttribute](dataAnimation), - // true / false - placementData = element[getAttribute](dataPlacement), - dismissibleData = element[getAttribute](dataDismissible), - delayData = element[getAttribute](dataDelay), - containerData = element[getAttribute](dataContainer), - // internal strings - component = 'popover', - template = 'template', - trigger = 'trigger', - classString = 'class', - div = 'div', - fade = 'fade', - dataContent = 'data-content', - dismissible = 'dismissible', - closeBtn = '', - // check container - containerElement = queryElement(options[container]), - containerDataElement = queryElement(containerData), - // maybe the element is inside a modal - modal = getClosest(element, '.modal'), - // maybe the element is inside a fixed navbar - navbarFixedTop = getClosest(element, '.' + fixedTop), - navbarFixedBottom = getClosest(element, '.' + fixedBottom); // set instance options - - this[template] = options[template] ? options[template] : null; // JavaScript only - - this[trigger] = options[trigger] ? options[trigger] : triggerData || hoverEvent; - this[animation] = options[animation] && options[animation] !== fade ? options[animation] : animationData || fade; - this[placement] = options[placement] ? options[placement] : placementData || top; - this[delay] = parseInt(options[delay] || delayData) || 200; - this[dismissible] = options[dismissible] || dismissibleData === 'true' ? true : false; - this[container] = containerElement ? containerElement : containerDataElement ? containerDataElement : navbarFixedTop ? navbarFixedTop : navbarFixedBottom ? navbarFixedBottom : modal ? modal : DOC[body]; // bind, content - - var self = this, - titleString = options.title || element[getAttribute](dataTitle) || null, - contentString = options.content || element[getAttribute](dataContent) || null; - if (!contentString && !this[template]) return; // invalidate - // constants, vars - - var popover = null, - timer = 0, - placementSetting = this[placement], - // handlers - dismissibleHandler = function dismissibleHandler(e) { - if (popover !== null && e[target] === queryElement('.close', popover)) { - self.hide(); - } - }, - // private methods - removePopover = function removePopover() { - self[container].removeChild(popover); - timer = null; - popover = null; - }, - createPopover = function createPopover() { - titleString = options.title || element[getAttribute](dataTitle); - contentString = options.content || element[getAttribute](dataContent); // fixing https://github.com/thednp/bootstrap.native/issues/233 - - contentString = !!contentString ? contentString.trim() : null; - popover = DOC[createElement](div); // popover arrow - - var popoverArrow = DOC[createElement](div); - popoverArrow[setAttribute](classString, 'arrow'); - popover[appendChild](popoverArrow); - - if (contentString !== null && self[template] === null) { - //create the popover from data attributes - popover[setAttribute]('role', 'tooltip'); - - if (titleString !== null) { - var popoverTitle = DOC[createElement]('h3'); - popoverTitle[setAttribute](classString, component + '-header'); - popoverTitle[innerHTML] = self[dismissible] ? titleString + closeBtn : titleString; - popover[appendChild](popoverTitle); - } //set popover content - - - var popoverContent = DOC[createElement](div); - popoverContent[setAttribute](classString, component + '-body'); - popoverContent[innerHTML] = self[dismissible] && titleString === null ? contentString + closeBtn : contentString; - popover[appendChild](popoverContent); - } else { - // or create the popover from template - var popoverTemplate = DOC[createElement](div); - self[template] = self[template].trim(); - popoverTemplate[innerHTML] = self[template]; - popover[innerHTML] = popoverTemplate.firstChild[innerHTML]; - } //append to the container - - - self[container][appendChild](popover); - popover[style].display = 'block'; - popover[setAttribute](classString, component + ' bs-' + component + '-' + placementSetting + ' ' + self[animation]); - }, - showPopover = function showPopover() { - !hasClass(popover, showClass) && addClass(popover, showClass); - }, - updatePopover = function updatePopover() { - styleTip(element, popover, placementSetting, self[container]); - }, - // event toggle - dismissHandlerToggle = function dismissHandlerToggle(type) { - if (clickEvent == self[trigger] || 'focus' == self[trigger]) { - !self[dismissible] && type(element, 'blur', self.hide); - } - - self[dismissible] && type(DOC, clickEvent, dismissibleHandler); - type(globalObject, resizeEvent, self.hide, passiveHandler); - }, - // triggers - showTrigger = function showTrigger() { - dismissHandlerToggle(on); - bootstrapCustomEvent.call(element, shownEvent, component); - }, - hideTrigger = function hideTrigger() { - dismissHandlerToggle(off); - removePopover(); - bootstrapCustomEvent.call(element, hiddenEvent, component); - }; // public methods / handlers - - - this.toggle = function () { - if (popover === null) { - self.show(); - } else { - self.hide(); - } - }; - - this.show = function () { - clearTimeout(timer); - timer = setTimeout(function () { - if (popover === null) { - placementSetting = self[placement]; // we reset placement in all cases - - createPopover(); - updatePopover(); - showPopover(); - bootstrapCustomEvent.call(element, showEvent, component); - !!self[animation] ? emulateTransitionEnd(popover, showTrigger) : showTrigger(); - } - }, 20); - }; - - this.hide = function () { - clearTimeout(timer); - timer = setTimeout(function () { - if (popover && popover !== null && hasClass(popover, showClass)) { - bootstrapCustomEvent.call(element, hideEvent, component); - removeClass(popover, showClass); - !!self[animation] ? emulateTransitionEnd(popover, hideTrigger) : hideTrigger(); - } - }, self[delay]); - }; // init - - - if (!(stringPopover in element)) { - // prevent adding event handlers twice - if (self[trigger] === hoverEvent) { - on(element, mouseHover[0], self.show); - - if (!self[dismissible]) { - on(element, mouseHover[1], self.hide); - } - } else if (clickEvent == self[trigger] || 'focus' == self[trigger]) { - on(element, self[trigger], self.toggle); - } - } - - element[stringPopover] = self; - }; // POPOVER DATA API - // ================ - - - supports[push]([stringPopover, Popover, '[' + dataToggle + '="popover"]']); - /* Native Javascript for Bootstrap 4 | Tab - -----------------------------------------*/ - // TAB DEFINITION - // ============== - - var Tab = function Tab(element, options) { - // initialization element - element = queryElement(element); // DATA API - - var heightData = element[getAttribute](dataHeight), - // strings - component = 'tab', - height = 'height', - float = 'float', - isAnimating = 'isAnimating'; // set options - - options = options || {}; - this[height] = supportTransitions ? options[height] || heightData === 'true' : false; // bind, event targets - - var self = this, - next, - tabs = getClosest(element, '.nav'), - tabsContentContainer = false, - dropdown = tabs && queryElement('.dropdown-toggle', tabs), - activeTab, - activeContent, - nextContent, - containerHeight, - equalContents, - nextHeight, - // trigger - triggerEnd = function triggerEnd() { - tabsContentContainer[style][height] = ''; - removeClass(tabsContentContainer, collapsing); - tabs[isAnimating] = false; - }, - triggerShow = function triggerShow() { - if (tabsContentContainer) { - // height animation - if (equalContents) { - triggerEnd(); - } else { - setTimeout(function () { - // enables height animation - tabsContentContainer[style][height] = nextHeight + 'px'; // height animation - - tabsContentContainer[offsetWidth]; - emulateTransitionEnd(tabsContentContainer, triggerEnd); - }, 50); - } - } else { - tabs[isAnimating] = false; - } - - bootstrapCustomEvent.call(next, shownEvent, component, activeTab); - }, - triggerHide = function triggerHide() { - if (tabsContentContainer) { - activeContent[style][float] = left; - nextContent[style][float] = left; - containerHeight = activeContent[scrollHeight]; - } - - addClass(nextContent, active); - bootstrapCustomEvent.call(next, showEvent, component, activeTab); - removeClass(activeContent, active); - bootstrapCustomEvent.call(activeTab, hiddenEvent, component, next); - - if (tabsContentContainer) { - nextHeight = nextContent[scrollHeight]; - equalContents = nextHeight === containerHeight; - addClass(tabsContentContainer, collapsing); - tabsContentContainer[style][height] = containerHeight + 'px'; // height animation - - tabsContentContainer[offsetHeight]; - activeContent[style][float] = ''; - nextContent[style][float] = ''; - } - - if (hasClass(nextContent, 'fade')) { - setTimeout(function () { - addClass(nextContent, showClass); - emulateTransitionEnd(nextContent, triggerShow); - }, 20); - } else { - triggerShow(); - } - }; - - if (!tabs) return; // invalidate - // set default animation state - - tabs[isAnimating] = false; // private methods - - var getActiveTab = function getActiveTab() { - var activeTabs = getElementsByClassName(tabs, active), - activeTab; - - if (activeTabs[length] === 1 && !hasClass(activeTabs[0][parentNode], 'dropdown')) { - activeTab = activeTabs[0]; - } else if (activeTabs[length] > 1) { - activeTab = activeTabs[activeTabs[length] - 1]; - } - - return activeTab; - }, - getActiveContent = function getActiveContent() { - return queryElement(getActiveTab()[getAttribute]('href')); - }, - // handler - clickHandler = function clickHandler(e) { - e[preventDefault](); - next = e[currentTarget]; - !tabs[isAnimating] && !hasClass(next, active) && self.show(); - }; // public method - - - this.show = function () { - // the tab we clicked is now the next tab - next = next || element; - nextContent = queryElement(next[getAttribute]('href')); //this is the actual object, the next tab content to activate - - activeTab = getActiveTab(); - activeContent = getActiveContent(); - tabs[isAnimating] = true; - removeClass(activeTab, active); - activeTab[setAttribute](ariaSelected, 'false'); - addClass(next, active); - next[setAttribute](ariaSelected, 'true'); - - if (dropdown) { - if (!hasClass(element[parentNode], 'dropdown-menu')) { - if (hasClass(dropdown, active)) removeClass(dropdown, active); - } else { - if (!hasClass(dropdown, active)) addClass(dropdown, active); - } - } - - bootstrapCustomEvent.call(activeTab, hideEvent, component, next); - - if (hasClass(activeContent, 'fade')) { - removeClass(activeContent, showClass); - emulateTransitionEnd(activeContent, triggerHide); - } else { - triggerHide(); - } - }; // init - - - if (!(stringTab in element)) { - // prevent adding event handlers twice - on(element, clickEvent, clickHandler); - } - - if (self[height]) { - tabsContentContainer = getActiveContent()[parentNode]; - } - - element[stringTab] = self; - }; // TAB DATA API - // ============ - - - supports[push]([stringTab, Tab, '[' + dataToggle + '="tab"]']); - /* Native Javascript for Bootstrap 4 | Toast - ---------------------------------------------*/ - // TOAST DEFINITION - // ================== - - var Toast = function Toast(element, options) { - // initialization element - element = queryElement(element); // set options - - options = options || {}; // DATA API - - var animationData = element[getAttribute](dataAnimation), - autohideData = element[getAttribute](dataAutohide), - delayData = element[getAttribute](dataDelay), - // strings - component = 'toast', - autohide = 'autohide', - animation = 'animation', - showing = 'showing', - hide = 'hide', - fade = 'fade'; // set instance options - - this[animation] = options[animation] === false || animationData === 'false' ? 0 : 1; // true by default - - this[autohide] = options[autohide] === false || autohideData === 'false' ? 0 : 1; // true by default - - this[delay] = parseInt(options[delay] || delayData) || 500; // 500ms default - // bind,toast and timer - - var self = this, - timer = 0, - // get the toast element - toast = getClosest(element, '.toast'); // private methods - // animation complete - - var showComplete = function showComplete() { - removeClass(toast, showing); - addClass(toast, showClass); - bootstrapCustomEvent.call(toast, shownEvent, component); - - if (self[autohide]) { - self.hide(); - } - }, - hideComplete = function hideComplete() { - addClass(toast, hide); - bootstrapCustomEvent.call(toast, hiddenEvent, component); - }, - close = function close() { - removeClass(toast, showClass); - self[animation] ? emulateTransitionEnd(toast, hideComplete) : hideComplete(); - }, - disposeComplete = function disposeComplete() { - clearTimeout(timer); - timer = null; - addClass(toast, hide); - off(element, clickEvent, self.hide); - element[stringToast] = null; - element = null; - toast = null; - }; // public methods - - - this.show = function () { - if (toast) { - bootstrapCustomEvent.call(toast, showEvent, component); - self[animation] && addClass(toast, fade); - removeClass(toast, hide); - addClass(toast, showing); - self[animation] ? emulateTransitionEnd(toast, showComplete) : showComplete(); - } - }; - - this.hide = function (noTimer) { - if (toast && hasClass(toast, showClass)) { - bootstrapCustomEvent.call(toast, hideEvent, component); - - if (noTimer) { - close(); - } else { - timer = setTimeout(close, self[delay]); - } - } - }; - - this.dispose = function () { - if (toast && hasClass(toast, showClass)) { - removeClass(toast, showClass); - self[animation] ? emulateTransitionEnd(toast, disposeComplete) : disposeComplete(); - } - }; // init - - - if (!(stringToast in element)) { - // prevent adding event handlers twice - on(element, clickEvent, self.hide); - } - - element[stringToast] = self; - }; // TOAST DATA API - // ================= - - - supports[push]([stringToast, Toast, '[' + dataDismiss + '="toast"]']); - /* Native Javascript for Bootstrap 4 | Tooltip - ---------------------------------------------*/ - // TOOLTIP DEFINITION - // ================== - - var Tooltip = function Tooltip(element, options) { - // initialization element - element = queryElement(element); // set options - - options = options || {}; // DATA API - - var animationData = element[getAttribute](dataAnimation), - placementData = element[getAttribute](dataPlacement), - delayData = element[getAttribute](dataDelay), - containerData = element[getAttribute](dataContainer), - // strings - component = 'tooltip', - classString = 'class', - title = 'title', - fade = 'fade', - div = 'div', - // check container - containerElement = queryElement(options[container]), - containerDataElement = queryElement(containerData), - // maybe the element is inside a modal - modal = getClosest(element, '.modal'), - // maybe the element is inside a fixed navbar - navbarFixedTop = getClosest(element, '.' + fixedTop), - navbarFixedBottom = getClosest(element, '.' + fixedBottom); // set instance options - - this[animation] = options[animation] && options[animation] !== fade ? options[animation] : animationData || fade; - this[placement] = options[placement] ? options[placement] : placementData || top; - this[delay] = parseInt(options[delay] || delayData) || 200; - this[container] = containerElement ? containerElement : containerDataElement ? containerDataElement : navbarFixedTop ? navbarFixedTop : navbarFixedBottom ? navbarFixedBottom : modal ? modal : DOC[body]; // bind, event targets, title and constants - - var self = this, - timer = 0, - placementSetting = this[placement], - tooltip = null, - titleString = element[getAttribute](title) || element[getAttribute](dataTitle) || element[getAttribute](dataOriginalTitle); - if (!titleString || titleString == "") return; // invalidate - // private methods - - var removeToolTip = function removeToolTip() { - self[container].removeChild(tooltip); - tooltip = null; - timer = null; - }, - createToolTip = function createToolTip() { - titleString = element[getAttribute](title) || element[getAttribute](dataTitle) || element[getAttribute](dataOriginalTitle); // read the title again - - if (titleString && titleString !== "") { - // invalidate, maybe markup changed - tooltip = DOC[createElement](div); - tooltip[setAttribute]('role', component); - tooltip[style][left] = '0'; - tooltip[style][top] = '0'; // tooltip arrow - - var tooltipArrow = DOC[createElement](div); - tooltipArrow[setAttribute](classString, 'arrow'); - tooltip[appendChild](tooltipArrow); - var tooltipInner = DOC[createElement](div); - tooltipInner[setAttribute](classString, component + '-inner'); - tooltip[appendChild](tooltipInner); - tooltipInner[innerHTML] = titleString; - self[container][appendChild](tooltip); - tooltip[setAttribute](classString, component + ' bs-' + component + '-' + placementSetting + ' ' + self[animation]); - } - }, - updateTooltip = function updateTooltip() { - styleTip(element, tooltip, placementSetting, self[container]); - }, - showTooltip = function showTooltip() { - !hasClass(tooltip, showClass) && addClass(tooltip, showClass); - }, - // triggers - showTrigger = function showTrigger() { - on(globalObject, resizeEvent, self.hide, passiveHandler); - bootstrapCustomEvent.call(element, shownEvent, component); - }, - hideTrigger = function hideTrigger() { - off(globalObject, resizeEvent, self.hide, passiveHandler); - removeToolTip(); - bootstrapCustomEvent.call(element, hiddenEvent, component); - }; // public methods - - - this.show = function () { - clearTimeout(timer); - timer = setTimeout(function () { - if (tooltip === null) { - placementSetting = self[placement]; // we reset placement in all cases - // if(createToolTip() == false) return; - - if (createToolTip() !== false) { - updateTooltip(); - showTooltip(); - bootstrapCustomEvent.call(element, showEvent, component); - !!self[animation] ? emulateTransitionEnd(tooltip, showTrigger) : showTrigger(); - } - } - }, 20); - }; - - this.hide = function () { - clearTimeout(timer); - timer = setTimeout(function () { - if (tooltip && hasClass(tooltip, showClass)) { - bootstrapCustomEvent.call(element, hideEvent, component); - removeClass(tooltip, showClass); - !!self[animation] ? emulateTransitionEnd(tooltip, hideTrigger) : hideTrigger(); - } - }, self[delay]); - }; - - this.toggle = function () { - if (!tooltip) { - self.show(); - } else { - self.hide(); - } - }; // init - - - if (!(stringTooltip in element)) { - // prevent adding event handlers twice - element[setAttribute](dataOriginalTitle, titleString); - element.removeAttribute(title); - on(element, mouseHover[0], self.show); - on(element, mouseHover[1], self.hide); - } - - element[stringTooltip] = self; - }; // TOOLTIP DATA API - // ================= - - - supports[push]([stringTooltip, Tooltip, '[' + dataToggle + '="tooltip"]']); - /* Native Javascript for Bootstrap | Initialize Data API - --------------------------------------------------------*/ - - var initializeDataAPI = function initializeDataAPI(constructor, collection) { - for (var i = 0, l = collection[length]; i < l; i++) { - new constructor(collection[i]); - } - }, - initCallback = BSN.initCallback = function (lookUp) { - lookUp = lookUp || DOC; - - for (var i = 0, l = supports[length]; i < l; i++) { - initializeDataAPI(supports[i][1], lookUp[querySelectorAll](supports[i][2])); - } - }; // bulk initialize all components - - - DOC[body] ? initCallback() : on(DOC, 'DOMContentLoaded', function () { - initCallback(); - }); - return { - Alert: Alert, - Button: Button, - Collapse: Collapse, - Dropdown: Dropdown, - Modal: Modal, - Popover: Popover, - Tab: Tab, - Toast: Toast, - Tooltip: Tooltip - }; + return { + Alert: bootstrap.Alert, + Button: bootstrap.Button, + Collapse: bootstrap.Collapse, + Dropdown: bootstrap.Dropdown, + Modal: bootstrap.Modal, + Popover: bootstrap.Popover, + Tab: bootstrap.Tab, + Tooltip: bootstrap.Tooltip + }; }); /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(12)))