UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

174 lines (150 loc) 6 kB
"use strict"; var $ = require("../../core/renderer"), noop = require("../../core/utils/common").noop, getPublicElement = require("../../core/utils/dom").getPublicElement, positionUtils = require("../../animation/position"), extend = require("../../core/utils/extend").extend, ContextMenu = require("../context_menu"); var DX_CONTEXT_MENU_CONTENT_DELIMITER_CLASS = "dx-context-menu-content-delimiter", DX_SUBMENU_CLASS = "dx-submenu"; var Submenu = ContextMenu.inherit({ _getDefaultOptions: function _getDefaultOptions() { return extend(this.callBase(), { orientation: "horizontal", onHoverStart: noop }); }, _initDataAdapter: function _initDataAdapter() { this._dataAdapter = this.option("_dataAdapter"); if (!this._dataAdapter) { this.callBase(); } }, _renderContentImpl: function _renderContentImpl() { this._renderContextMenuOverlay(); this.callBase(); var node = this._dataAdapter.getNodeByKey(this.option("_parentKey")); node && this._renderItems(this._getChildNodes(node)); this._renderDelimiter(); }, _renderDelimiter: function _renderDelimiter() { this.$contentDelimiter = $("<div>").appendTo(this._itemContainer()).addClass(DX_CONTEXT_MENU_CONTENT_DELIMITER_CLASS); }, _getOverlayOptions: function _getOverlayOptions() { return extend(this.callBase(), { onPositioned: this._overlayPositionedActionHandler.bind(this) }); }, _overlayPositionedActionHandler: function _overlayPositionedActionHandler(arg) { this._showDelimiter(arg); }, _hoverEndHandler: function _hoverEndHandler(e) { this.callBase(e); this._toggleFocusClass(false, e.currentTarget); }, _isMenuHorizontal: function _isMenuHorizontal() { return this.option("orientation") === "horizontal"; }, _hoverStartHandler: function _hoverStartHandler(e) { var hoverStartAction = this.option("onHoverStart"); hoverStartAction(e); this.callBase(e); this._toggleFocusClass(true, e.currentTarget); }, _drawSubmenu: function _drawSubmenu($rootItem) { this._actions.onShowing({ rootItem: getPublicElement($rootItem), submenu: this }); this.callBase($rootItem); this._actions.onShown({ rootItem: getPublicElement($rootItem), submenu: this }); }, _hideSubmenu: function _hideSubmenu($rootItem) { this._actions.onHiding({ cancel: true, rootItem: getPublicElement($rootItem), submenu: this }); this.callBase($rootItem); this._actions.onHidden({ rootItem: getPublicElement($rootItem), submenu: this }); }, // TODO: try to simplify it _showDelimiter: function _showDelimiter(arg) { if (!this.$contentDelimiter) { return; } var $submenu = this._itemContainer().children("." + DX_SUBMENU_CLASS).eq(0), $rootItem = this.option("position").of, position = { of: $submenu }, containerOffset = arg.position, vLocation = containerOffset.v.location, hLocation = containerOffset.h.location, rootOffset = $rootItem.offset(), offsetLeft = Math.round(rootOffset.left), offsetTop = Math.round(rootOffset.top), rootWidth = $rootItem.width(), rootHeight = $rootItem.height(), submenuWidth = $submenu.width(), submenuHeight = $submenu.height(); this.$contentDelimiter.css("display", "block"); this.$contentDelimiter.width(this._isMenuHorizontal() ? rootWidth < submenuWidth ? rootWidth - 2 : submenuWidth : 2); this.$contentDelimiter.height(this._isMenuHorizontal() ? 2 : rootHeight < submenuHeight ? rootHeight - 2 : submenuHeight); if (this._isMenuHorizontal()) { if (vLocation > offsetTop) { if (Math.round(hLocation) === offsetLeft) { position.offset = "1 -1"; position.at = position.my = "left top"; } else { position.offset = "-1 -1"; position.at = position.my = "right top"; } } else { this.$contentDelimiter.height(5); if (Math.round(hLocation) === offsetLeft) { position.offset = "1 4"; position.at = position.my = "left bottom"; } else { position.offset = "-1 2"; position.at = position.my = "right bottom"; } } } else { if (hLocation > offsetLeft) { if (Math.round(vLocation) === offsetTop) { position.offset = "-1 1"; position.at = position.my = "left top"; } else { position.offset = "-1 -1"; position.at = position.my = "left bottom"; } } else { if (Math.round(vLocation) === offsetTop) { position.offset = "1 1"; position.at = position.my = "right top"; } else { position.offset = "1 -1"; position.at = position.my = "right bottom"; } } } positionUtils.setup(this.$contentDelimiter, position); }, _getContextMenuPosition: function _getContextMenuPosition() { return this.option("position"); }, isOverlayVisible: function isOverlayVisible() { return this._overlay.option("visible"); }, getOverlayContent: function getOverlayContent() { return this._overlay.$content(); } }); module.exports = Submenu;