ag-grid-community
Version:
Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
1,364 lines (1,351 loc) • 2.18 MB
JavaScript
/**
* ag-grid-community - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components * @version v25.2.0
* @link http://www.ag-grid.com/
' * @license MIT
*/
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
/**
* @ag-grid-community/core - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
* @version v25.2.0
* @link http://www.ag-grid.com/
* @license MIT
*/
/**
* If value is undefined, null or blank, returns null, otherwise returns the value
* @param {T} value
* @returns {T | null}
*/
function makeNull(value) {
if (value == null || value === '') {
return null;
}
return value;
}
function exists(value, allowEmptyString) {
if (allowEmptyString === void 0) { allowEmptyString = false; }
return value != null && (value !== '' || allowEmptyString);
}
function missing(value) {
return !exists(value);
}
function missingOrEmpty(value) {
return value == null || value.length === 0;
}
function toStringOrNull(value) {
return value != null && typeof value.toString === 'function' ? value.toString() : null;
}
// for parsing html attributes, where we want empty strings and missing attributes to be undefined
function attrToNumber(value) {
if (value === undefined) {
// undefined or empty means ignore the value
return;
}
if (value === null || value === '') {
// null or blank means clear
return null;
}
if (typeof value === 'number') {
return isNaN(value) ? undefined : value;
}
var valueParsed = parseInt(value, 10);
return isNaN(valueParsed) ? undefined : valueParsed;
}
// for parsing html attributes, where we want empty strings and missing attributes to be undefined
function attrToBoolean(value) {
if (value === undefined) {
// undefined or empty means ignore the value
return;
}
if (value === null || value === '') {
// null means clear
return false;
}
if (typeof value === 'boolean') {
// if simple boolean, return the boolean
return value;
}
// if equal to the string 'true' (ignoring case) then return true
return (/true/i).test(value);
}
// for parsing html attributes, where we want empty strings and missing attributes to be undefined
function attrToString(value) {
if (value == null || value === '') {
return;
}
return value;
}
/** @deprecated */
function referenceCompare(left, right) {
if (left == null && right == null) {
return true;
}
if (left == null && right != null) {
return false;
}
if (left != null && right == null) {
return false;
}
return left === right;
}
function jsonEquals(val1, val2) {
var val1Json = val1 ? JSON.stringify(val1) : null;
var val2Json = val2 ? JSON.stringify(val2) : null;
return val1Json === val2Json;
}
function defaultComparator(valueA, valueB, accentedCompare) {
if (accentedCompare === void 0) { accentedCompare = false; }
var valueAMissing = valueA == null;
var valueBMissing = valueB == null;
// this is for aggregations sum and avg, where the result can be a number that is wrapped.
// if we didn't do this, then the toString() value would be used, which would result in
// the strings getting used instead of the numbers.
if (valueA && valueA.toNumber) {
valueA = valueA.toNumber();
}
if (valueB && valueB.toNumber) {
valueB = valueB.toNumber();
}
if (valueAMissing && valueBMissing) {
return 0;
}
if (valueAMissing) {
return -1;
}
if (valueBMissing) {
return 1;
}
function doQuickCompare(a, b) {
return (a > b ? 1 : (a < b ? -1 : 0));
}
if (typeof valueA !== 'string') {
return doQuickCompare(valueA, valueB);
}
if (!accentedCompare) {
return doQuickCompare(valueA, valueB);
}
try {
// using local compare also allows chinese comparisons
return valueA.localeCompare(valueB);
}
catch (e) {
// if something wrong with localeCompare, eg not supported
// by browser, then just continue with the quick one
return doQuickCompare(valueA, valueB);
}
}
function find(collection, predicate, value) {
if (collection === null || collection === undefined) {
return null;
}
if (!Array.isArray(collection)) {
var objToArray = values(collection);
return find(objToArray, predicate, value);
}
var collectionAsArray = collection;
var firstMatchingItem = null;
for (var i = 0; i < collectionAsArray.length; i++) {
var item = collectionAsArray[i];
if (typeof predicate === 'string') {
if (item[predicate] === value) {
firstMatchingItem = item;
break;
}
}
else {
var callback = predicate;
if (callback(item)) {
firstMatchingItem = item;
break;
}
}
}
return firstMatchingItem;
}
function values(object) {
if (object instanceof Set || object instanceof Map) {
var arr_1 = [];
object.forEach(function (value) { return arr_1.push(value); });
return arr_1;
}
return Object.keys(object).map(function (key) { return object[key]; });
}
var GenericUtils = /*#__PURE__*/Object.freeze({
__proto__: null,
makeNull: makeNull,
exists: exists,
missing: missing,
missingOrEmpty: missingOrEmpty,
toStringOrNull: toStringOrNull,
attrToNumber: attrToNumber,
attrToBoolean: attrToBoolean,
attrToString: attrToString,
referenceCompare: referenceCompare,
jsonEquals: jsonEquals,
defaultComparator: defaultComparator,
find: find,
values: values
});
/**
* @ag-grid-community/core - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
* @version v25.2.0
* @link http://www.ag-grid.com/
* @license MIT
*/
var ColumnKeyCreator = /** @class */ (function () {
function ColumnKeyCreator() {
this.existingKeys = {};
}
ColumnKeyCreator.prototype.addExistingKeys = function (keys) {
for (var i = 0; i < keys.length; i++) {
this.existingKeys[keys[i]] = true;
}
};
ColumnKeyCreator.prototype.getUniqueKey = function (colId, colField) {
// in case user passed in number for colId, convert to string
colId = toStringOrNull(colId);
var count = 0;
while (true) {
var idToTry = void 0;
if (colId) {
idToTry = colId;
if (count !== 0) {
idToTry += '_' + count;
}
}
else if (colField) {
idToTry = colField;
if (count !== 0) {
idToTry += '_' + count;
}
}
else {
idToTry = '' + count;
}
if (!this.existingKeys[idToTry]) {
this.existingKeys[idToTry] = true;
return idToTry;
}
count++;
}
};
return ColumnKeyCreator;
}());
/**
* @ag-grid-community/core - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
* @version v25.2.0
* @link http://www.ag-grid.com/
* @license MIT
*/
function firstExistingValue() {
var values = [];
for (var _i = 0; _i < arguments.length; _i++) {
values[_i] = arguments[_i];
}
for (var i = 0; i < values.length; i++) {
var value = values[i];
if (exists(value)) {
return value;
}
}
return null;
}
/** @deprecated */
function anyExists(values) {
return values && firstExistingValue(values) != null;
}
function existsAndNotEmpty(value) {
return value != null && value.length > 0;
}
function last(arr) {
if (!arr || !arr.length) {
return;
}
return arr[arr.length - 1];
}
function areEqual(a, b, comparator) {
if (a == null && b == null) {
return true;
}
return a != null &&
b != null &&
a.length === b.length &&
every(a, function (value, index) { return comparator ? comparator(value, b[index]) : b[index] === value; });
}
/** @deprecated */
function compareArrays(array1, array2) {
return areEqual(array1, array2);
}
/** @deprecated */
function shallowCompare(arr1, arr2) {
return areEqual(arr1, arr2);
}
function sortNumerically(array) {
return array.sort(function (a, b) { return a - b; });
}
function removeRepeatsFromArray(array, object) {
if (!array) {
return;
}
for (var index = array.length - 2; index >= 0; index--) {
var thisOneMatches = array[index] === object;
var nextOneMatches = array[index + 1] === object;
if (thisOneMatches && nextOneMatches) {
array.splice(index + 1, 1);
}
}
}
function removeFromArray(array, object) {
var index = array.indexOf(object);
if (index >= 0) {
array.splice(index, 1);
}
}
function removeAllFromArray(array, toRemove) {
forEach(toRemove, function (item) { return removeFromArray(array, item); });
}
function insertIntoArray(array, object, toIndex) {
array.splice(toIndex, 0, object);
}
function insertArrayIntoArray(dest, src, toIndex) {
if (dest == null || src == null) {
return;
}
// put items in backwards, otherwise inserted items end up in reverse order
for (var i = src.length - 1; i >= 0; i--) {
var item = src[i];
insertIntoArray(dest, item, toIndex);
}
}
function moveInArray(array, objectsToMove, toIndex) {
// first take out items from the array
removeAllFromArray(array, objectsToMove);
// now add the objects, in same order as provided to us, that means we start at the end
// as the objects will be pushed to the right as they are inserted
forEach(objectsToMove.slice().reverse(), function (obj) { return insertIntoArray(array, obj, toIndex); });
}
function includes(array, value) {
return array.indexOf(value) > -1;
}
function flatten(arrayOfArrays) {
return [].concat.apply([], arrayOfArrays);
}
function pushAll(target, source) {
if (source == null || target == null) {
return;
}
forEach(source, function (value) { return target.push(value); });
}
function toStrings(array) {
return map(array, toStringOrNull);
}
function findIndex(collection, predicate) {
for (var i = 0; i < collection.length; i++) {
if (predicate(collection[i], i, collection)) {
return i;
}
}
return -1;
}
function fill(collection, value, start, end) {
if (value === void 0) { value = null; }
if (start === void 0) { start = 0; }
if (end === void 0) { end = collection.length; }
for (var i = start; i < end; i++) {
collection[i] = value;
}
return collection;
}
/**
* The implementation of Array.prototype.every in browsers is always slower than just using a simple for loop, so
* use this for improved performance.
* https://jsbench.me/bek91dtit8/
*/
function every(list, predicate) {
if (list == null) {
return true;
}
for (var i = 0; i < list.length; i++) {
if (!predicate(list[i], i)) {
return false;
}
}
return true;
}
/**
* The implementation of Array.prototype.some in browsers is always slower than just using a simple for loop, so
* use this for improved performance.
* https://jsbench.me/5dk91e4tmt/
*/
function some(list, predicate) {
if (list == null) {
return false;
}
for (var i = 0; i < list.length; i++) {
if (predicate(list[i], i)) {
return true;
}
}
return false;
}
/**
* The implementation of Array.prototype.forEach in browsers is often slower than just using a simple for loop, so
* use this for improved performance.
* https://jsbench.me/apk91elt8a/
*/
function forEach(list, action) {
if (list == null) {
return;
}
for (var i = 0; i < list.length; i++) {
action(list[i], i);
}
}
function forEachReverse(list, action) {
if (list == null) {
return;
}
for (var i = list.length - 1; i >= 0; i--) {
action(list[i], i);
}
}
/**
* The implementation of Array.prototype.map in browsers is generally the same as just using a simple for loop. However,
* Firefox does exhibit some difference, and this performs no worse in other browsers, so use this if you want improved
* performance.
* https://jsbench.me/njk91ez8pc/
*/
function map(list, process) {
if (list == null) {
return null;
}
var mapped = [];
for (var i = 0; i < list.length; i++) {
mapped.push(process(list[i], i));
}
return mapped;
}
/**
* The implementation of Array.prototype.filter in browsers is always slower than just using a simple for loop, so
* use this for improved performance.
* https://jsbench.me/7bk91fk08c/
*/
function filter(list, predicate) {
if (list == null) {
return null;
}
var filtered = [];
for (var i = 0; i < list.length; i++) {
if (predicate(list[i], i)) {
filtered.push(list[i]);
}
}
return filtered;
}
/**
* The implementation of Array.prototype.reduce in browsers is generally the same as just using a simple for loop. However,
* Chrome does exhibit some difference, and this performs no worse in other browsers, so use this if you want improved
* performance.
* https://jsbench.me/7vk92n6u1f/
*/
function reduce(list, step, initial) {
if (list == null || initial == null) {
return null;
}
var result = initial;
for (var i = 0; i < list.length; i++) {
result = step(result, list[i], i);
}
return result;
}
/** @deprecated */
function forEachSnapshotFirst(list, callback) {
if (!list) {
return;
}
var arrayCopy = list.slice(0);
arrayCopy.forEach(callback);
}
var ArrayUtils = /*#__PURE__*/Object.freeze({
__proto__: null,
firstExistingValue: firstExistingValue,
anyExists: anyExists,
existsAndNotEmpty: existsAndNotEmpty,
last: last,
areEqual: areEqual,
compareArrays: compareArrays,
shallowCompare: shallowCompare,
sortNumerically: sortNumerically,
removeRepeatsFromArray: removeRepeatsFromArray,
removeFromArray: removeFromArray,
removeAllFromArray: removeAllFromArray,
insertIntoArray: insertIntoArray,
insertArrayIntoArray: insertArrayIntoArray,
moveInArray: moveInArray,
includes: includes,
flatten: flatten,
pushAll: pushAll,
toStrings: toStrings,
findIndex: findIndex,
fill: fill,
every: every,
some: some,
forEach: forEach,
forEachReverse: forEachReverse,
map: map,
filter: filter,
reduce: reduce,
forEachSnapshotFirst: forEachSnapshotFirst
});
/**
* @ag-grid-community/core - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
* @version v25.2.0
* @link http://www.ag-grid.com/
* @license MIT
*/
function iterateObject(object, callback) {
if (object == null) {
return;
}
if (Array.isArray(object)) {
forEach(object, function (value, index) { return callback("" + index, value); });
}
else {
forEach(Object.keys(object), function (key) { return callback(key, object[key]); });
}
}
function cloneObject(object) {
var copy = {};
var keys = Object.keys(object);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = object[key];
copy[key] = value;
}
return copy;
}
function deepCloneObject(object) {
return JSON.parse(JSON.stringify(object));
}
// returns copy of an object, doing a deep clone of any objects with that object.
// this is used for eg creating copies of Column Definitions, where we want to
// deep copy all objects, but do not want to deep copy functions (eg when user provides
// a function or class for colDef.cellRenderer)
function deepCloneDefinition(object, keysToSkip) {
if (!object) {
return;
}
var obj = object;
var res = {};
Object.keys(obj).forEach(function (key) {
if (keysToSkip && keysToSkip.indexOf(key) >= 0) {
return;
}
var value = obj[key];
// 'simple object' means a bunch of key/value pairs, eg {filter: 'myFilter'}. it does
// NOT include the following:
// 1) arrays
// 2) functions or classes (eg ColumnAPI instance)
var sourceIsSimpleObject = isNonNullObject(value) && value.constructor === Object;
if (sourceIsSimpleObject) {
res[key] = deepCloneDefinition(value);
}
else {
res[key] = value;
}
});
return res;
}
function getProperty(object, key) {
return object[key];
}
function setProperty(object, key, value) {
object[key] = value;
}
/**
* Will copy the specified properties from `source` into the equivalent properties on `target`, ignoring properties with
* a value of `undefined`.
*/
function copyPropertiesIfPresent(source, target) {
var properties = [];
for (var _i = 2; _i < arguments.length; _i++) {
properties[_i - 2] = arguments[_i];
}
forEach(properties, function (p) { return copyPropertyIfPresent(source, target, p); });
}
/**
* Will copy the specified property from `source` into the equivalent property on `target`, unless the property has a
* value of `undefined`. If a transformation is provided, it will be applied to the value before being set on `target`.
*/
function copyPropertyIfPresent(source, target, property, transform) {
var value = getProperty(source, property);
if (value !== undefined) {
setProperty(target, property, transform ? transform(value) : value);
}
}
function getAllKeysInObjects(objects) {
var allValues = {};
objects.filter(function (obj) { return obj != null; }).forEach(function (obj) {
forEach(Object.keys(obj), function (key) { return allValues[key] = null; });
});
return Object.keys(allValues);
}
function getAllValuesInObject(obj) {
if (!obj) {
return [];
}
var anyObject = Object;
if (typeof anyObject.values === 'function') {
return anyObject.values(obj);
}
var ret = [];
for (var key in obj) {
if (obj.hasOwnProperty(key) && obj.propertyIsEnumerable(key)) {
ret.push(obj[key]);
}
}
return ret;
}
function mergeDeep(dest, source, copyUndefined, makeCopyOfSimpleObjects) {
if (copyUndefined === void 0) { copyUndefined = true; }
if (makeCopyOfSimpleObjects === void 0) { makeCopyOfSimpleObjects = false; }
if (!exists(source)) {
return;
}
iterateObject(source, function (key, sourceValue) {
var destValue = dest[key];
if (destValue === sourceValue) {
return;
}
// when creating params, we don't want to just copy objects over. otherwise merging ColDefs (eg DefaultColDef
// and Column Types) would result in params getting shared between objects.
// by putting an empty value into destValue first, it means we end up copying over values from
// the source object, rather than just copying in the source object in it's entirety.
if (makeCopyOfSimpleObjects) {
var objectIsDueToBeCopied = destValue == null && sourceValue != null;
if (objectIsDueToBeCopied) {
// 'simple object' means a bunch of key/value pairs, eg {filter: 'myFilter'}, as opposed
// to a Class instance (such as ColumnAPI instance).
var sourceIsSimpleObject = typeof sourceValue === 'object' && sourceValue.constructor === Object;
var dontCopy = sourceIsSimpleObject;
if (dontCopy) {
destValue = {};
dest[key] = destValue;
}
}
}
if (isNonNullObject(sourceValue) && isNonNullObject(destValue) && !Array.isArray(destValue)) {
mergeDeep(destValue, sourceValue, copyUndefined, makeCopyOfSimpleObjects);
}
else if (copyUndefined || sourceValue !== undefined) {
dest[key] = sourceValue;
}
});
}
function assign(object) {
var sources = [];
for (var _i = 1; _i < arguments.length; _i++) {
sources[_i - 1] = arguments[_i];
}
forEach(sources, function (source) { return iterateObject(source, function (key, value) { return object[key] = value; }); });
return object;
}
function missingOrEmptyObject(value) {
return missing(value) || Object.keys(value).length === 0;
}
function get(source, expression, defaultValue) {
if (source == null) {
return defaultValue;
}
var keys = expression.split('.');
var objectToRead = source;
while (keys.length > 1) {
objectToRead = objectToRead[keys.shift()];
if (objectToRead == null) {
return defaultValue;
}
}
var value = objectToRead[keys[0]];
return value != null ? value : defaultValue;
}
function set(target, expression, value) {
if (target == null) {
return;
}
var keys = expression.split('.');
var objectToUpdate = target;
while (keys.length > 1) {
objectToUpdate = objectToUpdate[keys.shift()];
if (objectToUpdate == null) {
return;
}
}
objectToUpdate[keys[0]] = value;
}
function deepFreeze(object) {
Object.freeze(object);
forEach(values(object), function (v) {
if (isNonNullObject(v) || typeof v === 'function') {
deepFreeze(v);
}
});
return object;
}
function getValueUsingField(data, field, fieldContainsDots) {
if (!field || !data) {
return;
}
// if no '.', then it's not a deep value
if (!fieldContainsDots) {
return data[field];
}
// otherwise it is a deep value, so need to dig for it
var fields = field.split('.');
var currentObject = data;
for (var i = 0; i < fields.length; i++) {
if (currentObject == null) {
return undefined;
}
currentObject = currentObject[fields[i]];
}
return currentObject;
}
// used by ColumnAPI and GridAPI to remove all references, so keeping grid in memory resulting in a
// memory leak if user is not disposing of the GridAPI or ColumnApi references
function removeAllReferences(obj, objectName) {
Object.keys(obj).forEach(function (key) {
var value = obj[key];
// we want to replace all the @autowired services, which are objects. any simple types (boolean, string etc)
// we don't care about
if (typeof value === 'object') {
obj[key] = undefined;
}
});
var proto = Object.getPrototypeOf(obj);
var properties = {};
Object.keys(proto).forEach(function (key) {
var value = proto[key];
// leave all basic types - this is needed for GridAPI to leave the "destroyed: boolean" attribute alone
if (typeof value === 'function') {
var func = function () {
console.warn("AG Grid: " + objectName + " function " + key + "() cannot be called as the grid has been destroyed.\n Please don't call grid API functions on destroyed grids - as a matter of fact you shouldn't\n be keeping the API reference, your application has a memory leak! Remove the API reference\n when the grid is destroyed.");
};
properties[key] = { value: func, writable: true };
}
});
Object.defineProperties(obj, properties);
}
function isNonNullObject(value) {
return typeof value === 'object' && value !== null;
}
var ObjectUtils = /*#__PURE__*/Object.freeze({
__proto__: null,
iterateObject: iterateObject,
cloneObject: cloneObject,
deepCloneObject: deepCloneObject,
deepCloneDefinition: deepCloneDefinition,
getProperty: getProperty,
setProperty: setProperty,
copyPropertiesIfPresent: copyPropertiesIfPresent,
copyPropertyIfPresent: copyPropertyIfPresent,
getAllKeysInObjects: getAllKeysInObjects,
getAllValuesInObject: getAllValuesInObject,
mergeDeep: mergeDeep,
assign: assign,
missingOrEmptyObject: missingOrEmptyObject,
get: get,
set: set,
deepFreeze: deepFreeze,
getValueUsingField: getValueUsingField,
removeAllReferences: removeAllReferences,
isNonNullObject: isNonNullObject
});
/**
* @ag-grid-community/core - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
* @version v25.2.0
* @link http://www.ag-grid.com/
* @license MIT
*/
var FUNCTION_STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var FUNCTION_ARGUMENT_NAMES = /([^\s,]+)/g;
var doOnceFlags = {};
/**
* If the key was passed before, then doesn't execute the func
* @param {Function} func
* @param {string} key
*/
function doOnce(func, key) {
if (doOnceFlags[key]) {
return;
}
func();
doOnceFlags[key] = true;
}
function getFunctionName(funcConstructor) {
// for every other browser in the world
if (funcConstructor.name) {
return funcConstructor.name;
}
// for the pestilence that is ie11
var matches = /function\s+([^\(]+)/.exec(funcConstructor.toString());
return matches && matches.length === 2 ? matches[1].trim() : null;
}
/** @deprecated */
function getFunctionParameters(func) {
var fnStr = func.toString().replace(FUNCTION_STRIP_COMMENTS, '');
return fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(FUNCTION_ARGUMENT_NAMES) || [];
}
function isFunction(val) {
return !!(val && val.constructor && val.call && val.apply);
}
function executeInAWhile(funcs) {
executeAfter(funcs, 400);
}
var executeNextVMTurnFuncs = [];
var executeNextVMTurnPending = false;
function executeNextVMTurn(func) {
executeNextVMTurnFuncs.push(func);
if (executeNextVMTurnPending) {
return;
}
executeNextVMTurnPending = true;
window.setTimeout(function () {
var funcsCopy = executeNextVMTurnFuncs.slice();
executeNextVMTurnFuncs.length = 0;
executeNextVMTurnPending = false;
funcsCopy.forEach(function (func) { return func(); });
}, 0);
}
function executeAfter(funcs, milliseconds) {
if (milliseconds === void 0) { milliseconds = 0; }
if (funcs.length > 0) {
window.setTimeout(function () { return funcs.forEach(function (func) { return func(); }); }, milliseconds);
}
}
/**
* from https://stackoverflow.com/questions/24004791/can-someone-explain-the-debounce-function-in-javascript
* @param {Function} func The function to be debounced
* @param {number} wait The time in ms to debounce
* @param {boolean} immediate If it should run immediately or wait for the initial debounce delay
* @return {Function} The debounced function
*/
function debounce(func, wait, immediate) {
if (immediate === void 0) { immediate = false; }
// 'private' variable for instance
// The returned function will be able to reference this due to closure.
// Each call to the returned function will share this common timer.
var timeout;
// Calling debounce returns a new anonymous function
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
// reference the context and args for the setTimeout function
var context = this;
// Should the function be called now? If immediate is true
// and not already in a timeout then the answer is: Yes
var callNow = immediate && !timeout;
// This is the basic debounce behaviour where you can call this
// function several times, but it will only execute once
// [before or after imposing a delay].
// Each time the returned function is called, the timer starts over.
window.clearTimeout(timeout);
// Set the new timeout
timeout = window.setTimeout(function () {
// Inside the timeout function, clear the timeout variable
// which will let the next execution run when in 'immediate' mode
timeout = null;
// Check if the function already ran with the immediate flag
if (!immediate) {
// Call the original function with apply
// apply lets you define the 'this' object as well as the arguments
// (both captured before setTimeout)
func.apply(context, args);
}
}, wait);
// Immediate mode and no wait timer? Execute the function..
if (callNow) {
func.apply(context, args);
}
};
}
function compose() {
var fns = [];
for (var _i = 0; _i < arguments.length; _i++) {
fns[_i] = arguments[_i];
}
return function (arg) { return fns.reduce(function (composed, f) { return f(composed); }, arg); };
}
function callIfPresent(func) {
if (func) {
func();
}
}
var FunctionUtils = /*#__PURE__*/Object.freeze({
__proto__: null,
doOnce: doOnce,
getFunctionName: getFunctionName,
getFunctionParameters: getFunctionParameters,
isFunction: isFunction,
executeInAWhile: executeInAWhile,
executeNextVMTurn: executeNextVMTurn,
executeAfter: executeAfter,
debounce: debounce,
compose: compose,
callIfPresent: callIfPresent
});
/**
* @ag-grid-community/core - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
* @version v25.2.0
* @link http://www.ag-grid.com/
* @license MIT
*/
var Context = /** @class */ (function () {
function Context(params, logger) {
this.beanWrappers = {};
this.destroyed = false;
if (!params || !params.beanClasses) {
return;
}
this.contextParams = params;
this.logger = logger;
this.logger.log(">> creating ag-Application Context");
this.createBeans();
var beanInstances = this.getBeanInstances();
this.wireBeans(beanInstances);
this.logger.log(">> ag-Application Context ready - component is alive");
}
Context.prototype.getBeanInstances = function () {
return values(this.beanWrappers).map(function (beanEntry) { return beanEntry.beanInstance; });
};
Context.prototype.createBean = function (bean, afterPreCreateCallback) {
if (!bean) {
throw Error("Can't wire to bean since it is null");
}
this.wireBeans([bean], afterPreCreateCallback);
return bean;
};
Context.prototype.wireBeans = function (beanInstances, afterPreCreateCallback) {
this.autoWireBeans(beanInstances);
this.methodWireBeans(beanInstances);
this.callLifeCycleMethods(beanInstances, 'preConstructMethods');
// the callback sets the attributes, so the component has access to attributes
// before postConstruct methods in the component are executed
if (exists(afterPreCreateCallback)) {
beanInstances.forEach(afterPreCreateCallback);
}
this.callLifeCycleMethods(beanInstances, 'postConstructMethods');
};
Context.prototype.createBeans = function () {
var _this = this;
// register all normal beans
this.contextParams.beanClasses.forEach(this.createBeanWrapper.bind(this));
// register override beans, these will overwrite beans above of same name
// instantiate all beans - overridden beans will be left out
iterateObject(this.beanWrappers, function (key, beanEntry) {
var constructorParamsMeta;
if (beanEntry.bean.__agBeanMetaData && beanEntry.bean.__agBeanMetaData.autowireMethods && beanEntry.bean.__agBeanMetaData.autowireMethods.agConstructor) {
constructorParamsMeta = beanEntry.bean.__agBeanMetaData.autowireMethods.agConstructor;
}
var constructorParams = _this.getBeansForParameters(constructorParamsMeta, beanEntry.bean.name);
var newInstance = applyToConstructor(beanEntry.bean, constructorParams);
beanEntry.beanInstance = newInstance;
});
var createdBeanNames = Object.keys(this.beanWrappers).join(', ');
this.logger.log("created beans: " + createdBeanNames);
};
// tslint:disable-next-line
Context.prototype.createBeanWrapper = function (BeanClass) {
var metaData = BeanClass.__agBeanMetaData;
if (!metaData) {
var beanName = void 0;
if (BeanClass.prototype.constructor) {
beanName = getFunctionName(BeanClass.prototype.constructor);
}
else {
beanName = "" + BeanClass;
}
console.error("Context item " + beanName + " is not a bean");
return;
}
var beanEntry = {
bean: BeanClass,
beanInstance: null,
beanName: metaData.beanName
};
this.beanWrappers[metaData.beanName] = beanEntry;
};
Context.prototype.autoWireBeans = function (beanInstances) {
var _this = this;
beanInstances.forEach(function (beanInstance) {
_this.forEachMetaDataInHierarchy(beanInstance, function (metaData, beanName) {
var attributes = metaData.agClassAttributes;
if (!attributes) {
return;
}
attributes.forEach(function (attribute) {
var otherBean = _this.lookupBeanInstance(beanName, attribute.beanName, attribute.optional);
beanInstance[attribute.attributeName] = otherBean;
});
});
});
};
Context.prototype.methodWireBeans = function (beanInstances) {
var _this = this;
beanInstances.forEach(function (beanInstance) {
_this.forEachMetaDataInHierarchy(beanInstance, function (metaData, beanName) {
iterateObject(metaData.autowireMethods, function (methodName, wireParams) {
// skip constructor, as this is dealt with elsewhere
if (methodName === "agConstructor") {
return;
}
var initParams = _this.getBeansForParameters(wireParams, beanName);
beanInstance[methodName].apply(beanInstance, initParams);
});
});
});
};
Context.prototype.forEachMetaDataInHierarchy = function (beanInstance, callback) {
var prototype = Object.getPrototypeOf(beanInstance);
while (prototype != null) {
var constructor = prototype.constructor;
if (constructor.hasOwnProperty('__agBeanMetaData')) {
var metaData = constructor.__agBeanMetaData;
var beanName = this.getBeanName(constructor);
callback(metaData, beanName);
}
prototype = Object.getPrototypeOf(prototype);
}
};
Context.prototype.getBeanName = function (constructor) {
if (constructor.__agBeanMetaData && constructor.__agBeanMetaData.beanName) {
return constructor.__agBeanMetaData.beanName;
}
var constructorString = constructor.toString();
var beanName = constructorString.substring(9, constructorString.indexOf("("));
return beanName;
};
Context.prototype.getBeansForParameters = function (parameters, beanName) {
var _this = this;
var beansList = [];
if (parameters) {
iterateObject(parameters, function (paramIndex, otherBeanName) {
var otherBean = _this.lookupBeanInstance(beanName, otherBeanName);
beansList[Number(paramIndex)] = otherBean;
});
}
return beansList;
};
Context.prototype.lookupBeanInstance = function (wiringBean, beanName, optional) {
if (optional === void 0) { optional = false; }
if (beanName === "context") {
return this;
}
if (this.contextParams.providedBeanInstances && this.contextParams.providedBeanInstances.hasOwnProperty(beanName)) {
return this.contextParams.providedBeanInstances[beanName];
}
var beanEntry = this.beanWrappers[beanName];
if (beanEntry) {
return beanEntry.beanInstance;
}
if (!optional) {
console.error("AG Grid: unable to find bean reference " + beanName + " while initialising " + wiringBean);
}
return null;
};
Context.prototype.callLifeCycleMethods = function (beanInstances, lifeCycleMethod) {
var _this = this;
beanInstances.forEach(function (beanInstance) { return _this.callLifeCycleMethodsOnBean(beanInstance, lifeCycleMethod); });
};
Context.prototype.callLifeCycleMethodsOnBean = function (beanInstance, lifeCycleMethod, methodToIgnore) {
// putting all methods into a map removes duplicates
var allMethods = {};
// dump methods from each level of the metadata hierarchy
this.forEachMetaDataInHierarchy(beanInstance, function (metaData) {
var methods = metaData[lifeCycleMethod];
if (methods) {
methods.forEach(function (methodName) {
if (methodName != methodToIgnore) {
allMethods[methodName] = true;
}
});
}
});
var allMethodsList = Object.keys(allMethods);
allMethodsList.forEach(function (methodName) { return beanInstance[methodName](); });
};
Context.prototype.getBean = function (name) {
return this.lookupBeanInstance("getBean", name, true);
};
Context.prototype.destroy = function () {
if (this.destroyed) {
return;
}
this.logger.log(">> Shutting down ag-Application Context");
var beanInstances = this.getBeanInstances();
this.destroyBeans(beanInstances);
this.contextParams.providedBeanInstances = null;
this.destroyed = true;
this.logger.log(">> ag-Application Context shut down - component is dead");
};
Context.prototype.destroyBean = function (bean) {
if (!bean) {
return;
}
this.destroyBeans([bean]);
};
Context.prototype.destroyBeans = function (beans) {
var _this = this;
if (!beans) {
return [];
}
beans.forEach(function (bean) {
_this.callLifeCycleMethodsOnBean(bean, 'preDestroyMethods', 'destroy');
// call destroy() explicitly if it exists
var beanAny = bean;
if (typeof beanAny.destroy === 'function') {
beanAny.destroy();
}
});
return [];
};
return Context;
}());
// taken from: http://stackoverflow.com/questions/3362471/how-can-i-call-a-javascript-constructor-using-call-or-apply
// allows calling 'apply' on a constructor
function applyToConstructor(constructor, argArray) {
var args = [null].concat(argArray);
var factoryFunction = constructor.bind.apply(constructor, args);
return new factoryFunction();
}
function PreConstruct(target, methodName, descriptor) {
var props = getOrCreateProps(target.constructor);
if (!props.preConstructMethods) {
props.preConstructMethods = [];
}
props.preConstructMethods.push(methodName);
}
function PostConstruct(target, methodName, descriptor) {
var props = getOrCreateProps(target.constructor);
if (!props.postConstructMethods) {
props.postConstructMethods = [];
}
props.postConstructMethods.push(methodName);
}
function PreDestroy(target, methodName, descriptor) {
var props = getOrCreateProps(target.constructor);
if (!props.preDestroyMethods) {
props.preDestroyMethods = [];
}
props.preDestroyMethods.push(methodName);
}
function Bean(beanName) {
return function (classConstructor) {
var props = getOrCreateProps(classConstructor);
props.beanName = beanName;
};
}
function Autowired(name) {
return function (target, propertyKey, descriptor) {
autowiredFunc(target, name, false, target, propertyKey, null);
};
}
function Optional(name) {
return function (target, propertyKey, descriptor) {
autowiredFunc(target, name, true, target, propertyKey, null);
};
}
function autowiredFunc(target, name, optional, classPrototype, methodOrAttributeName, index) {
if (name === null) {
console.error("AG Grid: Autowired name should not be null");
return;
}
if (typeof index === "number") {
console.error("AG Grid: Autowired should be on an attribute");
return;
}
// it's an attribute on the class
var props = getOrCreateProps(target.constructor);
if (!props.agClassAttributes) {
props.agClassAttributes = [];
}
props.agClassAttributes.push({
attributeName: methodOrAttributeName,
beanName: name,
optional: optional
});
}
function Qualifier(name) {
return function (classPrototype, methodOrAttributeName, index) {
var constructor = typeof classPrototype == "function" ? classPrototype : classPrototype.constructor;
var props;
if (typeof index === "number") {
// it's a parameter on a method
var methodName = void 0;
if (methodOrAttributeName) {
props = getOrCreateProps(constructor);
methodName = methodOrAttributeName;
}
else {
props = getOrCreateProps(constructor);
methodName = "agConstructor";
}
if (!props.autowireMethods) {
props.autowireMethods = {};
}
if (!props.autowireMethods[methodName]) {
props.autowireMethods[methodName] = {};
}
props.autowireMethods[methodName][index] = name;
}
};
}
function getOrCreateProps(target) {
if (!target.hasOwnProperty("__agBeanMetaData")) {
target.__agBeanMetaData = {};
}
return target.__agBeanMetaData;
}
/**
* @ag-grid-community/core - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
* @version v25.2.0
* @link http://www.ag-grid.com/
* @license MIT
*/
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (undefined && undefined.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var EventService = /** @class */ (function () {
function EventService() {
this.allSyncListeners = new Map();
this.allAsyncListeners = new Map();
this.globalSyncListeners = new Set();
this.globalAsyncListeners = new Set();
this.asyncFunctionsQueue = [];
this.scheduled = false;
// using an object performs better than a Set for the number of different events we have
this.firedEvents = {};
}
// because this class is used both inside the context and outside the context, we do not
// use autowired attributes, as that would be confusing, as sometimes the attributes
// would be wired, and sometimes not.
//
// the global event servers used by AG Grid is autowired by the context once, and this
// setBeans method gets called once.
//
// the times when this class is used outside of the context (eg RowNode has an instance of this
// class) then it is not a bean, and this setBeans method is not called.
EventService.prototype.setBeans = function (loggerFactory, gridOptionsWrapper, frameworkOverrides, globalEventListener) {
if (globalEventListener === void 0) { globalEventListener = null; }
this.logger = loggerFactory.create('EventService');
this.frameworkOverrides = frameworkOverrides;
if (globalEventListener) {
var async = gridOptionsWrapper.useAsyncEvents();
this.addGlobalListener(globalEventListener, async);
}
};
EventService.prototype.getListeners = function (eventType, async, autoCreateListenerCollection) {
var listenerMap = async ? this.allAsyncListeners : this.allSyncListeners;
var listeners = listenerMap.get(eventType);
// Note: 'autoCreateListenerCollection' should only be 'true' if a listener is about to be added. For instance
// getListeners() is also called during event dispatch even though no listeners are added. This measure protects
// against 'memory bloat' as empty collections will prevent the RowNode's event service from being removed after
// the RowComp is destroyed, see noRegisteredListenersExist() below.
if (!listeners && autoCreateListenerCollection) {
listeners = new Set();
listenerMap.set(eventType, listeners);
}
return listeners;
};
EventService.prototype.noRegisteredListenersExist = function () {
return this.allSyncListeners.size === 0 && this.allAsyncListeners.size === 0 &&
this.globalSyncListeners.size === 0 && this.globalAsyncListeners.size === 0;
};
EventService.prototype.addEventListener = function (eventType, listener, async) {
if (async === void 0) { async = false; }
this.getListeners(eventType, async, true).add(listener);
};
EventService.prototype.removeEventListener = function (eventType, listener, async) {
if (async === void 0) { async = false; }
var listeners = this.getListeners(eventType, async, false);
if (!listeners) {
return;
}
listeners.delete(listener);
if (listeners.size === 0) {
var listenerMap = async ? this.allAsyncListeners : this.allSyncListeners;
listenerMap.delete(eventType);
}
};
EventService.prototype.addGlobalListener = function (listener, async) {
if (async === void 0) { async = false; }
(async ? this.globalAsyncListeners : this.globalSyncListeners).add(listener);
};
EventService.prototype.removeGlobalListener = function (listener, async) {
if (async === void 0) { async = false; }
(async ? this.globalAsyncListeners : this.globalSyncListeners).delete(listener);
};
EventService.prototype.dispatchEvent = function (event) {
this.dispatchToListeners(event, true);
this.dispatchToListeners(event, false);
this.firedEvents[event.type] = true;
};
EventService.prototype.dispatchEventOnce = function (event) {
if (!this.firedEvents[event.type]) {
this.dispatchEvent(event);
}
};
EventService.prototype.dispatchToListeners = function (event, async) {
var _this = this;
var eventType = event.type;
var processEventListeners = function (listeners) { return listeners.forEach(function (listener) {
if (async) {
_this.dispatchAsync(function () { return listener(event); });
}
else {
listener(event);
}
}); };
var listeners = this.getListeners(eventType, async, false);
if (listeners) {
processEventListeners(listeners);
}
var globalListeners = async ? this.globalAsyncListeners : this.globalSyncListeners;
globalListeners.forEach(function (listener) {
if (async) {
_this.dispatchAsync(function () { return _this.frameworkOverrides.dispatchEvent(eventType, function () { return listener(eventType, event); }); });
}
else {
_this.frameworkOverrides.dispatchEvent(eventType, function () { return listener(eventType, event); });
}
});
};
// this gets called inside the grid's thread, for each event that it
// wants to set async. the grid then batches the events into one setTimeout()
// because setTimeout() is an expensive operation. ideally we would have
// each event in it's own setTimeout(), but we batch for performance.
EventService.prototype.dispatchAsync = function (func) {
// add to the queue for executing later in the next VM turn
this.asyncFunctionsQueue.push(func);
// check if timeout is already scheduled. the first time the grid calls
// this within it's thread turn, this should be false, so it will schedule
// the 'flush queue' method the first time it comes here. then the flag is
// set to 'true' so it will know it's already scheduled for subsequent calls.
if (!this.scheduled) {
// if not scheduled, schedule one
window.setTimeout(this.flushAsyncQueue.bind(this), 0);
// mark that it is scheduled
this.scheduled = true;
}
};
// this happens in the next VM turn only, and empties the queue of events
EventService.prototype.flushAsyncQueue = function () {
this.scheduled = false;
// we take a copy, because the event listener could be usi