/**
* Determine the position for a root menu.
* @memberOf ContextMenuOptions
* @function ContextMenuOptions#determinePosition
* @param {(JQuery)} $menu
*/
export function determinePosition($menu) {
// position to the lower middle of the trigger element
if ($.ui && $.ui.position) {
// .position() is provided as a jQuery UI utility
// (...and it won't work on hidden elements)
$menu.css('display', 'block').position({
my: 'center top',
at: 'center bottom',
of: this,
offset: '0 5',
collision: 'fit'
}).css('display', 'none');
} else {
// determine contextMenu position
const offset = this.offset();
offset.top += this.outerHeight();
offset.left += this.outerWidth() / 2 - $menu.outerWidth() / 2;
$menu.css(offset);
}
}
/**
* Position the root menu.
* @memberOf ContextMenuOptions
* @function ContextMenuOptions#position
* @param {JQuery.Event} e
* @param {ContextMenuData} currentMenuData
* @param {(number|string)} x
* @param {(number|string)} y
*/
export function position(e, currentMenuData, x, y) {
const $window = $(window);
let offset;
// determine contextMenu position
if (!x && !y) {
currentMenuData.determinePosition.call(this, currentMenuData.$menu);
return;
} else if (x === 'maintain' && y === 'maintain') {
// x and y must not be changed (after re-show on command click)
offset = currentMenuData.$menu.position();
} else {
// x and y are given (by mouse event)
const offsetParentOffset = currentMenuData.$menu.offsetParent().offset();
offset = {top: y - offsetParentOffset.top, left: x - offsetParentOffset.left};
}
// correct offset if viewport demands it
const bottom = $window.scrollTop() + $window.height();
const right = $window.scrollLeft() + $window.width();
const height = currentMenuData.$menu.outerHeight();
const width = currentMenuData.$menu.outerWidth();
if (offset.top + height > bottom) {
offset.top -= height;
}
if (offset.top < 0) {
offset.top = 0;
}
if (offset.left + width > right) {
offset.left -= width;
}
if (offset.left < 0) {
offset.left = 0;
}
currentMenuData.$menu.css(offset);
}
/**
* Position a submenu.
* @memberOf ContextMenuOptions
* @function ContextMenuOptions#positionSubmenu
* @param {JQuery.Event} e
* @param {JQuery} $menu
*/
// position the sub-menu
export function positionSubmenu(e, $menu) {
if (typeof $menu === 'undefined') {
// When user hovers over item (which has sub items) handle.focusItem will call this.
// but the submenu does not exist yet if ContextMenuData.items is a promise. just return, will
// call positionSubmenu after promise is completed.
return;
}
if ($.ui && $.ui.position) {
// .position() is provided as a jQuery UI utility
// (...and it won't work on hidden elements)
$menu.css('display', 'block').position({
my: 'left top-5',
at: 'right top',
of: this,
collision: 'flipfit fit'
}).css('display', '');
} else {
// determine contextMenu position
const offset = {
top: -9,
left: this.outerWidth() - 5
};
$menu.css(offset);
}
}