From b7af8249d7cf66dc89fe1540861f5421502404ec Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Sat, 25 May 2019 18:45:58 +0200 Subject: [PATCH] move js utils to static/es and fix linting warnings --- static/es/utils/alerts.js | 212 ++++++++++++ static/es/utils/asidenav.js | 109 ++++++ static/es/utils/asyncForm.js | 126 +++++++ static/es/utils/asyncTable.js | 422 +++++++++++++++++++++++ static/es/utils/checkAll.js | 150 +++++++++ static/es/utils/form.js | 611 ++++++++++++++++++++++++++++++++++ static/es/utils/inputs.js | 200 +++++++++++ static/es/utils/massInput.js | 232 +++++++++++++ static/es/utils/modal.js | 212 ++++++++++++ static/es/utils/showHide.js | 114 +++++++ static/es/utils/tabber.js | 90 +++++ 11 files changed, 2478 insertions(+) create mode 100644 static/es/utils/alerts.js create mode 100644 static/es/utils/asidenav.js create mode 100644 static/es/utils/asyncForm.js create mode 100644 static/es/utils/asyncTable.js create mode 100644 static/es/utils/checkAll.js create mode 100644 static/es/utils/form.js create mode 100644 static/es/utils/inputs.js create mode 100644 static/es/utils/massInput.js create mode 100644 static/es/utils/modal.js create mode 100644 static/es/utils/showHide.js create mode 100644 static/es/utils/tabber.js diff --git a/static/es/utils/alerts.js b/static/es/utils/alerts.js new file mode 100644 index 000000000..427e38373 --- /dev/null +++ b/static/es/utils/alerts.js @@ -0,0 +1,212 @@ +(function() { + 'use strict'; + + /** + * + * Alerts Utility + * makes alerts interactive + * + * Attribute: uw-alerts + * + * Types of alerts: + * [default] + * Regular Info Alert + * Disappears automatically after 30 seconds + * Disappears after x seconds if explicitly specified via data-decay='x' + * Can be told not to disappear with data-decay='0' + * + * [success] + * Currently no special visual appearance + * Disappears automatically after 30 seconds + * + * [warning] + * Will be coloured warning-orange regardless of user's selected theme + * Does not disappear + * + * [error] + * Will be coloured error-red regardless of user's selected theme + * Does not disappear + * + * Example usage: + *
+ *
+ *
+ *
+ *
+ *
+ * This is some information + * + */ + + var ALERTS_UTIL_NAME = 'alerts'; + var ALERTS_UTIL_SELECTOR = '[uw-alerts]'; + + var ALERTS_INITIALIZED_CLASS = 'alerts--initialized'; + var ALERTS_ELEVATED_CLASS = 'alerts--elevated'; + var ALERTS_TOGGLER_CLASS = 'alerts__toggler'; + var ALERTS_TOGGLER_VISIBLE_CLASS = 'alerts__toggler--visible'; + var ALERTS_TOGGLER_APPEAR_DELAY = 120; + + var ALERT_CLASS = 'alert'; + var ALERT_INITIALIZED_CLASS = 'alert--initialized'; + var ALERT_CLOSER_CLASS = 'alert__closer'; + var ALERT_ICON_CLASS = 'alert__icon'; + var ALERT_CONTENT_CLASS = 'alert__content'; + var ALERT_INVISIBLE_CLASS = 'alert--invisible'; + var ALERT_AUTO_HIDE_DELAY = 10; + var ALERT_AUTOCLOSING_MATCHER = '.alert-info, .alert-success'; + + var alertsUtil = function(element) { + var togglerCheckRequested = false; + var togglerElement; + var alertElements; + + function init() { + if (!element) { + throw new Error('Alerts util has to be called with an element!'); + } + + if (element.classList.contains(ALERTS_INITIALIZED_CLASS)) { + return false; + } + + togglerElement = element.querySelector('.' + ALERTS_TOGGLER_CLASS); + alertElements = gatherAlertElements(); + + initToggler(); + initAlerts(); + + // register http client interceptor to filter out Alerts Header + setupHttpInterceptor(); + + // mark initialized + element.classList.add(ALERTS_INITIALIZED_CLASS); + + return { + name: ALERTS_UTIL_NAME, + element: element, + destroy: function() {}, + }; + } + + function gatherAlertElements() { + return Array.from(element.querySelectorAll('.' + ALERT_CLASS)).filter(function(alert) { + return !alert.classList.contains(ALERT_INITIALIZED_CLASS); + }); + } + + function initToggler() { + togglerElement.addEventListener('click', function() { + alertElements.forEach(function(alertEl) { + toggleAlert(alertEl, true); + }); + togglerElement.classList.remove(ALERTS_TOGGLER_VISIBLE_CLASS); + }); + } + + function initAlerts() { + alertElements.forEach(initAlert); + } + + function initAlert(alertElement) { + var autoHideDelay = ALERT_AUTO_HIDE_DELAY; + if (alertElement.dataset.decay) { + autoHideDelay = parseInt(alertElement.dataset.decay, 10); + } + + var closeEl = alertElement.querySelector('.' + ALERT_CLOSER_CLASS); + closeEl.addEventListener('click', function() { + toggleAlert(alertElement); + }); + + if (autoHideDelay > 0 && alertElement.matches(ALERT_AUTOCLOSING_MATCHER)) { + window.setTimeout(function() { + toggleAlert(alertElement); + }, autoHideDelay * 1000); + } + } + + function toggleAlert(alertEl, visible) { + alertEl.classList.toggle(ALERT_INVISIBLE_CLASS, !visible); + checkToggler(); + } + + function checkToggler() { + if (togglerCheckRequested) { + return; + } + + var alertsHidden = alertElements.reduce(function(acc, alert) { + return acc && alert.classList.contains(ALERT_INVISIBLE_CLASS); + }, true); + + window.setTimeout(function() { + togglerElement.classList.toggle(ALERTS_TOGGLER_VISIBLE_CLASS, alertsHidden); + togglerCheckRequested = false; + }, ALERTS_TOGGLER_APPEAR_DELAY); + } + + function setupHttpInterceptor() { + if (HttpClient) { + HttpClient.addResponseInterceptor(responseInterceptor.bind(this)); + } + } + + function elevateAlerts() { + element.classList.add(ALERTS_ELEVATED_CLASS); + } + + function responseInterceptor(response) { + var alerts; + for (var header of response.headers) { + if (header[0] === 'alerts') { + var decodedHeader = decodeURIComponent(header[1]); + alerts = JSON.parse(decodedHeader); + break; + } + } + + if (alerts) { + alerts.forEach(function(alert) { + var alertElement = createAlertElement(alert.status, alert.content); + element.appendChild(alertElement); + alertElements.push(alertElement); + initAlert(alertElement); + }); + + elevateAlerts(); + } + } + + function createAlertElement(type, content) { + var alertElement = document.createElement('div'); + alertElement.classList.add(ALERT_CLASS, 'alert-' + type); + + var alertCloser = document.createElement('div'); + alertCloser.classList.add(ALERT_CLOSER_CLASS); + + var alertIcon = document.createElement('div'); + alertIcon.classList.add(ALERT_ICON_CLASS); + + var alertContent = document.createElement('div'); + alertContent.classList.add(ALERT_CONTENT_CLASS); + alertContent.innerHTML = content; + + alertElement.appendChild(alertCloser); + alertElement.appendChild(alertIcon); + alertElement.appendChild(alertContent); + + return alertElement; + } + + return init(); + }; + + if (UtilRegistry) { + UtilRegistry.register({ + name: ALERTS_UTIL_NAME, + selector: ALERTS_UTIL_SELECTOR, + setup: alertsUtil, + }); + } +})(); diff --git a/static/es/utils/asidenav.js b/static/es/utils/asidenav.js new file mode 100644 index 000000000..b9fc1e323 --- /dev/null +++ b/static/es/utils/asidenav.js @@ -0,0 +1,109 @@ +(function() { + 'use strict'; + + /** + * + * Asidenav Utility + * Correctly positions hovered asidenav submenus and handles the favorites button on mobile + * + * Attribute: uw-asidenav + * + * Example usage: + *
+ *
+ *
+ *