UNPKG

ag-grid-community

Version:

Advanced Data Grid / Data Table supporting Javascript / Typescript / React / Angular / Vue

1,578 lines (1,564 loc) 2.28 MB
// packages/ag-grid-community/src/agStack/utils/array.ts function _last(arr) { if (!arr?.length) { return; } return arr[arr.length - 1]; } function _areEqual(a, b, comparator) { if (a === b) { return true; } if (!a || !b) { return a == null && b == null; } const len = a.length; if (len !== b.length) { return false; } for (let i = 0; i < len; i++) { if (a[i] !== b[i] && !comparator?.(a[i], b[i])) { return false; } } return true; } function _forAll(array, callback) { if (!array) { return; } for (const value of array) { if (callback(value)) { return true; } } } function _removeFromArray(array, object) { const index = array.indexOf(object); if (index >= 0) { array.splice(index, 1); } } function _removeAllFromArray(array, elementsToRemove) { let i = 0; let j = 0; for (; i < array.length; i++) { if (!elementsToRemove.includes(array[i])) { array[j] = array[i]; j++; } } while (j < array.length) { array.pop(); } } function _moveInArray(array, objectsToMove, toIndex) { for (let i = 0; i < objectsToMove.length; i++) { _removeFromArray(array, objectsToMove[i]); } for (let i = objectsToMove.length - 1; i >= 0; i--) { array.splice(toIndex, 0, objectsToMove[i]); } } function _flatten(arrays) { return [].concat.apply([], arrays); } // packages/ag-grid-community/src/agStack/utils/generic.ts var _makeNull = (value) => { if (value == null || value === "") { return null; } return value; }; function _exists(value) { return value != null && value !== ""; } function _missing(value) { return !_exists(value); } var _toStringOrNull = (value) => { return value != null && typeof value.toString === "function" ? value.toString() : null; }; var _jsonEquals = (val1, val2) => { const val1Json = val1 ? JSON.stringify(val1) : null; const val2Json = val2 ? JSON.stringify(val2) : null; return val1Json === val2Json; }; var _defaultComparator = (valueA, valueB, accentedCompare = false) => { if (valueA == null) { return valueB == null ? 0 : -1; } if (valueB == null) { return 1; } if (typeof valueA === "object" && valueA.toNumber) { valueA = valueA.toNumber(); } if (typeof valueB === "object" && valueB.toNumber) { valueB = valueB.toNumber(); } if (!accentedCompare || typeof valueA !== "string") { if (valueA > valueB) { return 1; } if (valueA < valueB) { return -1; } return 0; } return valueA.localeCompare(valueB); }; // packages/ag-grid-community/src/agStack/events/localEventService.ts var LocalEventService = class { constructor() { this.allSyncListeners = /* @__PURE__ */ new Map(); this.allAsyncListeners = /* @__PURE__ */ new Map(); this.globalSyncListeners = /* @__PURE__ */ new Set(); this.globalAsyncListeners = /* @__PURE__ */ 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 = {}; } setFrameworkOverrides(frameworkOverrides) { this.frameworkOverrides = frameworkOverrides; } getListeners(eventType, async, autoCreateListenerCollection) { const listenerMap = async ? this.allAsyncListeners : this.allSyncListeners; let listeners = listenerMap.get(eventType); if (!listeners && autoCreateListenerCollection) { listeners = /* @__PURE__ */ new Set(); listenerMap.set(eventType, listeners); } return listeners; } noRegisteredListenersExist() { return this.allSyncListeners.size === 0 && this.allAsyncListeners.size === 0 && this.globalSyncListeners.size === 0 && this.globalAsyncListeners.size === 0; } addEventListener(eventType, listener, async = false) { this.getListeners(eventType, async, true).add(listener); } removeEventListener(eventType, listener, async = false) { const listeners = this.getListeners(eventType, async, false); if (!listeners) { return; } listeners.delete(listener); if (listeners.size === 0) { (async ? this.allAsyncListeners : this.allSyncListeners).delete(eventType); } } addGlobalListener(listener, async = false) { this.getGlobalListeners(async).add(listener); } removeGlobalListener(listener, async = false) { this.getGlobalListeners(async).delete(listener); } dispatchEvent(event) { this.dispatchToListeners(event, true); this.dispatchToListeners(event, false); this.firedEvents[event.type] = true; } dispatchEventOnce(event) { if (!this.firedEvents[event.type]) { this.dispatchEvent(event); } } dispatchToListeners(event, async) { const eventType = event.type; if (async && "event" in event) { const browserEvent = event.event; if (browserEvent instanceof Event) { event.eventPath = browserEvent.composedPath(); } } const { frameworkOverrides } = this; const runCallback = (func) => { const callback = frameworkOverrides ? () => frameworkOverrides.wrapIncoming(func) : func; if (async) { this.dispatchAsync(callback); } else { callback(); } }; const originalListeners = this.getListeners(eventType, async, false); if ((originalListeners?.size ?? 0) > 0) { const listeners = new Set(originalListeners); for (const listener of listeners) { if (!originalListeners?.has(listener)) { continue; } runCallback(() => listener(event)); } } const globalListenersSrc = this.getGlobalListeners(async); if (globalListenersSrc.size > 0) { const globalListeners = new Set(globalListenersSrc); for (const listener of globalListeners) { runCallback(() => listener(eventType, event)); } } } getGlobalListeners(async) { return async ? this.globalAsyncListeners : this.globalSyncListeners; } // 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. dispatchAsync(func) { this.asyncFunctionsQueue.push(func); if (!this.scheduled) { const flush = () => { window.setTimeout(this.flushAsyncQueue.bind(this), 0); }; const frameworkOverrides = this.frameworkOverrides; if (frameworkOverrides) { frameworkOverrides.wrapIncoming(flush); } else { flush(); } this.scheduled = true; } } // this happens in the next VM turn only, and empties the queue of events flushAsyncQueue() { this.scheduled = false; const queueCopy = this.asyncFunctionsQueue.slice(); this.asyncFunctionsQueue = []; for (const func of queueCopy) { func(); } } }; // packages/ag-grid-community/src/agStack/utils/string.ts var reUnescapedHtml = /[&<>"']/g; var HTML_ESCAPES = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }; function _toString(toEscape) { return toEscape?.toString().toString() ?? null; } function _escapeString(toEscape) { return _toString(toEscape)?.replace(reUnescapedHtml, (chr) => HTML_ESCAPES[chr]) ?? null; } function _isExpressionString(value) { return typeof value === "string" && value.startsWith("=") && value.length > 1; } function _camelCaseToHumanText(camelCase) { if (!camelCase || camelCase == null) { return null; } const rex = /([a-z])([A-Z])/g; const rexCaps = /([A-Z]+)([A-Z])([a-z])/g; const words = camelCase.replace(rex, "$1 $2").replace(rexCaps, "$1 $2$3").replace(/\./g, " ").split(" "); return words.map((word) => word.substring(0, 1).toUpperCase() + (word.length > 1 ? word.substring(1, word.length) : "")).join(" "); } // packages/ag-grid-community/src/agStack/utils/document.ts function _getRootNode(beans) { return beans.eRootDiv.getRootNode(); } function _getActiveDomElement(beans) { return _getRootNode(beans).activeElement; } function _getDocument(beans) { const { gos, eRootDiv } = beans; let result = null; const optionsGetDocument = gos.get("getDocument"); if (optionsGetDocument && _exists(optionsGetDocument)) { result = optionsGetDocument(); } else if (eRootDiv) { result = eRootDiv.ownerDocument; } if (result && _exists(result)) { return result; } return document; } function _isNothingFocused(beans) { const activeEl = _getActiveDomElement(beans); return activeEl === null || activeEl === _getDocument(beans).body; } function _getWindow(beans) { const eDocument = _getDocument(beans); return eDocument.defaultView || window; } function _getPageBody(beans) { let rootNode = null; let targetEl = null; try { rootNode = _getDocument(beans).fullscreenElement; } catch (e) { } finally { if (!rootNode) { rootNode = _getRootNode(beans); } const body = rootNode.querySelector("body"); if (body) { targetEl = body; } else if (rootNode instanceof ShadowRoot) { targetEl = rootNode; } else if (rootNode instanceof Document) { targetEl = rootNode?.documentElement; } else { targetEl = rootNode; } } return targetEl; } function _getBodyWidth(beans) { const body = _getPageBody(beans); return body?.clientWidth ?? (window.innerWidth || -1); } function _getBodyHeight(beans) { const body = _getPageBody(beans); return body?.clientHeight ?? (window.innerHeight || -1); } // packages/ag-grid-community/src/agStack/utils/aria.ts function _toggleAriaAttribute(element, attribute, value) { if (value == null || typeof value === "string" && value == "") { _removeAriaAttribute(element, attribute); } else { _setAriaAttribute(element, attribute, value); } } function _setAriaAttribute(element, attribute, value) { element.setAttribute(_ariaAttributeName(attribute), value.toString()); } function _removeAriaAttribute(element, attribute) { element.removeAttribute(_ariaAttributeName(attribute)); } function _ariaAttributeName(attribute) { return `aria-${attribute}`; } function _setAriaRole(element, role) { if (role) { element.setAttribute("role", role); } else { element.removeAttribute("role"); } } function _getAriaSortState(directionOrDef) { const direction = directionOrDef?.direction; if (direction === "asc") { return "ascending"; } else if (direction === "desc") { return "descending"; } else if (direction === "mixed") { return "other"; } return "none"; } function _getAriaPosInSet(element) { return Number.parseInt(element.getAttribute("aria-posinset"), 10); } function _getAriaLabel(element) { return element.getAttribute("aria-label"); } function _setAriaLabel(element, label) { _toggleAriaAttribute(element, "label", label); } function _setAriaLabelledBy(element, labelledBy) { _toggleAriaAttribute(element, "labelledby", labelledBy); } function _setAriaDescribedBy(element, describedby) { _toggleAriaAttribute(element, "describedby", describedby); } function _setAriaLive(element, live) { _toggleAriaAttribute(element, "live", live); } function _setAriaAtomic(element, atomic) { _toggleAriaAttribute(element, "atomic", atomic); } function _setAriaRelevant(element, relevant) { _toggleAriaAttribute(element, "relevant", relevant); } function _setAriaInvalid(element, invalid) { _toggleAriaAttribute(element, "invalid", invalid); } function _setAriaLevel(element, level) { _toggleAriaAttribute(element, "level", level); } function _setAriaDisabled(element, disabled) { _toggleAriaAttribute(element, "disabled", disabled); } function _setAriaHidden(element, hidden) { _toggleAriaAttribute(element, "hidden", hidden); } function _setAriaActiveDescendant(element, descendantId) { _toggleAriaAttribute(element, "activedescendant", descendantId); } function _setAriaExpanded(element, expanded) { _setAriaAttribute(element, "expanded", expanded); } function _removeAriaExpanded(element) { _removeAriaAttribute(element, "expanded"); } function _setAriaSetSize(element, setsize) { _setAriaAttribute(element, "setsize", setsize); } function _setAriaPosInSet(element, position) { _setAriaAttribute(element, "posinset", position); } function _setAriaMultiSelectable(element, multiSelectable) { _setAriaAttribute(element, "multiselectable", multiSelectable); } function _setAriaRowCount(element, rowCount) { _setAriaAttribute(element, "rowcount", rowCount); } function _setAriaRowIndex(element, rowIndex) { _setAriaAttribute(element, "rowindex", rowIndex); } function _setAriaRowSpan(element, spanCount) { _setAriaAttribute(element, "rowspan", spanCount); } function _setAriaColCount(element, colCount) { _setAriaAttribute(element, "colcount", colCount); } function _setAriaColIndex(element, colIndex) { _setAriaAttribute(element, "colindex", colIndex); } function _setAriaColSpan(element, colSpan) { _setAriaAttribute(element, "colspan", colSpan); } function _setAriaSort(element, sort) { _setAriaAttribute(element, "sort", sort); } function _removeAriaSort(element) { _removeAriaAttribute(element, "sort"); } function _setAriaSelected(element, selected) { _toggleAriaAttribute(element, "selected", selected); } function _setAriaChecked(element, checked) { _setAriaAttribute(element, "checked", checked === void 0 ? "mixed" : checked); } function _setAriaControls(controllerElement, controlledId) { _toggleAriaAttribute(controllerElement, "controls", controlledId); } function _setAriaControlsAndLabel(controllerElement, controlledElement) { _setAriaControls(controllerElement, controlledElement.id); _setAriaLabelledBy(controlledElement, controllerElement.id); } function _setAriaOwns(ownerElement, ownedId) { _toggleAriaAttribute(ownerElement, "owns", ownedId); } function _setAriaHasPopup(element, hasPopup) { _toggleAriaAttribute(element, "haspopup", hasPopup === false ? null : hasPopup); } function _getAriaCheckboxStateName(translate, state) { return state === void 0 ? translate("ariaIndeterminate", "indeterminate") : state === true ? translate("ariaChecked", "checked") : translate("ariaUnchecked", "unchecked"); } function _setAriaOrientation(element, orientation) { if (orientation) { _setAriaAttribute(element, "orientation", orientation); } else { _removeAriaAttribute(element, "orientation"); } } // packages/ag-grid-community/src/agStack/utils/dom.ts function _radioCssClass(element, elementClass, otherElementClass) { const parent = element.parentElement; let sibling = parent && parent.firstChild; while (sibling) { if (elementClass) { sibling.classList.toggle(elementClass, sibling === element); } if (otherElementClass) { sibling.classList.toggle(otherElementClass, sibling !== element); } sibling = sibling.nextSibling; } } var FOCUSABLE_SELECTOR = "[tabindex], input, select, button, textarea, [href]"; var FOCUSABLE_EXCLUDE = "[disabled], .ag-disabled:not(.ag-button), .ag-disabled *"; function _isFocusableFormField(element) { if (!element) { return false; } const isFocusable = element.matches("input, select, button, textarea"); if (!isFocusable) { return false; } const isNotFocusable = element.matches(FOCUSABLE_EXCLUDE); if (!isNotFocusable) { return false; } return _isVisible(element); } function _setDisplayed(element, displayed, options = {}) { const { skipAriaHidden } = options; element.classList.toggle("ag-hidden", !displayed); if (!skipAriaHidden) { _setAriaHidden(element, !displayed); } } function _setVisible(element, visible, options = {}) { const { skipAriaHidden } = options; element.classList.toggle("ag-invisible", !visible); if (!skipAriaHidden) { _setAriaHidden(element, !visible); } } function _setDisabled(element, disabled) { const attributeName = "disabled"; const addOrRemoveDisabledAttribute = disabled ? (e) => e.setAttribute(attributeName, "") : (e) => e.removeAttribute(attributeName); addOrRemoveDisabledAttribute(element); const inputs = element.querySelectorAll("input") ?? []; for (const input of inputs) { addOrRemoveDisabledAttribute(input); } } function _isElementChildOfClass(element, cls, maxNest) { let counter = 0; while (element) { if (element.classList.contains(cls)) { return true; } element = element.parentElement; if (typeof maxNest == "number") { if (++counter > maxNest) { break; } } else if (element === maxNest) { break; } } return false; } function _getElementSize(el) { const { height, width, borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth, paddingTop, paddingRight, paddingBottom, paddingLeft, marginTop, marginRight, marginBottom, marginLeft, boxSizing } = window.getComputedStyle(el); const pf = Number.parseFloat; return { height: pf(height || "0"), width: pf(width || "0"), borderTopWidth: pf(borderTopWidth || "0"), borderRightWidth: pf(borderRightWidth || "0"), borderBottomWidth: pf(borderBottomWidth || "0"), borderLeftWidth: pf(borderLeftWidth || "0"), paddingTop: pf(paddingTop || "0"), paddingRight: pf(paddingRight || "0"), paddingBottom: pf(paddingBottom || "0"), paddingLeft: pf(paddingLeft || "0"), marginTop: pf(marginTop || "0"), marginRight: pf(marginRight || "0"), marginBottom: pf(marginBottom || "0"), marginLeft: pf(marginLeft || "0"), boxSizing }; } function _getInnerHeight(el) { const size = _getElementSize(el); if (size.boxSizing === "border-box") { return size.height - size.paddingTop - size.paddingBottom - size.borderTopWidth - size.borderBottomWidth; } return size.height; } function _getInnerWidth(el) { const size = _getElementSize(el); if (size.boxSizing === "border-box") { return size.width - size.paddingLeft - size.paddingRight - size.borderLeftWidth - size.borderRightWidth; } return size.width; } function _getAbsoluteHeight(el) { const { height, marginBottom, marginTop } = _getElementSize(el); return Math.floor(height + marginBottom + marginTop); } function _getAbsoluteWidth(el) { const { width, marginLeft, marginRight } = _getElementSize(el); return Math.floor(width + marginLeft + marginRight); } function _getElementRectWithOffset(el) { const offsetElementRect = el.getBoundingClientRect(); const { borderTopWidth, borderLeftWidth, borderRightWidth, borderBottomWidth } = _getElementSize(el); return { top: offsetElementRect.top + (borderTopWidth || 0), left: offsetElementRect.left + (borderLeftWidth || 0), right: offsetElementRect.right + (borderRightWidth || 0), bottom: offsetElementRect.bottom + (borderBottomWidth || 0) }; } function _getScrollLeft(element, rtl) { let scrollLeft = element.scrollLeft; if (rtl) { scrollLeft = Math.abs(scrollLeft); } return scrollLeft; } function _setScrollLeft(element, value, rtl) { if (rtl) { value *= -1; } element.scrollLeft = value; } function _clearElement(el) { while (el?.firstChild) { el.firstChild.remove(); } } function _removeFromParent(node) { if (node?.parentNode) { node.remove(); } } function _isInDOM(element) { return !!element.offsetParent; } function _isVisible(element) { if (element.checkVisibility) { return element.checkVisibility({ checkVisibilityCSS: true }); } const isHidden = !_isInDOM(element) || window.getComputedStyle(element).visibility !== "visible"; return !isHidden; } function _loadTemplate(template) { const tempDiv = document.createElement("div"); tempDiv.innerHTML = (template || "").trim(); return tempDiv.firstChild; } function _ensureDomOrder(eContainer, eChild, eChildBefore) { if (eChildBefore && eChildBefore.nextSibling === eChild) { return; } if (!eContainer.firstChild) { eContainer.appendChild(eChild); } else if (eChildBefore) { if (eChildBefore.nextSibling) { eContainer.insertBefore(eChild, eChildBefore.nextSibling); } else { eContainer.appendChild(eChild); } } else if (eContainer.firstChild && eContainer.firstChild !== eChild) { eContainer.prepend(eChild); } } function _setDomChildOrder(eContainer, orderedChildren) { for (let i = 0; i < orderedChildren.length; i++) { const correctCellAtIndex = orderedChildren[i]; const actualCellAtIndex = eContainer.children[i]; if (actualCellAtIndex !== correctCellAtIndex) { eContainer.insertBefore(correctCellAtIndex, actualCellAtIndex); } } } function _camelCaseToHyphenated(camelCase) { return camelCase.replace(/[A-Z]/g, (s) => `-${s.toLocaleLowerCase()}`); } function _addStylesToElement(eElement, styles) { if (!styles) { return; } for (const key of Object.keys(styles)) { const value = styles[key]; if (!key?.length || value == null) { continue; } const parsedKey = _camelCaseToHyphenated(key); const valueAsString = value.toString(); const parsedValue = valueAsString.replace(/\s*!important/g, ""); const priority = parsedValue.length != valueAsString.length ? "important" : void 0; eElement.style.setProperty(parsedKey, parsedValue, priority); } } function _isElementOverflowingCallback(getElement2) { return () => { const element = getElement2(); if (!element) { return true; } return _isHorizontalScrollShowing(element) || _isVerticalScrollShowing(element); }; } function _isHorizontalScrollShowing(element) { return element.clientWidth < element.scrollWidth; } function _isVerticalScrollShowing(element) { return element.clientHeight < element.scrollHeight; } function _setElementWidth(element, width) { if (width === "flex") { element.style.removeProperty("width"); element.style.removeProperty("minWidth"); element.style.removeProperty("maxWidth"); element.style.flex = "1 1 auto"; } else { _setFixedWidth(element, width); } } function _setFixedWidth(element, width) { width = _formatSize(width); element.style.width = width; element.style.maxWidth = width; element.style.minWidth = width; } function _setFixedHeight(element, height) { height = _formatSize(height); element.style.height = height; element.style.maxHeight = height; element.style.minHeight = height; } function _formatSize(size) { return typeof size === "number" ? `${size}px` : size; } function _isNodeOrElement(o) { return o instanceof Node || o instanceof HTMLElement; } function _addOrRemoveAttribute(element, name, value) { if (value == null || value === "") { element.removeAttribute(name); } else { element.setAttribute(name, value.toString()); } } function _placeCaretAtEnd(beans, contentElement) { if (!contentElement.isContentEditable) { return; } const selection = _getWindow(beans).getSelection(); if (!selection) { return; } const range = _getDocument(beans).createRange(); range.selectNodeContents(contentElement); range.collapse(false); selection.removeAllRanges(); selection.addRange(range); } function _observeResize(beans, element, callback) { const win = _getWindow(beans); const ResizeObserverImpl = win.ResizeObserver; const resizeObserver = ResizeObserverImpl ? new ResizeObserverImpl(callback) : null; resizeObserver?.observe(element); return () => resizeObserver?.disconnect(); } function _requestAnimationFrame(beans, callback) { const win = _getWindow(beans); if (win.requestAnimationFrame) { win.requestAnimationFrame(callback); } else if (win.webkitRequestAnimationFrame) { win.webkitRequestAnimationFrame(callback); } else { win.setTimeout(callback, 0); } } var DataRefAttribute = "data-ref"; var whitespaceNode; function getWhitespaceNode() { whitespaceNode ?? (whitespaceNode = document.createTextNode(" ")); return whitespaceNode.cloneNode(); } function _createAgElement(params) { const { attrs, children, cls, ref, role, tag } = params; const element = document.createElement(tag); if (cls) { element.className = cls; } if (ref) { element.setAttribute(DataRefAttribute, ref); } if (role) { element.setAttribute("role", role); } if (attrs) { for (const key of Object.keys(attrs)) { element.setAttribute(key, attrs[key]); } } if (children) { if (typeof children === "string") { element.textContent = children; } else { let addFirstWhitespace = true; for (const child of children) { if (child) { if (typeof child === "string") { element.appendChild(document.createTextNode(child)); addFirstWhitespace = false; } else if (typeof child === "function") { element.appendChild(child()); } else { if (addFirstWhitespace) { element.appendChild(getWhitespaceNode()); addFirstWhitespace = false; } element.append(_createAgElement(child)); element.appendChild(getWhitespaceNode()); } } } } } return element; } // packages/ag-grid-community/src/agStack/utils/event.ts var PASSIVE_EVENTS = ["touchstart", "touchend", "touchmove", "touchcancel", "scroll"]; var NON_PASSIVE_EVENTS = ["wheel"]; var supports = {}; var _isEventSupported = /* @__PURE__ */ (() => { const tags = { select: "input", change: "input", submit: "form", reset: "form", error: "img", load: "img", abort: "img" }; const eventChecker = (eventName) => { if (typeof supports[eventName] === "boolean") { return supports[eventName]; } const el = document.createElement(tags[eventName] || "div"); eventName = "on" + eventName; return supports[eventName] = eventName in el; }; return eventChecker; })(); function _isElementInEventPath(element, event) { if (!event || !element) { return false; } return _getEventPath(event).indexOf(element) >= 0; } function _createEventPath(event) { const res = []; let pointer = event.target; while (pointer) { res.push(pointer); pointer = pointer.parentElement; } return res; } function _getEventPath(event) { const eventNoType = event; if (eventNoType.path) { return eventNoType.path; } if (eventNoType.composedPath) { return eventNoType.composedPath(); } return _createEventPath(eventNoType); } function _addSafePassiveEventListener(eElement, event, listener) { const passive = getPassiveStateForEvent(event); let options; if (passive != null) { options = { passive }; } eElement.addEventListener(event, listener, options); } var getPassiveStateForEvent = (event) => { const isPassive = PASSIVE_EVENTS.includes(event); const isNonPassive = NON_PASSIVE_EVENTS.includes(event); if (isPassive) { return true; } if (isNonPassive) { return false; } }; function _areEventsNear(e1, e2, pixelCount) { if (pixelCount === 0) { return false; } const diffX = Math.abs(e1.clientX - e2.clientX); const diffY = Math.abs(e1.clientY - e2.clientY); return Math.max(diffX, diffY) <= pixelCount; } var _getFirstActiveTouch = (touch, touchList) => { const identifier = touch.identifier; for (let i = 0, len = touchList.length; i < len; ++i) { const item = touchList[i]; if (item.identifier === identifier) { return item; } } return null; }; function _isEventFromThisInstance(beans, event) { return beans.gos.isElementInThisInstance(event.target); } function _anchorElementToMouseMoveEvent(element, mouseMoveEvent, beans) { const eRect = element.getBoundingClientRect(); const height = eRect.height; const browserWidth = _getBodyWidth(beans) - 2; const browserHeight = _getBodyHeight(beans) - 2; const offsetParent = element.offsetParent; if (!offsetParent) { return; } const offsetParentSize = _getElementRectWithOffset(element.offsetParent); const { clientY, clientX } = mouseMoveEvent; let top = clientY - offsetParentSize.top - height / 2; let left = clientX - offsetParentSize.left - 10; const eDocument = _getDocument(beans); const win = eDocument.defaultView || window; const windowScrollY = win.pageYOffset || eDocument.documentElement.scrollTop; const windowScrollX = win.pageXOffset || eDocument.documentElement.scrollLeft; if (browserWidth > 0 && left + element.clientWidth > browserWidth + windowScrollX) { left = browserWidth + windowScrollX - element.clientWidth; } if (left < 0) { left = 0; } if (browserHeight > 0 && top + element.clientHeight > browserHeight + windowScrollY) { top = browserHeight + windowScrollY - element.clientHeight; } if (top < 0) { top = 0; } element.style.left = `${left}px`; element.style.top = `${top}px`; } var addTempEventHandlers = (list, ...handlers) => { for (const handler of handlers) { const [target, type, eventListener, options] = handler; target.addEventListener(type, eventListener, options); list.push(handler); } }; var clearTempEventHandlers = (list) => { if (list) { for (const [target, type, listener, options] of list) { target.removeEventListener(type, listener, options); } list.length = 0; } }; var preventEventDefault = (event) => { if (event.cancelable) { event.preventDefault(); } }; // packages/ag-grid-community/src/agStack/utils/locale.ts function defaultLocaleTextFunc(_key, defaultValue) { return defaultValue; } function _getLocaleTextFunc(localeSvc) { return localeSvc?.getLocaleTextFunc() ?? defaultLocaleTextFunc; } function _translate(bean, localeValues, key, variableValues) { const defaultValue = localeValues[key]; return bean.getLocaleTextFunc()( key, typeof defaultValue === "function" ? defaultValue(variableValues) : defaultValue, variableValues ); } function _getLocaleTextFromFunc(getLocaleText) { return (key, defaultValue, variableValues) => { return getLocaleText({ key, defaultValue, variableValues }); }; } function _getLocaleTextFromMap(localeText) { return (key, defaultValue, variableValues) => { let localisedText = localeText?.[key]; if (localisedText && variableValues?.length) { let found = 0; while (true) { if (found >= variableValues.length) { break; } const idx = localisedText.indexOf("${variable}"); if (idx === -1) { break; } localisedText = localisedText.replace("${variable}", variableValues[found++]); } } return localisedText ?? defaultValue; }; } // packages/ag-grid-community/src/agStack/core/agBeanStub.ts var AgBeanStub = class { constructor() { // not named context to allow children to use 'context' as a variable name this.destroyFunctions = []; this.destroyed = false; // for vue 3 - prevents Vue from trying to make this (and obviously any sub classes) from being reactive // prevents vue from creating proxies for created objects and prevents identity related issues this.__v_skip = true; this.propertyListenerId = 0; // Enable multiple grid properties to be updated together by the user but only trigger shared logic once. // Closely related to logic in GridOptionsUtils.ts _processOnChange this.lastChangeSetIdLookup = {}; this.isAlive = () => !this.destroyed; } preWireBeans(beans) { this.beans = beans; this.stubContext = beans.context; this.eventSvc = beans.eventSvc; this.gos = beans.gos; } // this was a test constructor niall built, when active, it prints after 5 seconds all beans/components that are // not destroyed. to use, create a new grid, then api.destroy() before 5 seconds. then anything that gets printed // points to a bean or component that was not properly disposed of. // constructor() { // setTimeout(()=> { // if (this.isAlive()) { // let prototype: any = Object.getPrototypeOf(this); // const constructor: any = prototype.constructor; // const constructorString = constructor.toString(); // const beanName = constructorString.substring(9, constructorString.indexOf("(")); // console.log('is alive ' + beanName); // } // }, 5000); // } destroy() { const { destroyFunctions } = this; for (let i = 0; i < destroyFunctions.length; i++) { destroyFunctions[i](); } destroyFunctions.length = 0; this.destroyed = true; this.dispatchLocalEvent({ type: "destroyed" }); } /** Add a local event listener against this BeanStub */ addEventListener(eventType, listener, async) { if (!this.localEventService) { this.localEventService = new LocalEventService(); } this.localEventService.addEventListener(eventType, listener, async); } /** Remove a local event listener from this BeanStub */ removeEventListener(eventType, listener, async) { this.localEventService?.removeEventListener(eventType, listener, async); } dispatchLocalEvent(event) { this.localEventService?.dispatchEvent(event); } addManagedElementListeners(object, handlers) { return this._setupListeners(object, handlers); } addManagedEventListeners(handlers) { return this._setupListeners(this.eventSvc, handlers); } addManagedListeners(object, handlers) { return this._setupListeners(object, handlers); } _setupListeners(object, handlers) { const destroyFuncs = []; for (const k of Object.keys(handlers)) { const handler = handlers[k]; if (handler) { destroyFuncs.push(this._setupListener(object, k, handler)); } } return destroyFuncs; } _setupListener(object, event, listener) { if (this.destroyed) { return () => null; } let destroyFunc; if (isAgEventEmitter(object)) { object.__addEventListener(event, listener); destroyFunc = () => { object.__removeEventListener(event, listener); return null; }; } else { const objIsEventService = isEventService(object); if (object instanceof HTMLElement) { _addSafePassiveEventListener(object, event, listener); } else if (objIsEventService) { object.addListener(event, listener); } else { object.addEventListener(event, listener); } destroyFunc = objIsEventService ? () => { object.removeListener(event, listener); return null; } : () => { object.removeEventListener(event, listener); return null; }; } this.destroyFunctions.push(destroyFunc); return () => { destroyFunc(); this.destroyFunctions = this.destroyFunctions.filter((fn) => fn !== destroyFunc); return null; }; } /** * Setup a managed property listener for the given property. * However, stores the destroy function in the beanStub so that if this bean * is a component the destroy function will be called when the component is destroyed * as opposed to being cleaned up only when the properties service is destroyed. */ setupPropertyListener(event, listener) { const { gos } = this; gos.addPropertyEventListener(event, listener); const destroyFunc = () => { gos.removePropertyEventListener(event, listener); return null; }; this.destroyFunctions.push(destroyFunc); return () => { destroyFunc(); this.destroyFunctions = this.destroyFunctions.filter((fn) => fn !== destroyFunc); return null; }; } /** * Setup a managed property listener for the given GridOption property. * @param event GridOption property to listen to changes for. * @param listener Listener to run when property value changes */ addManagedPropertyListener(event, listener) { if (this.destroyed) { return () => null; } return this.setupPropertyListener(event, listener); } /** * Setup managed property listeners for the given set of GridOption properties. * The listener will be run if any of the property changes but will only run once if * multiple of the properties change within the same framework lifecycle event. * Works on the basis that GridOptionsService updates all properties *before* any property change events are fired. * @param events Array of GridOption properties to listen for changes too. * @param listener Shared listener to run if any of the properties change */ addManagedPropertyListeners(events, listener) { if (this.destroyed) { return; } const eventsKey = events.join("-") + this.propertyListenerId++; const wrappedListener = (event) => { if (event.changeSet) { if (event.changeSet && event.changeSet.id === this.lastChangeSetIdLookup[eventsKey]) { return; } this.lastChangeSetIdLookup[eventsKey] = event.changeSet.id; } const propertiesChangeEvent = { type: "propertyChanged", changeSet: event.changeSet, source: event.source }; listener(propertiesChangeEvent); }; for (const event of events) { this.setupPropertyListener(event, wrappedListener); } } getLocaleTextFunc() { return _getLocaleTextFunc(this.beans.localeSvc); } addDestroyFunc(func) { if (this.isAlive()) { this.destroyFunctions.push(func); } else { func(); } } /** doesn't throw an error if `bean` is undefined */ createOptionalManagedBean(bean, context) { return bean ? this.createManagedBean(bean, context) : void 0; } createManagedBean(bean, context) { const res = this.createBean(bean, context); this.addDestroyFunc(this.destroyBean.bind(this, bean, context)); return res; } createBean(bean, context, afterPreCreateCallback) { return (context || this.stubContext).createBean(bean, afterPreCreateCallback); } /** * Destroys a bean and returns undefined to support destruction and clean up in a single line. * this.dateComp = this.context.destroyBean(this.dateComp); */ destroyBean(bean, context) { return (context || this.stubContext).destroyBean(bean); } /** * Destroys an array of beans and returns an empty array to support destruction and clean up in a single line. * this.dateComps = this.context.destroyBeans(this.dateComps); */ destroyBeans(beans, context) { return (context || this.stubContext).destroyBeans(beans); } }; function isAgEventEmitter(object) { return object.__addEventListener !== void 0; } function isEventService(object) { return object.eventServiceType === "global"; } // packages/ag-grid-community/src/context/beanStub.ts var BeanStub = class extends AgBeanStub { }; // packages/ag-grid-community/src/agStack/utils/function.ts var doOnceSet = /* @__PURE__ */ new Set(); var _doOnce = (func, key) => { if (!doOnceSet.has(key)) { doOnceSet.add(key); func(); } }; _doOnce._set = doOnceSet; var batchedCallsSetTimeout = { pending: false, funcs: [] }; var batchedCallsRaf = { pending: false, funcs: [] }; function _batchCall(func, mode = "setTimeout", beans) { const batch = mode === "raf" ? batchedCallsRaf : batchedCallsSetTimeout; batch.funcs.push(func); if (batch.pending) { return; } batch.pending = true; const runBatch = () => { const funcsCopy = batch.funcs.slice(); batch.funcs.length = 0; batch.pending = false; for (const func2 of funcsCopy) { func2(); } }; if (mode === "raf") { _requestAnimationFrame(beans, runBatch); } else { window.setTimeout(runBatch, 0); } } function _debounce(bean, func, delay) { let timeout; return function(...args) { const context = this; window.clearTimeout(timeout); timeout = window.setTimeout(function() { if (bean.isAlive()) { func.apply(context, args); } }, delay); return timeout; }; } function _throttle(func, wait) { let previousCall = 0; return function(...args) { const context = this; const currentCall = Date.now(); if (currentCall - previousCall < wait) { return; } previousCall = currentCall; func.apply(context, args); }; } function _waitUntil(bean, condition, callback, timeout = 100) { const timeStamp = Date.now(); let interval = null; let executed = false; const clearWait = () => { if (interval != null) { window.clearInterval(interval); interval = null; } }; bean.addDestroyFunc(clearWait); const internalCallback = () => { const reachedTimeout = Date.now() - timeStamp > timeout; if (condition() || reachedTimeout) { callback(); executed = true; clearWait(); } }; internalCallback(); if (!executed) { interval = window.setInterval(internalCallback, 10); } } // packages/ag-grid-community/src/utils/mergeDeep.ts var SKIP_JS_BUILTINS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]); function _iterateObject(object, callback) { if (object == null) { return; } if (Array.isArray(object)) { for (let i = 0; i < object.length; i++) { callback(i.toString(), object[i]); } return; } for (const key of Object.keys(object).filter((key2) => !SKIP_JS_BUILTINS.has(key2))) { callback(key, object[key]); } } function _mergeDeep(dest, source, copyUndefined = true, makeCopyOfSimpleObjects = false) { if (!_exists(source)) { return; } _iterateObject(source, (key, sourceValue) => { let destValue = dest[key]; if (destValue === sourceValue) { return; } if (makeCopyOfSimpleObjects) { const objectIsDueToBeCopied = destValue == null && sourceValue != null; if (objectIsDueToBeCopied) { const doNotCopyAsSourceIsSimpleObject = typeof sourceValue === "object" && sourceValue.constructor === Object; if (doNotCopyAsSourceIsSimpleObject) { destValue = {}; dest[key] = destValue; } } } if (_isNonNullObject(sourceValue) && _isNonNullObject(destValue) && !Array.isArray(destValue)) { _mergeDeep(destValue, sourceValue, copyUndefined, makeCopyOfSimpleObjects); } else if (copyUndefined || sourceValue !== void 0) { dest[key] = sourceValue; } }); } function _isNonNullObject(value) { return typeof value === "object" && value !== null; } // packages/ag-grid-community/src/globalGridOptions.ts var _GlobalGridOptions = class _GlobalGridOptions { /** * @param providedOptions * @returns Shallow copy of the provided options with global options merged in. */ static applyGlobalGridOptions(providedOptions) { if (!_GlobalGridOptions.gridOptions) { return { ...providedOptions }; } let mergedGridOps = {}; _mergeDeep(mergedGridOps, _GlobalGridOptions.gridOptions, true, true); if (_GlobalGridOptions.mergeStrategy === "deep") { _mergeDeep(mergedGridOps, providedOptions, true, true); } else { mergedGridOps = { ...mergedGridOps, ...providedOptions }; } if (_GlobalGridOptions.gridOptions.context) { mergedGridOps.context = _GlobalGridOptions.gridOptions.context; } if (providedOptions.context) { if (_GlobalGridOptions.mergeStrategy === "deep" && mergedGridOps.context) { _mergeDeep(providedOptions.context, mergedGridOps.context, true, true); } mergedGridOps.context = providedOptions.context; } return mergedGridOps; } /** * Apply global grid option for a specific option key. * If the merge strategy is 'deep' and both global and provided values are objects, they will be merged deeply. * Otherwise, the provided value is returned as is. * @param optionKey - The key of the grid option to apply. * @param providedValue - The value provided to the grid instance. * @returns The merged value if applicable, otherwise the provided value. */ static applyGlobalGridOption(optionKey, providedValue) { if (_GlobalGridOptions.mergeStrategy === "deep") { const globalValue = _getGlobalGridOption(optionKey); if (globalValue && typeof globalValue === "object" && typeof providedValue === "object") { return _GlobalGridOptions.applyGlobalGridOptions({ [optionKey]: providedValue })[optionKey]; } } return providedValue; } }; // eslint-disable-next-line no-restricted-syntax _GlobalGridOptions.gridOptions = void 0; // eslint-disable-next-line no-restricted-syntax _GlobalGridOptions.mergeStrategy = "shallow"; var GlobalGridOptions = _GlobalGridOptions; function provideGlobalGridOptions(gridOptions, mergeStrategy = "shallow") { GlobalGridOptions.gridOptions = gridOptions; GlobalGridOptions.mergeStrategy = mergeStrategy; } function _getGlobalGridOption(gridOption) { return GlobalGridOptions.gridOptions?.[gridOption]; } // packages/ag-grid-community/src/gridOptionsDefault.ts var GRID_OPTION_DEFAULTS = { suppressContextMenu: false, preventDefaultOnContextMenu: false, allowContextMenuWithControlKey: false, suppressMenuHide: true, enableBrowserTooltips: false, tooltipTrigger: "hover", tooltipShowDelay: 2e3, tooltipSwitchShowDelay: 200, tooltipHideDelay: 1e4, tooltipMouseTrack: false, tooltipShowMode: "standard", tooltipInteraction: false, copyHeadersToClipboard: false, copyGroupHeadersToClipboard: false, clipboardDelimiter: " ", suppressCopyRowsToClipboard: false, suppressCopySingleCellRanges: false, suppressLastEmptyLineOnPaste: false, suppressClipboardPaste: false, suppressClipboardApi: false, suppressCutToClipboard: false, maintainColumnOrder: false, enableStrictPivotColumnOrder: false, suppressFieldDotNotation: false, allowDragFromColumnsToolPanel: false, suppressMovableColumns: false, suppressColumnMoveAnimation: false, suppressMoveWhenColumnDragging: false, suppressDragLeaveHidesColumns: false, suppressRowGroupHidesColumns: false, suppressAutoSize: false, autoSizePadding: 20, skipHeaderOnAutoSize: false, singleClickEdit: false, suppressClickEdit: false, readOnlyEdit: false, stopEditingWhenCellsLoseFocus: false, enterNavigatesVertically: false, enterNavigatesVerticallyAfterEdit: false, enableCellEditingOnBackspace: false, undoRedoCellEditing: false, undoRedoCellEditingLimit: 10, suppressCsvExport: false, suppressExcelExport: false, cacheQuickFilter: false, includeHiddenColumnsInQuickFilter: false, excludeChildrenWhenTreeDataFiltering: false, enableAdvancedFilter: false, includeHiddenColumnsInAdvancedFilter: false, enableCharts: false, masterDetail: false, keepDetailRows: false, keepDetailRowsCount: 10, detailRowAutoHeight: false, tabIndex: 0, rowBuffer: 10, valueCache: false, valueCacheNeverExpires: false, enableCellExpressions: false, suppressTouch: false, suppressFocusAfterRefresh: false, suppressBrowserResizeObserver: false, suppressPropertyNamesCheck: false, suppressChangeDetection: false, debug: false, suppressLoadingOverlay: false, suppressNoRowsOverlay: false, pagination: false, paginationPageSize: 100, paginationPageSizeSelector: true, paginationAutoPageSize: false, paginateChildRows: false, suppressPaginationPanel: false, pivotMode: false, pivotPanelShow: "never", pivotDefaultExpanded: 0, pivotSuppressAutoColumn: false, suppressExpandablePivotGroups: false, functionsReadOnly: false, suppressAggFuncInHeader: false, alwaysAggregateAtRootLevel: false, aggregateOnlyChangedColumns: false, suppressAggFilteredOnly: false, removePivotHeaderRowWhenSingleValueColumn: false, animateRows: true, cellFlashDuration: 500, cellFadeDuration: 1e3, allowShowChangeAfterFilter: false, domLayout: "normal", ensureDomOrder: false, enableRtl: false, suppressColumnVirtualisation: false, suppressMaxRenderedRowRestriction: false, suppressRowVirtualisation: false, rowDragManaged: false, refreshAfterGroupEdit: false, rowDragInsertDelay: 500, suppressRowDrag: false, suppressMoveWhenRowDragging: false, rowDragEntireRow: false, rowDragMultiRow: false, embedFullWidthRows: false, groupDisplayType: "singleColumn", groupDefaultExpanded: 0, groupMaintainOrder: false, groupSelectsChildren: false, groupSuppressBlankHeader: false, groupSelectsFiltered: false, showOpenedGroup: false, groupRemoveSingleChildren: false, groupRemoveLowestSingleChildren: false, groupHideOpenParents: false, groupHideColumnsUntilExpanded: false, groupAllowUnbalanced: false, rowGroupPanelShow: "never", suppressMakeColumnVisibleAfterUnGroup: false, treeData: false, rowGroupPanelSuppressSort: false, suppressGroupRowsSticky: false, rowModelType: "clientSide", asyncTransactionWaitMillis: 50, suppressModelUpdateAfterUpdateTransaction: false, cacheOverflowSize: 1, infiniteInitialRowCount: 1, serverSideInitialRowCount: 1, cacheBlockSize: 100, maxBlocksInCache: -1, maxConcurrentDatasourceRequests: 2, blockLoadDebounceMillis: 0, purgeClosedRowNodes: false, serverSideSortAllLevels: false, serverSideOnlyRefreshFilteredGroups: false, serverSidePivotResultFieldSeparator: "_", viewportRowModelPageSize: 5, viewportRowModelBufferSize: 5, alwaysShowHorizontalScroll: false, alwaysShowVerticalScroll: false, debounceVerticalScrollbar: false, suppressHorizontalScroll: false, suppressScrollOnNewData: false, suppressScrollWhenPopupsAreOpen: false, suppressAnimationFrame: false, suppressMiddleClickScrolls: false, suppressPreventDefaultOnMouseWheel: false, rowMultiSelectWithClick: false, suppressRowDeselection: false, suppressRowClickSelection: false, suppressCellFocus: false, suppressHeaderFocus: false, suppressMultiRangeSelection: false, enableCellTextSelection: false, enableRangeSelection: false, enableRangeHandle: false, enableFillHandle: false, fillHandleDirection: "xy", suppressClearOnFillReduction: false