aboutsummaryrefslogtreecommitdiff
path: root/src/static/scripts
diff options
context:
space:
mode:
authorBlackDex <[email protected]>2021-11-28 13:02:27 +0100
committerBlackDex <[email protected]>2021-12-01 19:01:55 +0100
commite327583aa56a5129999d6295ff8a2be1ffa6d2a1 (patch)
tree9d832a731965e883259752cb20f9b5a1d702bc24 /src/static/scripts
parentead2f02cbd8a6fe29da0d0b09e68569920d3a4d2 (diff)
downloadvaultwarden-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.js397
-rw-r--r--src/static/scripts/bootstrap.css937
-rw-r--r--src/static/scripts/datatables.css4
-rw-r--r--src/static/scripts/datatables.js227
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, '&amp;')
@@ -15242,6 +15300,7 @@
_fnSortData: _fnSortData,
_fnSaveState: _fnSaveState,
_fnLoadState: _fnLoadState,
+ _fnImplementState: _fnImplementState,
_fnSettingsFromNode: _fnSettingsFromNode,
_fnLog: _fnLog,
_fnMap: _fnMap,