Skip to content

context option silently ignored when passed a raw Element #809

Description

@bbrala

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions