HEX
Server: Apache/2.4.41
System: Linux mainweb 5.4.0-182-generic #202-Ubuntu SMP Fri Apr 26 12:29:36 UTC 2024 x86_64
User: nationalmedicaregrp (1119)
PHP: 8.3.7
Disabled: exec,passthru,shell_exec,system,popen,proc_open,pcntl_exec
Upload Files
File: /home/callrouting/public_html/wwwroot/_content/BlazorFluentUI.CoreComponents/baseComponent.js
const IS_FOCUSABLE_ATTRIBUTE = 'data-is-focusable';
const IS_SCROLLABLE_ATTRIBUTE = 'data-is-scrollable';
const IS_VISIBLE_ATTRIBUTE = 'data-is-visible';
const FOCUSZONE_ID_ATTRIBUTE = 'data-focuszone-id';
const FOCUSZONE_SUB_ATTRIBUTE = 'data-is-sub-focuszone';
const IsFocusVisibleClassName = 'ms-Fabric--isFocusVisible';
//Store the element that the layer is started from so we can later match up the layer's children with the original parent.
const layerElements = {};
export function initializeFocusRects() {
    if (!window.__hasInitializeFocusRects__) {
        window.__hasInitializeFocusRects__ = true;
        window.addEventListener("mousedown", _onFocusRectMouseDown, true);
        window.addEventListener("keydown", _onFocusRectKeyDown, true);
    }
}
function _onFocusRectMouseDown(ev) {
    if (window.document.body.classList.contains(IsFocusVisibleClassName)) {
        window.document.body.classList.remove(IsFocusVisibleClassName);
    }
}
function _onFocusRectKeyDown(ev) {
    if (isDirectionalKeyCode(ev.which) && !window.document.body.classList.contains(IsFocusVisibleClassName)) {
        window.document.body.classList.add(IsFocusVisibleClassName);
    }
}
const DirectionalKeyCodes = {
    [38 /* up */]: 1,
    [40 /* down */]: 1,
    [37 /* left */]: 1,
    [39 /* right */]: 1,
    [36 /* home */]: 1,
    [35 /* end */]: 1,
    [9 /* tab */]: 1,
    [33 /* pageUp */]: 1,
    [34 /* pageDown */]: 1
};
function isDirectionalKeyCode(which) {
    return !!DirectionalKeyCodes[which];
}
// Disable/enable bodyscroll for overlay
var _bodyScrollDisabledCount = 0;
export function enableBodyScroll() {
    if (_bodyScrollDisabledCount > 0) {
        if (_bodyScrollDisabledCount === 1) {
            document.body.classList.remove("disabledBodyScroll");
            document.body.removeEventListener('touchmove', _disableIosBodyScroll);
        }
        _bodyScrollDisabledCount--;
    }
}
export function disableBodyScroll() {
    if (!_bodyScrollDisabledCount) {
        document.body.classList.add("disabledBodyScroll");
        document.body.addEventListener('touchmove', _disableIosBodyScroll, { passive: false, capture: false });
    }
    _bodyScrollDisabledCount++;
}
const _disableIosBodyScroll = (event) => {
    event.preventDefault();
};
// end
export function getSelectionStart(element) {
    if (element == null)
        return null;
    return element.selectionStart;
}
export function getSelectionEnd(element) {
    if (element == null)
        return null;
    return element.selectionEnd;
}
export function setSelectionRange(element, start, end) {
    if (element == null)
        return;
    return element.setSelectionRange(start, end);
}
export function getClientHeight(element) {
    if (element === null || element.clientHeight === undefined)
        return 0;
    return element.clientHeight;
}
export function getScrollHeight(element) {
    if (element === null || element.scrollHeight === undefined)
        return 0;
    return element.scrollHeight;
}
export function findScrollableParent(startingElement) {
    let el = startingElement;
    // First do a quick scan for the scrollable attribute.
    while (el && el !== document.body) {
        if (el.getAttribute(IS_SCROLLABLE_ATTRIBUTE) === 'true') {
            return el;
        }
        el = el.parentElement;
    }
    // If we haven't found it, then use the slower method: compute styles to evaluate if overflow is set.
    el = startingElement;
    while (el && el !== document.body) {
        if (el.getAttribute(IS_SCROLLABLE_ATTRIBUTE) !== 'false') {
            const computedStyles = getComputedStyle(el);
            let overflowY = computedStyles ? computedStyles.getPropertyValue('overflow-y') : '';
            if (overflowY && (overflowY === 'scroll' || overflowY === 'auto')) {
                return el;
            }
        }
        el = el.parentElement;
    }
    // Fall back to window scroll.
    if (!el || el === document.body) {
        // tslint:disable-next-line:no-any
        el = window;
    }
    return el;
}
export function measureElement(element) {
    var rect = {
        width: element.clientWidth,
        height: element.clientHeight,
        left: 0,
        top: 0
    };
    return rect;
}
export function getNaturalBounds(image) {
    if (image && image !== null) {
        var rect = {
            width: image.naturalWidth,
            height: image.naturalHeight,
            left: 0,
            top: 0
        };
        return rect;
    }
    return null;
}
export function supportsObjectFit() {
    return window !== undefined && window.navigator.maxTouchPoints === undefined;
}
export function hasOverflow(element) {
    return false;
}
export function measureScrollWindow(element) {
    if (element !== undefined && element !== null) {
        var rect = {
            width: element.scrollWidth,
            height: element.scrollHeight,
            top: element.scrollTop,
            left: element.scrollLeft,
            bottom: element.scrollTop + element.clientHeight,
            right: element.scrollLeft + element.clientWidth,
        };
        return rect;
    }
    else {
        return { height: 0, width: 0, left: 0, right: 0, top: 0, bottom: 0 };
    }
}
export function measureScrollDimensions(element) {
    if (element !== undefined && element !== null) {
        var dimensions = {
            scrollHeight: element?.scrollHeight,
            scrollWidth: element?.scrollWidth,
        };
        return dimensions;
    }
    else
        return { scrollHeight: 0, scrollWidth: 0 };
}
export function measureElementRect(element) {
    if (element !== undefined && element !== null) {
        // EdgeHTML's rectangle can't be serialized for some reason.... serializes to 0 everything.   So break it apart into simple JSON.
        var rect = element.getBoundingClientRect();
        //return { height: rect.height, width: rect.width, left: rect.left, right: rect.right, top: rect.top, bottom: rect.bottom };
        return rect;
    }
    else
        return { height: 0, width: 0, left: 0, right: 0, top: 0, bottom: 0 };
}
export function getWindow(element) {
    return element?.ownerDocument.defaultView;
}
export function getWindowRect() {
    var rect = {
        width: window.innerWidth,
        height: window.innerHeight,
        top: 0,
        left: 0
    };
    return rect;
}
export function getElementId(element) {
    if (element !== undefined) {
        return element.id;
    }
    return null;
}
var eventRegister = new Map();
var eventElementRegister = {};
/* Function for Dropdown, but could apply to focusing on any element after onkeydown outside of list containing is-element-focusable items */
export function registerKeyEventsForList(element, guid) {
    if (element instanceof HTMLElement) {
        eventElementRegister[guid] = [element, (ev) => {
                let elementToFocus;
                const containsExpandCollapseModifier = ev.altKey || ev.metaKey;
                switch (ev.keyCode) {
                    case 38 /* up */:
                        if (containsExpandCollapseModifier) {
                            //should send a close window or something, maybe let Blazor handle it.
                        }
                        else {
                            elementToFocus = getLastFocusable(element, element.lastChild, true);
                        }
                        break;
                    case 40 /* down */:
                        if (!containsExpandCollapseModifier) {
                            elementToFocus = getFirstFocusable(element, element.firstChild, true);
                        }
                        break;
                    default:
                        return;
                }
                if (elementToFocus) {
                    elementToFocus.focus();
                }
            }];
        element.addEventListener("keydown", eventElementRegister[guid][1]);
    }
}
export function deregisterKeyEventsForList(guid) {
    var tuple = eventElementRegister[guid];
    if (tuple) {
        var element = tuple[0];
        var func = tuple[1];
        element.removeEventListener("keydown", func);
        eventElementRegister[guid] = null;
    }
}
export function registerWindowKeyDownEvent(dotnetRef, keyCode, functionName, guid) {
    eventRegister.set(guid, (ev) => {
        if (ev.code == keyCode) {
            ev.preventDefault();
            ev.stopPropagation();
            dotnetRef.invokeMethodAsync(functionName, ev.code);
        }
    });
    window.addEventListener("keydown", eventRegister.get(guid));
}
export function deregisterWindowKeyDownEvent(guid) {
    var func = eventRegister.get(guid);
    window.removeEventListener("keydown", func);
    eventRegister.delete(guid);
}
export function registerResizeEvent(dotnetRef, functionName, guid) {
    var async = new Async(this);
    eventRegister.set(guid, async.debounce(() => {
        dotnetRef.invokeMethodAsync(functionName, window.innerWidth, innerHeight);
    }, 100, { leading: true }));
    window.addEventListener("resize", eventRegister.get(guid));
}
export function deregisterResizeEvent(guid) {
    var func = eventRegister.get(guid);
    window.removeEventListener("resize", func);
    eventRegister.delete(guid);
}
var _lastId = 0;
var cachedViewports = new Map();
class Viewport {
    constructor(component, rootElement, fireInitialViewport = false) {
        this.RESIZE_DELAY = 100;
        this.MAX_RESIZE_ATTEMPTS = 3;
        this.viewport = { width: 0, height: 0 };
        this._onAsyncResizeAsync = () => {
            this._updateViewportAsync();
        };
        this.id = _lastId++;
        this.component = component;
        this.rootElement = rootElement;
        this._async = new Async(this);
        this._onAsyncResizeAsync = this._async.debounce(this._onAsyncResizeAsync, this.RESIZE_DELAY, { leading: true });
        this.viewportResizeObserver = new window.ResizeObserver(this._onAsyncResizeAsync);
        this.viewportResizeObserver.observe(this.rootElement);
        if (fireInitialViewport) {
            this._onAsyncResizeAsync();
        }
    }
    disconnect() {
        this.viewportResizeObserver.disconnect();
    }
    async _updateViewportAsync(withForceUpdate) {
        //const { viewport } = this.state;
        const viewportElement = this.rootElement;
        const scrollElement = findScrollableParent(viewportElement);
        const scrollRect = getRect(scrollElement);
        const clientRect = getRect(viewportElement);
        const updateComponentAsync = async () => {
            if (withForceUpdate) {
                await this.component.invokeMethodAsync("ForceUpdate");
            }
        };
        const isSizeChanged = (clientRect && clientRect.width) !== this.viewport.width || (scrollRect && scrollRect.height) !== this.viewport.height;
        if (isSizeChanged && this._resizeAttempts < this.MAX_RESIZE_ATTEMPTS && clientRect && scrollRect) {
            this._resizeAttempts++;
            this.viewport = {
                width: clientRect.width,
                height: scrollRect.height
            };
            await this.component.invokeMethodAsync("ViewportChanged", this.viewport);
            await this._updateViewportAsync(withForceUpdate);
        }
        else {
            this._resizeAttempts = 0;
            await updateComponentAsync();
        }
    }
    ;
}
export function addViewport(component, rootElement, fireInitialViewport = false) {
    let viewport = new Viewport(component, rootElement, fireInitialViewport);
    cachedViewports.set(viewport.id, viewport);
    return viewport.id;
}
export function removeViewport(id) {
    let viewport = cachedViewports.get(id);
    viewport.disconnect();
    cachedViewports.delete(id);
}
export function getRect(element) {
    let rect;
    if (element) {
        if (element === window) {
            rect = {
                left: 0,
                top: 0,
                width: window.innerWidth,
                height: window.innerHeight,
                right: window.innerWidth,
                bottom: window.innerHeight,
            };
        }
        else if (element.getBoundingClientRect) {
            rect = element.getBoundingClientRect();
        }
    }
    return rect;
}
export function findElementRecursive(element, matchFunction) {
    if (!element || element === document.body) {
        return null;
    }
    return matchFunction(element) ? element : findElementRecursive(getParent(element), matchFunction);
}
export function elementContainsAttribute(element, attribute) {
    let elementMatch = findElementRecursive(element, (testElement) => testElement.hasAttribute(attribute));
    return elementMatch && elementMatch.getAttribute(attribute);
}
/* Focus stuff */
/* Since elements can be stored in Blazor and we don't want to create more js files, this will hold last focused elements for restoring focus later. */
var _lastFocus = {};
export function storeLastFocusedElement(guid) {
    let element = document.activeElement;
    let htmlElement = element;
    if (htmlElement) {
        _lastFocus[guid] = htmlElement;
        return guid;
    }
    return null;
}
export function restoreLastFocus(guid, restoreFocus = true) {
    var htmlElement = _lastFocus[guid];
    if (htmlElement != null) {
        if (restoreFocus) {
            htmlElement.focus();
        }
        delete _lastFocus[guid];
    }
}
export function getActiveElement() {
    return document.activeElement;
}
export function focusElement(element) {
    element.focus();
}
export function focusFirstElementChild(element) {
    if (element !== undefined && element != null) {
        let child = this.getFirstFocusable(element, element, true);
        if (child) {
            child.focus();
        }
        else {
            element.focus();
        }
    }
}
export function shouldWrapFocus(element, noWrapDataAttribute) {
    return elementContainsAttribute(element, noWrapDataAttribute) === 'true' ? false : true;
}
export function getFocusableByIndexPath(parent, path) {
    let element = parent;
    for (const index of path) {
        const nextChild = element.children[Math.min(index, element.children.length - 1)];
        if (!nextChild) {
            break;
        }
        element = nextChild;
    }
    element = isElementTabbable(element) && isElementVisible(element) ? element : getNextElement(parent, element, true) || getPreviousElement(parent, element);
    return element;
}
export function getElementIndexPath(fromElement, toElement) {
    const path = [];
    let currentElement = toElement;
    while (currentElement && fromElement && currentElement !== fromElement) {
        const parent = currentElement.parentNode;
        if (parent === null) {
            return [];
        }
        path.unshift(Array.prototype.indexOf.call(parent.children, currentElement));
        currentElement = parent;
    }
    return path;
}
export function getFirstFocusable(rootElement, currentElement, includeElementsInFocusZones) {
    return getNextElement(rootElement, currentElement, true /* checkNode */, false /* suppressParentTraversal */, false /* suppressChildTraversal */, includeElementsInFocusZones);
}
export function getLastFocusable(rootElement, currentElement, includeElementsInFocusZones) {
    return getPreviousElement(rootElement, currentElement, true /* checkNode */, false /* suppressParentTraversal */, true /* traverseChildren */, includeElementsInFocusZones);
}
export function getFirstTabbable(rootElement, currentElement, includeElementsInFocusZones, checkNode) {
    return getNextElement(rootElement, currentElement, checkNode, false /* suppressParentTraversal */, false /* suppressChildTraversal */, includeElementsInFocusZones, true /* tabbable */);
}
export function getLastTabbable(rootElement, currentElement, includeElementsInFocusZones, checkNode) {
    return getPreviousElement(rootElement, currentElement, checkNode, false /* suppressParentTraversal */, true /* traverseChildren */, includeElementsInFocusZones, true /* tabbable */);
}
export function isElementTabbable(element, checkTabIndex) {
    // If this element is null or is disabled, it is not considered tabbable.
    if (!element || element.disabled) {
        return false;
    }
    let tabIndex = 0;
    let tabIndexAttributeValue = null;
    if (element && element.getAttribute) {
        tabIndexAttributeValue = element.getAttribute('tabIndex');
        if (tabIndexAttributeValue) {
            tabIndex = parseInt(tabIndexAttributeValue, 10);
        }
    }
    const isFocusableAttribute = element.getAttribute ? element.getAttribute(IS_FOCUSABLE_ATTRIBUTE) : null;
    const isTabIndexSet = tabIndexAttributeValue !== null && tabIndex >= 0;
    const result = !!element &&
        isFocusableAttribute !== 'false' &&
        (element.tagName === 'A' ||
            element.tagName === 'BUTTON' ||
            element.tagName === 'INPUT' ||
            element.tagName === 'TEXTAREA' ||
            isFocusableAttribute === 'true' ||
            isTabIndexSet ||
            (element.getAttribute && element.getAttribute('role') === 'button'));
    return checkTabIndex ? tabIndex !== -1 && result : result;
}
export function isElementVisible(element) {
    // If the element is not valid, return false.
    if (!element || !element.getAttribute) {
        return false;
    }
    const visibilityAttribute = element.getAttribute(IS_VISIBLE_ATTRIBUTE);
    // If the element is explicitly marked with the visibility attribute, return that value as boolean.
    if (visibilityAttribute !== null && visibilityAttribute !== undefined) {
        return visibilityAttribute === 'true';
    }
    // Fallback to other methods of determining actual visibility.
    return (element.offsetHeight !== 0 ||
        element.offsetParent !== null ||
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        element.isVisible === true); // used as a workaround for testing.
}
export function isElementFocusZone(element) {
    return !!(element && element.getAttribute && !!element.getAttribute(FOCUSZONE_ID_ATTRIBUTE));
}
export function isElementFocusSubZone(element) {
    return !!(element && element.getAttribute && element.getAttribute(FOCUSZONE_SUB_ATTRIBUTE) === 'true');
}
let targetToFocusOnNextRepaint = undefined;
export function focusAsync(element) {
    if (element) {
        // An element was already queued to be focused, so replace that one with the new element
        if (targetToFocusOnNextRepaint) {
            targetToFocusOnNextRepaint = element;
            return;
        }
        targetToFocusOnNextRepaint = element;
        const win = window;
        if (win) {
            // element.focus() is a no-op if the element is no longer in the DOM, meaning this is always safe
            win.requestAnimationFrame(() => {
                targetToFocusOnNextRepaint && targetToFocusOnNextRepaint.focus();
                // We are done focusing for this frame, so reset the queued focus element
                targetToFocusOnNextRepaint = undefined;
            });
        }
    }
}
export function focusFirstChild(rootElement) {
    return false;
}
export function getParent(child, allowVirtualParents = true) {
    return child && ((allowVirtualParents && getVirtualParent(child)) || (child.parentNode && child.parentNode));
}
export function addOrUpdateVirtualParent(parent) {
    if (parent !== null) {
        layerElements[parent.dataset.layerId] = parent;
    }
}
export function getVirtualParent(child) {
    let parent;
    if (child && child.dataset && child.dataset.parentLayerId) {
        parent = layerElements[child.dataset.parentLayerId];
    }
    return parent;
}
//export function setVirtualParent(child: HTMLElement, parent: HTMLElement) {
//    let virtualChild = <IVirtualElement>child;
//    let virtualParent = <IVirtualElement>parent;
//    if (!virtualChild._virtual) {
//        virtualChild._virtual = {
//            children: []
//        };
//    }
//    let oldParent = virtualChild._virtual.parent;
//    if (oldParent && oldParent !== parent) {
//        // Remove the child from its old parent.
//        let index = oldParent._virtual.children.indexOf(virtualChild);
//        if (index > -1) {
//            oldParent._virtual.children.splice(index, 1);
//        }
//    }
//    virtualChild._virtual.parent = virtualParent || undefined;
//    if (virtualParent) {
//        if (!virtualParent._virtual) {
//            virtualParent._virtual = {
//                children: []
//            };
//        }
//        virtualParent._virtual.children.push(virtualChild);
//    }
//}
//export function setVirtualParent(child: HTMLElement) {
//}
//export function getVirtualParent(child: HTMLElement): HTMLElement | undefined {
//    let parent: HTMLElement | undefined;
//    if (child && !!(<IVirtualElement>child)._virtual) {
//        parent = (child as IVirtualElement)._virtual.parent;
//    }
//    return parent;
//}
export function elementContains(parent, child, allowVirtualParents = true) {
    let isContained = false;
    if (parent && child) {
        if (allowVirtualParents) {
            isContained = false;
            while (child) {
                let nextParent = getParent(child);
                if (nextParent === parent) {
                    isContained = true;
                    break;
                }
                child = nextParent;
            }
        }
        else if (parent.contains) {
            isContained = parent.contains(child);
        }
    }
    return isContained;
}
export function getNextElement(rootElement, currentElement, checkNode, suppressParentTraversal, suppressChildTraversal, includeElementsInFocusZones, tabbable) {
    if (!currentElement || (currentElement === rootElement && suppressChildTraversal)) {
        return null;
    }
    const isCurrentElementVisible = isElementVisible(currentElement);
    // Check the current node, if it's not the first traversal.
    if (checkNode && isCurrentElementVisible && isElementTabbable(currentElement, tabbable)) {
        return currentElement;
    }
    // Check its children.
    if (!suppressChildTraversal &&
        isCurrentElementVisible &&
        (includeElementsInFocusZones || !(isElementFocusZone(currentElement) || isElementFocusSubZone(currentElement)))) {
        const childMatch = getNextElement(rootElement, currentElement.firstElementChild, true, true, false, includeElementsInFocusZones, tabbable);
        if (childMatch) {
            return childMatch;
        }
    }
    if (currentElement === rootElement) {
        return null;
    }
    // Check its sibling.
    const siblingMatch = getNextElement(rootElement, currentElement.nextElementSibling, true, true, false, includeElementsInFocusZones, tabbable);
    if (siblingMatch) {
        return siblingMatch;
    }
    if (!suppressParentTraversal) {
        return getNextElement(rootElement, currentElement.parentElement, false, false, true, includeElementsInFocusZones, tabbable);
    }
    return null;
}
export function getPreviousElement(rootElement, currentElement, checkNode, suppressParentTraversal, traverseChildren, includeElementsInFocusZones, tabbable) {
    if (!currentElement || currentElement === rootElement) {
        return null;
    }
    const isCurrentElementVisible = isElementVisible(currentElement);
    // Check its children.
    if (traverseChildren &&
        isCurrentElementVisible &&
        (includeElementsInFocusZones || !(isElementFocusZone(currentElement) || isElementFocusSubZone(currentElement)))) {
        const childMatch = getPreviousElement(rootElement, currentElement.lastElementChild, true, true, true, includeElementsInFocusZones, tabbable);
        if (childMatch) {
            if ((tabbable && isElementTabbable(childMatch, true)) || !tabbable) {
                return childMatch;
            }
            const childMatchSiblingMatch = getPreviousElement(rootElement, childMatch.previousElementSibling, true, true, true, includeElementsInFocusZones, tabbable);
            if (childMatchSiblingMatch) {
                return childMatchSiblingMatch;
            }
            let childMatchParent = childMatch.parentElement;
            // At this point if we have not found any potential matches
            // start looking at the rest of the subtree under the currentParent.
            // NOTE: We do not want to recurse here because doing so could
            // cause elements to get skipped.
            while (childMatchParent && childMatchParent !== currentElement) {
                const childMatchParentMatch = getPreviousElement(rootElement, childMatchParent.previousElementSibling, true, true, true, includeElementsInFocusZones, tabbable);
                if (childMatchParentMatch) {
                    return childMatchParentMatch;
                }
                childMatchParent = childMatchParent.parentElement;
            }
        }
    }
    // Check the current node, if it's not the first traversal.
    if (checkNode && isCurrentElementVisible && isElementTabbable(currentElement, tabbable)) {
        return currentElement;
    }
    // Check its previous sibling.
    const siblingMatch = getPreviousElement(rootElement, currentElement.previousElementSibling, true, true, true, includeElementsInFocusZones, tabbable);
    if (siblingMatch) {
        return siblingMatch;
    }
    // Check its parent.
    if (!suppressParentTraversal) {
        return getPreviousElement(rootElement, currentElement.parentElement, true, false, false, includeElementsInFocusZones, tabbable);
    }
    return null;
}
/** Raises a click event. */
export function raiseClick(target) {
    const event = createNewEvent('MouseEvents');
    event.initEvent('click', true, true);
    target.dispatchEvent(event);
}
function createNewEvent(eventName) {
    let event;
    if (typeof Event === 'function') {
        // Chrome, Opera, Firefox
        event = new Event(eventName);
    }
    else {
        // IE
        event = document.createEvent('Event');
        event.initEvent(eventName, true, true);
    }
    return event;
}
export function on(element, eventName, callback, options) {
    element?.addEventListener(eventName, callback, options);
    return () => element?.removeEventListener(eventName, callback, options);
}
function _expandRect(rect, pagesBefore, pagesAfter) {
    const top = rect.top - pagesBefore * rect.height;
    const height = rect.height + (pagesBefore + pagesAfter) * rect.height;
    return {
        top: top,
        bottom: top + height,
        height: height,
        left: rect.left,
        right: rect.right,
        width: rect.width
    };
}
function _isContainedWithin(innerRect, outerRect) {
    return (innerRect.top >= outerRect.top &&
        innerRect.left >= outerRect.left &&
        innerRect.bottom <= outerRect.bottom &&
        innerRect.right <= outerRect.right);
}
function _mergeRect(targetRect, newRect) {
    targetRect.top = newRect.top < targetRect.top || targetRect.top === -1 ? newRect.top : targetRect.top;
    targetRect.left = newRect.left < targetRect.left || targetRect.left === -1 ? newRect.left : targetRect.left;
    targetRect.bottom = newRect.bottom > targetRect.bottom || targetRect.bottom === -1 ? newRect.bottom : targetRect.bottom;
    targetRect.right = newRect.right > targetRect.right || targetRect.right === -1 ? newRect.right : targetRect.right;
    targetRect.width = targetRect.right - targetRect.left + 1;
    targetRect.height = targetRect.bottom - targetRect.top + 1;
    return targetRect;
}
const RTL_LOCAL_STORAGE_KEY = 'isRTL';
let _isRTL;
export function getRTL() {
    if (_isRTL === undefined) {
        // Fabric supports persisting the RTL setting between page refreshes via session storage
        let savedRTL = getItem(RTL_LOCAL_STORAGE_KEY);
        if (savedRTL !== null) {
            _isRTL = savedRTL === '1';
            setRTL(_isRTL);
        }
        let doc = document;
        if (_isRTL === undefined && doc) {
            _isRTL = ((doc.body && doc.body.getAttribute('dir')) || doc.documentElement.getAttribute('dir')) === 'rtl';
            //mergeStylesSetRTL(_isRTL);
        }
    }
    return !!_isRTL;
}
export function setRTL(isRTL, persistSetting = false) {
    let doc = document;
    if (doc) {
        doc.documentElement.setAttribute('dir', isRTL ? 'rtl' : 'ltr');
    }
    if (persistSetting) {
        setItem(RTL_LOCAL_STORAGE_KEY, isRTL ? '1' : '0');
    }
    _isRTL = isRTL;
    //mergeStylesSetRTL(_isRTL);
}
export function getItem(key) {
    let result = null;
    try {
        result = window.sessionStorage.getItem(key);
    }
    catch (e) {
        /* Eat the exception */
    }
    return result;
}
export function setItem(key, data) {
    try {
        window.sessionStorage.setItem(key, data);
    }
    catch (e) {
        /* Eat the exception */
    }
}
/**
 * Bugs often appear in async code when stuff gets disposed, but async operations don't get canceled.
 * This Async helper class solves these issues by tying async code to the lifetime of a disposable object.
 *
 * Usage: Anything class extending from BaseModel can access this helper via this.async. Otherwise create a
 * new instance of the class and remember to call dispose() during your code's dispose handler.
 *
 * @public
 */
