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/focusTrapZone.js
import * as FluentUIBaseComponent from './baseComponent.js';
const HIDDEN_FROM_ACC_TREE = 'data-is-hidden-from-acc-tree';
class FocusTrapZoneInternal {
    constructor(focusTrapZoneProps, dotNetRef) {
        this._hasFocus = true;
        this._onRootFocus = (ev) => {
            //if (this._props.onFocus) {
            //    this._props.onFocus(ev);
            //}
            this._hasFocus = true;
        };
        this._onRootBlur = (ev) => {
            //if (this.props.onBlur) {
            //    this.props.onBlur(ev);
            //}
            let relatedTarget = ev.relatedTarget;
            if (ev.relatedTarget === null) {
                // In IE11, due to lack of support, event.relatedTarget is always
                // null making every onBlur call to be "outside" of the ComboBox
                // even when it's not. Using document.activeElement is another way
                // for us to be able to get what the relatedTarget without relying
                // on the event
                relatedTarget = document.activeElement;
            }
            if (!FluentUIBaseComponent.elementContains(this._props.rootElement, relatedTarget)) {
                this._hasFocus = false;
            }
        };
        this._onFirstBumperFocus = () => {
            this._onBumperFocus(true);
        };
        this._onLastBumperFocus = () => {
            this._onBumperFocus(false);
        };
        this._onBumperFocus = (isFirstBumper) => {
            if (!this._props.rootElement) {
                return;
            }
            const currentBumper = (isFirstBumper === this._hasFocus ? this._props.lastBumper : this._props.firstBumper);
            if (this._props.rootElement) {
                const nextFocusable = isFirstBumper === this._hasFocus
                    ? FluentUIBaseComponent.getLastTabbable(this._props.rootElement, currentBumper, true, false)
                    : FluentUIBaseComponent.getFirstTabbable(this._props.rootElement, currentBumper, true, false);
                if (nextFocusable) {
                    if (this._isBumper(nextFocusable)) {
                        // This can happen when FTZ contains no tabbable elements. focus will take care of finding a focusable element in FTZ.
                        this._findElementAndFocusAsync();
                    }
                    else {
                        nextFocusable.focus();
                    }
                }
            }
        };
        this._enableFocusTrapZone = () => {
            const { disabled = false } = this._props;
            if (disabled) {
                return;
            }
            FocusTrapZoneInternal._focusStack.push(this);
            this._bringFocusIntoZone();
            this._hideContentFromAccessibilityTree();
        };
        this._releaseFocusTrapZone = () => {
            const { ignoreExternalFocusing } = this._props;
            FocusTrapZoneInternal._focusStack = FocusTrapZoneInternal._focusStack.filter((value) => {
                return this !== value;
            });
            // try to focus element which triggered FocusTrapZone - prviously focused element outside trap zone
            //const doc = getDocument(this._props.rootElement);
            // @ts-ignore
            const activeElement = document.activeElement;
            if (!ignoreExternalFocusing &&
                this._previouslyFocusedElementOutsideTrapZone &&
                // @ts-ignore
                (this._props.rootElement.contains(activeElement) || activeElement === document.body)) {
                this._focusAsync(this._previouslyFocusedElementOutsideTrapZone);
            }
            // if last active focus trap zone is going to be released - show previously hidden content in accessibility tree
            const lastActiveFocusTrap = FocusTrapZoneInternal._focusStack.length && FocusTrapZoneInternal._focusStack[FocusTrapZoneInternal._focusStack.length - 1];
            if (!lastActiveFocusTrap) {
                this._showContentInAccessibilityTree();
            }
            else if (lastActiveFocusTrap._props.rootElement &&
                lastActiveFocusTrap._props.rootElement.hasAttribute(HIDDEN_FROM_ACC_TREE)) {
                lastActiveFocusTrap._props.rootElement?.removeAttribute(HIDDEN_FROM_ACC_TREE);
                lastActiveFocusTrap._props.rootElement?.removeAttribute('aria-hidden');
            }
        };
        this._findElementAndFocusAsync = () => {
            if (!this._props.rootElement) {
                return;
            }
            const { focusPreviouslyFocusedInnerElement, firstFocusableSelector } = this._props;
            if (focusPreviouslyFocusedInnerElement &&
                this._previouslyFocusedElementInTrapZone &&
                this._props.rootElement.contains(this._previouslyFocusedElementInTrapZone)) {
                // focus on the last item that had focus in the zone before we left the zone
                this._focusAsync(this._previouslyFocusedElementInTrapZone);
                return;
            }
            const focusSelector = firstFocusableSelector &&
                (typeof firstFocusableSelector === 'string' ? firstFocusableSelector : firstFocusableSelector());
            let firstFocusableChild = null;
            if (focusSelector) {
                firstFocusableChild = this._props.rootElement.querySelector(focusSelector);
            }
            // Fall back to first element if query selector did not match any elements.
            if (!firstFocusableChild) {
                firstFocusableChild = FluentUIBaseComponent.getNextElement(this._props.rootElement, this._props.rootElement.firstChild, false, false, false, true);
            }
            firstFocusableChild && this._focusAsync(firstFocusableChild);
        };
        this._onFocusCapture = (ev) => {
            //this._props.onFocusCapture && this._props.onFocusCapture(ev);
            if (ev.target !== ev.currentTarget && !this._isBumper(ev.target)) {
                // every time focus changes within the trap zone, remember the focused element so that
                // it can be restored if focus leaves the pane and returns via keystroke (i.e. via a call to this.focus(true))
                this._previouslyFocusedElementInTrapZone = ev.target;
            }
        };
        this._forceFocusInTrap = (ev, triggeredElement) => {
            if (FocusTrapZoneInternal._focusStack.length && this === FocusTrapZoneInternal._focusStack[FocusTrapZoneInternal._focusStack.length - 1]) {
                // @ts-ignore
                if (!this._props.rootElement.contains(triggeredElement)) {
                    this._findElementAndFocusAsync();
                    ev.preventDefault();
                    ev.stopPropagation();
                }
            }
        };
        this._handleOutsideFocus = (ev) => {
            // @ts-ignore
            const focusedElement = document.activeElement;
            focusedElement && this._forceFocusInTrap(ev, focusedElement);
        };
        this._handleOutsideClick = (ev) => {
            const clickedElement = ev.target;
            const { isClickableOutsideFocusTrap, focusTriggerOnOutsideClick } = this._props;
            if (!isClickableOutsideFocusTrap) {
                clickedElement && this._forceFocusInTrap(ev, clickedElement);
            }
            else if (!focusTriggerOnOutsideClick) {
                const isOutsideFocusTrapZone = this._props.rootElement && !this._props.rootElement.contains(clickedElement);
                const isOutsideTriggerElement = this._previouslyFocusedElementOutsideTrapZone &&
                    !this._previouslyFocusedElementOutsideTrapZone.contains(clickedElement);
                if (isOutsideFocusTrapZone && isOutsideTriggerElement) {
                    // set it to NULL, so the trigger will not be focused on componentWillUnmount
                    // @ts-ignore
                    this._previouslyFocusedElementOutsideTrapZone = null;
                }
            }
        };
        this._onKeyboardHandler = (ev) => {
            //if (this._props.onKeyDown) {
            //    this._props.onKeyDown(ev);
            //}
            // do not propogate keyboard events outside focus trap zone
            // https://github.com/microsoft/fluent-ui-react/pull/1180
            ev.stopPropagation();
        };
        this._getPreviouslyFocusedElementOutsideTrapZone = () => {
            const { elementToFocusOnDismiss } = this._props;
            let previouslyFocusedElement = this._previouslyFocusedElementOutsideTrapZone;
            if (elementToFocusOnDismiss && previouslyFocusedElement !== elementToFocusOnDismiss) {
                previouslyFocusedElement = elementToFocusOnDismiss;
            }
            else if (!previouslyFocusedElement) {
                // @ts-ignore
                previouslyFocusedElement = document.activeElement;
            }
            return previouslyFocusedElement;
        };
        this._hideContentFromAccessibilityTree = () => {
            const doc = document;
            // @ts-ignore
            const bodyChildren = (doc.body && doc.body.children) || [];
            // @ts-ignore
            if (bodyChildren.length && !doc.body.contains(this._props.rootElement)) {
                // In case popup render options will change
                /* eslint-disable-next-line no-console */
                console.warn('Body element does not contain trap zone element. Please, ensure the trap zone element is placed inside body, so it will work properly.');
            }
            for (let index = 0; index < bodyChildren.length; index++) {
                const currentChild = bodyChildren[index];
                const isOrHasFocusTrapZone = currentChild === this._props.rootElement || currentChild.contains(this._props.rootElement);
                const isAriaLiveRegion = currentChild.hasAttribute('aria-live');
                if (!isOrHasFocusTrapZone && !isAriaLiveRegion && currentChild.getAttribute('aria-hidden') !== 'true') {
                    currentChild.setAttribute('aria-hidden', 'true');
                    currentChild.setAttribute(HIDDEN_FROM_ACC_TREE, 'true');
                }
            }
        };
        this._showContentInAccessibilityTree = () => {
            const doc = document;
            // @ts-ignore
            const hiddenElements = doc.querySelectorAll(`[${HIDDEN_FROM_ACC_TREE}="true"]`);
            for (let index = 0; index < hiddenElements.length; index++) {
                const element = hiddenElements[index];
                element.removeAttribute('aria-hidden');
                element.removeAttribute(HIDDEN_FROM_ACC_TREE);
            }
        };
        this._props = focusTrapZoneProps;
        this._dotNetRef = dotNetRef;
        this._props.rootElement?.addEventListener("focus", this._onRootFocus, false);
        this._props.rootElement?.addEventListener("blur", this._onRootBlur, false);
        this._props.firstBumper?.addEventListener("focus", this._onFirstBumperFocus, false);
        this._props.lastBumper?.addEventListener("focus", this._onLastBumperFocus, false);
        //this._bringFocusIntoZone();
    }
    unRegister() {
        const activeElement = document.activeElement;
        this._props.rootElement?.removeEventListener("focus", this._onRootFocus, false);
        this._props.rootElement?.removeEventListener("blur", this._onRootBlur, false);
        this._props.firstBumper?.removeEventListener("focus", this._onFirstBumperFocus, false);
        this._props.lastBumper?.removeEventListener("focus", this._onLastBumperFocus, false);
        if (!this._props.disabled ||
            this._props.forceFocusInsideTrapOnOutsideFocus ||
            // @ts-ignore
            !FluentUIBaseComponent.elementContains(this._props.rootElement, activeElement)) {
            this._releaseFocusTrapZone();
        }
        // Dispose of element references so the DOM Nodes can be garbage-collected
        delete this._previouslyFocusedElementInTrapZone;
        delete this._previouslyFocusedElementOutsideTrapZone;
    }
    updateProps(prevProps) {
        const { forceFocusInsideTrapOnComponentUpdate, forceFocusInsideTrapOnOutsideFocus, disabled } = this._props;
        // @ts-ignore
        const activeElement = document.activeElement;
        // if after componentDidUpdate focus is not inside the focus trap, bring it back
        if (!disabled &&
            // @ts-ignore
            !FluentUIBaseComponent.elementContains(this._props.rootElement, activeElement) &&
            forceFocusInsideTrapOnComponentUpdate) {
            this._bringFocusIntoZone();
            return;
        }
        const prevForceFocusInsideTrap = prevProps.forceFocusInsideTrapOnOutsideFocus !== undefined ? prevProps.forceFocusInsideTrapOnOutsideFocus : true;
        const newForceFocusInsideTrap = forceFocusInsideTrapOnOutsideFocus !== undefined ? forceFocusInsideTrapOnOutsideFocus : true;
        const prevDisabled = prevProps.disabled !== undefined ? prevProps.disabled : false;
        const newDisabled = disabled !== undefined ? disabled : false;
        if ((!prevForceFocusInsideTrap && newForceFocusInsideTrap) || (prevDisabled && !newDisabled)) {
            // Transition from forceFocusInsideTrap / FTZ disabled to enabled.
            // Emulate what happens when a FocusTrapZone gets mounted.
            this._enableFocusTrapZone();
        }
        else if ((prevForceFocusInsideTrap && !newForceFocusInsideTrap) || (!prevDisabled && newDisabled)) {
            // Transition from forceFocusInsideTrap / FTZ enabled to disabled.
            // Emulate what happens when a FocusTrapZone gets unmounted.
            this._releaseFocusTrapZone();
        }
    }
    setDisabled(disabled) {
        this._props.disabled = disabled;
    }
    _isBumper(element) {
        return element === this._props.firstBumper || element === this._props.lastBumper;
    }
    _focusAsync(element) {
        if (!this._isBumper(element)) {
            FluentUIBaseComponent.focusAsync(element);
        }
    }
    _bringFocusIntoZone() {
        const { disableFirstFocus = false } = this._props;
        this._previouslyFocusedElementOutsideTrapZone = this._getPreviouslyFocusedElementOutsideTrapZone();
        if (
        // @ts-ignore
        FluentUIBaseComponent.elementContains(this._props.rootElement, this._previouslyFocusedElementOutsideTrapZone) &&
            !disableFirstFocus) {
            this._findElementAndFocusAsync();
        }
    }
    _returnFocusToInitiator() {
        const { ignoreExternalFocusing, rootElement } = this._props;
        FocusTrapZoneInternal._focusStack = FocusTrapZoneInternal._focusStack.filter((value) => {
            return this !== value;
        });
        const activeElement = document.activeElement;
        if (!ignoreExternalFocusing &&
            this._previouslyFocusedElementOutsideTrapZone &&
            typeof this._previouslyFocusedElementOutsideTrapZone.focus === 'function' &&
            (FluentUIBaseComponent.elementContains(rootElement, activeElement) || activeElement === document.body)) {
            this._focusAsync(this._previouslyFocusedElementOutsideTrapZone);
        }
    }
}
FocusTrapZoneInternal._focusStack = [];
var count = 0;
var focusTrapZones = {};
export function register(props, focusTrapZone) {
    let currentId = count++;
    focusTrapZones[currentId] = new FocusTrapZoneInternal(props, focusTrapZone);
    return currentId;
}
export function unregister(id) {
    let focusTrapZone = focusTrapZones[id];
    if (focusTrapZone) {
        focusTrapZone.unRegister();
    }
    delete focusTrapZones[id];
}
export function updateProps(id, props) {
    let focusTrapZone = focusTrapZones[id];
    if (focusTrapZone) {
        focusTrapZone.updateProps(props);
    }
}
let targetToFocusOnNextRepaint = undefined;