UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

901 lines (899 loc) • 36.5 kB
/** * DevExtreme (cjs/__internal/ui/context_menu/m_context_menu.js) * Version: 24.2.6 * Build date: Mon Mar 17 2025 * * Copyright (c) 2012 - 2025 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 _animation = require("../../../common/core/animation"); var _position = _interopRequireDefault(require("../../../common/core/animation/position")); var _contextmenu = require("../../../common/core/events/contextmenu"); var _events_engine = _interopRequireDefault(require("../../../common/core/events/core/events_engine")); var _hold = _interopRequireDefault(require("../../../common/core/events/hold")); var _index = require("../../../common/core/events/utils/index"); 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 _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(e) { return e && e.__esModule ? e : { default: e } } 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()); this._shownSubmenus = []; 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.isGeneric)((0, _themes.current)()) ? 1 : 0 } _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._planPostRenderActions($submenu) } _setSubmenuVisible($submenu) { if (!$submenu) { return } const $item = null === $submenu || void 0 === $submenu ? void 0 : $submenu.closest(".dx-menu-item"); this._setSubMenuHeight($submenu, $item, true); if (!this._isSubmenuVisible($submenu) && $item) { 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) { _animation.fx.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) { _animation.fx.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) { _animation.fx.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) } _postProcessRenderItems($submenu) { this._setSubmenuVisible($submenu) } }(0, _component_registrator.default)("dxContextMenu", ContextMenu); var _default = exports.default = ContextMenu;