').append(this._element).contents();
- } else {
- $result = this._renderCore(options);
- }
+ const { onRendered } = options;
+ delete options.onRendered;
- this._ensureResultInContainer($result, options.container);
- renderedCallbacks.fire($result, options.container);
-
- onRendered && onRendered();
- return $result;
+ let $result;
+ if (options.renovated && options.transclude && this._element) {
+ $result = $('
').append(this._element).contents();
+ } else {
+ // @ts-expect-error need type overload
+ $result = this._renderCore(options);
}
- _ensureResultInContainer($result, container) {
- if(!container) {
- return;
- }
+ this._ensureResultInContainer($result, options.container);
+ renderedCallbacks.fire($result, options.container);
- const $container = $(container);
- const resultInContainer = contains($container.get(0), $result.get(0));
- $container.append($result);
- if(resultInContainer) {
- return;
- }
+ onRendered && onRendered();
+ return $result;
+ }
- const resultInBody = contains(domAdapter.getBody(), $container.get(0));
- if(!resultInBody) {
- return;
- }
+ _ensureResultInContainer($result, container) {
+ if (!container) {
+ return;
+ }
- triggerShownEvent($result);
+ const $container = $(container);
+ const resultInContainer = contains($container.get(0), $result.get(0));
+ $container.append($result);
+ if (resultInContainer) {
+ return;
}
- _renderCore() {
- throw errors.Error('E0001');
+ const resultInBody = contains(domAdapter.getBody(), $container.get(0));
+ if (!resultInBody) {
+ return;
}
+
+ triggerShownEvent($result);
+ }
+
+ _renderCore() {
+ throw errors.Error('E0001');
+ }
}
diff --git a/packages/devextreme/js/__internal/core/templates/m_template_engine_registry.ts b/packages/devextreme/js/__internal/core/templates/m_template_engine_registry.ts
index 9fb63dcafcf4..1500c021436e 100644
--- a/packages/devextreme/js/__internal/core/templates/m_template_engine_registry.ts
+++ b/packages/devextreme/js/__internal/core/templates/m_template_engine_registry.ts
@@ -1,23 +1,22 @@
-import { isString } from '../utils/type';
-import errors from '../errors';
+import errors from '@js/core/errors';
+import { isString } from '@js/core/utils/type';
const templateEngines = {};
let currentTemplateEngine;
export function registerTemplateEngine(name, templateEngine) {
- templateEngines[name] = templateEngine;
+ templateEngines[name] = templateEngine;
}
-
export function setTemplateEngine(templateEngine) {
- if(isString(templateEngine)) {
- currentTemplateEngine = templateEngines[templateEngine];
- if(!currentTemplateEngine) {
- throw errors.Error('E0020', templateEngine);
- }
- } else {
- currentTemplateEngine = templateEngine;
+ if (isString(templateEngine)) {
+ currentTemplateEngine = templateEngines[templateEngine];
+ if (!currentTemplateEngine) {
+ throw errors.Error('E0020', templateEngine);
}
+ } else {
+ currentTemplateEngine = templateEngine;
+ }
}
export function getCurrentTemplateEngine() { return currentTemplateEngine; }
diff --git a/packages/devextreme/js/__internal/core/utils/m_ajax.ts b/packages/devextreme/js/__internal/core/utils/m_ajax.ts
index 3db05f2e8110..6e9d9deca4d7 100644
--- a/packages/devextreme/js/__internal/core/utils/m_ajax.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_ajax.ts
@@ -1,18 +1,19 @@
-import { Deferred } from './deferred';
-import httpRequest from '../../core/http_request';
-import { getWindow } from '../../core/utils/window';
-const window = getWindow();
-import { isDefined } from './type';
-import injector from './dependency_injector';
+import httpRequest from '@js/core/http_request';
import {
- isCrossDomain,
- getJsonpCallbackName as getJsonpOptions,
- getRequestHeaders,
- getRequestOptions,
- evalScript,
- evalCrossDomainScript,
- getMethod,
-} from './ajax_utils';
+ evalCrossDomainScript,
+ evalScript,
+ getJsonpCallbackName as getJsonpOptions,
+ getMethod,
+ getRequestHeaders,
+ getRequestOptions,
+ isCrossDomain,
+} from '@js/core/utils/ajax_utils';
+import { Deferred } from '@js/core/utils/deferred';
+import injector from '@js/core/utils/dependency_injector';
+import { isDefined } from '@js/core/utils/type';
+import { getWindow } from '@js/core/utils/window';
+
+const window = getWindow();
const SUCCESS = 'success';
const ERROR = 'error';
@@ -20,160 +21,164 @@ const TIMEOUT = 'timeout';
const NO_CONTENT = 'nocontent';
const PARSER_ERROR = 'parsererror';
-const isStatusSuccess = function(status) {
- return 200 <= status && status < 300;
+const isStatusSuccess = function (status) {
+ return status >= 200 && status < 300;
};
-const hasContent = function(status) {
- return status !== 204;
+const hasContent = function (status) {
+ return status !== 204;
};
-const getDataFromResponse = function(xhr) {
- return xhr.responseType && xhr.responseType !== 'text' || typeof xhr.responseText !== 'string'
- ? xhr.response
- : xhr.responseText;
+const getDataFromResponse = function (xhr) {
+ return xhr.responseType && xhr.responseType !== 'text' || typeof xhr.responseText !== 'string'
+ ? xhr.response
+ : xhr.responseText;
};
-const postProcess = function(deferred, xhr, dataType) {
-
- const data = getDataFromResponse(xhr);
-
- switch(dataType) {
- case 'jsonp':
- evalScript(data);
- break;
-
- case 'script':
- evalScript(data);
- deferred.resolve(data, SUCCESS, xhr);
- break;
-
- case 'json':
- try {
- deferred.resolve(JSON.parse(data), SUCCESS, xhr);
- } catch(e) {
- deferred.reject(xhr, PARSER_ERROR, e);
- }
- break;
-
- default:
- deferred.resolve(data, SUCCESS, xhr);
- }
+const postProcess = function (deferred, xhr, dataType) {
+ const data = getDataFromResponse(xhr);
+
+ switch (dataType) {
+ case 'jsonp':
+ evalScript(data);
+ break;
+
+ case 'script':
+ evalScript(data);
+ deferred.resolve(data, SUCCESS, xhr);
+ break;
+
+ case 'json':
+ try {
+ deferred.resolve(JSON.parse(data), SUCCESS, xhr);
+ } catch (e) {
+ deferred.reject(xhr, PARSER_ERROR, e);
+ }
+ break;
+
+ default:
+ deferred.resolve(data, SUCCESS, xhr);
+ }
};
-const setHttpTimeout = function(timeout, xhr) {
- return timeout && setTimeout(function() {
- xhr.customStatus = TIMEOUT;
- xhr.abort();
- }, timeout);
+const setHttpTimeout = function (timeout, xhr) {
+ return timeout && setTimeout(function () {
+ xhr.customStatus = TIMEOUT;
+ xhr.abort();
+ }, timeout);
};
-const sendRequest = function(options) {
- const xhr = httpRequest.getXhr();
- const d = new Deferred();
- const result = d.promise();
- const async = isDefined(options.async) ? options.async : true;
- const dataType = options.dataType;
- const timeout = options.timeout || 0;
- let timeoutId;
-
- options.crossDomain = isCrossDomain(options.url);
- const needScriptEvaluation = dataType === 'jsonp' || dataType === 'script';
-
- if(options.cache === undefined) {
- options.cache = !needScriptEvaluation;
- }
-
- const callbackName = getJsonpOptions(options);
- const headers = getRequestHeaders(options);
- const requestOptions = getRequestOptions(options, headers);
- const url = requestOptions.url;
- const parameters = requestOptions.parameters;
-
- if(callbackName) {
- window[callbackName] = function(data) {
- d.resolve(data, SUCCESS, xhr);
- };
- }
-
- if(options.crossDomain && needScriptEvaluation) {
- const reject = function() {
- d.reject(xhr, ERROR);
- };
- const resolve = function() {
- if(dataType === 'jsonp') return;
- d.resolve(null, SUCCESS, xhr);
- };
-
- evalCrossDomainScript(url).then(resolve, reject);
- return result;
- }
-
- if(options.crossDomain && !('withCredentials' in xhr)) {
- d.reject(xhr, ERROR);
- return result;
- }
-
- xhr.open(
- getMethod(options),
- url,
- async,
- options.username,
- options.password);
-
- if(async) {
- xhr.timeout = timeout;
- timeoutId = setHttpTimeout(timeout, xhr);
- }
+const sendRequest = function (options) {
+ const xhr = httpRequest.getXhr();
+ // @ts-expect-error only void function can be called with new
+ const d = new Deferred();
+ const result = d.promise();
+ const async = isDefined(options.async) ? options.async : true;
+ const { dataType } = options;
+ const timeout = options.timeout || 0;
+ let timeoutId;
+
+ options.crossDomain = isCrossDomain(options.url);
+ const needScriptEvaluation = dataType === 'jsonp' || dataType === 'script';
+
+ if (options.cache === undefined) {
+ options.cache = !needScriptEvaluation;
+ }
+
+ const callbackName = getJsonpOptions(options);
+ const headers = getRequestHeaders(options);
+ const requestOptions = getRequestOptions(options, headers);
+ const { url } = requestOptions;
+ const { parameters } = requestOptions;
+
+ if (callbackName) {
+ // @ts-expect-error window[callback] is window type
+ window[callbackName] = function (data) {
+ d.resolve(data, SUCCESS, xhr);
+ };
+ }
- xhr['onreadystatechange'] = function(e) {
- if(xhr.readyState === 4) {
- clearTimeout(timeoutId);
- if(isStatusSuccess(xhr.status)) {
- if(hasContent(xhr.status)) {
- postProcess(d, xhr, dataType);
- } else {
- d.resolve(null, NO_CONTENT, xhr);
- }
- } else {
- d.reject(xhr, xhr.customStatus || ERROR);
- }
- }
+ if (options.crossDomain && needScriptEvaluation) {
+ const reject = function () {
+ d.reject(xhr, ERROR);
+ };
+ const resolve = function () {
+ if (dataType === 'jsonp') return;
+ d.resolve(null, SUCCESS, xhr);
};
- if(options.upload) {
- xhr.upload['onprogress'] = options.upload['onprogress'];
- xhr.upload['onloadstart'] = options.upload['onloadstart'];
- xhr.upload['onabort'] = options.upload['onabort'];
- }
+ evalCrossDomainScript(url).then(resolve, reject);
+ return result;
+ }
- if(options.xhrFields) {
- for(const field in options.xhrFields) {
- xhr[field] = options.xhrFields[field];
+ if (options.crossDomain && !('withCredentials' in xhr)) {
+ d.reject(xhr, ERROR);
+ return result;
+ }
+
+ xhr.open(
+ getMethod(options),
+ url,
+ async,
+ options.username,
+ options.password,
+ );
+
+ if (async) {
+ xhr.timeout = timeout;
+ timeoutId = setHttpTimeout(timeout, xhr);
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ xhr.onreadystatechange = function (e) {
+ if (xhr.readyState === 4) {
+ clearTimeout(timeoutId);
+ if (isStatusSuccess(xhr.status)) {
+ if (hasContent(xhr.status)) {
+ postProcess(d, xhr, dataType);
+ } else {
+ d.resolve(null, NO_CONTENT, xhr);
}
+ } else {
+ d.reject(xhr, xhr.customStatus || ERROR);
+ }
}
+ };
- if(options.responseType === 'arraybuffer') {
- xhr.responseType = options.responseType;
- }
+ if (options.upload) {
+ xhr.upload.onprogress = options.upload.onprogress;
+ xhr.upload.onloadstart = options.upload.onloadstart;
+ xhr.upload.onabort = options.upload.onabort;
+ }
- for(const name in headers) {
- if(Object.prototype.hasOwnProperty.call(headers, name) && isDefined(headers[name])) {
- xhr.setRequestHeader(name, headers[name]);
- }
+ if (options.xhrFields) {
+ for (const field in options.xhrFields) {
+ xhr[field] = options.xhrFields[field];
}
+ }
- if(options.beforeSend) {
- options.beforeSend(xhr);
+ if (options.responseType === 'arraybuffer') {
+ xhr.responseType = options.responseType;
+ }
+
+ for (const name in headers) {
+ if (Object.prototype.hasOwnProperty.call(headers, name) && isDefined(headers[name])) {
+ xhr.setRequestHeader(name, headers[name]);
}
+ }
- xhr.send(parameters);
+ if (options.beforeSend) {
+ options.beforeSend(xhr);
+ }
- result.abort = function() {
- xhr.abort();
- };
+ xhr.send(parameters);
- return result;
+ result.abort = function () {
+ xhr.abort();
+ };
+
+ return result;
};
-export default injector({ sendRequest: sendRequest });
+const Ajax = injector({ sendRequest });
+export { Ajax };
diff --git a/packages/devextreme/js/__internal/core/utils/m_ajax_utils.ts b/packages/devextreme/js/__internal/core/utils/m_ajax_utils.ts
index 3d385bb5753c..671d1e7c461e 100644
--- a/packages/devextreme/js/__internal/core/utils/m_ajax_utils.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_ajax_utils.ts
@@ -1,200 +1,202 @@
-import { extendFromObject } from './extend';
-import { getWindow, hasWindow } from './window';
-import domAdapter from '../dom_adapter';
+/* eslint-disable guard-for-in */
+/* eslint-disable no-restricted-syntax */
+import domAdapter from '@js/core/dom_adapter';
+import { extendFromObject } from '@js/core/utils/extend';
+import { getWindow, hasWindow } from '@js/core/utils/window';
const window = getWindow();
-const createScript = function(options) {
- const script = domAdapter.createElement('script');
- for(const name in options) {
- script[name] = options[name];
- }
- return script;
+const createScript = function (options) {
+ const script = domAdapter.createElement('script');
+ for (const name in options) {
+ script[name] = options[name];
+ }
+ return script;
};
-const appendToHead = function(element) {
- return domAdapter.getHead().appendChild(element);
+const appendToHead = function (element) {
+ return domAdapter.getHead().appendChild(element);
};
-const removeScript = function(scriptNode) {
- scriptNode.parentNode.removeChild(scriptNode);
+const removeScript = function (scriptNode) {
+ scriptNode.parentNode.removeChild(scriptNode);
};
-const evalScript = function(code) {
- const script = createScript({ text: code });
- appendToHead(script);
- removeScript(script);
+const evalScript = function (code) {
+ const script = createScript({ text: code });
+ appendToHead(script);
+ removeScript(script);
};
-const evalCrossDomainScript = function(url) {
- const script = createScript({ src: url });
+const evalCrossDomainScript = function (url) {
+ const script = createScript({ src: url });
- return new Promise(function(resolve, reject) {
- const events = {
- 'load': resolve,
- 'error': reject
- };
+ return new Promise((resolve, reject) => {
+ const events = {
+ load: resolve,
+ error: reject,
+ };
- const loadHandler = function(e) {
- events[e.type]();
- removeScript(script);
- };
+ const loadHandler = function (e) {
+ events[e.type]();
+ removeScript(script);
+ };
- for(const event in events) {
- domAdapter.listen(script, event, loadHandler);
- }
+ for (const event in events) {
+ domAdapter.listen(script, event, loadHandler);
+ }
- appendToHead(script);
- });
+ appendToHead(script);
+ });
};
function getMethod(options) {
- return (options.method || 'GET').toUpperCase();
+ return (options.method || 'GET').toUpperCase();
}
-const paramsConvert = function(params) {
- const result = [];
-
- for(const name in params) {
- let value = params[name];
-
- if(value === undefined) {
- continue;
- }
+const paramsConvert = function (params) {
+ const result: string[] = [];
- if(value === null) {
- value = '';
- }
+ for (const name in params) {
+ let value = params[name];
- if(typeof value === 'function') {
- value = value();
- }
-
- result.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
+ if (value === undefined) {
+ continue;
}
- return result.join('&');
-};
+ if (value === null) {
+ value = '';
+ }
-const getContentTypeHeader = function(options) {
- let defaultContentType;
- if(options.data && !options.upload && getMethod(options) !== 'GET') {
- defaultContentType = 'application/x-www-form-urlencoded;charset=utf-8';
+ if (typeof value === 'function') {
+ value = value();
}
- return options.contentType ||
- defaultContentType;
+ result.push(`${encodeURIComponent(name)}=${encodeURIComponent(value)}`);
+ }
+
+ return result.join('&');
};
-const getAcceptHeader = function(options) {
- const dataType = options.dataType || '*';
- const scriptAccept = 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript';
- const accepts = {
- '*': '*/*',
- text: 'text/plain',
- html: 'text/html',
- xml: 'application/xml, text/xml',
- json: 'application/json, text/javascript',
- jsonp: scriptAccept,
- script: scriptAccept
- };
+const getContentTypeHeader = function (options) {
+ let defaultContentType;
+ if (options.data && !options.upload && getMethod(options) !== 'GET') {
+ defaultContentType = 'application/x-www-form-urlencoded;charset=utf-8';
+ }
- extendFromObject(accepts, options.accepts, true);
+ return options.contentType
+ || defaultContentType;
+};
- return accepts[dataType] ?
- accepts[dataType] + (dataType !== '*' ? ', */*; q=0.01' : '') :
- accepts['*'];
+const getAcceptHeader = function (options) {
+ const dataType = options.dataType || '*';
+ const scriptAccept = 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript';
+ const accepts = {
+ '*': '*/*',
+ text: 'text/plain',
+ html: 'text/html',
+ xml: 'application/xml, text/xml',
+ json: 'application/json, text/javascript',
+ jsonp: scriptAccept,
+ script: scriptAccept,
+ };
+
+ extendFromObject(accepts, options.accepts, true);
+
+ return accepts[dataType]
+ ? accepts[dataType] + (dataType !== '*' ? ', */*; q=0.01' : '')
+ : accepts['*'];
};
-const getRequestHeaders = function(options) {
- const headers = options.headers || {};
+const getRequestHeaders = function (options) {
+ const headers = options.headers || {};
- headers['Content-Type'] = headers['Content-Type'] || getContentTypeHeader(options);
- headers['Accept'] = headers['Accept'] || getAcceptHeader(options);
+ headers['Content-Type'] = headers['Content-Type'] || getContentTypeHeader(options);
+ headers.Accept = headers.Accept || getAcceptHeader(options);
- if(!options.crossDomain && !headers['X-Requested-With']) {
- headers['X-Requested-With'] = 'XMLHttpRequest';
- }
- return headers;
+ if (!options.crossDomain && !headers['X-Requested-With']) {
+ headers['X-Requested-With'] = 'XMLHttpRequest';
+ }
+ return headers;
};
-const getJsonpOptions = function(options) {
- if(options.dataType === 'jsonp') {
- const random = Math.random().toString().replace(/\D/g, '');
- const callbackName = options.jsonpCallback || 'dxCallback' + Date.now() + '_' + random;
- const callbackParameter = options.jsonp || 'callback';
+const getJsonpOptions = function (options) {
+ if (options.dataType === 'jsonp') {
+ const random = Math.random().toString().replace(/\D/g, '');
+ const callbackName = options.jsonpCallback || `dxCallback${Date.now()}_${random}`;
+ const callbackParameter = options.jsonp || 'callback';
- options.data = options.data || {};
- options.data[callbackParameter] = callbackName;
+ options.data = options.data || {};
+ options.data[callbackParameter] = callbackName;
- return callbackName;
- }
+ return callbackName;
+ }
};
-const getRequestOptions = function(options, headers) {
- let params = options.data;
- const paramsAlreadyString = typeof params === 'string';
- let url = options.url || window.location.href;
+const getRequestOptions = function (options, headers) {
+ let params = options.data;
+ const paramsAlreadyString = typeof params === 'string';
+ let url = options.url || window.location.href;
+
+ if (!paramsAlreadyString && !options.cache) {
+ params = params || {};
+ params._ = Date.now();
+ }
- if(!paramsAlreadyString && !options.cache) {
- params = params || {};
- params['_'] = Date.now();
+ if (params && !options.upload) {
+ if (!paramsAlreadyString) {
+ params = paramsConvert(params);
}
- if(params && !options.upload) {
- if(!paramsAlreadyString) {
- params = paramsConvert(params);
- }
-
- if(getMethod(options) === 'GET') {
- if(params !== '') {
- url += (url.indexOf('?') > -1 ? '&' : '?') + params;
- }
- params = null;
- } else if(headers['Content-Type'] && headers['Content-Type'].indexOf('application/x-www-form-urlencoded') > -1) {
- params = params.replace(/%20/g, '+');
- }
+ if (getMethod(options) === 'GET') {
+ if (params !== '') {
+ url += (url.indexOf('?') > -1 ? '&' : '?') + params;
+ }
+ params = null;
+ } else if (headers['Content-Type'] && headers['Content-Type'].indexOf('application/x-www-form-urlencoded') > -1) {
+ params = params.replace(/%20/g, '+');
}
+ }
- return {
- url: url,
- parameters: params
- };
+ return {
+ url,
+ parameters: params,
+ };
};
-const isCrossDomain = function(url) {
- if(!hasWindow()) {
- return true;
- }
+const isCrossDomain = function (url) {
+ if (!hasWindow()) {
+ return true;
+ }
- let crossDomain = false;
- const originAnchor = domAdapter.createElement('a');
- const urlAnchor = domAdapter.createElement('a');
+ let crossDomain = false;
+ const originAnchor = domAdapter.createElement('a') as HTMLAnchorElement;
+ const urlAnchor = domAdapter.createElement('a') as HTMLAnchorElement;
- originAnchor.href = window.location.href;
+ originAnchor.href = window.location.href;
- try {
- urlAnchor.href = url;
+ try {
+ urlAnchor.href = url;
- // NOTE: IE11
- // eslint-disable-next-line no-self-assign
- urlAnchor.href = urlAnchor.href;
+ // NOTE: IE11
+ // eslint-disable-next-line no-self-assign
+ urlAnchor.href = urlAnchor.href;
- crossDomain = originAnchor.protocol + '//' + originAnchor.host !==
- urlAnchor.protocol + '//' + urlAnchor.host;
- } catch(e) {
- crossDomain = true;
- }
- return crossDomain;
+ crossDomain = `${originAnchor.protocol}//${originAnchor.host}`
+ !== `${urlAnchor.protocol}//${urlAnchor.host}`;
+ } catch (e) {
+ crossDomain = true;
+ }
+ return crossDomain;
};
export {
- isCrossDomain,
- getJsonpOptions as getJsonpCallbackName,
- getRequestHeaders,
- getRequestOptions,
- getAcceptHeader,
- evalScript,
- evalCrossDomainScript,
- getMethod,
+ evalCrossDomainScript,
+ evalScript,
+ getAcceptHeader,
+ getJsonpOptions as getJsonpCallbackName,
+ getMethod,
+ getRequestHeaders,
+ getRequestOptions,
+ isCrossDomain,
};
diff --git a/packages/devextreme/js/__internal/core/utils/m_array.ts b/packages/devextreme/js/__internal/core/utils/m_array.ts
index 139bd930937c..5048cdd27d4e 100644
--- a/packages/devextreme/js/__internal/core/utils/m_array.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_array.ts
@@ -1,101 +1,99 @@
-import { isDefined } from './type';
-import { orderEach } from './object';
-import config from '../config';
+import config from '@js/core/config';
+import { orderEach } from '@js/core/utils/object';
+import { isDefined } from '@js/core/utils/type';
function createOccurrenceMap(array) {
- return array.reduce((map, value) => {
- const count = (map.get(value) ?? 0) + 1;
- map.set(value, count);
- return map;
- }, new Map());
+ return array.reduce((map, value) => {
+ const count = (map.get(value) ?? 0) + 1;
+ map.set(value, count);
+ return map;
+ }, new Map());
}
-export const wrapToArray = function(item) {
- return Array.isArray(item) ? item : [item];
+export const wrapToArray = function (item) {
+ return Array.isArray(item) ? item : [item];
};
-export const getUniqueValues = function(values) {
- return [...new Set(values)];
+export const getUniqueValues = function (values) {
+ return [...new Set(values)];
};
-export const getIntersection = function(firstArray, secondArray) {
- const toRemoveMap = createOccurrenceMap(secondArray);
- return firstArray.filter(value => {
- const occurrencesCount = toRemoveMap.get(value);
- occurrencesCount && toRemoveMap.set(value, occurrencesCount - 1);
- return occurrencesCount;
- });
+export const getIntersection = function (firstArray, secondArray) {
+ const toRemoveMap = createOccurrenceMap(secondArray);
+ return firstArray.filter((value) => {
+ const occurrencesCount = toRemoveMap.get(value);
+ occurrencesCount && toRemoveMap.set(value, occurrencesCount - 1);
+ return occurrencesCount;
+ });
};
-export const removeDuplicates = function(from = [], toRemove = []) {
- const toRemoveMap = createOccurrenceMap(toRemove);
- return from.filter(value => {
- const occurrencesCount = toRemoveMap.get(value);
- occurrencesCount && toRemoveMap.set(value, occurrencesCount - 1);
- return !occurrencesCount;
- });
+export const removeDuplicates = function (from = [], toRemove = []) {
+ const toRemoveMap = createOccurrenceMap(toRemove);
+ return from.filter((value) => {
+ const occurrencesCount = toRemoveMap.get(value);
+ occurrencesCount && toRemoveMap.set(value, occurrencesCount - 1);
+ return !occurrencesCount;
+ });
};
-export const normalizeIndexes = function(items, indexPropName, currentItem, needIndexCallback) {
- const indexedItems = {};
- const { useLegacyVisibleIndex } = config();
- let currentIndex = 0;
+export const normalizeIndexes = function (items, indexPropName, currentItem?, needIndexCallback?) {
+ const indexedItems = {};
+ const { useLegacyVisibleIndex } = config();
+ let currentIndex = 0;
- const shouldUpdateIndex = (item) => !isDefined(item[indexPropName])
- && (!needIndexCallback || needIndexCallback(item));
+ const shouldUpdateIndex = (item) => !isDefined(item[indexPropName])
+ && (!needIndexCallback || needIndexCallback(item));
- items.forEach((item) => {
- const index = item[indexPropName];
- if(index >= 0) {
- indexedItems[index] = indexedItems[index] || [];
+ items.forEach((item) => {
+ const index = item[indexPropName];
+ if (index >= 0) {
+ indexedItems[index] = indexedItems[index] || [];
- if(item === currentItem) {
- indexedItems[index].unshift(item);
- } else {
- indexedItems[index].push(item);
- }
- } else {
- item[indexPropName] = undefined;
+ if (item === currentItem) {
+ indexedItems[index].unshift(item);
+ } else {
+ indexedItems[index].push(item);
+ }
+ } else {
+ item[indexPropName] = undefined;
+ }
+ });
+
+ if (!useLegacyVisibleIndex) {
+ items.forEach((item) => {
+ if (shouldUpdateIndex(item)) {
+ while (indexedItems[currentIndex]) {
+ currentIndex++;
}
+ indexedItems[currentIndex] = [item];
+ currentIndex++;
+ }
});
+ }
- if(!useLegacyVisibleIndex) {
- items.forEach(item => {
- if(shouldUpdateIndex(item)) {
- while(indexedItems[currentIndex]) {
- currentIndex++;
- }
- indexedItems[currentIndex] = [item];
- currentIndex++;
- }
- });
- }
+ currentIndex = 0;
- currentIndex = 0;
-
- orderEach(indexedItems, function(index, items) {
- items.forEach(item => {
- if(index >= 0) {
- item[indexPropName] = currentIndex++;
- }
- });
+ orderEach(indexedItems, function (index, items) {
+ items.forEach((item) => {
+ if (index >= 0) {
+ item[indexPropName] = currentIndex++;
+ }
});
+ });
- if(useLegacyVisibleIndex) {
- items.forEach(item => {
- if(shouldUpdateIndex(item)) {
- item[indexPropName] = currentIndex++;
- }
- });
- }
+ if (useLegacyVisibleIndex) {
+ items.forEach((item) => {
+ if (shouldUpdateIndex(item)) {
+ item[indexPropName] = currentIndex++;
+ }
+ });
+ }
};
-export const groupBy = (array, getGroupName) => {
- return array.reduce((groupedResult, item) => {
- const groupName = getGroupName(item);
- groupedResult[groupName] = groupedResult[groupName] ?? [];
- groupedResult[groupName].push(item);
+export const groupBy = (array, getGroupName) => array.reduce((groupedResult, item) => {
+ const groupName = getGroupName(item);
+ groupedResult[groupName] = groupedResult[groupName] ?? [];
+ groupedResult[groupName].push(item);
- return groupedResult;
- }, {});
-};
+ return groupedResult;
+}, {});
diff --git a/packages/devextreme/js/__internal/core/utils/m_array_compare.ts b/packages/devextreme/js/__internal/core/utils/m_array_compare.ts
index 0821bbfdb4b7..31e83dada542 100644
--- a/packages/devextreme/js/__internal/core/utils/m_array_compare.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_array_compare.ts
@@ -1,98 +1,97 @@
-import { isObject } from './type';
+import { isObject } from '@js/core/utils/type';
-const getKeyWrapper = function(item, getKey) {
- const key = getKey(item);
- if(isObject(key)) {
- try {
- return JSON.stringify(key);
- } catch(e) {
- return key;
- }
+const getKeyWrapper = function (item, getKey) {
+ const key = getKey(item);
+ if (isObject(key)) {
+ try {
+ return JSON.stringify(key);
+ } catch (e) {
+ return key;
}
- return key;
+ }
+ return key;
};
-const getSameNewByOld = function(oldItem, newItems, newIndexByKey, getKey) {
- const key = getKeyWrapper(oldItem, getKey);
- return newItems[newIndexByKey[key]];
+const getSameNewByOld = function (oldItem, newItems, newIndexByKey, getKey) {
+ const key = getKeyWrapper(oldItem, getKey);
+ return newItems[newIndexByKey[key]];
};
-export const isKeysEqual = function(oldKeys, newKeys) {
- if(oldKeys.length !== newKeys.length) {
- return false;
- }
+export const isKeysEqual = function (oldKeys, newKeys) {
+ if (oldKeys.length !== newKeys.length) {
+ return false;
+ }
- for(let i = 0; i < newKeys.length; i++) {
- if(oldKeys[i] !== newKeys[i]) {
- return false;
- }
+ for (let i = 0; i < newKeys.length; i++) {
+ if (oldKeys[i] !== newKeys[i]) {
+ return false;
}
+ }
- return true;
+ return true;
};
-export const findChanges = function(oldItems, newItems, getKey, isItemEquals) {
- const oldIndexByKey = {};
- const newIndexByKey = {};
- let addedCount = 0;
- let removeCount = 0;
- const result = [];
+export const findChanges = function (oldItems, newItems, getKey, isItemEquals) {
+ const oldIndexByKey = {};
+ const newIndexByKey = {};
+ let addedCount = 0;
+ let removeCount = 0;
+ const result: any[] = [];
- oldItems.forEach(function(item, index) {
- const key = getKeyWrapper(item, getKey);
- oldIndexByKey[key] = index;
- });
+ oldItems.forEach(function (item, index) {
+ const key = getKeyWrapper(item, getKey);
+ oldIndexByKey[key] = index;
+ });
- newItems.forEach(function(item, index) {
- const key = getKeyWrapper(item, getKey);
- newIndexByKey[key] = index;
- });
+ newItems.forEach(function (item, index) {
+ const key = getKeyWrapper(item, getKey);
+ newIndexByKey[key] = index;
+ });
- const itemCount = Math.max(oldItems.length, newItems.length);
- for(let index = 0; index < itemCount + addedCount; index++) {
- const newItem = newItems[index];
- const oldNextIndex = index - addedCount + removeCount;
- const nextOldItem = oldItems[oldNextIndex];
- const isRemoved = !newItem || (nextOldItem && !getSameNewByOld(nextOldItem, newItems, newIndexByKey, getKey));
+ const itemCount = Math.max(oldItems.length, newItems.length);
+ for (let index = 0; index < itemCount + addedCount; index++) {
+ const newItem = newItems[index];
+ const oldNextIndex = index - addedCount + removeCount;
+ const nextOldItem = oldItems[oldNextIndex];
+ const isRemoved = !newItem || (nextOldItem && !getSameNewByOld(nextOldItem, newItems, newIndexByKey, getKey));
- if(isRemoved) {
- if(nextOldItem) {
- result.push({
- type: 'remove',
- key: getKey(nextOldItem),
- index: index,
- oldItem: nextOldItem
- });
- removeCount++;
- index--;
- }
- } else {
- const key = getKeyWrapper(newItem, getKey);
- const oldIndex = oldIndexByKey[key];
- const oldItem = oldItems[oldIndex];
- if(!oldItem) {
- addedCount++;
- result.push({
- type: 'insert',
- data: newItem,
- index: index
- });
- } else if(oldIndex === oldNextIndex) {
- if(!isItemEquals(oldItem, newItem)) {
- result.push({
- type: 'update',
- data: newItem,
- key: getKey(newItem),
- index: index,
- oldItem: oldItem
- });
- }
- } else {
- return;
- }
+ if (isRemoved) {
+ if (nextOldItem) {
+ result.push({
+ type: 'remove',
+ key: getKey(nextOldItem),
+ index,
+ oldItem: nextOldItem,
+ });
+ removeCount++;
+ index--;
+ }
+ } else {
+ const key = getKeyWrapper(newItem, getKey);
+ const oldIndex = oldIndexByKey[key];
+ const oldItem = oldItems[oldIndex];
+ if (!oldItem) {
+ addedCount++;
+ result.push({
+ type: 'insert',
+ data: newItem,
+ index,
+ });
+ } else if (oldIndex === oldNextIndex) {
+ if (!isItemEquals(oldItem, newItem)) {
+ result.push({
+ type: 'update',
+ data: newItem,
+ key: getKey(newItem),
+ index,
+ oldItem,
+ });
}
+ } else {
+ return;
+ }
}
+ }
- return result;
+ return result;
};
-
diff --git a/packages/devextreme/js/__internal/core/utils/m_browser.ts b/packages/devextreme/js/__internal/core/utils/m_browser.ts
index 658f4f95b55f..2420a5b4d70e 100644
--- a/packages/devextreme/js/__internal/core/utils/m_browser.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_browser.ts
@@ -1,48 +1,49 @@
-import { extend } from './extend';
-import { getNavigator } from './window';
+import { extend } from '@js/core/utils/extend';
+import { getNavigator } from '@js/core/utils/window';
+
const navigator = getNavigator();
const webkitRegExp = /(webkit)[ /]([\w.]+)/;
const mozillaRegExp = /(mozilla)(?:.*? rv:([\w.]+))/;
const browserFromUA = (ua) => {
- ua = ua.toLowerCase();
-
- const result = {};
- const matches =
- webkitRegExp.exec(ua) ||
- ua.indexOf('compatible') < 0 && mozillaRegExp.exec(ua) ||
- [];
- let browserName = matches[1];
- let browserVersion = matches[2];
-
- if(browserName === 'webkit') {
- result['webkit'] = true;
-
- if(ua.indexOf('chrome') >= 0 || ua.indexOf('crios') >= 0) {
- browserName = 'chrome';
- browserVersion = /(?:chrome|crios)\/(\d+\.\d+)/.exec(ua);
- browserVersion = browserVersion && browserVersion[1];
- } else if(ua.indexOf('fxios') >= 0) {
- browserName = 'mozilla';
- browserVersion = /fxios\/(\d+\.\d+)/.exec(ua);
- browserVersion = browserVersion && browserVersion[1];
- } else if(ua.indexOf('safari') >= 0 && /version|phantomjs/.test(ua)) {
- browserName = 'safari';
- browserVersion = /(?:version|phantomjs)\/([0-9.]+)/.exec(ua);
- browserVersion = browserVersion && browserVersion[1];
- } else {
- browserName = 'unknown';
- browserVersion = /applewebkit\/([0-9.]+)/.exec(ua);
- browserVersion = browserVersion && browserVersion[1];
- }
- }
+ ua = ua.toLowerCase();
+
+ const result: any = {};
+ const matches = webkitRegExp.exec(ua)
+ || ua.indexOf('compatible') < 0 && mozillaRegExp.exec(ua)
+ || [];
+ let browserName = matches[1];
+ let browserVersion: any = matches[2];
- if(browserName) {
- result[browserName] = true;
- result.version = browserVersion;
+ if (browserName === 'webkit') {
+ result.webkit = true;
+
+ if (ua.indexOf('chrome') >= 0 || ua.indexOf('crios') >= 0) {
+ browserName = 'chrome';
+ browserVersion = /(?:chrome|crios)\/(\d+\.\d+)/.exec(ua);
+ browserVersion = browserVersion && browserVersion[1];
+ } else if (ua.indexOf('fxios') >= 0) {
+ browserName = 'mozilla';
+ browserVersion = /fxios\/(\d+\.\d+)/.exec(ua);
+ browserVersion = browserVersion && browserVersion[1];
+ } else if (ua.indexOf('safari') >= 0 && /version|phantomjs/.test(ua)) {
+ browserName = 'safari';
+ browserVersion = /(?:version|phantomjs)\/([0-9.]+)/.exec(ua);
+ browserVersion = browserVersion && browserVersion[1];
+ } else {
+ browserName = 'unknown';
+ browserVersion = /applewebkit\/([0-9.]+)/.exec(ua);
+ browserVersion = browserVersion && browserVersion[1];
}
+ }
+
+ if (browserName) {
+ result[browserName] = true;
+ result.version = browserVersion;
+ }
- return result;
+ return result;
};
-export default extend({ _fromUA: browserFromUA }, browserFromUA(navigator.userAgent));
+const browser = extend({ _fromUA: browserFromUA }, browserFromUA(navigator.userAgent));
+export { browser };
diff --git a/packages/devextreme/js/__internal/core/utils/m_call_once.ts b/packages/devextreme/js/__internal/core/utils/m_call_once.ts
index 1771ea8fac42..ca68b5648b5d 100644
--- a/packages/devextreme/js/__internal/core/utils/m_call_once.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_call_once.ts
@@ -1,17 +1,18 @@
-const callOnce = function(handler) {
- let result;
+const callOnce = function (handler) {
+ let result;
- let wrappedHandler = function() {
- result = handler.apply(this, arguments);
- wrappedHandler = function() {
- return result;
- };
- return result;
+ let wrappedHandler = function () {
+ result = handler.apply(this, arguments);
+ wrappedHandler = function () {
+ return result;
};
+ return result;
+ };
- return function() {
- return wrappedHandler.apply(this, arguments);
- };
+ return function () {
+ // @ts-expect-error Iarguments not assignable to []
+ return wrappedHandler.apply(this, arguments);
+ };
};
-export default callOnce;
+export { callOnce };
diff --git a/packages/devextreme/js/__internal/core/utils/m_callbacks.ts b/packages/devextreme/js/__internal/core/utils/m_callbacks.ts
index 9f9b82cc343d..f404ffb73616 100644
--- a/packages/devextreme/js/__internal/core/utils/m_callbacks.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_callbacks.ts
@@ -1,109 +1,130 @@
-const Callback = function(options) {
- this._options = options || {};
- this._list = [];
- this._queue = [];
- this._firing = false;
- this._fired = false;
- this._firingIndexes = [];
-};
+type CallbackType
+ = ((this: TContext, ...args: TArgs) => boolean)
+ | ((this: TContext, ...args: TArgs) => void);
-Callback.prototype._fireCore = function(context, args) {
- const firingIndexes = this._firingIndexes;
- const list = this._list;
- const stopOnFalse = this._options.stopOnFalse;
- const step = firingIndexes.length;
+export interface CallbackInterface {
+ add: (fn: CallbackType) => this;
- for(firingIndexes[step] = 0; firingIndexes[step] < list.length; firingIndexes[step]++) {
- const result = list[firingIndexes[step]].apply(context, args);
+ remove: (fn: CallbackType) => this;
- if(result === false && stopOnFalse) {
- break;
- }
- }
+ has: (fn: CallbackType) => this;
+
+ empty: () => this;
+
+ fireWith: (context: TContext, args: TArgs) => this;
+
+ fire: (...args: TArgs) => this;
+
+ fired: () => boolean;
+}
- firingIndexes.pop();
+const Callback = function (options) {
+ this._options = options || {};
+ this._list = [];
+ this._queue = [];
+ this._firing = false;
+ this._fired = false;
+ this._firingIndexes = [];
};
+Callback.prototype._fireCore = function (context, args) {
+ const firingIndexes = this._firingIndexes;
+ const list = this._list;
+ const { stopOnFalse } = this._options;
+ const step = firingIndexes.length;
-Callback.prototype.add = function(fn) {
- if(typeof fn === 'function' && (!this._options.unique || !this.has(fn))) {
- this._list.push(fn);
+ for (firingIndexes[step] = 0; firingIndexes[step] < list.length; firingIndexes[step]++) {
+ const result = list[firingIndexes[step]].apply(context, args);
+
+ if (result === false && stopOnFalse) {
+ break;
}
- return this;
+ }
+
+ firingIndexes.pop();
+};
+
+Callback.prototype.add = function (fn) {
+ if (typeof fn === 'function' && (!this._options.unique || !this.has(fn))) {
+ this._list.push(fn);
+ }
+ return this;
};
-Callback.prototype.remove = function(fn) {
- const list = this._list;
- const firingIndexes = this._firingIndexes;
- const index = list.indexOf(fn);
+Callback.prototype.remove = function (fn) {
+ const list = this._list;
+ const firingIndexes = this._firingIndexes;
+ const index = list.indexOf(fn);
- if(index > -1) {
- list.splice(index, 1);
+ if (index > -1) {
+ list.splice(index, 1);
- if(this._firing && firingIndexes.length) {
- for(let step = 0; step < firingIndexes.length; step++) {
- if(index <= firingIndexes[step]) {
- firingIndexes[step]--;
- }
- }
+ if (this._firing && firingIndexes.length) {
+ for (let step = 0; step < firingIndexes.length; step++) {
+ if (index <= firingIndexes[step]) {
+ firingIndexes[step]--;
}
+ }
}
+ }
- return this;
+ return this;
};
-Callback.prototype.has = function(fn) {
- const list = this._list;
+Callback.prototype.has = function (fn) {
+ const list = this._list;
- return fn ? list.indexOf(fn) > -1 : !!list.length;
+ return fn ? list.indexOf(fn) > -1 : !!list.length;
};
-Callback.prototype.empty = function(fn) {
- this._list = [];
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+Callback.prototype.empty = function (fn) {
+ this._list = [];
- return this;
+ return this;
};
-Callback.prototype.fireWith = function(context, args) {
- const queue = this._queue;
+Callback.prototype.fireWith = function (context, args) {
+ const queue = this._queue;
- args = args || [];
- args = args.slice ? args.slice() : args;
+ args = args || [];
+ args = args.slice ? args.slice() : args;
- if(this._options.syncStrategy) {
- this._firing = true;
- this._fireCore(context, args);
- } else {
- queue.push([context, args]);
- if(this._firing) {
- return;
- }
+ if (this._options.syncStrategy) {
+ this._firing = true;
+ this._fireCore(context, args);
+ } else {
+ queue.push([context, args]);
+ if (this._firing) {
+ return;
+ }
- this._firing = true;
+ this._firing = true;
- while(queue.length) {
- const memory = queue.shift();
+ while (queue.length) {
+ const memory = queue.shift();
- this._fireCore(memory[0], memory[1]);
- }
+ this._fireCore(memory[0], memory[1]);
}
+ }
- this._firing = false;
- this._fired = true;
+ this._firing = false;
+ this._fired = true;
- return this;
+ return this;
};
-Callback.prototype.fire = function() {
- this.fireWith(this, arguments);
+Callback.prototype.fire = function () {
+ this.fireWith(this, arguments);
};
-Callback.prototype.fired = function() {
- return this._fired;
+Callback.prototype.fired = function () {
+ return this._fired;
};
-const Callbacks = function(options) {
- return new Callback(options);
+const Callbacks = function (options?) {
+ return new Callback(options);
};
+export { Callbacks };
export default Callbacks;
diff --git a/packages/devextreme/js/__internal/core/utils/m_common.ts b/packages/devextreme/js/__internal/core/utils/m_common.ts
index 34520f56b5e4..2517eb6c4e4a 100644
--- a/packages/devextreme/js/__internal/core/utils/m_common.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_common.ts
@@ -1,320 +1,348 @@
-import config from '../config';
-import Guid from '../guid';
-import { when, Deferred } from '../utils/deferred';
-import { toComparable } from './data';
-import { each } from './iterator';
-import { isDefined, isFunction, isString, isObject, type } from './type';
-
-export const ensureDefined = function(value, defaultValue) {
- return isDefined(value) ? value : defaultValue;
+import config from '@js/core/config';
+import Guid from '@js/core/guid';
+import { toComparable } from '@js/core/utils/data';
+import { Deferred, when } from '@js/core/utils/deferred';
+import { each } from '@js/core/utils/iterator';
+import {
+ isDefined, isFunction, isObject, isString, type,
+} from '@js/core/utils/type';
+
+export const ensureDefined = function (value, defaultValue) {
+ return isDefined(value) ? value : defaultValue;
};
-export const executeAsync = function(action, context/* , internal */) {
- const deferred = new Deferred();
- const normalizedContext = context || this;
- const task = {
- promise: deferred.promise(),
- abort: function() {
- clearTimeout(timerId);
- deferred.rejectWith(normalizedContext);
- }
- };
-
- const callback = function() {
- const result = action.call(normalizedContext);
-
- if(result && result.done && isFunction(result.done)) {
- result.done(function() {
- deferred.resolveWith(normalizedContext);
- });
- } else {
- deferred.resolveWith(normalizedContext);
- }
- };
-
- const timerId = (arguments[2] || setTimeout)(callback, typeof context === 'number' ? context : 0);
-
- return task;
+export const executeAsync = function (action, context?/* , internal */) {
+ // @ts-expect-error only void function can be called with new
+ const deferred = new Deferred();
+ const normalizedContext = context || this;
+ const task = {
+ promise: deferred.promise(),
+ abort() {
+ clearTimeout(timerId);
+ deferred.rejectWith(normalizedContext);
+ },
+ };
+
+ const callback = function () {
+ const result = action.call(normalizedContext);
+
+ if (result && result.done && isFunction(result.done)) {
+ result.done(function () {
+ deferred.resolveWith(normalizedContext);
+ });
+ } else {
+ deferred.resolveWith(normalizedContext);
+ }
+ };
+
+ const timerId = (arguments[2] || setTimeout)(callback, typeof context === 'number' ? context : 0);
+
+ return task;
};
-const delayedFuncs = [];
-const delayedNames = [];
-const delayedDeferreds = [];
+const delayedFuncs: any[] = [];
+const delayedNames: any[] = [];
+const delayedDeferreds: any[] = [];
let executingName;
-const deferExecute = function(name, func, deferred) {
- if(executingName && executingName !== name) {
- delayedFuncs.push(func);
- delayedNames.push(name);
- deferred = deferred || new Deferred();
- delayedDeferreds.push(deferred);
- return deferred;
- } else {
- const oldExecutingName = executingName;
- const currentDelayedCount = delayedDeferreds.length;
-
- executingName = name;
- let result = func();
-
- if(!result) {
- if(delayedDeferreds.length > currentDelayedCount) {
- result = when.apply(this, delayedDeferreds.slice(currentDelayedCount));
- } else if(deferred) {
- deferred.resolve();
- }
- }
-
- executingName = oldExecutingName;
-
- if(deferred && result && result.done) {
- result.done(deferred.resolve).fail(deferred.reject);
- }
-
- if(!executingName && delayedFuncs.length) {
- (delayedNames.shift() === 'render' ? deferRender : deferUpdate)(delayedFuncs.shift(), delayedDeferreds.shift());
- }
- return result || when();
+const deferExecute = function (name, func, deferred?) {
+ if (executingName && executingName !== name) {
+ delayedFuncs.push(func);
+ delayedNames.push(name);
+ // @ts-expect-error only void function can be called with new
+ deferred = deferred || new Deferred();
+ delayedDeferreds.push(deferred);
+ return deferred;
+ }
+ const oldExecutingName = executingName;
+ const currentDelayedCount = delayedDeferreds.length;
+
+ executingName = name;
+ let result = func();
+
+ if (!result) {
+ if (delayedDeferreds.length > currentDelayedCount) {
+ result = when.apply(this, delayedDeferreds.slice(currentDelayedCount));
+ } else if (deferred) {
+ deferred.resolve();
}
+ }
+
+ executingName = oldExecutingName;
+
+ if (deferred && result && result.done) {
+ result.done(deferred.resolve).fail(deferred.reject);
+ }
+
+ if (!executingName && delayedFuncs.length) {
+ (delayedNames.shift() === 'render' ? deferRender : deferUpdate)(delayedFuncs.shift(), delayedDeferreds.shift());
+ }
+ return result || when();
};
-export const deferRender = function(func, deferred) {
- return deferExecute('render', func, deferred);
+export const deferRender = function (func, deferred) {
+ return deferExecute('render', func, deferred);
};
-export const deferUpdate = function(func, deferred) {
- return deferExecute('update', func, deferred);
+export const deferUpdate = function (func, deferred) {
+ return deferExecute('update', func, deferred);
};
-export const deferRenderer = function(func) {
- return function() {
- const that = this;
- return deferExecute('render', function() {
- return func.call(that);
- });
- };
+export const deferRenderer = function (func) {
+ return function () {
+ const that = this;
+ return deferExecute('render', function () {
+ return func.call(that);
+ });
+ };
};
-export const deferUpdater = function(func) {
- return function() {
- const that = this;
- return deferExecute('update', function() {
- return func.call(that);
- });
- };
+export const deferUpdater = function (func) {
+ return function () {
+ const that = this;
+ return deferExecute('update', function () {
+ return func.call(that);
+ });
+ };
};
-export const findBestMatches = function(targetFilter, items, mapFn) {
- const bestMatches = [];
- let maxMatchCount = 0;
-
- each(items, (index, itemSrc) => {
- let matchCount = 0;
- const item = mapFn ? mapFn(itemSrc) : itemSrc;
-
- each(targetFilter, (paramName, targetValue) => {
- const value = item[paramName];
-
- if(value === undefined) {
- return;
- }
-
- if(match(value, targetValue)) {
- matchCount++;
- return;
- }
- matchCount = -1;
- return false;
- });
-
- if(matchCount < maxMatchCount) {
- return;
- }
- if(matchCount > maxMatchCount) {
- bestMatches.length = 0;
- maxMatchCount = matchCount;
- }
- bestMatches.push(itemSrc);
+export const findBestMatches = (
+ targetFilter: unknown,
+ items: unknown[],
+ mapFn?: (item: unknown) => unknown,
+): unknown[] => {
+ const bestMatches: unknown[] = [];
+ let maxMatchCount = 0;
+
+ each(items, (index, itemSrc) => {
+ let matchCount = 0;
+ const item = mapFn ? mapFn(itemSrc) : itemSrc;
+
+ each(targetFilter, (paramName, targetValue) => {
+ const value = item[paramName];
+
+ if (value === undefined) {
+ return;
+ }
+
+ if (match(value, targetValue)) {
+ matchCount++;
+ return;
+ }
+ matchCount = -1;
+ return false;
});
- return bestMatches;
-};
+ if (matchCount < maxMatchCount) {
+ return;
+ }
+ if (matchCount > maxMatchCount) {
+ bestMatches.length = 0;
+ maxMatchCount = matchCount;
+ }
+ bestMatches.push(itemSrc);
+ });
-const match = function(value, targetValue) {
- if(Array.isArray(value) && Array.isArray(targetValue)) {
- let mismatch = false;
+ return bestMatches;
+};
- each(value, (index, valueItem) => {
- if(valueItem !== targetValue[index]) {
- mismatch = true;
- return false;
- }
- });
+const match = function (value, targetValue) {
+ if (Array.isArray(value) && Array.isArray(targetValue)) {
+ let mismatch = false;
- if(mismatch) {
- return false;
- }
+ // @ts-expect-error not all code paths return value
+ each(value, (index, valueItem) => {
+ if (valueItem !== targetValue[index]) {
+ mismatch = true;
+ return false;
+ }
+ });
- return true;
+ if (mismatch) {
+ return false;
}
- if(value === targetValue) {
- return true;
- }
+ return true;
+ }
- return false;
+ if (value === targetValue) {
+ return true;
+ }
+
+ return false;
};
-export const splitPair = function(raw) {
- switch(type(raw)) {
- case 'string':
- return raw.split(/\s+/, 2);
- case 'object':
- return [raw.x ?? raw.h, raw.y ?? raw.v];
- case 'number':
- return [raw];
- case 'array':
- return raw;
- default:
- return null;
- }
+export const splitPair = function (raw) {
+ switch (type(raw)) {
+ case 'string':
+ return raw.split(/\s+/, 2);
+ case 'object':
+ return [raw.x ?? raw.h, raw.y ?? raw.v];
+ case 'number':
+ return [raw];
+ case 'array':
+ return raw;
+ default:
+ return null;
+ }
};
-export const normalizeKey = function(id) {
- let key = isString(id) ? id : id.toString();
- const arr = key.match(/[^a-zA-Z0-9_]/g);
+export const normalizeKey = function (id) {
+ let key = isString(id) ? id : id.toString();
+ const arr = key.match(/[^a-zA-Z0-9_]/g);
- arr && each(arr, (_, sign) => {
- key = key.replace(sign, '__' + sign.charCodeAt() + '__');
- });
- return key;
+ arr && each(arr, (_, sign) => {
+ key = key.replace(sign, `__${sign.charCodeAt()}__`);
+ });
+ return key;
};
-export const denormalizeKey = function(key) {
- const arr = key.match(/__\d+__/g);
+export const denormalizeKey = function (key) {
+ const arr = key.match(/__\d+__/g);
- arr && arr.forEach((char) => {
- const charCode = parseInt(char.replace('__', ''));
+ arr && arr.forEach((char) => {
+ const charCode = parseInt(char.replace('__', ''));
- key = key.replace(char, String.fromCharCode(charCode));
- });
+ key = key.replace(char, String.fromCharCode(charCode));
+ });
- return key;
+ return key;
};
-export const pairToObject = function(raw, preventRound) {
- const pair = splitPair(raw);
- let h = preventRound ? parseFloat(pair && pair[0]) : parseInt(pair && pair[0], 10);
- let v = preventRound ? parseFloat(pair && pair[1]) : parseInt(pair && pair[1], 10);
+export const pairToObject = function (raw, preventRound) {
+ const pair = splitPair(raw);
+ let h = preventRound ? parseFloat(pair && pair[0]) : parseInt(pair && pair[0], 10);
+ let v = preventRound ? parseFloat(pair && pair[1]) : parseInt(pair && pair[1], 10);
- if(!isFinite(h)) {
- h = 0;
- }
- if(!isFinite(v)) {
- v = h;
- }
+ if (!isFinite(h)) {
+ h = 0;
+ }
+ if (!isFinite(v)) {
+ v = h;
+ }
- return { h, v };
+ return { h, v };
};
-export const getKeyHash = function(key) {
- if(key instanceof Guid) {
- return key.toString();
- } else if(isObject(key) || Array.isArray(key)) {
- try {
- const keyHash = JSON.stringify(key);
- return keyHash === '{}' ? key : keyHash;
- } catch(e) {
- return key;
- }
+export const getKeyHash = function (key) {
+ if (key instanceof Guid) {
+ return key.toString();
+ } if (isObject(key) || Array.isArray(key)) {
+ try {
+ const keyHash = JSON.stringify(key);
+ return keyHash === '{}' ? key : keyHash;
+ } catch (e) {
+ return key;
}
+ }
- return key;
+ return key;
};
-export const escapeRegExp = function(string) {
- return string.replace(/[[\]{}\-()*+?.\\^$|\s]/g, '\\$&');
+export const escapeRegExp = function (string) {
+ return string.replace(/[[\]{}\-()*+?.\\^$|\s]/g, '\\$&');
};
-export const applyServerDecimalSeparator = function(value) {
- const separator = config().serverDecimalSeparator;
- if(isDefined(value)) {
- value = value.toString().replace('.', separator);
- }
- return value;
+export const applyServerDecimalSeparator = function (value) {
+ const separator = config().serverDecimalSeparator;
+ if (isDefined(value)) {
+ value = value.toString().replace('.', separator);
+ }
+ return value;
};
-export const noop = function() {};
-export const asyncNoop = function() { return new Deferred().resolve().promise(); };
+export const noop = function () {};
+// @ts-expect-error only void function can be called with new
+export const asyncNoop = function () { return new Deferred().resolve().promise(); };
-export const grep = function(elements, checkFunction, invert) {
- const result = [];
- let check;
- const expectedCheck = !invert;
+export const grep = function (elements, checkFunction, invert) {
+ const result: any[] = [];
+ let check;
+ const expectedCheck = !invert;
- for(let i = 0; i < elements.length; i++) {
- check = !!checkFunction(elements[i], i);
+ for (let i = 0; i < elements.length; i++) {
+ check = !!checkFunction(elements[i], i);
- if(check === expectedCheck) {
- result.push(elements[i]);
- }
+ if (check === expectedCheck) {
+ result.push(elements[i]);
}
+ }
- return result;
+ return result;
};
const compareArrays = (array1, array2, depth, options) => {
- if(array1.length !== array2.length) {
- return false;
- }
+ if (array1.length !== array2.length) {
+ return false;
+ }
- return !array1.some((item, idx) => !compareByValue(item, array2[idx], depth + 1, {
- ...options,
- strict: true,
- }));
+ return !array1.some((item, idx) => !compareByValue(item, array2[idx], depth + 1, {
+ ...options,
+ strict: true,
+ }));
};
const compareObjects = (object1, object2, depth, options) => {
- const keys1 = Object.keys(object1);
- const keys2 = Object.keys(object2);
+ const keys1 = Object.keys(object1);
+ const keys2 = Object.keys(object2);
- if(keys1.length !== keys2.length) {
- return false;
- }
+ if (keys1.length !== keys2.length) {
+ return false;
+ }
- const keys2Set = new Set(keys2);
- return !keys1.some((key) =>
- !keys2Set.has(key) || !compareByValue(object1[key], object2[key], depth + 1, options)
- );
+ const keys2Set = new Set(keys2);
+ return !keys1.some((key) => !keys2Set.has(key) || !compareByValue(object1[key], object2[key], depth + 1, options));
};
const DEFAULT_EQUAL_BY_VALUE_OPTS = {
- maxDepth: 3,
- strict: true,
+ maxDepth: 3,
+ strict: true,
};
const compareByValue = (value1, value2, depth, options) => {
- const { strict, maxDepth } = options;
- const comparable1 = toComparable(value1, true);
- const comparable2 = toComparable(value2, true);
-
- const comparisonResult = strict
- ? comparable1 === comparable2
- // eslint-disable-next-line eqeqeq
- : comparable1 == comparable2;
-
- switch(true) {
- case comparisonResult:
- case depth >= maxDepth:
- return true;
- case isObject(comparable1) && isObject(comparable2):
- return compareObjects(comparable1, comparable2, depth, options);
- case Array.isArray(comparable1) && Array.isArray(comparable2):
- return compareArrays(comparable1, comparable2, depth, options);
- default:
- return false;
- }
+ const { strict, maxDepth } = options;
+ const comparable1 = toComparable(value1, true);
+ const comparable2 = toComparable(value2, true);
+
+ const comparisonResult = strict
+ ? comparable1 === comparable2
+ // eslint-disable-next-line eqeqeq
+ : comparable1 == comparable2;
+
+ switch (true) {
+ case comparisonResult:
+ case depth >= maxDepth:
+ return true;
+ case isObject(comparable1) && isObject(comparable2):
+ return compareObjects(comparable1, comparable2, depth, options);
+ case Array.isArray(comparable1) && Array.isArray(comparable2):
+ return compareArrays(comparable1, comparable2, depth, options);
+ default:
+ return false;
+ }
};
export const equalByValue = (value1, value2, options = DEFAULT_EQUAL_BY_VALUE_OPTS) => {
- const compareOptions = { ...DEFAULT_EQUAL_BY_VALUE_OPTS, ...options };
- return compareByValue(value1, value2, 0, compareOptions);
+ const compareOptions = { ...DEFAULT_EQUAL_BY_VALUE_OPTS, ...options };
+ return compareByValue(value1, value2, 0, compareOptions);
+};
+
+export default {
+ ensureDefined,
+ executeAsync,
+ deferRender,
+ deferUpdate,
+ deferRenderer,
+ deferUpdater,
+ findBestMatches,
+ splitPair,
+ normalizeKey,
+ denormalizeKey,
+ pairToObject,
+ getKeyHash,
+ escapeRegExp,
+ applyServerDecimalSeparator,
+ noop,
+ asyncNoop,
+ grep,
+ equalByValue,
};
diff --git a/packages/devextreme/js/__internal/core/utils/m_comparator.ts b/packages/devextreme/js/__internal/core/utils/m_comparator.ts
index 36ba408364ea..0a4fd974984f 100644
--- a/packages/devextreme/js/__internal/core/utils/m_comparator.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_comparator.ts
@@ -1,32 +1,32 @@
-import domAdapter from '../dom_adapter';
-import { toComparable } from './data';
-import { isRenderer } from './type';
+import domAdapter from '@js/core/dom_adapter';
+import { toComparable } from '@js/core/utils/data';
+import { isRenderer } from '@js/core/utils/type';
-const hasNegation = function(oldValue, newValue) {
- return (1 / oldValue) === (1 / newValue);
+const hasNegation = function (oldValue, newValue) {
+ return (1 / oldValue) === (1 / newValue);
};
-export const equals = function(oldValue, newValue) {
- oldValue = toComparable(oldValue, true);
- newValue = toComparable(newValue, true);
+export const equals = function (oldValue, newValue) {
+ oldValue = toComparable(oldValue, true);
+ newValue = toComparable(newValue, true);
- if(oldValue && newValue && isRenderer(oldValue) && isRenderer(newValue)) {
- return newValue.is(oldValue);
- }
+ if (oldValue && newValue && isRenderer(oldValue) && isRenderer(newValue)) {
+ return newValue.is(oldValue);
+ }
- const oldValueIsNaN = oldValue !== oldValue;
- const newValueIsNaN = newValue !== newValue;
- if(oldValueIsNaN && newValueIsNaN) {
- return true;
- }
+ const oldValueIsNaN = oldValue !== oldValue;
+ const newValueIsNaN = newValue !== newValue;
+ if (oldValueIsNaN && newValueIsNaN) {
+ return true;
+ }
- if(oldValue === 0 && newValue === 0) {
- return hasNegation(oldValue, newValue);
- }
+ if (oldValue === 0 && newValue === 0) {
+ return hasNegation(oldValue, newValue);
+ }
- if(oldValue === null || typeof oldValue !== 'object' || domAdapter.isElementNode(oldValue)) {
- return oldValue === newValue;
- }
+ if (oldValue === null || typeof oldValue !== 'object' || domAdapter.isElementNode(oldValue)) {
+ return oldValue === newValue;
+ }
- return false;
+ return false;
};
diff --git a/packages/devextreme/js/__internal/core/utils/m_console.ts b/packages/devextreme/js/__internal/core/utils/m_console.ts
index ed1181b5c92a..0cba72576449 100644
--- a/packages/devextreme/js/__internal/core/utils/m_console.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_console.ts
@@ -1,34 +1,36 @@
/* global console */
/* eslint no-console: off */
-import { isFunction } from './type';
+import { isFunction } from '@js/core/utils/type';
-const noop = function() {};
-const getConsoleMethod = function(method) {
- if(typeof console === 'undefined' || !isFunction(console[method])) {
- return noop;
- }
- return console[method].bind(console);
+const noop = function () {};
+const getConsoleMethod = function (method) {
+ if (typeof console === 'undefined' || !isFunction(console[method])) {
+ return noop;
+ }
+ return console[method].bind(console);
};
export const logger = {
- log: getConsoleMethod('log'),
- info: getConsoleMethod('info'),
- warn: getConsoleMethod('warn'),
- error: getConsoleMethod('error')
+ log: getConsoleMethod('log'),
+ info: getConsoleMethod('info'),
+ warn: getConsoleMethod('warn'),
+ error: getConsoleMethod('error'),
};
-export const debug = (function() {
- function assert(condition, message) {
- if(!condition) {
- throw new Error(message);
- }
- }
- function assertParam(parameter, message) {
- assert(parameter !== null && parameter !== undefined, message);
+export const debug = (function () {
+ function assert(condition, message) {
+ if (!condition) {
+ throw new Error(message);
}
- return {
- assert: assert,
- assertParam: assertParam
- };
+ }
+ function assertParam(parameter, message) {
+ assert(parameter !== null && parameter !== undefined, message);
+ }
+ return {
+ assert,
+ assertParam,
+ };
}());
+
+export default { logger, debug };
diff --git a/packages/devextreme/js/__internal/core/utils/m_data.ts b/packages/devextreme/js/__internal/core/utils/m_data.ts
index 0daeed1c41e4..52a70b038e39 100644
--- a/packages/devextreme/js/__internal/core/utils/m_data.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_data.ts
@@ -1,221 +1,225 @@
-import errors from '../errors';
-import Class from '../class';
-import { deepExtendArraySafe } from './object';
-import { isObject, isPlainObject, isFunction, isDefined } from './type';
-import { each } from './iterator';
-import variableWrapper from './variable_wrapper';
+import Class from '@js/core/class';
+import errors from '@js/core/errors';
+import { each } from '@js/core/utils/iterator';
+import { deepExtendArraySafe } from '@js/core/utils/object';
+import {
+ isDefined, isFunction, isObject, isPlainObject,
+} from '@js/core/utils/type';
+import variableWrapper from '@js/core/utils/variable_wrapper';
+
const unwrapVariable = variableWrapper.unwrap;
-const isWrapped = variableWrapper.isWrapped;
-const assign = variableWrapper.assign;
+const { isWrapped } = variableWrapper;
+const { assign } = variableWrapper;
-const bracketsToDots = function(expr) {
- return expr
- .replace(/\[/g, '.')
- .replace(/\]/g, '');
+const bracketsToDots = function (expr) {
+ return expr
+ .replace(/\[/g, '.')
+ .replace(/\]/g, '');
};
-export const getPathParts = function(name) {
- return bracketsToDots(name).split('.');
+export const getPathParts = function (name) {
+ return bracketsToDots(name).split('.');
};
-const readPropValue = function(obj, propName, options) {
- options = options || { };
- if(propName === 'this') {
- return unwrap(obj, options);
- }
- return unwrap(obj[propName], options);
+const readPropValue = function (obj, propName, options) {
+ options = options || { };
+ if (propName === 'this') {
+ return unwrap(obj, options);
+ }
+ return unwrap(obj[propName], options);
};
-const assignPropValue = function(obj, propName, value, options) {
- if(propName === 'this') {
- throw new errors.Error('E4016');
- }
-
- const propValue = obj[propName];
- if(options.unwrapObservables && isWrapped(propValue)) {
- assign(propValue, value);
- } else {
- obj[propName] = value;
- }
+const assignPropValue = function (obj, propName, value, options) {
+ if (propName === 'this') {
+ // @ts-expect-error only void function can be called with new
+ throw new errors.Error('E4016');
+ }
+
+ const propValue = obj[propName];
+ if (options.unwrapObservables && isWrapped(propValue)) {
+ assign(propValue, value);
+ } else {
+ obj[propName] = value;
+ }
};
-const prepareOptions = function(options) {
- options = options || {};
- options.unwrapObservables = options.unwrapObservables !== undefined ? options.unwrapObservables : true;
- return options;
+const prepareOptions = function (options) {
+ options = options || {};
+ options.unwrapObservables = options.unwrapObservables !== undefined ? options.unwrapObservables : true;
+ return options;
};
function unwrap(value, options) {
- return options.unwrapObservables ? unwrapVariable(value) : value;
+ return options.unwrapObservables ? unwrapVariable(value) : value;
}
-export const compileGetter = function(expr) {
- if(arguments.length > 1) {
- expr = [].slice.call(arguments);
- }
-
- if(!expr || expr === 'this') {
- return function(obj) { return obj; };
- }
-
- if(typeof expr === 'string') {
- const path = getPathParts(expr);
-
- return function(obj, options) {
- options = prepareOptions(options);
- const functionAsIs = options.functionsAsIs;
- const hasDefaultValue = 'defaultValue' in options;
- let current = unwrap(obj, options);
-
- for(let i = 0; i < path.length; i++) {
- if(!current) {
- if(current == null && hasDefaultValue) {
- return options.defaultValue;
- }
- break;
- }
+export const compileGetter = function (expr) {
+ if (arguments.length > 1) {
+ expr = [].slice.call(arguments);
+ }
+
+ if (!expr || expr === 'this') {
+ return function (obj) { return obj; };
+ }
+
+ if (typeof expr === 'string') {
+ const path = getPathParts(expr);
+
+ return function (obj, options) {
+ options = prepareOptions(options);
+ const functionAsIs = options.functionsAsIs;
+ const hasDefaultValue = 'defaultValue' in options;
+ let current = unwrap(obj, options);
+
+ for (let i = 0; i < path.length; i++) {
+ if (!current) {
+ if (current == null && hasDefaultValue) {
+ return options.defaultValue;
+ }
+ break;
+ }
- const pathPart = path[i];
+ const pathPart = path[i];
- if(hasDefaultValue && isObject(current) && !(pathPart in current)) {
- return options.defaultValue;
- }
+ if (hasDefaultValue && isObject(current) && !(pathPart in current)) {
+ return options.defaultValue;
+ }
- let next = unwrap(current[pathPart], options);
+ let next = unwrap(current[pathPart], options);
- if(!functionAsIs && isFunction(next)) {
- next = next.call(current);
- }
+ if (!functionAsIs && isFunction(next)) {
+ next = next.call(current);
+ }
- current = next;
- }
+ current = next;
+ }
- return current;
- };
- }
+ return current;
+ };
+ }
- if(Array.isArray(expr)) {
- return combineGetters(expr);
- }
+ if (Array.isArray(expr)) {
+ return combineGetters(expr);
+ }
- if(isFunction(expr)) {
- return expr;
- }
+ if (isFunction(expr)) {
+ return expr;
+ }
};
function combineGetters(getters) {
- const compiledGetters = {};
- for(let i = 0, l = getters.length; i < l; i++) {
- const getter = getters[i];
- compiledGetters[getter] = compileGetter(getter);
- }
-
- return function(obj, options) {
- let result;
-
- each(compiledGetters, function(name) {
- const value = this(obj, options);
-
- if(value === undefined) {
- return;
- }
-
- let current = (result || (result = {}));
- const path = name.split('.');
- const last = path.length - 1;
-
- for(let i = 0; i < last; i++) {
- const pathItem = path[i];
- if(!(pathItem in current)) {
- current[pathItem] = { };
- }
- current = current[pathItem];
- }
+ const compiledGetters = {};
+ for (let i = 0, l = getters.length; i < l; i++) {
+ const getter = getters[i];
+ compiledGetters[getter] = compileGetter(getter);
+ }
+
+ return function (obj, options) {
+ let result;
+
+ each(compiledGetters, function (name) {
+ const value = this(obj, options);
+
+ if (value === undefined) {
+ return;
+ }
+
+ let current = result || (result = {});
+ const path = name.split('.');
+ const last = path.length - 1;
+
+ for (let i = 0; i < last; i++) {
+ const pathItem = path[i];
+ if (!(pathItem in current)) {
+ current[pathItem] = { };
+ }
+ current = current[pathItem];
+ }
- current[path[last]] = value;
- });
- return result;
- };
+ current[path[last]] = value;
+ });
+ return result;
+ };
}
function toLowerCase(value, options) {
- return options?.locale ? value.toLocaleLowerCase(options.locale) : value.toLowerCase();
+ return options?.locale ? value.toLocaleLowerCase(options.locale) : value.toLowerCase();
}
function toUpperCase(value, options) {
- return options?.locale ? value.toLocaleUpperCase(options.locale) : value.toUpperCase();
+ return options?.locale ? value.toLocaleUpperCase(options.locale) : value.toUpperCase();
}
-const ensurePropValueDefined = function(obj, propName, value, options) {
- if(isDefined(value)) {
- return value;
- }
+const ensurePropValueDefined = function (obj, propName, value, options) {
+ if (isDefined(value)) {
+ return value;
+ }
- const newValue = {};
- assignPropValue(obj, propName, newValue, options);
+ const newValue = {};
+ assignPropValue(obj, propName, newValue, options);
- return newValue;
+ return newValue;
};
-export const compileSetter = function(expr) {
- expr = getPathParts(expr || 'this');
- const lastLevelIndex = expr.length - 1;
-
- return function(obj, value, options) {
- options = prepareOptions(options);
- let currentValue = unwrap(obj, options);
-
- expr.forEach(function(propertyName, levelIndex) {
- let propertyValue = readPropValue(currentValue, propertyName, options);
- const isPropertyFunc = !options.functionsAsIs && isFunction(propertyValue) && !isWrapped(propertyValue);
-
- if(levelIndex === lastLevelIndex) {
- if(options.merge && isPlainObject(value) && (!isDefined(propertyValue) || isPlainObject(propertyValue))) {
- propertyValue = ensurePropValueDefined(currentValue, propertyName, propertyValue, options);
- deepExtendArraySafe(propertyValue, value, false, true);
- } else if(isPropertyFunc) {
- currentValue[propertyName](value);
- } else {
- assignPropValue(currentValue, propertyName, value, options);
- }
- } else {
- propertyValue = ensurePropValueDefined(currentValue, propertyName, propertyValue, options);
- if(isPropertyFunc) {
- propertyValue = propertyValue.call(currentValue);
- }
- currentValue = propertyValue;
- }
- });
- };
+export const compileSetter = function (expr) {
+ expr = getPathParts(expr || 'this');
+ const lastLevelIndex = expr.length - 1;
+
+ return function (obj, value, options) {
+ options = prepareOptions(options);
+ let currentValue = unwrap(obj, options);
+
+ expr.forEach(function (propertyName, levelIndex) {
+ let propertyValue = readPropValue(currentValue, propertyName, options);
+ const isPropertyFunc = !options.functionsAsIs && isFunction(propertyValue) && !isWrapped(propertyValue);
+
+ if (levelIndex === lastLevelIndex) {
+ if (options.merge && isPlainObject(value) && (!isDefined(propertyValue) || isPlainObject(propertyValue))) {
+ propertyValue = ensurePropValueDefined(currentValue, propertyName, propertyValue, options);
+ deepExtendArraySafe(propertyValue, value, false, true);
+ } else if (isPropertyFunc) {
+ currentValue[propertyName](value);
+ } else {
+ assignPropValue(currentValue, propertyName, value, options);
+ }
+ } else {
+ propertyValue = ensurePropValueDefined(currentValue, propertyName, propertyValue, options);
+ if (isPropertyFunc) {
+ propertyValue = propertyValue.call(currentValue);
+ }
+ currentValue = propertyValue;
+ }
+ });
+ };
};
-export const toComparable = function(value, caseSensitive, options = {}) {
- if(value instanceof Date) {
- return value.getTime();
- }
+export const toComparable = function (value, caseSensitive?, options: any = {}) {
+ if (value instanceof Date) {
+ return value.getTime();
+ }
- const collatorSensitivity = options?.collatorOptions?.sensitivity;
+ const collatorSensitivity = options?.collatorOptions?.sensitivity;
- if(value && value instanceof Class && value.valueOf) {
- value = value.valueOf();
- } else if(typeof value === 'string' && (collatorSensitivity === 'base' || collatorSensitivity === 'case')) {
- const REMOVE_DIACRITICAL_MARKS_REGEXP = /[\u0300-\u036f]/g;
+ if (value && value instanceof Class && value.valueOf) {
+ value = value.valueOf();
+ } else if (typeof value === 'string' && (collatorSensitivity === 'base' || collatorSensitivity === 'case')) {
+ const REMOVE_DIACRITICAL_MARKS_REGEXP = /[\u0300-\u036f]/g;
- if(collatorSensitivity === 'base') {
- value = toLowerCase(value, options);
- }
-
- value = value.normalize('NFD').replace(REMOVE_DIACRITICAL_MARKS_REGEXP, '');
+ if (collatorSensitivity === 'base') {
+ value = toLowerCase(value, options);
}
- const isCaseSensitive = caseSensitive || collatorSensitivity === 'case' || collatorSensitivity === 'variant';
+ value = value.normalize('NFD').replace(REMOVE_DIACRITICAL_MARKS_REGEXP, '');
+ }
- if(typeof value === 'string' && !isCaseSensitive) {
- const locale = options?.locale?.toLowerCase();
- const useUpperCase = locale && !!['hy', 'el'].find((code) => locale === code || locale.startsWith(`${code}-`));
+ const isCaseSensitive = caseSensitive || collatorSensitivity === 'case' || collatorSensitivity === 'variant';
- return (useUpperCase ? toUpperCase : toLowerCase)(value, options);
- }
+ if (typeof value === 'string' && !isCaseSensitive) {
+ const locale = options?.locale?.toLowerCase();
+ const useUpperCase = locale && !!['hy', 'el'].find((code) => locale === code || locale.startsWith(`${code}-`));
- return value;
+ return (useUpperCase ? toUpperCase : toLowerCase)(value, options);
+ }
+
+ return value;
};
diff --git a/packages/devextreme/js/__internal/core/utils/m_date.ts b/packages/devextreme/js/__internal/core/utils/m_date.ts
index 7c9dde7451c4..ed5f11487ef6 100644
--- a/packages/devextreme/js/__internal/core/utils/m_date.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_date.ts
@@ -1,11 +1,14 @@
/* globals Intl */
// TODO refactoring: Review all date utils functions and move useful to __internal/core/utils/date.ts
-import { isObject, isString, isDate, isDefined, isNumeric } from './type';
-import { adjust } from './math';
-import { each } from './iterator';
-import { camelize } from './inflector';
-import { toMilliseconds } from '../../renovation/ui/common/utils/date/index';
-import dateSerialization from './date_serialization';
+import dateSerialization from '@js/core/utils/date_serialization';
+import { camelize } from '@js/core/utils/inflector';
+import { each } from '@js/core/utils/iterator';
+import { adjust } from '@js/core/utils/math';
+import {
+ isDate, isDefined, isNumeric, isObject, isString,
+} from '@js/core/utils/type';
+
+import { toMilliseconds } from '../../../renovation/ui/common/utils/date/index';
const DAYS_IN_WEEK = 7;
const THURSDAY_WEEK_NUMBER = 4;
@@ -14,782 +17,787 @@ const USUAL_WEEK_COUNT_IN_YEAR = 52;
const dateUnitIntervals = ['millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'];
-const getDatesInterval = function(startDate, endDate, intervalUnit) {
- const delta = endDate.getTime() - startDate.getTime();
- const millisecondCount = toMilliseconds(intervalUnit) || 1;
-
- return Math.floor(delta / millisecondCount);
-};
-
-const getNextDateUnit = function(unit, withWeeks) {
- const interval = getDateUnitInterval(unit);
-
- switch(interval) {
- case 'millisecond':
- return 'second';
- case 'second':
- return 'minute';
- case 'minute':
- return 'hour';
- case 'hour':
- return 'day';
- case 'day':
- return withWeeks ? 'week' : 'month';
- case 'week':
- return 'month';
- case 'month':
- return 'quarter';
- case 'quarter':
- return 'year';
- case 'year':
- return 'year';
- default:
- return 0;
- }
-};
-
-const convertMillisecondsToDateUnits = function(value) {
- let i;
- let dateUnitCount;
- let dateUnitInterval;
- const dateUnitIntervals = ['millisecond', 'second', 'minute', 'hour', 'day', 'month', 'year'];
- const result = {};
-
- for(i = dateUnitIntervals.length - 1; i >= 0; i--) {
- dateUnitInterval = dateUnitIntervals[i];
- dateUnitCount = Math.floor(value / toMilliseconds(dateUnitInterval));
- if(dateUnitCount > 0) {
- result[dateUnitInterval + 's'] = dateUnitCount;
- value -= convertDateUnitToMilliseconds(dateUnitInterval, dateUnitCount);
- }
- }
- return result;
-};
-
-const dateToMilliseconds = function(tickInterval) {
- let milliseconds = 0;
- if(isObject(tickInterval)) {
- each(tickInterval, function(key, value) {
- milliseconds += convertDateUnitToMilliseconds(key.substr(0, key.length - 1), value);
- });
- }
- if(isString(tickInterval)) {
- milliseconds = convertDateUnitToMilliseconds(tickInterval, 1);
- }
- return milliseconds;
+const getDatesInterval = function (startDate, endDate, intervalUnit) {
+ const delta = endDate.getTime() - startDate.getTime();
+ const millisecondCount = toMilliseconds(intervalUnit) || 1;
+
+ return Math.floor(delta / millisecondCount);
+};
+
+const getNextDateUnit = function (unit, withWeeks) {
+ const interval = getDateUnitInterval(unit);
+
+ switch (interval) {
+ case 'millisecond':
+ return 'second';
+ case 'second':
+ return 'minute';
+ case 'minute':
+ return 'hour';
+ case 'hour':
+ return 'day';
+ case 'day':
+ return withWeeks ? 'week' : 'month';
+ case 'week':
+ return 'month';
+ case 'month':
+ return 'quarter';
+ case 'quarter':
+ return 'year';
+ case 'year':
+ return 'year';
+ default:
+ return 0;
+ }
+};
+
+const convertMillisecondsToDateUnits = function (value) {
+ let i;
+ let dateUnitCount;
+ let dateUnitInterval;
+ const dateUnitIntervals = ['millisecond', 'second', 'minute', 'hour', 'day', 'month', 'year'];
+ const result = {};
+
+ for (i = dateUnitIntervals.length - 1; i >= 0; i--) {
+ dateUnitInterval = dateUnitIntervals[i];
+ dateUnitCount = Math.floor(value / toMilliseconds(dateUnitInterval));
+ if (dateUnitCount > 0) {
+ result[`${dateUnitInterval}s`] = dateUnitCount;
+ value -= convertDateUnitToMilliseconds(dateUnitInterval, dateUnitCount);
+ }
+ }
+ return result;
+};
+
+const dateToMilliseconds = function (tickInterval) {
+ let milliseconds = 0;
+ if (isObject(tickInterval)) {
+ each(tickInterval, function (key, value) {
+ milliseconds += convertDateUnitToMilliseconds(key.substr(0, key.length - 1), value);
+ });
+ }
+ if (isString(tickInterval)) {
+ milliseconds = convertDateUnitToMilliseconds(tickInterval, 1);
+ }
+ return milliseconds;
};
function convertDateUnitToMilliseconds(dateUnit, count) {
- return toMilliseconds(dateUnit) * count;
+ return toMilliseconds(dateUnit) * count;
}
// refactor for performance
function getDateUnitInterval(tickInterval) {
- let maxInterval = -1;
- let i;
-
- if(isString(tickInterval)) {
- return tickInterval;
- }
-
- if(isObject(tickInterval)) {
- each(tickInterval, function(key, value) {
- for(i = 0; i < dateUnitIntervals.length; i++) {
- if(value && (key === dateUnitIntervals[i] + 's' || key === dateUnitIntervals[i]) && maxInterval < i) {
- maxInterval = i;
- }
- }
- });
+ let maxInterval = -1;
+ let i;
+
+ if (isString(tickInterval)) {
+ return tickInterval;
+ }
+
+ if (isObject(tickInterval)) {
+ each(tickInterval, function (key, value) {
+ for (i = 0; i < dateUnitIntervals.length; i++) {
+ if (value && (key === `${dateUnitIntervals[i]}s` || key === dateUnitIntervals[i]) && maxInterval < i) {
+ maxInterval = i;
+ }
+ }
+ });
- return dateUnitIntervals[maxInterval];
- }
- return '';
+ return dateUnitIntervals[maxInterval];
+ }
+ return '';
}
// T375972
const tickIntervalToFormatMap = {
- millisecond: 'millisecond',
- second: 'longtime',
- minute: 'shorttime',
- hour: 'shorttime',
- day: 'day',
- week: 'day',
- month: 'month',
- quarter: 'quarter',
- year: 'year'
+ millisecond: 'millisecond',
+ second: 'longtime',
+ minute: 'shorttime',
+ hour: 'shorttime',
+ day: 'day',
+ week: 'day',
+ month: 'month',
+ quarter: 'quarter',
+ year: 'year',
};
// Because of changes in formatting (Globalize has been updated) common date formatting has been changed.
// The purpose of the following method is to preserve original dates formatting in axes and range selector slider markers.
function getDateFormatByTickInterval(tickInterval) {
- return tickIntervalToFormatMap[getDateUnitInterval(tickInterval)] || '';
+ return tickIntervalToFormatMap[getDateUnitInterval(tickInterval)] || '';
}
-const getQuarter = function(month) {
- return Math.floor(month / 3);
-};
-
-const getFirstQuarterMonth = function(month) {
- return getQuarter(month) * 3;
-};
-
-function correctDateWithUnitBeginning(date, dateInterval, withCorrection, firstDayOfWeek) {
- date = new Date(date.getTime());
- const oldDate = new Date(date.getTime());
- let firstQuarterMonth;
- let month;
- const dateUnitInterval = getDateUnitInterval(dateInterval);
-
- switch(dateUnitInterval) {
- case 'second':
- date = new Date(Math.floor(oldDate.getTime() / 1000) * 1000);
- break;
- case 'minute':
- date = new Date(Math.floor(oldDate.getTime() / 60000) * 60000);
- break;
- case 'hour':
- date = new Date(Math.floor(oldDate.getTime() / 3600000) * 3600000);
- break;
- case 'year':
- date.setMonth(0);
- /* falls through */
- case 'month':
- date.setDate(1);
- /* falls through */
- case 'day':
- date.setHours(0, 0, 0, 0);
- break;
- case 'week':
- date = getFirstWeekDate(date, firstDayOfWeek || 0);
- date.setHours(0, 0, 0, 0);
- break;
- case 'quarter':
- firstQuarterMonth = getFirstQuarterMonth(date.getMonth());
- month = date.getMonth();
-
- date.setDate(1);
- date.setHours(0, 0, 0, 0);
- if(month !== firstQuarterMonth) {
- date.setMonth(firstQuarterMonth);
- }
- break;
- }
-
- if(withCorrection && dateUnitInterval !== 'hour' && dateUnitInterval !== 'minute' && dateUnitInterval !== 'second') {
- fixTimezoneGap(oldDate, date);
- }
- return date;
+const getQuarter = function (month) {
+ return Math.floor(month / 3);
+};
+
+const getFirstQuarterMonth = function (month) {
+ return getQuarter(month) * 3;
+};
+
+function correctDateWithUnitBeginning(date, dateInterval, withCorrection?, firstDayOfWeek?) {
+ date = new Date(date.getTime());
+ const oldDate = new Date(date.getTime());
+ let firstQuarterMonth;
+ let month;
+ const dateUnitInterval = getDateUnitInterval(dateInterval);
+
+ // eslint-disable-next-line default-case
+ switch (dateUnitInterval) {
+ case 'second':
+ date = new Date(Math.floor(oldDate.getTime() / 1000) * 1000);
+ break;
+ case 'minute':
+ date = new Date(Math.floor(oldDate.getTime() / 60000) * 60000);
+ break;
+ case 'hour':
+ date = new Date(Math.floor(oldDate.getTime() / 3600000) * 3600000);
+ break;
+ case 'year':
+ date.setMonth(0);
+ /* falls through */
+ case 'month':
+ date.setDate(1);
+ /* falls through */
+ case 'day':
+ date.setHours(0, 0, 0, 0);
+ break;
+ case 'week':
+ date = getFirstWeekDate(date, firstDayOfWeek || 0);
+ date.setHours(0, 0, 0, 0);
+ break;
+ case 'quarter':
+ firstQuarterMonth = getFirstQuarterMonth(date.getMonth());
+ month = date.getMonth();
+
+ date.setDate(1);
+ date.setHours(0, 0, 0, 0);
+ if (month !== firstQuarterMonth) {
+ date.setMonth(firstQuarterMonth);
+ }
+ break;
+ }
+
+ if (withCorrection && dateUnitInterval !== 'hour' && dateUnitInterval !== 'minute' && dateUnitInterval !== 'second') {
+ fixTimezoneGap(oldDate, date);
+ }
+ return date;
}
function trimTime(date) {
- return correctDateWithUnitBeginning(date, 'day');
+ return correctDateWithUnitBeginning(date, 'day');
}
-const setToDayEnd = function(date) {
- const result = trimTime(date);
+const setToDayEnd = function (date) {
+ const result = trimTime(date);
- result.setDate(result.getDate() + 1);
- return new Date(result.getTime() - 1);
+ result.setDate(result.getDate() + 1);
+ return new Date(result.getTime() - 1);
};
+const getDatesDifferences = function (date1, date2) {
+ let counter = 0;
-const getDatesDifferences = function(date1, date2) {
- let counter = 0;
+ const differences: any = {
+ year: date1.getFullYear() !== date2.getFullYear(),
+ month: date1.getMonth() !== date2.getMonth(),
+ day: date1.getDate() !== date2.getDate(),
+ hour: date1.getHours() !== date2.getHours(),
+ minute: date1.getMinutes() !== date2.getMinutes(),
+ second: date1.getSeconds() !== date2.getSeconds(),
+ millisecond: date1.getMilliseconds() !== date2.getMilliseconds(),
+ };
- const differences = {
- year: date1.getFullYear() !== date2.getFullYear(),
- month: date1.getMonth() !== date2.getMonth(),
- day: date1.getDate() !== date2.getDate(),
- hour: date1.getHours() !== date2.getHours(),
- minute: date1.getMinutes() !== date2.getMinutes(),
- second: date1.getSeconds() !== date2.getSeconds(),
- millisecond: date1.getMilliseconds() !== date2.getMilliseconds()
- };
-
- each(differences, function(key, value) {
- if(value) {
- counter++;
- }
- });
- if(counter === 0 && getTimezonesDifference(date1, date2) !== 0) {
- differences.hour = true;
- counter++;
+ each(differences, function (key, value) {
+ if (value) {
+ counter++;
}
+ });
+ if (counter === 0 && getTimezonesDifference(date1, date2) !== 0) {
+ differences.hour = true;
+ counter++;
+ }
- differences.count = counter;
- return differences;
+ differences.count = counter;
+ return differences;
};
function addDateInterval(value, interval, dir) {
- const result = new Date(value.getTime());
- const intervalObject = isString(interval) ? getDateIntervalByString(interval.toLowerCase())
- : isNumeric(interval) ? convertMillisecondsToDateUnits(interval)
- : interval;
- if(intervalObject.years) {
- result.setFullYear(result.getFullYear() + intervalObject.years * dir);
- }
- if(intervalObject.quarters) {
- result.setMonth(result.getMonth() + 3 * intervalObject.quarters * dir);
- }
- if(intervalObject.months) {
- result.setMonth(result.getMonth() + intervalObject.months * dir);
- }
- if(intervalObject.weeks) {
- result.setDate(result.getDate() + 7 * intervalObject.weeks * dir);
- }
- if(intervalObject.days) {
- result.setDate(result.getDate() + intervalObject.days * dir);
- }
- if(intervalObject.hours) {
- result.setTime(result.getTime() + intervalObject.hours * 3600000 * dir);
- }
- if(intervalObject.minutes) {
- result.setTime(result.getTime() + intervalObject.minutes * 60000 * dir);
- }
- if(intervalObject.seconds) {
- result.setTime(result.getTime() + intervalObject.seconds * 1000 * dir);
- }
- if(intervalObject.milliseconds) {
- result.setTime(result.getTime() + intervalObject.milliseconds * dir);
- }
- return result;
+ const result = new Date(value.getTime());
+ const intervalObject = isString(interval) ? getDateIntervalByString(interval.toLowerCase())
+ : isNumeric(interval) ? convertMillisecondsToDateUnits(interval)
+ : interval;
+ if (intervalObject.years) {
+ result.setFullYear(result.getFullYear() + intervalObject.years * dir);
+ }
+ if (intervalObject.quarters) {
+ result.setMonth(result.getMonth() + 3 * intervalObject.quarters * dir);
+ }
+ if (intervalObject.months) {
+ result.setMonth(result.getMonth() + intervalObject.months * dir);
+ }
+ if (intervalObject.weeks) {
+ result.setDate(result.getDate() + 7 * intervalObject.weeks * dir);
+ }
+ if (intervalObject.days) {
+ result.setDate(result.getDate() + intervalObject.days * dir);
+ }
+ if (intervalObject.hours) {
+ result.setTime(result.getTime() + intervalObject.hours * 3600000 * dir);
+ }
+ if (intervalObject.minutes) {
+ result.setTime(result.getTime() + intervalObject.minutes * 60000 * dir);
+ }
+ if (intervalObject.seconds) {
+ result.setTime(result.getTime() + intervalObject.seconds * 1000 * dir);
+ }
+ if (intervalObject.milliseconds) {
+ result.setTime(result.getTime() + intervalObject.milliseconds * dir);
+ }
+ return result;
}
-const addInterval = function(value, interval, isNegative) {
- const dir = isNegative ? -1 : +1;
- return isDate(value) ? addDateInterval(value, interval, dir) : adjust(value + interval * dir, interval);
+const addInterval = function (value, interval, isNegative?: boolean) {
+ const dir = isNegative ? -1 : +1;
+ return isDate(value) ? addDateInterval(value, interval, dir) : adjust(value + interval * dir, interval);
};
-const getSequenceByInterval = function(min, max, interval) {
- const intervals = [];
- let cur;
+const getSequenceByInterval = function (min, max, interval) {
+ const intervals: any[] = [];
+ let cur;
- intervals.push(isDate(min) ? new Date(min.getTime()) : min);
- cur = min;
- while(cur < max) {
- cur = addInterval(cur, interval);
- intervals.push(cur);
- }
- return intervals;
+ intervals.push(isDate(min) ? new Date(min.getTime()) : min);
+ cur = min;
+ while (cur < max) {
+ cur = addInterval(cur, interval);
+ intervals.push(cur);
+ }
+ return intervals;
};
-const getViewFirstCellDate = function(viewType, date) {
- if(viewType === 'month') { return createDateWithFullYear(date.getFullYear(), date.getMonth(), 1); }
- if(viewType === 'year') { return createDateWithFullYear(date.getFullYear(), 0, date.getDate()); }
- if(viewType === 'decade') { return createDateWithFullYear(getFirstYearInDecade(date), date.getMonth(), date.getDate()); }
- if(viewType === 'century') { return createDateWithFullYear(getFirstDecadeInCentury(date), date.getMonth(), date.getDate()); }
+// @ts-expect-error not all code paths return value
+const getViewFirstCellDate = function (viewType, date) {
+ if (viewType === 'month') { return createDateWithFullYear(date.getFullYear(), date.getMonth(), 1); }
+ if (viewType === 'year') { return createDateWithFullYear(date.getFullYear(), 0, date.getDate()); }
+ if (viewType === 'decade') { return createDateWithFullYear(getFirstYearInDecade(date), date.getMonth(), date.getDate()); }
+ if (viewType === 'century') { return createDateWithFullYear(getFirstDecadeInCentury(date), date.getMonth(), date.getDate()); }
};
-const getViewLastCellDate = function(viewType, date) {
- if(viewType === 'month') { return createDateWithFullYear(date.getFullYear(), date.getMonth(), getLastMonthDay(date)); }
- if(viewType === 'year') { return createDateWithFullYear(date.getFullYear(), 11, date.getDate()); }
- if(viewType === 'decade') { return createDateWithFullYear(getFirstYearInDecade(date) + 9, date.getMonth(), date.getDate()); }
- if(viewType === 'century') { return createDateWithFullYear(getFirstDecadeInCentury(date) + 90, date.getMonth(), date.getDate()); }
+// @ts-expect-error not all code paths return value
+const getViewLastCellDate = function (viewType, date) {
+ if (viewType === 'month') { return createDateWithFullYear(date.getFullYear(), date.getMonth(), getLastMonthDay(date)); }
+ if (viewType === 'year') { return createDateWithFullYear(date.getFullYear(), 11, date.getDate()); }
+ if (viewType === 'decade') { return createDateWithFullYear(getFirstYearInDecade(date) + 9, date.getMonth(), date.getDate()); }
+ if (viewType === 'century') { return createDateWithFullYear(getFirstDecadeInCentury(date) + 90, date.getMonth(), date.getDate()); }
};
-const getViewMinBoundaryDate = function(viewType, date) {
- const resultDate = createDateWithFullYear(date.getFullYear(), date.getMonth(), 1);
+const getViewMinBoundaryDate = function (viewType, date) {
+ const resultDate = createDateWithFullYear(date.getFullYear(), date.getMonth(), 1);
- if(viewType === 'month') {
- return resultDate;
- }
+ if (viewType === 'month') {
+ return resultDate;
+ }
- resultDate.setMonth(0);
+ resultDate.setMonth(0);
- if(viewType === 'year') {
- return resultDate;
- }
+ if (viewType === 'year') {
+ return resultDate;
+ }
- if(viewType === 'decade') {
- resultDate.setFullYear(getFirstYearInDecade(date));
- }
+ if (viewType === 'decade') {
+ resultDate.setFullYear(getFirstYearInDecade(date));
+ }
- if(viewType === 'century') {
- resultDate.setFullYear(getFirstDecadeInCentury(date));
- }
+ if (viewType === 'century') {
+ resultDate.setFullYear(getFirstDecadeInCentury(date));
+ }
- return resultDate;
+ return resultDate;
};
-const getViewMaxBoundaryDate = function(viewType, date) {
- const resultDate = new Date(date);
- resultDate.setDate(getLastMonthDay(date));
+const getViewMaxBoundaryDate = function (viewType, date) {
+ const resultDate = new Date(date);
+ resultDate.setDate(getLastMonthDay(date));
- if(viewType === 'month') {
- return resultDate;
- }
+ if (viewType === 'month') {
+ return resultDate;
+ }
- resultDate.setMonth(11);
- resultDate.setDate(getLastMonthDay(resultDate));
+ resultDate.setMonth(11);
+ resultDate.setDate(getLastMonthDay(resultDate));
- if(viewType === 'year') {
- return resultDate;
- }
+ if (viewType === 'year') {
+ return resultDate;
+ }
- if(viewType === 'decade') {
- resultDate.setFullYear(getFirstYearInDecade(date) + 9);
- }
+ if (viewType === 'decade') {
+ resultDate.setFullYear(getFirstYearInDecade(date) + 9);
+ }
- if(viewType === 'century') {
- resultDate.setFullYear(getFirstDecadeInCentury(date) + 99);
- }
+ if (viewType === 'century') {
+ resultDate.setFullYear(getFirstDecadeInCentury(date) + 99);
+ }
- return resultDate;
+ return resultDate;
};
function getLastMonthDay(date) {
- const resultDate = createDateWithFullYear(date.getFullYear(), date.getMonth() + 1, 0);
- return resultDate.getDate();
+ const resultDate = createDateWithFullYear(date.getFullYear(), date.getMonth() + 1, 0);
+ return resultDate.getDate();
}
-
-const getViewUp = function(typeView) {
- switch(typeView) {
- case 'month':
- return 'year';
- case 'year':
- return 'decade';
- case 'decade':
- return 'century';
- default:
- break;
- }
+// @ts-expect-error not all code paths return value
+const getViewUp = function (typeView) {
+ switch (typeView) {
+ case 'month':
+ return 'year';
+ case 'year':
+ return 'decade';
+ case 'decade':
+ return 'century';
+ default:
+ break;
+ }
};
-
-const getViewDown = function(typeView) {
- switch(typeView) {
- case 'century':
- return 'decade';
- case 'decade':
- return 'year';
- case 'year':
- return 'month';
- default:
- break;
- }
+// @ts-expect-error not all code paths return value
+const getViewDown = function (typeView) {
+ switch (typeView) {
+ case 'century':
+ return 'decade';
+ case 'decade':
+ return 'year';
+ case 'year':
+ return 'month';
+ default:
+ break;
+ }
};
-const getDifferenceInMonth = function(typeView) {
- let difference = 1;
+const getDifferenceInMonth = function (typeView) {
+ let difference = 1;
- if(typeView === 'year') { difference = 12; }
- if(typeView === 'decade') { difference = 12 * 10; }
- if(typeView === 'century') { difference = 12 * 100; }
+ if (typeView === 'year') { difference = 12; }
+ if (typeView === 'decade') { difference = 12 * 10; }
+ if (typeView === 'century') { difference = 12 * 100; }
- return difference;
+ return difference;
};
-const getDifferenceInMonthForCells = function(typeView) {
- let difference = 1;
+const getDifferenceInMonthForCells = function (typeView) {
+ let difference = 1;
- if(typeView === 'decade') { difference = 12; }
- if(typeView === 'century') { difference = 12 * 10; }
+ if (typeView === 'decade') { difference = 12; }
+ if (typeView === 'century') { difference = 12 * 10; }
- return difference;
+ return difference;
};
function getDateIntervalByString(intervalString) {
- const result = {};
- switch(intervalString) {
- case 'year':
- result.years = 1;
- break;
- case 'month':
- result.months = 1;
- break;
- case 'quarter':
- result.months = 3;
- break;
- case 'week':
- result.weeks = 1;
- break;
- case 'day':
- result.days = 1;
- break;
- case 'hour':
- result.hours = 1;
- break;
- case 'minute':
- result.minutes = 1;
- break;
- case 'second':
- result.seconds = 1;
- break;
- case 'millisecond':
- result.milliseconds = 1;
- break;
- }
- return result;
+ const result: any = {};
+ // eslint-disable-next-line default-case
+ switch (intervalString) {
+ case 'year':
+ result.years = 1;
+ break;
+ case 'month':
+ result.months = 1;
+ break;
+ case 'quarter':
+ result.months = 3;
+ break;
+ case 'week':
+ result.weeks = 1;
+ break;
+ case 'day':
+ result.days = 1;
+ break;
+ case 'hour':
+ result.hours = 1;
+ break;
+ case 'minute':
+ result.minutes = 1;
+ break;
+ case 'second':
+ result.seconds = 1;
+ break;
+ case 'millisecond':
+ result.milliseconds = 1;
+ break;
+ }
+ return result;
}
function sameDate(date1, date2) {
- return sameMonthAndYear(date1, date2) && date1.getDate() === date2.getDate();
+ return sameMonthAndYear(date1, date2) && date1.getDate() === date2.getDate();
}
function sameMonthAndYear(date1, date2) {
- return sameYear(date1, date2) && date1.getMonth() === date2.getMonth();
+ return sameYear(date1, date2) && date1.getMonth() === date2.getMonth();
}
function sameYear(date1, date2) {
- return date1 && date2 && date1.getFullYear() === date2.getFullYear();
+ return date1 && date2 && date1.getFullYear() === date2.getFullYear();
}
function sameHoursAndMinutes(date1, date2) {
- return date1 && date2 && date1.getHours() === date2.getHours() && date1.getMinutes() === date2.getMinutes();
+ return date1 && date2 && date1.getHours() === date2.getHours() && date1.getMinutes() === date2.getMinutes();
}
-const sameDecade = function(date1, date2) {
- if(!isDefined(date1) || !isDefined(date2)) return;
+const sameDecade = function (date1, date2) {
+ if (!isDefined(date1) || !isDefined(date2)) return;
- const startDecadeDate1 = date1.getFullYear() - date1.getFullYear() % 10;
- const startDecadeDate2 = date2.getFullYear() - date2.getFullYear() % 10;
+ const startDecadeDate1 = date1.getFullYear() - date1.getFullYear() % 10;
+ const startDecadeDate2 = date2.getFullYear() - date2.getFullYear() % 10;
- return date1 && date2 && startDecadeDate1 === startDecadeDate2;
+ return date1 && date2 && startDecadeDate1 === startDecadeDate2;
};
-const sameCentury = function(date1, date2) {
- if(!isDefined(date1) || !isDefined(date2)) return;
+const sameCentury = function (date1, date2) {
+ if (!isDefined(date1) || !isDefined(date2)) return;
- const startCenturyDate1 = date1.getFullYear() - date1.getFullYear() % 100;
- const startCenturyDate2 = date2.getFullYear() - date2.getFullYear() % 100;
+ const startCenturyDate1 = date1.getFullYear() - date1.getFullYear() % 100;
+ const startCenturyDate2 = date2.getFullYear() - date2.getFullYear() % 100;
- return date1 && date2 && startCenturyDate1 === startCenturyDate2;
+ return date1 && date2 && startCenturyDate1 === startCenturyDate2;
};
function getFirstDecadeInCentury(date) {
- return date && date.getFullYear() - date.getFullYear() % 100;
+ return date && date.getFullYear() - date.getFullYear() % 100;
}
function getFirstYearInDecade(date) {
- return date && date.getFullYear() - date.getFullYear() % 10;
+ return date && date.getFullYear() - date.getFullYear() % 10;
}
-const getShortDateFormat = function() {
- return 'yyyy/MM/dd';
+const getShortDateFormat = function () {
+ return 'yyyy/MM/dd';
};
-const getFirstMonthDate = function(date) {
- if(!isDefined(date)) return;
- return createDateWithFullYear(date.getFullYear(), date.getMonth(), 1);
+const getFirstMonthDate = function (date) {
+ if (!isDefined(date)) return;
+ return createDateWithFullYear(date.getFullYear(), date.getMonth(), 1);
};
-const getLastMonthDate = function(date) {
- if(!isDefined(date)) return;
- return createDateWithFullYear(date.getFullYear(), date.getMonth() + 1, 0);
+const getLastMonthDate = function (date) {
+ if (!isDefined(date)) return;
+ return createDateWithFullYear(date.getFullYear(), date.getMonth() + 1, 0);
};
function getFirstWeekDate(date, firstDayOfWeek) {
- const delta = (date.getDay() - firstDayOfWeek + DAYS_IN_WEEK) % DAYS_IN_WEEK;
+ const delta = (date.getDay() - firstDayOfWeek + DAYS_IN_WEEK) % DAYS_IN_WEEK;
- const result = new Date(date);
- result.setDate(date.getDate() - delta);
+ const result = new Date(date);
+ result.setDate(date.getDate() - delta);
- return result;
+ return result;
}
function getUTCTime(date) {
- return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate());
+ return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate());
}
function getDayNumber(date) {
- const ms = getUTCTime(date) - getUTCTime(getFirstDateInYear(date.getFullYear()));
+ const ms = getUTCTime(date) - getUTCTime(getFirstDateInYear(date.getFullYear()));
- return 1 + Math.floor(ms / toMilliseconds('day'));
+ return 1 + Math.floor(ms / toMilliseconds('day'));
}
function getFirstDateInYear(year) {
- return new Date(year, 0, 1);
+ return new Date(year, 0, 1);
}
function getLastDateInYear(year) {
- return new Date(year, 11, 31);
+ return new Date(year, 11, 31);
}
function getDayWeekNumber(date, firstDayOfWeek) {
- let day = date.getDay() - firstDayOfWeek + 1;
- if(day <= 0) { day += DAYS_IN_WEEK; }
+ let day = date.getDay() - firstDayOfWeek + 1;
+ if (day <= 0) { day += DAYS_IN_WEEK; }
- return day;
+ return day;
}
function getWeekNumber(date, firstDayOfWeek, rule) {
- const firstWeekDayInYear = getDayWeekNumber(getFirstDateInYear(date.getFullYear()), firstDayOfWeek);
- const lastWeekDayInYear = getDayWeekNumber(getLastDateInYear(date.getFullYear()), firstDayOfWeek);
- const daysInFirstWeek = DAYS_IN_WEEK - firstWeekDayInYear + 1;
-
- let weekNumber = Math.ceil((getDayNumber(date) - daysInFirstWeek) / 7);
- switch(rule) {
- case 'fullWeek': {
- if(daysInFirstWeek === DAYS_IN_WEEK) { weekNumber++; }
- if(weekNumber === 0) {
- const lastDateInPreviousYear = getLastDateInYear(date.getFullYear() - 1);
- return getWeekNumber(lastDateInPreviousYear, firstDayOfWeek, rule);
- }
- return weekNumber;
- }
- case 'firstDay': {
- if(daysInFirstWeek > 0) { weekNumber++; }
-
- const isSunday = firstWeekDayInYear === SUNDAY_WEEK_NUMBER
+ const firstWeekDayInYear = getDayWeekNumber(getFirstDateInYear(date.getFullYear()), firstDayOfWeek);
+ const lastWeekDayInYear = getDayWeekNumber(getLastDateInYear(date.getFullYear()), firstDayOfWeek);
+ const daysInFirstWeek = DAYS_IN_WEEK - firstWeekDayInYear + 1;
+
+ let weekNumber = Math.ceil((getDayNumber(date) - daysInFirstWeek) / 7);
+ switch (rule) {
+ case 'fullWeek': {
+ if (daysInFirstWeek === DAYS_IN_WEEK) { weekNumber++; }
+ if (weekNumber === 0) {
+ const lastDateInPreviousYear = getLastDateInYear(date.getFullYear() - 1);
+ return getWeekNumber(lastDateInPreviousYear, firstDayOfWeek, rule);
+ }
+ return weekNumber;
+ }
+ case 'firstDay': {
+ if (daysInFirstWeek > 0) { weekNumber++; }
+
+ const isSunday = firstWeekDayInYear === SUNDAY_WEEK_NUMBER
|| lastWeekDayInYear === SUNDAY_WEEK_NUMBER;
- if((weekNumber > USUAL_WEEK_COUNT_IN_YEAR && !isSunday) || weekNumber === 54) { weekNumber = 1; }
+ if ((weekNumber > USUAL_WEEK_COUNT_IN_YEAR && !isSunday) || weekNumber === 54) { weekNumber = 1; }
- return weekNumber;
- }
- case 'firstFourDays': {
- if(daysInFirstWeek > 3) { weekNumber++; }
+ return weekNumber;
+ }
+ case 'firstFourDays': {
+ if (daysInFirstWeek > 3) { weekNumber++; }
- const isThursday = firstWeekDayInYear === THURSDAY_WEEK_NUMBER
+ const isThursday = firstWeekDayInYear === THURSDAY_WEEK_NUMBER
|| lastWeekDayInYear === THURSDAY_WEEK_NUMBER;
- if(weekNumber > USUAL_WEEK_COUNT_IN_YEAR && !isThursday) { weekNumber = 1; }
+ if (weekNumber > USUAL_WEEK_COUNT_IN_YEAR && !isThursday) { weekNumber = 1; }
- if(weekNumber === 0) {
- const lastDateInPreviousYear = getLastDateInYear(date.getFullYear() - 1);
- return getWeekNumber(lastDateInPreviousYear, firstDayOfWeek, rule);
- }
- return weekNumber;
- }
- default:
- break;
+ if (weekNumber === 0) {
+ const lastDateInPreviousYear = getLastDateInYear(date.getFullYear() - 1);
+ return getWeekNumber(lastDateInPreviousYear, firstDayOfWeek, rule);
+ }
+ return weekNumber;
}
+ default:
+ break;
+ }
}
-const normalizeDateByWeek = function(date, currentDate) {
- const differenceInDays = dateUtils.getDatesInterval(date, currentDate, 'day');
- let resultDate = new Date(date);
+const normalizeDateByWeek = function (date, currentDate) {
+ const differenceInDays = dateUtils.getDatesInterval(date, currentDate, 'day');
+ let resultDate = new Date(date);
- if(differenceInDays >= 6) {
- resultDate = new Date(resultDate.setDate(resultDate.getDate() + 7));
- }
+ if (differenceInDays >= 6) {
+ resultDate = new Date(resultDate.setDate(resultDate.getDate() + 7));
+ }
- return resultDate;
+ return resultDate;
};
-const dateInRange = function(date, min, max, format) {
- if(format === 'date') {
- min = min && dateUtils.correctDateWithUnitBeginning(min, 'day');
- max = max && dateUtils.correctDateWithUnitBeginning(max, 'day');
- date = date && dateUtils.correctDateWithUnitBeginning(date, 'day');
- }
+const dateInRange = function (date, min, max, format?) {
+ if (format === 'date') {
+ min = min && dateUtils.correctDateWithUnitBeginning(min, 'day');
+ max = max && dateUtils.correctDateWithUnitBeginning(max, 'day');
+ date = date && dateUtils.correctDateWithUnitBeginning(date, 'day');
+ }
- return normalizeDate(date, min, max) === date;
+ return normalizeDate(date, min, max) === date;
};
-const intervalsOverlap = function(options) {
- const {
- firstMin,
- firstMax,
- secondMin,
- secondMax
- } = options;
+const intervalsOverlap = function (options) {
+ const {
+ firstMin,
+ firstMax,
+ secondMin,
+ secondMax,
+ } = options;
- return (firstMin <= secondMin && secondMin <= firstMax) ||
- (firstMin > secondMin && firstMin < secondMax) ||
- (firstMin < secondMax && firstMax > secondMax);
+ return (firstMin <= secondMin && secondMin <= firstMax)
+ || (firstMin > secondMin && firstMin < secondMax)
+ || (firstMin < secondMax && firstMax > secondMax);
};
-const dateTimeFromDecimal = function(number) {
- const hours = Math.floor(number);
- const minutes = (number % 1) * 60;
+const dateTimeFromDecimal = function (number) {
+ const hours = Math.floor(number);
+ const minutes = (number % 1) * 60;
- return {
- hours: hours,
- minutes: minutes
- };
+ return {
+ hours,
+ minutes,
+ };
};
-const roundDateByStartDayHour = function(date, startDayHour) {
- const startTime = this.dateTimeFromDecimal(startDayHour);
- const result = new Date(date);
+const roundDateByStartDayHour = function (date, startDayHour) {
+ const startTime = this.dateTimeFromDecimal(startDayHour);
+ const result = new Date(date);
- if(date.getHours() === startTime.hours && date.getMinutes() < startTime.minutes || date.getHours() < startTime.hours) {
- result.setHours(startTime.hours, startTime.minutes, 0, 0);
- }
+ if (date.getHours() === startTime.hours && date.getMinutes() < startTime.minutes || date.getHours() < startTime.hours) {
+ result.setHours(startTime.hours, startTime.minutes, 0, 0);
+ }
- return result;
+ return result;
};
-function normalizeDate(date, min, max) {
- let normalizedDate = date;
+function normalizeDate(date, min?, max?) {
+ let normalizedDate = date;
- if(!isDefined(date)) {
- return date;
- }
+ if (!isDefined(date)) {
+ return date;
+ }
- if(isDefined(min) && date < min) {
- normalizedDate = min;
- }
+ if (isDefined(min) && date < min) {
+ normalizedDate = min;
+ }
- if(isDefined(max) && date > max) {
- normalizedDate = max;
- }
+ if (isDefined(max) && date > max) {
+ normalizedDate = max;
+ }
- return normalizedDate;
+ return normalizedDate;
}
function fixTimezoneGap(oldDate, newDate) {
- // NOTE: T182866
- if(!isDefined(oldDate)) {
- return;
- }
+ // NOTE: T182866
+ if (!isDefined(oldDate)) {
+ return;
+ }
- const diff = newDate.getHours() - oldDate.getHours();
+ const diff = newDate.getHours() - oldDate.getHours();
- if(diff === 0) {
- return;
- }
+ if (diff === 0) {
+ return;
+ }
- const sign = (diff === 1 || diff === -23) ? -1 : 1;
- const trial = new Date(newDate.getTime() + sign * 3600000);
+ const sign = diff === 1 || diff === -23 ? -1 : 1;
+ const trial = new Date(newDate.getTime() + sign * 3600000);
- if(sign > 0 || trial.getDate() === newDate.getDate()) {
- newDate.setTime(trial.getTime());
- }
+ if (sign > 0 || trial.getDate() === newDate.getDate()) {
+ newDate.setTime(trial.getTime());
+ }
}
-const roundToHour = function(date) {
- const result = new Date(date.getTime());
+const roundToHour = function (date) {
+ const result = new Date(date.getTime());
- result.setHours(result.getHours() + 1);
- result.setMinutes(0);
+ result.setHours(result.getHours() + 1);
+ result.setMinutes(0);
- return result;
+ return result;
};
function getTimezonesDifference(min, max) {
- return (max.getTimezoneOffset() - min.getTimezoneOffset()) * 60 * 1000;
+ return (max.getTimezoneOffset() - min.getTimezoneOffset()) * 60 * 1000;
}
-const makeDate = function(date) {
- // TODO: will be useful later for work with different timezones
- return new Date(date);
+const makeDate = function (date) {
+ // TODO: will be useful later for work with different timezones
+ return new Date(date);
};
-const getDatesOfInterval = function(startDate, endDate, step) {
- const result = [];
- let currentDate = new Date(startDate.getTime());
+const getDatesOfInterval = function (startDate, endDate, step) {
+ const result: any[] = [];
+ let currentDate = new Date(startDate.getTime());
- while(currentDate < endDate) {
- result.push(new Date(currentDate.getTime()));
+ while (currentDate < endDate) {
+ result.push(new Date(currentDate.getTime()));
- currentDate = this.addInterval(currentDate, step);
- }
+ currentDate = this.addInterval(currentDate, step);
+ }
- return result;
+ return result;
};
-const createDateWithFullYear = function(year) {
- const result = new Date(...arguments);
- result.setFullYear(year);
- return result;
+const createDateWithFullYear = function (year, ...args) {
+ // @ts-expect-error spread should have tuple type
+ const result = new Date(year, ...args);
+ result.setFullYear(year);
+ return result;
};
const getMachineTimezoneName = () => {
- const hasIntl = typeof Intl !== 'undefined';
- return hasIntl
- ? Intl.DateTimeFormat().resolvedOptions().timeZone
- : null;
+ const hasIntl = typeof Intl !== 'undefined';
+ return hasIntl
+ ? Intl.DateTimeFormat().resolvedOptions().timeZone
+ : null;
};
const getRangesByDates = (dates) => {
- const datesInMilliseconds = dates.map((value) => correctDateWithUnitBeginning(value, 'day').getTime());
- const sortedDates = datesInMilliseconds.sort((a, b) => a - b);
+ const datesInMilliseconds = dates.map((value) => correctDateWithUnitBeginning(value, 'day').getTime());
+ const sortedDates = datesInMilliseconds.sort((a, b) => a - b);
- const msInDay = toMilliseconds('day');
- const ranges = [];
+ const msInDay = toMilliseconds('day');
+ const ranges: any[] = [];
- let startDate = sortedDates[0];
+ let startDate = sortedDates[0];
- for(let i = 1; i <= sortedDates.length; ++i) {
- const nextDate = sortedDates[i];
- const currentDate = sortedDates[i - 1];
+ for (let i = 1; i <= sortedDates.length; ++i) {
+ const nextDate = sortedDates[i];
+ const currentDate = sortedDates[i - 1];
- const isNewRange = nextDate - currentDate > msInDay;
+ const isNewRange = nextDate - currentDate > msInDay;
- if(isNewRange || i === sortedDates.length) {
- const range = startDate === sortedDates[i - 1]
- ? [startDate]
- : [startDate, sortedDates[i - 1]];
+ if (isNewRange || i === sortedDates.length) {
+ const range = startDate === sortedDates[i - 1]
+ ? [startDate]
+ : [startDate, sortedDates[i - 1]];
- const serializedRange = range.map((value) => dateSerialization.deserializeDate(value));
+ const serializedRange = range.map((value) => dateSerialization.deserializeDate(value));
- ranges.push(serializedRange);
+ ranges.push(serializedRange);
- startDate = nextDate;
- }
+ startDate = nextDate;
}
+ }
+
+ return ranges;
+};
- return ranges;
+const sameView = function (view, date1, date2) {
+ return dateUtils[camelize(`same ${view}`)](date1, date2);
};
const dateUtils = {
- dateUnitIntervals: dateUnitIntervals,
-
- convertMillisecondsToDateUnits: convertMillisecondsToDateUnits,
- dateToMilliseconds: dateToMilliseconds,
- getNextDateUnit: getNextDateUnit,
- convertDateUnitToMilliseconds: convertDateUnitToMilliseconds,
- getDateUnitInterval: getDateUnitInterval,
- getDateFormatByTickInterval: getDateFormatByTickInterval, // T375972
- getDatesDifferences: getDatesDifferences,
- correctDateWithUnitBeginning: correctDateWithUnitBeginning,
- trimTime: trimTime,
- setToDayEnd: setToDayEnd,
- roundDateByStartDayHour: roundDateByStartDayHour,
- dateTimeFromDecimal: dateTimeFromDecimal,
-
- addDateInterval: addDateInterval,
- addInterval: addInterval,
- getSequenceByInterval: getSequenceByInterval,
- getDateIntervalByString: getDateIntervalByString,
- sameHoursAndMinutes: sameHoursAndMinutes,
- sameDate: sameDate,
- sameMonthAndYear: sameMonthAndYear,
- sameMonth: sameMonthAndYear,
- sameYear: sameYear,
- sameDecade: sameDecade,
- sameCentury: sameCentury,
- getDifferenceInMonth: getDifferenceInMonth,
- getDifferenceInMonthForCells: getDifferenceInMonthForCells,
- getFirstYearInDecade: getFirstYearInDecade,
- getFirstDecadeInCentury: getFirstDecadeInCentury,
- getShortDateFormat: getShortDateFormat,
- getViewFirstCellDate: getViewFirstCellDate,
- getViewLastCellDate: getViewLastCellDate,
- getViewDown: getViewDown,
- getViewUp: getViewUp,
- getLastMonthDay: getLastMonthDay,
- getLastMonthDate: getLastMonthDate,
- getFirstMonthDate: getFirstMonthDate,
- getFirstWeekDate: getFirstWeekDate,
- getWeekNumber: getWeekNumber,
- normalizeDateByWeek: normalizeDateByWeek,
- getQuarter: getQuarter,
- getFirstQuarterMonth: getFirstQuarterMonth,
- dateInRange: dateInRange,
- intervalsOverlap: intervalsOverlap,
- roundToHour: roundToHour,
- normalizeDate: normalizeDate,
- getViewMinBoundaryDate: getViewMinBoundaryDate,
- getViewMaxBoundaryDate: getViewMaxBoundaryDate,
-
- fixTimezoneGap: fixTimezoneGap,
- getTimezonesDifference: getTimezonesDifference,
-
- makeDate: makeDate,
-
- getDatesInterval: getDatesInterval,
-
- getDatesOfInterval: getDatesOfInterval,
-
- createDateWithFullYear: createDateWithFullYear,
-
- getMachineTimezoneName: getMachineTimezoneName,
-
- getRangesByDates: getRangesByDates,
-};
-
-dateUtils.sameView = function(view, date1, date2) {
- return dateUtils[camelize('same ' + view)](date1, date2);
-};
-
-export default dateUtils;
+ dateUnitIntervals,
+
+ convertMillisecondsToDateUnits,
+ dateToMilliseconds,
+ getNextDateUnit,
+ convertDateUnitToMilliseconds,
+ getDateUnitInterval,
+ getDateFormatByTickInterval, // T375972
+ getDatesDifferences,
+ correctDateWithUnitBeginning,
+ trimTime,
+ setToDayEnd,
+ roundDateByStartDayHour,
+ dateTimeFromDecimal,
+
+ addDateInterval,
+ addInterval,
+ getSequenceByInterval,
+ getDateIntervalByString,
+ sameHoursAndMinutes,
+ sameDate,
+ sameMonthAndYear,
+ sameMonth: sameMonthAndYear,
+ sameYear,
+ sameDecade,
+ sameCentury,
+ sameView,
+ getDifferenceInMonth,
+ getDifferenceInMonthForCells,
+ getFirstYearInDecade,
+ getFirstDecadeInCentury,
+ getShortDateFormat,
+ getViewFirstCellDate,
+ getViewLastCellDate,
+ getViewDown,
+ getViewUp,
+ getLastMonthDay,
+ getLastMonthDate,
+ getFirstMonthDate,
+ getFirstWeekDate,
+ getWeekNumber,
+ normalizeDateByWeek,
+ getQuarter,
+ getFirstQuarterMonth,
+ dateInRange,
+ intervalsOverlap,
+ roundToHour,
+ normalizeDate,
+ getViewMinBoundaryDate,
+ getViewMaxBoundaryDate,
+
+ fixTimezoneGap,
+ getTimezonesDifference,
+
+ makeDate,
+
+ getDatesInterval,
+
+ getDatesOfInterval,
+
+ createDateWithFullYear,
+
+ getMachineTimezoneName,
+
+ getRangesByDates,
+};
+
+export { dateUtils };
diff --git a/packages/devextreme/js/__internal/core/utils/m_date_serialization.ts b/packages/devextreme/js/__internal/core/utils/m_date_serialization.ts
index 0b87f7bee468..09ffd2877370 100644
--- a/packages/devextreme/js/__internal/core/utils/m_date_serialization.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_date_serialization.ts
@@ -1,7 +1,7 @@
-import config from '../config';
-import { getFormatter as getLDMLFormatter } from '../../localization/ldml/date.formatter';
-import defaultDateNames from '../../localization/default_date_names';
-import { isString, isDate, isNumeric as isNumber } from './type';
+import config from '@js/core/config';
+import { isDate, isNumeric as isNumber, isString } from '@js/core/utils/type';
+import defaultDateNames from '@js/localization/default_date_names';
+import { getFormatter as getLDMLFormatter } from '@js/localization/ldml/date.formatter';
const NUMBER_SERIALIZATION_FORMAT = 'number';
const DATE_SERIALIZATION_FORMAT = 'yyyy/MM/dd';
@@ -15,167 +15,168 @@ const DATE_SERIALIZATION_PATTERN = /^(\d{4})\/(\d{2})\/(\d{2})$/;
const MILLISECOND_LENGHT = 3;
-const dateParser = function(text, skipISO8601Parsing) {
- let result;
+const dateParser = function (text, skipISO8601Parsing?: boolean) {
+ let result;
- if(isString(text) && !skipISO8601Parsing) {
- result = parseISO8601String(text);
- }
+ if (isString(text) && !skipISO8601Parsing) {
+ result = parseISO8601String(text);
+ }
- return result || parseDate(text);
+ return result || parseDate(text);
};
function getTimePart(part) {
- return +part || 0;
+ return +part || 0;
}
function parseDate(text) {
- const isDefaultSerializationFormat = getDateSerializationFormat(text) === DATE_SERIALIZATION_FORMAT;
- const parsedValue = !isDate(text) && Date.parse(text);
- if(!parsedValue && isDefaultSerializationFormat) {
- const parts = text.match(DATE_SERIALIZATION_PATTERN);
- if(parts) {
- const newDate = new Date(getTimePart(parts[1]), getTimePart(parts[2]), getTimePart(parts[3]));
- newDate.setFullYear(getTimePart(parts[1]));
- newDate.setMonth(getTimePart(parts[2]) - 1);
- newDate.setDate(getTimePart(parts[3]));
- return newDate;
- }
+ const isDefaultSerializationFormat = getDateSerializationFormat(text) === DATE_SERIALIZATION_FORMAT;
+ const parsedValue = !isDate(text) && Date.parse(text);
+ if (!parsedValue && isDefaultSerializationFormat) {
+ const parts = text.match(DATE_SERIALIZATION_PATTERN);
+ if (parts) {
+ const newDate = new Date(getTimePart(parts[1]), getTimePart(parts[2]), getTimePart(parts[3]));
+ newDate.setFullYear(getTimePart(parts[1]));
+ newDate.setMonth(getTimePart(parts[2]) - 1);
+ newDate.setDate(getTimePart(parts[3]));
+ return newDate;
}
+ }
- return isNumber(parsedValue) ? new Date(parsedValue) : text;
+ return isNumber(parsedValue) ? new Date(parsedValue) : text;
}
function parseISO8601String(text) {
- let parts = text.match(ISO8601_PATTERN);
-
- if(!parts) {
- parts = text.match(ISO8601_TIME_PATTERN);
- if(parts) {
- return new Date(0, 0, 0, getTimePart(parts[1]), getTimePart(parts[2]), getTimePart(parts[4]));
- }
+ let parts = text.match(ISO8601_PATTERN);
- return;
+ if (!parts) {
+ parts = text.match(ISO8601_TIME_PATTERN);
+ if (parts) {
+ return new Date(0, 0, 0, getTimePart(parts[1]), getTimePart(parts[2]), getTimePart(parts[4]));
}
- const year = getTimePart(parts[1]);
- const month = --parts[3];
- const day = parts[5];
- let timeZoneHour = 0;
- let timeZoneMinute = 0;
- const correctYear = (d) => {
- year < 100 && d.setFullYear(year);
- return d;
- };
-
- timeZoneHour = getTimePart(parts[14]);
- timeZoneMinute = getTimePart(parts[16]);
-
- if(parts[13] === '-') {
- timeZoneHour = -timeZoneHour;
- timeZoneMinute = -timeZoneMinute;
- }
-
- const hour = getTimePart(parts[6]) - timeZoneHour;
- const minute = getTimePart(parts[8]) - timeZoneMinute;
- const second = getTimePart(parts[10]);
- const parseMilliseconds = function(part) {
- part = part || '';
- return getTimePart(part) * Math.pow(10, MILLISECOND_LENGHT - part.length);
- };
- const millisecond = parseMilliseconds(parts[11]);
-
- if(parts[12]) {
- return correctYear(new Date(Date.UTC(year, month, day, hour, minute, second, millisecond)));
- }
-
- return correctYear(new Date(year, month, day, hour, minute, second, millisecond));
+ return;
+ }
+
+ const year = getTimePart(parts[1]);
+ const month = --parts[3];
+ const day = parts[5];
+ let timeZoneHour = 0;
+ let timeZoneMinute = 0;
+ const correctYear = (d) => {
+ year < 100 && d.setFullYear(year);
+ return d;
+ };
+
+ timeZoneHour = getTimePart(parts[14]);
+ timeZoneMinute = getTimePart(parts[16]);
+
+ if (parts[13] === '-') {
+ timeZoneHour = -timeZoneHour;
+ timeZoneMinute = -timeZoneMinute;
+ }
+
+ const hour = getTimePart(parts[6]) - timeZoneHour;
+ const minute = getTimePart(parts[8]) - timeZoneMinute;
+ const second = getTimePart(parts[10]);
+ const parseMilliseconds = function (part) {
+ part = part || '';
+ return getTimePart(part) * 10 ** (MILLISECOND_LENGHT - part.length);
+ };
+ const millisecond = parseMilliseconds(parts[11]);
+
+ if (parts[12]) {
+ return correctYear(new Date(Date.UTC(year, month, day, hour, minute, second, millisecond)));
+ }
+
+ return correctYear(new Date(year, month, day, hour, minute, second, millisecond));
}
-const getIso8601Format = function(text, useUtc) {
- let parts = text.match(ISO8601_PATTERN);
- let result = '';
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+const getIso8601Format = function (text, useUtc?) {
+ let parts = text.match(ISO8601_PATTERN);
+ let result = '';
- if(!parts) {
- parts = text.match(ISO8601_TIME_PATTERN);
- if(parts) {
- return parts[3] ? 'HH:mm:ss' : 'HH:mm';
- }
- return;
+ if (!parts) {
+ parts = text.match(ISO8601_TIME_PATTERN);
+ if (parts) {
+ return parts[3] ? 'HH:mm:ss' : 'HH:mm';
}
+ return;
+ }
-
- for(let i = 1; i < ISO8601_PATTERN_PARTS.length; i++) {
- if(parts[i]) {
- result += ISO8601_PATTERN_PARTS[i] || parts[i];
- }
+ for (let i = 1; i < ISO8601_PATTERN_PARTS.length; i++) {
+ if (parts[i]) {
+ result += ISO8601_PATTERN_PARTS[i] || parts[i];
}
-
- if(parts[12] === 'Z') {
- result += '\'Z\'';
+ }
+
+ if (parts[12] === 'Z') {
+ result += '\'Z\'';
+ }
+
+ if (parts[14]) {
+ if (parts[15]) {
+ result += 'xxx';
+ } else if (parts[16]) {
+ result += 'xx';
+ } else {
+ result += 'x';
}
+ }
- if(parts[14]) {
- if(parts[15]) {
- result += 'xxx';
- } else if(parts[16]) {
- result += 'xx';
- } else {
- result += 'x';
- }
- }
-
- return result;
+ return result;
};
-const deserializeDate = function(value) {
- if(typeof value === 'number') {
- return new Date(value);
- }
+const deserializeDate = function (value) {
+ if (typeof value === 'number') {
+ return new Date(value);
+ }
- return dateParser(value, !config().forceIsoDateParsing);
+ return dateParser(value, !config().forceIsoDateParsing);
};
-const serializeDate = function(value, serializationFormat) {
- if(!serializationFormat) {
- return value;
- }
+const serializeDate = function (value, serializationFormat) {
+ if (!serializationFormat) {
+ return value;
+ }
- if(!isDate(value)) {
- return null;
- }
+ if (!isDate(value)) {
+ return null;
+ }
- if(serializationFormat === NUMBER_SERIALIZATION_FORMAT) {
- return value && value.valueOf ? value.valueOf() : null;
- }
+ if (serializationFormat === NUMBER_SERIALIZATION_FORMAT) {
+ return value && value.valueOf ? value.valueOf() : null;
+ }
- return getLDMLFormatter(serializationFormat, defaultDateNames)(value);
+ return getLDMLFormatter(serializationFormat, defaultDateNames)(value);
};
-const getDateSerializationFormat = function(value) {
- if(typeof value === 'number') {
- return NUMBER_SERIALIZATION_FORMAT;
- } else if(isString(value)) {
- let format;
-
- if(config().forceIsoDateParsing) {
- format = getIso8601Format(value);
- }
- if(format) {
- return format;
- } else if(value.indexOf(':') >= 0) {
- return DATETIME_SERIALIZATION_FORMAT;
- } else {
- return DATE_SERIALIZATION_FORMAT;
- }
- } else if(value) {
- return null;
+const getDateSerializationFormat = function (value) {
+ if (typeof value === 'number') {
+ return NUMBER_SERIALIZATION_FORMAT;
+ } if (isString(value)) {
+ let format;
+
+ if (config().forceIsoDateParsing) {
+ format = getIso8601Format(value);
}
+ if (format) {
+ return format;
+ } if (value.includes(':')) {
+ return DATETIME_SERIALIZATION_FORMAT;
+ }
+ return DATE_SERIALIZATION_FORMAT;
+ } if (value) {
+ return null;
+ }
};
-export default {
- dateParser: dateParser,
- deserializeDate: deserializeDate,
- serializeDate: serializeDate,
- getDateSerializationFormat: getDateSerializationFormat
+const dateSerialization = {
+ dateParser,
+ deserializeDate,
+ serializeDate,
+ getDateSerializationFormat,
};
+
+export { dateSerialization };
diff --git a/packages/devextreme/js/__internal/core/utils/m_deferred.ts b/packages/devextreme/js/__internal/core/utils/m_deferred.ts
index 381f9b72ab15..ca4bcb249a84 100644
--- a/packages/devextreme/js/__internal/core/utils/m_deferred.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_deferred.ts
@@ -1,179 +1,179 @@
-import { isDeferred, isDefined, isPromise } from '../utils/type';
-import { extend } from '../utils/extend';
-import Callbacks from '../utils/callbacks';
+import Callbacks from '@js/core/utils/callbacks';
+import { extend } from '@js/core/utils/extend';
+import { isDeferred, isDefined, isPromise } from '@js/core/utils/type';
const deferredConfig = [{
- method: 'resolve',
- handler: 'done',
- state: 'resolved'
+ method: 'resolve',
+ handler: 'done',
+ state: 'resolved',
}, {
- method: 'reject',
- handler: 'fail',
- state: 'rejected'
+ method: 'reject',
+ handler: 'fail',
+ state: 'rejected',
}, {
- method: 'notify',
- handler: 'progress'
+ method: 'notify',
+ handler: 'progress',
}];
-let DeferredObj = function() {
- const that = this;
- this._state = 'pending';
- this._promise = {};
-
- deferredConfig.forEach(function(config) {
- const methodName = config.method;
- this[methodName + 'Callbacks'] = Callbacks();
-
- this[methodName] = function() {
- return this[methodName + 'With'](this._promise, arguments);
- }.bind(this);
-
- this._promise[config.handler] = function(handler) {
- if(!handler) return this;
-
- const callbacks = that[methodName + 'Callbacks'];
- if(callbacks.fired()) {
- handler.apply(that[methodName + 'Context'], that[methodName + 'Args']);
- } else {
- callbacks.add(function(context, args) {
- handler.apply(context, args);
- }.bind(this));
- }
- return this;
- };
- }.bind(this));
+let DeferredObj = function () {
+ const that = this;
+ this._state = 'pending';
+ this._promise = {};
- this._promise.always = function(handler) {
- return this.done(handler).fail(handler);
- };
+ deferredConfig.forEach(function (config) {
+ const methodName = config.method;
+ this[`${methodName}Callbacks`] = Callbacks();
- this._promise.catch = function(handler) {
- return this.then(null, handler);
- };
+ this[methodName] = function () {
+ return this[`${methodName}With`](this._promise, arguments);
+ }.bind(this);
- this._promise.then = function(resolve, reject) {
- const result = new DeferredObj();
-
- ['done', 'fail'].forEach(function(method) {
- const callback = method === 'done' ? resolve : reject;
-
- this[method](function() {
- if(!callback) {
- result[method === 'done' ? 'resolve' : 'reject'].apply(this, arguments);
- return;
- }
-
- const callbackResult = callback && callback.apply(this, arguments);
- if(isDeferred(callbackResult)) {
- callbackResult.done(result.resolve).fail(result.reject);
- } else if(isPromise(callbackResult)) {
- callbackResult.then(result.resolve, result.reject);
- } else {
- result.resolve.apply(this, isDefined(callbackResult) ? [callbackResult] : arguments);
- }
- });
- }.bind(this));
-
- return result.promise();
- };
+ this._promise[config.handler] = function (handler) {
+ if (!handler) return this;
- this._promise.state = function() {
- return that._state;
+ const callbacks = that[`${methodName}Callbacks`];
+ if (callbacks.fired()) {
+ handler.apply(that[`${methodName}Context`], that[`${methodName}Args`]);
+ } else {
+ callbacks.add(function (context, args) {
+ handler.apply(context, args);
+ });
+ }
+ return this;
};
+ }.bind(this));
- this._promise.promise = function(args) {
- return args ? extend(args, that._promise) : that._promise;
- };
+ this._promise.always = function (handler) {
+ return this.done(handler).fail(handler);
+ };
- this._promise.promise(this);
-};
+ this._promise.catch = function (handler) {
+ return this.then(null, handler);
+ };
-deferredConfig.forEach(function(config) {
- const methodName = config.method;
- const state = config.state;
-
- DeferredObj.prototype[methodName + 'With'] = function(context, args) {
- const callbacks = this[methodName + 'Callbacks'];
-
- if(this.state() === 'pending') {
- this[methodName + 'Args'] = args;
- this[methodName + 'Context'] = context;
- if(state) this._state = state;
- callbacks.fire(context, args);
- if(state !== 'pending') {
- this.resolveCallbacks.empty();
- this.rejectCallbacks.empty();
- }
+ this._promise.then = function (resolve, reject) {
+ const result = new DeferredObj();
+
+ ['done', 'fail'].forEach(function (method) {
+ const callback = method === 'done' ? resolve : reject;
+
+ this[method](function () {
+ if (!callback) {
+ result[method === 'done' ? 'resolve' : 'reject'].apply(this, arguments);
+ return;
}
- return this;
- };
-});
+ const callbackResult = callback && callback.apply(this, arguments);
+ if (isDeferred(callbackResult)) {
+ callbackResult.done(result.resolve).fail(result.reject);
+ } else if (isPromise(callbackResult)) {
+ callbackResult.then(result.resolve, result.reject);
+ } else {
+ result.resolve.apply(this, isDefined(callbackResult) ? [callbackResult] : arguments);
+ }
+ });
+ }.bind(this));
-export function fromPromise(promise, context) {
- if(isDeferred(promise)) {
- return promise;
- } else if(isPromise(promise)) {
- const d = new DeferredObj();
- promise.then(function() {
- d.resolveWith.apply(d, [context].concat([[].slice.call(arguments)]));
- }, function() {
- d.rejectWith.apply(d, [context].concat([[].slice.call(arguments)]));
- });
- return d;
- }
+ return result.promise();
+ };
- return new DeferredObj().resolveWith(context, [promise]);
-}
+ this._promise.state = function () {
+ return that._state;
+ };
-let whenFunc = function() {
- if(arguments.length === 1) {
- return fromPromise(arguments[0]);
- }
+ this._promise.promise = function (args) {
+ return args ? extend(args, that._promise) : that._promise;
+ };
- const values = [].slice.call(arguments);
- const contexts = [];
- let resolvedCount = 0;
- const deferred = new DeferredObj();
-
- const updateState = function(i) {
- return function(value) {
- contexts[i] = this;
- values[i] = arguments.length > 1 ? [].slice.call(arguments) : value;
- resolvedCount++;
- if(resolvedCount === values.length) {
- deferred.resolveWith(contexts, values);
- }
- };
- };
+ this._promise.promise(this);
+};
- for(let i = 0; i < values.length; i++) {
- if(isDeferred(values[i])) {
- values[i].promise()
- .done(updateState(i))
- .fail(deferred.reject);
- } else {
- resolvedCount++;
- }
+deferredConfig.forEach(function (config) {
+ const methodName = config.method;
+ const { state } = config;
+
+ DeferredObj.prototype[`${methodName}With`] = function (context, args) {
+ const callbacks = this[`${methodName}Callbacks`];
+
+ if (this.state() === 'pending') {
+ this[`${methodName}Args`] = args;
+ this[`${methodName}Context`] = context;
+ if (state) this._state = state;
+ callbacks.fire(context, args);
+ if (state !== 'pending') {
+ this.resolveCallbacks.empty();
+ this.rejectCallbacks.empty();
+ }
}
- if(resolvedCount === values.length) {
+ return this;
+ };
+});
+
+export function fromPromise(promise, context?: any) {
+ if (isDeferred(promise)) {
+ return promise;
+ } if (isPromise(promise)) {
+ const d = new DeferredObj();
+ promise.then(function () {
+ d.resolveWith.apply(d, [context].concat([[].slice.call(arguments)]));
+ }, function () {
+ d.rejectWith.apply(d, [context].concat([[].slice.call(arguments)]));
+ });
+ return d;
+ }
+
+ return new DeferredObj().resolveWith(context, [promise]);
+}
+
+let whenFunc = function () {
+ if (arguments.length === 1) {
+ return fromPromise(arguments[0]);
+ }
+
+ const values: any[] = [].slice.call(arguments);
+ const contexts: any[] = [];
+ let resolvedCount = 0;
+ const deferred = new DeferredObj();
+
+ const updateState = function (i) {
+ return function (value) {
+ contexts[i] = this;
+ values[i] = arguments.length > 1 ? [].slice.call(arguments) : value;
+ resolvedCount++;
+ if (resolvedCount === values.length) {
deferred.resolveWith(contexts, values);
+ }
+ };
+ };
+
+ for (let i = 0; i < values.length; i++) {
+ if (isDeferred(values[i])) {
+ values[i].promise()
+ .done(updateState(i))
+ .fail(deferred.reject);
+ } else {
+ resolvedCount++;
}
+ }
+
+ if (resolvedCount === values.length) {
+ deferred.resolveWith(contexts, values);
+ }
- return deferred.promise();
+ return deferred.promise();
};
export function setStrategy(value) {
- DeferredObj = value.Deferred;
- whenFunc = value.when;
+ DeferredObj = value.Deferred;
+ whenFunc = value.when;
}
export function Deferred() {
- return new DeferredObj();
+ return new DeferredObj();
}
export function when() {
- return whenFunc.apply(this, arguments);
+ // @ts-expect-error
+ return whenFunc.apply(this, arguments);
}
-
diff --git a/packages/devextreme/js/__internal/core/utils/m_dependency_injector.ts b/packages/devextreme/js/__internal/core/utils/m_dependency_injector.ts
index 6b7da1a67e62..acda838cd10d 100644
--- a/packages/devextreme/js/__internal/core/utils/m_dependency_injector.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_dependency_injector.ts
@@ -1,44 +1,48 @@
-import { extend } from './extend';
-import { isFunction } from './type';
-import { each } from './iterator';
-import Class from '../class';
+/* eslint-disable prefer-arrow-callback */
+/* eslint-disable func-names */
+import Class from '@js/core/class';
+import { extend } from '@js/core/utils/extend';
+import { each } from '@js/core/utils/iterator';
+import { isFunction } from '@js/core/utils/type';
-export default function(object) {
- const BaseClass = Class.inherit(object);
- let InjectedClass = BaseClass;
- let instance = new InjectedClass(object);
- const initialFields = {};
+function injector(object) {
+ const BaseClass = Class.inherit(object);
+ let InjectedClass = BaseClass;
+ let instance = new InjectedClass(object);
+ const initialFields = {};
- const injectFields = function(injectionObject, initial) {
- each(injectionObject, function(key) {
- if(isFunction(instance[key])) {
- if(initial || !object[key]) {
- object[key] = function() {
- return instance[key].apply(object, arguments);
- };
- }
- } else {
- if(initial) {
- initialFields[key] = object[key];
- }
- object[key] = instance[key];
- }
- });
- };
+ const injectFields = function (injectionObject, initial?) {
+ each(injectionObject, function (key) {
+ if (isFunction(instance[key])) {
+ if (initial || !object[key]) {
+ object[key] = function () {
+ return instance[key].apply(object, arguments);
+ };
+ }
+ } else {
+ if (initial) {
+ initialFields[key] = object[key];
+ }
+ object[key] = instance[key];
+ }
+ });
+ };
- injectFields(object, true);
+ injectFields(object, true);
- object.inject = function(injectionObject) {
- InjectedClass = InjectedClass.inherit(injectionObject);
- instance = new InjectedClass();
- injectFields(injectionObject);
- };
+ object.inject = function (injectionObject) {
+ InjectedClass = InjectedClass.inherit(injectionObject);
+ instance = new InjectedClass();
+ injectFields(injectionObject);
+ };
- object.resetInjection = function() {
- extend(object, initialFields);
- InjectedClass = BaseClass;
- instance = new BaseClass();
- };
+ object.resetInjection = function () {
+ extend(object, initialFields);
+ InjectedClass = BaseClass;
+ instance = new BaseClass();
+ };
- return object;
+ return object;
}
+
+export { injector };
diff --git a/packages/devextreme/js/__internal/core/utils/m_dom.ts b/packages/devextreme/js/__internal/core/utils/m_dom.ts
index 195466856316..1a36392a4b9e 100644
--- a/packages/devextreme/js/__internal/core/utils/m_dom.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_dom.ts
@@ -1,164 +1,181 @@
-import domAdapter from '../../core/dom_adapter';
-import $ from '../../core/renderer';
-import { each } from './iterator';
-import { isDefined, isRenderer, isWindow, isString } from './type';
-import { getWindow } from './window';
+import domAdapter from '@js/core/dom_adapter';
+import $ from '@js/core/renderer';
+import { each } from '@js/core/utils/iterator';
+import {
+ isDefined, isRenderer, isString, isWindow,
+} from '@js/core/utils/type';
+import { getWindow } from '@js/core/utils/window';
const window = getWindow();
const getRootNodeHost = (element) => {
- if(!element.getRootNode) {
- return undefined;
- }
+ if (!element.getRootNode) {
+ return undefined;
+ }
- const host = element.getRootNode().host;
+ const { host } = element.getRootNode();
- // NOTE: getRootNode().host can return a string if element is detached "a" element
- if(isString(host)) {
- return undefined;
- }
+ // NOTE: getRootNode().host can return a string if element is detached "a" element
+ if (isString(host)) {
+ return undefined;
+ }
- return host;
+ return host;
};
export const resetActiveElement = () => {
- const activeElement = domAdapter.getActiveElement();
+ const activeElement = domAdapter.getActiveElement();
- if(activeElement && activeElement !== domAdapter.getBody()) {
- activeElement.blur?.();
- }
+ if (activeElement && activeElement !== domAdapter.getBody()) {
+ activeElement.blur?.();
+ }
};
export const clearSelection = () => {
- const selection = window.getSelection();
- if(!selection) return;
- if(selection.type === 'Caret') return;
-
- if(selection.empty) {
- selection.empty();
- } else if(selection.removeAllRanges) {
- // T522811
- try {
- selection.removeAllRanges();
- } catch(e) {}
- }
+ const selection = window.getSelection();
+ if (!selection) return;
+ if (selection.type === 'Caret') return;
+
+ if (selection.empty) {
+ selection.empty();
+ } else if (selection.removeAllRanges) {
+ // T522811
+ try {
+ selection.removeAllRanges();
+ } catch (e) { /* empty */ }
+ }
};
export const closestCommonParent = (startTarget, endTarget) => {
- const $startTarget = $(startTarget);
- const $endTarget = $(endTarget);
+ const $startTarget = $(startTarget);
+ const $endTarget = $(endTarget);
- if($startTarget[0] === $endTarget[0]) {
- return $startTarget[0];
- }
+ if ($startTarget[0] === $endTarget[0]) {
+ return $startTarget[0];
+ }
- const $startParents = $startTarget.parents();
- const $endParents = $endTarget.parents();
- const startingParent = Math.min($startParents.length, $endParents.length);
+ const $startParents = $startTarget.parents();
+ const $endParents = $endTarget.parents();
+ const startingParent = Math.min($startParents.length, $endParents.length);
- for(let i = -startingParent; i < 0; i++) {
- if($startParents.get(i) === $endParents.get(i)) {
- return $startParents.get(i);
- }
+ for (let i = -startingParent; i < 0; i++) {
+ if ($startParents.get(i) === $endParents.get(i)) {
+ return $startParents.get(i);
}
+ }
};
export const extractTemplateMarkup = (element) => {
- element = $(element);
-
- const templateTag = element.length && element.filter(function isNotExecutableScript() {
- const $node = $(this);
- return $node.is('script[type]') && ($node.attr('type').indexOf('script') < 0);
- });
-
- if(templateTag.length) {
- return templateTag.eq(0).html();
- } else {
- element = $('').append(element);
- return element.html();
- }
+ element = $(element);
+
+ const templateTag = element.length && element.filter(function isNotExecutableScript() {
+ const $node = $(this);
+ // @ts-expect-error
+ return $node.is('script[type]') && !$node.attr('type').includes('script');
+ });
+
+ if (templateTag.length) {
+ return templateTag.eq(0).html();
+ }
+ element = $('
').append(element);
+ return element.html();
};
export const normalizeTemplateElement = (element) => {
- let $element = isDefined(element) && (element.nodeType || isRenderer(element))
- ? $(element)
- : $('
').html(element).contents();
-
- if($element.length === 1) {
- if($element.is('script')) {
- $element = normalizeTemplateElement($element.html().trim());
- } else if($element.is('table')) {
- $element = $element.children('tbody').contents();
- }
+ let $element = isDefined(element) && (element.nodeType || isRenderer(element))
+ ? $(element)
+ : $('
').html(element).contents();
+
+ if ($element.length === 1) {
+ if ($element.is('script')) {
+ $element = normalizeTemplateElement($element.html().trim());
+ } else if ($element.is('table')) {
+ $element = $element.children('tbody').contents();
}
+ }
- return $element;
+ return $element;
};
-export const clipboardText = (event, text) => {
- const clipboard = (event.originalEvent && event.originalEvent.clipboardData) || window.clipboardData;
- if(!text) {
- return clipboard && clipboard.getData('Text');
- }
+export const clipboardText = (event, text?) => {
+ // @ts-expect-error clipboardData doesn't exist in window type
+ const clipboard = (event.originalEvent && event.originalEvent.clipboardData) || window.clipboardData;
+ if (!text) {
+ return clipboard && clipboard.getData('Text');
+ }
- clipboard && clipboard.setData('Text', text);
+ clipboard && clipboard.setData('Text', text);
};
export const contains = (container, element) => {
- if(!element) {
- return false;
- }
- if(isWindow(container)) {
- return contains(container.document, element);
- }
- return container.contains(element) || contains(container, getRootNodeHost(element));
+ if (!element) {
+ return false;
+ }
+ if (isWindow(container)) {
+ return contains(container.document, element);
+ }
+ return container.contains(element) || contains(container, getRootNodeHost(element));
};
-export const createTextElementHiddenCopy = (element, text, options) => {
- const elementStyles = window.getComputedStyle($(element).get(0));
- const includePaddings = options && options.includePaddings;
-
- return $('
').text(text).css({
- 'fontStyle': elementStyles.fontStyle,
- 'fontVariant': elementStyles.fontVariant,
- 'fontWeight': elementStyles.fontWeight,
- 'fontSize': elementStyles.fontSize,
- 'fontFamily': elementStyles.fontFamily,
- 'letterSpacing': elementStyles.letterSpacing,
- 'border': elementStyles.border,
- 'paddingTop': includePaddings ? elementStyles.paddingTop : '',
- 'paddingRight': includePaddings ? elementStyles.paddingRight : '',
- 'paddingBottom': includePaddings ? elementStyles.paddingBottom : '',
- 'paddingLeft': includePaddings ? elementStyles.paddingLeft : '',
- 'visibility': 'hidden',
- 'whiteSpace': 'pre',
- 'position': 'absolute',
- 'float': 'left'
- });
+export const createTextElementHiddenCopy = (element, text, options?) => {
+ const elementStyles = window.getComputedStyle($(element).get(0));
+ const includePaddings = options && options.includePaddings;
+
+ return $('
').text(text).css({
+ fontStyle: elementStyles.fontStyle,
+ fontVariant: elementStyles.fontVariant,
+ fontWeight: elementStyles.fontWeight,
+ fontSize: elementStyles.fontSize,
+ fontFamily: elementStyles.fontFamily,
+ letterSpacing: elementStyles.letterSpacing,
+ border: elementStyles.border,
+ paddingTop: includePaddings ? elementStyles.paddingTop : '',
+ paddingRight: includePaddings ? elementStyles.paddingRight : '',
+ paddingBottom: includePaddings ? elementStyles.paddingBottom : '',
+ paddingLeft: includePaddings ? elementStyles.paddingLeft : '',
+ visibility: 'hidden',
+ whiteSpace: 'pre',
+ position: 'absolute',
+ float: 'left',
+ });
};
export const insertBefore = (element, newElement) => {
- if(newElement) {
- domAdapter.insertElement(element.parentNode, newElement, element);
- }
- return element;
+ if (newElement) {
+ domAdapter.insertElement(element.parentNode, newElement, element);
+ }
+ return element;
};
export const replaceWith = (element, newElement) => {
- if(!(newElement && newElement[0])) return;
- if(newElement.is(element)) return element;
+ if (!(newElement && newElement[0])) return;
+ if (newElement.is(element)) return element;
- each(newElement, (_, currentElement) => {
- insertBefore(element[0], currentElement);
- });
- element.remove();
+ each(newElement, (_, currentElement) => {
+ insertBefore(element[0], currentElement);
+ });
+ element.remove();
- return newElement;
+ return newElement;
};
-export const isElementInDom = $element => {
- const element = $element?.get(0);
- const shadowHost = element?.getRootNode().host;
+export const isElementInDom = ($element) => {
+ const element = $element?.get(0);
+ const shadowHost = element?.getRootNode().host;
+
+ return !!$(shadowHost || element).closest(getWindow().document).length;
+};
- return !!$(shadowHost || element).closest(getWindow().document).length;
+export default {
+ resetActiveElement,
+ clearSelection,
+ closestCommonParent,
+ extractTemplateMarkup,
+ normalizeTemplateElement,
+ clipboardText,
+ contains,
+ createTextElementHiddenCopy,
+ insertBefore,
+ replaceWith,
+ isElementInDom,
};
diff --git a/packages/devextreme/js/__internal/core/utils/m_error.ts b/packages/devextreme/js/__internal/core/utils/m_error.ts
index 7759cbcce27d..ff5fc27fc9f4 100644
--- a/packages/devextreme/js/__internal/core/utils/m_error.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_error.ts
@@ -1,68 +1,71 @@
/* eslint-disable import/no-commonjs */
-import { extend } from './extend';
-import { logger } from './console';
-import { format } from './string';
-import { version } from '../version';
-
-const ERROR_URL = 'https://js.devexpress.com/error/' + version.split('.').slice(0, 2).join('_') + '/';
-
-export default function(baseErrors, errors) {
-
- const exports = {
-
- ERROR_MESSAGES: extend(errors, baseErrors),
-
- Error: function() {
- return makeError([].slice.call(arguments));
- },
-
- log: function(id) {
- let method = 'log';
-
- if(/^E\d+$/.test(id)) {
- method = 'error';
- } else if(/^W\d+$/.test(id)) {
- method = 'warn';
- }
-
- logger[method](method === 'log' ? id : combineMessage([].slice.call(arguments)));
- }
- };
-
- function combineMessage(args) {
- const id = args[0];
- args = args.slice(1);
- return formatMessage(id, formatDetails(id, args));
- }
-
- function formatDetails(id, args) {
- args = [exports.ERROR_MESSAGES[id]].concat(args);
- return format.apply(this, args).replace(/\.*\s*?$/, '');
- }
-
- function formatMessage(id, details) {
- const kind = id?.startsWith('W') ? 'warning' : 'error';
- return format.apply(this, ['{0} - {1}.\n\nFor additional information on this {2} message, see: {3}', id, details, kind, getErrorUrl(id)]);
- }
-
- function makeError(args) {
- const id = args[0];
- args = args.slice(1);
- const details = formatDetails(id, args);
- const url = getErrorUrl(id);
- const message = formatMessage(id, details);
-
- return extend(new Error(message), {
- __id: id,
- __details: details,
- url: url
- });
- }
-
- function getErrorUrl(id) {
- return ERROR_URL + id;
- }
-
- return exports;
-
+import { extend } from '@js/core/utils/extend';
+import { format } from '@js/core/utils/string';
+import { version } from '@js/core/version';
+
+import consoleUtils from './m_console';
+
+const ERROR_URL = `https://js.devexpress.com/error/${version.split('.').slice(0, 2).join('_')}/`;
+
+function error(baseErrors, errors?) {
+ const exports = {
+
+ ERROR_MESSAGES: extend(errors, baseErrors),
+
+ // eslint-disable-next-line object-shorthand
+ Error: function (...args) {
+ return makeError(args);
+ },
+
+ log(...args) {
+ const id = args[0];
+ let method = 'log';
+
+ if (/^E\d+$/.test(id)) {
+ method = 'error';
+ } else if (/^W\d+$/.test(id)) {
+ method = 'warn';
+ }
+
+ consoleUtils.logger[method](method === 'log' ? id : combineMessage(args));
+ },
+ };
+
+ function combineMessage(args) {
+ const id = args[0];
+ args = args.slice(1);
+ return formatMessage(id, formatDetails(id, args));
+ }
+
+ function formatDetails(id, args) {
+ args = [exports.ERROR_MESSAGES[id]].concat(args);
+ return format.apply(this, args).replace(/\.*\s*?$/, '');
+ }
+
+ function formatMessage(id, details) {
+ const kind = id?.startsWith('W') ? 'warning' : 'error';
+ return format.apply(this, ['{0} - {1}.\n\nFor additional information on this {2} message, see: {3}', id, details, kind, getErrorUrl(id)]);
+ }
+
+ function makeError(args) {
+ const id = args[0];
+ args = args.slice(1);
+ const details = formatDetails(id, args);
+ const url = getErrorUrl(id);
+ const message = formatMessage(id, details);
+
+ return extend(new Error(message), {
+ __id: id,
+ __details: details,
+ url,
+ });
+ }
+
+ function getErrorUrl(id) {
+ return ERROR_URL + id;
+ }
+
+ return exports;
}
+export { error };
+export default error;
diff --git a/packages/devextreme/js/__internal/core/utils/m_extend.ts b/packages/devextreme/js/__internal/core/utils/m_extend.ts
index 77a64ea64e5e..cfbfe04debc7 100644
--- a/packages/devextreme/js/__internal/core/utils/m_extend.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_extend.ts
@@ -1,62 +1,61 @@
-import { isPlainObject } from './type';
-
-export const extendFromObject = function(target, source, overrideExistingValues) {
- target = target || {};
- for(const prop in source) {
- if(Object.prototype.hasOwnProperty.call(source, prop)) {
- const value = source[prop];
- if(!(prop in target) || overrideExistingValues) {
- target[prop] = value;
- }
- }
+import { isPlainObject } from '@js/core/utils/type';
+
+export const extendFromObject = function (target, source, overrideExistingValues) {
+ target = target || {};
+ for (const prop in source) {
+ if (Object.prototype.hasOwnProperty.call(source, prop)) {
+ const value = source[prop];
+ if (!(prop in target) || overrideExistingValues) {
+ target[prop] = value;
+ }
}
- return target;
+ }
+ return target;
};
-export const extend = function(target) {
- target = target || {};
+export const extend: any = function (target) {
+ target = target || {};
+
+ let i = 1;
+ let deep = false;
- let i = 1;
- let deep = false;
+ if (typeof target === 'boolean') {
+ deep = target;
+ target = arguments[1] || {};
+ i++;
+ }
- if(typeof target === 'boolean') {
- deep = target;
- target = arguments[1] || {};
- i++;
+ for (; i < arguments.length; i++) {
+ const source = arguments[i];
+ if (source == null) {
+ continue;
}
- for(; i < arguments.length; i++) {
- const source = arguments[i];
- if(source == null) {
- continue;
+ for (const key in source) {
+ const targetValue = target[key];
+ const sourceValue = source[key];
+ let sourceValueIsArray = false;
+ let clone;
+
+ if (key === '__proto__' || key === 'constructor' || target === sourceValue) {
+ continue;
+ }
+
+ if (deep && sourceValue && (isPlainObject(sourceValue)
+ // eslint-disable-next-line no-cond-assign
+ || (sourceValueIsArray = Array.isArray(sourceValue)))) {
+ if (sourceValueIsArray) {
+ clone = targetValue && Array.isArray(targetValue) ? targetValue : [];
+ } else {
+ clone = targetValue && isPlainObject(targetValue) ? targetValue : {};
}
- for(const key in source) {
- const targetValue = target[key];
- const sourceValue = source[key];
- let sourceValueIsArray = false;
- let clone;
-
- if(key === '__proto__' || key === 'constructor' || target === sourceValue) {
- continue;
- }
-
- if(deep && sourceValue && (isPlainObject(sourceValue) ||
- (sourceValueIsArray = Array.isArray(sourceValue)))) {
-
- if(sourceValueIsArray) {
- clone = targetValue && Array.isArray(targetValue) ? targetValue : [];
- } else {
- clone = targetValue && isPlainObject(targetValue) ? targetValue : {};
- }
-
- target[key] = extend(deep, clone, sourceValue);
-
- } else if(sourceValue !== undefined) {
- target[key] = sourceValue;
- }
- }
+ target[key] = extend(deep, clone, sourceValue);
+ } else if (sourceValue !== undefined) {
+ target[key] = sourceValue;
+ }
}
+ }
- return target;
+ return target;
};
diff --git a/packages/devextreme/js/__internal/core/utils/m_html_parser.ts b/packages/devextreme/js/__internal/core/utils/m_html_parser.ts
index 21426cc4b4ff..a8b4b6be967a 100644
--- a/packages/devextreme/js/__internal/core/utils/m_html_parser.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_html_parser.ts
@@ -1,59 +1,59 @@
-import domAdapter from '../dom_adapter';
+import domAdapter from '@js/core/dom_adapter';
const isTagName = (/<([a-z][^/\0>\x20\t\r\n\f]+)/i);
-const tagWrappers = {
- default: {
- tagsCount: 0,
- startTags: '',
- endTags: ''
- },
- thead: {
- tagsCount: 1,
- startTags: '
'
- },
- td: {
- tagsCount: 3,
- startTags: '
'
- },
- col: {
- tagsCount: 2,
- startTags: '
'
- },
- tr: {
- tagsCount: 2,
- startTags: '
'
- },
+const tagWrappers: any = {
+ default: {
+ tagsCount: 0,
+ startTags: '',
+ endTags: '',
+ },
+ thead: {
+ tagsCount: 1,
+ startTags: '
',
+ },
+ td: {
+ tagsCount: 3,
+ startTags: '
',
+ },
+ col: {
+ tagsCount: 2,
+ startTags: '
',
+ },
+ tr: {
+ tagsCount: 2,
+ startTags: '
',
+ },
};
tagWrappers.tbody = tagWrappers.colgroup = tagWrappers.caption = tagWrappers.tfoot = tagWrappers.thead;
tagWrappers.th = tagWrappers.td;
-export const parseHTML = function(html) {
- if(typeof html !== 'string') {
- return null;
- }
+export const parseHTML = function (html) {
+ if (typeof html !== 'string') {
+ return null;
+ }
- const fragment = domAdapter.createDocumentFragment();
- let container = fragment.appendChild(domAdapter.createElement('div'));
- const tags = isTagName.exec(html);
- const firstRootTag = tags && tags[1].toLowerCase();
- const tagWrapper = tagWrappers[firstRootTag] || tagWrappers.default;
+ const fragment = domAdapter.createDocumentFragment();
+ let container: HTMLElement | ChildNode = fragment.appendChild(domAdapter.createElement('div'));
+ const tags = isTagName.exec(html);
+ const firstRootTag = tags?.[1].toLowerCase();
+ const tagWrapper = tagWrappers[firstRootTag!] || tagWrappers.default;
- container.innerHTML = tagWrapper.startTags + html + tagWrapper.endTags;
+ (container as HTMLElement).innerHTML = tagWrapper.startTags + html + tagWrapper.endTags;
- for(let i = 0; i < tagWrapper.tagsCount; i++) {
- container = container.lastChild;
- }
+ for (let i = 0; i < tagWrapper.tagsCount; i++) {
+ container = container.lastChild!;
+ }
- return [...container.childNodes];
+ return [...container.childNodes];
};
-export const isTablePart = function(html) {
- const tags = isTagName.exec(html);
- return tags && tags[1] in tagWrappers;
+export const isTablePart = function (html) {
+ const tags = isTagName.exec(html);
+ return tags && tags[1] in tagWrappers;
};
diff --git a/packages/devextreme/js/__internal/core/utils/m_icon.ts b/packages/devextreme/js/__internal/core/utils/m_icon.ts
index f5adfea791cc..2525500340f1 100644
--- a/packages/devextreme/js/__internal/core/utils/m_icon.ts
+++ b/packages/devextreme/js/__internal/core/utils/m_icon.ts
@@ -1,43 +1,43 @@
-import $ from '../../core/renderer';
+import $ from '@js/core/renderer';
const ICON_CLASS = 'dx-icon';
const SVG_ICON_CLASS = 'dx-svg-icon';
export const getImageSourceType = (source) => {
- if(!source || typeof source !== 'string') {
- return false;
- }
+ if (!source || typeof source !== 'string') {
+ return false;
+ }
- if(/^\s*