Jenkins and plugins versions report
Pre-existing on current master (verified at master 063b6a7, Jenkins 2.568+; combobox component src/main/js/components/dropdowns/combo-box.js, tippy.js 6.3.7). Not introduced by #26884 (the appendTo change does not affect this flash). Client-side / web-UI only. Affects <f:combobox> (INPUT.combobox2); INPUT.auto-complete is not affected. Most visible when the combobox is rendered inside a <dialog>.
What Operating System are you using (both controller, and any agents involved in the problem)?
Controller OS is irrelevant (client-side). Reproduces in any modern browser with a mouse. (Originally reported for a combobox shown inside a dialog.)
Reproduction steps
- Open a page that renders an
<f:combobox>, ideally inside a <dialog> (a plugin descriptor config opened via an "Add"/config dialog, for example the credentials add/config flow). The same structural code path is exercised in core at /project-relationship (projectRelationship.jelly:47,52).
- Click (mouse) into the combobox input.
- Observe the suggestion list. For contrast, instead type a character into the same field.
Expected Results
Clicking into the combobox opens the suggestion list and keeps it open, the same as typing does.
Actual Results
On click, the suggestion list appears and immediately disappears (a flash), and a second click is needed to keep it open. Typing in the same field opens the list normally with no flash.
Anything else?
Root cause, verified against the source. Single true cause: the Jenkins document "click" listener in utils.js hides the dropdown because the combobox's tippy reference is the sibling <div>, not the clicked <input>.
Structural setup (combobox-specific):
src/main/js/components/dropdowns/combo-box.js:63-64 inserts a sibling DIV after the input (e.parentNode.insertBefore(div, e.nextElementSibling)), and combo-box.js:29 calls Utils.generateDropdown(div, …), so the tippy reference is the DIV (div.contains(input) is false).
combo-box.js:77 shows the dropdown when the input is focused/clicked: e.addEventListener("focus", () => updateSuggestions(e, div, items)), which calls e.dropdown.show() (combo-box.js:41). It is shown programmatically, not via tippy's trigger:"click".
The hide that causes the flash, src/main/js/components/dropdowns/utils.js:31-42:
document.addEventListener("click", (event) => {
const isClickOnReference = instance.reference.contains(event.target);
const isSelect = event.target.tagName === "SELECT";
if (!isClickOnReference && !isSelect) {
instance.clickToHide = true;
instance.hide();
}
});
instance.reference is the DIV; event.target is the INPUT (a sibling, outside the DIV), so isClickOnReference is false, the target is not a SELECT, and instance.hide() runs.
Sequence on one click (mousedown, focus, mouseup, click):
focus (combo-box.js:77) calls e.dropdown.show(), so the items become visible.
- The same click's
click phase bubbles to document and hits the utils.js:31 listener; the reference (DIV) does not contain the input, so instance.hide() runs.
- Net within one click: show (focus), then hide (document-click), which is the flash. This runs on every click outside the DIV and is sufficient on its own.
Why typing does not flash: typing shows the list via the input event (combo-box.js:85-90), which dispatches no click, so the utils.js:31 listener never fires.
Why it is combobox-specific (autocomplete never flashes):
- Autocomplete's reference is the input (
autocomplete.js:39-40 passes e), so a click on the input gives instance.reference.contains(event.target) === true and the hide branch is skipped.
- Autocomplete has no focus-to-show handler (only
input + focusout, autocomplete.js:103-111), so a bare click opens nothing to flash.
Ruled out: tippy's own onDocumentPress/hideOnClick (default hideOnClick: true, not overridden) is not decisive, because the list is shown programmatically and the deterministic hide is the app's utils.js:31 listener; tippy trigger:"click" toggling is not involved, because tippy binds its click trigger to the DIV reference, which the user never clicks.
Fix direction: at utils.js:32, treat a click on the combobox's associated input as "on reference" (for example instance.reference.parentNode.contains(event.target), or check the reference's sibling input), or make the combobox's tippy reference the input itself like autocomplete (combo-box.js:29), or guard the focus-to-show so it does not re-open within the same click. No automated coverage (HtmlUnit ComboBoxTest.java cannot render the popper); verify manually in a browser.
Are you interested in contributing a fix?
Yes. Targeted fix at the utils.js document-click containment check (and/or making the combobox reference the input), per the analysis above.
Jenkins and plugins versions report
Pre-existing on current
master(verified at master063b6a7, Jenkins 2.568+; combobox componentsrc/main/js/components/dropdowns/combo-box.js, tippy.js 6.3.7). Not introduced by #26884 (theappendTochange does not affect this flash). Client-side / web-UI only. Affects<f:combobox>(INPUT.combobox2);INPUT.auto-completeis not affected. Most visible when the combobox is rendered inside a<dialog>.What Operating System are you using (both controller, and any agents involved in the problem)?
Controller OS is irrelevant (client-side). Reproduces in any modern browser with a mouse. (Originally reported for a combobox shown inside a dialog.)
Reproduction steps
<f:combobox>, ideally inside a<dialog>(a plugin descriptor config opened via an "Add"/config dialog, for example the credentials add/config flow). The same structural code path is exercised in core at/project-relationship(projectRelationship.jelly:47,52).Expected Results
Clicking into the combobox opens the suggestion list and keeps it open, the same as typing does.
Actual Results
On click, the suggestion list appears and immediately disappears (a flash), and a second click is needed to keep it open. Typing in the same field opens the list normally with no flash.
Anything else?
Root cause, verified against the source. Single true cause: the Jenkins
document"click" listener inutils.jshides the dropdown because the combobox's tippy reference is the sibling<div>, not the clicked<input>.Structural setup (combobox-specific):
src/main/js/components/dropdowns/combo-box.js:63-64inserts a sibling DIV after the input (e.parentNode.insertBefore(div, e.nextElementSibling)), andcombo-box.js:29callsUtils.generateDropdown(div, …), so the tippy reference is the DIV (div.contains(input)isfalse).combo-box.js:77shows the dropdown when the input is focused/clicked:e.addEventListener("focus", () => updateSuggestions(e, div, items)), which callse.dropdown.show()(combo-box.js:41). It is shown programmatically, not via tippy'strigger:"click".The hide that causes the flash,
src/main/js/components/dropdowns/utils.js:31-42:instance.referenceis the DIV;event.targetis the INPUT (a sibling, outside the DIV), soisClickOnReferenceisfalse, the target is not aSELECT, andinstance.hide()runs.Sequence on one click (
mousedown,focus,mouseup,click):focus(combo-box.js:77) callse.dropdown.show(), so the items become visible.clickphase bubbles todocumentand hits theutils.js:31listener; the reference (DIV) does not contain the input, soinstance.hide()runs.Why typing does not flash: typing shows the list via the
inputevent (combo-box.js:85-90), which dispatches noclick, so theutils.js:31listener never fires.Why it is combobox-specific (autocomplete never flashes):
autocomplete.js:39-40passese), so a click on the input givesinstance.reference.contains(event.target) === trueand the hide branch is skipped.input+focusout,autocomplete.js:103-111), so a bare click opens nothing to flash.Ruled out: tippy's own
onDocumentPress/hideOnClick(defaulthideOnClick: true, not overridden) is not decisive, because the list is shown programmatically and the deterministic hide is the app'sutils.js:31listener; tippytrigger:"click"toggling is not involved, because tippy binds its click trigger to the DIV reference, which the user never clicks.Fix direction: at
utils.js:32, treat a click on the combobox's associated input as "on reference" (for exampleinstance.reference.parentNode.contains(event.target), or check the reference's sibling input), or make the combobox's tippy reference the input itself like autocomplete (combo-box.js:29), or guard the focus-to-show so it does not re-open within the same click. No automated coverage (HtmlUnitComboBoxTest.javacannot render the popper); verify manually in a browser.Are you interested in contributing a fix?
Yes. Targeted fix at the
utils.jsdocument-click containment check (and/or making the combobox reference the input), per the analysis above.