cui-light
Version:
cUI light framework for the web
1,409 lines (1,387 loc) • 504 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("cui-light", [], factory);
else if(typeof exports === 'object')
exports["cui-light"] = factory();
else
root["cui-light"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, "CUI_LIGHT_VERSION", function() { return /* binding */ CUI_LIGHT_VERSION; });
__webpack_require__.d(__webpack_exports__, "CuiInstance", function() { return /* reexport */ instance_CuiInstance; });
// CONCATENATED MODULE: ./src/core/models/errors.ts
class ErrorBase extends Error {
constructor(name, message) {
super(message);
Object.setPrototypeOf(this, new.target.prototype);
this.name = name;
}
}
class ItemNotFoundError extends ErrorBase {
constructor(message) {
super("ItemNotFoundError", message);
}
}
class ArgumentError extends ErrorBase {
constructor(message) {
super("ArgumentError", message);
}
}
class CuiBusError extends ErrorBase {
constructor(message) {
super("ArgumentError", message);
}
}
class CuiInstanceInitError extends ErrorBase {
constructor(message) {
super("CuiInstanceInitError", message);
}
}
class CuiScrollSpyOutOfRangeError extends ErrorBase {
constructor(message) {
super("CuiScrollSpyOutOfRangeError", message);
}
}
class RegisterElementError extends ErrorBase {
constructor(message) {
super("RegisterElementError", message);
}
}
class AnimatorError extends ErrorBase {
constructor(message) {
super("AnimatorError", message);
}
}
class CSSVariableError extends ErrorBase {
constructor(message) {
super("CSSVariableError", message);
}
}
class CuiColorError extends ErrorBase {
constructor(message) {
super("CuiColorError", message);
}
}
class CuiPositionError extends ErrorBase {
constructor(message) {
super("CuiPositionError", message);
}
}
// CONCATENATED MODULE: ./src/core/utils/statics.ts
const CUID_ATTRIBUTE = "cuid";
const CLASSES = {
dark: 'dark',
animProgress: 'animation-progress',
print: 'print',
active: 'active',
swipingOn: "swiping-on",
selectionOff: "selection-off",
};
const ICONS = {
close: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" width=\"20\" height=\"20\"><path d=\"M 1.9999999,1.9999999 18,18\"></path><path d=\"M 18,1.9999999 1.9999999,18\"></path></svg>",
accordion: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" width=\"20\" height=\"20\"><path d=\"M 5.0000475,7.4490018 10.000024,12.551028 15,7.4490018\"></path></svg>",
special_menu: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" width=\"20\" height=\"20\"><path class=\"menu_handle_2\" d=\"M 1,10 H 19\"></path><path class=\"menu_handle_1\" d=\"M 1,4.8571429 H 19\"></path><path class=\"menu_handle_3\" d=\"M 1,15.142857 H 19\"></path></svg>",
special_fail: "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"special-fail\" viewBox=\"0 0 100 100\" width=\"100\" height=\"100\"><path class=\"circle\" d=\"M 50,7.000001 A 43,43 0 0 1 92.999999,50 43,43 0 0 1 50,92.999999 43,43 0 0 1 7.0000011,50 43,43 0 0 1 50,7.000001 Z\"></path><path class=\"arm_1\" d=\"M 28.536809,28.536809 71.342023,71.342023\"></path><path class=\"arm_2\" d=\"M 71.342023,28.536809 28.536809,71.342023\"></path></svg>",
special_success: "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"special-success\" viewBox=\"0 0 100 100\" width=\"100\" height=\"100\"><path class=\"circle\" d=\"M 50,7 A 43,43 0 0 1 93,50 43,43 0 0 1 50,93 43,43 0 0 1 7,50 43,43 0 0 1 50,7 Z\"></path><path class=\"arm\" d=\"M 22.988405,48.234784 36.946233,72.410453 75.516456,33.84023\"></path></svg>",
};
const COLORS = ['red', 'green', 'blue', 'alpha'];
const CSS_APP_BACKGROUND_COLORS = {
light: '--cui-color-light-app-background',
dark: '--cui-color-dark-app-background'
};
const CSS_COMPONENT_BACKGROUND_COLORS = {
light: '--cui-color-light-background',
dark: '--cui-color-dark-background '
};
const CSS_COMPONENT_BORDER_COLORS = {
light: '--cui-color-light-border',
dark: '--cui-color-dark-border'
};
const CSS_THEMES = {
light: {
base: '--cui-color-light-base',
muted: '--cui-color-light-muted',
active: '--cui-color-light-active'
},
dark: {
base: '--cui-color-dark-base',
muted: '--cui-color-dark-muted',
active: '--cui-color-dark-active'
},
accent: {
base: '--cui-color-primary',
muted: '--cui-color-primary-muted',
active: '--cui-color-primary-active'
},
secondary: {
base: '--cui-color-secondary',
muted: '--cui-color-secondary-muted',
active: '--cui-color-secondary-active'
},
success: {
base: '--cui-color-success',
muted: '--cui-color-success-muted',
active: '--cui-color-success-active'
},
warning: {
base: '--cui-color-warning',
muted: '--cui-color-warning-muted',
active: '--cui-color-warning-active'
},
error: {
base: '--cui-color-error',
muted: '--cui-color-error-muted',
active: '--cui-color-error-active'
}
};
const SCOPE_SELECTOR = ":scope ";
const CSS_VARIABLES = {
fontSize: "--{prefix}-font-size",
lineHeight: "--{prefix}-line-height",
animationTime: "--{prefix}-animation-time",
animationTimeLong: "--{prefix}-animation-time-long",
animationTimeShort: "--{prefix}-animation-time-short",
colorLightAppBackground: "--{prefix}-color-light-app-background",
colorLightBackground: "--{prefix}-color-light-background",
colorLightBorder: "--{prefix}-color-light-border",
colorLightBase: "--{prefix}-color-light-base",
colorLightActive: "--{prefix}-color-light-active",
colorLightMuted: "--{prefix}-color-light-muted",
colorDarkAppBackground: "--{prefix}-color-dark-app-background",
colorDarkBackground: "--{prefix}-color-dark-background",
colorDarkBorder: "--{prefix}-color-dark-border",
colorDarkBase: "--{prefix}-color-dark-base",
colorDarkActive: "--{prefix}-color-dark-active",
colorDarkMuted: "--{prefix}-color-dark-muted",
colorAccent: "--{prefix}-color-primary",
colorAccentActive: "--{prefix}-color-primary-active",
colorAccentMuted: "--{prefix}-color-primary-muted",
colorAccentShade: "--{prefix}-color-primary-shade",
colorAccentShadeDark: "--{prefix}-color-primary-shade-dark",
colorSecondary: "--{prefix}-color-secondary",
colorSecondaryActive: "--{prefix}-color-secondary-active",
colorSecondaryMuted: "--{prefix}-color-secondary-muted",
colorSecondaryShade: "--{prefix}-color-secondary-shade",
colorSecondaryShadeDark: "--{prefix}-color-secondary-shade-dark",
colorWarning: "--{prefix}-color-warning",
colorWarningActive: "--{prefix}-color-warning-active",
colorWarningMuted: "--{prefix}-color-warning-muted",
colorWarningShade: "--{prefix}-color-warning-shade",
colorWarningShadeDark: "--{prefix}-color-warning-shade-dark",
colorSuccess: "--{prefix}-color-success",
colorSuccessActive: "--{prefix}-color-success-active",
colorSuccessMuted: "--{prefix}-color-success-muted",
colorSuccessShade: "--{prefix}-color-success-shade",
colorSuccessShadeDark: "--{prefix}-color-success-shade-dark",
colorError: "--{prefix}-color-error",
colorErrorActive: "--{prefix}-color-error-active",
colorErrorMuted: "--{prefix}-color-error-muted",
colorErrorShade: "--{prefix}-color-error-shade",
colorErrorShadeDark: "--{prefix}-color-error-shade-dark",
inputBackground: "--{prefix}-input-background-color",
colorShade: "--{prefix}-color-shade",
colorShadeDarker: "--{prefix}-color-shade-darker",
colorShadeLight: "--{prefix}-color-shade-light",
colorShadeLighter: "--{prefix}-color-shade-light-lighter",
outline: "--{prefix}-outline",
borderRadius: "--{prefix}-border-radius",
padding: "--{prefix}-padding",
margin: "--{prefix}-margin",
scrollbarWidth: "--{prefix}-scrollbar-width",
componentSpace: "--{prefix}-component-space",
accordionIcon: "--{prefix}-accordion-icon"
};
class STATICS {
}
STATICS.logLevel = 'none';
STATICS.prefix = 'cui';
const EVENTS = {
INSTANCE_INITIALIZED: 'instance-initialized',
INSTANCE_FINISHED: 'instance-finished',
RESIZE: "resize",
OPEN: "open",
OPENED: "opened",
CLOSE: "close",
CLOSED: "closed",
TOGGLE: "toggle",
TOGGLED: 'toggled',
SWITCH: "switch",
SWITCHED: "switched",
ON_SCROLL: "scroll",
TARGET_CHANGE: 'targetchange',
INTERSECTION: 'intersection',
KEYDOWN: 'keydown',
SCROLLBY: 'scrollby',
WINDOW_CLICK: 'windowclick',
OFFSET: 'offset',
PROGRESS_CHANGE: "progresschange",
PROGRESS_CHANGED: "progresschanged",
CHANGE: "change",
CHANGED: "changed",
GLOBAL_MOVE: "globalmove",
MOVE_LOCK: "movelock",
PAUSE: "pause",
PAUSED: "paused",
SORTED: "sorted",
SORT_START: "sortstart"
};
const OBSERVABLE_SCROLL = "SCROLL";
const OBSERVABLE_INTERSECTION = "INTERSECTION";
const COMPONENTS_COUNTER = counter();
// CONCATENATED MODULE: ./src/core/utils/functions.ts
/**
* Checks if value is defined an is not null
* Additionally with type check it can check value if it is not empty string or collection or object
*
* @param val - value
* @param typecheck - default true - additional check whether value is not empty (string, collection, object)
* @returns whether value passed all conditions
*/
function is(val, typecheck = true) {
if (typeof val !== 'undefined' && val !== null) {
if (!typecheck) {
return true;
}
else {
return !isEmpty(val);
}
}
return false;
}
/**
* Checks if value is empty string, array or object
*
*
* @param val - value
* @returns whether value passed all conditions
*/
function isEmpty(val) {
if (typeof val === "string") {
return val.length === 0;
}
if (typeof val === "boolean") {
return val;
}
else if (Array.isArray(val)) {
return val.length === 0;
}
return false;
}
function getName(prefix, name) {
if (!is(prefix) || !is(name)) {
throw new ArgumentError("Missing argument value");
}
return `${prefix}-${name}`;
}
function sleep(timeout) {
return new Promise(resolve => setTimeout(() => {
resolve(true);
}, timeout));
}
/**
* Creates proper html element from given string
* @param htmlString - string containing html
*/
function createElementFromString(htmlString) {
if (!is(htmlString)) {
return null;
}
let template = document.createElement('template');
template.innerHTML = htmlString;
return template.content.children.length > 0 ? template.content.children[0] : null;
}
function getMatchingAttribute(element, attributes) {
let attr = null;
let len = attributes.length;
for (let i = 0; i < len; i++) {
let attribute = attributes[i];
if (element.hasAttribute(attribute)) {
attr = attribute;
break;
}
}
return attr;
}
function getMatchingAttributes(element, attributes) {
if (!element || !is(element.hasAttribute)) {
return [];
}
return attributes.filter(a => {
return element.hasAttribute(a);
});
}
function getRangeValue(value, min, max) {
if (value < min) {
return min;
}
else if (value > max) {
return max;
}
return value;
}
function getRangeValueOrDefault(value, min, max, def) {
if (value === null || typeof value === 'undefined' || isNaN(value)) {
return def;
}
return getRangeValue(value, min, max);
}
function increaseValue(value, amount) {
return amount < 0 || amount > 1 ? 0 : value + (value * amount);
}
function decreaseValue(value, amount) {
return amount < 0 || amount > 1 ? 0 : value - (value * amount);
}
function clone(object) {
if (!is(object)) {
return null;
}
return Object.assign({}, object);
}
function getSingleColorRatio(first, second, max) {
return Math.abs(((first - second) / max) * 100);
}
/**
* Creates string containg css selector for array of attributes
* @param attributes - attributes values
*/
function joinAttributesForQuery(attributes) {
if (!is(attributes)) {
return "";
}
return `[${attributes.join('],[')}]`;
}
/**
* Checks light system light mode
* @returns Light Mode - dark/light
*/
function getSystemLightMode() {
return window.matchMedia &&
window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
/**
* Check print mode in the browser window
* @returns true if window is displayed in print mode
*/
function getSystemPrintMode() {
return window.matchMedia &&
window.matchMedia('print').matches;
}
/**
* Verifies whether attributes exist and have some values
* @param attributes attributes list
*/
function are(...attributes) {
if (!is(attributes)) {
return false;
}
let c = attributes.length;
for (let i = 0; i < c; i++) {
if (!is(attributes[i])) {
return false;
}
}
return true;
}
function calcWindowSize(width) {
if (width <= 640) {
return 'small';
}
else if (width > 640 && width <= 960) {
return "medium";
}
else if (width > 960 && width <= 1200) {
return "large";
}
return 'xlarge';
}
function calcWindowSize2(width) {
let size = "none";
if (width >= 640) {
size = 'small';
}
if (width >= 960) {
size = "medium";
}
if (width >= 1200) {
size = "large";
}
if (width >= 1600) {
size = 'xlarge';
}
return size;
}
/**
* Creates object from string.
* Supported syntaxes are:
* - JSON
* - single value
* - key:value,value;key=value
*
* @param attribute - attribute value
*/
function parseAttributeString(attribute) {
let ret = {};
if (!is(attribute)) {
return ret;
}
//@ts-ignore - null already checked
ret = parseJsonString(attribute.trim());
if (!is(ret)) {
//@ts-ignore - null already checked
if (!attribute.includes(';') && !attribute.includes(':')) {
ret = attribute;
}
else {
ret = {};
//@ts-ignore - null already checked
attribute.split(';').forEach(val => {
let sp = splitColon(val);
//let sp = val.split(':')
let len = sp.length;
let tag = undefined;
let value = "";
if (len < 2) {
return;
}
tag = sp[0].trim();
value = sp[1].trim();
if (tag)
ret[tag] = value.replace('U+0003B', ';');
});
}
}
return ret;
}
/**
* Creates object from JSON string
* String must start with { and end with }
*
* @param attribute - attribute value
* @returns object if string passes test, null otherwise
*/
function parseJsonString(attribute) {
let out = null;
if (is(attribute) && attribute.startsWith('{') && attribute.endsWith('}')) {
try {
out = jsonify(attribute);
}
catch (e) {
console.error(prepLogString("An exception occured", 'Functions', 'parseJsonString'), e);
}
return out;
}
return null;
}
/**
* Creates object from JSON string
* @param attribute - JSON string
*/
function jsonify(attribute) {
return attribute && attribute.length > 0 ? JSON.parse(attribute) : {};
}
function getOffsetTop(element) {
if (!is(element)) {
return -1;
}
let val = element.offsetTop - parseInt(getStyleValue(element, 'margin-top')) - parseInt(getStyleValue(element, 'padding-top')) - parseInt(getStyleValue(element, 'border-top-width'));
return val < 0 ? element.offsetTop : val;
}
function getOffsetLeft(element) {
if (!is(element)) {
return -1;
}
let val = element.offsetLeft - parseInt(getStyleValue(element, 'margin-left')) - parseInt(getStyleValue(element, 'padding-left')) - parseInt(getStyleValue(element, 'border-left-width'));
return val < 0 ? element.offsetLeft : val;
}
function getIntOrDefault(value, def) {
let integer = parseInt(value);
return isNaN(integer) ? def : integer;
}
function getStyleValue(target, property) {
if (!is(target) || !is(property)) {
return null;
}
if (target.currentStyle) {
return target.currentStyle[property];
}
else if (window.getComputedStyle) {
return window.getComputedStyle(target, null).getPropertyValue(property);
}
return null;
}
function prepLogString(message, component, functionName) {
return `[${new Date().toLocaleString()}][${component !== null && component !== void 0 ? component : "-"}][${functionName !== null && functionName !== void 0 ? functionName : '-'}][${message}]`;
}
function isInRange(value, min, max) {
return is(value) && value >= min && value <= max;
}
function getActiveClass(prefix) {
return `${prefix !== null && prefix !== void 0 ? prefix : ""}-active`;
}
function parseAttribute(element, attribute) {
return are(element, attribute) ? parseAttributeString(element.getAttribute(attribute)) : null;
}
/**
* Checks whether string value contains synonym of true
* @param value - string to check
*/
function isStringTrue(value) {
return is(value) ? ['y', 't', 'true', 'yes'].includes(value.toLowerCase()) : false;
}
function boolStringOrDefault(prop, def) {
return is(prop) ? isStringTrue(prop) : def;
}
function getStringOrDefault(value, def) {
return is(value) ? value.toLowerCase() : def;
}
/**
* Checks whether device supports touch
*/
function isTouchSupported() {
return ('ontouchstart' in window) ||
(navigator.maxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0);
}
/**
* Checks whether value is type of string
* @param {any} value - value to be checked
*/
function isString(value) {
return typeof value === 'string';
}
/**
* Replaces mask {prefix} with actual value in the string
* @param {string} value - text containg a mask
* @param {string} prefix - value to be put in place of mask
*/
function replacePrefix(value, prefix) {
return !is(value) ? value : value.replace("{prefix}", prefix !== null && prefix !== void 0 ? prefix : "");
}
/**
* Generates identifier for Cui element
*
* @param element - Cui element selector
* @returns generated identifier
*/
function generateCUID(element) {
let starter = is(element) ? element : "cui-element";
return `${starter}-${COMPONENTS_COUNTER.next().value}`;
}
/**
* Generates random string
*/
function generateRandomString() {
let rand = getRandomInt(1, 1000);
let rand2 = getRandomInt(1, 100);
return `${Math.floor(Math.random() * rand2)}-${Math.floor(rand)}`;
}
/**
* Generates random integer
* @param min - min number
* @param max - max number
* @returns random integer
*/
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
/**
* Registers Element as Cui element, initializes handlers, sets component style to document header and sets $cuid
* @param {any} node - document node
* @param {ICuiComponent[]} components -supported components array
* @param {string[]} attributes - supported attributes array
* @param {CuiUtils} utils - Cui Utils instance
*/
function registerCuiElement(node, components, attributes, utils) {
let element = node;
element.$handlers = {};
let matching = getMatchingAttributes(node, attributes);
if (is(matching)) {
element.$cuid = node.hasAttribute(CUID_ATTRIBUTE) ? node.getAttribute(CUID_ATTRIBUTE) : generateCUID(node.tagName);
node.setAttribute(CUID_ATTRIBUTE, element.$cuid);
matching.forEach(match => {
let component = components.find(c => { return c.attribute === match; });
if (!is(component)) {
return;
}
try {
//@ts-ignore - component already checked agains undefined
utils.styleAppender.append(component.getStyle());
//@ts-ignore - component already checked agains undefined
let handler = component.get(node, utils);
//@ts-ignore - component already checked agains undefined
element.$handlers[component.attribute] = handler;
//@ts-ignore - component already checked agains undefined
element.$handlers[component.attribute].handle(parseAttribute(node, component.attribute));
}
catch (e) {
let attr = matching ? matching.join(", ") : "";
throw new RegisterElementError(`An error occured during [${attr}] initialization: ${e.message}`);
}
});
}
}
function addCuiArgument(element, cuiArg, args) {
if (!are(cuiArg, args, element)) {
return false;
}
if (element.hasAttribute(cuiArg)) {
return false;
}
let argArr = [];
enumerateObject(args, (arg, value) => {
argArr.push(`${arg}: ${value}`);
});
element.setAttribute(cuiArg, argArr.join("; "));
return true;
}
function* counter() {
let idx = 0;
while (true) {
let reset = yield idx++;
if (reset || idx > 200000) {
idx = 0;
}
}
}
function getHandlerExtendingOrNull(target, fName) {
if (!is(target.$handlers)) {
return null;
}
for (let handler in target.$handlers) {
if (target.$handlers.hasOwnProperty(handler)) {
let h = target.$handlers[handler];
if (hasFunction(h, fName))
return h;
}
}
return null;
}
/**
* Checks whether property exists on the object and it is a function
* @param obj - object
* @param fName - property name
*/
function hasFunction(obj, fName) {
return is(obj[fName]) && typeof obj[fName] === 'function';
}
/**
* Gets closest parent element which is a cUI element
* @param element
*/
function getParentCuiElement(element) {
if (!is(element)) {
return undefined;
}
let parent = element.parentElement;
return is(parent) && is(parent.$cuid) ? parent : getParentCuiElement(parent);
}
/**
* Calculates element height by calculating childerns heights
* @param element
*/
function getChildrenHeight(element) {
let height = 0;
if (!element) {
return -1;
}
Array.from(element.children).forEach((child) => {
height += child.getBoundingClientRect().height;
});
return height > 0 ? height + 4 : height;
}
function enumerateObject(object, callback) {
if (!are(object, callback)) {
return;
}
for (let prop in object) {
if (object.hasOwnProperty(prop)) {
callback(prop, object[prop]);
}
}
}
function round(value, decimalPlaces) {
const multiplier = Math.pow(10, decimalPlaces);
return Math.floor(value) / multiplier;
}
function calculateNextIndex(val, currentIndex, totalLength) {
let idx = -1;
switch (val) {
case 'prev':
idx = currentIndex <= 0 ? totalLength - 1 : currentIndex - 1;
break;
case 'next':
idx = currentIndex < totalLength - 1 ? currentIndex + 1 : 0;
break;
case 'first':
idx = 0;
break;
case 'last':
idx = totalLength - 1;
default:
idx = getIntOrDefault(val, -1);
break;
}
return idx;
}
function getFirstMatching(array, callback) {
let count = array.length;
if (!array || count === 0) {
return undefined;
}
for (let idx = 0; idx < count; idx++) {
if (callback(array[idx], idx)) {
return array[idx];
}
}
return undefined;
}
function mapObject(input, callback) {
return callback(input);
}
function mapObjectArray(input, callback) {
return input.map((item) => {
return mapObject(item, callback);
});
}
/**
* Delays callback execution by specific time. Callback cannot be called again until previous execution finishes or was cancelled
* @param callback - callback to execute
* @param delayTime - time in ms that execution shall be delayed by
* @returns Cancel callback
*/
function functions_delay(callback, delayTime) {
if (!are(callback, delayTime)) {
throw new Error("[delay]: Input arguments are not correct");
}
let id = null;
return function (...args) {
if (id === null) {
id = setTimeout(() => {
callback(...args);
id = null;
}, delayTime);
}
return function () {
if (id !== null) {
clearTimeout(id);
id = null;
}
};
};
}
function splitColon(text) {
let ret = [];
if (!is(text)) {
return ret;
}
let split = text.split(":");
if (split.length === 1) {
return split;
}
let tag = split.shift();
// @ts-ignore tag is always defined
return [tag, split.join(":")];
}
// CONCATENATED MODULE: ./src/core/models/setup.ts
class CuiSetup {
constructor() {
this.autoLightMode = false;
this.scrollThreshold = 20;
this.resizeThreshold = 20;
this.prefix = "cui";
this.plugins = {};
}
fromInit(init) {
var _a;
this.prefix = (_a = init.prefix) !== null && _a !== void 0 ? _a : "cui";
this.logLevel = init.logLevel;
this.cacheSize = init.cacheSize;
this.autoLightMode = init.autoLightMode;
this.animationTime = init.animationTime;
this.animationTimeShort = init.animationTimeShort;
this.animationTimeLong = init.animationTimeLong;
this.scrollThreshold = init.scrollThreshold;
this.resizeThreshold = init.resizeThreshold;
return this;
}
}
class CuiSetupInit {
constructor() {
this.prefix = 'cui';
this.app = '$cui';
this.logLevel = 'warning';
this.interaction = 'async';
this.animationTime = 300;
this.animationTimeShort = 150;
this.animationTimeLong = 500;
this.cacheSize = 500;
this.autoLightMode = false;
this.scrollThreshold = 20;
this.resizeThreshold = 20;
this.root = document.body;
this.busSetup = undefined;
this.development = undefined;
}
}
// CONCATENATED MODULE: ./src/core/utils/logger.ts
class CuiLogger {
constructor(name, level) {
this.level = level;
this.component = name;
this.id = "-";
}
setLevel(level) {
this.level = level;
}
setId(id) {
this.id = id;
}
debug(message, functionName) {
if (this.level === 'debug') {
console.log(this.prepString(message, "debug", functionName));
}
}
error(message, functionName) {
if (this.level === 'error' || this.level === 'debug' || this.level === 'warning')
console.error(this.prepString(message, "error", functionName));
}
warning(message, functionName) {
if (this.level === 'warning' || this.level === 'debug')
console.warn(this.prepString(message, "warning", functionName));
}
exception(e, functionName) {
console.error(this.prepString(`An exception occured: ${e.name}: ${e.message}`, "exception", functionName));
if (this.level === 'debug')
console.error(e.stack);
}
performance(callback, functionName) {
if (this.level !== 'debug') {
return;
}
let start = Date.now();
callback();
console.log(this.prepString(`Performance measure: ${Date.now() - start}ms`, "performance", functionName));
}
prepString(message, level, functionName) {
return `[${new Date().toLocaleString()}][${level}][${this.component}][${functionName !== null && functionName !== void 0 ? functionName : '-'}][${this.id}][${message}]`;
}
}
// CONCATENATED MODULE: ./src/core/factories/logger.ts
/**
*
*/
class logger_CuiLoggerFactory {
/**
* Gets new instance of component focused logger
* @param name - component name
*/
static get(name, logLevel) {
return new CuiLogger(name, logLevel !== null && logLevel !== void 0 ? logLevel : STATICS.logLevel);
}
}
// CONCATENATED MODULE: ./src/core/observers/mutations.ts
var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, privateMap, value) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to set private field on non-instance");
}
privateMap.set(receiver, value);
return value;
};
var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, privateMap) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to get private field on non-instance");
}
return privateMap.get(receiver);
};
var _observer, _options, _element, _components, _attributes, _utils, _queryString, _isObserving, _observer_1, _element_1, _disabled, _options_1;
class mutations_CuiMutationObserver {
constructor(element, utils) {
_observer.set(this, void 0);
_options.set(this, void 0);
_element.set(this, void 0);
_components.set(this, void 0);
_attributes.set(this, void 0);
_utils.set(this, void 0);
_queryString.set(this, void 0);
__classPrivateFieldSet(this, _observer, undefined);
this.plugins = undefined;
__classPrivateFieldSet(this, _options, undefined);
__classPrivateFieldSet(this, _element, element);
this._log = logger_CuiLoggerFactory.get('CuiMutationObserver');
__classPrivateFieldSet(this, _components, []);
__classPrivateFieldSet(this, _attributes, []);
__classPrivateFieldSet(this, _utils, utils);
__classPrivateFieldSet(this, _queryString, "");
}
setPlugins(plugins) {
this.plugins = plugins;
return this;
}
setComponents(components) {
__classPrivateFieldSet(this, _components, components);
return this;
}
setAttributes(attributes) {
__classPrivateFieldSet(this, _options, {
attributes: true,
subtree: true,
childList: true,
attributeFilter: attributes
});
__classPrivateFieldSet(this, _attributes, attributes);
__classPrivateFieldSet(this, _queryString, joinAttributesForQuery(attributes));
return this;
}
start() {
this._log.debug("Starting");
if (!__classPrivateFieldGet(this, _options)) {
this._log.error("Cannot start - options are not defined");
return this;
}
__classPrivateFieldSet(this, _observer, new MutationObserver(this.mutationCallback.bind(this)));
__classPrivateFieldGet(this, _observer).observe(__classPrivateFieldGet(this, _element), __classPrivateFieldGet(this, _options));
this._log.debug("Started");
return this;
}
stop() {
this._log.debug("Stopping");
if (!__classPrivateFieldGet(this, _observer)) {
this._log.debug("Observer not available");
return this;
}
__classPrivateFieldGet(this, _observer).disconnect();
__classPrivateFieldSet(this, _observer, undefined);
this._log.debug("Stopped");
return this;
}
mutationCallback(mutations, observer) {
mutations.forEach((mutation) => {
switch (mutation.type) {
case 'attributes':
const item = mutation.target;
if (are(mutation.attributeName, item)) {
// @ts-ignore - attribute name is checked
if (are(item.$handlers, item.$handlers[mutation.attributeName])) {
// @ts-ignore - attribute name is checked
item.$handlers[mutation.attributeName].refresh(parseAttribute(item, mutation.attributeName));
}
}
else {
this._log.error("Mutation attribute doesn't not exisist");
}
break;
case 'childList':
this.handleChildListMutation(mutation);
break;
}
if (is(this.plugins)) {
// @ts-ignore plugins is defined here
this.plugins.onMutation(mutation).then(() => {
//
});
}
});
}
handleChildListMutation(mutation) {
const addedLen = mutation.addedNodes.length;
const removedLen = mutation.removedNodes.length;
if (addedLen > 0) {
this._log.debug("Registering added nodes: " + addedLen);
this.handleAddedNodes(mutation.addedNodes);
}
else if (removedLen > 0) {
this._log.debug("Removing nodes: " + removedLen);
this.handleRemovedNodes(mutation.removedNodes);
}
}
handleAddedNodes(nodes) {
nodes.forEach((node) => {
try {
registerCuiElement(node, __classPrivateFieldGet(this, _components), __classPrivateFieldGet(this, _attributes), __classPrivateFieldGet(this, _utils));
let childrens = node.hasChildNodes() ? node.querySelectorAll(__classPrivateFieldGet(this, _queryString)) : null;
if (is(childrens)) {
childrens.forEach((child) => {
registerCuiElement(child, __classPrivateFieldGet(this, _components), __classPrivateFieldGet(this, _attributes), __classPrivateFieldGet(this, _utils));
});
}
}
catch (e) {
this._log.exception(e);
}
});
}
handleRemovedNodes(nodes) {
nodes.forEach((node) => {
this.destroySingleElement(node);
let childrens = node.hasChildNodes() ? node.querySelectorAll(__classPrivateFieldGet(this, _queryString)) : null;
if (is(childrens)) {
childrens.forEach((child) => {
this.destroySingleElement(child);
});
}
});
}
destroySingleElement(node) {
let element = node;
if (element.$handlers) {
for (let name in element.$handlers) {
if (element.$handlers.hasOwnProperty(name)) {
try {
element.$handlers[name].destroy();
}
catch (e) {
this._log.exception(e, 'remove - ' + name);
}
}
}
}
}
}
_observer = new WeakMap(), _options = new WeakMap(), _element = new WeakMap(), _components = new WeakMap(), _attributes = new WeakMap(), _utils = new WeakMap(), _queryString = new WeakMap();
class CuiComponentMutationHandler {
constructor(target) {
_isObserving.set(this, void 0);
_observer_1.set(this, void 0);
_element_1.set(this, void 0);
_disabled.set(this, void 0);
_options_1.set(this, {
childList: true,
subtree: true
});
__classPrivateFieldSet(this, _observer_1, undefined);
__classPrivateFieldSet(this, _disabled, false);
__classPrivateFieldSet(this, _isObserving, false);
__classPrivateFieldSet(this, _element_1, target);
}
observe() {
if (!__classPrivateFieldGet(this, _isObserving) && !__classPrivateFieldGet(this, _disabled) && __classPrivateFieldGet(this, _observer_1)) {
__classPrivateFieldGet(this, _observer_1).observe(__classPrivateFieldGet(this, _element_1), __classPrivateFieldGet(this, _options_1));
__classPrivateFieldSet(this, _isObserving, true);
}
}
unobserve() {
if (__classPrivateFieldGet(this, _isObserving) && __classPrivateFieldGet(this, _observer_1)) {
__classPrivateFieldGet(this, _observer_1).disconnect();
__classPrivateFieldSet(this, _isObserving, false);
}
}
isObserving() {
return __classPrivateFieldGet(this, _isObserving);
}
disable(flag) {
__classPrivateFieldSet(this, _disabled, flag);
if (__classPrivateFieldGet(this, _disabled)) {
this.unobserve();
}
}
onMutation(callback) {
if (__classPrivateFieldGet(this, _isObserving))
this.unobserve();
__classPrivateFieldSet(this, _observer_1, new MutationObserver(callback));
}
}
_isObserving = new WeakMap(), _observer_1 = new WeakMap(), _element_1 = new WeakMap(), _disabled = new WeakMap(), _options_1 = new WeakMap();
// CONCATENATED MODULE: ./src/core/utils/interactions.ts
var interactions_classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, privateMap, value) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to set private field on non-instance");
}
privateMap.set(receiver, value);
return value;
};
var interactions_classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, privateMap) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to get private field on non-instance");
}
return privateMap.get(receiver);
};
var _writes, _reads, _raf, _isScheduled, _limit, _reportCallback;
class FastDom {
constructor() {
_writes.set(this, void 0);
_reads.set(this, void 0);
_raf.set(this, void 0);
_isScheduled.set(this, false);
_limit.set(this, void 0);
_reportCallback.set(this, void 0);
interactions_classPrivateFieldSet(this, _raf, window.requestAnimationFrame.bind(window));
interactions_classPrivateFieldSet(this, _writes, []);
interactions_classPrivateFieldSet(this, _reads, []);
interactions_classPrivateFieldSet(this, _limit, 5);
interactions_classPrivateFieldSet(this, _reportCallback, undefined);
}
onError(callback) {
interactions_classPrivateFieldSet(this, _reportCallback, callback);
}
mutate(callback, ctx, ...args) {
interactions_classPrivateFieldGet(this, _reads).push(this.createTask(callback, ctx, ...args));
this.schedule();
}
fetch(callback, ctx, ...args) {
interactions_classPrivateFieldGet(this, _writes).push(this.createTask(callback, ctx, ...args));
this.schedule();
}
createTask(callback, ctx, ...args) {
return ctx || args ? callback.bind(ctx, ...args) : callback;
}
run(tasks) {
let task = null;
while (task = tasks.shift()) {
task();
}
}
schedule(recursion) {
if (!interactions_classPrivateFieldGet(this, _isScheduled)) {
interactions_classPrivateFieldSet(this, _isScheduled, true);
if (recursion && recursion >= interactions_classPrivateFieldGet(this, _limit)) {
throw new Error("Fast Dom limit reached");
}
else {
interactions_classPrivateFieldGet(this, _raf).call(this, this.flush.bind(this, recursion));
}
}
}
flush(recursion) {
let rec = recursion !== null && recursion !== void 0 ? recursion : 0;
let error = null;
let writes = interactions_classPrivateFieldGet(this, _writes);
let reads = interactions_classPrivateFieldGet(this, _reads);
try {
this.run(reads);
this.run(writes);
}
catch (e) {
if (interactions_classPrivateFieldGet(this, _reportCallback)) {
interactions_classPrivateFieldGet(this, _reportCallback).call(this, e);
}
else {
console.error(`An error has been captured in interactions: ${e.message}`);
//console.error(e)
}
error = e;
}
interactions_classPrivateFieldSet(this, _isScheduled, false);
if (error || interactions_classPrivateFieldGet(this, _writes).length || interactions_classPrivateFieldGet(this, _reads).length) {
this.schedule(rec + 1);
}
}
}
_writes = new WeakMap(), _reads = new WeakMap(), _raf = new WeakMap(), _isScheduled = new WeakMap(), _limit = new WeakMap(), _reportCallback = new WeakMap();
class SyncInteractions {
constructor() {
this.isRunning = false;
this.tasks = [];
this.raf = window.requestAnimationFrame.bind(window);
}
mutate(callback, ctx, ...args) {
this.tasks.push(this.createTask(callback, ctx, ...args));
this.schedule();
}
fetch(callback, ctx, ...args) {
this.tasks.push(this.createTask(callback, ctx, ...args));
this.schedule();
}
schedule() {
if (!this.isRunning) {
this.isRunning = true;
this.raf(this.flush.bind(this));
}
}
flush() {
let task = null;
while (task = this.tasks.shift()) {
try {
task();
}
catch (e) {
}
}
this.isRunning = false;
}
createTask(callback, ctx, ...args) {
return ctx || args ? callback.bind(ctx, ...args) : callback;
}
}
// CONCATENATED MODULE: ./src/core/factories/interactions.ts
class interactions_CuiInteractionsFactory {
/**
* Gets new instance of component focused logger
* @param type - Interactions type
*/
static get(type, errorReport) {
const interactionType = type;
switch (interactionType) {
case 'async':
const fastDom = new FastDom();
if (errorReport)
fastDom.onError(errorReport);
return fastDom;
default:
return new SyncInteractions();
}
}
}
// CONCATENATED MODULE: ./src/core/utils/dictionary.ts
var dictionary_classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, privateMap, value) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to set private field on non-instance");
}
privateMap.set(receiver, value);
return value;
};
var dictionary_classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, privateMap) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to get private field on non-instance");
}
return privateMap.get(receiver);
};
var _keys, _values;
class dictionary_CuiDictionary {
constructor(init) {
_keys.set(this, void 0);
_values.set(this, void 0);
dictionary_classPrivateFieldSet(this, _keys, []);
dictionary_classPrivateFieldSet(this, _values, []);
if (init) {
init.forEach(x => {
if (!is(x.key)) {
dictionary_classPrivateFieldSet(this, _keys, []);
dictionary_classPrivateFieldSet(this, _values, []);
throw new ArgumentError("Key is empty");
}
this.add(x.key, x.value);
});
}
}
add(key, value) {
this.throwOnEmptyKey(key);
if (this.containsKey(key))
throw new Error("Key already exists");
dictionary_classPrivateFieldGet(this, _keys).push(key);
dictionary_classPrivateFieldGet(this, _values).push(value);
}
remove(key) {
if (!is(key)) {
return;
}
let index = dictionary_classPrivateFieldGet(this, _keys).indexOf(key);
if (index >= 0) {
dictionary_classPrivateFieldGet(this, _keys).splice(index, 1);
dictionary_classPrivateFieldGet(this, _values).splice(index, 1);
}
}
get(key) {
this.throwOnEmptyKey(key);
let index = this.indexOf(key);
if (index < 0) {
return undefined;
}
return dictionary_classPrivateFieldGet(this, _values)[index];
}
containsKey(key) {
return is(key) && this.indexOf(key) >= 0;
}
keys() {
return dictionary_classPrivateFieldGet(this, _keys);
}
values() {
return dictionary_classPrivateFieldGet(this, _values);
}
indexOf(key) {
return is(key) ? dictionary_classPrivateFieldGet(this, _keys).indexOf(key) : -1;