|
11 | 11 | * Licensed under
|
12 | 12 | * MIT License http://www.opensource.org/licenses/mit-license
|
13 | 13 | *
|
14 |
| - * Date: 2017-08-30T12:16:04.336Z |
| 14 | + * Date: 2017-10-26T16:51:13.459Z |
15 | 15 | */
|
16 | 16 |
|
17 | 17 | // jscs:disable
|
|
116 | 116 | // flag denoting if a second trigger should simply move (true) or rebuild (false) an open menu
|
117 | 117 | // as long as the trigger happened on one of the trigger-element's child nodes
|
118 | 118 | reposition: true,
|
| 119 | + // Flag denoting if a second trigger should close the menu, as long as |
| 120 | + // the trigger happened on one of the trigger-element's child nodes. |
| 121 | + // This overrides the reposition option. |
| 122 | + hideOnSecondTrigger: false, |
119 | 123 |
|
120 | 124 | //ability to select submenu
|
121 | 125 | selectableSubMenu: false,
|
|
217 | 221 | collision: 'flipfit fit'
|
218 | 222 | }).css('display', '');
|
219 | 223 | } else {
|
| 224 | + var parentOffset = this.offset(); |
220 | 225 | // determine contextMenu position
|
221 | 226 | var offset = {
|
222 |
| - top: -9, |
223 |
| - left: this.outerWidth() - 5 |
| 227 | + top: parentOffset.top, |
| 228 | + left: parentOffset.left + this.outerWidth() |
224 | 229 | };
|
225 | 230 | $menu.css(offset);
|
| 231 | + op.activated($menu); |
226 | 232 | }
|
227 | 233 | },
|
228 | 234 | // offset to add to zIndex
|
|
236 | 242 | // events
|
237 | 243 | events: {
|
238 | 244 | show: $.noop,
|
239 |
| - hide: $.noop |
| 245 | + hide: $.noop, |
| 246 | + activated: $.noop |
240 | 247 | },
|
241 | 248 | // default callback
|
242 | 249 | callback: null,
|
|
471 | 478 | $(target).trigger(e);
|
472 | 479 | root.$layer.show();
|
473 | 480 | }
|
474 |
| - |
| 481 | + |
| 482 | + if (root.hideOnSecondTrigger && triggerAction && root.$menu !== null && typeof root.$menu !== 'undefined') { |
| 483 | + root.$menu.trigger('contextmenu:hide'); |
| 484 | + return; |
| 485 | + } |
| 486 | + |
475 | 487 | if (root.reposition && triggerAction) {
|
476 | 488 | if (document.elementFromPoint) {
|
477 | 489 | if (root.$trigger.is(target)) {
|
|
997 | 1009 | // position and show context menu
|
998 | 1010 | opt.$menu.css(css)[opt.animation.show](opt.animation.duration, function () {
|
999 | 1011 | $trigger.trigger('contextmenu:visible');
|
| 1012 | + |
| 1013 | + op.activated(opt.$menu); |
| 1014 | + opt.events.activated(); |
1000 | 1015 | });
|
1001 | 1016 | // make options available and set state
|
1002 | 1017 | $trigger
|
|
1527 | 1542 | // Wait for promise completion. .then(success, error, notify) (we don't track notify). Bind the opt
|
1528 | 1543 | // and root to avoid scope problems
|
1529 | 1544 | promise.then(completedPromise.bind(this, opt, root), errorPromise.bind(this, opt, root));
|
| 1545 | + }, |
| 1546 | + // operation that will run after contextMenu showed on screen |
| 1547 | + activated: function(menu){ |
| 1548 | + var $menu = menu; |
| 1549 | + var win = $(window); |
| 1550 | + var $menuOffset = $menu.offset(); |
| 1551 | + var winHeight = win.height(); |
| 1552 | + var winWidth = win.width(); |
| 1553 | + var winScrollTop = win.scrollTop(); |
| 1554 | + var menuHeight = $menu.outerHeight(); |
| 1555 | + var menuWidth = $menu.outerWidth(); |
| 1556 | + if(menuHeight > winHeight){ |
| 1557 | + $menu.css({ |
| 1558 | + 'height': winHeight - |
| 1559 | + ((parseInt($menu.css('padding-top'))*2)+(parseInt($menu.css('margin-top'))*2))+'px', |
| 1560 | + 'overflow-x':'hidden', |
| 1561 | + 'overflow-y':'auto', |
| 1562 | + 'top':winScrollTop+'px' |
| 1563 | + }); |
| 1564 | + } else if($menuOffset.top < winScrollTop){ |
| 1565 | + $menu.css({ |
| 1566 | + 'top':'0px' |
| 1567 | + }); |
| 1568 | + } else if($menuOffset.top+menuHeight > winScrollTop + winHeight){ |
| 1569 | + $menu.css({ |
| 1570 | + 'top':$menuOffset.top - Math.abs((winScrollTop+winHeight)-($menuOffset.top+menuHeight)) -((parseInt($menu.css('padding-top'))*2)+(parseInt($menu.css('margin-top'))*2))+'px' |
| 1571 | + }); |
| 1572 | + } |
| 1573 | + if($menuOffset.left + menuWidth > winWidth){ |
| 1574 | + var newLeftPosition = $menuOffset.left - Math.abs(($menuOffset.left+menuWidth) - winWidth); |
| 1575 | + var parent = $menu.parents('ul.context-menu-list').first(); |
| 1576 | + if(parent.length){ |
| 1577 | + if(newLeftPosition <= parent.offset().left + parent.outerWidth() |
| 1578 | + && newLeftPosition >= parent.offset().left){ |
| 1579 | + $menu.css({ |
| 1580 | + 'left':parent.offset().left - $menu.outerWidth() + 'px' |
| 1581 | + }); |
| 1582 | + }else{ |
| 1583 | + $menu.css({ |
| 1584 | + 'left':$menuOffset.left-Math.abs(($menuOffset.left+menuWidth) - winWidth) + 'px' |
| 1585 | + }); |
| 1586 | + } |
| 1587 | + }else{ |
| 1588 | + $menu.css({ |
| 1589 | + 'left':$menuOffset.left-Math.abs(($menuOffset.left+menuWidth) - winWidth) + 'px' |
| 1590 | + }); |
| 1591 | + } |
| 1592 | + } |
1530 | 1593 | }
|
1531 | 1594 | };
|
1532 | 1595 |
|
|
1616 | 1679 | }
|
1617 | 1680 |
|
1618 | 1681 | switch (operation) {
|
| 1682 | + |
| 1683 | + case 'update': |
| 1684 | + // Updates visibility and such |
| 1685 | + if(_hasContext){ |
| 1686 | + op.update($context); |
| 1687 | + } else { |
| 1688 | + for(var menu in menus){ |
| 1689 | + if(menus.hasOwnProperty(menu)){ |
| 1690 | + op.update(menus[menu]); |
| 1691 | + } |
| 1692 | + } |
| 1693 | + } |
| 1694 | + break; |
| 1695 | + |
1619 | 1696 | case 'create':
|
1620 | 1697 | // no selector no joy
|
1621 | 1698 | if (!o.selector) {
|
|
1905 | 1982 | disabled: !!$node.attr('disabled'),
|
1906 | 1983 | callback: (function () {
|
1907 | 1984 | return function () {
|
1908 |
| - $node.get(0).click() |
| 1985 | + $node.get(0).click(); |
1909 | 1986 | };
|
1910 | 1987 | })()
|
1911 | 1988 | };
|
|
1924 | 2001 | icon: $node.attr('icon'),
|
1925 | 2002 | callback: (function () {
|
1926 | 2003 | return function () {
|
1927 |
| - $node.get(0).click() |
| 2004 | + $node.get(0).click(); |
1928 | 2005 | };
|
1929 | 2006 | })()
|
1930 | 2007 | };
|
|
0 commit comments