diff --git a/src/static/scripts/bootstrap-native-v4.js b/src/static/scripts/bootstrap-native-v4.js index e0cdf3a5..b1cf682f 100644 --- a/src/static/scripts/bootstrap-native-v4.js +++ b/src/static/scripts/bootstrap-native-v4.js @@ -1,1999 +1,1689 @@ -// Native Javascript for Bootstrap 4 v2.0.27 | © dnp_theme | MIT-License -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD support: - define([], factory); - } else if (typeof module === 'object' && module.exports) { - // CommonJS-like: - module.exports = factory(); - } else { - // Browser globals (root is window) - var bsn = factory(); - root.Alert = bsn.Alert; - root.Button = bsn.Button; - root.Carousel = bsn.Carousel; - root.Collapse = bsn.Collapse; - root.Dropdown = bsn.Dropdown; - root.Modal = bsn.Modal; - root.Popover = bsn.Popover; - root.ScrollSpy = bsn.ScrollSpy; - root.Tab = bsn.Tab; - root.Toast = bsn.Toast; - root.Tooltip = bsn.Tooltip; +/*! + * Native JavaScript for Bootstrap v3.0.1 (https://thednp.github.io/bootstrap.native/) + * Copyright 2015-2020 © dnp_theme + * Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE) + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = global || self, global.BSN = factory()); +}(this, (function () { 'use strict'; + + function hasClass(element,classNAME) { + return element.classList.contains(classNAME) } -}(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(element){ - element.focus ? element.focus() : element.setActive(); - }, - - // class manipulation, since 2.0.0 requires polyfill.js - addClass = function(element,classNAME) { - element.classList.add(classNAME); - }, - removeClass = function(element,classNAME) { - element.classList.remove(classNAME); - }, - hasClass = function(element,classNAME){ // since 2.0.0 - return element.classList[contains](classNAME); - }, - - // selection methods - getElementsByClassName = function(element,classNAME) { // returns Array - return [].slice.call(element[getElementsByCLASSNAME]( classNAME )); - }, - queryElement = function (selector, parent) { - var lookUp = parent ? parent : DOC; - return typeof selector === 'object' ? selector : lookUp.querySelector(selector); - }, - getClosest = function (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 (element, event, handler, options) { - options = options || false; - element.addEventListener(event, handler, options); - }, - off = function(element, event, handler, options) { - options = options || false; - element.removeEventListener(event, handler, options); - }, - one = function (element, event, handler, options) { // one since 2.0.4 - on(element, event, function handlerWrapper(e){ + + function removeClass(element,classNAME) { + element.classList.remove(classNAME); + } + + function on (element, event, handler, options) { + options = options || false; + element.addEventListener(event, handler, options); + } + + function off (element, event, handler, options) { + options = options || false; + element.removeEventListener(event, handler, options); + } + + function one (element, event, handler, options) { + on(element, event, function handlerWrapper(e){ + if (e.target === element) { 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() { - 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(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(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 (eventName, componentName, related) { - var OriginalCustomEvent = new CustomEvent( eventName + '.bs.' + componentName); - OriginalCustomEvent.relatedTarget = related; - this.dispatchEvent(OriginalCustomEvent); - }, - - // tooltip / popover stuff - getScroll = function() { // also Affix and ScrollSpy uses it - return { - y : globalObject.pageYOffset || HTML[scrollTop], - x : globalObject.pageXOffset || HTML[scrollLeft] - } - }, - styleTip = function(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; + } + }, options); + } + + var transitionEndEvent = 'webkitTransition' in document.body.style ? 'webkitTransitionEnd' : 'transitionend'; + + var supportTransition = 'webkitTransition' in document.body.style || 'transition' in document.body.style; + + var transitionDuration = 'webkitTransition' in document.body.style ? 'webkitTransitionDuration' : 'transitionDuration'; + + function getElementTransitionDuration (element) { + var duration = supportTransition ? window.getComputedStyle(element)[transitionDuration] : 0; + duration = parseFloat(duration); + duration = typeof duration === 'number' && !isNaN(duration) ? duration * 1000 : 0; + return duration; + } + + function emulateTransitionEnd (element,handler){ + var called = 0, duration = getElementTransitionDuration(element); + duration ? one(element, transitionEndEvent, function(e){ !called && handler(e), called = 1; }) + : setTimeout(function() { !called && handler(), called = 1; }, 17); + } + + function queryElement (selector, parent) { + var lookUp = parent && parent instanceof Element ? parent : document; + return selector instanceof Element ? selector : lookUp.querySelector(selector); + } + + function tryWrapper (fn,origin){ + try{ fn(); } + catch(e){ + console.error((origin + ": " + e)); + } + } + + function bootstrapCustomEvent (eventName, componentName, related) { + var OriginalCustomEvent = new CustomEvent( eventName + '.bs.' + componentName, {cancelable: true}); + OriginalCustomEvent.relatedTarget = related; + return OriginalCustomEvent; + } + function dispatchCustomEvent (customEvent){ + this && this.dispatchEvent(customEvent); + } + + function Alert(element) { + var self = this, + alert, + closeCustomEvent = bootstrapCustomEvent('close','alert'), + closedCustomEvent = bootstrapCustomEvent('closed','alert'); + function triggerHandler() { + hasClass(alert,'fade') ? emulateTransitionEnd(alert,transitionEndHandler) : transitionEndHandler(); + } + function clickHandler(e) { + alert = e && e.target.closest(".alert"); + element = queryElement('[data-dismiss="alert"]',alert); + element && alert && (element === e.target || element.contains(e.target)) && self.close(); + } + function transitionEndHandler() { + off(element, 'click', clickHandler); + alert.parentNode.removeChild(alert); + dispatchCustomEvent.call(alert,closedCustomEvent); + } + self.close = function () { + if ( alert && element && hasClass(alert,'show') ) { + dispatchCustomEvent.call(alert,closeCustomEvent); + if ( closeCustomEvent.defaultPrevented ) { return; } + self.dispose(); + removeClass(alert,'show'); + triggerHandler(); + } + }; + self.dispose = function () { + off(element, 'click', clickHandler); + delete element.Alert; + }; + tryWrapper(function (){ + element = queryElement(element); + alert = element.closest('.alert'); + element.Alert && element.Alert.dispose(); + if ( !element.Alert ) { + on(element, 'click', clickHandler); + } + self.element = element; + element.Alert = self; + },"BSN.Alert"); + } + + function addClass(element,classNAME) { + element.classList.add(classNAME); + } + + function Button(element) { + var self = this, labels, + changeCustomEvent = bootstrapCustomEvent('change', 'button'); + function toggle(e) { + var input, + label = e.target.tagName === 'LABEL' ? e.target + : e.target.closest('LABEL') ? e.target.closest('LABEL') : null; + input = label && label.getElementsByTagName('INPUT')[0]; + if ( !input ) { return; } + dispatchCustomEvent.call(input, changeCustomEvent); + dispatchCustomEvent.call(element, changeCustomEvent); + if ( input.type === 'checkbox' ) { + if ( changeCustomEvent.defaultPrevented ) { return; } + if ( !input.checked ) { + addClass(label,'active'); + input.getAttribute('checked'); + input.setAttribute('checked','checked'); + input.checked = true; } else { - topPosition = rect[top] + scroll.y - elementDimensions.h/2 + linkDimensions.h/2; - arrowTop = elementDimensions.h/2 - (isPopover ? arrowHeight*0.9 : arrowHeight/2); + removeClass(label,'active'); + input.getAttribute('checked'); + input.removeAttribute('checked'); + input.checked = false; } - } 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; + if (!element.toggled) { + element.toggled = true; } - // 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 ); + } + if ( input.type === 'radio' && !element.toggled ) { + if ( changeCustomEvent.defaultPrevented ) { return; } + if ( !input.checked || (e.screenX === 0 && e.screenY == 0) ) { + addClass(label,'active'); + addClass(label,'focus'); + input.setAttribute('checked','checked'); + input.checked = true; + element.toggled = true; + Array.from(labels).map(function (otherLabel){ + var otherInput = otherLabel.getElementsByTagName('INPUT')[0]; + if ( otherLabel !== label && hasClass(otherLabel,'active') ) { + dispatchCustomEvent.call(otherInput, changeCustomEvent); + removeClass(otherLabel,'active'); + otherInput.removeAttribute('checked'); + otherInput.checked = false; + } + }); } } - - // 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( element ) { - - // initialization element - element = queryElement(element); - - // bind, target alert, duration and stuff - var self = this, component = 'alert', - alert = getClosest(element,'.'+component), - triggerHandler = function(){ hasClass(alert,'fade') ? emulateTransitionEnd(alert,transitionEndHandler) : transitionEndHandler(); }, - // handlers - clickHandler = function(e){ - alert = getClosest(e[target],'.'+component); - element = queryElement('['+dataDismiss+'="'+component+'"]',alert); - element && alert && (element === e[target] || element[contains](e[target])) && self.close(); - }, - transitionEndHandler = function(){ - 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(); + setTimeout( function () { element.toggled = false; }, 50 ); + } + function keyHandler(e) { + var key = e.which || e.keyCode; + key === 32 && e.target === document.activeElement && toggle(e); + } + function preventScroll(e) { + var key = e.which || e.keyCode; + key === 32 && e.preventDefault(); + } + function focusToggle(e) { + var action = e.type === 'focusin' ? addClass : removeClass; + if (e.target.tagName === 'INPUT' ) { + action(e.target.closest('.btn'),'focus'); } - }; - - // 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( 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(e){ - var key = e.which || e.keyCode; - key === 32 && e[target] === DOC.activeElement && toggle(e); - }, - preventScroll = function(e){ - var key = e.which || e.keyCode; - key === 32 && e[preventDefault](); - }, - toggle = function(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= 0; + } + + function Carousel (element,options) { options = options || {}; - - // DATA API - var intervalAttribute = element[getAttribute](dataInterval), - intervalOption = options[interval], - intervalData = intervalAttribute === 'false' ? 0 : parseInt(intervalAttribute), - pauseData = element[getAttribute](dataPause) === hoverEvent || false, - keyboardData = element[getAttribute](dataKeyboard) === 'true' || false, - - // strings - component = 'carousel', - paused = 'paused', - direction = 'direction', - carouselItem = 'carousel-item', - dataSlideTo = 'data-slide-to'; - - this[keyboard] = options[keyboard] === true || keyboardData; - this[pause] = (options[pause] === hoverEvent || pauseData) ? hoverEvent : false; // false / hover - - this[interval] = typeof intervalOption === 'number' ? intervalOption - : intervalOption === false || intervalData === 0 || intervalData === false ? 0 - : isNaN(intervalData) ? 5000 // bootstrap carousel default interval - : intervalData; - - // bind, event targets - var self = this, index = element.index = 0, timer = element.timer = 0, - isSliding = false, // isSliding prevents click event handlers when animation is running - isTouch = false, startXPosition = null, currentXPosition = null, endXPosition = null, // touch and event coordinates - slides = getElementsByClassName(element,carouselItem), total = slides[length], - slideDirection = this[direction] = left, - leftArrow = getElementsByClassName(element,component+'-control-prev')[0], - rightArrow = getElementsByClassName(element,component+'-control-next')[0], - indicator = queryElement( '.'+component+'-indicators', element ), - indicators = indicator && indicator[getElementsByTagName]( "LI" ) || []; - - // invalidate when not enough items - if (total < 2) { return; } - - // handlers - var pauseHandler = function () { - if ( self[interval] !==false && !hasClass(element,paused) ) { - addClass(element,paused); - !isSliding && ( clearInterval(timer), timer = null ); - } - }, - resumeHandler = function() { - if ( self[interval] !== false && hasClass(element,paused) ) { - removeClass(element,paused); - !isSliding && ( clearInterval(timer), timer = null ); - !isSliding && self.cycle(); - } - }, - indicatorHandler = function(e) { - e[preventDefault](); - if (isSliding) return; - - var eventTarget = e[target]; // event target | the current active item - - if ( eventTarget && !hasClass(eventTarget,active) && eventTarget[getAttribute](dataSlideTo) ) { - index = parseInt( eventTarget[getAttribute](dataSlideTo), 10 ); - } else { return false; } - - self.slideTo( index ); //Do the slide - }, - controlsHandler = function (e) { - e[preventDefault](); - if (isSliding) return; - - var eventTarget = e.currentTarget || e.srcElement; - - if ( eventTarget === rightArrow ) { - index++; - } else if ( eventTarget === leftArrow ) { - index--; - } - - self.slideTo( index ); //Do the slide - }, - keyHandler = function (e) { - if (isSliding) return; - switch (e.which) { - case 39: - index++; - break; - case 37: - index--; - break; - default: return; - } - self.slideTo( index ); //Do the slide - }, - // touch events - toggleTouchEvents = function(toggle){ - toggle( element, touchEvents.move, touchMoveHandler, passiveHandler ); - toggle( element, touchEvents.end, touchEndHandler, passiveHandler ); - }, - touchDownHandler = function(e) { - if ( isTouch ) { return; } - - startXPosition = parseInt(e.touches[0].pageX); - - if ( element.contains(e[target]) ) { - isTouch = true; - toggleTouchEvents(on); - } - }, - touchMoveHandler = function(e) { - if ( !isTouch ) { e.preventDefault(); return; } - - currentXPosition = parseInt(e.touches[0].pageX); - - //cancel touch if more than one touches detected - if ( e.type === 'touchmove' && e.touches[length] > 1 ) { - e.preventDefault(); + var self = this, + vars, ops = {}, + slideCustomEvent, slidCustomEvent, + slides, leftArrow, rightArrow, indicator, indicators; + function pauseHandler() { + if ( ops.interval !==false && !hasClass(element,'paused') ) { + addClass(element,'paused'); + !vars.isSliding && ( clearInterval(vars.timer), vars.timer = null ); + } + } + function resumeHandler() { + if ( ops.interval !== false && hasClass(element,'paused') ) { + removeClass(element,'paused'); + !vars.isSliding && ( clearInterval(vars.timer), vars.timer = null ); + !vars.isSliding && self.cycle(); + } + } + function indicatorHandler(e) { + e.preventDefault(); + if (vars.isSliding) { return; } + var eventTarget = e.target; + if ( eventTarget && !hasClass(eventTarget,'active') && eventTarget.getAttribute('data-slide-to') ) { + vars.index = parseInt( eventTarget.getAttribute('data-slide-to'), 10 ); + } else { return false; } + self.slideTo( vars.index ); + } + function controlsHandler(e) { + e.preventDefault(); + if (vars.isSliding) { return; } + var eventTarget = e.currentTarget || e.srcElement; + if ( eventTarget === rightArrow ) { + vars.index++; + } else if ( eventTarget === leftArrow ) { + vars.index--; + } + self.slideTo( vars.index ); + } + function keyHandler(ref) { + var which = ref.which; + if (vars.isSliding) { return; } + switch (which) { + case 39: + vars.index++; + break; + case 37: + vars.index--; + break; + default: return; + } + self.slideTo( vars.index ); + } + function toggleEvents(action) { + if ( ops.pause && ops.interval ) { + action( element, mouseHoverEvents[0], pauseHandler ); + action( element, mouseHoverEvents[1], resumeHandler ); + action( element, touchEvents.start, pauseHandler, passiveHandler ); + action( element, touchEvents.end, resumeHandler, passiveHandler ); + } + slides.length > 1 && action( element, touchEvents.start, touchDownHandler, passiveHandler ); + rightArrow && action( rightArrow, 'click', controlsHandler ); + leftArrow && action( leftArrow, 'click', controlsHandler ); + indicator && action( indicator, 'click', indicatorHandler ); + ops.keyboard && action( window, 'keydown', keyHandler ); + } + function toggleTouchEvents(action) { + action( element, touchEvents.move, touchMoveHandler, passiveHandler ); + action( element, touchEvents.end, touchEndHandler, passiveHandler ); + } + function touchDownHandler(e) { + if ( vars.isTouch ) { return; } + vars.touchPosition.startX = e.changedTouches[0].pageX; + if ( element.contains(e.target) ) { + vars.isTouch = true; + toggleTouchEvents(on); + } + } + function touchMoveHandler(e) { + if ( !vars.isTouch ) { e.preventDefault(); return; } + vars.touchPosition.currentX = e.changedTouches[0].pageX; + if ( e.type === 'touchmove' && e.changedTouches.length > 1 ) { + e.preventDefault(); + return false; + } + } + function touchEndHandler (e) { + if ( !vars.isTouch || vars.isSliding ) { return } + vars.touchPosition.endX = vars.touchPosition.currentX || e.changedTouches[0].pageX; + if ( vars.isTouch ) { + if ( (!element.contains(e.target) || !element.contains(e.relatedTarget) ) + && Math.abs(vars.touchPosition.startX - vars.touchPosition.endX) < 75 ) { return false; + } else { + if ( vars.touchPosition.currentX < vars.touchPosition.startX ) { + vars.index++; + } else if ( vars.touchPosition.currentX > vars.touchPosition.startX ) { + vars.index--; + } + vars.isTouch = false; + self.slideTo(vars.index); } - }, - touchEndHandler = function(e) { - if ( !isTouch || isSliding ) { return } - - endXPosition = currentXPosition || parseInt( e.touches[0].pageX ); - - if ( isTouch ) { - if ( (!element.contains(e[target]) || !element.contains(e.relatedTarget) ) && Math.abs(startXPosition - endXPosition) < 75 ) { - return false; - } else { - if ( currentXPosition < startXPosition ) { - index++; - } else if ( currentXPosition > startXPosition ) { - index--; + toggleTouchEvents(off); + } + } + function setActivePage(pageIndex) { + Array.from(indicators).map(function (x){removeClass(x,'active');}); + indicators[pageIndex] && addClass(indicators[pageIndex], 'active'); + } + function transitionEndHandler(e){ + if (vars.touchPosition){ + var next = vars.index, + timeout = e && e.target !== slides[next] ? e.elapsedTime*1000+100 : 20, + activeItem = self.getActiveIndex(), + orientation = vars.direction === 'left' ? 'next' : 'prev'; + vars.isSliding && setTimeout(function () { + if (vars.touchPosition){ + vars.isSliding = false; + addClass(slides[next],'active'); + removeClass(slides[activeItem],'active'); + removeClass(slides[next],("carousel-item-" + orientation)); + removeClass(slides[next],("carousel-item-" + (vars.direction))); + removeClass(slides[activeItem],("carousel-item-" + (vars.direction))); + dispatchCustomEvent.call(element, slidCustomEvent); + if ( !document.hidden && ops.interval && !hasClass(element,'paused') ) { + self.cycle(); } - isTouch = false; - self.slideTo(index); } - toggleTouchEvents(off); - } - }, - - // private methods - isElementInScrollRange = function () { - var rect = element[getBoundingClientRect](), - viewportHeight = globalObject[innerHeight] || HTML[clientHeight] - return rect[top] <= viewportHeight && rect[bottom] >= 0; // bottom && top - }, - setActivePage = function( pageIndex ) { //indicators - for ( var i = 0, icl = indicators[length]; i < icl; i++ ) { - removeClass(indicators[i],active); - } - if (indicators[pageIndex]) addClass(indicators[pageIndex], active); - }; - - - // public methods - this.cycle = function() { - if (timer) { - clearInterval(timer); - timer = null; - } - - timer = setInterval(function() { - isElementInScrollRange() && (index++, self.slideTo( index ) ); - }, this[interval]); + }, timeout); + } + } + self.cycle = function () { + if (vars.timer) { + clearInterval(vars.timer); + vars.timer = null; + } + vars.timer = setInterval(function () { + var idx = vars.index || self.getActiveIndex(); + isElementInScrollRange(element) && (idx++, self.slideTo( idx ) ); + }, ops.interval); }; - this.slideTo = function( next ) { - if (isSliding) return; // when controled via methods, make sure to check again - - var activeItem = this.getActiveIndex(), // the current active - orientation; - - // first return if we're on the same item #227 + self.slideTo = function (next) { + if (vars.isSliding) { return; } + var activeItem = self.getActiveIndex(), orientation; if ( activeItem === next ) { return; - // or determine slideDirection - } else if ( (activeItem < next ) || (activeItem === 0 && next === total -1 ) ) { - slideDirection = self[direction] = left; // next - } else if ( (activeItem > next) || (activeItem === total - 1 && next === 0 ) ) { - slideDirection = self[direction] = right; // prev - } - - // find the right next index - if ( next < 0 ) { next = total - 1; } - else if ( next >= total ){ next = 0; } - - // update index - index = next; - - orientation = slideDirection === left ? 'next' : 'prev'; //determine type - bootstrapCustomEvent.call(element, slideEvent, component, slides[next]); // here we go with the slide - - isSliding = true; - clearInterval(timer); - timer = null; + } else if ( (activeItem < next ) || (activeItem === 0 && next === slides.length -1 ) ) { + vars.direction = 'left'; + } else if ( (activeItem > next) || (activeItem === slides.length - 1 && next === 0 ) ) { + vars.direction = 'right'; + } + if ( next < 0 ) { next = slides.length - 1; } + else if ( next >= slides.length ){ next = 0; } + orientation = vars.direction === 'left' ? 'next' : 'prev'; + slideCustomEvent = bootstrapCustomEvent('slide', 'carousel', slides[next]); + slidCustomEvent = bootstrapCustomEvent('slid', 'carousel', slides[next]); + dispatchCustomEvent.call(element, slideCustomEvent); + if (slideCustomEvent.defaultPrevented) { return; } + vars.index = next; + vars.isSliding = true; + clearInterval(vars.timer); + vars.timer = null; setActivePage( next ); - - if ( supportTransitions && hasClass(element,'slide') ) { - - addClass(slides[next],carouselItem +'-'+ orientation); - slides[next][offsetWidth]; - addClass(slides[next],carouselItem +'-'+ slideDirection); - addClass(slides[activeItem],carouselItem +'-'+ slideDirection); - - emulateTransitionEnd(slides[next], function(e) { - var timeout = e && e[target] !== slides[next] ? e.elapsedTime*1000+100 : 20; - - isSliding && setTimeout(function(){ - isSliding = false; - - addClass(slides[next],active); - removeClass(slides[activeItem],active); - - removeClass(slides[next],carouselItem +'-'+ orientation); - removeClass(slides[next],carouselItem +'-'+ slideDirection); - removeClass(slides[activeItem],carouselItem +'-'+ slideDirection); - - bootstrapCustomEvent.call(element, slidEvent, component, slides[next]); - - if ( !DOC.hidden && self[interval] && !hasClass(element,paused) ) { - self.cycle(); - } - }, timeout); - }); - + if ( getElementTransitionDuration(slides[next]) && hasClass(element,'slide') ) { + addClass(slides[next],("carousel-item-" + orientation)); + slides[next].offsetWidth; + addClass(slides[next],("carousel-item-" + (vars.direction))); + addClass(slides[activeItem],("carousel-item-" + (vars.direction))); + emulateTransitionEnd(slides[next], transitionEndHandler); } else { - addClass(slides[next],active); - slides[next][offsetWidth]; - removeClass(slides[activeItem],active); - setTimeout(function() { - isSliding = false; - if ( self[interval] && !hasClass(element,paused) ) { + addClass(slides[next],'active'); + slides[next].offsetWidth; + removeClass(slides[activeItem],'active'); + setTimeout(function () { + vars.isSliding = false; + if ( ops.interval && element && !hasClass(element,'paused') ) { self.cycle(); } - bootstrapCustomEvent.call(element, slidEvent, component, slides[next]); + dispatchCustomEvent.call(element, slidCustomEvent); }, 100 ); } }; - this.getActiveIndex = function () { - return slides[indexOf](getElementsByClassName(element,carouselItem+' active')[0]) || 0; + self.getActiveIndex = function () { return Array.from(slides).indexOf(element.getElementsByClassName('carousel-item active')[0]) || 0; }; + self.dispose = function () { + var itemClasses = ['left','right','prev','next']; + Array.from(slides).map(function (slide,idx) { + if (hasClass(slide,'active')){ + setActivePage( idx ); + } + itemClasses.map(function (cls) { return removeClass(slide,("carousel-item-" + cls)); }); + }); + clearInterval(vars.timer); + toggleEvents(off); + vars = {}; + delete element.Carousel; }; - - // init - if ( !(stringCarousel in element ) ) { // prevent adding event handlers twice - - if ( self[pause] && self[interval] ) { - on( element, mouseHover[0], pauseHandler ); - on( element, mouseHover[1], resumeHandler ); - on( element, touchEvents.start, pauseHandler, passiveHandler ); - on( element, touchEvents.end, resumeHandler, passiveHandler ); - } - - slides[length] > 1 && on( element, touchEvents.start, touchDownHandler, passiveHandler ); - - rightArrow && on( rightArrow, clickEvent, controlsHandler ); - leftArrow && on( leftArrow, clickEvent, controlsHandler ); - - indicator && on( indicator, clickEvent, indicatorHandler ); - self[keyboard] && on( globalObject, keydownEvent, keyHandler ); - - } - if (self.getActiveIndex()<0) { - slides[length] && addClass(slides[0],active); - indicators[length] && setActivePage(0); - } - - if ( self[interval] ){ self.cycle(); } - element[stringCarousel] = self; - }; - - // CAROUSEL DATA API - // ================= - supports[push]( [ stringCarousel, Carousel, '['+dataRide+'="carousel"]' ] ); - - - /* Native Javascript for Bootstrap 4 | Collapse - -----------------------------------------------*/ - - // COLLAPSE DEFINITION - // =================== - var Collapse = function( element, options ) { - - // initialization element - element = queryElement(element); - - // set options + vars = {}; + vars.direction = 'left'; + vars.index = 0; + vars.timer = null; + vars.isSliding = false; + vars.isTouch = false; + vars.touchPosition = { + startX : 0, + currentX : 0, + endX : 0 + }; + tryWrapper(function (){ + element = queryElement( element ); + element.Carousel && element.Carousel.dispose(); + var + intervalAttribute = element.getAttribute('data-interval'), + intervalOption = options.interval, + intervalData = intervalAttribute === 'false' ? 0 : parseInt(intervalAttribute), + pauseData = element.getAttribute('data-pause') === 'hover' || false, + keyboardData = element.getAttribute('data-keyboard') === 'true' || false; + slides = element.getElementsByClassName('carousel-item'); + leftArrow = element.getElementsByClassName('carousel-control-prev')[0]; + rightArrow = element.getElementsByClassName('carousel-control-next')[0]; + indicator = element.getElementsByClassName('carousel-indicators')[0]; + indicators = indicator && indicator.getElementsByTagName( "LI" ) || []; + ops.keyboard = options.keyboard === true || keyboardData; + ops.pause = (options.pause === 'hover' || pauseData) ? 'hover' : false; + ops.interval = typeof intervalOption === 'number' ? intervalOption + : intervalOption === false || intervalData === 0 || intervalData === false ? 0 + : isNaN(intervalData) ? 5000 + : intervalData; + if (slides.length < 2) { return; } + if ( !element.Carousel ) { + toggleEvents(on); + } + if (self.getActiveIndex()<0) { + slides.length && addClass(slides[0],'active'); + indicators.length && setActivePage(0); + } + if ( ops.interval ){ self.cycle(); } + element.Carousel = self; + },"BSN.Carousel"); + } + + function Collapse(element,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(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(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() { - 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(); } + var self = this; + var accordion = null, + collapse = null, + activeCollapse, + activeElement, + showCustomEvent, + shownCustomEvent, + hideCustomEvent, + hiddenCustomEvent; + function openAction(collapseElement, toggle) { + dispatchCustomEvent.call(collapseElement, showCustomEvent); + if ( showCustomEvent.defaultPrevented ) { return; } + collapseElement.isAnimating = true; + addClass(collapseElement,'collapsing'); + removeClass(collapseElement,'collapse'); + collapseElement.style.height = (collapseElement.scrollHeight) + "px"; + emulateTransitionEnd(collapseElement, function () { + collapseElement.isAnimating = false; + collapseElement.setAttribute('aria-expanded','true'); + toggle.setAttribute('aria-expanded','true'); + removeClass(collapseElement,'collapsing'); + addClass(collapseElement, 'collapse'); + addClass(collapseElement,'show'); + collapseElement.style.height = ''; + dispatchCustomEvent.call(collapseElement, shownCustomEvent); + }); + } + function closeAction(collapseElement, toggle) { + dispatchCustomEvent.call(collapseElement, hideCustomEvent); + if ( hideCustomEvent.defaultPrevented ) { return; } + collapseElement.isAnimating = true; + collapseElement.style.height = (collapseElement.scrollHeight) + "px"; + removeClass(collapseElement,'collapse'); + removeClass(collapseElement,'show'); + addClass(collapseElement,'collapsing'); + collapseElement.offsetWidth; + collapseElement.style.height = '0px'; + emulateTransitionEnd(collapseElement, function () { + collapseElement.isAnimating = false; + collapseElement.setAttribute('aria-expanded','false'); + toggle.setAttribute('aria-expanded','false'); + removeClass(collapseElement,'collapsing'); + addClass(collapseElement,'collapse'); + collapseElement.style.height = ''; + dispatchCustomEvent.call(collapseElement, hiddenCustomEvent); + }); + } + self.toggle = function (e) { + if (e && e.target.tagName === 'A' || element.tagName === 'A') {e.preventDefault();} + if (element.contains(e.target) || e.target === element) { + if (!hasClass(collapse,'show')) { self.show(); } + else { self.hide(); } + } }; - this.hide = function() { - if ( collapse[isAnimating] ) return; + self.hide = function () { + if ( collapse.isAnimating ) { return; } closeAction(collapse,element); - addClass(element,collapsed); + addClass(element,'collapsed'); }; - this.show = function() { + self.show = function () { if ( accordion ) { - activeCollapse = queryElement('.'+component+'.'+showClass,accordion); - activeElement = activeCollapse && (queryElement('['+dataTarget+'="#'+activeCollapse.id+'"]',accordion) - || queryElement('[href="#'+activeCollapse.id+'"]',accordion) ); + activeCollapse = accordion.getElementsByClassName("collapse show")[0]; + activeElement = activeCollapse && (queryElement(("[data-target=\"#" + (activeCollapse.id) + "\"]"),accordion) + || queryElement(("[href=\"#" + (activeCollapse.id) + "\"]"),accordion) ); } - - if ( !collapse[isAnimating] || activeCollapse && !activeCollapse[isAnimating] ) { + if ( !collapse.isAnimating ) { if ( activeElement && activeCollapse !== collapse ) { - closeAction(activeCollapse,activeElement); - addClass(activeElement,collapsed); + closeAction(activeCollapse,activeElement); + addClass(activeElement,'collapsed'); } openAction(collapse,element); - removeClass(element,collapsed); + 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( 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= 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; + position = (position === 'left' || position === 'right') && leftExceed && rightExceed ? 'top' : position; + position = position === 'top' && topExceed ? 'bottom' : position; + position = position === 'bottom' && bottomExceed ? 'top' : position; + position = position === 'left' && leftExceed ? 'right' : position; + position = position === 'right' && rightExceed ? 'left' : position; + var topPosition, + leftPosition, + arrowTop, + arrowLeft, + arrowWidth, + arrowHeight; + element.className.indexOf(position) === -1 && (element.className = element.className.replace(tipPositions,position)); + arrowWidth = arrow.offsetWidth; arrowHeight = arrow.offsetHeight; + if ( position === 'left' || position === 'right' ) { + if ( position === 'left' ) { + leftPosition = rect.left + scroll.x - elementDimensions.w - ( isPopover ? arrowWidth : 0 ); + } else { + leftPosition = rect.left + scroll.x + linkDimensions.w; + } + 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' ) { + if ( position === 'top') { + topPosition = rect.top + scroll.y - elementDimensions.h - ( isPopover ? arrowHeight : 0 ); + } else { + topPosition = rect.top + scroll.y + linkDimensions.h; + } + 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 ); + } + } + element.style.top = topPosition + 'px'; + element.style.left = leftPosition + 'px'; + arrowTop && (arrow.style.top = arrowTop + 'px'); + arrowLeft && (arrow.style.left = arrowLeft + 'px'); + } + + function Dropdown(element,option) { + var self = this, + showCustomEvent, + shownCustomEvent, + hideCustomEvent, + hiddenCustomEvent, + relatedTarget = null, + parent, menu, menuItems = [], + persist; + function preventEmptyAnchor(anchor) { + (anchor.href && anchor.href.slice(-1) === '#' || anchor.parentNode && anchor.parentNode.href + && anchor.parentNode.href.slice(-1) === '#') && this.preventDefault(); + } + function toggleDismiss() { + var action = element.open ? on : off; + action(document, 'click', dismissHandler); + action(document, 'keydown', preventScroll); + action(document, 'keyup', keyHandler); + action(document, 'focus', dismissHandler, true); + } + function dismissHandler(e) { + var eventTarget = e.target, + hasData = eventTarget && (eventTarget.getAttribute('data-toggle') + || eventTarget.parentNode && eventTarget.parentNode.getAttribute + && eventTarget.parentNode.getAttribute('data-toggle')); + if ( e.type === 'focus' && (eventTarget === element || eventTarget === menu || menu.contains(eventTarget) ) ) { + return; + } + if ( (eventTarget === menu || menu.contains(eventTarget)) && (persist || hasData) ) { return; } + else { + relatedTarget = eventTarget === element || element.contains(eventTarget) ? element : null; + self.hide(); + } + preventEmptyAnchor.call(e,eventTarget); + } + function clickHandler(e) { + relatedTarget = element; + self.show(); + preventEmptyAnchor.call(e,e.target); + } + function preventScroll(e) { + var key = e.which || e.keyCode; + if( key === 38 || key === 40 ) { e.preventDefault(); } + } + function keyHandler(ref) { + var which = ref.which; + var keyCode = ref.keyCode; + var key = which || keyCode, + activeItem = document.activeElement, 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 ? (idx1?idx-1:0) + : key === 40 ? (idx= topEdge && bottomEdge > scrollOffset; - - if ( !isActive && inside ) { - if ( !hasClass(item,active) ) { - addClass(item,active); - if (dropdownLink && !hasClass(dropdownLink,active) ) { - addClass(dropdownLink,active); - } - bootstrapCustomEvent.call(element, 'activate', 'scrollspy', items[index]); - } - } else if ( !inside ) { - if ( hasClass(item,active) ) { - removeClass(item,active); - if (dropdownLink && hasClass(dropdownLink,active) && !getElementsByClassName(item[parentNode],active).length ) { - removeClass(dropdownLink,active); - } + var self = this, + vars, + targetData, + offsetData, + spyTarget, + scrollTarget, + ops = {}; + function updateTargets(){ + var links = spyTarget.getElementsByTagName('A'); + if (vars.length !== links.length) { + vars.items = []; + vars.targets = []; + Array.from(links).map(function (link){ + var href = link.getAttribute('href'), + targetItem = href && href.charAt(0) === '#' && href.slice(-1) !== '#' && queryElement(href); + if ( targetItem ) { + vars.items.push(link); + vars.targets.push(targetItem); } - } else if ( !inside && !isActive || isActive && inside ) { - return; + }); + vars.length = links.length; + } + } + function updateItem(index) { + var item = vars.items[index], + targetItem = vars.targets[index], + dropmenu = hasClass(item,'dropdown-item') && item.closest('.dropdown-menu'), + dropLink = dropmenu && dropmenu.previousElementSibling, + nextSibling = item.nextElementSibling, + activeSibling = nextSibling && nextSibling.getElementsByClassName('active').length, + targetRect = vars.isWindow && targetItem.getBoundingClientRect(), + isActive = hasClass(item,'active') || false, + topEdge = (vars.isWindow ? targetRect.top + vars.scrollOffset : targetItem.offsetTop) - ops.offset, + bottomEdge = vars.isWindow ? targetRect.bottom + vars.scrollOffset - ops.offset + : vars.targets[index+1] ? vars.targets[index+1].offsetTop - ops.offset + : element.scrollHeight, + inside = activeSibling || vars.scrollOffset >= topEdge && bottomEdge > vars.scrollOffset; + if ( !isActive && inside ) { + addClass(item,'active'); + if (dropLink && !hasClass(dropLink,'active') ) { + addClass(dropLink,'active'); } - }, - updateItems = function(){ - scrollOffset = isWindow ? getScroll().y : element[scrollTop]; - for (var index=0, itl=items[length]; index 1 ) { - activeTab = activeTabs[activeTabs[length]-1]; - } - return activeTab; - }, - getActiveContent = function() { - return queryElement(getActiveTab()[getAttribute]('href')); - }, - // handler - clickHandler = function(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 + } else { + tabs.isAnimating = false; + } + shownCustomEvent = bootstrapCustomEvent('shown', 'tab', activeTab); + dispatchCustomEvent.call(next, shownCustomEvent); + } + function triggerHide() { + if (tabsContentContainer) { + activeContent.style.float = 'left'; + nextContent.style.float = 'left'; + containerHeight = activeContent.scrollHeight; + } + showCustomEvent = bootstrapCustomEvent('show', 'tab', activeTab); + hiddenCustomEvent = bootstrapCustomEvent('hidden', 'tab', next); + dispatchCustomEvent.call(next, showCustomEvent); + if ( showCustomEvent.defaultPrevented ) { return; } + addClass(nextContent,'active'); + removeClass(activeContent,'active'); + if (tabsContentContainer) { + nextHeight = nextContent.scrollHeight; + equalContents = nextHeight === containerHeight; + addClass(tabsContentContainer,'collapsing'); + tabsContentContainer.style.height = containerHeight + "px"; + tabsContentContainer.offsetHeight; + activeContent.style.float = ''; + nextContent.style.float = ''; + } + if ( hasClass(nextContent, 'fade') ) { + setTimeout(function () { + addClass(nextContent,'show'); + emulateTransitionEnd(nextContent,triggerShow); + },20); + } else { triggerShow(); } + dispatchCustomEvent.call(activeTab, hiddenCustomEvent); + } + function getActiveTab() { + var activeTabs = tabs.getElementsByClassName('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; + } + function getActiveContent() { return queryElement(getActiveTab().getAttribute('href')) } + function clickHandler(e) { + e.preventDefault(); + next = e.currentTarget; + !tabs.isAnimating && self.show(); + } + self.show = function () { 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); + if (!hasClass(next,'active')) { + nextContent = queryElement(next.getAttribute('href')); + activeTab = getActiveTab(); + activeContent = getActiveContent(); + hideCustomEvent = bootstrapCustomEvent( 'hide', 'tab', next); + dispatchCustomEvent.call(activeTab, hideCustomEvent); + if (hideCustomEvent.defaultPrevented) { return; } + tabs.isAnimating = true; + removeClass(activeTab,'active'); + activeTab.setAttribute('aria-selected','false'); + addClass(next,'active'); + next.setAttribute('aria-selected','true'); + if ( dropdown ) { + if ( !hasClass(element.parentNode,'dropdown-menu') ) { + if (hasClass(dropdown,'active')) { removeClass(dropdown,'active'); } + } else { + if (!hasClass(dropdown,'active')) { addClass(dropdown,'active'); } + } } + if (hasClass(activeContent, 'fade')) { + removeClass(activeContent,'show'); + emulateTransitionEnd(activeContent, triggerHide); + } else { triggerHide(); } } - - 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( element,options ) { - - // initialization element - element = queryElement(element); - - // set options + self.dispose = function () { + off(element, 'click', clickHandler); + delete element.Tab; + }; + tryWrapper(function (){ + element = queryElement(element); + element.Tab && element.Tab.dispose(); + heightData = element.getAttribute('data-height'); + tabs = element.closest('.nav'); + dropdown = tabs && queryElement('.dropdown-toggle',tabs); + animateHeight = !supportTransition || (options.height === false || heightData === 'false') ? false : true; + tabs.isAnimating = false; + if ( !element.Tab ) { + on(element, 'click', clickHandler); + } + if (animateHeight) { tabsContentContainer = getActiveContent().parentNode; } + element.Tab = self; + },'BSN.Tab'); + } + + function Toast(element,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() { - removeClass( toast, showing ); - addClass( toast, showClass ); - bootstrapCustomEvent.call(toast, shownEvent, component); - if (self[autohide]) { self.hide(); } - }, - hideComplete = function() { - addClass( toast, hide ); - bootstrapCustomEvent.call(toast, hiddenEvent, component); - }, - close = function() { - removeClass( toast,showClass ); - self[animation] ? emulateTransitionEnd(toast, hideComplete) : hideComplete(); - }, - disposeComplete = function(){ - 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(); + var self = this, + toast, timer = 0, + animationData, + autohideData, + delayData, + showCustomEvent, + hideCustomEvent, + shownCustomEvent, + hiddenCustomEvent, + ops = {}; + function showComplete() { + removeClass( toast, 'showing' ); + addClass( toast, 'show' ); + dispatchCustomEvent.call(toast,shownCustomEvent); + if (ops.autohide) { self.hide(); } + } + function hideComplete() { + addClass( toast, 'hide' ); + dispatchCustomEvent.call(toast,hiddenCustomEvent); + } + function close () { + removeClass( toast,'show' ); + ops.animation ? emulateTransitionEnd(toast, hideComplete) : hideComplete(); + } + function disposeComplete() { + clearTimeout(timer); + off(element, 'click', self.hide); + delete element.Toast; + } + self.show = function () { + if (toast && !hasClass(toast,'show')) { + dispatchCustomEvent.call(toast,showCustomEvent); + if (showCustomEvent.defaultPrevented) { return; } + ops.animation && addClass( toast,'fade' ); + removeClass( toast,'hide' ); + toast.offsetWidth; + addClass( toast,'showing' ); + ops.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]); - } + self.hide = function (noTimer) { + if (toast && hasClass(toast,'show')) { + dispatchCustomEvent.call(toast,hideCustomEvent); + if(hideCustomEvent.defaultPrevented) { return; } + noTimer ? close() : (timer = setTimeout( close, ops.delay)); } }; - this.dispose = function() { - if ( toast && hasClass(toast,showClass) ) { - removeClass( toast,showClass ); - self[animation] ? emulateTransitionEnd(toast, disposeComplete) : disposeComplete(); - } + self.dispose = function () { + ops.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( element,options ) { - - // initialization element - element = queryElement(element); - - // set options + tryWrapper(function (){ + element = queryElement(element); + element.Toast && element.Toast.dispose(); + toast = element.closest('.toast'); + animationData = element.getAttribute('data-animation'); + autohideData = element.getAttribute('data-autohide'); + delayData = element.getAttribute('data-delay'); + showCustomEvent = bootstrapCustomEvent('show', 'toast'); + hideCustomEvent = bootstrapCustomEvent('hide', 'toast'); + shownCustomEvent = bootstrapCustomEvent('shown', 'toast'); + hiddenCustomEvent = bootstrapCustomEvent('hidden', 'toast'); + ops.animation = options.animation === false || animationData === 'false' ? 0 : 1; + ops.autohide = options.autohide === false || autohideData === 'false' ? 0 : 1; + ops.delay = parseInt(options.delay || delayData) || 500; + if ( !element.Toast ) { + on(element, 'click', self.hide); + } + element.Toast = self; + },'BSN.Toast'); + } + + function Tooltip(element,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() { - self[container].removeChild(tooltip); - tooltip = null; timer = null; - }, - createToolTip = function() { - 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]); + var self = this, + tooltip = null, timer = 0, titleString, + animationData, + placementData, + delayData, + containerData, + showCustomEvent, + shownCustomEvent, + hideCustomEvent, + hiddenCustomEvent, + containerElement, + containerDataElement, + modal, + navbarFixedTop, + navbarFixedBottom, + placementClass, + ops = {}; + function getTitle() { + return element.getAttribute('title') + || element.getAttribute('data-title') + || element.getAttribute('data-original-title') + } + function removeToolTip() { + ops.container.removeChild(tooltip); + tooltip = null; timer = null; + } + function createToolTip() { + titleString = getTitle(); + if ( titleString ) { + tooltip = document.createElement('div'); + if (ops.template) { + var tooltipMarkup = document.createElement('div'); + tooltipMarkup.innerHTML = ops.template.trim(); + tooltip.className = tooltipMarkup.firstChild.className; + tooltip.innerHTML = tooltipMarkup.firstChild.innerHTML; + queryElement('.tooltip-inner',tooltip).innerHTML = titleString.trim(); + } else { + var tooltipArrow = document.createElement('div'); + addClass(tooltipArrow,'arrow'); + tooltip.appendChild(tooltipArrow); + var tooltipInner = document.createElement('div'); + addClass(tooltipInner,'tooltip-inner'); + tooltip.appendChild(tooltipInner); + tooltipInner.innerHTML = titleString; } - }, - updateTooltip = function () { - styleTip(element, tooltip, placementSetting, self[container]); - }, - showTooltip = function () { - !hasClass(tooltip,showClass) && ( addClass(tooltip,showClass) ); - }, - // triggers - showTrigger = function() { - on( globalObject, resizeEvent, self.hide, passiveHandler ); - bootstrapCustomEvent.call(element, shownEvent, component); - }, - hideTrigger = function() { - off( globalObject, resizeEvent, self.hide, passiveHandler ); - removeToolTip(); - bootstrapCustomEvent.call(element, hiddenEvent, component); - }; - - // public methods - this.show = function() { + tooltip.style.left = '0'; + tooltip.style.top = '0'; + tooltip.setAttribute('role','tooltip'); + !hasClass(tooltip, 'tooltip') && addClass(tooltip, 'tooltip'); + !hasClass(tooltip, ops.animation) && addClass(tooltip, ops.animation); + !hasClass(tooltip, placementClass) && addClass(tooltip, placementClass); + ops.container.appendChild(tooltip); + } + } + function updateTooltip() { + styleTip(element, tooltip, ops.placement, ops.container); + } + function showTooltip() { + !hasClass(tooltip,'show') && ( addClass(tooltip,'show') ); + } + function touchHandler(e){ + if ( tooltip && tooltip.contains(e.target) || e.target === element || element.contains(e.target)) ; else { + self.hide(); + } + } + function showAction() { + on( document, touchEvents.start, touchHandler, passiveHandler ); + on( window, 'resize', self.hide, passiveHandler ); + dispatchCustomEvent.call(element, shownCustomEvent); + } + function hideAction() { + off( document, touchEvents.start, touchHandler, passiveHandler ); + off( window, 'resize', self.hide, passiveHandler ); + removeToolTip(); + dispatchCustomEvent.call(element, hiddenCustomEvent); + } + function toggleEvents(action) { + action(element, mouseClickEvents.down, self.show); + action(element, mouseHoverEvents[0], self.show); + action(element, mouseHoverEvents[1], self.hide); + } + self.show = function () { clearTimeout(timer); - timer = setTimeout( function() { + timer = setTimeout( function () { if (tooltip === null) { - placementSetting = self[placement]; // we reset placement in all cases - // if(createToolTip() == false) return; + dispatchCustomEvent.call(element, showCustomEvent); + if (showCustomEvent.defaultPrevented) { return; } if(createToolTip() !== false) { updateTooltip(); showTooltip(); - bootstrapCustomEvent.call(element, showEvent, component); - !!self[animation] ? emulateTransitionEnd(tooltip, showTrigger) : showTrigger(); + !!ops.animation ? emulateTransitionEnd(tooltip, showAction) : showAction(); } } }, 20 ); }; - this.hide = function() { + self.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(); + timer = setTimeout( function () { + if (tooltip && hasClass(tooltip,'show')) { + dispatchCustomEvent.call(element, hideCustomEvent); + if (hideCustomEvent.defaultPrevented) { return; } + removeClass(tooltip,'show'); + !!ops.animation ? emulateTransitionEnd(tooltip, hideAction) : hideAction(); } - }, self[delay]); + }, ops.delay); }; - this.toggle = function() { - if (!tooltip) { self.show(); } + self.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( constructor, collection ){ - for (var i=0, l=collection[length]; i code { @@ -577,7 +571,7 @@ pre code { } } -.container-fluid { +.container-fluid, .container-sm, .container-md, .container-lg, .container-xl { width: 100%; padding-right: 15px; padding-left: 15px; @@ -585,6 +579,30 @@ pre code { margin-left: auto; } +@media (min-width: 576px) { + .container, .container-sm { + max-width: 540px; + } +} + +@media (min-width: 768px) { + .container, .container-sm, .container-md { + max-width: 720px; + } +} + +@media (min-width: 992px) { + .container, .container-sm, .container-md, .container-lg { + max-width: 960px; + } +} + +@media (min-width: 1200px) { + .container, .container-sm, .container-md, .container-lg, .container-xl { + max-width: 1140px; + } +} + .row { display: -ms-flexbox; display: flex; @@ -622,9 +640,46 @@ pre code { flex-basis: 0; -ms-flex-positive: 1; flex-grow: 1; + min-width: 0; max-width: 100%; } +.row-cols-1 > * { + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; +} + +.row-cols-2 > * { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; +} + +.row-cols-3 > * { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; +} + +.row-cols-4 > * { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; +} + +.row-cols-5 > * { + -ms-flex: 0 0 20%; + flex: 0 0 20%; + max-width: 20%; +} + +.row-cols-6 > * { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; +} + .col-auto { -ms-flex: 0 0 auto; flex: 0 0 auto; @@ -829,8 +884,39 @@ pre code { flex-basis: 0; -ms-flex-positive: 1; flex-grow: 1; + min-width: 0; + max-width: 100%; + } + .row-cols-sm-1 > * { + -ms-flex: 0 0 100%; + flex: 0 0 100%; max-width: 100%; } + .row-cols-sm-2 > * { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .row-cols-sm-3 > * { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .row-cols-sm-4 > * { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .row-cols-sm-5 > * { + -ms-flex: 0 0 20%; + flex: 0 0 20%; + max-width: 20%; + } + .row-cols-sm-6 > * { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } .col-sm-auto { -ms-flex: 0 0 auto; flex: 0 0 auto; @@ -1001,8 +1087,39 @@ pre code { flex-basis: 0; -ms-flex-positive: 1; flex-grow: 1; + min-width: 0; + max-width: 100%; + } + .row-cols-md-1 > * { + -ms-flex: 0 0 100%; + flex: 0 0 100%; max-width: 100%; } + .row-cols-md-2 > * { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .row-cols-md-3 > * { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .row-cols-md-4 > * { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .row-cols-md-5 > * { + -ms-flex: 0 0 20%; + flex: 0 0 20%; + max-width: 20%; + } + .row-cols-md-6 > * { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } .col-md-auto { -ms-flex: 0 0 auto; flex: 0 0 auto; @@ -1173,8 +1290,39 @@ pre code { flex-basis: 0; -ms-flex-positive: 1; flex-grow: 1; + min-width: 0; + max-width: 100%; + } + .row-cols-lg-1 > * { + -ms-flex: 0 0 100%; + flex: 0 0 100%; max-width: 100%; } + .row-cols-lg-2 > * { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .row-cols-lg-3 > * { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .row-cols-lg-4 > * { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .row-cols-lg-5 > * { + -ms-flex: 0 0 20%; + flex: 0 0 20%; + max-width: 20%; + } + .row-cols-lg-6 > * { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } .col-lg-auto { -ms-flex: 0 0 auto; flex: 0 0 auto; @@ -1345,8 +1493,39 @@ pre code { flex-basis: 0; -ms-flex-positive: 1; flex-grow: 1; + min-width: 0; + max-width: 100%; + } + .row-cols-xl-1 > * { + -ms-flex: 0 0 100%; + flex: 0 0 100%; max-width: 100%; } + .row-cols-xl-2 > * { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .row-cols-xl-3 > * { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .row-cols-xl-4 > * { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .row-cols-xl-5 > * { + -ms-flex: 0 0 20%; + flex: 0 0 20%; + max-width: 20%; + } + .row-cols-xl-6 > * { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } .col-xl-auto { -ms-flex: 0 0 auto; flex: 0 0 auto; @@ -1881,6 +2060,11 @@ pre code { border: 0; } +.form-control:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #495057; +} + .form-control:focus { color: #495057; background-color: #fff; @@ -1919,6 +2103,15 @@ pre code { opacity: 1; } +input[type="date"].form-control, +input[type="time"].form-control, +input[type="datetime-local"].form-control, +input[type="month"].form-control { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + select.form-control:focus::-ms-value { color: #495057; background-color: #fff; @@ -1955,9 +2148,9 @@ select.form-control:focus::-ms-value { .form-control-plaintext { display: block; width: 100%; - padding-top: 0.375rem; - padding-bottom: 0.375rem; + padding: 0.375rem 0; margin-bottom: 0; + font-size: 1rem; line-height: 1.5; color: #212529; background-color: transparent; @@ -2030,6 +2223,7 @@ textarea.form-control { margin-left: -1.25rem; } +.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label { color: #6c757d; } @@ -2077,12 +2271,19 @@ textarea.form-control { border-radius: 0.25rem; } +.was-validated :valid ~ .valid-feedback, +.was-validated :valid ~ .valid-tooltip, +.is-valid ~ .valid-feedback, +.is-valid ~ .valid-tooltip { + display: block; +} + .was-validated .form-control:valid, .form-control.is-valid { border-color: #28a745; padding-right: calc(1.5em + 0.75rem); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); background-repeat: no-repeat; - background-position: center right calc(0.375em + 0.1875rem); + background-position: right calc(0.375em + 0.1875rem) center; background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } @@ -2091,12 +2292,6 @@ textarea.form-control { box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); } -.was-validated .form-control:valid ~ .valid-feedback, -.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback, -.form-control.is-valid ~ .valid-tooltip { - display: block; -} - .was-validated textarea.form-control:valid, textarea.form-control.is-valid { padding-right: calc(1.5em + 0.75rem); background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); @@ -2104,8 +2299,8 @@ textarea.form-control { .was-validated .custom-select:valid, .custom-select.is-valid { border-color: #28a745; - padding-right: calc((1em + 0.75rem) * 3 / 4 + 1.75rem); - background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); + padding-right: calc(0.75em + 2.3125rem); + background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } .was-validated .custom-select:valid:focus, .custom-select.is-valid:focus { @@ -2113,18 +2308,6 @@ textarea.form-control { box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); } -.was-validated .custom-select:valid ~ .valid-feedback, -.was-validated .custom-select:valid ~ .valid-tooltip, .custom-select.is-valid ~ .valid-feedback, -.custom-select.is-valid ~ .valid-tooltip { - display: block; -} - -.was-validated .form-control-file:valid ~ .valid-feedback, -.was-validated .form-control-file:valid ~ .valid-tooltip, .form-control-file.is-valid ~ .valid-feedback, -.form-control-file.is-valid ~ .valid-tooltip { - display: block; -} - .was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { color: #28a745; } @@ -2143,12 +2326,6 @@ textarea.form-control { border-color: #28a745; } -.was-validated .custom-control-input:valid ~ .valid-feedback, -.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback, -.custom-control-input.is-valid ~ .valid-tooltip { - display: block; -} - .was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before { border-color: #34ce57; background-color: #34ce57; @@ -2166,12 +2343,6 @@ textarea.form-control { border-color: #28a745; } -.was-validated .custom-file-input:valid ~ .valid-feedback, -.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback, -.custom-file-input.is-valid ~ .valid-tooltip { - display: block; -} - .was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label { border-color: #28a745; box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); @@ -2200,12 +2371,19 @@ textarea.form-control { border-radius: 0.25rem; } +.was-validated :invalid ~ .invalid-feedback, +.was-validated :invalid ~ .invalid-tooltip, +.is-invalid ~ .invalid-feedback, +.is-invalid ~ .invalid-tooltip { + display: block; +} + .was-validated .form-control:invalid, .form-control.is-invalid { border-color: #dc3545; padding-right: calc(1.5em + 0.75rem); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E"); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); background-repeat: no-repeat; - background-position: center right calc(0.375em + 0.1875rem); + background-position: right calc(0.375em + 0.1875rem) center; background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } @@ -2214,12 +2392,6 @@ textarea.form-control { box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); } -.was-validated .form-control:invalid ~ .invalid-feedback, -.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback, -.form-control.is-invalid ~ .invalid-tooltip { - display: block; -} - .was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { padding-right: calc(1.5em + 0.75rem); background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); @@ -2227,8 +2399,8 @@ textarea.form-control { .was-validated .custom-select:invalid, .custom-select.is-invalid { border-color: #dc3545; - padding-right: calc((1em + 0.75rem) * 3 / 4 + 1.75rem); - background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); + padding-right: calc(0.75em + 2.3125rem); + background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); } .was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus { @@ -2236,18 +2408,6 @@ textarea.form-control { box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); } -.was-validated .custom-select:invalid ~ .invalid-feedback, -.was-validated .custom-select:invalid ~ .invalid-tooltip, .custom-select.is-invalid ~ .invalid-feedback, -.custom-select.is-invalid ~ .invalid-tooltip { - display: block; -} - -.was-validated .form-control-file:invalid ~ .invalid-feedback, -.was-validated .form-control-file:invalid ~ .invalid-tooltip, .form-control-file.is-invalid ~ .invalid-feedback, -.form-control-file.is-invalid ~ .invalid-tooltip { - display: block; -} - .was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { color: #dc3545; } @@ -2266,12 +2426,6 @@ textarea.form-control { border-color: #dc3545; } -.was-validated .custom-control-input:invalid ~ .invalid-feedback, -.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback, -.custom-control-input.is-invalid ~ .invalid-tooltip { - display: block; -} - .was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before { border-color: #e4606d; background-color: #e4606d; @@ -2289,12 +2443,6 @@ textarea.form-control { border-color: #dc3545; } -.was-validated .custom-file-input:invalid ~ .invalid-feedback, -.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback, -.custom-file-input.is-invalid ~ .invalid-tooltip { - display: block; -} - .was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label { border-color: #dc3545; box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); @@ -2414,6 +2562,10 @@ textarea.form-control { opacity: 0.65; } +.btn:not(:disabled):not(.disabled) { + cursor: pointer; +} + a.btn.disabled, fieldset:disabled a.btn { pointer-events: none; @@ -2432,6 +2584,9 @@ fieldset:disabled a.btn { } .btn-primary:focus, .btn-primary.focus { + color: #fff; + background-color: #0069d9; + border-color: #0062cc; box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5); } @@ -2466,6 +2621,9 @@ fieldset:disabled a.btn { } .btn-secondary:focus, .btn-secondary.focus { + color: #fff; + background-color: #5a6268; + border-color: #545b62; box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5); } @@ -2500,6 +2658,9 @@ fieldset:disabled a.btn { } .btn-success:focus, .btn-success.focus { + color: #fff; + background-color: #218838; + border-color: #1e7e34; box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5); } @@ -2534,6 +2695,9 @@ fieldset:disabled a.btn { } .btn-info:focus, .btn-info.focus { + color: #fff; + background-color: #138496; + border-color: #117a8b; box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5); } @@ -2568,6 +2732,9 @@ fieldset:disabled a.btn { } .btn-warning:focus, .btn-warning.focus { + color: #212529; + background-color: #e0a800; + border-color: #d39e00; box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5); } @@ -2602,6 +2769,9 @@ fieldset:disabled a.btn { } .btn-danger:focus, .btn-danger.focus { + color: #fff; + background-color: #c82333; + border-color: #bd2130; box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5); } @@ -2636,6 +2806,9 @@ fieldset:disabled a.btn { } .btn-light:focus, .btn-light.focus { + color: #212529; + background-color: #e2e6ea; + border-color: #dae0e5; box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5); } @@ -2670,6 +2843,9 @@ fieldset:disabled a.btn { } .btn-dark:focus, .btn-dark.focus { + color: #fff; + background-color: #23272b; + border-color: #1d2124; box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5); } @@ -2960,7 +3136,6 @@ fieldset:disabled a.btn { .btn-link:focus, .btn-link.focus { text-decoration: underline; - box-shadow: none; } .btn-link:disabled, .btn-link.disabled { @@ -3422,6 +3597,7 @@ input[type="button"].btn-block { -ms-flex: 1 1 auto; flex: 1 1 auto; width: 1%; + min-width: 0; margin-bottom: 0; } @@ -3613,7 +3789,10 @@ input[type="button"].btn-block { .custom-control-input { position: absolute; + left: 0; z-index: -1; + width: 1rem; + height: 1.25rem; opacity: 0; } @@ -3637,11 +3816,11 @@ input[type="button"].btn-block { border-color: #b3d7ff; } -.custom-control-input:disabled ~ .custom-control-label { +.custom-control-input[disabled] ~ .custom-control-label, .custom-control-input:disabled ~ .custom-control-label { color: #6c757d; } -.custom-control-input:disabled ~ .custom-control-label::before { +.custom-control-input[disabled] ~ .custom-control-label::before, .custom-control-input:disabled ~ .custom-control-label::before { background-color: #e9ecef; } @@ -3680,7 +3859,7 @@ input[type="button"].btn-block { } .custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e"); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e"); } .custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before { @@ -3689,7 +3868,7 @@ input[type="button"].btn-block { } .custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e"); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e"); } .custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before { @@ -3705,7 +3884,7 @@ input[type="button"].btn-block { } .custom-radio .custom-control-input:checked ~ .custom-control-label::after { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); } .custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before { @@ -3761,8 +3940,7 @@ input[type="button"].btn-block { line-height: 1.5; color: #495057; vertical-align: middle; - background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px; - background-color: #fff; + background: #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px; border: 1px solid #ced4da; border-radius: 0.25rem; -webkit-appearance: none; @@ -3796,6 +3974,11 @@ input[type="button"].btn-block { display: none; } +.custom-select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #495057; +} + .custom-select-sm { height: calc(1.5em + 0.5rem + 2px); padding-top: 0.25rem; @@ -3834,6 +4017,7 @@ input[type="button"].btn-block { box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } +.custom-file-input[disabled] ~ .custom-file-label, .custom-file-input:disabled ~ .custom-file-label { background-color: #e9ecef; } @@ -3881,7 +4065,7 @@ input[type="button"].btn-block { .custom-range { width: 100%; - height: calc(1rem + 0.4rem); + height: 1.4rem; padding: 0; background-color: transparent; -webkit-appearance: none; @@ -3916,6 +4100,7 @@ input[type="button"].btn-block { background-color: #007bff; border: 0; border-radius: 1rem; + -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -webkit-appearance: none; appearance: none; @@ -3923,6 +4108,7 @@ input[type="button"].btn-block { @media (prefers-reduced-motion: reduce) { .custom-range::-webkit-slider-thumb { + -webkit-transition: none; transition: none; } } @@ -3947,6 +4133,7 @@ input[type="button"].btn-block { background-color: #007bff; border: 0; border-radius: 1rem; + -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -moz-appearance: none; appearance: none; @@ -3954,6 +4141,7 @@ input[type="button"].btn-block { @media (prefers-reduced-motion: reduce) { .custom-range::-moz-range-thumb { + -moz-transition: none; transition: none; } } @@ -3981,12 +4169,14 @@ input[type="button"].btn-block { background-color: #007bff; border: 0; border-radius: 1rem; + -ms-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; appearance: none; } @media (prefers-reduced-motion: reduce) { .custom-range::-ms-thumb { + -ms-transition: none; transition: none; } } @@ -4157,8 +4347,8 @@ input[type="button"].btn-block { padding: 0.5rem 1rem; } -.navbar > .container, -.navbar > .container-fluid { +.navbar .container, +.navbar .container-fluid, .navbar .container-sm, .navbar .container-md, .navbar .container-lg, .navbar .container-xl { display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; @@ -4243,7 +4433,7 @@ input[type="button"].btn-block { @media (max-width: 575.98px) { .navbar-expand-sm > .container, - .navbar-expand-sm > .container-fluid { + .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl { padding-right: 0; padding-left: 0; } @@ -4268,7 +4458,7 @@ input[type="button"].btn-block { padding-left: 0.5rem; } .navbar-expand-sm > .container, - .navbar-expand-sm > .container-fluid { + .navbar-expand-sm > .container-fluid, .navbar-expand-sm > .container-sm, .navbar-expand-sm > .container-md, .navbar-expand-sm > .container-lg, .navbar-expand-sm > .container-xl { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } @@ -4285,7 +4475,7 @@ input[type="button"].btn-block { @media (max-width: 767.98px) { .navbar-expand-md > .container, - .navbar-expand-md > .container-fluid { + .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl { padding-right: 0; padding-left: 0; } @@ -4310,7 +4500,7 @@ input[type="button"].btn-block { padding-left: 0.5rem; } .navbar-expand-md > .container, - .navbar-expand-md > .container-fluid { + .navbar-expand-md > .container-fluid, .navbar-expand-md > .container-sm, .navbar-expand-md > .container-md, .navbar-expand-md > .container-lg, .navbar-expand-md > .container-xl { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } @@ -4327,7 +4517,7 @@ input[type="button"].btn-block { @media (max-width: 991.98px) { .navbar-expand-lg > .container, - .navbar-expand-lg > .container-fluid { + .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl { padding-right: 0; padding-left: 0; } @@ -4352,7 +4542,7 @@ input[type="button"].btn-block { padding-left: 0.5rem; } .navbar-expand-lg > .container, - .navbar-expand-lg > .container-fluid { + .navbar-expand-lg > .container-fluid, .navbar-expand-lg > .container-sm, .navbar-expand-lg > .container-md, .navbar-expand-lg > .container-lg, .navbar-expand-lg > .container-xl { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } @@ -4369,7 +4559,7 @@ input[type="button"].btn-block { @media (max-width: 1199.98px) { .navbar-expand-xl > .container, - .navbar-expand-xl > .container-fluid { + .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl { padding-right: 0; padding-left: 0; } @@ -4394,7 +4584,7 @@ input[type="button"].btn-block { padding-left: 0.5rem; } .navbar-expand-xl > .container, - .navbar-expand-xl > .container-fluid { + .navbar-expand-xl > .container-fluid, .navbar-expand-xl > .container-sm, .navbar-expand-xl > .container-md, .navbar-expand-xl > .container-lg, .navbar-expand-xl > .container-xl { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } @@ -4417,7 +4607,7 @@ input[type="button"].btn-block { } .navbar-expand > .container, -.navbar-expand > .container-fluid { +.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl { padding-right: 0; padding-left: 0; } @@ -4437,7 +4627,7 @@ input[type="button"].btn-block { } .navbar-expand > .container, -.navbar-expand > .container-fluid { +.navbar-expand > .container-fluid, .navbar-expand > .container-sm, .navbar-expand > .container-md, .navbar-expand > .container-lg, .navbar-expand > .container-xl { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } @@ -4486,7 +4676,7 @@ input[type="button"].btn-block { } .navbar-light .navbar-toggler-icon { - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); } .navbar-light .navbar-text { @@ -4534,7 +4724,7 @@ input[type="button"].btn-block { } .navbar-dark .navbar-toggler-icon { - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); } .navbar-dark .navbar-text { @@ -4568,19 +4758,27 @@ input[type="button"].btn-block { margin-left: 0; } -.card > .list-group:first-child .list-group-item:first-child { - border-top-left-radius: 0.25rem; - border-top-right-radius: 0.25rem; +.card > .list-group { + border-top: inherit; + border-bottom: inherit; } -.card > .list-group:last-child .list-group-item:last-child { - border-bottom-right-radius: 0.25rem; - border-bottom-left-radius: 0.25rem; +.card > .list-group:first-child { + border-top-width: 0; + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} + +.card > .list-group:last-child { + border-bottom-width: 0; + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); } .card-body { -ms-flex: 1 1 auto; flex: 1 1 auto; + min-height: 1px; padding: 1.25rem; } @@ -4651,67 +4849,56 @@ input[type="button"].btn-block { padding: 1.25rem; } -.card-img { +.card-img, +.card-img-top, +.card-img-bottom { + -ms-flex-negative: 0; + flex-shrink: 0; width: 100%; - border-radius: calc(0.25rem - 1px); } +.card-img, .card-img-top { - width: 100%; border-top-left-radius: calc(0.25rem - 1px); border-top-right-radius: calc(0.25rem - 1px); } +.card-img, .card-img-bottom { - width: 100%; border-bottom-right-radius: calc(0.25rem - 1px); border-bottom-left-radius: calc(0.25rem - 1px); } -.card-deck { - display: -ms-flexbox; - display: flex; - -ms-flex-direction: column; - flex-direction: column; -} - .card-deck .card { margin-bottom: 15px; } @media (min-width: 576px) { .card-deck { + display: -ms-flexbox; + display: flex; -ms-flex-flow: row wrap; flex-flow: row wrap; margin-right: -15px; margin-left: -15px; } .card-deck .card { - display: -ms-flexbox; - display: flex; -ms-flex: 1 0 0%; flex: 1 0 0%; - -ms-flex-direction: column; - flex-direction: column; margin-right: 15px; margin-bottom: 0; margin-left: 15px; } } -.card-group { - display: -ms-flexbox; - display: flex; - -ms-flex-direction: column; - flex-direction: column; -} - .card-group > .card { margin-bottom: 15px; } @media (min-width: 576px) { .card-group { + display: -ms-flexbox; + display: flex; -ms-flex-flow: row wrap; flex-flow: row wrap; } @@ -4775,27 +4962,19 @@ input[type="button"].btn-block { overflow: hidden; } -.accordion > .card:not(:first-of-type) .card-header:first-child { - border-radius: 0; -} - -.accordion > .card:not(:first-of-type):not(:last-of-type) { - border-bottom: 0; - border-radius: 0; -} - -.accordion > .card:first-of-type { +.accordion > .card:not(:last-of-type) { border-bottom: 0; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } -.accordion > .card:last-of-type { +.accordion > .card:not(:first-of-type) { border-top-left-radius: 0; border-top-right-radius: 0; } -.accordion > .card .card-header { +.accordion > .card > .card-header { + border-radius: 0; margin-bottom: -1px; } @@ -4811,6 +4990,11 @@ input[type="button"].btn-block { border-radius: 0.25rem; } +.breadcrumb-item { + display: -ms-flexbox; + display: flex; +} + .breadcrumb-item + .breadcrumb-item { padding-left: 0.5rem; } @@ -4862,7 +5046,7 @@ input[type="button"].btn-block { } .page-link:focus { - z-index: 2; + z-index: 3; outline: 0; box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); } @@ -4879,7 +5063,7 @@ input[type="button"].btn-block { } .page-item.active .page-link { - z-index: 1; + z-index: 3; color: #fff; background-color: #007bff; border-color: #007bff; @@ -5265,6 +5449,7 @@ a.badge-dark:focus, a.badge-dark.focus { display: flex; height: 1rem; overflow: hidden; + line-height: 0; font-size: 0.75rem; background-color: #e9ecef; border-radius: 0.25rem; @@ -5277,6 +5462,7 @@ a.badge-dark:focus, a.badge-dark.focus { flex-direction: column; -ms-flex-pack: center; justify-content: center; + overflow: hidden; color: #fff; text-align: center; white-space: nowrap; @@ -5326,6 +5512,7 @@ a.badge-dark:focus, a.badge-dark.focus { flex-direction: column; padding-left: 0; margin-bottom: 0; + border-radius: 0.25rem; } .list-group-item-action { @@ -5350,20 +5537,18 @@ a.badge-dark:focus, a.badge-dark.focus { position: relative; display: block; padding: 0.75rem 1.25rem; - margin-bottom: -1px; background-color: #fff; border: 1px solid rgba(0, 0, 0, 0.125); } .list-group-item:first-child { - border-top-left-radius: 0.25rem; - border-top-right-radius: 0.25rem; + border-top-left-radius: inherit; + border-top-right-radius: inherit; } .list-group-item:last-child { - margin-bottom: 0; - border-bottom-right-radius: 0.25rem; - border-bottom-left-radius: 0.25rem; + border-bottom-right-radius: inherit; + border-bottom-left-radius: inherit; } .list-group-item.disabled, .list-group-item:disabled { @@ -5379,49 +5564,68 @@ a.badge-dark:focus, a.badge-dark.focus { border-color: #007bff; } +.list-group-item + .list-group-item { + border-top-width: 0; +} + +.list-group-item + .list-group-item.active { + margin-top: -1px; + border-top-width: 1px; +} + .list-group-horizontal { -ms-flex-direction: row; flex-direction: row; } -.list-group-horizontal .list-group-item { - margin-right: -1px; - margin-bottom: 0; -} - -.list-group-horizontal .list-group-item:first-child { - border-top-left-radius: 0.25rem; +.list-group-horizontal > .list-group-item:first-child { border-bottom-left-radius: 0.25rem; border-top-right-radius: 0; } -.list-group-horizontal .list-group-item:last-child { - margin-right: 0; +.list-group-horizontal > .list-group-item:last-child { border-top-right-radius: 0.25rem; - border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0; } +.list-group-horizontal > .list-group-item.active { + margin-top: 0; +} + +.list-group-horizontal > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; +} + +.list-group-horizontal > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; +} + @media (min-width: 576px) { .list-group-horizontal-sm { -ms-flex-direction: row; flex-direction: row; } - .list-group-horizontal-sm .list-group-item { - margin-right: -1px; - margin-bottom: 0; - } - .list-group-horizontal-sm .list-group-item:first-child { - border-top-left-radius: 0.25rem; + .list-group-horizontal-sm > .list-group-item:first-child { border-bottom-left-radius: 0.25rem; border-top-right-radius: 0; } - .list-group-horizontal-sm .list-group-item:last-child { - margin-right: 0; + .list-group-horizontal-sm > .list-group-item:last-child { border-top-right-radius: 0.25rem; - border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0; } + .list-group-horizontal-sm > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } } @media (min-width: 768px) { @@ -5429,21 +5633,25 @@ a.badge-dark:focus, a.badge-dark.focus { -ms-flex-direction: row; flex-direction: row; } - .list-group-horizontal-md .list-group-item { - margin-right: -1px; - margin-bottom: 0; - } - .list-group-horizontal-md .list-group-item:first-child { - border-top-left-radius: 0.25rem; + .list-group-horizontal-md > .list-group-item:first-child { border-bottom-left-radius: 0.25rem; border-top-right-radius: 0; } - .list-group-horizontal-md .list-group-item:last-child { - margin-right: 0; + .list-group-horizontal-md > .list-group-item:last-child { border-top-right-radius: 0.25rem; - border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0; } + .list-group-horizontal-md > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } } @media (min-width: 992px) { @@ -5451,21 +5659,25 @@ a.badge-dark:focus, a.badge-dark.focus { -ms-flex-direction: row; flex-direction: row; } - .list-group-horizontal-lg .list-group-item { - margin-right: -1px; - margin-bottom: 0; - } - .list-group-horizontal-lg .list-group-item:first-child { - border-top-left-radius: 0.25rem; + .list-group-horizontal-lg > .list-group-item:first-child { border-bottom-left-radius: 0.25rem; border-top-right-radius: 0; } - .list-group-horizontal-lg .list-group-item:last-child { - margin-right: 0; + .list-group-horizontal-lg > .list-group-item:last-child { border-top-right-radius: 0.25rem; - border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0; } + .list-group-horizontal-lg > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } } @media (min-width: 1200px) { @@ -5473,40 +5685,37 @@ a.badge-dark:focus, a.badge-dark.focus { -ms-flex-direction: row; flex-direction: row; } - .list-group-horizontal-xl .list-group-item { - margin-right: -1px; - margin-bottom: 0; - } - .list-group-horizontal-xl .list-group-item:first-child { - border-top-left-radius: 0.25rem; + .list-group-horizontal-xl > .list-group-item:first-child { border-bottom-left-radius: 0.25rem; border-top-right-radius: 0; } - .list-group-horizontal-xl .list-group-item:last-child { - margin-right: 0; + .list-group-horizontal-xl > .list-group-item:last-child { border-top-right-radius: 0.25rem; - border-bottom-right-radius: 0.25rem; border-bottom-left-radius: 0; } + .list-group-horizontal-xl > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } } -.list-group-flush .list-group-item { - border-right: 0; - border-left: 0; +.list-group-flush { border-radius: 0; } -.list-group-flush .list-group-item:last-child { - margin-bottom: -1px; +.list-group-flush > .list-group-item { + border-width: 0 0 1px; } -.list-group-flush:first-child .list-group-item:first-child { - border-top: 0; -} - -.list-group-flush:last-child .list-group-item:last-child { - margin-bottom: 0; - border-bottom: 0; +.list-group-flush > .list-group-item:last-child { + border-bottom-width: 0; } .list-group-item-primary { @@ -5660,9 +5869,6 @@ button.close { padding: 0; background-color: transparent; border: 0; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; } a.close.disabled { @@ -5763,6 +5969,11 @@ a.close.disabled { transform: none; } +.modal.modal-static .modal-dialog { + -webkit-transform: scale(1.02); + transform: scale(1.02); +} + .modal-dialog-scrollable { display: -ms-flexbox; display: flex; @@ -5795,6 +6006,9 @@ a.close.disabled { .modal-dialog-centered::before { display: block; height: calc(100vh - 1rem); + height: -webkit-min-content; + height: -moz-min-content; + height: min-content; content: ""; } @@ -5856,8 +6070,8 @@ a.close.disabled { justify-content: space-between; padding: 1rem 1rem; border-bottom: 1px solid #dee2e6; - border-top-left-radius: 0.3rem; - border-top-right-radius: 0.3rem; + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); } .modal-header .close { @@ -5880,22 +6094,20 @@ a.close.disabled { .modal-footer { display: -ms-flexbox; display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; -ms-flex-align: center; align-items: center; -ms-flex-pack: end; justify-content: flex-end; - padding: 1rem; + padding: 0.75rem; border-top: 1px solid #dee2e6; - border-bottom-right-radius: 0.3rem; - border-bottom-left-radius: 0.3rem; + border-bottom-right-radius: calc(0.3rem - 1px); + border-bottom-left-radius: calc(0.3rem - 1px); } -.modal-footer > :not(:first-child) { - margin-left: .25rem; -} - -.modal-footer > :not(:last-child) { - margin-right: .25rem; +.modal-footer > * { + margin: 0.25rem; } .modal-scrollbar-measure { @@ -5922,6 +6134,9 @@ a.close.disabled { } .modal-dialog-centered::before { height: calc(100vh - 3.5rem); + height: -webkit-min-content; + height: -moz-min-content; + height: min-content; } .modal-sm { max-width: 300px; @@ -6102,7 +6317,7 @@ a.close.disabled { } .bs-popover-top > .arrow, .bs-popover-auto[x-placement^="top"] > .arrow { - bottom: calc((0.5rem + 1px) * -1); + bottom: calc(-0.5rem - 1px); } .bs-popover-top > .arrow::before, .bs-popover-auto[x-placement^="top"] > .arrow::before { @@ -6122,7 +6337,7 @@ a.close.disabled { } .bs-popover-right > .arrow, .bs-popover-auto[x-placement^="right"] > .arrow { - left: calc((0.5rem + 1px) * -1); + left: calc(-0.5rem - 1px); width: 0.5rem; height: 1rem; margin: 0.3rem 0; @@ -6145,7 +6360,7 @@ a.close.disabled { } .bs-popover-bottom > .arrow, .bs-popover-auto[x-placement^="bottom"] > .arrow { - top: calc((0.5rem + 1px) * -1); + top: calc(-0.5rem - 1px); } .bs-popover-bottom > .arrow::before, .bs-popover-auto[x-placement^="bottom"] > .arrow::before { @@ -6176,7 +6391,7 @@ a.close.disabled { } .bs-popover-left > .arrow, .bs-popover-auto[x-placement^="left"] > .arrow { - right: calc((0.5rem + 1px) * -1); + right: calc(-0.5rem - 1px); width: 0.5rem; height: 1rem; margin: 0.3rem 0; @@ -6289,7 +6504,7 @@ a.close.disabled { .carousel-fade .active.carousel-item-right { z-index: 0; opacity: 0; - transition: 0s 0.6s opacity; + transition: opacity 0s 0.6s; } @media (prefers-reduced-motion: reduce) { @@ -6351,11 +6566,11 @@ a.close.disabled { } .carousel-control-prev-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e"); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e"); } .carousel-control-next-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e"); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e"); } .carousel-indicators { @@ -6453,6 +6668,8 @@ a.close.disabled { } 50% { opacity: 1; + -webkit-transform: none; + transform: none; } } @@ -6463,6 +6680,8 @@ a.close.disabled { } 50% { opacity: 1; + -webkit-transform: none; + transform: none; } } @@ -7748,6 +7967,27 @@ button.bg-dark:focus { } } +.user-select-all { + -webkit-user-select: all !important; + -moz-user-select: all !important; + -ms-user-select: all !important; + user-select: all !important; +} + +.user-select-auto { + -webkit-user-select: auto !important; + -moz-user-select: auto !important; + -ms-user-select: auto !important; + user-select: auto !important; +} + +.user-select-none { + -webkit-user-select: none !important; + -moz-user-select: none !important; + -ms-user-select: none !important; + user-select: none !important; +} + .overflow-auto { overflow: auto !important; } @@ -7807,6 +8047,7 @@ button.bg-dark:focus { width: 1px; height: 1px; padding: 0; + margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; @@ -7902,18 +8143,6 @@ button.bg-dark:focus { height: 100vh !important; } -.stretched-link::after { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1; - pointer-events: auto; - content: ""; - background-color: rgba(0, 0, 0, 0); -} - .m-0 { margin: 0 !important; } @@ -9726,6 +9955,18 @@ button.bg-dark:focus { } } +.stretched-link::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + pointer-events: auto; + content: ""; + background-color: rgba(0, 0, 0, 0); +} + .text-monospace { font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !important; } @@ -9941,8 +10182,7 @@ a.text-dark:hover, a.text-dark:focus { } .text-break { - word-break: break-word !important; - overflow-wrap: break-word !important; + word-wrap: break-word !important; } .text-reset { @@ -10035,3 +10275,4 @@ a.text-dark:hover, a.text-dark:focus { border-color: #dee2e6; } } +/*# sourceMappingURL=bootstrap.css.map */ \ No newline at end of file diff --git a/src/static/templates/admin/base.hbs b/src/static/templates/admin/base.hbs index a7270b9c..c9cd40dc 100644 --- a/src/static/templates/admin/base.hbs +++ b/src/static/templates/admin/base.hbs @@ -1,40 +1,26 @@ - - - + + + Bitwarden_rs Admin Panel - - - - + + + + - \ No newline at end of file diff --git a/src/static/templates/admin/users.hbs b/src/static/templates/admin/users.hbs index d3e12f78..758031fc 100644 --- a/src/static/templates/admin/users.hbs +++ b/src/static/templates/admin/users.hbs @@ -2,57 +2,61 @@
Registered Users
-
- {{#each users}} -
- -
-
-
+ + +
+ + + + + + + + + + + + {{#each users}} + + + + + + + + {{/each}} + +
UserItemsOrganizationsActions
{{Name}} - {{#if TwoFactorEnabled}} - 2FA - {{/if}} - {{#case _Status 1}} - Invited - {{/case}} - {{Email}} + {{Email}} + + {{#if TwoFactorEnabled}} + 2FA + {{/if}} + {{#case _Status 1}} + Invited + {{/case}} {{#if EmailVerified}} - Verified + Verified {{/if}} - -
- Personal Items: - - {{cipher_count}} - -
-
- Organizations: - - {{#each Organizations}} - {{Name}} - {{/each}} - -
-
+
+ {{cipher_count}} + + {{#each Organizations}} + {{Name}} + {{/each}} + {{#if TwoFactorEnabled}} - Remove all 2FA + Remove all 2FA {{/if}} - - Deauthorize sessions - Delete User - - - - - {{/each}} - + Deauthorize sessions + Delete User +
-