diff options
author | BlackDex <[email protected]> | 2021-11-28 13:02:27 +0100 |
---|---|---|
committer | BlackDex <[email protected]> | 2021-12-01 19:01:55 +0100 |
commit | e327583aa56a5129999d6295ff8a2be1ffa6d2a1 (patch) | |
tree | 9d832a731965e883259752cb20f9b5a1d702bc24 /src/static/scripts | |
parent | ead2f02cbd8a6fe29da0d0b09e68569920d3a4d2 (diff) | |
download | vaultwarden-e327583aa56a5129999d6295ff8a2be1ffa6d2a1.tar.gz vaultwarden-e327583aa56a5129999d6295ff8a2be1ffa6d2a1.zip |
Enabled trust-dns and some updates.
- Enabled trust-dns feature which seems to help a bit when DNS is
causing long timeouts. Though in the blocking version it is less visible
then on the async branch.
- Updated crates
- Removed some redundant code
- Updated javascript/css libraries
Resolves #2118
Resolves #2119
Diffstat (limited to 'src/static/scripts')
-rw-r--r-- | src/static/scripts/bootstrap-native.js | 397 | ||||
-rw-r--r-- | src/static/scripts/bootstrap.css | 937 | ||||
-rw-r--r-- | src/static/scripts/datatables.css | 4 | ||||
-rw-r--r-- | src/static/scripts/datatables.js | 227 |
4 files changed, 1047 insertions, 518 deletions
diff --git a/src/static/scripts/bootstrap-native.js b/src/static/scripts/bootstrap-native.js index 2159b3db..3827dfa6 100644 --- a/src/static/scripts/bootstrap-native.js +++ b/src/static/scripts/bootstrap-native.js @@ -1,5 +1,5 @@ /*! - * Native JavaScript for Bootstrap v4.0.6 (https://thednp.github.io/bootstrap.native/) + * Native JavaScript for Bootstrap v4.0.8 (https://thednp.github.io/bootstrap.native/) * Copyright 2015-2021 © dnp_theme * Licensed under MIT (https://github.com/thednp/bootstrap.native/blob/master/LICENSE) */ @@ -7,7 +7,7 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.BSN = factory()); -}(this, (function () { 'use strict'; +})(this, (function () { 'use strict'; const transitionEndEvent = 'webkitTransition' in document.head.style ? 'webkitTransitionEnd' : 'transitionend'; @@ -188,7 +188,7 @@ element.dispatchEvent(closedAlertEvent); self.dispose(); - element.parentNode.removeChild(element); + element.remove(); } // ALERT PRIVATE METHOD @@ -1022,9 +1022,9 @@ function isEmptyAnchor(elem) { const parentAnchor = elem.closest('A'); // anchor href starts with # - return elem && ((elem.href && elem.href.slice(-1) === '#') + return elem && ((elem.hasAttribute('href') && elem.href.slice(-1) === '#') // OR a child of an anchor with href starts with # - || (parentAnchor && parentAnchor.href && parentAnchor.href.slice(-1) === '#')); + || (parentAnchor && parentAnchor.hasAttribute('href') && parentAnchor.href.slice(-1) === '#')); } function setFocus(element) { @@ -1487,7 +1487,7 @@ function appendOverlay(hasFade, isModal) { toggleOverlayType(isModal); - document.body.appendChild(overlay); + document.body.append(overlay); if (hasFade) addClass(overlay, fadeClass); } @@ -1501,12 +1501,11 @@ } function removeOverlay() { - const bd = document.body; const currentOpen = getCurrentOpen(); if (!currentOpen) { removeClass(overlay, fadeClass); - bd.removeChild(overlay); + overlay.remove(); resetScrollbar(); } } @@ -1928,7 +1927,7 @@ if ((!element.contains(target) && options.backdrop && (!trigger || (trigger && !triggers.includes(trigger)))) - || offCanvasDismiss.contains(target)) { + || (offCanvasDismiss && offCanvasDismiss.contains(target))) { self.relatedTarget = target === offCanvasDismiss ? offCanvasDismiss : null; self.hide(); } @@ -2122,19 +2121,6 @@ .some((mediaType) => element instanceof mediaType); } - function closestRelative(element) { - let retval = null; - let el = element; - while (el !== document.body) { - el = el.parentElement; - if (getComputedStyle(el).position === 'relative') { - retval = el; - break; - } - } - return retval; - } - // both popovers and tooltips (this, event) function styleTip(self, e) { const tipClasses = /\b(top|bottom|start|end)+/; @@ -2148,32 +2134,32 @@ let tipDimensions = { w: tip.offsetWidth, h: tip.offsetHeight }; const windowWidth = (document.documentElement.clientWidth || document.body.clientWidth); const windowHeight = (document.documentElement.clientHeight || document.body.clientHeight); - const { element, options, arrow } = self; + const { + element, options, arrow, positions, + } = self; let { container, placement } = options; let parentIsBody = container === document.body; - const targetPosition = getComputedStyle(element).position; - const parentPosition = getComputedStyle(container).position; - const staticParent = !parentIsBody && parentPosition === 'static'; - let relativeParent = !parentIsBody && parentPosition === 'relative'; - const relContainer = staticParent && closestRelative(container); + + const { elementPosition, containerIsStatic, relContainer } = positions; + let { containerIsRelative } = positions; // static containers should refer to another relative container or the body container = relContainer || container; - relativeParent = staticParent && relContainer ? 1 : relativeParent; + containerIsRelative = containerIsStatic && relContainer ? 1 : containerIsRelative; parentIsBody = container === document.body; const parentRect = container.getBoundingClientRect(); - const leftBoundry = relativeParent ? parentRect.left : 0; - const rightBoundry = relativeParent ? parentRect.right : windowWidth; + const leftBoundry = containerIsRelative ? parentRect.left : 0; + const rightBoundry = containerIsRelative ? parentRect.right : windowWidth; // this case should not be possible - // absoluteParent = !parentIsBody && parentPosition === 'absolute', - // this case requires a container with placement: relative - const absoluteTarget = targetPosition === 'absolute'; + // containerIsAbsolute = !parentIsBody && containerPosition === 'absolute', + // this case requires a container with position: relative + const absoluteTarget = elementPosition === 'absolute'; const targetRect = element.getBoundingClientRect(); const scroll = parentIsBody ? { x: window.pageXOffset, y: window.pageYOffset } : { x: container.scrollLeft, y: container.scrollTop }; const elemDimensions = { w: element.offsetWidth, h: element.offsetHeight }; - const top = relativeParent ? element.offsetTop : targetRect.top; - const left = relativeParent ? element.offsetLeft : targetRect.left; + const top = containerIsRelative ? element.offsetTop : targetRect.top; + const left = containerIsRelative ? element.offsetLeft : targetRect.left; // reset arrow style arrow.style.top = ''; arrow.style.left = ''; @@ -2245,8 +2231,12 @@ } } else if (['top', 'bottom'].includes(placement)) { if (e && isMedia(element)) { - const eX = !relativeParent ? e.pageX : e.layerX + (absoluteTarget ? element.offsetLeft : 0); - const eY = !relativeParent ? e.pageY : e.layerY + (absoluteTarget ? element.offsetTop : 0); + const eX = !containerIsRelative + ? e.pageX + : e.layerX + (absoluteTarget ? element.offsetLeft : 0); + const eY = !containerIsRelative + ? e.pageY + : e.layerY + (absoluteTarget ? element.offsetTop : 0); if (placement === 'top') { topPosition = eY - tipDimensions.h - (isPopover ? arrowWidth : arrowHeight); @@ -2323,6 +2313,36 @@ return modal || navbarFixed || document.body; } + function closestRelative(element) { + let retval = null; + let el = element; + while (el !== document.body) { + el = el.parentElement; + if (getComputedStyle(el).position === 'relative') { + retval = el; + break; + } + } + return retval; + } + + function setHtml(element, content, sanitizeFn) { + if (typeof content === 'string' && !content.length) return; + + if (typeof content === 'object') { + element.append(content); + } else { + let dirty = content.trim(); // fixing #233 + + if (typeof sanitizeFn === 'function') dirty = sanitizeFn(dirty); + + const domParser = new DOMParser(); + const tempDocument = domParser.parseFromString(dirty, 'text/html'); + const method = tempDocument.children.length ? 'innerHTML' : 'innerText'; + element[method] = tempDocument.body[method]; + } + } + /* Native JavaScript for Bootstrap 5 | Popover ---------------------------------------------- */ @@ -2335,12 +2355,13 @@ template: '<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>', // string title: null, // string content: null, // string - sanitizeFn: null, // function customClass: null, // string - dismissible: false, // boolean - animation: true, // boolean trigger: 'hover', // string placement: 'top', // string + btnClose: '<button class="btn-close" aria-label="Close"></button>', // string + sanitizeFn: null, // function + dismissible: false, // boolean + animation: true, // boolean delay: 200, // number }; @@ -2350,11 +2371,8 @@ const isIphone = navigator.userAgentData ? navigator.userAgentData.brands.some((x) => appleBrands.test(x.brand)) : appleBrands.test(navigator.userAgent); - // popoverArrowClass = `${popoverString}-arrow`, const popoverHeaderClass = `${popoverString}-header`; const popoverBodyClass = `${popoverString}-body`; - // close btn for dissmissible popover - let popoverCloseButton = '<button type="button" class="btn-close"></button>'; // POPOVER CUSTOM EVENTS // ===================== @@ -2387,51 +2405,59 @@ const { animation, customClass, sanitizeFn, placement, dismissible, } = options; - let { title, content, template } = options; + let { + title, content, + } = options; + const { + template, btnClose, + } = options; // set initial popover class const placementClass = `bs-${popoverString}-${tipClassPositions[placement]}`; - // fixing #233 - title = title ? title.trim() : null; - content = content ? content.trim() : null; - - // sanitize title && content - if (sanitizeFn) { - title = title ? sanitizeFn(title) : null; - content = content ? sanitizeFn(content) : null; - template = template ? sanitizeFn(template) : null; - popoverCloseButton = sanitizeFn(popoverCloseButton); + // load template + let popoverTemplate; + if (typeof template === 'object') { + popoverTemplate = template; + } else { + const htmlMarkup = document.createElement('div'); + setHtml(htmlMarkup, template, sanitizeFn); + popoverTemplate = htmlMarkup.firstChild; } + // set popover markup + self.popover = popoverTemplate.cloneNode(true); - self.popover = document.createElement('div'); const { popover } = self; - // set id and aria-describedby + // set id and role attributes popover.setAttribute('id', id); popover.setAttribute('role', 'tooltip'); - // load template - const popoverTemplate = document.createElement('div'); - popoverTemplate.innerHTML = template.trim(); - popover.className = popoverTemplate.firstChild.className; - popover.innerHTML = popoverTemplate.firstChild.innerHTML; - const popoverHeader = queryElement(`.${popoverHeaderClass}`, popover); const popoverBody = queryElement(`.${popoverBodyClass}`, popover); - // set arrow + // set arrow and enable access for styleTip self.arrow = queryElement(`.${popoverString}-arrow`, popover); // set dismissible button if (dismissible) { - title = title ? title + popoverCloseButton : title; - content = title === null ? +popoverCloseButton : content; + if (title) { + if (title instanceof Element) setHtml(title, btnClose, sanitizeFn); + else title += btnClose; + } else { + if (popoverHeader) popoverHeader.remove(); + if (content instanceof Element) setHtml(content, btnClose, sanitizeFn); + else content += btnClose; + } } - // fill the template with content from data attributes - if (title && popoverHeader) popoverHeader.innerHTML = title.trim(); - if (content && popoverBody) popoverBody.innerHTML = content.trim(); + // fill the template with content from options / data attributes + // also sanitize title && content + if (title && popoverHeader) setHtml(popoverHeader, title, sanitizeFn); + if (content && popoverBody) setHtml(popoverBody, content, sanitizeFn); + + // set btn and enable access for styleTip + [self.btn] = popover.getElementsByClassName('btn-close'); // set popover animation and placement if (!hasClass(popover, popoverString)) addClass(popover, popoverString); @@ -2443,9 +2469,9 @@ } function removePopover(self) { - const { element, popover, options } = self; + const { element, popover } = self; element.removeAttribute(ariaDescribedBy); - options.container.removeChild(popover); + popover.remove(); self.timer = null; } @@ -2470,12 +2496,11 @@ function dismissHandlerToggle(self, add) { const action = add ? addEventListener : removeEventListener; - const { options, element, popover } = self; + const { options, element, btn } = self; const { trigger, dismissible } = options; if (dismissible) { - const [btnClose] = popover.getElementsByClassName('btn-close'); - if (btnClose) btnClose[action]('click', self.hide); + if (btn) btn[action]('click', self.hide); } else { if (trigger === 'focus') element[action]('focusout', self.hide); if (trigger === 'hover') document[action]('touchstart', popoverTouchHandler, passiveHandler); @@ -2488,12 +2513,10 @@ } function popoverShowTrigger(self) { - dismissHandlerToggle(self, 1); self.element.dispatchEvent(shownPopoverEvent); } function popoverHideTrigger(self) { - dismissHandlerToggle(self); removePopover(self); self.element.dispatchEvent(hiddenPopoverEvent); } @@ -2514,6 +2537,7 @@ self.timer = null; self.popover = null; self.arrow = null; + self.btn = null; self.enabled = false; // set unique ID for aria-describedby self.id = `${popoverString}-${getUID(element)}`; @@ -2535,6 +2559,21 @@ // crate popover createPopover(self); + // set positions + const { container } = self.options; + const elementPosition = getComputedStyle(element).position; + const containerPosition = getComputedStyle(container).position; + const parentIsBody = container === document.body; + const containerIsStatic = !parentIsBody && containerPosition === 'static'; + const containerIsRelative = !parentIsBody && containerPosition === 'relative'; + const relContainer = containerIsStatic && closestRelative(container); + self.positions = { + elementPosition, + containerIsRelative, + containerIsStatic, + relContainer, + }; + // bind self.update = self.update.bind(self); @@ -2563,23 +2602,21 @@ const { container } = options; clearTimeout(self.timer); + if (!isVisibleTip(popover, container)) { + element.dispatchEvent(showPopoverEvent); + if (showPopoverEvent.defaultPrevented) return; - self.timer = setTimeout(() => { - if (!isVisibleTip(popover, container)) { - element.dispatchEvent(showPopoverEvent); - if (showPopoverEvent.defaultPrevented) return; - - // append to the container - container.appendChild(popover); - element.setAttribute(ariaDescribedBy, id); + // append to the container + container.append(popover); + element.setAttribute(ariaDescribedBy, id); - self.update(e); - if (!hasClass(popover, showClass)) addClass(popover, showClass); + self.update(e); + if (!hasClass(popover, showClass)) addClass(popover, showClass); + dismissHandlerToggle(self, 1); - if (options.animation) emulateTransitionEnd(popover, () => popoverShowTrigger(self)); - else popoverShowTrigger(self); - } - }, 17); + if (options.animation) emulateTransitionEnd(popover, () => popoverShowTrigger(self)); + else popoverShowTrigger(self); + } } hide(e) { @@ -2596,13 +2633,13 @@ const { element, popover, options } = self; clearTimeout(self.timer); - self.timer = setTimeout(() => { if (isVisibleTip(popover, options.container)) { element.dispatchEvent(hidePopoverEvent); if (hidePopoverEvent.defaultPrevented) return; removeClass(popover, showClass); + dismissHandlerToggle(self); if (options.animation) emulateTransitionEnd(popover, () => popoverHideTrigger(self)); else popoverHideTrigger(self); @@ -2648,7 +2685,7 @@ const { popover, options } = self; const { container, animation } = options; if (animation && isVisibleTip(popover, container)) { - options.delay = 0; // reset delay + self.options.delay = 0; // reset delay self.hide(); emulateTransitionEnd(popover, () => togglePopoverHandlers(self)); } else { @@ -3067,7 +3104,7 @@ const toastSelector = `.${toastString}`; const toastDismissSelector = `[${dataBsDismiss}="${toastString}"]`; const showingClass = 'showing'; - const hideClass = 'hide'; + const hideClass = 'hide'; // marked as deprecated const toastDefaultOptions = { animation: true, autohide: true, @@ -3085,10 +3122,7 @@ // ===================== function showToastComplete(self) { const { element, options } = self; - if (!options.animation) { - removeClass(element, showingClass); - addClass(element, showClass); - } + removeClass(element, showingClass); element.dispatchEvent(shownToastEvent); if (options.autohide) self.hide(); @@ -3096,13 +3130,15 @@ function hideToastComplete(self) { const { element } = self; - addClass(element, hideClass); + removeClass(element, showingClass); + removeClass(element, showClass); + addClass(element, hideClass); // B/C element.dispatchEvent(hiddenToastEvent); } - function closeToast(self) { + function hideToast(self) { const { element, options } = self; - removeClass(element, showClass); + addClass(element, showingClass); if (options.animation) { reflow(element); @@ -3112,15 +3148,14 @@ } } - function openToast(self) { + function showToast(self) { const { element, options } = self; - removeClass(element, hideClass); + removeClass(element, hideClass); // B/C + reflow(element); + addClass(element, showClass); + addClass(element, showingClass); if (options.animation) { - reflow(element); - addClass(element, showingClass); - addClass(element, showClass); - emulateTransitionEnd(element, () => showToastComplete(self)); } else { showToastComplete(self); @@ -3148,9 +3183,13 @@ super(toastComponent, target, toastDefaultOptions, config); // bind const self = this; + const { element, options } = self; + // set fadeClass, the options.animation will override the markup + if (options.animation && !hasClass(element, fadeClass)) addClass(element, fadeClass); + else if (!options.animation && hasClass(element, fadeClass)) removeClass(element, fadeClass); // dismiss button - self.dismiss = queryElement(toastDismissSelector, self.element); + self.dismiss = queryElement(toastDismissSelector, element); // bind self.show = self.show.bind(self); @@ -3165,13 +3204,12 @@ show() { const self = this; const { element } = self; - if (element && hasClass(element, hideClass)) { + if (element && !hasClass(element, showClass)) { element.dispatchEvent(showToastEvent); if (showToastEvent.defaultPrevented) return; - addClass(element, fadeClass); clearTimeout(self.timer); - self.timer = setTimeout(() => openToast(self), 10); + self.timer = setTimeout(() => showToast(self), 10); } } @@ -3184,7 +3222,7 @@ if (hideToastEvent.defaultPrevented) return; clearTimeout(self.timer); - self.timer = setTimeout(() => closeToast(self), + self.timer = setTimeout(() => hideToast(self), noTimer ? 10 : options.delay); } } @@ -3192,7 +3230,7 @@ dispose() { const self = this; const { element, options } = self; - self.hide(); + self.hide(1); if (options.animation) emulateTransitionEnd(element, () => completeDisposeToast(self)); else completeDisposeToast(self); @@ -3221,13 +3259,14 @@ const titleAttr = 'title'; const tooltipInnerClass = `${tooltipString}-inner`; const tooltipDefaultOptions = { - title: null, template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', - placement: 'top', - animation: true, - customClass: null, - delay: 200, - sanitizeFn: null, + title: null, // string + customClass: null, // string | null + placement: 'top', // string + sanitizeFn: null, // function + animation: true, // bool + html: false, // bool + delay: 200, // number }; // TOOLTIP CUSTOM EVENTS @@ -3241,51 +3280,48 @@ // ======================= function createTooltip(self) { const { options, id } = self; - const placementClass = `bs-${tooltipString}-${tipClassPositions[options.placement]}`; - let titleString = options.title.trim(); + const { + title, template, customClass, animation, placement, sanitizeFn, + } = options; + const placementClass = `bs-${tooltipString}-${tipClassPositions[placement]}`; - // sanitize stuff - if (options.sanitizeFn) { - titleString = options.sanitizeFn(titleString); - options.template = options.sanitizeFn(options.template); - } + if (!title) return; - if (!titleString) return; + // load template + let tooltipTemplate; + if (typeof template === 'object') { + tooltipTemplate = template; + } else { + const htmlMarkup = document.createElement('div'); + setHtml(htmlMarkup, template, sanitizeFn); + tooltipTemplate = htmlMarkup.firstChild; + } // create tooltip - self.tooltip = document.createElement('div'); + self.tooltip = tooltipTemplate.cloneNode(true); const { tooltip } = self; - - // set aria + // set title + setHtml(queryElement(`.${tooltipInnerClass}`, tooltip), title, sanitizeFn); + // set id & role attribute tooltip.setAttribute('id', id); - - // set markup - const tooltipMarkup = document.createElement('div'); - tooltipMarkup.innerHTML = options.template.trim(); - - tooltip.className = tooltipMarkup.firstChild.className; - tooltip.innerHTML = tooltipMarkup.firstChild.innerHTML; - - queryElement(`.${tooltipInnerClass}`, tooltip).innerHTML = titleString; + tooltip.setAttribute('role', tooltipString); // set arrow self.arrow = queryElement(`.${tooltipString}-arrow`, tooltip); - // set class and role attribute - tooltip.setAttribute('role', tooltipString); // set classes if (!hasClass(tooltip, tooltipString)) addClass(tooltip, tooltipString); - if (options.animation && !hasClass(tooltip, fadeClass)) addClass(tooltip, fadeClass); - if (options.customClass && !hasClass(tooltip, options.customClass)) { - addClass(tooltip, options.customClass); + if (animation && !hasClass(tooltip, fadeClass)) addClass(tooltip, fadeClass); + if (customClass && !hasClass(tooltip, customClass)) { + addClass(tooltip, customClass); } if (!hasClass(tooltip, placementClass)) addClass(tooltip, placementClass); } function removeTooltip(self) { - const { element, options, tooltip } = self; + const { element, tooltip } = self; element.removeAttribute(ariaDescribedBy); - options.container.removeChild(tooltip); + tooltip.remove(); self.timer = null; } @@ -3387,6 +3423,21 @@ self.id = `${tooltipString}-${getUID(element)}`; createTooltip(self); + // set positions + const { container } = self.options; + const elementPosition = getComputedStyle(element).position; + const containerPosition = getComputedStyle(container).position; + const parentIsBody = container === document.body; + const containerIsStatic = !parentIsBody && containerPosition === 'static'; + const containerIsRelative = !parentIsBody && containerPosition === 'relative'; + const relContainer = containerIsStatic && closestRelative(container); + self.positions = { + elementPosition, + containerIsRelative, + containerIsStatic, + relContainer, + }; + // attach events toggleTooltipHandlers(self, 1); } @@ -3398,22 +3449,23 @@ const { options, tooltip, element, id, } = self; + const { + container, animation, + } = options; clearTimeout(self.timer); - self.timer = setTimeout(() => { - if (!isVisibleTip(tooltip, options.container)) { - element.dispatchEvent(showTooltipEvent); - if (showTooltipEvent.defaultPrevented) return; - - // append to container - options.container.appendChild(tooltip); - element.setAttribute(ariaDescribedBy, id); - - self.update(e); - if (!hasClass(tooltip, showClass)) addClass(tooltip, showClass); - if (options.animation) emulateTransitionEnd(tooltip, () => tooltipShownAction(self)); - else tooltipShownAction(self); - } - }, 20); + if (!isVisibleTip(tooltip, container)) { + element.dispatchEvent(showTooltipEvent); + if (showTooltipEvent.defaultPrevented) return; + + // append to container + container.append(tooltip); + element.setAttribute(ariaDescribedBy, id); + + self.update(e); + if (!hasClass(tooltip, showClass)) addClass(tooltip, showClass); + if (animation) emulateTransitionEnd(tooltip, () => tooltipShownAction(self)); + else tooltipShownAction(self); + } } hide(e) { @@ -3498,20 +3550,9 @@ constructor: Tooltip, }; - var version = "4.0.6"; - - // import { alertInit } from '../components/alert-native.js'; - // import { buttonInit } from '../components/button-native.js'; - // import { carouselInit } from '../components/carousel-native.js'; - // import { collapseInit } from '../components/collapse-native.js'; - // import { dropdownInit } from '../components/dropdown-native.js'; - // import { modalInit } from '../components/modal-native.js'; - // import { offcanvasInit } from '../components/offcanvas-native.js'; - // import { popoverInit } from '../components/popover-native.js'; - // import { scrollSpyInit } from '../components/scrollspy-native.js'; - // import { tabInit } from '../components/tab-native.js'; - // import { toastInit } from '../components/toast-native.js'; - // import { tooltipInit } from '../components/tooltip-native.js'; + var version = "4.0.8"; + + const Version = version; const componentsInit = { Alert: Alert.init, @@ -3547,7 +3588,7 @@ document.addEventListener('DOMContentLoaded', () => initCallback(), { once: true }); } - var index = { + const BSN = { Alert, Button, Carousel, @@ -3562,9 +3603,9 @@ Tooltip, initCallback, - Version: version, + Version, }; - return index; + return BSN; -}))); +}));
\ No newline at end of file diff --git a/src/static/scripts/bootstrap.css b/src/static/scripts/bootstrap.css index 892302a6..f16c5be8 100644 --- a/src/static/scripts/bootstrap.css +++ b/src/static/scripts/bootstrap.css @@ -1,6 +1,6 @@ @charset "UTF-8"; /*! - * Bootstrap v5.0.2 (https://getbootstrap.com/) + * Bootstrap v5.1.3 (https://getbootstrap.com/) * Copyright 2011-2021 The Bootstrap Authors * Copyright 2011-2021 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) @@ -19,6 +19,15 @@ --bs-white: #fff; --bs-gray: #6c757d; --bs-gray-dark: #343a40; + --bs-gray-100: #f8f9fa; + --bs-gray-200: #e9ecef; + --bs-gray-300: #dee2e6; + --bs-gray-400: #ced4da; + --bs-gray-500: #adb5bd; + --bs-gray-600: #6c757d; + --bs-gray-700: #495057; + --bs-gray-800: #343a40; + --bs-gray-900: #212529; --bs-primary: #0d6efd; --bs-secondary: #6c757d; --bs-success: #198754; @@ -27,9 +36,27 @@ --bs-danger: #dc3545; --bs-light: #f8f9fa; --bs-dark: #212529; + --bs-primary-rgb: 13, 110, 253; + --bs-secondary-rgb: 108, 117, 125; + --bs-success-rgb: 25, 135, 84; + --bs-info-rgb: 13, 202, 240; + --bs-warning-rgb: 255, 193, 7; + --bs-danger-rgb: 220, 53, 69; + --bs-light-rgb: 248, 249, 250; + --bs-dark-rgb: 33, 37, 41; + --bs-white-rgb: 255, 255, 255; + --bs-black-rgb: 0, 0, 0; + --bs-body-color-rgb: 33, 37, 41; + --bs-body-bg-rgb: 255, 255, 255; --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); + --bs-body-font-family: var(--bs-font-sans-serif); + --bs-body-font-size: 1rem; + --bs-body-font-weight: 400; + --bs-body-line-height: 1.5; + --bs-body-color: #212529; + --bs-body-bg: #fff; } *, @@ -46,12 +73,13 @@ body { margin: 0; - font-family: var(--bs-font-sans-serif); - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #212529; - background-color: #fff; + font-family: var(--bs-body-font-family); + font-size: var(--bs-body-font-size); + font-weight: var(--bs-body-font-weight); + line-height: var(--bs-body-line-height); + color: var(--bs-body-color); + text-align: var(--bs-body-text-align); + background-color: var(--bs-body-bg); -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } @@ -420,6 +448,10 @@ legend + * { padding: 0; } +::-webkit-file-upload-button { + font: inherit; +} + ::file-selector-button { font: inherit; } @@ -633,16 +665,16 @@ progress { --bs-gutter-y: 0; display: flex; flex-wrap: wrap; - margin-top: calc(var(--bs-gutter-y) * -1); - margin-right: calc(var(--bs-gutter-x) * -.5); - margin-left: calc(var(--bs-gutter-x) * -.5); + margin-top: calc(-1 * var(--bs-gutter-y)); + margin-right: calc(-0.5 * var(--bs-gutter-x)); + margin-left: calc(-0.5 * var(--bs-gutter-x)); } .row > * { flex-shrink: 0; width: 100%; max-width: 100%; - padding-right: calc(var(--bs-gutter-x) * .5); - padding-left: calc(var(--bs-gutter-x) * .5); + padding-right: calc(var(--bs-gutter-x) * 0.5); + padding-left: calc(var(--bs-gutter-x) * 0.5); margin-top: var(--bs-gutter-y); } @@ -685,206 +717,6 @@ progress { width: 16.6666666667%; } -@media (min-width: 576px) { - .col-sm { - flex: 1 0 0%; - } - - .row-cols-sm-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-sm-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-sm-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-sm-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-sm-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-sm-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-sm-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } -} -@media (min-width: 768px) { - .col-md { - flex: 1 0 0%; - } - - .row-cols-md-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-md-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-md-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-md-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-md-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-md-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-md-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } -} -@media (min-width: 992px) { - .col-lg { - flex: 1 0 0%; - } - - .row-cols-lg-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-lg-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-lg-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-lg-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-lg-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-lg-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-lg-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } -} -@media (min-width: 1200px) { - .col-xl { - flex: 1 0 0%; - } - - .row-cols-xl-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-xl-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-xl-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-xl-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-xl-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-xl-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-xl-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } -} -@media (min-width: 1400px) { - .col-xxl { - flex: 1 0 0%; - } - - .row-cols-xxl-auto > * { - flex: 0 0 auto; - width: auto; - } - - .row-cols-xxl-1 > * { - flex: 0 0 auto; - width: 100%; - } - - .row-cols-xxl-2 > * { - flex: 0 0 auto; - width: 50%; - } - - .row-cols-xxl-3 > * { - flex: 0 0 auto; - width: 33.3333333333%; - } - - .row-cols-xxl-4 > * { - flex: 0 0 auto; - width: 25%; - } - - .row-cols-xxl-5 > * { - flex: 0 0 auto; - width: 20%; - } - - .row-cols-xxl-6 > * { - flex: 0 0 auto; - width: 16.6666666667%; - } -} .col-auto { flex: 0 0 auto; width: auto; @@ -1055,6 +887,45 @@ progress { } @media (min-width: 576px) { + .col-sm { + flex: 1 0 0%; + } + + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + .col-sm-auto { flex: 0 0 auto; width: auto; @@ -1229,6 +1100,45 @@ progress { } } @media (min-width: 768px) { + .col-md { + flex: 1 0 0%; + } + + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + .col-md-auto { flex: 0 0 auto; width: auto; @@ -1403,6 +1313,45 @@ progress { } } @media (min-width: 992px) { + .col-lg { + flex: 1 0 0%; + } + + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + .col-lg-auto { flex: 0 0 auto; width: auto; @@ -1577,6 +1526,45 @@ progress { } } @media (min-width: 1200px) { + .col-xl { + flex: 1 0 0%; + } + + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + .col-xl-auto { flex: 0 0 auto; width: auto; @@ -1751,6 +1739,45 @@ progress { } } @media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0%; + } + + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto; + } + + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100%; + } + + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50%; + } + + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25%; + } + + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20%; + } + + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + .col-xxl-auto { flex: 0 0 auto; width: auto; @@ -1951,8 +1978,8 @@ progress { .table > thead { vertical-align: bottom; } -.table > :not(:last-child) > :last-child > * { - border-bottom-color: currentColor; +.table > :not(:first-child) { + border-top: 2px solid currentColor; } .caption-top { @@ -1973,8 +2000,11 @@ progress { .table-borderless > :not(caption) > * > * { border-bottom-width: 0; } +.table-borderless > :not(:first-child) { + border-top-width: 0; +} -.table-striped > tbody > tr:nth-of-type(odd) { +.table-striped > tbody > tr:nth-of-type(odd) > * { --bs-table-accent-bg: var(--bs-table-striped-bg); color: var(--bs-table-striped-color); } @@ -1984,7 +2014,7 @@ progress { color: var(--bs-table-active-color); } -.table-hover > tbody > tr:hover { +.table-hover > tbody > tr:hover > * { --bs-table-accent-bg: var(--bs-table-hover-bg); color: var(--bs-table-hover-color); } @@ -2200,6 +2230,22 @@ progress { background-color: #e9ecef; opacity: 1; } +.form-control::-webkit-file-upload-button { + padding: 0.375rem 0.75rem; + margin: -0.375rem -0.75rem; + -webkit-margin-end: 0.75rem; + margin-inline-end: 0.75rem; + color: #212529; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} .form-control::file-selector-button { padding: 0.375rem 0.75rem; margin: -0.375rem -0.75rem; @@ -2216,10 +2262,17 @@ progress { transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } @media (prefers-reduced-motion: reduce) { + .form-control::-webkit-file-upload-button { + -webkit-transition: none; + transition: none; + } .form-control::file-selector-button { transition: none; } } +.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { + background-color: #dde0e3; +} .form-control:hover:not(:disabled):not([readonly])::file-selector-button { background-color: #dde0e3; } @@ -2266,11 +2319,17 @@ progress { } .form-control-sm { - min-height: calc(1.5em + (0.5rem + 2px)); + min-height: calc(1.5em + 0.5rem + 2px); padding: 0.25rem 0.5rem; font-size: 0.875rem; border-radius: 0.2rem; } +.form-control-sm::-webkit-file-upload-button { + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; + -webkit-margin-end: 0.5rem; + margin-inline-end: 0.5rem; +} .form-control-sm::file-selector-button { padding: 0.25rem 0.5rem; margin: -0.25rem -0.5rem; @@ -2285,11 +2344,17 @@ progress { } .form-control-lg { - min-height: calc(1.5em + (1rem + 2px)); + min-height: calc(1.5em + 1rem + 2px); padding: 0.5rem 1rem; font-size: 1.25rem; border-radius: 0.3rem; } +.form-control-lg::-webkit-file-upload-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem; +} .form-control-lg::file-selector-button { padding: 0.5rem 1rem; margin: -0.5rem -1rem; @@ -2304,17 +2369,17 @@ progress { } textarea.form-control { - min-height: calc(1.5em + (0.75rem + 2px)); + min-height: calc(1.5em + 0.75rem + 2px); } textarea.form-control-sm { - min-height: calc(1.5em + (0.5rem + 2px)); + min-height: calc(1.5em + 0.5rem + 2px); } textarea.form-control-lg { - min-height: calc(1.5em + (1rem + 2px)); + min-height: calc(1.5em + 1rem + 2px); } .form-control-color { - max-width: 3rem; + width: 3rem; height: auto; padding: 0.375rem; } @@ -2378,6 +2443,7 @@ textarea.form-control-lg { padding-bottom: 0.25rem; padding-left: 0.5rem; font-size: 0.875rem; + border-radius: 0.2rem; } .form-select-lg { @@ -2385,6 +2451,7 @@ textarea.form-control-lg { padding-bottom: 0.5rem; padding-left: 1rem; font-size: 1.25rem; + border-radius: 0.3rem; } .form-check { @@ -3430,6 +3497,16 @@ textarea.form-control-lg { transition: none; } } +.collapsing.collapse-horizontal { + width: 0; + height: auto; + transition: width 0.35s ease; +} +@media (prefers-reduced-motion: reduce) { + .collapsing.collapse-horizontal { + transition: none; + } +} .dropup, .dropend, @@ -4047,6 +4124,33 @@ textarea.form-control-lg { .navbar-expand-sm .navbar-toggler { display: none; } + .navbar-expand-sm .offcanvas-header { + display: none; + } + .navbar-expand-sm .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-sm .offcanvas-top, +.navbar-expand-sm .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-sm .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } } @media (min-width: 768px) { .navbar-expand-md { @@ -4073,6 +4177,33 @@ textarea.form-control-lg { .navbar-expand-md .navbar-toggler { display: none; } + .navbar-expand-md .offcanvas-header { + display: none; + } + .navbar-expand-md .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-md .offcanvas-top, +.navbar-expand-md .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-md .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } } @media (min-width: 992px) { .navbar-expand-lg { @@ -4099,6 +4230,33 @@ textarea.form-control-lg { .navbar-expand-lg .navbar-toggler { display: none; } + .navbar-expand-lg .offcanvas-header { + display: none; + } + .navbar-expand-lg .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-lg .offcanvas-top, +.navbar-expand-lg .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-lg .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } } @media (min-width: 1200px) { .navbar-expand-xl { @@ -4125,6 +4283,33 @@ textarea.form-control-lg { .navbar-expand-xl .navbar-toggler { display: none; } + .navbar-expand-xl .offcanvas-header { + display: none; + } + .navbar-expand-xl .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-xl .offcanvas-top, +.navbar-expand-xl .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-xl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } } @media (min-width: 1400px) { .navbar-expand-xxl { @@ -4151,6 +4336,33 @@ textarea.form-control-lg { .navbar-expand-xxl .navbar-toggler { display: none; } + .navbar-expand-xxl .offcanvas-header { + display: none; + } + .navbar-expand-xxl .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; + } + .navbar-expand-xxl .offcanvas-top, +.navbar-expand-xxl .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; + } + .navbar-expand-xxl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } } .navbar-expand { flex-wrap: nowrap; @@ -4176,6 +4388,33 @@ textarea.form-control-lg { .navbar-expand .navbar-toggler { display: none; } +.navbar-expand .offcanvas-header { + display: none; +} +.navbar-expand .offcanvas { + position: inherit; + bottom: 0; + z-index: 1000; + flex-grow: 1; + visibility: visible !important; + background-color: transparent; + border-right: 0; + border-left: 0; + transition: none; + transform: none; +} +.navbar-expand .offcanvas-top, +.navbar-expand .offcanvas-bottom { + height: auto; + border-top: 0; + border-bottom: 0; +} +.navbar-expand .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; +} .navbar-light .navbar-brand { color: rgba(0, 0, 0, 0.9); @@ -4299,9 +4538,6 @@ textarea.form-control-lg { margin-bottom: 0; } -.card-link:hover { - text-decoration: none; -} .card-link + .card-link { margin-left: 1rem; } @@ -5177,10 +5413,10 @@ textarea.form-control-lg { box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); border-radius: 0.25rem; } -.toast:not(.showing):not(.show) { +.toast.showing { opacity: 0; } -.toast.hide { +.toast:not(.show) { display: none; } @@ -5220,7 +5456,7 @@ textarea.form-control-lg { position: fixed; top: 0; left: 0; - z-index: 1060; + z-index: 1055; display: none; width: 100%; height: 100%; @@ -5285,7 +5521,7 @@ textarea.form-control-lg { position: fixed; top: 0; left: 0; - z-index: 1040; + z-index: 1050; width: 100vw; height: 100vh; background-color: #000; @@ -6010,7 +6246,7 @@ textarea.form-control-lg { .offcanvas { position: fixed; bottom: 0; - z-index: 1050; + z-index: 1045; display: flex; flex-direction: column; max-width: 100%; @@ -6026,6 +6262,22 @@ textarea.form-control-lg { } } +.offcanvas-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1040; + width: 100vw; + height: 100vh; + background-color: #000; +} +.offcanvas-backdrop.fade { + opacity: 0; +} +.offcanvas-backdrop.show { + opacity: 0.5; +} + .offcanvas-header { display: flex; align-items: center; @@ -6089,6 +6341,69 @@ textarea.form-control-lg { transform: none; } +.placeholder { + display: inline-block; + min-height: 1em; + vertical-align: middle; + cursor: wait; + background-color: currentColor; + opacity: 0.5; +} +.placeholder.btn::before { + display: inline-block; + content: ""; +} + +.placeholder-xs { + min-height: 0.6em; +} + +.placeholder-sm { + min-height: 0.8em; +} + +.placeholder-lg { + min-height: 1.2em; +} + +.placeholder-glow .placeholder { + -webkit-animation: placeholder-glow 2s ease-in-out infinite; + animation: placeholder-glow 2s ease-in-out infinite; +} + +@-webkit-keyframes placeholder-glow { + 50% { + opacity: 0.2; + } +} + +@keyframes placeholder-glow { + 50% { + opacity: 0.2; + } +} +.placeholder-wave { + -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); + mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); + -webkit-mask-size: 200% 100%; + mask-size: 200% 100%; + -webkit-animation: placeholder-wave 2s linear infinite; + animation: placeholder-wave 2s linear infinite; +} + +@-webkit-keyframes placeholder-wave { + 100% { + -webkit-mask-position: -200% 0%; + mask-position: -200% 0%; + } +} + +@keyframes placeholder-wave { + 100% { + -webkit-mask-position: -200% 0%; + mask-position: -200% 0%; + } +} .clearfix::after { display: block; clear: both; @@ -6173,15 +6488,15 @@ textarea.form-control-lg { } .ratio-4x3 { - --bs-aspect-ratio: calc(3 / 4 * 100%); + --bs-aspect-ratio: 75%; } .ratio-16x9 { - --bs-aspect-ratio: calc(9 / 16 * 100%); + --bs-aspect-ratio: 56.25%; } .ratio-21x9 { - --bs-aspect-ratio: calc(9 / 21 * 100%); + --bs-aspect-ratio: 42.8571428571%; } .fixed-top { @@ -6247,6 +6562,20 @@ textarea.form-control-lg { z-index: 1020; } } +.hstack { + display: flex; + flex-direction: row; + align-items: center; + align-self: stretch; +} + +.vstack { + display: flex; + flex: 1 1 auto; + flex-direction: column; + align-self: stretch; +} + .visually-hidden, .visually-hidden-focusable:not(:focus):not(:focus-within) { position: absolute !important; @@ -6276,6 +6605,15 @@ textarea.form-control-lg { white-space: nowrap; } +.vr { + display: inline-block; + align-self: stretch; + width: 1px; + min-height: 1em; + background-color: currentColor; + opacity: 0.25; +} + .align-baseline { vertical-align: baseline !important; } @@ -6312,6 +6650,26 @@ textarea.form-control-lg { float: none !important; } +.opacity-0 { + opacity: 0 !important; +} + +.opacity-25 { + opacity: 0.25 !important; +} + +.opacity-50 { + opacity: 0.5 !important; +} + +.opacity-75 { + opacity: 0.75 !important; +} + +.opacity-100 { + opacity: 1 !important; +} + .overflow-auto { overflow: auto !important; } @@ -7335,105 +7693,176 @@ textarea.form-control-lg { /* rtl:end:remove */ .text-primary { - color: #0d6efd !important; + --bs-text-opacity: 1; + color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important; } .text-secondary { - color: #6c757d !important; + --bs-text-opacity: 1; + color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important; } .text-success { - color: #198754 !important; + --bs-text-opacity: 1; + color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important; } .text-info { - color: #0dcaf0 !important; + --bs-text-opacity: 1; + color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important; } .text-warning { - color: #ffc107 !important; + --bs-text-opacity: 1; + color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important; } .text-danger { - color: #dc3545 !important; + --bs-text-opacity: 1; + color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important; } .text-light { - color: #f8f9fa !important; + --bs-text-opacity: 1; + color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important; } .text-dark { - color: #212529 !important; + --bs-text-opacity: 1; + color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important; +} + +.text-black { + --bs-text-opacity: 1; + color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important; } .text-white { - color: #fff !important; + --bs-text-opacity: 1; + color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important; } .text-body { - color: #212529 !important; + --bs-text-opacity: 1; + color: rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important; } .text-muted { + --bs-text-opacity: 1; color: #6c757d !important; } .text-black-50 { + --bs-text-opacity: 1; color: rgba(0, 0, 0, 0.5) !important; } .text-white-50 { + --bs-text-opacity: 1; color: rgba(255, 255, 255, 0.5) !important; } .text-reset { + --bs-text-opacity: 1; color: inherit !important; } +.text-opacity-25 { + --bs-text-opacity: 0.25; +} + +.text-opacity-50 { + --bs-text-opacity: 0.5; +} + +.text-opacity-75 { + --bs-text-opacity: 0.75; +} + +.text-opacity-100 { + --bs-text-opacity: 1; +} + .bg-primary { - background-color: #0d6efd !important; + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important; } .bg-secondary { - background-color: #6c757d !important; + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important; } .bg-success { - background-color: #198754 !important; + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important; } .bg-info { - background-color: #0dcaf0 !important; + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important; } .bg-warning { - background-color: #ffc107 !important; + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important; } .bg-danger { - background-color: #dc3545 !important; + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important; } .bg-light { - background-color: #f8f9fa !important; + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important; } .bg-dark { - background-color: #212529 !important; + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important; } -.bg-body { - background-color: #fff !important; +.bg-black { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important; } .bg-white { - background-color: #fff !important; + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-body { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important; } .bg-transparent { + --bs-bg-opacity: 1; background-color: transparent !important; } +.bg-opacity-10 { + --bs-bg-opacity: 0.1; +} + +.bg-opacity-25 { + --bs-bg-opacity: 0.25; +} + +.bg-opacity-50 { + --bs-bg-opacity: 0.5; +} + +.bg-opacity-75 { + --bs-bg-opacity: 0.75; +} + +.bg-opacity-100 { + --bs-bg-opacity: 1; +} + .bg-gradient { background-image: var(--bs-gradient) !important; } diff --git a/src/static/scripts/datatables.css b/src/static/scripts/datatables.css index 585f9390..989e0960 100644 --- a/src/static/scripts/datatables.css +++ b/src/static/scripts/datatables.css @@ -4,10 +4,10 @@ * * To rebuild or modify this file with the latest versions of the included * software please visit: - * https://datatables.net/download/#bs5/dt-1.11.2 + * https://datatables.net/download/#bs5/dt-1.11.3 * * Included libraries: - * DataTables 1.11.2 + * DataTables 1.11.3 */ @charset "UTF-8"; diff --git a/src/static/scripts/datatables.js b/src/static/scripts/datatables.js index 93bbe80b..0d88756e 100644 --- a/src/static/scripts/datatables.js +++ b/src/static/scripts/datatables.js @@ -4,20 +4,20 @@ * * To rebuild or modify this file with the latest versions of the included * software please visit: - * https://datatables.net/download/#bs5/dt-1.11.2 + * https://datatables.net/download/#bs5/dt-1.11.3 * * Included libraries: - * DataTables 1.11.2 + * DataTables 1.11.3 */ -/*! DataTables 1.11.2 +/*! DataTables 1.11.3 * ©2008-2021 SpryMedia Ltd - datatables.net/license */ /** * @summary DataTables * @description Paginate, search and order HTML tables - * @version 1.11.2 + * @version 1.11.3 * @file jquery.dataTables.js * @author SpryMedia Ltd * @contact www.datatables.net @@ -1626,6 +1626,14 @@ return out; } + var _includes = function (search, start) { + if (start === undefined) { + start = 0; + } + + return this.indexOf(search, start) !== -1; + }; + // Array.isArray polyfill. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray if (! Array.isArray) { @@ -1634,6 +1642,10 @@ }; } + if (! Array.prototype.includes) { + Array.prototype.includes = _includes; + } + // .trim() polyfill // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim if (!String.prototype.trim) { @@ -1642,6 +1654,10 @@ }; } + if (! String.prototype.includes) { + String.prototype.includes = _includes; + } + /** * DataTables utility methods * @@ -2808,9 +2824,18 @@ return cellData.call( rowData ); } - if ( cellData === null && type == 'display' ) { + if ( cellData === null && type === 'display' ) { return ''; } + + if ( type === 'filter' ) { + var fomatters = DataTable.ext.type.search; + + if ( fomatters[ col.sType ] ) { + cellData = fomatters[ col.sType ]( cellData ); + } + } + return cellData; } @@ -4565,7 +4590,6 @@ var columns = settings.aoColumns; var column; var i, j, ien, jen, filterData, cellData, row; - var fomatters = DataTable.ext.type.search; var wasInvalidated = false; for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) { @@ -4580,10 +4604,6 @@ if ( column.bSearchable ) { cellData = _fnGetCellData( settings, i, j, 'filter' ); - if ( fomatters[ column.sType ] ) { - cellData = fomatters[ column.sType ]( cellData ); - } - // Search in DataTables 1.10 is string based. In 1.11 this // should be altered to also allow strict type checking. if ( cellData === null ) { @@ -6374,6 +6394,10 @@ */ function _fnSaveState ( settings ) { + if (settings._bLoadingState) { + return; + } + /* Store the interesting variables */ var state = { time: +new Date(), @@ -6408,98 +6432,128 @@ */ function _fnLoadState ( settings, oInit, callback ) { + if ( ! settings.oFeatures.bStateSave ) { + callback(); + return; + } + + var loaded = function(state) { + _fnImplementState(settings, state, callback); + } + + var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded ); + + if ( state !== undefined ) { + _fnImplementState( settings, state, callback ); + } + // otherwise, wait for the loaded callback to be executed + + return true; + } + + function _fnImplementState ( settings, s, callback) { var i, ien; var columns = settings.aoColumns; - var loaded = function ( s ) { - if ( ! s || ! s.time ) { - callback(); - return; - } + settings._bLoadingState = true; - // Allow custom and plug-in manipulation functions to alter the saved data set and - // cancelling of loading by returning false - var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] ); - if ( $.inArray( false, abStateLoad ) !== -1 ) { - callback(); - return; - } + // When StateRestore was introduced the state could now be implemented at any time + // Not just initialisation. To do this an api instance is required in some places + var api = settings._bInitComplete ? new DataTable.Api(settings) : null; - // Reject old data - var duration = settings.iStateDuration; - if ( duration > 0 && s.time < +new Date() - (duration*1000) ) { - callback(); - return; - } + if ( ! s || ! s.time ) { + settings._bLoadingState = false; + callback(); + return; + } - // Number of columns have changed - all bets are off, no restore of settings - if ( s.columns && columns.length !== s.columns.length ) { - callback(); - return; - } + // Allow custom and plug-in manipulation functions to alter the saved data set and + // cancelling of loading by returning false + var abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s] ); + if ( $.inArray( false, abStateLoad ) !== -1 ) { + settings._bLoadingState = false; + callback(); + return; + } + + // Reject old data + var duration = settings.iStateDuration; + if ( duration > 0 && s.time < +new Date() - (duration*1000) ) { + settings._bLoadingState = false; + callback(); + return; + } - // Store the saved state so it might be accessed at any time - settings.oLoadedState = $.extend( true, {}, s ); + // Number of columns have changed - all bets are off, no restore of settings + if ( s.columns && columns.length !== s.columns.length ) { + settings._bLoadingState = false; + callback(); + return; + } - // Restore key features - todo - for 1.11 this needs to be done by - // subscribed events - if ( s.start !== undefined ) { - settings._iDisplayStart = s.start; + // Store the saved state so it might be accessed at any time + settings.oLoadedState = $.extend( true, {}, s ); + + // Restore key features - todo - for 1.11 this needs to be done by + // subscribed events + if ( s.start !== undefined ) { + settings._iDisplayStart = s.start; + if(api === null) { settings.iInitDisplayStart = s.start; } - if ( s.length !== undefined ) { - settings._iDisplayLength = s.length; - } + } + if ( s.length !== undefined ) { + settings._iDisplayLength = s.length; + } - // Order - if ( s.order !== undefined ) { - settings.aaSorting = []; - $.each( s.order, function ( i, col ) { - settings.aaSorting.push( col[0] >= columns.length ? - [ 0, col[1] ] : - col - ); - } ); - } + // Order + if ( s.order !== undefined ) { + settings.aaSorting = []; + $.each( s.order, function ( i, col ) { + settings.aaSorting.push( col[0] >= columns.length ? + [ 0, col[1] ] : + col + ); + } ); + } - // Search - if ( s.search !== undefined ) { - $.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) ); - } + // Search + if ( s.search !== undefined ) { + $.extend( settings.oPreviousSearch, _fnSearchToHung( s.search ) ); + } - // Columns - // - if ( s.columns ) { - for ( i=0, ien=s.columns.length ; i<ien ; i++ ) { - var col = s.columns[i]; + // Columns + if ( s.columns ) { + for ( i=0, ien=s.columns.length ; i<ien ; i++ ) { + var col = s.columns[i]; - // Visibility - if ( col.visible !== undefined ) { + // Visibility + if ( col.visible !== undefined ) { + // If the api is defined, the table has been initialised so we need to use it rather than internal settings + if (api) { + // Don't redraw the columns on every iteration of this loop, we will do this at the end instead + api.column(i).visible(col.visible, false); + } + else { columns[i].bVisible = col.visible; } + } - // Search - if ( col.search !== undefined ) { - $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) ); - } + // Search + if ( col.search !== undefined ) { + $.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) ); } } - - _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] ); - callback(); - }; - - if ( ! settings.oFeatures.bStateSave ) { - callback(); - return; + + // If the api is defined then we need to adjust the columns once the visibility has been changed + if (api) { + api.columns.adjust(); + } } - var state = settings.fnStateLoadCallback.call( settings.oInstance, settings, loaded ); - - if ( state !== undefined ) { - loaded( state ); - } - // otherwise, wait for the loaded callback to be executed - } + settings._bLoadingState = false; + _fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, s] ); + callback(); + }; /** @@ -9590,7 +9644,7 @@ * @type string * @default Version number */ - DataTable.version = "1.11.2"; + DataTable.version = "1.11.3"; /** * Private data store, containing all of the settings objects that are @@ -14015,7 +14069,7 @@ * * @type string */ - build:"bs5/dt-1.11.2", + build:"bs5/dt-1.11.3", /** @@ -15048,6 +15102,10 @@ */ var __htmlEscapeEntities = function ( d ) { + if (Array.isArray(d)) { + d = d.join(','); + } + return typeof d === 'string' ? d .replace(/&/g, '&') @@ -15242,6 +15300,7 @@ _fnSortData: _fnSortData, _fnSaveState: _fnSaveState, _fnLoadState: _fnLoadState, + _fnImplementState: _fnImplementState, _fnSettingsFromNode: _fnSettingsFromNode, _fnLog: _fnLog, _fnMap: _fnMap, |