/**
 * DevExtreme (cjs/__internal/ui/context_menu/m_context_menu.js)
 * Version: 24.1.7-build-24272-1937
 * Build date: Sat Sep 28 2024
 *
 * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.default = void 0;
var _fx = _interopRequireDefault(require("../../../animation/fx"));
var _position = _interopRequireDefault(require("../../../animation/position"));
var _component_registrator = _interopRequireDefault(require("../../../core/component_registrator"));
var _devices = _interopRequireDefault(require("../../../core/devices"));
var _dom_adapter = _interopRequireDefault(require("../../../core/dom_adapter"));
var _element = require("../../../core/element");
var _guid = _interopRequireDefault(require("../../../core/guid"));
var _renderer = _interopRequireDefault(require("../../../core/renderer"));
var _common = require("../../../core/utils/common");
var _deferred = require("../../../core/utils/deferred");
var _dom = require("../../../core/utils/dom");
var _extend = require("../../../core/utils/extend");
var _iterator = require("../../../core/utils/iterator");
var _size = require("../../../core/utils/size");
var _type = require("../../../core/utils/type");
var _window = require("../../../core/utils/window");
var _contextmenu = require("../../../events/contextmenu");
var _events_engine = _interopRequireDefault(require("../../../events/core/events_engine"));
var _hold = _interopRequireDefault(require("../../../events/hold"));
var _index = require("../../../events/utils/index");
var _ui = _interopRequireDefault(require("../../../ui/overlay/ui.overlay"));
var _ui2 = _interopRequireDefault(require("../../../ui/scroll_view/ui.scrollable"));
var _themes = require("../../../ui/themes");
var _m_menu_base = _interopRequireDefault(require("../../ui/context_menu/m_menu_base"));

function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    }
}
const DX_MENU_CLASS = "dx-menu";
const DX_MENU_ITEM_CLASS = "dx-menu-item";
const DX_MENU_ITEM_EXPANDED_CLASS = "dx-menu-item-expanded";
const DX_MENU_PHONE_CLASS = "dx-menu-phone-overlay";
const DX_MENU_ITEMS_CONTAINER_CLASS = "dx-menu-items-container";
const DX_MENU_ITEM_WRAPPER_CLASS = "dx-menu-item-wrapper";
const DX_SUBMENU_CLASS = "dx-submenu";
const DX_CONTEXT_MENU_CLASS = "dx-context-menu";
const DX_HAS_CONTEXT_MENU_CLASS = "dx-has-context-menu";
const DX_STATE_DISABLED_CLASS = "dx-state-disabled";
const DX_STATE_FOCUSED_CLASS = "dx-state-focused";
const DX_STATE_HOVER_CLASS = "dx-state-hover";
const OVERLAY_CONTENT_CLASS = "dx-overlay-content";
const SCROLLABLE_CLASS = "dx-scrollable";
const FOCUS_UP = "up";
const FOCUS_DOWN = "down";
const FOCUS_LEFT = "left";
const FOCUS_RIGHT = "right";
const FOCUS_FIRST = "first";
const FOCUS_LAST = "last";
const ACTIONS = ["onShowing", "onShown", "onSubmenuCreated", "onHiding", "onHidden", "onPositioning", "onLeftFirstItem", "onLeftLastItem", "onCloseRootSubmenu", "onExpandLastSubmenu"];
const LOCAL_SUBMENU_DIRECTIONS = ["up", "down", "first", "last"];
const DEFAULT_SHOW_EVENT = "dxcontextmenu";
const SUBMENU_PADDING = 10;
const BORDER_WIDTH = 1;
const window = (0, _window.getWindow)();
class ContextMenu extends _m_menu_base.default {
    getShowEvent(showEventOption) {
        if ((0, _type.isObject)(showEventOption)) {
            if (null !== showEventOption.name) {
                return showEventOption.name ?? "dxcontextmenu"
            }
        } else {
            return showEventOption
        }
        return null
    }
    getShowDelay(showEventOption) {
        return (0, _type.isObject)(showEventOption) && showEventOption.delay
    }
    _getDefaultOptions() {
        return (0, _extend.extend)(super._getDefaultOptions(), {
            showEvent: "dxcontextmenu",
            hideOnOutsideClick: true,
            position: {
                at: "top left",
                my: "top left"
            },
            onShowing: null,
            onShown: null,
            onSubmenuCreated: null,
            onHiding: null,
            onHidden: null,
            onPositioning: null,
            submenuDirection: "auto",
            visible: false,
            target: void 0,
            onLeftFirstItem: null,
            onLeftLastItem: null,
            onCloseRootSubmenu: null,
            onExpandLastSubmenu: null
        })
    }
    _defaultOptionsRules() {
        return super._defaultOptionsRules().concat([{
            device: () => !(0, _window.hasWindow)(),
            options: {
                animation: null
            }
        }])
    }
    _setDeprecatedOptions() {
        super._setDeprecatedOptions();
        (0, _extend.extend)(this._deprecatedOptions, {
            closeOnOutsideClick: {
                since: "22.2",
                alias: "hideOnOutsideClick"
            }
        })
    }
    _initActions() {
        this._actions = {};
        (0, _iterator.each)(ACTIONS, ((index, action) => {
            this._actions[action] = this._createActionByOption(action) || _common.noop
        }))
    }
    _setOptionsByReference() {
        super._setOptionsByReference();
        (0, _extend.extend)(this._optionsByReference, {
            animation: true,
            selectedItem: true
        })
    }
    _focusInHandler() {}
    _itemContainer() {
        return this._overlay ? this._overlay.$content() : (0, _renderer.default)()
    }
    _eventBindingTarget() {
        return this._itemContainer()
    }
    itemsContainer() {
        return this._overlay ? this._overlay.$content() : void 0
    }
    _supportedKeys() {
        return (0, _extend.extend)(super._supportedKeys(), {
            space: () => {
                const $item = (0, _renderer.default)(this.option("focusedElement"));
                this.hide();
                if (!$item.length || !this._isSelectionEnabled()) {
                    return
                }
                this.selectItem($item[0])
            },
            escape: this.hide
        })
    }
    _getActiveItem(last) {
        const $availableItems = this._getAvailableItems();
        const $focusedItem = $availableItems.filter(".dx-state-focused");
        const $hoveredItem = $availableItems.filter(".dx-state-hover");
        const $hoveredItemContainer = $hoveredItem.closest(".dx-menu-items-container");
        if ($hoveredItemContainer.find(".dx-menu-item").index($focusedItem) >= 0) {
            return $focusedItem
        }
        if ($hoveredItem.length) {
            return $hoveredItem
        }
        return super._getActiveItem()
    }
    _moveFocus(location) {
        const $items = this._getItemsByLocation(location);
        const $oldTarget = this._getActiveItem(true);
        const $hoveredItem = this.itemsContainer().find(".dx-state-hover");
        const $focusedItem = (0, _renderer.default)(this.option("focusedElement"));
        const $activeItemHighlighted = !!($focusedItem.length || $hoveredItem.length);
        let $newTarget;
        switch (location) {
            case "up":
                $newTarget = $activeItemHighlighted ? this._prevItem($items) : $oldTarget;
                this._setFocusedElement($newTarget);
                if ($oldTarget.is($items.first())) {
                    this._actions.onLeftFirstItem($oldTarget)
                }
                break;
            case "down":
                $newTarget = $activeItemHighlighted ? this._nextItem($items) : $oldTarget;
                this._setFocusedElement($newTarget);
                if ($oldTarget.is($items.last())) {
                    this._actions.onLeftLastItem($oldTarget)
                }
                break;
            case "right":
                $newTarget = this.option("rtlEnabled") ? this._hideSubmenuHandler() : this._expandSubmenuHandler($items, location);
                this._setFocusedElement($newTarget);
                break;
            case "left":
                $newTarget = this.option("rtlEnabled") ? this._expandSubmenuHandler($items, location) : this._hideSubmenuHandler();
                this._setFocusedElement($newTarget);
                break;
            case "first":
                $newTarget = $items.first();
                this._setFocusedElement($newTarget);
                break;
            case "last":
                $newTarget = $items.last();
                this._setFocusedElement($newTarget);
                break;
            default:
                return super._moveFocus(location)
        }
    }
    _setFocusedElement($element) {
        if ($element && 0 !== $element.length) {
            this.option("focusedElement", (0, _element.getPublicElement)($element));
            this._scrollToElement($element)
        }
    }
    _scrollToElement($element) {
        const $scrollableElement = $element.closest(".dx-scrollable");
        const scrollableInstance = $scrollableElement.dxScrollable("instance");
        null === scrollableInstance || void 0 === scrollableInstance || scrollableInstance.scrollToElement($element)
    }
    _getItemsByLocation(location) {
        const $activeItem = this._getActiveItem(true);
        let $items;
        if (LOCAL_SUBMENU_DIRECTIONS.includes(location)) {
            $items = $activeItem.closest(".dx-menu-items-container").children().children()
        }
        $items = this._getAvailableItems($items);
        return $items
    }
    _getAriaTarget() {
        return this.$element()
    }
    _refreshActiveDescendant() {
        if ((0, _type.isDefined)(this._overlay)) {
            const $target = this._overlay.$content();
            super._refreshActiveDescendant($target)
        }
    }
    _hideSubmenuHandler() {
        const $curItem = this._getActiveItem(true);
        const $parentItem = $curItem.parents(".dx-menu-item-expanded").first();
        if ($parentItem.length) {
            this._hideSubmenusOnSameLevel($parentItem);
            this._hideSubmenu($curItem.closest(".dx-submenu"));
            return $parentItem
        }
        this._actions.onCloseRootSubmenu($curItem)
    }
    _expandSubmenuHandler($items, location) {
        const $curItem = this._getActiveItem(true);
        const itemData = this._getItemData($curItem);
        const node = this._dataAdapter.getNodeByItem(itemData);
        const isItemHasSubmenu = this._hasSubmenu(node);
        const $submenu = $curItem.children(".dx-submenu");
        if (isItemHasSubmenu && !$curItem.hasClass("dx-state-disabled")) {
            if (!$submenu.length || "hidden" === $submenu.css("visibility")) {
                this._showSubmenu($curItem)
            }
            return this._nextItem(this._getItemsByLocation(location))
        }
        this._actions.onExpandLastSubmenu($curItem);
        return
    }
    _clean() {
        if (this._overlay) {
            this._overlay.$element().remove();
            this._overlay = null
        }
        this._detachShowContextMenuEvents(this._getTarget());
        super._clean()
    }
    _initMarkup() {
        this.$element().addClass("dx-has-context-menu");
        super._initMarkup()
    }
    _render() {
        super._render();
        this._renderVisibility(this.option("visible"));
        this._addWidgetClass()
    }
    _isTargetOutOfComponent(relatedTarget) {
        const isInsideContextMenu = 0 !== (0, _renderer.default)(relatedTarget).closest(".dx-context-menu").length;
        return !isInsideContextMenu
    }
    _focusOutHandler(e) {
        const {
            relatedTarget: relatedTarget
        } = e;
        if (relatedTarget) {
            const isTargetOutside = this._isTargetOutOfComponent(relatedTarget);
            if (isTargetOutside) {
                this.hide()
            }
        }
        super._focusOutHandler(e)
    }
    _renderContentImpl() {
        this._detachShowContextMenuEvents(this._getTarget());
        this._attachShowContextMenuEvents()
    }
    _attachKeyboardEvents() {
        !this._keyboardListenerId && this._focusTarget().length && super._attachKeyboardEvents()
    }
    _renderContextMenuOverlay() {
        if (this._overlay) {
            return
        }
        const overlayOptions = this._getOverlayOptions();
        this._overlay = this._createComponent((0, _renderer.default)("<div>").appendTo(this._$element), _ui.default, overlayOptions);
        const $overlayContent = this._overlay.$content();
        $overlayContent.addClass("dx-context-menu");
        this._addCustomCssClass($overlayContent);
        this._addPlatformDependentClass($overlayContent);
        this._attachContextMenuEvent()
    }
    preventShowingDefaultContextMenuAboveOverlay() {
        const $itemContainer = this._itemContainer();
        const eventName = (0, _index.addNamespace)(_contextmenu.name, this.NAME);
        _events_engine.default.off($itemContainer, eventName, ".dx-submenu");
        _events_engine.default.on($itemContainer, eventName, ".dx-submenu", (e => {
            e.stopPropagation();
            e.preventDefault();
            _events_engine.default.off($itemContainer, eventName, ".dx-submenu")
        }))
    }
    _itemContextMenuHandler(e) {
        super._itemContextMenuHandler(e);
        e.stopPropagation()
    }
    _addPlatformDependentClass($element) {
        if (_devices.default.current().phone) {
            $element.addClass(DX_MENU_PHONE_CLASS)
        }
    }
    _detachShowContextMenuEvents(target) {
        const showEvent = this.getShowEvent(this.option("showEvent"));
        if (!showEvent) {
            return
        }
        const eventName = (0, _index.addNamespace)(showEvent, this.NAME);
        if (this._showContextMenuEventHandler) {
            _events_engine.default.off(_dom_adapter.default.getDocument(), eventName, target, this._showContextMenuEventHandler)
        } else {
            _events_engine.default.off((0, _renderer.default)(target), eventName)
        }
    }
    _attachShowContextMenuEvents() {
        const target = this._getTarget();
        const showEvent = this.getShowEvent(this.option("showEvent"));
        if (!showEvent) {
            return
        }
        const eventName = (0, _index.addNamespace)(showEvent, this.NAME);
        let contextMenuAction = this._createAction((e => {
            const delay = this.getShowDelay(this.option("showEvent"));
            if (delay) {
                setTimeout((() => this._show(e.event)), delay)
            } else {
                this._show(e.event)
            }
        }), {
            validatingTargetName: "target"
        });
        const handler = e => contextMenuAction({
            event: e,
            target: (0, _renderer.default)(e.currentTarget)
        });
        contextMenuAction = this._createAction(contextMenuAction);
        if ((0, _type.isRenderer)(target) || target.nodeType || (0, _type.isWindow)(target)) {
            this._showContextMenuEventHandler = void 0;
            _events_engine.default.on(target, eventName, handler)
        } else {
            this._showContextMenuEventHandler = handler;
            _events_engine.default.on(_dom_adapter.default.getDocument(), eventName, target, this._showContextMenuEventHandler)
        }
    }
    _hoverEndHandler(e) {
        super._hoverEndHandler(e);
        e.stopPropagation()
    }
    _renderDimensions() {}
    _renderContainer($wrapper, submenuContainer) {
        const $holder = submenuContainer || this._itemContainer();
        $wrapper = (0, _renderer.default)("<div>");
        $wrapper.appendTo($holder).addClass("dx-submenu").css("visibility", submenuContainer ? "hidden" : "visible");
        if (!$wrapper.parent().hasClass("dx-overlay-content")) {
            this._addCustomCssClass($wrapper)
        }
        const $itemsContainer = super._renderContainer($wrapper);
        if (submenuContainer) {
            return $itemsContainer
        }
        if (this.option("width")) {
            return $itemsContainer.css("minWidth", this.option("width"))
        }
        if (this.option("height")) {
            return $itemsContainer.css("minHeight", this.option("height"))
        }
        return $itemsContainer
    }
    _renderSubmenuItems(node, $itemFrame) {
        this._renderItems(this._getChildNodes(node), $itemFrame);
        const $submenu = $itemFrame.children(".dx-submenu");
        this._actions.onSubmenuCreated({
            itemElement: (0, _element.getPublicElement)($itemFrame),
            itemData: node.internalFields.item,
            submenuElement: (0, _element.getPublicElement)($submenu)
        });
        this._initScrollable($submenu);
        this.setAria({
            role: "menu"
        }, $submenu)
    }
    _getOverlayOptions() {
        const position = this.option("position");
        const overlayOptions = {
            focusStateEnabled: this.option("focusStateEnabled"),
            animation: this.option("animation"),
            innerOverlay: true,
            hideOnOutsideClick: e => this._hideOnOutsideClickHandler(e),
            propagateOutsideClick: true,
            hideOnParentScroll: true,
            deferRendering: false,
            position: {
                at: position.at,
                my: position.my,
                of: this._getTarget(),
                collision: "flipfit"
            },
            shading: false,
            showTitle: false,
            height: "auto",
            width: "auto",
            onShown: this._overlayShownActionHandler.bind(this),
            onHiding: this._overlayHidingActionHandler.bind(this),
            onHidden: this._overlayHiddenActionHandler.bind(this),
            visualContainer: window
        };
        return overlayOptions
    }
    _overlayShownActionHandler(arg) {
        this._actions.onShown(arg)
    }
    _overlayHidingActionHandler(arg) {
        this._actions.onHiding(arg);
        if (!arg.cancel) {
            this._hideAllShownSubmenus();
            this._setOptionWithoutOptionChange("visible", false)
        }
    }
    _overlayHiddenActionHandler(arg) {
        this._actions.onHidden(arg)
    }
    _shouldHideOnOutsideClick(e) {
        const {
            closeOnOutsideClick: closeOnOutsideClick,
            hideOnOutsideClick: hideOnOutsideClick
        } = this.option();
        if ((0, _type.isFunction)(hideOnOutsideClick)) {
            return hideOnOutsideClick(e)
        }
        if ((0, _type.isFunction)(closeOnOutsideClick)) {
            return closeOnOutsideClick(e)
        }
        return hideOnOutsideClick || closeOnOutsideClick
    }
    _hideOnOutsideClickHandler(e) {
        if (!this._shouldHideOnOutsideClick(e)) {
            return false
        }
        if (_dom_adapter.default.isDocument(e.target)) {
            return true
        }
        const $activeItemContainer = this._getActiveItemsContainer(e.target);
        const $itemContainers = this._getItemsContainers();
        const $clickedItem = this._searchActiveItem(e.target);
        const $rootItem = this.$element().parents(".dx-menu-item");
        const isRootItemClicked = $clickedItem[0] === $rootItem[0] && $clickedItem.length && $rootItem.length;
        const isInnerOverlayClicked = this._isIncludeOverlay($activeItemContainer, $itemContainers) && $clickedItem.length;
        if (isInnerOverlayClicked || isRootItemClicked) {
            if ("onClick" === this._getShowSubmenuMode()) {
                this._hideAllShownChildSubmenus($clickedItem)
            }
            return false
        }
        return true
    }
    _getActiveItemsContainer(target) {
        return (0, _renderer.default)(target).closest(".dx-menu-items-container")
    }
    _getItemsContainers() {
        return this._overlay.$content().find(".dx-menu-items-container")
    }
    _searchActiveItem(target) {
        return (0, _renderer.default)(target).closest(".dx-menu-item").eq(0)
    }
    _isIncludeOverlay($activeOverlay, $allOverlays) {
        let isSame = false;
        (0, _iterator.each)($allOverlays, ((index, $overlay) => {
            if ($activeOverlay.is($overlay) && !isSame) {
                isSame = true
            }
        }));
        return isSame
    }
    _hideAllShownChildSubmenus($clickedItem) {
        const $submenuElements = $clickedItem.find(".dx-submenu");
        const shownSubmenus = (0, _extend.extend)([], this._shownSubmenus);
        if ($submenuElements.length > 0) {
            (0, _iterator.each)(shownSubmenus, ((index, $submenu) => {
                const $context = this._searchActiveItem($submenu.context).parent();
                if ($context.parent().is($clickedItem.parent().parent()) && !$context.is($clickedItem.parent())) {
                    this._hideSubmenu($submenu)
                }
            }))
        }
    }
    _initScrollable($container) {
        this._createComponent($container, _ui2.default, {
            useKeyboard: false,
            _onVisibilityChanged: scrollable => {
                scrollable.scrollTo(0)
            }
        })
    }
    _setSubMenuHeight($submenu, anchor, isNestedSubmenu) {
        const $itemsContainer = $submenu.find(".dx-menu-items-container");
        const contentHeight = (0, _size.getOuterHeight)($itemsContainer);
        const maxHeight = this._getMaxHeight(anchor, !isNestedSubmenu);
        const menuHeight = Math.min(contentHeight, maxHeight);
        $submenu.css("height", isNestedSubmenu ? menuHeight : "100%")
    }
    _getMaxHeight(anchor) {
        let considerAnchorHeight = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : true;
        const windowHeight = (0, _size.getOuterHeight)(window);
        const isAnchorRenderer = (0, _type.isRenderer)(anchor);
        const document = _dom_adapter.default.getDocument();
        const isAnchorDocument = anchor.length && anchor[0] === document;
        if (!isAnchorRenderer || isAnchorDocument) {
            return windowHeight
        }
        const offsetTop = anchor[0].getBoundingClientRect().top;
        const anchorHeight = (0, _size.getOuterHeight)(anchor);
        const availableHeight = considerAnchorHeight ? Math.max(offsetTop, windowHeight - offsetTop - anchorHeight) : Math.max(offsetTop + anchorHeight, windowHeight - offsetTop);
        return availableHeight - 10
    }
    _dimensionChanged() {
        if (!this._shownSubmenus) {
            return
        }
        this._shownSubmenus.forEach(($submenu => {
            const $item = $submenu.closest(".dx-menu-item");
            this._setSubMenuHeight($submenu, $item, true);
            this._scrollToElement($item);
            const submenuPosition = this._getSubmenuPosition($item);
            _position.default.setup($submenu, submenuPosition)
        }))
    }
    _getSubmenuBorderWidth() {
        return (0, _themes.isMaterialBased)((0, _themes.current)()) ? 0 : 1
    }
    _showSubmenu($item) {
        const node = this._dataAdapter.getNodeByItem(this._getItemData($item));
        this._hideSubmenusOnSameLevel($item);
        if (!this._hasSubmenu(node)) {
            return
        }
        let $submenu = $item.children(".dx-submenu");
        const isSubmenuRendered = $submenu.length;
        super._showSubmenu($item);
        if (!isSubmenuRendered) {
            this._renderSubmenuItems(node, $item);
            $submenu = $item.children(".dx-submenu")
        }
        this._setSubMenuHeight($submenu, $item, true);
        if (!this._isSubmenuVisible($submenu)) {
            this._drawSubmenu($item)
        }
    }
    _hideSubmenusOnSameLevel($item) {
        const $expandedItems = $item.parent(".dx-menu-item-wrapper").siblings().find(".dx-menu-item-expanded");
        if ($expandedItems.length) {
            $expandedItems.removeClass("dx-menu-item-expanded");
            this._hideSubmenu($expandedItems.find(".dx-submenu"))
        }
    }
    _hideSubmenuGroup($submenu) {
        if (this._isSubmenuVisible($submenu)) {
            this._hideSubmenuCore($submenu)
        }
    }
    _isSubmenuVisible($submenu) {
        return "visible" === $submenu.css("visibility")
    }
    _drawSubmenu($itemElement) {
        const animation = this.option("animation") ? this.option("animation").show : {};
        const $submenu = $itemElement.children(".dx-submenu");
        const submenuPosition = this._getSubmenuPosition($itemElement);
        if (this._overlay && this._overlay.option("visible")) {
            if (!(0, _type.isDefined)(this._shownSubmenus)) {
                this._shownSubmenus = []
            }
            if (!this._shownSubmenus.includes($submenu)) {
                this._shownSubmenus.push($submenu)
            }
            if (animation) {
                _fx.default.stop($submenu)
            }
            _position.default.setup($submenu, submenuPosition);
            if (animation) {
                if ((0, _type.isPlainObject)(animation.to)) {
                    animation.to.position = submenuPosition
                }
                this._animate($submenu, animation)
            }
            $submenu.css("visibility", "visible")
        }
    }
    _animate($container, options) {
        _fx.default.animate($container, options)
    }
    _getSubmenuPosition($rootItem) {
        const submenuDirection = this.option("submenuDirection").toLowerCase();
        const $rootItemWrapper = $rootItem.parent(".dx-menu-item-wrapper");
        const position = {
            collision: "flip",
            of: $rootItemWrapper,
            offset: {
                h: 0,
                v: -1
            }
        };
        switch (submenuDirection) {
            case "left":
                position.at = "left top";
                position.my = "right top";
                break;
            case "right":
                position.at = "right top";
                position.my = "left top";
                break;
            default:
                if (this.option("rtlEnabled")) {
                    position.at = "left top";
                    position.my = "right top"
                } else {
                    position.at = "right top";
                    position.my = "left top"
                }
        }
        return position
    }
    _updateSubmenuVisibilityOnClick(actionArgs) {
        if (!actionArgs.args.length) {
            return
        }
        const {
            itemData: itemData
        } = actionArgs.args[0];
        const node = this._dataAdapter.getNodeByItem(itemData);
        if (!node) {
            return
        }
        const $itemElement = (0, _renderer.default)(actionArgs.args[0].itemElement);
        let $submenu = $itemElement.find(".dx-submenu");
        const shouldRenderSubmenu = this._hasSubmenu(node) && !$submenu.length;
        if (shouldRenderSubmenu) {
            this._renderSubmenuItems(node, $itemElement);
            $submenu = $itemElement.find(".dx-submenu")
        }
        if ($itemElement.context === $submenu.context && "visible" === $submenu.css("visibility")) {
            return
        }
        this._updateSelectedItemOnClick(actionArgs);
        const notCloseMenuOnItemClick = itemData && false === itemData.closeMenuOnClick;
        if (!itemData || itemData.disabled || notCloseMenuOnItemClick) {
            return
        }
        if (0 === $submenu.length) {
            const $prevSubmenu = (0, _renderer.default)($itemElement.parents(".dx-submenu")[0]);
            this._hideSubmenu($prevSubmenu);
            if (!actionArgs.canceled && this._overlay && this._overlay.option("visible")) {
                this.option("visible", false)
            }
        } else {
            if (this._shownSubmenus && this._shownSubmenus.length > 0) {
                if (this._shownSubmenus[0].is($submenu)) {
                    this._hideSubmenu($submenu)
                }
            }
            this._showSubmenu($itemElement)
        }
    }
    _hideSubmenu($curSubmenu) {
        const shownSubmenus = (0, _extend.extend)([], this._shownSubmenus);
        (0, _iterator.each)(shownSubmenus, ((index, $submenu) => {
            if ($curSubmenu.is($submenu) || (0, _dom.contains)($curSubmenu[0], $submenu[0])) {
                $submenu.parent().removeClass("dx-menu-item-expanded");
                this._hideSubmenuCore($submenu)
            }
        }))
    }
    _hideSubmenuCore($submenu) {
        const index = this._shownSubmenus.indexOf($submenu);
        const animation = this.option("animation") ? this.option("animation").hide : null;
        if (index >= 0) {
            this._shownSubmenus.splice(index, 1)
        }
        this._stopAnimate($submenu);
        animation && this._animate($submenu, animation);
        $submenu.css("visibility", "hidden");
        const scrollableInstance = $submenu.dxScrollable("instance");
        scrollableInstance.scrollTo(0);
        this.option("focusedElement", null)
    }
    _stopAnimate($container) {
        _fx.default.stop($container, true)
    }
    _hideAllShownSubmenus() {
        const shownSubmenus = (0, _extend.extend)([], this._shownSubmenus);
        const $expandedItems = this._overlay.$content().find(".dx-menu-item-expanded");
        $expandedItems.removeClass("dx-menu-item-expanded");
        (0, _iterator.each)(shownSubmenus, ((_, $submenu) => {
            this._hideSubmenu($submenu)
        }))
    }
    _visibilityChanged(visible) {
        if (visible) {
            this._renderContentImpl()
        }
    }
    _optionChanged(args) {
        if (ACTIONS.includes(args.name)) {
            this._initActions();
            return
        }
        switch (args.name) {
            case "visible":
                this._renderVisibility(args.value);
                break;
            case "showEvent":
            case "position":
            case "submenuDirection":
                this._invalidate();
                break;
            case "target":
                args.previousValue && this._detachShowContextMenuEvents(args.previousValue);
                this._invalidate();
                break;
            case "closeOnOutsideClick":
            case "hideOnOutsideClick":
                break;
            default:
                super._optionChanged(args)
        }
    }
    _renderVisibility(showing) {
        return showing ? this._show() : this._hide()
    }
    _toggleVisibility() {}
    _show(event) {
        const args = {
            jQEvent: event
        };
        let promise = (0, _deferred.Deferred)().reject().promise();
        this._actions.onShowing(args);
        if (args.cancel) {
            return promise
        }
        const position = this._positionContextMenu(event);
        if (position) {
            var _event$originalEvent;
            if (!this._overlay) {
                this._renderContextMenuOverlay();
                this._overlay.$content().addClass(this._widgetClass());
                this._renderFocusState();
                this._attachHoverEvents();
                this._attachClickEvent();
                this._renderItems(this._dataAdapter.getRootNodes())
            }
            const $subMenu = (0, _renderer.default)(this._overlay.content()).children(".dx-submenu");
            this._setOptionWithoutOptionChange("visible", true);
            this._overlay.option({
                height: () => this._getMaxHeight(position.of),
                maxHeight: () => {
                    const $content = $subMenu.find(".dx-menu-items-container");
                    const borderWidth = this._getSubmenuBorderWidth();
                    return (0, _size.getOuterHeight)($content) + 2 * borderWidth
                },
                position: position
            });
            if ($subMenu.length) {
                this._setSubMenuHeight($subMenu, position.of, false)
            }
            promise = this._overlay.show();
            event && event.stopPropagation();
            this._setAriaAttributes();
            if ((null === event || void 0 === event || null === (_event$originalEvent = event.originalEvent) || void 0 === _event$originalEvent ? void 0 : _event$originalEvent.type) === _hold.default.name) {
                this.preventShowingDefaultContextMenuAboveOverlay()
            }
        }
        return promise
    }
    _renderItems(nodes, submenuContainer) {
        super._renderItems(nodes, submenuContainer);
        const $submenu = (0, _renderer.default)(this._overlay.content()).children(".dx-submenu");
        if ($submenu.length) {
            this._initScrollable($submenu)
        }
    }
    _setAriaAttributes() {
        this._overlayContentId = `dx-${new _guid.default}`;
        this.setAria("owns", this._overlayContentId);
        this.setAria({
            id: this._overlayContentId,
            role: "menu"
        }, this._overlay.$content())
    }
    _cleanAriaAttributes() {
        this._overlay && this.setAria("id", null, this._overlay.$content());
        this.setAria("owns", void 0)
    }
    _getTarget() {
        return this.option("target") || this.option("position").of || (0, _renderer.default)(_dom_adapter.default.getDocument())
    }
    _getContextMenuPosition() {
        return (0, _extend.extend)({}, this.option("position"), {
            of: this._getTarget()
        })
    }
    _positionContextMenu(jQEvent) {
        let position = this._getContextMenuPosition();
        const isInitialPosition = this._isInitialOptionValue("position");
        const positioningAction = this._createActionByOption("onPositioning");
        if (jQEvent && jQEvent.preventDefault && isInitialPosition) {
            position.of = jQEvent
        }
        const actionArgs = {
            position: position,
            event: jQEvent
        };
        positioningAction(actionArgs);
        if (actionArgs.cancel) {
            position = null
        } else if (actionArgs.event) {
            actionArgs.event.cancel = true;
            jQEvent.preventDefault()
        }
        return position
    }
    _refresh() {
        if (!(0, _window.hasWindow)()) {
            super._refresh()
        } else if (this._overlay) {
            const lastPosition = this._overlay.option("position");
            super._refresh();
            this._overlay && this._overlay.option("position", lastPosition)
        } else {
            super._refresh()
        }
    }
    _hide() {
        let promise;
        if (this._overlay) {
            promise = this._overlay.hide();
            this._setOptionWithoutOptionChange("visible", false)
        }
        this._cleanAriaAttributes();
        this.option("focusedElement", null);
        return promise || (0, _deferred.Deferred)().reject().promise()
    }
    toggle(showing) {
        const visible = this.option("visible");
        showing = void 0 === showing ? !visible : showing;
        return this._renderVisibility(showing)
    }
    show() {
        return this.toggle(true)
    }
    hide() {
        return this.toggle(false)
    }
}(0, _component_registrator.default)("dxContextMenu", ContextMenu);
var _default = exports.default = ContextMenu;
