UNPKG

ag-grid

Version:

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

1,318 lines (1,312 loc) 1.66 MB
// ag-grid v18.1.2 (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["agGrid"] = factory(); else root["agGrid"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 120); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * ag-grid - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components * @version v18.1.2 * @link http://www.ag-grid.com/ * @license MIT */ Object.defineProperty(exports, "__esModule", { value: true }); var utils_1 = __webpack_require__(1); var Context = (function () { function Context(params, logger) { this.beans = {}; this.componentsMappedByName = {}; this.destroyed = false; if (!params || !params.beans) { return; } this.contextParams = params; this.logger = logger; this.logger.log(">> creating ag-Application Context"); this.setupComponents(); this.createBeans(); var beans = utils_1.Utils.mapObject(this.beans, function (beanEntry) { return beanEntry.beanInstance; }); this.wireBeans(beans); this.logger.log(">> ag-Application Context ready - component is alive"); } Context.prototype.setupComponents = function () { var _this = this; if (this.contextParams.components) { this.contextParams.components.forEach(function (componentMeta) { return _this.addComponent(componentMeta); }); } }; Context.prototype.addComponent = function (componentMeta) { // get name of the class as a string // let className = _.getNameOfClass(ComponentClass); // insert a dash after every capital letter // let classEscaped = className.replace(/([A-Z])/g, "-$1").toLowerCase(); var classEscaped = componentMeta.componentName.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(); // put all to upper case var classUpperCase = classEscaped.toUpperCase(); // finally store this.componentsMappedByName[classUpperCase] = componentMeta.theClass; }; Context.prototype.createComponent = function (element, afterPreCreateCallback) { var key = element.nodeName; if (this.componentsMappedByName && this.componentsMappedByName[key]) { var newComponent = new this.componentsMappedByName[key](); this.wireBean(newComponent, afterPreCreateCallback); return newComponent; } else { return null; } }; Context.prototype.wireBean = function (bean, afterPreCreateCallback) { if (!bean) { throw Error("Can't wire to bean since it is null"); } this.wireBeans([bean], afterPreCreateCallback); }; Context.prototype.wireBeans = function (beans, afterPreCreateCallback) { this.autoWireBeans(beans); this.methodWireBeans(beans); this.preConstruct(beans); // the callback sets the attributes, so the component has access to attributes // before postConstruct methods in the component are executed if (utils_1.Utils.exists(afterPreCreateCallback)) { beans.forEach(afterPreCreateCallback); } this.postConstruct(beans); }; Context.prototype.createBeans = function () { var _this = this; // register all normal beans this.contextParams.beans.forEach(this.createBeanEntry.bind(this)); // register override beans, these will overwrite beans above of same name if (this.contextParams.overrideBeans) { this.contextParams.overrideBeans.forEach(this.createBeanEntry.bind(this)); } // instantiate all beans - overridden beans will be left out utils_1.Utils.iterateObject(this.beans, 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; _this.logger.log("bean " + _this.getBeanName(newInstance) + " created"); }); }; Context.prototype.createBeanEntry = function (Bean) { var metaData = Bean.__agBeanMetaData; if (!metaData) { var beanName = void 0; if (Bean.prototype.constructor) { beanName = Bean.prototype.constructor.name; } else { beanName = "" + Bean; } console.error("context item " + beanName + " is not a bean"); return; } var beanEntry = { bean: Bean, beanInstance: null, beanName: metaData.beanName }; this.beans[metaData.beanName] = beanEntry; }; Context.prototype.autoWireBeans = function (beans) { var _this = this; beans.forEach(function (bean) { return _this.autoWireBean(bean); }); }; Context.prototype.methodWireBeans = function (beans) { var _this = this; beans.forEach(function (bean) { if (!bean) { throw Error("Can't wire to bean since it is null"); } return _this.methodWireBean(bean); }); }; Context.prototype.autoWireBean = function (bean) { var _this = this; var currentBean = bean; var _loop_1 = function () { var currentConstructor = currentBean.constructor; if (currentConstructor.__agBeanMetaData && currentConstructor.__agBeanMetaData.agClassAttributes) { var attributes = currentConstructor.__agBeanMetaData.agClassAttributes; if (!attributes) { return { value: void 0 }; } var beanName_1 = this_1.getBeanName(currentConstructor); attributes.forEach(function (attribute) { var otherBean = _this.lookupBeanInstance(beanName_1, attribute.beanName, attribute.optional); bean[attribute.attributeName] = otherBean; }); } currentBean = Object.getPrototypeOf(currentBean) ? Object.getPrototypeOf(currentBean) : null; }; var this_1 = this; while (currentBean != null) { var state_1 = _loop_1(); if (typeof state_1 === "object") return state_1.value; } }; 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.methodWireBean = function (bean) { var _this = this; var autowiredMethods; if (bean.constructor.__agBeanMetaData && bean.constructor.__agBeanMetaData.autowireMethods) { autowiredMethods = bean.constructor.__agBeanMetaData.autowireMethods; } utils_1.Utils.iterateObject(autowiredMethods, function (methodName, wireParams) { // skip constructor, as this is dealt with elsewhere if (methodName === "agConstructor") { return; } var beanName = _this.getBeanName(bean.constructor); var initParams = _this.getBeansForParameters(wireParams, beanName); bean[methodName].apply(bean, initParams); }); }; Context.prototype.getBeansForParameters = function (parameters, beanName) { var _this = this; var beansList = []; if (parameters) { utils_1.Utils.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; } else if (this.contextParams.seed && this.contextParams.seed.hasOwnProperty(beanName)) { return this.contextParams.seed[beanName]; } else { var beanEntry = this.beans[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.postConstruct = function (beans) { beans.forEach(function (bean) { // try calling init methods if (bean.constructor.__agBeanMetaData && bean.constructor.__agBeanMetaData.postConstructMethods) { bean.constructor.__agBeanMetaData && bean.constructor.__agBeanMetaData.postConstructMethods.forEach(function (methodName) { return bean[methodName](); }); } }); }; Context.prototype.preConstruct = function (beans) { beans.forEach(function (bean) { // try calling init methods if (bean.constructor.__agBeanMetaData && bean.constructor.__agBeanMetaData.preConstructMethods) { bean.constructor.__agBeanMetaData.preConstructMethods.forEach(function (methodName) { return bean[methodName](); }); } }); }; Context.prototype.getBean = function (name) { return this.lookupBeanInstance("getBean", name, true); }; Context.prototype.destroy = function () { // should only be able to destroy once if (this.destroyed) { return; } this.logger.log(">> Shutting down ag-Application Context"); // try calling destroy methods utils_1.Utils.iterateObject(this.beans, function (key, beanEntry) { var bean = beanEntry.beanInstance; if (bean.constructor.__agBeanMetaData && bean.constructor.__agBeanMetaData.preDestroyMethods) { bean.constructor.__agBeanMetaData.preDestroyMethods.forEach(function (methodName) { return bean[methodName](); }); } }); this.destroyed = true; this.logger.log(">> ag-Application Context shut down - component is dead"); }; return Context; }()); exports.Context = 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.postConstructMethods) { props.preConstructMethods = []; } props.preConstructMethods.push(methodName); } exports.PreConstruct = PreConstruct; function PostConstruct(target, methodName, descriptor) { var props = getOrCreateProps(target.constructor); if (!props.postConstructMethods) { props.postConstructMethods = []; } props.postConstructMethods.push(methodName); } exports.PostConstruct = PostConstruct; function PreDestroy(target, methodName, descriptor) { var props = getOrCreateProps(target.constructor); if (!props.preDestroyMethods) { props.preDestroyMethods = []; } props.preDestroyMethods.push(methodName); } exports.PreDestroy = PreDestroy; function Bean(beanName) { return function (classConstructor) { var props = getOrCreateProps(classConstructor); props.beanName = beanName; }; } exports.Bean = Bean; function Autowired(name) { return function (target, propertyKey, descriptor) { autowiredFunc(target, name, false, target, propertyKey, null); }; } exports.Autowired = Autowired; function Optional(name) { return function (target, propertyKey, descriptor) { autowiredFunc(target, name, true, target, propertyKey, null); }; } exports.Optional = Optional; 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; } }; } exports.Qualifier = Qualifier; function getOrCreateProps(target) { if (!target.hasOwnProperty("__agBeanMetaData")) { target.__agBeanMetaData = {}; } return target.__agBeanMetaData; } /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * ag-grid - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components * @version v18.1.2 * @link http://www.ag-grid.com/ * @license MIT */ Object.defineProperty(exports, "__esModule", { value: true }); var constants_1 = __webpack_require__(9); var FUNCTION_STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; var FUNCTION_ARGUMENT_NAMES = /([^\s,]+)/g; var AG_GRID_STOP_PROPAGATION = '__ag_Grid_Stop_Propagation'; // util class, only used when debugging, for printing time to console var Timer = (function () { function Timer() { this.timestamp = new Date().getTime(); } Timer.prototype.print = function (msg) { var duration = (new Date().getTime()) - this.timestamp; console.log(msg + " = " + duration); this.timestamp = new Date().getTime(); }; return Timer; }()); exports.Timer = Timer; /** HTML Escapes. */ var HTML_ESCAPES = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }; var reUnescapedHtml = /[&<>"']/g; var Utils = (function () { function Utils() { } // if the key was passed before, then doesn't execute the func Utils.doOnce = function (func, key) { if (this.doOnceFlags[key]) { return; } func(); this.doOnceFlags[key] = true; }; // returns true if the event is close to the original event by X pixels either vertically or horizontally. // we only start dragging after X pixels so this allows us to know if we should start dragging yet. Utils.areEventsNear = function (e1, e2, pixelCount) { // by default, we wait 4 pixels before starting the drag if (pixelCount === 0) { return false; } var diffX = Math.abs(e1.clientX - e2.clientX); var diffY = Math.abs(e1.clientY - e2.clientY); return Math.max(diffX, diffY) <= pixelCount; }; Utils.shallowCompare = function (arr1, arr2) { // if both are missing, then they are the same if (this.missing(arr1) && this.missing(arr2)) { return true; } // if one is present, but other is missing, then then are different if (this.missing(arr1) || this.missing(arr2)) { return false; } if (arr1.length !== arr2.length) { return false; } for (var i = 0; i < arr1.length; i++) { if (arr1[i] !== arr2[i]) { return false; } } return true; }; Utils.getNameOfClass = function (TheClass) { var funcNameRegex = /function (.{1,})\(/; var funcAsString = TheClass.toString(); var results = (funcNameRegex).exec(funcAsString); return (results && results.length > 1) ? results[1] : ""; }; Utils.values = function (object) { var result = []; this.iterateObject(object, function (key, value) { result.push(value); }); return result; }; Utils.getValueUsingField = function (data, field, fieldContainsDots) { if (!field || !data) { return; } // if no '.', then it's not a deep value if (!fieldContainsDots) { return data[field]; } else { // 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++) { currentObject = currentObject[fields[i]]; if (this.missing(currentObject)) { return null; } } return currentObject; } }; Utils.getScrollLeft = function (element, rtl) { var scrollLeft = element.scrollLeft; if (rtl) { // Absolute value - for FF that reports RTL scrolls in negative numbers scrollLeft = Math.abs(scrollLeft); // Get Chrome and Safari to return the same value as well if (this.isBrowserSafari() || this.isBrowserChrome()) { scrollLeft = element.scrollWidth - element.clientWidth - scrollLeft; } } return scrollLeft; }; Utils.cleanNumber = function (value) { if (typeof value === 'string') { value = parseInt(value); } if (typeof value === 'number') { value = Math.floor(value); } else { value = null; } return value; }; Utils.setScrollLeft = function (element, value, rtl) { if (rtl) { // Chrome and Safari when doing RTL have the END position of the scroll as zero, not the start if (this.isBrowserSafari() || this.isBrowserChrome()) { value = element.scrollWidth - element.clientWidth - value; } // Firefox uses negative numbers when doing RTL scrolling if (this.isBrowserFirefox()) { value *= -1; } } element.scrollLeft = value; }; Utils.iterateNamedNodeMap = function (map, callback) { if (!map) { return; } for (var i = 0; i < map.length; i++) { var attr = map[i]; callback(attr.name, attr.value); } }; Utils.iterateObject = function (object, callback) { if (this.missing(object)) { return; } if (Array.isArray(object)) { object.forEach(function (value, index) { callback(index + '', value); }); } else { var keys = Object.keys(object); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = object[key]; callback(key, value); } } }; Utils.cloneObject = function (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; }; Utils.map = function (array, callback) { var result = []; for (var i = 0; i < array.length; i++) { var item = array[i]; var mappedItem = callback(item); result.push(mappedItem); } return result; }; Utils.mapObject = function (object, callback) { var result = []; Utils.iterateObject(object, function (key, value) { result.push(callback(value)); }); return result; }; Utils.forEach = function (array, callback) { if (!array) { return; } for (var i = 0; i < array.length; i++) { var value = array[i]; callback(value, i); } }; Utils.filter = function (array, callback) { var result = []; array.forEach(function (item) { if (callback(item)) { result.push(item); } }); return result; }; Utils.getAllKeysInObjects = function (objects) { var allValues = {}; objects.forEach(function (obj) { if (obj) { Object.keys(obj).forEach(function (key) { return allValues[key] = null; }); } }); return Object.keys(allValues); }; Utils.mergeDeep = function (dest, source) { if (this.exists(source)) { this.iterateObject(source, function (key, newValue) { var oldValue = dest[key]; if (oldValue === newValue) { return; } if (typeof oldValue === 'object' && typeof newValue === 'object') { Utils.mergeDeep(oldValue, newValue); } else { dest[key] = newValue; } }); } }; Utils.assign = function (object) { var _this = this; var sources = []; for (var _i = 1; _i < arguments.length; _i++) { sources[_i - 1] = arguments[_i]; } sources.forEach(function (source) { if (_this.exists(source)) { _this.iterateObject(source, function (key, value) { object[key] = value; }); } }); return object; }; Utils.parseYyyyMmDdToDate = function (yyyyMmDd, separator) { try { if (!yyyyMmDd) return null; if (yyyyMmDd.indexOf(separator) === -1) return null; var fields = yyyyMmDd.split(separator); if (fields.length != 3) return null; return new Date(Number(fields[0]), Number(fields[1]) - 1, Number(fields[2])); } catch (e) { return null; } }; Utils.serializeDateToYyyyMmDd = function (date, separator) { if (!date) return null; return date.getFullYear() + separator + Utils.pad(date.getMonth() + 1, 2) + separator + Utils.pad(date.getDate(), 2); }; Utils.pad = function (num, totalStringSize) { var asString = num + ""; while (asString.length < totalStringSize) asString = "0" + asString; return asString; }; Utils.pushAll = function (target, source) { if (this.missing(source) || this.missing(target)) { return; } source.forEach(function (func) { return target.push(func); }); }; Utils.createArrayOfNumbers = function (first, last) { var result = []; for (var i = first; i <= last; i++) { result.push(i); } return result; }; Utils.getFunctionParameters = function (func) { var fnStr = func.toString().replace(FUNCTION_STRIP_COMMENTS, ''); var result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(FUNCTION_ARGUMENT_NAMES); if (result === null) { return []; } else { return result; } }; Utils.find = function (collection, predicate, value) { if (collection === null || collection === undefined) { return null; } if (!Array.isArray(collection)) { var objToArray = this.values(collection); return this.find(objToArray, predicate, value); } var collectionAsArray = collection; var firstMatchingItem; 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; }; Utils.toStrings = function (array) { return this.map(array, function (item) { if (item === undefined || item === null || !item.toString) { return null; } else { return item.toString(); } }); }; Utils.iterateArray = function (array, callback) { for (var index = 0; index < array.length; index++) { var value = array[index]; callback(value, index); } }; //Returns true if it is a DOM node //taken from: http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object Utils.isNode = function (o) { return (typeof Node === "function" ? o instanceof Node : o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName === "string"); }; //Returns true if it is a DOM element //taken from: http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object Utils.isElement = function (o) { return (typeof HTMLElement === "function" ? o instanceof HTMLElement : o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string"); }; Utils.isNodeOrElement = function (o) { return this.isNode(o) || this.isElement(o); }; // makes a copy of a node list into a list Utils.copyNodeList = function (nodeList) { var childCount = nodeList ? nodeList.length : 0; var res = []; for (var i = 0; i < childCount; i++) { res.push(nodeList[i]); } return res; }; Utils.isEventFromPrintableCharacter = function (event) { var pressedChar = String.fromCharCode(event.charCode); // newline is an exception, as it counts as a printable character, but we don't // want to start editing when it is pressed. without this check, if user is in chrome // and editing a cell, and they press ctrl+enter, the cell stops editing, and then // starts editing again with a blank value (two 'key down' events are fired). to // test this, remove the line below, edit a cell in chrome and hit ctrl+enter while editing. // https://ag-grid.atlassian.net/browse/AG-605 if (this.isKeyPressed(event, constants_1.Constants.KEY_NEW_LINE)) { return false; } if (exports._.exists(event.key)) { // modern browser will implement key, so we return if key is length 1, eg if it is 'a' for the // a key, or '2' for the '2' key. non-printable characters have names, eg 'Enter' or 'Backspace'. var printableCharacter = event.key.length === 1; // IE11 & Edge treat the numpad del key differently - with numlock on we get "Del" for key, // so this addition checks if its IE11/Edge and handles that specific case the same was as all other browers var numpadDelWithNumlockOnForEdgeOrIe = Utils.isNumpadDelWithNumlockOnForEdgeOrIe(event); return printableCharacter || numpadDelWithNumlockOnForEdgeOrIe; } else { // otherwise, for older browsers, we test against a list of characters, which doesn't include // accents for non-English, but don't care much, as most users are on modern browsers return Utils.PRINTABLE_CHARACTERS.indexOf(pressedChar) >= 0; } }; //adds all type of change listeners to an element, intended to be a text field Utils.addChangeListener = function (element, listener) { element.addEventListener("changed", listener); element.addEventListener("paste", listener); element.addEventListener("input", listener); // IE doesn't fire changed for special keys (eg delete, backspace), so need to // listen for this further ones element.addEventListener("keydown", listener); element.addEventListener("keyup", listener); }; //if value is undefined, null or blank, returns null, otherwise returns the value Utils.makeNull = function (value) { var valueNoType = value; if (value === null || value === undefined || valueNoType === "") { return null; } else { return value; } }; Utils.missing = function (value) { return !this.exists(value); }; Utils.missingOrEmpty = function (value) { return this.missing(value) || value.length === 0; }; Utils.missingOrEmptyObject = function (value) { return this.missing(value) || Object.keys(value).length === 0; }; Utils.exists = function (value) { if (value === null || value === undefined || value === '') { return false; } else { return true; } }; Utils.firstExistingValue = function () { 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 (exports._.exists(value)) return value; } return null; }; Utils.anyExists = function (values) { if (values) { for (var i = 0; i < values.length; i++) { if (this.exists(values[i])) { return true; } } } return false; }; Utils.existsAndNotEmpty = function (value) { return this.exists(value) && value.length > 0; }; Utils.removeAllChildren = function (node) { if (node) { while (node.hasChildNodes()) { node.removeChild(node.lastChild); } } }; Utils.removeElement = function (parent, cssSelector) { this.removeFromParent(parent.querySelector(cssSelector)); }; Utils.removeFromParent = function (node) { if (node && node.parentNode) { node.parentNode.removeChild(node); } }; Utils.isVisible = function (element) { return (element.offsetParent !== null); }; /** * loads the template and returns it as an element. makes up for no simple way in * the dom api to load html directly, eg we cannot do this: document.createElement(template) */ Utils.loadTemplate = function (template) { var tempDiv = document.createElement("div"); tempDiv.innerHTML = template; return tempDiv.firstChild; }; Utils.appendHtml = function (eContainer, htmlTemplate) { if (eContainer.lastChild) { // https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML // we put the items at the start, so new items appear underneath old items, // so when expanding/collapsing groups, the new rows don't go on top of the // rows below that are moving our of the way eContainer.insertAdjacentHTML('afterbegin', htmlTemplate); } else { eContainer.innerHTML = htmlTemplate; } }; Utils.addOrRemoveCssClass = function (element, className, addOrRemove) { if (addOrRemove) { this.addCssClass(element, className); } else { this.removeCssClass(element, className); } }; Utils.callIfPresent = function (func) { if (func) { func(); } }; Utils.addCssClass = function (element, className) { var _this = this; if (!className || className.length === 0) { return; } if (className.indexOf(' ') >= 0) { className.split(' ').forEach(function (value) { return _this.addCssClass(element, value); }); return; } if (element.classList) { if (!element.classList.contains(className)) { element.classList.add(className); } } else { if (element.className && element.className.length > 0) { var cssClasses = element.className.split(' '); if (cssClasses.indexOf(className) < 0) { cssClasses.push(className); element.className = cssClasses.join(' '); } } else { element.className = className; } } }; Utils.containsClass = function (element, className) { if (element.classList) { // for modern browsers return element.classList.contains(className); } else if (element.className) { // for older browsers, check against the string of class names // if only one class, can check for exact match var onlyClass = element.className === className; // if many classes, check for class name, we have to pad with ' ' to stop other // class names that are a substring of this class var contains = element.className.indexOf(' ' + className + ' ') >= 0; // the padding above then breaks when it's the first or last class names var startsWithClass = element.className.indexOf(className + ' ') === 0; var endsWithClass = element.className.lastIndexOf(' ' + className) === (element.className.length - className.length - 1); return onlyClass || contains || startsWithClass || endsWithClass; } else { // if item is not a node return false; } }; Utils.getElementAttribute = function (element, attributeName) { if (element.attributes) { if (element.attributes[attributeName]) { var attribute = element.attributes[attributeName]; return attribute.value; } else { return null; } } else { return null; } }; Utils.offsetHeight = function (element) { return element && element.clientHeight ? element.clientHeight : 0; }; Utils.offsetWidth = function (element) { return element && element.clientWidth ? element.clientWidth : 0; }; Utils.sortNumberArray = function (numberArray) { numberArray.sort(function (a, b) { return a - b; }); }; Utils.removeCssClass = function (element, className) { if (element.classList) { if (element.classList.contains(className)) { element.classList.remove(className); } } else { if (element.className && element.className.length > 0) { var cssClasses = element.className.split(' '); if (cssClasses.indexOf(className) >= 0) { // remove all instances of the item, not just the first, in case it's in more than once while (cssClasses.indexOf(className) >= 0) { cssClasses.splice(cssClasses.indexOf(className), 1); } element.className = cssClasses.join(' '); } } } }; Utils.removeRepeatsFromArray = function (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); } } }; Utils.removeFromArray = function (array, object) { if (array.indexOf(object) >= 0) { array.splice(array.indexOf(object), 1); } }; Utils.removeAllFromArray = function (array, toRemove) { toRemove.forEach(function (item) { if (array.indexOf(item) >= 0) { array.splice(array.indexOf(item), 1); } }); }; Utils.insertIntoArray = function (array, object, toIndex) { array.splice(toIndex, 0, object); }; Utils.insertArrayIntoArray = function (dest, src, toIndex) { if (this.missing(dest) || this.missing(src)) { 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]; this.insertIntoArray(dest, item, toIndex); } }; Utils.moveInArray = function (array, objectsToMove, toIndex) { var _this = this; // first take out it items from the array objectsToMove.forEach(function (obj) { _this.removeFromArray(array, obj); }); // 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 objectsToMove.slice().reverse().forEach(function (obj) { _this.insertIntoArray(array, obj, toIndex); }); }; Utils.defaultComparator = function (valueA, valueB, accentedCompare) { if (accentedCompare === void 0) { accentedCompare = false; } var valueAMissing = valueA === null || valueA === undefined; var valueBMissing = valueB === null || valueB === undefined; // 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; } if (typeof valueA === "string") { if (!accentedCompare) { return doQuickCompare(valueA, valueB); } else { 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); } } } if (valueA < valueB) { return -1; } else if (valueA > valueB) { return 1; } else { return 0; } function doQuickCompare(a, b) { return (a > b ? 1 : (a < b ? -1 : 0)); } }; Utils.compareArrays = function (array1, array2) { if (this.missing(array1) && this.missing(array2)) { return true; } if (this.missing(array1) || this.missing(array2)) { return false; } if (array1.length !== array2.length) { return false; } for (var i = 0; i < array1.length; i++) { if (array1[i] !== array2[i]) { return false; } } return true; }; Utils.ensureDomOrder = function (eContainer, eChild, eChildBefore) { // if already in right order, do nothing if (eChildBefore && eChildBefore.nextSibling === eChild) { return; } if (eChildBefore) { if (eChildBefore.nextSibling) { // insert between the eRowBefore and the row after it eContainer.insertBefore(eChild, eChildBefore.nextSibling); } else { // if nextSibling is missing, means other row is at end, so just append new row at the end eContainer.appendChild(eChild); } } else { // otherwise put at start if (eContainer.firstChild) { // insert it at the first location eContainer.insertBefore(eChild, eContainer.firstChild); } } }; Utils.insertWithDomOrder = function (eContainer, eChild, eChildBefore) { if (eChildBefore) { if (eChildBefore.nextSibling) { // insert between the eRowBefore and the row after it eContainer.insertBefore(eChild, eChildBefore.nextSibling); } else { // if nextSibling is missing, means other row is at end, so just append new row at the end eContainer.appendChild(eChild); } } else { if (eContainer.firstChild) { // insert it at the first location eContainer.insertBefore(eChild, eContainer.firstChild); } else { // otherwise eContainer is empty, so just append it eContainer.appendChild(eChild); } } }; Utils.insertTemplateWithDomOrder = function (eContainer, htmlTemplate, eChildBefore) { var res; if (eChildBefore) { // if previous element exists, just slot in after the previous element eChildBefore.insertAdjacentHTML('afterend', htmlTemplate); res = eChildBefore.nextSibling; } else { if (eContainer.firstChild) { // insert it at the first location eContainer.insertAdjacentHTML('afterbegin', htmlTemplate); } else { // otherwise eContainer is empty, so just append it eContainer.innerHTML = htmlTemplate; } res = eContainer.firstChild; } return res; }; Utils.every = function (items, callback) { if (!items || items.length === 0) { return true; } for (var i = 0; i < items.length; i++) { if (!callback(items[i])) { return false; } } return true; }; Utils.toStringOrNull = function (value) { if (this.exists(value) && value.toString) { return value.toString(); } else { return null; } }; Utils.formatWidth = function (width) { if (typeof width === "number") { return width + "px"; } else { return width; } }; Utils.formatNumberTwoDecimalPlacesAndCommas = function (value) { if (typeof value !== 'number') { return ''; } // took this from: http://blog.tompawlak.org/number-currency-formatting-javascript return (Math.round(value * 100) / 100).toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,"); }; // the native method number.toLocaleString(undefined, {minimumFractionDigits: 0}) puts in decimal places in IE, // so we use this method instead Utils.formatNumberCommas = function (value) { if (typeof value !== 'number') { return ''; } // took this from: http://blog.tompawlak.org/number-currency-formatting-javascript return value.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,"); }; Utils.prependDC = function (parent, documentFragment) { if (this.exists(parent.firstChild)) { parent.insertBefore(documentFragment, parent.firstChild); } else { parent.appendChild(documentFragment); } }; /** * If icon provided, use this (either a string, or a function callback). * if not, then use the default icon from the theme */ Utils.createIcon = function (iconName, gridOptionsWrapper, column) { var iconContents = this.createIconNoSpan(iconName, gridOptionsWrapper, column); if (iconContents.className.indexOf('ag-icon') > -1) { return iconContents; } else { var eResult = document.createElement('span'); eResult.appendChild(iconContents); return eResult; } }; Utils.createIconNoSpan = function (iconName, gridOptionsWrapper, column) { var userProvidedIcon; // check col for icon first if (column && column.getColDef().icons) { userProvidedIcon = column.getColDef().icons[iconName]; } // it not in col, try grid options if (!userProvidedIcon && gridOptionsWrapper.getIcons()) { userProvidedIcon = gridOptionsWrapper.getIcons()[iconName]; } // now if user provided, use it if (userProvidedIcon) { var rendererResult = void 0; if (typeof userProvidedIcon === 'function') { rendererResult = userProvidedIcon(); } else if (typeof userProvidedIcon === 'string') { rendererResult = userProvidedIcon; } else { throw 'icon from grid options needs to be a string or a function'; } if (typeof rendererResult === 'string') { return this.loadTemplate(rendererResult); } else if (this.isNodeOrElement(rendererResult)) { return rendererResult; } else { throw 'iconRenderer should return back a string or a dom object'; } } else { var span = document.createElement(