@syncfusion/ej2-base
Version:
A common package of Essential JS 2 base libraries, methods and class definitions
510 lines (509 loc) • 17.2 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* Functions related to dom operations.
*/
import { EventHandler } from './event-handler';
import { isNullOrUndefined, getValue, setValue, isObject, extend } from './util';
var SVG_REG = /^svg|^path|^g/;
/**
* Function to create Html element.
*
* @param {string} tagName - Name of the tag, id and class names.
* @param {ElementProperties} properties - Object to set properties in the element.
* @param {ElementProperties} properties.id - To set the id to the created element.
* @param {ElementProperties} properties.className - To add classes to the element.
* @param {ElementProperties} properties.innerHTML - To set the innerHTML to element.
* @param {ElementProperties} properties.styles - To set the some custom styles to element.
* @param {ElementProperties} properties.attrs - To set the attributes to element.
* @returns {any} ?
* @private
*/
export function createElement(tagName, properties) {
var element = (SVG_REG.test(tagName) ? document.createElementNS('http://www.w3.org/2000/svg', tagName) : document.createElement(tagName));
if (typeof (properties) === 'undefined') {
return element;
}
element.innerHTML = (properties.innerHTML ? properties.innerHTML : '');
if (properties.className !== undefined) {
element.className = properties.className;
}
if (properties.id !== undefined) {
element.id = properties.id;
}
if (properties.styles !== undefined) {
element.style.cssText = properties.styles;
}
if (properties.attrs !== undefined) {
attributes(element, properties.attrs);
}
return element;
}
/**
* Updates the CSS text of an element by merging new styles with existing styles.
*
* @param {HTMLElement} element - The element whose styles need to be updated.
* @param {string} cssText - The new CSS styles to be added or updated.
* @returns {void}
*/
export function updateCSSText(element, cssText) {
var existingStyles = element.style.cssText.split(';').reduce(function (styles, style) {
var _a = style.split(':'), key = _a[0], value = _a[1];
if (key && value) {
styles[key.trim()] = value.trim();
}
return styles;
}, {});
var newStyles = cssText.split(';').reduce(function (styles, style) {
var _a = style.split(':'), key = _a[0], value = _a[1];
if (key && value) {
styles[key.trim()] = value.trim();
}
return styles;
}, {});
var styleElement = document.createElement('div');
// Use safe iteration over keys using Object.keys
Object.keys(__assign({}, existingStyles, newStyles)).forEach(function (key) {
styleElement.style.setProperty(key, newStyles[key] || existingStyles[key]);
});
element.style.cssText = styleElement.style.cssText;
}
/**
* The function used to add the classes to array of elements
*
* @param {Element[]|NodeList} elements - An array of elements that need to add a list of classes
* @param {string|string[]} classes - String or array of string that need to add an individual element as a class
* @returns {any} .
* @private
*/
export function addClass(elements, classes) {
var classList = getClassList(classes);
var regExp = RegExp;
for (var _i = 0, _a = elements; _i < _a.length; _i++) {
var ele = _a[_i];
for (var _b = 0, classList_1 = classList; _b < classList_1.length; _b++) {
var className = classList_1[_b];
if (isObject(ele)) {
var curClass = getValue('attributes.className', ele);
if (isNullOrUndefined(curClass)) {
setValue('attributes.className', className, ele);
}
else if (!new regExp('\\b' + className + '\\b', 'i').test(curClass)) {
setValue('attributes.className', curClass + ' ' + className, ele);
}
}
else {
if (!ele.classList.contains(className)) {
ele.classList.add(className);
}
}
}
}
return elements;
}
/**
* The function used to add the classes to array of elements
*
* @param {Element[]|NodeList} elements - An array of elements that need to remove a list of classes
* @param {string|string[]} classes - String or array of string that need to add an individual element as a class
* @returns {any} .
* @private
*/
export function removeClass(elements, classes) {
var classList = getClassList(classes);
for (var _i = 0, _a = elements; _i < _a.length; _i++) {
var ele = _a[_i];
var flag = isObject(ele);
var canRemove = flag ? getValue('attributes.className', ele) : ele.className !== '';
if (canRemove) {
for (var _b = 0, classList_2 = classList; _b < classList_2.length; _b++) {
var className = classList_2[_b];
if (flag) {
var classes_1 = getValue('attributes.className', ele);
var classArr = classes_1.split(' ');
var index = classArr.indexOf(className);
if (index !== -1) {
classArr.splice(index, 1);
}
setValue('attributes.className', classArr.join(' '), ele);
}
else {
ele.classList.remove(className);
}
}
}
}
return elements;
}
/**
* The function used to get classlist.
*
* @param {string | string[]} classes - An element the need to check visibility
* @returns {string[]} ?
* @private
*/
function getClassList(classes) {
var classList = [];
if (typeof classes === 'string') {
classList.push(classes);
}
else {
classList = classes;
}
return classList;
}
/**
* The function used to check element is visible or not.
*
* @param {Element|Node} element - An element the need to check visibility
* @returns {boolean} ?
* @private
*/
export function isVisible(element) {
var ele = element;
return (ele.style.visibility === '' && ele.offsetWidth > 0);
}
/**
* The function used to insert an array of elements into a first of the element.
*
* @param {Element[]|NodeList} fromElements - An array of elements that need to prepend.
* @param {Element} toElement - An element that is going to prepend.
* @param {boolean} isEval - ?
* @returns {Element[] | NodeList} ?
* @private
*/
export function prepend(fromElements, toElement, isEval) {
var docFrag = document.createDocumentFragment();
for (var _i = 0, _a = fromElements; _i < _a.length; _i++) {
var ele = _a[_i];
docFrag.appendChild(ele);
}
toElement.insertBefore(docFrag, toElement.firstElementChild);
if (isEval) {
executeScript(toElement);
}
return fromElements;
}
/**
* The function used to insert an array of elements into last of the element.
*
* @param {Element[]|NodeList} fromElements - An array of elements that need to append.
* @param {Element} toElement - An element that is going to prepend.
* @param {boolean} isEval - ?
* @returns {Element[] | NodeList} ?
* @private
*/
export function append(fromElements, toElement, isEval) {
var docFrag = document.createDocumentFragment();
if (fromElements instanceof NodeList) {
while (fromElements.length > 0) {
docFrag.appendChild(fromElements[0]);
}
}
else {
for (var _i = 0, _a = fromElements; _i < _a.length; _i++) {
var ele = _a[_i];
docFrag.appendChild(ele);
}
}
toElement.appendChild(docFrag);
if (isEval) {
executeScript(toElement);
}
return fromElements;
}
/**
* The function is used to evaluate script from Ajax request
*
* @param {Element} ele - An element is going to evaluate the script
* @returns {void} ?
*/
function executeScript(ele) {
var eleArray = ele.querySelectorAll('script');
eleArray.forEach(function (element) {
var script = document.createElement('script');
script.text = element.innerHTML;
document.head.appendChild(script);
detach(script);
});
}
/**
* The function used to remove the element from parentnode
*
* @param {Element|Node|HTMLElement} element - An element that is going to detach from the Dom
* @returns {any} ?
* @private
*/
export function detach(element) {
var parentNode = element.parentNode;
if (parentNode) {
return parentNode.removeChild(element);
}
}
/**
* The function used to remove the element from Dom also clear the bounded events
*
* @param {Element|Node|HTMLElement} element - An element remove from the Dom
* @returns {void} ?
* @private
*/
export function remove(element) {
var parentNode = element.parentNode;
EventHandler.clearEvents(element);
parentNode.removeChild(element);
}
/**
* The function helps to set multiple attributes to an element
*
* @param {Element|Node} element - An element that need to set attributes.
* @param {string} attributes - JSON Object that is going to as attributes.
* @returns {Element} ?
* @private
*/
export function attributes(element, attributes) {
var keys = Object.keys(attributes);
var ele = element;
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
var key = keys_1[_i];
if (isObject(ele)) {
var iKey = key;
if (key === 'tabindex') {
iKey = 'tabIndex';
}
ele.attributes["" + iKey] = attributes["" + key];
}
else {
ele.setAttribute(key, attributes["" + key]);
}
}
return ele;
}
/**
* The function selects the element from giving context.
*
* @param {string} selector - Selector string need fetch element
* @param {Document|Element} context - It is an optional type, That specifies a Dom context.
* @param {boolean} needsVDOM ?
* @returns {any} ?
* @private
*/
export function select(selector, context, needsVDOM) {
if (context === void 0) { context = document; }
selector = querySelectId(selector);
return context.querySelector(selector);
}
/**
* The function selects an array of element from the given context.
*
* @param {string} selector - Selector string need fetch element
* @param {Document|Element} context - It is an optional type, That specifies a Dom context.
* @param {boolean} needsVDOM ?
* @returns {HTMLElement[]} ?
* @private
*/
export function selectAll(selector, context, needsVDOM) {
if (context === void 0) { context = document; }
selector = querySelectId(selector);
var nodeList = context.querySelectorAll(selector);
return nodeList;
}
/**
* The function selects an id of element from the given context.
*
* @param {string} selector - Selector string need fetch element
* @returns {string} ?
* @private
*/
function querySelectId(selector) {
var charRegex = /(!|"|\$|%|&|'|\(|\)|\*|\/|:|;|<|=|\?|@|\]|\^|`|{|}|\||\+|~)/g;
if (selector.match(/#[0-9]/g) || selector.match(charRegex)) {
var idList = selector.split(',');
for (var i = 0; i < idList.length; i++) {
var list = idList[parseInt(i.toString(), 10)].split(' ');
for (var j = 0; j < list.length; j++) {
if (list[parseInt(j.toString(), 10)].indexOf('#') > -1) {
if (!list[parseInt(j.toString(), 10)].match(/\[.*\]/)) {
var splitId = list[parseInt(j.toString(), 10)].split('#');
if (splitId[1].match(/^\d/) || splitId[1].match(charRegex)) {
var setId = list[parseInt(j.toString(), 10)].split('.');
setId[0] = setId[0].replace(/#/, '[id=\'') + '\']';
list[parseInt(j.toString(), 10)] = setId.join('.');
}
}
}
}
idList[parseInt(i.toString(), 10)] = list.join(' ');
}
return idList.join(',');
}
return selector;
}
/**
* Returns single closest parent element based on class selector.
*
* @param {Element} element - An element that need to find the closest element.
* @param {string} selector - A classSelector of closest element.
* @returns {Element} ?
* @private
*/
export function closest(element, selector) {
var el = element;
if (typeof el.closest === 'function') {
return el.closest(selector);
}
while (el && el.nodeType === 1) {
if (matches(el, selector)) {
return el;
}
el = el.parentNode;
}
return null;
}
/**
* Returns all sibling elements of the given element.
*
* @param {Element|Node} element - An element that need to get siblings.
* @returns {Element[]} ?
* @private
*/
export function siblings(element) {
var siblings = [];
var childNodes = Array.prototype.slice.call(element.parentNode.childNodes);
for (var _i = 0, childNodes_1 = childNodes; _i < childNodes_1.length; _i++) {
var curNode = childNodes_1[_i];
if (curNode.nodeType === Node.ELEMENT_NODE && element !== curNode) {
siblings.push(curNode);
}
}
return siblings;
}
/**
* set the value if not exist. Otherwise set the existing value
*
* @param {HTMLElement} element - An element to which we need to set value.
* @param {string} property - Property need to get or set.
* @param {string} value - value need to set.
* @returns {string} ?
* @private
*/
export function getAttributeOrDefault(element, property, value) {
var attrVal;
var isObj = isObject(element);
if (isObj) {
attrVal = getValue('attributes.' + property, element);
}
else {
attrVal = element.getAttribute(property);
}
if (isNullOrUndefined(attrVal) && value) {
if (!isObj) {
element.setAttribute(property, value.toString());
}
else {
element.attributes["" + property] = value;
}
attrVal = value;
}
return attrVal;
}
/**
* Set the style attributes to Html element.
*
* @param {HTMLElement} element - Element which we want to set attributes
* @param {any} attrs - Set the given attributes to element
* @returns {void} ?
* @private
*/
export function setStyleAttribute(element, attrs) {
if (attrs !== undefined) {
Object.keys(attrs).forEach(function (key) {
element.style["" + key] = attrs["" + key];
});
}
}
/**
* Method for add and remove classes to a dom element.
*
* @param {Element} element - Element for add and remove classes
* @param {string[]} addClasses - List of classes need to be add to the element
* @param {string[]} removeClasses - List of classes need to be remove from the element
* @returns {void} ?
* @private
*/
export function classList(element, addClasses, removeClasses) {
addClass([element], addClasses);
removeClass([element], removeClasses);
}
/**
* Method to check whether the element matches the given selector.
*
* @param {Element} element - Element to compare with the selector.
* @param {string} selector - String selector which element will satisfy.
* @returns {void} ?
* @private
*/
export function matches(element, selector) {
var matches = element.matches || element.msMatchesSelector || element.webkitMatchesSelector;
if (matches) {
return matches.call(element, selector);
}
else {
return [].indexOf.call(document.querySelectorAll(selector), element) !== -1;
}
}
/**
* Method to get the html text from DOM.
*
* @param {HTMLElement} ele - Element to compare with the selector.
* @param {string} innerHTML - String selector which element will satisfy.
* @returns {void} ?
* @private
*/
export function includeInnerHTML(ele, innerHTML) {
ele.innerHTML = innerHTML;
}
/**
* Method to get the containsclass.
*
* @param {HTMLElement} ele - Element to compare with the selector.
* @param {string} className - String selector which element will satisfy.
* @returns {any} ?
* @private
*/
export function containsClass(ele, className) {
if (isObject(ele)) {
var regExp = RegExp;
return new regExp('\\b' + className + '\\b', 'i').test(ele.attributes.className);
}
else {
return ele.classList.contains(className);
}
}
/**
* Method to check whether the element matches the given selector.
*
* @param {Object} element - Element to compare with the selector.
* @param {boolean} deep ?
* @returns {any} ?
* @private
*/
export function cloneNode(element, deep) {
if (isObject(element)) {
if (deep) {
return extend({}, {}, element, true);
}
}
else {
return element.cloneNode(deep);
}
}