Skip to content

Commit 708d416

Browse files
bbralaSpeedphoenix
andauthored
Fix unpropagated click for background layer (#780)
* Make the contextmenu let click events passthrough With useModal set to false, uses document.addeventlistener in capture mode rather than an invisible layer. Note that this probably breaks on older browsers, and some features or options might not work anymore. useModal is set to true by default, and should behave just like before. * fix: fixup changes to older syntax and rebase onto master --------- Co-authored-by: Speedphoenix <leonardo.jeanteur@gmail.com>
1 parent 9b38fa4 commit 708d416

File tree

7 files changed

+82
-26
lines changed

7 files changed

+82
-26
lines changed

dist/jquery.contextMenu.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Licensed under
1313
* MIT License http://www.opensource.org/licenses/mit-license
1414
*
15-
* Date: 2025-11-04T11:10:12.861Z
15+
* Date: 2025-11-04T11:25:40.032Z
1616
*/
1717
@-webkit-keyframes cm-spin {
1818
0% {

dist/jquery.contextMenu.js

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Licensed under
1212
* MIT License http://www.opensource.org/licenses/mit-license
1313
*
14-
* Date: 2025-11-04T11:10:13.179Z
14+
* Date: 2025-11-04T11:25:40.325Z
1515
*/
1616

1717
// jscs:disable
@@ -151,6 +151,9 @@
151151
// This overrides the reposition option.
152152
hideOnSecondTrigger: false,
153153

154+
// use a modal layer for closing the menu rather than a captured event on document
155+
useModal: true,
156+
154157
//ability to select submenu
155158
selectableSubMenu: false,
156159

@@ -460,26 +463,38 @@
460463
hoveract.timer = null;
461464
},
462465
// click on layer to hide contextMenu
463-
layerClick: function (e) {
466+
layerClick: function (e, opt, onhide) {
464467
var $this = $(this),
465-
root = $this.data('contextMenuRoot'),
468+
root = (opt !== undefined) ? opt : $this.data('contextMenuRoot'),
466469
button = e.button,
467470
x = e.pageX,
468471
y = e.pageY,
469472
fakeClick = x === undefined,
470473
target,
471474
offset;
472475

476+
// If the click is not real, things break: https://github.com/swisnl/jQuery-contextMenu/issues/132
477+
if(fakeClick){
478+
if (root !== null && typeof root !== 'undefined' && root.$menu !== null && typeof root.$menu !== 'undefined') {
479+
root.$menu.trigger('contextmenu:hide');
480+
}
481+
return;
482+
}
483+
484+
// if the click closing is done through windwow event listener rather than a transparent layer
485+
if (!root.$layer) {
486+
target = document.elementFromPoint(x - $win.scrollLeft(), y - $win.scrollTop());
487+
if (root.$menu === null || typeof root.$menu === 'undefined' || !root.$menu[0].contains(target)) {
488+
489+
root.$menu.trigger('contextmenu:hide');
490+
if (typeof onhide !== 'undefined')
491+
onhide();
492+
}
493+
return;
494+
}
473495
e.preventDefault();
474496

475497
setTimeout(function () {
476-
// If the click is not real, things break: https://github.com/swisnl/jQuery-contextMenu/issues/132
477-
if(fakeClick){
478-
if (root !== null && typeof root !== 'undefined' && root.$menu !== null && typeof root.$menu !== 'undefined') {
479-
root.$menu.trigger('contextmenu:hide');
480-
}
481-
return;
482-
}
483498

484499
var $window;
485500
var triggerAction = ((root.trigger === 'left' && button === 0) || (root.trigger === 'right' && button === 2));
@@ -1022,7 +1037,10 @@
10221037
css = {};
10231038

10241039
// hide any open menus
1025-
$('#context-menu-layer').trigger('mousedown');
1040+
if ($('#context-menu-layer').length > 0)
1041+
$('#context-menu-layer').trigger('mousedown');
1042+
else
1043+
$(document).trigger('contextmenu:hide');
10261044

10271045
// backreference for callbacks
10281046
opt.$trigger = $trigger;
@@ -1569,6 +1587,16 @@
15691587
return hasVisibleItems;
15701588
},
15711589
layer: function (opt, zIndex) {
1590+
if (!opt.useModal) {
1591+
var listener = function (ev) {
1592+
handle.layerClick(ev, opt, function() {
1593+
document.removeEventListener('mousedown', listener, true);
1594+
});
1595+
};
1596+
document.addEventListener('mousedown', listener, true);
1597+
return;
1598+
}
1599+
15721600
// add transparent layer for click area
15731601
// filter and background for Internet Explorer, Issue #23
15741602
var $layer = opt.$layer = $('<div id="context-menu-layer"></div>')

dist/jquery.contextMenu.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)