diff --git a/core/src/main/resources/jenkins/model/Jenkins/configure.jelly b/core/src/main/resources/jenkins/model/Jenkins/configure.jelly index 57e2b2cbb0..c5644dd192 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/configure.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/configure.jelly @@ -29,7 +29,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/lib/form/breadcrumb-config-outline.jelly b/core/src/main/resources/lib/form/breadcrumb-config-outline.jelly index 7a5f4d3b20..9c730d1941 100644 --- a/core/src/main/resources/lib/form/breadcrumb-config-outline.jelly +++ b/core/src/main/resources/lib/form/breadcrumb-config-outline.jelly @@ -32,5 +32,5 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/lib/layout/breadcrumb.jelly b/core/src/main/resources/lib/layout/breadcrumb.jelly index d0284e4b37..7d41ad3164 100644 --- a/core/src/main/resources/lib/layout/breadcrumb.jelly +++ b/core/src/main/resources/lib/layout/breadcrumb.jelly @@ -48,10 +48,10 @@ THE SOFTWARE. -
  • +
  • - ${attrs.title} + ${attrs.title} diff --git a/src/main/js/components/dropdowns/autocomplete.js b/src/main/js/components/dropdowns/autocomplete.js index 068313f84b..d4d37fd779 100644 --- a/src/main/js/components/dropdowns/autocomplete.js +++ b/src/main/js/components/dropdowns/autocomplete.js @@ -93,7 +93,6 @@ function init() { 0, function (e) { e.setAttribute("autocomplete", "off"); - e.dataset["hideOnClick"] = "false"; // form field with auto-completion support e.style.position = "relative"; // otherwise menu won't hide on tab with nothing selected diff --git a/src/main/js/components/dropdowns/inpage-jumplist.js b/src/main/js/components/dropdowns/inpage-jumplist.js index d912b77330..d1b9a4cdd6 100644 --- a/src/main/js/components/dropdowns/inpage-jumplist.js +++ b/src/main/js/components/dropdowns/inpage-jumplist.js @@ -5,12 +5,10 @@ import { toId } from "@/util/dom"; * sections on the page (if using ) */ function init() { - const inpageNavigationBreadcrumb = document.querySelector("#inpage-nav"); + const inpageNavigationBreadcrumb = document.querySelector("#inpage-nav span"); if (inpageNavigationBreadcrumb) { - const chevron = document.createElement("li"); - chevron.classList.add("children"); - chevron.items = Array.from( + inpageNavigationBreadcrumb.items = Array.from( document.querySelectorAll( "form > div > .jenkins-section > .jenkins-section__title", ), @@ -18,8 +16,6 @@ function init() { section.id = toId(section.textContent); return { label: section.textContent, url: "#" + section.id }; }); - - inpageNavigationBreadcrumb.after(chevron); } } diff --git a/src/main/js/components/dropdowns/jumplists.js b/src/main/js/components/dropdowns/jumplists.js index 1ee97588c8..f861b483e7 100644 --- a/src/main/js/components/dropdowns/jumplists.js +++ b/src/main/js/components/dropdowns/jumplists.js @@ -38,13 +38,13 @@ function generateDropdowns() { Utils.generateDropdown( element, (instance) => { - const href = element.href; - if (element.items) { instance.setContent(Utils.generateDropdownItems(element.items)); return; } + const href = element.href; + const hasModelLink = element.classList.contains( "hoverable-model-link", ); @@ -105,7 +105,7 @@ function generateDropdowns() { instance.loaded = true; }); }, - false, + element.items != null, { trigger: "mouseenter", offset: [-16, 10], diff --git a/src/main/js/components/dropdowns/utils.js b/src/main/js/components/dropdowns/utils.js index 473139680a..c226c962de 100644 --- a/src/main/js/components/dropdowns/utils.js +++ b/src/main/js/components/dropdowns/utils.js @@ -22,8 +22,6 @@ function generateDropdown(element, callback, immediate, options = {}) { {}, Templates.dropdown(), { - hideOnClick: - element.dataset["hideOnClick"] !== "false" ? "toggle" : false, onCreate(instance) { const onload = () => { if (instance.loaded) { @@ -31,34 +29,18 @@ function generateDropdown(element, callback, immediate, options = {}) { } document.addEventListener("click", (event) => { - const isClickInAnyDropdown = - !!event.target.closest("[data-tippy-root]"); const isClickOnReference = instance.reference.contains( event.target, ); + // Don't close the dropdown if the user is interacting with a SELECT menu inside of it + const isSelect = event.target.tagName === "SELECT"; - if (!isClickInAnyDropdown && !isClickOnReference) { + if (!isClickOnReference && !isSelect) { + instance.clickToHide = true; instance.hide(); } }); - instance.popper.addEventListener("mouseenter", () => { - const handleMouseMove = () => { - const dropdowns = - document.querySelectorAll("[data-tippy-root]"); - const isMouseOverAnyDropdown = Array.from(dropdowns).some( - (dropdown) => dropdown.matches(":hover"), - ); - - if (!isMouseOverAnyDropdown) { - instance.hide(); - document.removeEventListener("mousemove", handleMouseMove); - } - }; - - document.addEventListener("mousemove", handleMouseMove); - }); - callback(instance); }; if (immediate) { @@ -69,13 +51,21 @@ function generateDropdown(element, callback, immediate, options = {}) { }); } }, - onHide() { - const dropdowns = document.querySelectorAll("[data-tippy-root]"); - const isMouseOverAnyDropdown = Array.from(dropdowns).some( - (dropdown) => dropdown.matches(":hover"), - ); + onHide(instance) { + if ( + instance.props.trigger === "mouseenter" && + !instance.clickToHide + ) { + const dropdowns = document.querySelectorAll("[data-tippy-root]"); + const isMouseOverAnyDropdown = Array.from(dropdowns).some( + (dropdown) => dropdown.matches(":hover"), + ); - return !isMouseOverAnyDropdown; + return !isMouseOverAnyDropdown; + } + + instance.clickToHide = false; + return true; }, }, options, diff --git a/src/main/scss/base/_core.scss b/src/main/scss/base/_core.scss index ad90d35e8f..944e1945ef 100644 --- a/src/main/scss/base/_core.scss +++ b/src/main/scss/base/_core.scss @@ -3,6 +3,7 @@ html { box-sizing: border-box; -webkit-tap-highlight-color: transparent; color: var(--text-color); + scroll-padding-top: calc(var(--header-height) + var(--section-padding)); } body {