Found while hardening selector handling for #731. Not introduced by that work, this is pre-existing on master.
Problem
src/jquery.contextMenu.js:2363:
if (!o.context || !o.context.length) {
o.context = document;
}
A plain DOM Element has no .length property, so !o.context.length is true and the registration silently falls back to document. The menu still works, but it is registered globally instead of being scoped to the element the caller passed.
Only a jQuery object or a selector string actually scopes a registration today. There is no error and no warning, so the caller has no way to notice.
// scopes correctly
$.contextMenu({selector: '.item', context: $('#panel'), items: {...}});
$.contextMenu({selector: '.item', context: '#panel', items: {...}});
// silently global
$.contextMenu({selector: '.item', context: document.getElementById('panel'), items: {...}});
Note the .length check also misfires the other way for <form> and <select> elements, which do have a length property (their control/option count). An empty <form> passed as context has length === 0 and is ignored; a non-empty one is accepted.
Why it matters now
cf26191 added support for selector being an Element or a jQuery object, so it is reasonable for a caller to expect context to accept the same shapes. It does not.
Suggested fix
Normalise context by type rather than by truthiness of .length, in the same spirit as the existing isElementSelector() helper used for selector.
Found while hardening selector handling for #731. Not introduced by that work, this is pre-existing on master.
Problem
src/jquery.contextMenu.js:2363:
A plain DOM Element has no .length property, so !o.context.length is true and the registration silently falls back to document. The menu still works, but it is registered globally instead of being scoped to the element the caller passed.
Only a jQuery object or a selector string actually scopes a registration today. There is no error and no warning, so the caller has no way to notice.
Note the .length check also misfires the other way for <form> and <select> elements, which do have a length property (their control/option count). An empty <form> passed as context has length === 0 and is ignored; a non-empty one is accepted.
Why it matters now
cf26191 added support for selector being an Element or a jQuery object, so it is reasonable for a caller to expect context to accept the same shapes. It does not.
Suggested fix
Normalise context by type rather than by truthiness of .length, in the same spirit as the existing isElementSelector() helper used for selector.