UNPKG

ag-grid-community

Version:

Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components

1,364 lines (1,351 loc) 2.18 MB
/** * 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