export class Async {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    constructor(parent, onError) {
        this._timeoutIds = null;
        this._immediateIds = null;
        this._intervalIds = null;
        this._animationFrameIds = null;
        this._isDisposed = false;
        this._parent = parent || null;
        this._onErrorHandler = onError;
        this._noop = () => {
            /* do nothing */
        };
    }
    /**
     * Dispose function, clears all async operations.
     */
    dispose() {
        let id;
        this._isDisposed = true;
        this._parent = null;
        // Clear timeouts.
        if (this._timeoutIds) {
            for (id in this._timeoutIds) {
                if (this._timeoutIds.hasOwnProperty(id)) {
                    this.clearTimeout(parseInt(id, 10));
                }
            }
            this._timeoutIds = null;
        }
        // Clear immediates.
        if (this._immediateIds) {
            for (id in this._immediateIds) {
                if (this._immediateIds.hasOwnProperty(id)) {
                    this.clearImmediate(parseInt(id, 10));
                }
            }
            this._immediateIds = null;
        }
        // Clear intervals.
        if (this._intervalIds) {
            for (id in this._intervalIds) {
                if (this._intervalIds.hasOwnProperty(id)) {
                    this.clearInterval(parseInt(id, 10));
                }
            }
            this._intervalIds = null;
        }
        // Clear animation frames.
        if (this._animationFrameIds) {
            for (id in this._animationFrameIds) {
                if (this._animationFrameIds.hasOwnProperty(id)) {
                    this.cancelAnimationFrame(parseInt(id, 10));
                }
            }
            this._animationFrameIds = null;
        }
    }
    /**
     * SetTimeout override, which will auto cancel the timeout during dispose.
     * @param callback - Callback to execute.
     * @param duration - Duration in milliseconds.
     * @returns The setTimeout id.
     */
    setTimeout(callback, duration) {
        let timeoutId = 0;
        if (!this._isDisposed) {
            if (!this._timeoutIds) {
                this._timeoutIds = {};
            }
            timeoutId = setTimeout(() => {
                // Time to execute the timeout, enqueue it as a foreground task to be executed.
                try {
                    // Now delete the record and call the callback.
                    if (this._timeoutIds) {
                        delete this._timeoutIds[timeoutId];
                    }
                    callback.apply(this._parent);
                }
                catch (e) {
                    this._logError(e);
                }
            }, duration);
            this._timeoutIds[timeoutId] = true;
        }
        return timeoutId;
    }
    /**
     * Clears the timeout.
     * @param id - Id to cancel.
     */
    clearTimeout(id) {
        if (this._timeoutIds && this._timeoutIds[id]) {
            clearTimeout(id);
            delete this._timeoutIds[id];
        }
    }
    /**
     * SetImmediate override, which will auto cancel the immediate during dispose.
     * @param callback - Callback to execute.
     * @param targetElement - Optional target element to use for identifying the correct window.
     * @returns The setTimeout id.
     */
    setImmediate(callback, targetElement) {
        let immediateId = 0;
        const win = getWindow(targetElement);
        if (!this._isDisposed) {
            if (!this._immediateIds) {
                this._immediateIds = {};
            }
            let setImmediateCallback = () => {
                // Time to execute the timeout, enqueue it as a foreground task to be executed.
                try {
                    // Now delete the record and call the callback.
                    if (this._immediateIds) {
                        delete this._immediateIds[immediateId];
                    }
                    callback.apply(this._parent);
                }
                catch (e) {
                    this._logError(e);
                }
            };
            immediateId = win.setTimeout(setImmediateCallback, 0);
            this._immediateIds[immediateId] = true;
        }
        return immediateId;
    }
    /**
     * Clears the immediate.
     * @param id - Id to cancel.
     * @param targetElement - Optional target element to use for identifying the correct window.
     */
    clearImmediate(id, targetElement) {
        const win = getWindow(targetElement);
        if (this._immediateIds && this._immediateIds[id]) {
            win.clearTimeout(id);
            delete this._immediateIds[id];
        }
    }
    /**
     * SetInterval override, which will auto cancel the timeout during dispose.
     * @param callback - Callback to execute.
     * @param duration - Duration in milliseconds.
     * @returns The setTimeout id.
     */
    setInterval(callback, duration) {
        let intervalId = 0;
        if (!this._isDisposed) {
            if (!this._intervalIds) {
                this._intervalIds = {};
            }
            intervalId = setInterval(() => {
                // Time to execute the interval callback, enqueue it as a foreground task to be executed.
                try {
                    callback.apply(this._parent);
                }
                catch (e) {
                    this._logError(e);
                }
            }, duration);
            this._intervalIds[intervalId] = true;
        }
        return intervalId;
    }
    /**
     * Clears the interval.
     * @param id - Id to cancel.
     */
    clearInterval(id) {
        if (this._intervalIds && this._intervalIds[id]) {
            clearInterval(id);
            delete this._intervalIds[id];
        }
    }
    /**
     * Creates a function that, when executed, will only call the func function at most once per
     * every wait milliseconds. Provide an options object to indicate that func should be invoked
     * on the leading and/or trailing edge of the wait timeout. Subsequent calls to the throttled
     * function will return the result of the last func call.
     *
     * Note: If leading and trailing options are true func will be called on the trailing edge of
     * the timeout only if the throttled function is invoked more than once during the wait timeout.
     *
     * @param func - The function to throttle.
     * @param wait - The number of milliseconds to throttle executions to. Defaults to 0.
     * @param options - The options object.
     * @returns The new throttled function.
     */
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    throttle(func, wait, options) {
        if (this._isDisposed) {
            return this._noop;
        }
        let waitMS = wait || 0;
        let leading = true;
        let trailing = true;
        let lastExecuteTime = 0;
        let lastResult;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        let lastArgs;
        let timeoutId = null;
        if (options && typeof options.leading === 'boolean') {
            leading = options.leading;
        }
        if (options && typeof options.trailing === 'boolean') {
            trailing = options.trailing;
        }
        let callback = (userCall) => {
            let now = Date.now();
            let delta = now - lastExecuteTime;
            let waitLength = leading ? waitMS - delta : waitMS;
            if (delta >= waitMS && (!userCall || leading)) {
                lastExecuteTime = now;
                if (timeoutId) {
                    this.clearTimeout(timeoutId);
                    timeoutId = null;
                }
                lastResult = func.apply(this._parent, lastArgs);
            }
            else if (timeoutId === null && trailing) {
                timeoutId = this.setTimeout(callback, waitLength);
            }
            return lastResult;
        };
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        let resultFunction = ((...args) => {
            lastArgs = args;
            return callback(true);
        });
        return resultFunction;
    }
    /**
     * Creates a function that will delay the execution of func until after wait milliseconds have
     * elapsed since the last time it was invoked. Provide an options object to indicate that func
     * should be invoked on the leading and/or trailing edge of the wait timeout. Subsequent calls
     * to the debounced function will return the result of the last func call.
     *
     * Note: If leading and trailing options are true func will be called on the trailing edge of
     * the timeout only if the debounced function is invoked more than once during the wait
     * timeout.
     *
     * @param func - The function to debounce.
     * @param wait - The number of milliseconds to delay.
     * @param options - The options object.
     * @returns The new debounced function.
     */
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    debounce(func, wait, options) {
        if (this._isDisposed) {
            let noOpFunction = (() => {
                /** Do nothing */
            });
            noOpFunction.cancel = () => {
                return;
            };
            noOpFunction.flush = (() => null);
            noOpFunction.pending = () => false;
            return noOpFunction;
        }
        let waitMS = wait || 0;
        let leading = false;
        let trailing = true;
        let maxWait = null;
        let lastCallTime = 0;
        let lastExecuteTime = Date.now();
        let lastResult;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        let lastArgs;
        let timeoutId = null;
        if (options && typeof options.leading === 'boolean') {
            leading = options.leading;
        }
        if (options && typeof options.trailing === 'boolean') {
            trailing = options.trailing;
        }
        if (options && typeof options.maxWait === 'number' && !isNaN(options.maxWait)) {
            maxWait = options.maxWait;
        }
        let markExecuted = (time) => {
            if (timeoutId) {
                this.clearTimeout(timeoutId);
                timeoutId = null;
            }
            lastExecuteTime = time;
        };
        let invokeFunction = (time) => {
            markExecuted(time);
            lastResult = func.apply(this._parent, lastArgs);
        };
        let callback = (userCall) => {
            let now = Date.now();
            let executeImmediately = false;
            if (userCall) {
                if (leading && now - lastCallTime >= waitMS) {
                    executeImmediately = true;
                }
                lastCallTime = now;
            }
            let delta = now - lastCallTime;
            let waitLength = waitMS - delta;
            let maxWaitDelta = now - lastExecuteTime;
            let maxWaitExpired = false;
            if (maxWait !== null) {
                // maxWait only matters when there is a pending callback
                if (maxWaitDelta >= maxWait && timeoutId) {
                    maxWaitExpired = true;
                }
                else {
                    waitLength = Math.min(waitLength, maxWait - maxWaitDelta);
                }
            }
            if (delta >= waitMS || maxWaitExpired || executeImmediately) {
                invokeFunction(now);
            }
            else if ((timeoutId === null || !userCall) && trailing) {
                timeoutId = this.setTimeout(callback, waitLength);
            }
            return lastResult;
        };
        let pending = () => {
            return !!timeoutId;
        };
        let cancel = () => {
            if (pending()) {
                // Mark the debounced function as having executed
                markExecuted(Date.now());
            }
        };
        let flush = () => {
            if (pending()) {
                invokeFunction(Date.now());
            }
            return lastResult;
        };
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        let resultFunction = ((...args) => {
            lastArgs = args;
            return callback(true);
        });
        resultFunction.cancel = cancel;
        resultFunction.flush = flush;
        resultFunction.pending = pending;
        return resultFunction;
    }
    requestAnimationFrame(callback, targetElement) {
        let animationFrameId = 0;
        const win = getWindow(targetElement);
        if (!this._isDisposed) {
            if (!this._animationFrameIds) {
                this._animationFrameIds = {};
            }
            let animationFrameCallback = () => {
                try {
                    // Now delete the record and call the callback.
                    if (this._animationFrameIds) {
                        delete this._animationFrameIds[animationFrameId];
                    }
                    callback.apply(this._parent);
                }
                catch (e) {
                    this._logError(e);
                }
            };
            animationFrameId = win.requestAnimationFrame
                ? win.requestAnimationFrame(animationFrameCallback)
                : win.setTimeout(animationFrameCallback, 0);
            this._animationFrameIds[animationFrameId] = true;
        }
        return animationFrameId;
    }
    cancelAnimationFrame(id, targetElement) {
        const win = getWindow(targetElement);
        if (this._animationFrameIds && this._animationFrameIds[id]) {
            win.cancelAnimationFrame ? win.cancelAnimationFrame(id) : win.clearTimeout(id);
            delete this._animationFrameIds[id];
        }
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    _logError(e) {
        if (this._onErrorHandler) {
            this._onErrorHandler(e);
        }
    }
}
export function assign(target, ...args) {
    return filteredAssign.apply(this, [null, target].concat(args));
}
export function filteredAssign(isAllowed, target, ...args) {
    target = target || {};
    for (let sourceObject of args) {
        if (sourceObject) {
            for (let propName in sourceObject) {
                if (sourceObject.hasOwnProperty(propName) && (!isAllowed || isAllowed(propName))) {
                    target[propName] = sourceObject[propName];
                }
            }
        }
    }
    return target;
}
/** An instance of EventGroup allows anything with a handle to it to trigger events on it.
     *  If the target is an HTMLElement, the event will be attached to the element and can be
     *  triggered as usual (like clicking for onClick).
     *  The event can be triggered by calling EventGroup.raise() here. If the target is an
     *  HTMLElement, the event gets raised and is handled by the browser. Otherwise, it gets
     *  handled here in EventGroup, and the handler is called in the context of the parent
     *  (which is passed in in the constructor).
     *
     * @public
     * {@docCategory EventGroup}
     */
export class EventGroup {
    /** parent: the context in which events attached to non-HTMLElements are called */
    constructor(parent) {
        this._id = EventGroup._uniqueId++;
        this._parent = parent;
        this._eventRecords = [];
    }
    /** For IE8, bubbleEvent is ignored here and must be dealt with by the handler.
     *  Events raised here by default have bubbling set to false and cancelable set to true.
     *  This applies also to built-in events being raised manually here on HTMLElements,
     *  which may lead to unexpected behavior if it differs from the defaults.
     *
     */
    static raise(target, eventName, eventArgs, bubbleEvent) {
        let retVal;
        if (EventGroup._isElement(target)) {
            if (typeof document !== 'undefined' && document.createEvent) {
                let ev = document.createEvent('HTMLEvents');
                ev.initEvent(eventName, bubbleEvent || false, true);
                assign(ev, eventArgs);
                retVal = target.dispatchEvent(ev);
            }
            else if (typeof document !== 'undefined' && document.createEventObject) {
                // IE8
                let evObj = document.createEventObject(eventArgs);
                // cannot set cancelBubble on evObj, fireEvent will overwrite it
                target.fireEvent('on' + eventName, evObj);
            }
        }
        else {
            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
            // @ts-ignore  -- FIXME: strictBindCallApply error - https://github.com/microsoft/fluentui/issues/17331
            while (target && retVal !== false) {
                let events = target.__events__;
                let eventRecords = events ? events[eventName] : null;
                if (eventRecords) {
                    for (let id in eventRecords) {
                        if (eventRecords.hasOwnProperty(id)) {
                            let eventRecordList = eventRecords[id];
                            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                            // @ts-ignore  -- FIXME: strictBindCallApply error - https://github.com/microsoft/fluentui/issues/17331
                            for (let listIndex = 0; retVal !== false && listIndex < eventRecordList.length; listIndex++) {
                                let record = eventRecordList[listIndex];
                                if (record.objectCallback) {
                                    retVal = record.objectCallback.call(record.parent, eventArgs);
                                }
                            }
                        }
                    }
                }
                // If the target has a parent, bubble the event up.
                target = bubbleEvent ? target.parent : null;
            }
        }
        return retVal;
    }
    static isObserved(target, eventName) {
        let events = target && target.__events__;
        return !!events && !!events[eventName];
    }
    /** Check to see if the target has declared support of the given event. */
    static isDeclared(target, eventName) {
        let declaredEvents = target && target.__declaredEvents;
        return !!declaredEvents && !!declaredEvents[eventName];
    }
    static stopPropagation(event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        }
        else {
            // IE8
            event.cancelBubble = true;
        }
    }
    static _isElement(target) {
        return (!!target && (!!target.addEventListener || (typeof HTMLElement !== 'undefined' && target instanceof HTMLElement)));
    }
    dispose() {
        if (!this._isDisposed) {
            this._isDisposed = true;
            this.off();
            this._parent = null;
        }
    }
    /** On the target, attach a set of events, where the events object is a name to function mapping. */
    onAll(target, events, useCapture) {
        for (let eventName in events) {
            if (events.hasOwnProperty(eventName)) {
                this.on(target, eventName, events[eventName], useCapture);
            }
        }
    }
    /**
     * On the target, attach an event whose handler will be called in the context of the parent
     * of this instance of EventGroup.
     */
    on(target, eventName, callback, options) {
        if (eventName.indexOf(',') > -1) {
            let events = eventName.split(/[ ,]+/);
            for (let i = 0; i < events.length; i++) {
                this.on(target, events[i], callback, options);
            }
        }
        else {
            let parent = this._parent;
            let eventRecord = {
                target: target,
                eventName: eventName,
                parent: parent,
                callback: callback,
                options,
            };
            // Initialize and wire up the record on the target, so that it can call the callback if the event fires.
            let events = (target.__events__ = target.__events__ || {});
            events[eventName] =
                events[eventName] ||
                    {
                        count: 0,
                    };
            events[eventName][this._id] = events[eventName][this._id] || [];
            events[eventName][this._id].push(eventRecord);
            events[eventName].count++;
            if (EventGroup._isElement(target)) {
                let processElementEvent = (...args) => {
                    if (this._isDisposed) {
                        return;
                    }
                    let result;
                    try {
                        result = callback.apply(parent, args);
                        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                        // @ts-ignore  -- FIXME: strictBindCallApply error - https://github.com/microsoft/fluentui/issues/17331
                        if (result === false && args[0]) {
                            let e = args[0];
                            if (e.preventDefault) {
                                e.preventDefault();
                            }
                            if (e.stopPropagation) {
                                e.stopPropagation();
                            }
                            e.cancelBubble = true;
                        }
                    }
                    catch (e) {
                        // ignore
                    }
                    return result;
                };
                eventRecord.elementCallback = processElementEvent;
                if (target.addEventListener) {
                    target.addEventListener(eventName, processElementEvent, options);
                }
                else if (target.attachEvent) {
                    // IE8
                    target.attachEvent('on' + eventName, processElementEvent);
                }
            }
            else {
                let processObjectEvent = (...args) => {
                    if (this._isDisposed) {
                        return;
                    }
                    return callback.apply(parent, args);
                };
                eventRecord.objectCallback = processObjectEvent;
            }
            // Remember the record locally, so that it can be removed.
            this._eventRecords.push(eventRecord);
        }
    }
    off(target, eventName, callback, options) {
        for (let i = 0; i < this._eventRecords.length; i++) {
            let eventRecord = this._eventRecords[i];
            if ((!target || target === eventRecord.target) &&
                (!eventName || eventName === eventRecord.eventName) &&
                (!callback || callback === eventRecord.callback) &&
                (typeof options !== 'boolean' || options === eventRecord.options)) {
                let events = eventRecord.target.__events__;
                let targetArrayLookup = events[eventRecord.eventName];
                let targetArray = targetArrayLookup ? targetArrayLookup[this._id] : null;
                // We may have already target's entries, so check for null.
                if (targetArray) {
                    if (targetArray.length === 1 || !callback) {
                        targetArrayLookup.count -= targetArray.length;
                        delete events[eventRecord.eventName][this._id];
                    }
                    else {
                        targetArrayLookup.count--;
                        targetArray.splice(targetArray.indexOf(eventRecord), 1);
                    }
                    if (!targetArrayLookup.count) {
                        delete events[eventRecord.eventName];
                    }
                }
                if (eventRecord.elementCallback) {
                    if (eventRecord.target.removeEventListener) {
                        eventRecord.target.removeEventListener(eventRecord.eventName, eventRecord.elementCallback, eventRecord.options);
                    }
                    else if (eventRecord.target.detachEvent) {
                        // IE8
                        eventRecord.target.detachEvent('on' + eventRecord.eventName, eventRecord.elementCallback);
                    }
                }
                this._eventRecords.splice(i--, 1);
            }
        }
    }
    /** Trigger the given event in the context of this instance of EventGroup. */
    raise(eventName, eventArgs, bubbleEvent) {
        return EventGroup.raise(this._parent, eventName, eventArgs, bubbleEvent);
    }
    /** Declare an event as being supported by this instance of EventGroup. */
    declare(event) {
        let declaredEvents = (this._parent.__declaredEvents = this._parent.__declaredEvents || {});
        if (typeof event === 'string') {
            declaredEvents[event] = true;
        }
        else {
            for (let i = 0; i < event.length; i++) {
                declaredEvents[event[i]] = true;
            }
        }
    }
}
EventGroup._uniqueId = 0;
// Workaround to prevent default on keypress until we can do it in Blazor conditionally without javascript
// https://stackoverflow.com/questions/24386354/execute-js-code-after-pressing-the-spacebar
window.addEventListener("load", function () {
    //This will be called when a key is pressed
    var preventDefaultOnSpaceCallback = function (e) {
        if (e.keyCode === 32 || e.key === " ") {
            // console.log("Prevented default.")
            e.preventDefault();
            return false;
        }
    };
    //This will add key event listener on all nodes with the class preventSpace.
    function setupPreventDefaultOnSpaceOnNode(node, add) {
        if (node instanceof HTMLElement) {
            var el = node;
            //Check if main element contains class
            if (el.classList.contains("prevent-default-on-space") && add) {
                // console.log("Adding preventer: " + el.id);
                el.addEventListener('keydown', preventDefaultOnSpaceCallback, false);
            }
            else {
                // console.log("Removing preventer: " + el.id);
                el.removeEventListener('keydown', preventDefaultOnSpaceCallback, false);
            }
        }
    }
    //This will add key event listener on all nodes with the class preventSpace.
    function setupPreventDefaultOnEnterOnElements(nodelist, add) {
        for (var i = 0; i < nodelist.length; i++) {
            var node = nodelist[i];
            if (node instanceof HTMLElement) {
                var el = node;
                //Check if main element contains class
                setupPreventDefaultOnSpaceOnNode(node, add);
                //Check if any child nodes contains class
                var elements = el.getElementsByClassName("prevent-default-on-space");
                for (var i_1 = 0; i_1 < elements.length; i_1++) {
                    setupPreventDefaultOnSpaceOnNode(elements[i_1], add);
                }
            }
        }
    }
    // Create an observer instance linked to the callback function
    // Read more: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
    var preventDefaultOnEnterObserver = new MutationObserver(function (mutations) {
        for (var _i = 0, mutations_1 = mutations; _i < mutations_1.length; _i++) {
            var mutation = mutations_1[_i];
            if (mutation.type === 'childList') {
                // A child node has been added or removed.
                setupPreventDefaultOnEnterOnElements(mutation.addedNodes, true);
            }
            else if (mutation.type === 'attributes') {
                if (mutation.attributeName === "class") {
                    //console.log('The ' + mutation.attributeName + ' attribute was modified on' + (mutation.target as any).id);
                    //class was modified on this node. Remove previous event handler (if any).
                    setupPreventDefaultOnSpaceOnNode(mutation.target, false);
                    //And add event handler if class i specified.
                    setupPreventDefaultOnSpaceOnNode(mutation.target, true);
                }
            }
        }
    });
    // Only observe changes in nodes in the whole tree, but do not observe attributes.
    var preventDefaultOnEnterObserverConfig = { subtree: true, childList: true, attributes: true };
    // Start observing the target node for configured mutations
    preventDefaultOnEnterObserver.observe(document, preventDefaultOnEnterObserverConfig);
    //Also check all elements when loaded.
    setupPreventDefaultOnEnterOnElements(document.getElementsByClassName("prevent-default-on-space"), true);
});