/* eslint-disable */ // Vendored third-party code — preserve original style. See header below. import { globalState } from '../app/global-state'; import './css/ladda-themeless-zoomin.min.css'; /*! Ladda http://lab.hakim.se/ladda MIT licensed Copyright (C) 2016 Hakim El Hattab, http://hakim.se ....Lightweight adaptation for Inviton API needs */ namespace laddaLiteUtils { function createButtonSpinner(spinnerArgs: any): any { const prefixes = [ 'webkit', 'Moz', 'ms', 'O', ]; const animations: any = {}; let useCssAnimations: any; /* Whether to use CSS animations or setTimeout */ /** * Utility function to create elements. If no tag name is given, * a DIV is created. Optionally properties can be passed. */ function createEl(tag?: any, prop?: any) { const el = document.createElement(tag || 'div'); let n; for (n in prop) { el[n] = prop[n]; } return el; } /** * Appends children and returns the parent. */ function ins(parent: any, ...items: Array) { for (let i = 1, n = arguments.length; i < n; i++) { parent.appendChild(arguments[i]); } return parent; } /** * Insert a new stylesheet to hold the @keyframe or VML rules. */ const sheet = (function () { const el = createEl('style', { type: 'text/css' }); ins(document.getElementsByTagName('head')[0], el); return el.sheet || el.styleSheet; })(); /** * Creates an opacity keyframe animation rule and returns its name. * Since most mobile Webkits have timing issues with animation-delay, * we create separate rules for each line/segment. */ function addAnimation( alpha: any, trail: any, i: any, lines: any, ) { const name = [ 'opacity', trail, ~~(alpha * 100), i, lines, ].join('-'); const start = 0.01 + (i / lines) * 100; const z = Math.max(1 - ((1 - alpha) / trail) * (100 - start), alpha); const prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase(); const pre = (prefix && `-${prefix}-`) || ''; if (!animations[name]) { sheet.insertRule(`@${ pre }keyframes ${ name }{` + `0%{opacity:${ z }}${ start }%{opacity:${ alpha }}${ start + 0.01 }%{opacity:1}${ (start + trail) % 100 }%{opacity:${ alpha }}` + `100%{opacity:${ z }}` + `}`, sheet.cssRules.length); animations[name] = 1; } return name; } /** * Tries various vendor prefixes and returns the first supported property. */ function vendor(el: any, prop: any) { const s = el.style; let pp; let i; prop = prop.charAt(0).toUpperCase() + prop.slice(1); for (i = 0; i < prefixes.length; i++) { pp = prefixes[i] + prop; if (s[pp] !== undefined) { return pp; } } if (s[prop] !== undefined) { return prop; } } /** * Sets multiple style properties at once. */ function css(el: any, prop: any) { for (const n in prop) { el.style[vendor(el, n) || n] = prop[n]; } return el; } /** * Fills in default values. */ function merge(obj: any, ...newObj: Array) { for (let i = 1; i < arguments.length; i++) { const def = arguments[i]; for (const n in def) { if (obj[n] === undefined) { obj[n] = def[n]; } } } return obj; } /** * Returns the absolute page-offset of the given element. */ function pos(el: any) { const o = { x: el.offsetLeft, y: el.offsetTop }; while ((el = el.offsetParent)) { (o.x += el.offsetLeft), (o.y += el.offsetTop); } return o; } /** * Returns the line color from the given string or array. */ function getColor(color: any, idx: any) { return typeof color == 'string' ? color : color[idx % color.length]; } const mergedOpts = merge(spinnerArgs || {}, { lines: 12, // The number of lines to draw length: 7, // The length of each line width: 5, // The line thickness radius: 10, // The radius of the inner circle rotate: 0, // Rotation offset corners: 1, // Roundness (0..1) color: '#000', // #rgb or #rrggbb direction: 1, // 1: clockwise, -1: counterclockwise speed: 1, // Rounds per second trail: 100, // Afterglow percentage opacity: 1 / 4, // Opacity of the lines fps: 20, // Frames per second when using setTimeout() zIndex: 2e9, // Use a high z-index by default className: 'spinner', // CSS class to assign to the element top: '50%', // center vertically left: '50%', // center horizontally position: 'absolute', // element position }); const probe = css(createEl('group'), { behavior: 'url(#default#VML)' }); useCssAnimations = vendor(probe, 'animation'); return { /** * Adds the spinner to the given target element. If this instance is already * spinning, it is automatically removed from its previous target b calling * stop() internally. */ spin(target: any) { this.stop(); const self = this; const o = mergedOpts; const el = (self.el = css(createEl(0, { className: o.className }), { position: o.position, width: 0, zIndex: o.zIndex, })); const mid = o.radius + o.length + o.width; css(el, { left: o.left, top: o.top, }); if (target) { target.insertBefore(el, target.firstChild || null); } el.setAttribute('role', 'progressbar'); self.lines(el, o); return self; }, stop() { const el = this.el; if (el) { if (el.parentNode) { el.parentNode.removeChild(el); } this.el = undefined; } return this; }, lines(el: any, o: any) { let i = 0; const start = ((o.lines - 1) * (1 - o.direction)) / 2; let seg; // The visual params of each spinner bar are wrapped in CSS custom // properties with the computed value as a fallback. Inline styles // don't block `var()` resolution, so consumers can override the // look by setting any of the following on a parent (e.g. on // `.ladda-spinner`, `.ladda-button`, or globally): // --ladda-bar-length bar length (default = length+width px) // --ladda-bar-thickness bar thickness (default = width px) // --ladda-bar-color bar background (default = color option) // --ladda-bar-shadow bar box-shadow (default = shadow arg) // --ladda-bar-radius bar corner radius (default = (corners*width)>>1 px) // --ladda-bar-distance translate distance from centre (default = radius px) // The per-line `rotate(...)` angle stays computed — it positions // the bar around the wheel and overriding it would break the // spinner pattern. function fill(color: any, shadow: any) { return css(createEl(), { position: 'absolute', width: `var(--ladda-bar-length, ${o.length + o.width}px)`, height: `var(--ladda-bar-thickness, ${o.width}px)`, background: `var(--ladda-bar-color, ${color})`, boxShadow: `var(--ladda-bar-shadow, ${shadow})`, transformOrigin: 'left', transform: `rotate(${~~((360 / o.lines) * i + o.rotate)}deg) translate(var(--ladda-bar-distance, ${o.radius}px), 0)`, borderRadius: `var(--ladda-bar-radius, ${(o.corners * o.width) >> 1}px)`, }); } for (; i < o.lines; i++) { seg = css(createEl(), { position: 'absolute', top: `${1 + ~(o.width / 2)}px`, transform: o.hwaccel ? 'translate3d(0,0,0)' : '', opacity: o.opacity, animation: useCssAnimations && `${addAnimation( o.opacity, o.trail, start + i * o.direction, o.lines, )} ${1 / o.speed}s linear infinite`, }); if (o.shadow) { ins(seg, css(fill('#000', '0 0 4px ' + '#000'), { top: `${2}px` })); } ins(el, ins(seg, fill(getColor(o.color, i), '0 0 1px rgba(0,0,0,.1)'))); } return el; }, /** * Internal method that adjusts the opacity of a single line. * Will be overwritten in VML fallback mode below. */ opacity( el: any, i: any, val: any, ) { if (i < el.childNodes.length) { el.childNodes[i].style.opacity = val; } }, }; } const ID_ATTRIBUTE = 'data-inv-lid'; export const instanceCache: any = {}; export const getTarget = (target: any): any => { let realTarget: HTMLElement; let retTarget: HTMLElement; let navCount = 0; if (target.jquery || target.inviDom == true) { realTarget = target[0]; } else { realTarget = target; } retTarget = realTarget; while (true) { const classList = retTarget.className; if (classList.includes('ladda-')) { if (classList.includes('ladda-button-root')) { break; } navCount += 1; retTarget = retTarget.parentElement; } else if (navCount > 3) { retTarget = realTarget; break; } else { break; } } if (!retTarget.classList.contains('ladda-button-root')) { retTarget.classList.add('ladda-button-root'); } return retTarget; }; export const getInstanceId = (target: any) => target.getAttribute(ID_ATTRIBUTE); function createSpinner(button: any) { let height = button.offsetHeight; if (height === 0) { height = parseFloat(globalState.getComputedStyle(button).height); } if (height > 32) { height *= 0.8; } const radius = height * 0.2; return createButtonSpinner({ color: '#fff', lines: 12, radius, length: radius * 0.6, width: radius < 7 ? 2 : 3, zIndex: 'auto', top: 'auto', left: 'auto', className: '', }); } function getButtonSpinner(button: any) { return button._spinner; } function wrapContent(node: any, wrapper: any) { const r = document.createRange(); r.selectNodeContents(node); r.surroundContents(wrapper); node.appendChild(wrapper); } interface LaddaInstance { timer: number; spinner: any; } /** * Brings `button` to a known-good ladda state and returns its (cached) * instance, (re)creating only whatever is missing. Safe — and meant — to be * called on every spin. * * Why idempotent instead of "create once": the host