@fe6/water-pro
Version:
An enterprise-class UI design language and Vue-based implementation
218 lines (182 loc) • 7.7 kB
JavaScript
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
/* eslint-disable prefer-rest-params */
function eventListener(method, elements, events, fn) {
var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
// Normalize array
if (elements instanceof HTMLCollection || elements instanceof NodeList) {
elements = Array.from(elements);
} else if (!Array.isArray(elements)) {
elements = [elements];
}
if (!Array.isArray(events)) {
events = [events];
}
var _iterator = _createForOfIteratorHelper(elements),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var el = _step.value;
var _iterator2 = _createForOfIteratorHelper(events),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var ev = _step2.value;
el[method](ev, fn, _extends({
capture: false
}, options));
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return Array.prototype.slice.call(arguments, 1);
}
/**
* Add event(s) to element(s).
* @param elements DOM-Elements
* @param events Event names
* @param fn Callback
* @param options Optional options
* @return Array passed arguments
*/
export var on = eventListener.bind(null, 'addEventListener');
/**
* Remove event(s) from element(s).
* @param elements DOM-Elements
* @param events Event names
* @param fn Callback
* @param options Optional options
* @return Array passed arguments
*/
export var off = eventListener.bind(null, 'removeEventListener');
/**
* Creates an DOM-Element out of a string (Single element).
* @param html HTML representing a single element
* @returns {Element | null} The element.
*/
export function createElementFromString(html) {
var div = document.createElement('div');
div.innerHTML = html.trim();
return div.firstElementChild;
}
/**
* Creates a new html element, every element which has
* a ':ref' attribute will be saved in a object (which will be returned)
* where the value of ':ref' is the object-key and the value the HTMLElement.
*
* It's possible to create a hierarchy if you add a ':obj' attribute. Every
* sibling will be added to the object which will get the name from the 'data-con' attribute.
*
* If you want to create an Array out of multiple elements, you can use the ':arr' attribute,
* the value defines the key and all elements, which has the same parent and the same 'data-arr' attribute,
* would be added to it.
*
* @param str - The HTML String.
*/
export function createFromTemplate(str) {
// Removes an attribute from a HTMLElement and returns the value.
var removeAttribute = function removeAttribute(el, name) {
var value = el.getAttribute(name);
el.removeAttribute(name);
return value;
}; // Recursive function to resolve template
var resolve = function resolve(element) {
var base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
// Check key and container attribute
var con = removeAttribute(element, ':obj');
var key = removeAttribute(element, ':ref');
var subtree = con ? base[con] = {} : base; // Check and save element
key && (base[key] = element);
for (var _i = 0, _Array$from = Array.from(element.children); _i < _Array$from.length; _i++) {
var child = _Array$from[_i];
var arr = removeAttribute(child, ':arr');
var sub = resolve(child, arr ? {} : subtree);
if (arr) {
// Check if there is already an array and add element
(subtree[arr] || (subtree[arr] = [])).push(Object.keys(sub).length ? sub : child);
}
}
return base;
};
return resolve(createElementFromString(str));
}
/**
* Polyfill for safari & firefox for the eventPath event property.
* @param evt The event object.
* @return [String] event path.
*/
export function eventPath(evt) {
var path = evt.path || evt.composedPath && evt.composedPath();
if (path) {
return path;
}
var el = evt.target.parentElement;
path = [evt.target, el];
while (el = el.parentElement) {
path.push(el);
}
path.push(document, window);
return path;
}
/**
* Resolves a HTMLElement by query.
* @param val
* @returns {null|Document|Element}
*/
export function resolveElement(val) {
if (val instanceof Element) {
return val;
} else if (typeof val === 'string') {
return val.split(/>>/g).reduce(function (pv, cv, ci, a) {
pv = pv.querySelector(cv);
return ci < a.length - 1 ? pv.shadowRoot : pv;
}, document);
}
return null;
}
/**
* Creates the ability to change numbers in an input field with the scroll-wheel.
* @param el
* @param mapper
*/
export function adjustableInputNumbers(el) {
var mapper = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (v) {
return v;
};
function handleScroll(e) {
var inc = [0.001, 0.01, 0.1][Number(e.shiftKey || e.ctrlKey * 2)] * (e.deltaY < 0 ? 1 : -1);
var index = 0;
var off = el.selectionStart;
el.value = el.value.replace(/[\d.]+/g, function (v, i) {
// Check if number is in cursor range and increase it
if (i <= off && i + v.length >= off) {
off = i;
return mapper(Number(v), inc, index);
}
index++;
return v;
});
el.focus();
el.setSelectionRange(off, off); // Prevent default and trigger input event
e.preventDefault();
el.dispatchEvent(new Event('input'));
} // Bind events
on(el, 'focus', function () {
return on(window, 'wheel', handleScroll, {
passive: false
});
});
on(el, 'blur', function () {
return off(window, 'wheel', handleScroll);
});
}