diff --git a/.github/renovate.json b/.github/renovate.json
index 90c5a18d9f6d..cfd588a66b8d 100644
--- a/.github/renovate.json
+++ b/.github/renovate.json
@@ -71,16 +71,6 @@
"org.fusesource.jansi:jansi"
]
},
- {
- "description": "Depends on commons-lang3 which is in progress for removal from core. See: https://issues.jenkins.io/browse/JENKINS-73355",
- "matchManagers": [
- "maven"
- ],
- "enabled": false,
- "matchPackageNames": [
- "org.apache.commons:commons-compress"
- ]
- },
{
"description": "Contains incompatible API changes and needs compatibility work. See: https://github.com/jenkinsci/jenkins/pull/4224",
"matchManagers": [
diff --git a/bom/pom.xml b/bom/pom.xml
index 61de025b3e9b..f94253ce6f70 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -191,11 +191,6 @@ THE SOFTWARE.
ant
1.10.15
-
- org.apache.commons
- commons-compress
- 1.26.1
-
org.apache.commons
commons-fileupload2
diff --git a/core/pom.xml b/core/pom.xml
index 9bff5e5ad0b2..0b9cb30d8763 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -285,17 +285,6 @@ THE SOFTWARE.
org.apache.ant
ant
-
- org.apache.commons
- commons-compress
-
-
-
- org.apache.commons
- commons-lang3
-
-
-
org.apache.commons
commons-fileupload2-core
diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java
index 150b1b658c16..67801475233d 100644
--- a/core/src/main/java/hudson/Functions.java
+++ b/core/src/main/java/hudson/Functions.java
@@ -62,6 +62,7 @@
import hudson.model.View;
import hudson.scm.SCM;
import hudson.scm.SCMDescriptor;
+import hudson.search.SearchFactory;
import hudson.search.SearchableModelObject;
import hudson.security.ACL;
import hudson.security.AccessControlled;
@@ -124,6 +125,7 @@
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.DecimalFormat;
+import java.text.MessageFormat;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
@@ -2576,4 +2578,34 @@ static String guessIcon(String iconGuess, String rootURL) {
public static String generateItemId() {
return String.valueOf(Math.floor(Math.random() * 3000));
}
+
+ @Restricted(NoExternalUse.class)
+ public static ExtensionList getSearchFactories() {
+ return SearchFactory.all();
+ }
+
+ /**
+ * @param keyboardShortcut the shortcut to be translated
+ * @return the translated shortcut, e.g. CMD+K to ⌘+K for macOS, CTRL+K for Windows
+ */
+ @Restricted(NoExternalUse.class)
+ public static String translateModifierKeysForUsersPlatform(String keyboardShortcut) {
+ StaplerRequest2 currentRequest = Stapler.getCurrentRequest2();
+ currentRequest.getWebApp().getDispatchValidator().allowDispatch(currentRequest, Stapler.getCurrentResponse2());
+ String userAgent = currentRequest.getHeader("User-Agent");
+
+ List platformsThatUseCommand = List.of("MAC", "IPHONE", "IPAD");
+ boolean useCmdKey = platformsThatUseCommand.stream().anyMatch(e -> userAgent.toUpperCase().contains(e));
+
+ return keyboardShortcut.replace("CMD", useCmdKey ? "⌘" : "CTRL");
+ }
+
+ @Restricted(NoExternalUse.class)
+ public static String formatMessage(String format, Object args) {
+ if (format == null) {
+ return args.toString();
+ }
+
+ return MessageFormat.format(format, args);
+ }
}
diff --git a/core/src/main/java/hudson/model/Descriptor.java b/core/src/main/java/hudson/model/Descriptor.java
index 33c981d657f5..c55b7982695e 100644
--- a/core/src/main/java/hudson/model/Descriptor.java
+++ b/core/src/main/java/hudson/model/Descriptor.java
@@ -474,6 +474,12 @@ public void calcAutoCompleteSettings(String field, Map attribute
if (method == null)
return; // no auto-completion
+ // build query parameter line by figuring out what should be submitted
+ List depends = buildFillDependencies(method, new ArrayList<>());
+ if (!depends.isEmpty()) {
+ attributes.put("fillDependsOn", String.join(" ", depends));
+ }
+
attributes.put("autoCompleteUrl", String.format("%s/%s/autoComplete%s", getCurrentDescriptorByNameUrl(), getDescriptorUrl(), capitalizedFieldName));
}
diff --git a/core/src/main/java/hudson/model/Job.java b/core/src/main/java/hudson/model/Job.java
index d22c25e98e3d..7d140656e363 100644
--- a/core/src/main/java/hudson/model/Job.java
+++ b/core/src/main/java/hudson/model/Job.java
@@ -541,7 +541,7 @@ public void find(String token, List result) {
public void suggest(String token, List result) {
find(token, result);
}
- }).add("configure", "config", "configure");
+ });
}
@Override
diff --git a/core/src/main/java/hudson/search/Search.java b/core/src/main/java/hudson/search/Search.java
index 7773d9e9d696..9bd624e34742 100644
--- a/core/src/main/java/hudson/search/Search.java
+++ b/core/src/main/java/hudson/search/Search.java
@@ -158,7 +158,7 @@ public void doSuggestOpenSearch(StaplerRequest2 req, StaplerResponse2 rsp, @Quer
public void doSuggest(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String query) throws IOException, ServletException {
Result r = new Result();
for (SuggestedItem item : getSuggestions(req, query))
- r.suggestions.add(new Item(item.getPath()));
+ r.suggestions.add(new Item(item.getPath(), item.getUrl()));
rsp.serveExposedBean(req, r, Flavor.JSON);
}
@@ -252,12 +252,25 @@ public static class Result {
@ExportedBean(defaultVisibility = 999)
public static class Item {
+
@Exported
@SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification = "read by Stapler")
public String name;
+ private final String url;
+
public Item(String name) {
+ this(name, null);
+ }
+
+ public Item(String name, String url) {
this.name = name;
+ this.url = url;
+ }
+
+ @Exported
+ public String getUrl() {
+ return url;
}
}
diff --git a/core/src/main/java/hudson/search/SuggestedItem.java b/core/src/main/java/hudson/search/SuggestedItem.java
index 9ba455270e58..6911d002fe50 100644
--- a/core/src/main/java/hudson/search/SuggestedItem.java
+++ b/core/src/main/java/hudson/search/SuggestedItem.java
@@ -62,7 +62,7 @@ private void getPath(StringBuilder buf) {
buf.append(item.getSearchName());
else {
parent.getPath(buf);
- buf.append(' ').append(item.getSearchName());
+ buf.append(" » ").append(item.getSearchName());
}
}
diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java
index 312f7a804cde..e643e848dd9b 100644
--- a/core/src/main/java/jenkins/model/Jenkins.java
+++ b/core/src/main/java/jenkins/model/Jenkins.java
@@ -2346,9 +2346,7 @@ public String getSearchUrl() {
public SearchIndexBuilder makeSearchIndex() {
SearchIndexBuilder builder = super.makeSearchIndex();
if (hasPermission(ADMINISTER)) {
- builder.add("configure", "config", "configure")
- .add("manage")
- .add("log");
+ builder.add("manage", Messages.ManageJenkinsAction_DisplayName());
}
builder.add(new CollectionSearchIndex() {
@Override
diff --git a/core/src/main/java/jenkins/telemetry/Telemetry.java b/core/src/main/java/jenkins/telemetry/Telemetry.java
index 1f60e319f97d..de081c16954b 100644
--- a/core/src/main/java/jenkins/telemetry/Telemetry.java
+++ b/core/src/main/java/jenkins/telemetry/Telemetry.java
@@ -130,6 +130,11 @@ public static ExtensionList all() {
return ExtensionList.lookup(Telemetry.class);
}
+ @Restricted(NoExternalUse.class) // called by jelly
+ public static boolean isAnyTrialActive() {
+ return all().stream().anyMatch(Telemetry::isActivePeriod);
+ }
+
/**
* @since 2.147
* @return whether to collect telemetry
diff --git a/core/src/main/resources/hudson/model/UsageStatistics/global.groovy b/core/src/main/resources/hudson/model/UsageStatistics/global.groovy
index 5506a37a67d5..7254eb283a60 100644
--- a/core/src/main/resources/hudson/model/UsageStatistics/global.groovy
+++ b/core/src/main/resources/hudson/model/UsageStatistics/global.groovy
@@ -8,7 +8,7 @@ def f=namespace(lib.FormTagLib)
f.section(title: _("Usage Statistics")) {
if (UsageStatistics.DISABLED) {
- span(class: "jenkins-not-applicable") {
+ div(class: "jenkins-not-applicable jenkins-description") {
raw(_("disabledBySystemProperty"))
}
} else if (FIPS140.useCompliantAlgorithms()) {
diff --git a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.jelly b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.jelly
index a1bef14d4e22..2d01661a175b 100644
--- a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.jelly
+++ b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.jelly
@@ -1,14 +1,14 @@
-
+
For any project, it's critical to know how the software is used, but tracking usage data is inherently difficult in open-source projects.
Anonymous usage statistics address this need.
When enabled, Jenkins periodically sends information to the Jenkins project.
The Jenkins project uses this information to set development priorities.
-
+
- General usage statistics
+ General usage statistics
Jenkins reports the following general usage statistics:
- Telemetry collection
+ Telemetry collection
@@ -38,24 +38,34 @@
Each trial has a specific purpose and a defined end date, after which collection stops, independent of the installed versions of Jenkins or plugins.
Once a trial is complete, the trial results may be aggregated and shared with the developer community.
-
- The following trials defined on this instance are active now or in the future:
-
+
+
-
-
-
- ${collector.displayName}
-
-
-
- Start date: ${collector.start}
- End date: ${collector.end}
-
-
-
-
-
+
+
+ ${%There are currently no active trials.}
+
+
+
+ The following trials defined on this instance are active now or in the future:
+
+
+
+
+ ${collector.displayName}
+
+
+
+ Start date: ${collector.start}
+
+ End date: ${collector.end}
+
+
+
+
+
+
+
diff --git a/core/src/main/resources/jenkins/views/JenkinsHeader/search-box.js b/core/src/main/resources/jenkins/views/JenkinsHeader/search-box.js
deleted file mode 100644
index 91e805c4ceaf..000000000000
--- a/core/src/main/resources/jenkins/views/JenkinsHeader/search-box.js
+++ /dev/null
@@ -1,6 +0,0 @@
-(function () {
- var element = document.getElementById("search-box-completion");
- if (element) {
- createSearchBox(element.getAttribute("data-search-url"));
- }
-})();
diff --git a/core/src/main/resources/lib/form/toggleSwitch.jelly b/core/src/main/resources/lib/form/toggleSwitch.jelly
index 2a2da3e94eb4..b0c9fcf5f835 100644
--- a/core/src/main/resources/lib/form/toggleSwitch.jelly
+++ b/core/src/main/resources/lib/form/toggleSwitch.jelly
@@ -76,19 +76,19 @@ THE SOFTWARE.
disabled="${readOnlyMode ? 'true' : null}"
checked="${value ? 'true' : null}"/>
+ for="${attrs.id}" data-title="${attrs.title}" data-checked-title="${attrs.checkedTitle}">
-
- ${title}
+
+ ${attrs.title}
- ${title}
- ${checkedTitle}
+ ${attrs.title}
+ ${attrs.checkedTitle}
-
- ${description}
+
+ ${attrs.description}
diff --git a/core/src/main/resources/lib/layout/command-palette.jelly b/core/src/main/resources/lib/layout/command-palette.jelly
new file mode 100644
index 000000000000..3d454f88a8c1
--- /dev/null
+++ b/core/src/main/resources/lib/layout/command-palette.jelly
@@ -0,0 +1,47 @@
+
+
+
+
+
+ The command palette overlay
+
+
+
+
+
+
+
+
diff --git a/core/src/main/resources/lib/layout/header/searchbox.jelly b/core/src/main/resources/lib/layout/header/searchbox.jelly
index 916f5ad49c22..033dc2ab0407 100644
--- a/core/src/main/resources/lib/layout/header/searchbox.jelly
+++ b/core/src/main/resources/lib/layout/header/searchbox.jelly
@@ -1,25 +1,27 @@
-
-
diff --git a/core/src/main/resources/lib/layout/search-bar.properties b/core/src/main/resources/lib/layout/search-bar.properties
new file mode 100644
index 000000000000..5a17184bb037
--- /dev/null
+++ b/core/src/main/resources/lib/layout/search-bar.properties
@@ -0,0 +1,23 @@
+# The MIT License
+#
+# Copyright (c) 2023, Damian Szczepanik
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+shortcut=Press '{0}' on your keyboard to focus
diff --git a/core/src/main/resources/lib/layout/search-bar_pl.properties b/core/src/main/resources/lib/layout/search-bar_pl.properties
index 1404a046d112..b9de372589b4 100644
--- a/core/src/main/resources/lib/layout/search-bar_pl.properties
+++ b/core/src/main/resources/lib/layout/search-bar_pl.properties
@@ -20,4 +20,4 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
-Press\ /\ on\ your\ keyboard\ to\ focus=Naciśnij / na klawiaturze, aby przesunąć tutaj kursor
+shortcut=Naciśnij '{0}' na klawiaturze, aby przesunąć tutaj kursor
diff --git a/core/src/main/resources/lib/layout/search-bar_pt_BR.properties b/core/src/main/resources/lib/layout/search-bar_pt_BR.properties
index b676df91ce65..3d3b237a71f2 100644
--- a/core/src/main/resources/lib/layout/search-bar_pt_BR.properties
+++ b/core/src/main/resources/lib/layout/search-bar_pt_BR.properties
@@ -21,4 +21,4 @@
# THE SOFTWARE.
Search=Busca
-Press\ /\ on\ your\ keyboard\ to\ focus=Digite /\ no seu teclado para realçar
+shortcut=Digite '{0}' no seu teclado para realçar
diff --git a/eslint.config.cjs b/eslint.config.cjs
index 0362bf627a7a..a546c32cfa44 100644
--- a/eslint.config.cjs
+++ b/eslint.config.cjs
@@ -36,7 +36,6 @@ module.exports = [
CodeMirror: "readonly",
ComboBox: "readonly",
COMBOBOX_VERSION: "writeable",
- createSearchBox: "readonly",
crumb: "readonly",
dialog: "readonly",
ensureVisible: "readonly",
@@ -61,6 +60,7 @@ module.exports = [
object: "readonly",
objectToUrlFormEncoded: "readonly",
onSetupWizardInitialized: "readonly",
+ qs: "readonly",
refillOnChange: "readonly",
refreshPart: "readonly",
registerSortableDragDrop: "readonly",
@@ -72,6 +72,7 @@ module.exports = [
shortenName: "readonly",
Sortable: "readonly",
toQueryString: "readonly",
+ TryEach: "readonly",
ts_refresh: "readonly",
updateOptionalBlock: "readonly",
Utilities: "readonly",
diff --git a/package.json b/package.json
index bfcb2bd931a2..1989b499283c 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"lint": "yarn lint:js && yarn lint:css"
},
"devDependencies": {
- "@babel/cli": "7.25.9",
+ "@babel/cli": "7.26.4",
"@babel/core": "7.26.0",
"@babel/preset-env": "7.26.0",
"@eslint/js": "9.16.0",
@@ -34,21 +34,21 @@
"eslint": "9.16.0",
"eslint-config-prettier": "9.1.0",
"eslint-formatter-checkstyle": "8.40.0",
- "globals": "15.12.0",
+ "globals": "15.13.0",
"handlebars-loader": "1.7.3",
"mini-css-extract-plugin": "2.9.2",
"postcss": "8.4.49",
"postcss-loader": "8.1.1",
"postcss-preset-env": "10.1.1",
"postcss-scss": "4.0.9",
- "prettier": "3.4.1",
- "sass": "1.81.0",
- "sass-loader": "16.0.3",
+ "prettier": "3.4.2",
+ "sass": "1.82.0",
+ "sass-loader": "16.0.4",
"style-loader": "4.0.0",
"stylelint": "16.11.0",
"stylelint-checkstyle-reporter": "1.0.0",
"stylelint-config-standard": "36.0.1",
- "webpack": "5.96.1",
+ "webpack": "5.97.1",
"webpack-cli": "5.1.4",
"webpack-remove-empty-scripts": "1.0.4"
},
diff --git a/src/main/js/api/search.js b/src/main/js/api/search.js
new file mode 100644
index 000000000000..ebe5f89df1bd
--- /dev/null
+++ b/src/main/js/api/search.js
@@ -0,0 +1,10 @@
+/**
+ * @param {string} searchTerm
+ */
+function search(searchTerm) {
+ const address = document.getElementById("button-open-command-palette").dataset
+ .searchUrl;
+ return fetch(`${address}?query=${encodeURIComponent(searchTerm)}`);
+}
+
+export default { search: search };
diff --git a/src/main/js/app.js b/src/main/js/app.js
index 63a35226d7d4..c59153608751 100644
--- a/src/main/js/app.js
+++ b/src/main/js/app.js
@@ -1,4 +1,5 @@
import Dropdowns from "@/components/dropdowns";
+import CommandPalette from "@/components/command-palette";
import Notifications from "@/components/notifications";
import SearchBar from "@/components/search-bar";
import Tooltips from "@/components/tooltips";
@@ -7,6 +8,7 @@ import ConfirmationLink from "@/components/confirmation-link";
import Dialogs from "@/components/dialogs";
Dropdowns.init();
+CommandPalette.init();
Notifications.init();
SearchBar.init();
Tooltips.init();
diff --git a/src/main/js/components/command-palette/datasources.js b/src/main/js/components/command-palette/datasources.js
new file mode 100644
index 000000000000..8357fca3feaf
--- /dev/null
+++ b/src/main/js/components/command-palette/datasources.js
@@ -0,0 +1,29 @@
+import { LinkResult } from "./models";
+import Search from "@/api/search";
+import * as Symbols from "./symbols";
+
+export const JenkinsSearchSource = {
+ execute(query) {
+ const rootUrl = document.head.dataset.rooturl;
+
+ function correctAddress(url) {
+ if (url.startsWith("/")) {
+ url = url.substring(1);
+ }
+
+ return rootUrl + "/" + url;
+ }
+
+ return Search.search(query).then((rsp) =>
+ rsp.json().then((data) => {
+ return data["suggestions"].slice().map((e) =>
+ LinkResult({
+ icon: Symbols.SEARCH,
+ label: e.name,
+ url: correctAddress(e.url),
+ }),
+ );
+ }),
+ );
+ },
+};
diff --git a/src/main/js/components/command-palette/index.js b/src/main/js/components/command-palette/index.js
new file mode 100644
index 000000000000..dfb3c6eb7efe
--- /dev/null
+++ b/src/main/js/components/command-palette/index.js
@@ -0,0 +1,155 @@
+import { LinkResult } from "@/components/command-palette/models";
+import { JenkinsSearchSource } from "./datasources";
+import debounce from "lodash/debounce";
+import * as Symbols from "./symbols";
+import makeKeyboardNavigable from "@/util/keyboard";
+import { xmlEscape } from "@/util/security";
+import { createElementFromHtml } from "@/util/dom";
+
+const datasources = [JenkinsSearchSource];
+
+function init() {
+ const i18n = document.getElementById("command-palette-i18n");
+ const headerCommandPaletteButton = document.getElementById(
+ "button-open-command-palette",
+ );
+ const commandPalette = document.getElementById("command-palette");
+ const commandPaletteWrapper = commandPalette.querySelector(
+ ".jenkins-command-palette__wrapper",
+ );
+ const commandPaletteInput = document.getElementById("command-bar");
+ const commandPaletteSearchBarContainer = commandPalette.querySelector(
+ ".jenkins-command-palette__search",
+ );
+ const searchResults = document.getElementById("search-results");
+ const searchResultsContainer = document.getElementById(
+ "search-results-container",
+ );
+
+ const hoverClass = "jenkins-command-palette__results__item--hover";
+
+ makeKeyboardNavigable(
+ searchResultsContainer,
+ () => searchResults.querySelectorAll("a"),
+ hoverClass,
+ );
+
+ // Events
+ headerCommandPaletteButton.addEventListener("click", function () {
+ if (commandPalette.hasAttribute("open")) {
+ hideCommandPalette();
+ } else {
+ showCommandPalette();
+ }
+ });
+
+ commandPaletteWrapper.addEventListener("click", function (e) {
+ if (e.target !== e.currentTarget) {
+ return;
+ }
+
+ hideCommandPalette();
+ });
+
+ function renderResults() {
+ const query = commandPaletteInput.value;
+ let results;
+
+ if (query.length === 0) {
+ results = Promise.all([
+ LinkResult({
+ icon: Symbols.HELP,
+ label: i18n.dataset.getHelp,
+ url: headerCommandPaletteButton.dataset.searchHelpUrl,
+ isExternal: true,
+ }),
+ ]);
+ } else {
+ results = Promise.all(datasources.map((ds) => ds.execute(query))).then(
+ (e) => e.flat(),
+ );
+ }
+
+ results.then((results) => {
+ // Clear current search results
+ searchResults.innerHTML = "";
+
+ if (query.length === 0 || Object.keys(results).length > 0) {
+ results.forEach(function (obj) {
+ const link = createElementFromHtml(obj.render());
+ link.addEventListener("mouseenter", (e) => itemMouseEnter(e));
+ searchResults.append(link);
+ });
+
+ updateSelectedItem(0);
+ } else {
+ const label = document.createElement("p");
+ label.className = "jenkins-command-palette__info";
+ label.innerHTML =
+ "" +
+ i18n.dataset.noResultsFor +
+ " " +
+ xmlEscape(commandPaletteInput.value);
+ searchResults.append(label);
+ }
+
+ searchResultsContainer.style.height = searchResults.offsetHeight + "px";
+ commandPaletteSearchBarContainer.classList.remove(
+ "jenkins-search--loading",
+ );
+ });
+ }
+
+ const debouncedLoad = debounce(() => {
+ renderResults();
+ }, 150);
+
+ commandPaletteInput.addEventListener("input", () => {
+ commandPaletteSearchBarContainer.classList.add("jenkins-search--loading");
+ debouncedLoad();
+ });
+
+ // Helper methods for visibility of command palette
+ function showCommandPalette() {
+ commandPalette.showModal();
+ commandPaletteInput.focus();
+ commandPaletteInput.setSelectionRange(0, commandPaletteInput.value.length);
+
+ renderResults();
+ }
+
+ function hideCommandPalette() {
+ commandPalette.close();
+ }
+
+ function itemMouseEnter(item) {
+ let hoveredItems = document.querySelector("." + hoverClass);
+ if (hoveredItems) {
+ hoveredItems.classList.remove(hoverClass);
+ }
+
+ item.target.classList.add(hoverClass);
+ }
+
+ function updateSelectedItem(index, scrollIntoView = false) {
+ const maxLength = searchResults.getElementsByTagName("a").length;
+ const hoveredItem = document.querySelector("." + hoverClass);
+
+ if (hoveredItem) {
+ hoveredItem.classList.remove(hoverClass);
+ }
+
+ if (index < maxLength) {
+ const element = Array.from(searchResults.getElementsByTagName("a"))[
+ index
+ ];
+ element.classList.add(hoverClass);
+
+ if (scrollIntoView) {
+ element.scrollIntoView();
+ }
+ }
+ }
+}
+
+export default { init };
diff --git a/src/main/js/components/command-palette/models.js b/src/main/js/components/command-palette/models.js
new file mode 100644
index 000000000000..8159ce68c9a2
--- /dev/null
+++ b/src/main/js/components/command-palette/models.js
@@ -0,0 +1,27 @@
+import * as Symbols from "./symbols";
+import { xmlEscape } from "@/util/security";
+
+/**
+ * @param {Object} params
+ * @param {string} params.icon
+ * @param {string} params.label
+ * @param {string} params.url
+ * @param {boolean | undefined} params.isExternal
+ */
+export function LinkResult(params) {
+ return {
+ label: params.label,
+ url: params.url,
+ render: () => {
+ return `
+ ${
+ params.icon
+ }
+ ${xmlEscape(params.label)}
+ ${params.isExternal ? Symbols.EXTERNAL_LINK : ""}
+ `;
+ },
+ };
+}
diff --git a/src/main/js/components/command-palette/symbols.js b/src/main/js/components/command-palette/symbols.js
new file mode 100644
index 000000000000..f1d7b63c4b2c
--- /dev/null
+++ b/src/main/js/components/command-palette/symbols.js
@@ -0,0 +1,3 @@
+export const EXTERNAL_LINK = ` `;
+export const HELP = ` `;
+export const SEARCH = `Search `;
diff --git a/src/main/js/components/dropdowns/autocomplete.js b/src/main/js/components/dropdowns/autocomplete.js
index b6d982c44911..068313f84b36 100644
--- a/src/main/js/components/dropdowns/autocomplete.js
+++ b/src/main/js/components/dropdowns/autocomplete.js
@@ -59,9 +59,30 @@ function init() {
}
return;
}
- const url =
- e.getAttribute("autoCompleteUrl") + "?value=" + encodeURIComponent(word);
- fetch(url)
+
+ const url = e.getAttribute("autoCompleteUrl");
+
+ const depends = e.getAttribute("fillDependsOn");
+ const q = qs(e).addThis();
+ if (depends && depends.length > 0) {
+ depends.split(" ").forEach(
+ TryEach(function (n) {
+ q.nearBy(n);
+ }),
+ );
+ }
+
+ const queryString = q.toString();
+ const idx = queryString.indexOf("?");
+ const parameters = queryString.substring(idx + 1);
+
+ fetch(url, {
+ method: "post",
+ headers: crumb.wrap({
+ "Content-Type": "application/x-www-form-urlencoded",
+ }),
+ body: parameters,
+ })
.then((rsp) => (rsp.ok ? rsp.json() : {}))
.then((response) => createAndShowDropdown(e, response.suggestions || []));
}
diff --git a/src/main/js/keyboard-shortcuts.js b/src/main/js/keyboard-shortcuts.js
index 3a10f4938b55..d22c023121ea 100644
--- a/src/main/js/keyboard-shortcuts.js
+++ b/src/main/js/keyboard-shortcuts.js
@@ -1,19 +1,21 @@
import hotkeys from "hotkeys-js";
window.addEventListener("load", () => {
- const searchBar = document.querySelector("#search-box");
- searchBar.placeholder =
- searchBar.placeholder +
- ` (${translateModifierKeysForUsersPlatform("CMD+K").replace("CMD", "⌘")})`;
+ const openCommandPaletteButton = document.querySelector(
+ "#button-open-command-palette",
+ );
+ if (openCommandPaletteButton) {
+ hotkeys(translateModifierKeysForUsersPlatform("CMD+K"), () => {
+ openCommandPaletteButton.click();
- hotkeys(translateModifierKeysForUsersPlatform("CMD+K"), () => {
- searchBar.focus();
-
- // Returning false stops the event and prevents default browser events
- return false;
- });
+ // Returning false stops the event and prevents default browser events
+ return false;
+ });
+ }
- const pageSearchBar = document.querySelectorAll(".jenkins-search__input");
+ const pageSearchBar = document.querySelectorAll(
+ "#page-body .jenkins-search__input",
+ );
if (pageSearchBar.length === 1) {
hotkeys("/", () => {
pageSearchBar[0].focus();
diff --git a/src/main/scss/abstracts/_mixins.scss b/src/main/scss/abstracts/_mixins.scss
index 63a963f698c6..7999284e1a96 100644
--- a/src/main/scss/abstracts/_mixins.scss
+++ b/src/main/scss/abstracts/_mixins.scss
@@ -59,6 +59,7 @@
@mixin item {
position: relative;
z-index: 0;
+ text-decoration: none !important;
border-radius: 0.66rem;
&::before,
diff --git a/src/main/scss/abstracts/_theme.scss b/src/main/scss/abstracts/_theme.scss
index 9353cc165201..f1248e5b21de 100644
--- a/src/main/scss/abstracts/_theme.scss
+++ b/src/main/scss/abstracts/_theme.scss
@@ -199,6 +199,19 @@ $semantics: (
--link-text-decoration--active: underline;
--link-font-weight: 450;
+ // Command Palette
+ --command-palette-results-backdrop-filter: contrast(0.7) brightness(1.5)
+ saturate(1.4) blur(20px);
+ --command-palette-inset-shadow: inset 0 0 2px 2px rgba(255, 255, 255, 0.1);
+
+ ::backdrop {
+ --command-palette-backdrop-background: radial-gradient(
+ farthest-corner at 50% 30vh,
+ rgba(0, 0, 0, 0.3),
+ rgba(0, 0, 0, 0.1)
+ );
+ }
+
// Tooltips
--tooltip-backdrop-filter: saturate(2) blur(20px);
--tooltip-color: var(--text-color);
diff --git a/src/main/scss/base/_style.scss b/src/main/scss/base/_style.scss
index 273d583d4ca9..98807c6e5401 100644
--- a/src/main/scss/base/_style.scss
+++ b/src/main/scss/base/_style.scss
@@ -372,6 +372,8 @@ pre.console {
border-radius: 6px;
z-index: 0;
+ --section-padding: 0.8rem;
+
&::before {
content: "";
position: absolute;
@@ -389,6 +391,24 @@ pre.console {
p:last-of-type {
margin-bottom: 0;
}
+
+ // add spacing above headings except for when its the first element in the help
+ // the need for this is caused by p:last-of-type setting margin-bottom to 0
+ // unfortunately because of the varied markup I wasn't able to find a way to avoid this
+ h1:not(:first-child),
+ .h1:not(:first-child),
+ h2:not(:first-child),
+ .h2:not(:first-child),
+ h3:not(:first-child),
+ .h3:not(:first-child),
+ h4:not(:first-child),
+ .h4:not(:first-child),
+ h5:not(:first-child),
+ .h5:not(:first-child),
+ h6:not(:first-child),
+ .h6:not(:first-child) {
+ margin-top: var(--section-padding);
+ }
}
.help .from-plugin {
diff --git a/src/main/scss/components/_command-palette.scss b/src/main/scss/components/_command-palette.scss
new file mode 100644
index 000000000000..6c3b16517e3a
--- /dev/null
+++ b/src/main/scss/components/_command-palette.scss
@@ -0,0 +1,176 @@
+@use "../abstracts/mixins";
+
+.jenkins-command-palette__dialog {
+ &::backdrop {
+ background: var(--command-palette-backdrop-background);
+ backdrop-filter: contrast(0.7) brightness(0.9) saturate(1.25) blur(3px);
+ animation: jenkins-modal-backdrop-animate-in 0.3s;
+ }
+}
+
+.jenkins-command-palette__dialog {
+ background: none;
+ border: none;
+ height: 100vw !important;
+ max-height: 100vh !important;
+ width: 100vw !important;
+ max-width: 100vw !important;
+ margin: 0 !important;
+ padding: 0 !important;
+}
+
+.jenkins-command-palette__wrapper {
+ width: 100%;
+ height: 100%;
+ max-height: 100vh;
+ overflow: scroll;
+ padding-top: 20vh;
+}
+
+.jenkins-command-palette {
+ position: relative;
+ width: 50vw;
+ min-width: 400px;
+ max-width: 650px;
+ color: var(--text-color);
+ pointer-events: auto;
+ margin: 0 auto 20vh;
+
+ &__search {
+ --search-bar-height: 3rem !important;
+
+ background: transparent;
+ box-shadow:
+ 0 0 0 20px transparent,
+ var(--command-palette-inset-shadow);
+ margin-bottom: 1.5rem;
+ border-radius: 1rem;
+ transition: var(--standard-transition);
+ z-index: 10;
+ backdrop-filter: var(--command-palette-results-backdrop-filter);
+ max-width: unset;
+
+ input {
+ background: transparent !important;
+ border-radius: inherit;
+
+ &::before,
+ &::after {
+ border-radius: inherit;
+ }
+ }
+
+ &::before {
+ content: unset;
+ }
+ }
+
+ &__results-container {
+ display: flex;
+ flex-direction: column;
+ border-radius: 1rem;
+ backdrop-filter: var(--command-palette-results-backdrop-filter);
+ box-shadow: var(--command-palette-inset-shadow);
+ height: 0;
+ transition: height var(--standard-transition);
+ overflow: hidden;
+ will-change: height;
+ }
+
+ &__results {
+ display: flex;
+ flex-direction: column;
+ padding: 0.5rem;
+
+ &__heading {
+ font-weight: 600;
+ font-size: 0.85rem;
+ margin: 0;
+ padding: 0.75rem 0.75rem 0.625rem;
+ color: var(--text-color-secondary);
+
+ &:not(:first-of-type) {
+ padding-top: 2rem;
+ }
+ }
+
+ &__item {
+ @include mixins.item;
+
+ --item-background--hover: color-mix(
+ in sRGB,
+ var(--text-color-secondary) 15%,
+ transparent
+ );
+ --item-background--active: color-mix(
+ in sRGB,
+ var(--text-color-secondary) 20%,
+ transparent
+ );
+
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ background: transparent;
+ padding: 0.75rem;
+ border-radius: 0.66rem;
+ font-weight: 600;
+ cursor: pointer;
+ color: var(--text-color) !important;
+ transition: var(--standard-transition);
+ box-shadow: 0 0 0 10px transparent;
+ border: none;
+ outline: none;
+
+ &--hover {
+ &::before {
+ background-color: var(--item-background--hover);
+ }
+ }
+
+ &__icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 1.4rem;
+ height: 1.4rem;
+ margin-right: 12.5px;
+ overflow: hidden;
+ pointer-events: none;
+ color: var(--text-color);
+
+ svg,
+ img {
+ width: 1.2rem;
+ height: 1.2rem;
+ }
+ }
+
+ &__description {
+ opacity: 0.5;
+ margin-left: 1ch;
+ }
+
+ &__chevron {
+ position: absolute;
+ top: calc(50% - 8px);
+ right: 12.5px;
+ width: 16px;
+ height: 16px;
+ opacity: 0.5;
+ }
+ }
+ }
+
+ &__info {
+ font-weight: 600;
+ font-size: 0.85rem;
+ margin: 0;
+ padding: 12.5px 12.5px 10px;
+ color: var(--text-color);
+
+ span {
+ color: var(--text-color-secondary);
+ }
+ }
+}
diff --git a/src/main/scss/components/_index.scss b/src/main/scss/components/_index.scss
index f3167bd091f9..d9c4133a2730 100644
--- a/src/main/scss/components/_index.scss
+++ b/src/main/scss/components/_index.scss
@@ -5,6 +5,7 @@
@use "buttons";
@use "buttons-deprecated";
@use "cards";
+@use "command-palette";
@use "content-blocks";
@use "dialogs";
@use "dropdowns";
diff --git a/src/main/scss/components/_page-header.scss b/src/main/scss/components/_page-header.scss
index e1b34ea09c71..76c7fc9028e4 100644
--- a/src/main/scss/components/_page-header.scss
+++ b/src/main/scss/components/_page-header.scss
@@ -47,6 +47,7 @@ a.page-header__brand-link {
}
.page-header__hyperlinks > a,
+.page-header__hyperlinks > button,
.am-container > a {
@include mixins.item;
@@ -54,11 +55,21 @@ a.page-header__brand-link {
display: inline-flex;
align-items: center;
+ appearance: none;
+ background: transparent;
+ outline: none;
+ border: none;
+ cursor: pointer;
color: var(--text-color);
text-decoration: none;
padding: 0.5rem;
margin-right: 0 !important;
+ svg {
+ width: 1.25rem;
+ height: 1.25rem;
+ }
+
&::before,
&::after {
inset: 0 !important;
diff --git a/src/main/scss/components/_tooltips.scss b/src/main/scss/components/_tooltips.scss
index 5f79ec42e97d..bdbb1d7dd006 100644
--- a/src/main/scss/components/_tooltips.scss
+++ b/src/main/scss/components/_tooltips.scss
@@ -30,6 +30,41 @@
margin: 0;
width: 450px;
}
+
+ .jenkins-keyboard-shortcut {
+ &::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ border-radius: 0.375rem;
+ border: 0.1rem solid var(--text-color-secondary);
+ opacity: 0.3;
+ mask-image: linear-gradient(
+ -45deg,
+ transparent 40%,
+ white,
+ transparent 60%
+ );
+ mask-size: 200% 200%;
+ animation: shortcut-glow-animation 1.25s forwards linear;
+ }
+
+ @keyframes shortcut-glow-animation {
+ 0% {
+ opacity: 0;
+ mask-position: 100% 100%;
+ }
+
+ 50% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ mask-position: 0;
+ }
+ }
+ }
}
.tippy-box[data-animation="tooltip"][data-state="hidden"] {
@@ -52,3 +87,35 @@
.jenkins-table .healthReportDetails {
display: none !important;
}
+
+.jenkins-keyboard-shortcut {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 1.7em;
+ min-height: 1.7em;
+ padding-inline: 0.55ch;
+
+ &::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ border-radius: 0.375rem;
+ border: 0.1rem solid var(--text-color-secondary);
+ opacity: 0.3;
+ }
+
+ svg {
+ width: 1em;
+ height: 1em;
+ }
+}
+
+.jenkins-keyboard-shortcut__tooltip {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.6ch;
+}
diff --git a/src/main/scss/form/_search-bar.scss b/src/main/scss/form/_search-bar.scss
index ed552e85c987..ab4f6e9718cf 100644
--- a/src/main/scss/form/_search-bar.scss
+++ b/src/main/scss/form/_search-bar.scss
@@ -38,7 +38,7 @@
min-height: 1.1rem;
aspect-ratio: 1;
margin-right: 0.2rem;
- background: currentColor;
+ background: var(--text-color-secondary);
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M256 48C141.31 48 48 141.31 48 256s93.31 208 208 208 208-93.31 208-208S370.69 48 256 48zm75.31 260.69a16 16 0 11-22.62 22.62L256 278.63l-52.69 52.68a16 16 0 01-22.62-22.62L233.37 256l-52.68-52.69a16 16 0 0122.62-22.62L256 233.37l52.69-52.68a16 16 0 0122.62 22.62L278.63 256z'/%3E%3C/svg%3E");
mask-size: contain;
mask-repeat: no-repeat;
@@ -49,11 +49,11 @@
cursor: pointer;
&:hover {
- opacity: 0.75 !important;
+ opacity: 0.85 !important;
}
&:active {
- opacity: 1 !important;
+ opacity: 0.7 !important;
}
}
@@ -78,6 +78,21 @@
}
}
+ &:active,
+ &:focus {
+ outline: none;
+ background: var(--item-background--active);
+ box-shadow:
+ 0 0 0 2px var(--focus-input-border),
+ 0 0 0 7px var(--focus-input-glow);
+
+ &::-webkit-search-cancel-button {
+ opacity: 1;
+ pointer-events: all;
+ transform: scale(1);
+ }
+ }
+
&:disabled {
cursor: not-allowed;
}
@@ -106,22 +121,24 @@
&::before,
&::after {
content: "";
- width: 0;
- height: 0;
+ width: 45%;
+ height: 45%;
max-width: 1.1rem;
max-height: 1.1rem;
- border: 0.125rem solid currentColor;
+ border: 0.125rem solid var(--text-color-secondary);
border-radius: 100%;
transition: var(--standard-transition);
grid-column-start: 1;
grid-row-start: 1;
place-self: center center;
opacity: 0;
+ scale: 0;
+ filter: blur(5px);
}
&::after {
+ border-color: currentColor;
clip-path: inset(0 0 50% 50%);
- transition: var(--standard-transition);
animation: loading-spinner 1s infinite linear;
@media (prefers-reduced-motion) {
@@ -130,56 +147,34 @@
}
}
- &__shortcut {
+ .jenkins-keyboard-shortcut {
position: absolute;
- aspect-ratio: 1 / 1;
- top: 0;
- right: 0;
- bottom: 0;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: 0.25s ease;
- text-align: center;
- font-size: 0.6875rem;
- font-weight: 500;
- line-height: 1;
+ top: calc(50% - 0.6875rem);
+ right: 0.5rem;
+ min-width: 1.375rem;
+ min-height: 1.375rem;
+ padding: 0;
color: var(--text-color-secondary);
-
- &::after {
- content: "";
- position: absolute;
- top: calc(50% - 1em);
- right: calc(50% - 1em);
- width: 2em;
- height: 2em;
- border: 0.1rem solid var(--item-background--active);
- border-radius: 0.3rem;
- }
-
- svg {
- width: 1.2em;
- height: 1.2em;
- }
}
&--loading {
.jenkins-search__icon {
svg {
opacity: 0;
- transform: scale(0);
+ scale: 0;
+ filter: blur(5px);
}
&::before {
- opacity: 0.2;
- width: 45%;
- height: 45%;
+ opacity: 0.5;
+ scale: 1;
+ filter: blur(0);
}
&::after {
opacity: 1;
- width: 45%;
- height: 45%;
+ scale: 1;
+ filter: blur(0);
}
}
}
@@ -190,6 +185,10 @@
max-width: 50vw;
margin-block: -6px;
+ .jenkins-keyboard-shortcut {
+ right: 0.8125rem;
+ }
+
&::before {
content: "";
position: absolute;
@@ -210,7 +209,7 @@
fill: var(--focus-input-border);
}
- .jenkins-search__shortcut {
+ .jenkins-keyboard-shortcut {
opacity: 0;
transform: scale(0.9);
pointer-events: none;
@@ -221,7 +220,7 @@
color: var(--text-color-secondary);
opacity: 0.5;
- .jenkins-search__shortcut {
+ .jenkins-keyboard-shortcut {
display: none;
}
}
diff --git a/test/pom.xml b/test/pom.xml
index 50111b234ab0..ac3b8efc9a5f 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -178,7 +178,7 @@ THE SOFTWARE.
org.jenkins-ci.main
jenkins-test-harness
- 2363.vf95c19b_2ca_72
+ 2364.v163897b_238b_3
test
diff --git a/test/src/test/java/hudson/model/AbstractProjectTest.java b/test/src/test/java/hudson/model/AbstractProjectTest.java
index 290096ae30bc..04db7ea8f4fb 100644
--- a/test/src/test/java/hudson/model/AbstractProjectTest.java
+++ b/test/src/test/java/hudson/model/AbstractProjectTest.java
@@ -663,6 +663,7 @@ private void testAutoCompleteResponse(JSONObject responseBody, String... project
for (String p : projects) {
JSONObject o = new JSONObject();
o.put("name", p);
+ o.put("url", JSONObject.fromObject(null));
expected.add(o);
}
assertThat(suggestions.containsAll(expected), is(true));
diff --git a/test/src/test/java/hudson/search/SearchTest.java b/test/src/test/java/hudson/search/SearchTest.java
index be92c9dd471a..31660090eba2 100644
--- a/test/src/test/java/hudson/search/SearchTest.java
+++ b/test/src/test/java/hudson/search/SearchTest.java
@@ -28,6 +28,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.jvnet.hudson.test.QueryUtils.waitUntilStringIsPresent;
import hudson.model.FreeStyleProject;
import hudson.model.ListView;
@@ -38,7 +39,6 @@
import hudson.security.GlobalMatrixAuthorizationStrategy;
import java.io.IOException;
import java.lang.reflect.Field;
-import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
@@ -48,6 +48,8 @@
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import org.htmlunit.Page;
+import org.htmlunit.html.HtmlButton;
+import org.htmlunit.html.HtmlInput;
import org.htmlunit.html.HtmlPage;
import org.junit.Rule;
import org.junit.Test;
@@ -64,15 +66,22 @@ public class SearchTest {
@Rule public JenkinsRule j = new JenkinsRule();
- /**
- * No exact match should result in a failure status code.
- */
+ private void searchWithoutNavigating(HtmlPage page, String query) throws IOException {
+ HtmlButton button = page.querySelector("#button-open-command-palette");
+ button.click();
+
+ HtmlInput search = page.querySelector("#command-bar");
+ search.setValue(query);
+ page.executeJavaScript("document.querySelector('#command-bar').dispatchEvent(new Event(\"input\"))");
+ }
+
@Test
public void testFailure() throws Exception {
- WebClient wc = j.createWebClient()
- .withThrowExceptionOnFailingStatusCode(false);
- HtmlPage resultPage = wc.search("no-such-thing");
- assertEquals(HttpURLConnection.HTTP_NOT_FOUND, resultPage.getWebResponse().getStatusCode());
+ HtmlPage page = j.createWebClient().goTo("");
+
+ searchWithoutNavigating(page, "no-such-thing");
+
+ waitUntilStringIsPresent(page, "No results for no-such-thing");
}
/**
@@ -81,13 +90,17 @@ public void testFailure() throws Exception {
@Issue("JENKINS-3415")
@Test
public void testXSS() throws Exception {
- WebClient wc = j.createWebClient()
- .withThrowExceptionOnFailingStatusCode(false);
+ WebClient wc = j.createWebClient();
wc.setAlertHandler((page, message) -> {
throw new AssertionError();
});
- HtmlPage resultPage = wc.search("");
- assertEquals(HttpURLConnection.HTTP_NOT_FOUND, resultPage.getWebResponse().getStatusCode());
+ FreeStyleProject freeStyleProject = j.createFreeStyleProject("Project");
+ freeStyleProject.setDisplayName("");
+
+ Page result = wc.search("");
+
+ assertNotNull(result);
+ assertEquals(j.getInstance().getRootUrl() + freeStyleProject.getUrl(), result.getUrl().toString());
}
@Test
@@ -127,7 +140,7 @@ public void testSearchByProjectNameInAFolder() throws Exception {
MockFolder myMockFolder = j.createFolder("my-folder-1");
FreeStyleProject myFreeStyleProject = myMockFolder.createProject(FreeStyleProject.class, "my-job-1");
- Page result = j.createWebClient().goTo(myMockFolder.getUrl() + "search?q=" + myFreeStyleProject.getFullName());
+ Page result = j.search(myFreeStyleProject.getName());
assertNotNull(result);
j.assertGoodStatus(result);
@@ -181,41 +194,6 @@ public void testSearch2ProjectsWithSameDisplayName() throws Exception {
assertFalse(contents.contains(otherDisplayName));
}
- @Test
- public void testProjectNamePrecedesDisplayName() throws Exception {
- final String project1Name = "foo";
- final String project1DisplayName = "project1DisplayName";
- final String project2Name = "project2Name";
- final String project2DisplayName = project1Name;
- final String project3Name = "project3Name";
- final String project3DisplayName = "project3DisplayName";
-
- // create 1 freestyle project with the name foo
- FreeStyleProject project1 = j.createFreeStyleProject(project1Name);
- project1.setDisplayName(project1DisplayName);
-
- // create another with the display name foo
- FreeStyleProject project2 = j.createFreeStyleProject(project2Name);
- project2.setDisplayName(project2DisplayName);
-
- // create a third project and make sure it's not picked up by search
- FreeStyleProject project3 = j.createFreeStyleProject(project3Name);
- project3.setDisplayName(project3DisplayName);
-
- // search for foo
- Page result = j.search(project1Name);
- assertNotNull(result);
- j.assertGoodStatus(result);
-
- // make sure we get the project with the name foo
- String contents = result.getWebResponse().getContentAsString();
- assertTrue(contents.contains(String.format("%s [Jenkins] ", project1DisplayName)));
- // make sure projects 2 and 3 were not picked up
- assertFalse(contents.contains(project2Name));
- assertFalse(contents.contains(project3Name));
- assertFalse(contents.contains(project3DisplayName));
- }
-
@Test
public void testGetSuggestionsHasBothNamesAndDisplayNames() throws Exception {
final String projectName = "project name";
@@ -335,7 +313,7 @@ public void testProjectNameInAFolderDisplayName() throws Exception {
String name = (String) jsonSuggestion.get("name");
- if (displayName2.equals(name)) {
+ if ("my-folder-1 » job-2".equals(name)) {
foundDisplayName = true;
}
}
diff --git a/test/src/test/java/hudson/widgets/HistoryWidgetTest.java b/test/src/test/java/hudson/widgets/HistoryWidgetTest.java
index 45af1b28b806..bc1229d3b658 100644
--- a/test/src/test/java/hudson/widgets/HistoryWidgetTest.java
+++ b/test/src/test/java/hudson/widgets/HistoryWidgetTest.java
@@ -36,7 +36,7 @@ public void displayFilterInput() throws Exception {
{ // Filter input shouldn't display when there's no build
HtmlPage page = wc.goTo("job/" + p.getName());
- DomNode searchInputContainer = page.querySelector(".jenkins-search");
+ DomNode searchInputContainer = page.querySelector("#jenkins-builds .jenkins-search");
assertTrue(searchInputContainer.getAttributes().getNamedItem("class").getNodeValue().contains("jenkins-hidden"));
}
@@ -44,7 +44,7 @@ public void displayFilterInput() throws Exception {
{ // Filter input should display when there's a build
HtmlPage page = wc.goTo("job/" + p.getName());
- DomNode searchInputContainer = page.querySelector(".jenkins-search");
+ DomNode searchInputContainer = page.querySelector("#jenkins-builds .jenkins-search");
assertFalse(searchInputContainer.getAttributes().getNamedItem("class").getNodeValue().contains("jenkins-hidden"));
}
}
diff --git a/test/src/test/java/jenkins/model/JenkinsTest.java b/test/src/test/java/jenkins/model/JenkinsTest.java
index 8fdb761791a8..acef3b6a2300 100644
--- a/test/src/test/java/jenkins/model/JenkinsTest.java
+++ b/test/src/test/java/jenkins/model/JenkinsTest.java
@@ -136,8 +136,7 @@ public void verifyUploadedFingerprintFilePermission() throws Exception {
assumeFalse(Functions.isWindows());
HtmlPage page = j.createWebClient().goTo("fingerprintCheck");
- // The form doesn't have a name, the page contain the search form and the one we're interested in
- HtmlForm form = page.getForms().get(1);
+ HtmlForm form = page.getForms().get(0);
File dir = tmp.newFolder();
File plugin = new File(dir, "htmlpublisher.jpi");
// We're using a plugin to have a file above DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD
diff --git a/war/src/main/webapp/scripts/hudson-behavior.js b/war/src/main/webapp/scripts/hudson-behavior.js
index da691e76c97f..9ae3d9298d37 100644
--- a/war/src/main/webapp/scripts/hudson-behavior.js
+++ b/war/src/main/webapp/scripts/hudson-behavior.js
@@ -895,6 +895,7 @@ function preventInputEe(event) {
}
}
+// eslint-disable-next-line no-unused-vars
function escapeHTML(html) {
return html
.replace(/&/g, "&")
@@ -2201,6 +2202,7 @@ function toQueryString(params) {
}
// get the cascaded computed style value. 'a' is the style name like 'backgroundColor'
+// eslint-disable-next-line no-unused-vars
function getStyle(e, a) {
if (document.defaultView && document.defaultView.getComputedStyle) {
return document.defaultView
@@ -2259,61 +2261,6 @@ function ensureVisible(e) {
}
}
-// set up logic behind the search box
-// eslint-disable-next-line no-unused-vars
-function createSearchBox(searchURL) {
- var ds = new YAHOO.util.XHRDataSource(searchURL + "suggest");
- ds.responseType = YAHOO.util.XHRDataSource.TYPE_JSON;
- ds.responseSchema = {
- resultsList: "suggestions",
- fields: ["name"],
- };
- var ac = new YAHOO.widget.AutoComplete(
- "search-box",
- "search-box-completion",
- ds,
- );
- ac.typeAhead = false;
- ac.autoHighlight = false;
- ac.formatResult = ac.formatEscapedResult;
- ac.maxResultsDisplayed = 25;
-
- var box = document.getElementById("search-box");
- var sizer = document.getElementById("search-box-sizer");
- var comp = document.getElementById("search-box-completion");
-
- Behaviour.addLoadEvent(function () {
- // copy font style of box to sizer
- var ds = sizer.style;
- ds.fontFamily = getStyle(box, "fontFamily");
- ds.fontSize = getStyle(box, "fontSize");
- ds.fontStyle = getStyle(box, "fontStyle");
- ds.fontWeight = getStyle(box, "fontWeight");
- });
-
- // update positions and sizes of the components relevant to search
- function updatePos() {
- sizer.innerHTML = escapeHTML(box.value);
- var cssWidth,
- offsetWidth = sizer.offsetWidth;
- if (offsetWidth > 0) {
- cssWidth = offsetWidth + "px";
- } else {
- // sizer hidden on small screen, make sure resizing looks OK
- cssWidth = getStyle(sizer, "minWidth");
- }
- box.style.width = comp.firstElementChild.style.minWidth =
- "calc(60px + " + cssWidth + ")";
-
- var pos = YAHOO.util.Dom.getXY(box);
- pos[1] += YAHOO.util.Dom.get(box).offsetHeight + 2;
- YAHOO.util.Dom.setXY(comp, pos);
- }
-
- updatePos();
- box.addEventListener("input", updatePos);
-}
-
/**
* Finds the DOM node of the given DOM node that acts as a parent in the form submission.
*
diff --git a/yarn.lock b/yarn.lock
index 1597ad34a3b7..2a4945df8592 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -15,9 +15,9 @@ __metadata:
languageName: node
linkType: hard
-"@babel/cli@npm:7.25.9":
- version: 7.25.9
- resolution: "@babel/cli@npm:7.25.9"
+"@babel/cli@npm:7.26.4":
+ version: 7.26.4
+ resolution: "@babel/cli@npm:7.26.4"
dependencies:
"@jridgewell/trace-mapping": "npm:^0.3.25"
"@nicolo-ribaudo/chokidar-2": "npm:2.1.8-no-fsevents.3"
@@ -38,7 +38,7 @@ __metadata:
bin:
babel: ./bin/babel.js
babel-external-helpers: ./bin/babel-external-helpers.js
- checksum: 10c0/2e8228c3715e220fa902888c643ce1a89c4ee90be3d9f7a31218d5bb2500456e0cef12cb90fd5877ab3e5a4498df8f27670425d346422a3eb52052fd3184d520
+ checksum: 10c0/f2d4fc3c4a34dd3001e3bd7084b78b38211003c36afaf2dc8fedf4565c0442bd59b1c64a9f91a0b7b2450e089123f197e09577ae50dc994307c3348b310ce34c
languageName: node
linkType: hard
@@ -2212,154 +2212,154 @@ __metadata:
languageName: node
linkType: hard
-"@webassemblyjs/ast@npm:1.12.1, @webassemblyjs/ast@npm:^1.12.1":
- version: 1.12.1
- resolution: "@webassemblyjs/ast@npm:1.12.1"
+"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/ast@npm:1.14.1"
dependencies:
- "@webassemblyjs/helper-numbers": "npm:1.11.6"
- "@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
- checksum: 10c0/ba7f2b96c6e67e249df6156d02c69eb5f1bd18d5005303cdc42accb053bebbbde673826e54db0437c9748e97abd218366a1d13fa46859b23cde611b6b409998c
+ "@webassemblyjs/helper-numbers": "npm:1.13.2"
+ "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
+ checksum: 10c0/67a59be8ed50ddd33fbb2e09daa5193ac215bf7f40a9371be9a0d9797a114d0d1196316d2f3943efdb923a3d809175e1563a3cb80c814fb8edccd1e77494972b
languageName: node
linkType: hard
-"@webassemblyjs/floating-point-hex-parser@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.11.6"
- checksum: 10c0/37fe26f89e18e4ca0e7d89cfe3b9f17cfa327d7daf906ae01400416dbb2e33c8a125b4dc55ad7ff405e5fcfb6cf0d764074c9bc532b9a31a71e762be57d2ea0a
+"@webassemblyjs/floating-point-hex-parser@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.13.2"
+ checksum: 10c0/0e88bdb8b50507d9938be64df0867f00396b55eba9df7d3546eb5dc0ca64d62e06f8d881ec4a6153f2127d0f4c11d102b6e7d17aec2f26bb5ff95a5e60652412
languageName: node
linkType: hard
-"@webassemblyjs/helper-api-error@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/helper-api-error@npm:1.11.6"
- checksum: 10c0/a681ed51863e4ff18cf38d223429f414894e5f7496856854d9a886eeddcee32d7c9f66290f2919c9bb6d2fc2b2fae3f989b6a1e02a81e829359738ea0c4d371a
+"@webassemblyjs/helper-api-error@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/helper-api-error@npm:1.13.2"
+ checksum: 10c0/31be497f996ed30aae4c08cac3cce50c8dcd5b29660383c0155fce1753804fc55d47fcba74e10141c7dd2899033164e117b3bcfcda23a6b043e4ded4f1003dfb
languageName: node
linkType: hard
-"@webassemblyjs/helper-buffer@npm:1.12.1":
- version: 1.12.1
- resolution: "@webassemblyjs/helper-buffer@npm:1.12.1"
- checksum: 10c0/0270724afb4601237410f7fd845ab58ccda1d5456a8783aadfb16eaaf3f2c9610c28e4a5bcb6ad880cde5183c82f7f116d5ccfc2310502439d33f14b6888b48a
+"@webassemblyjs/helper-buffer@npm:1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/helper-buffer@npm:1.14.1"
+ checksum: 10c0/0d54105dc373c0fe6287f1091e41e3a02e36cdc05e8cf8533cdc16c59ff05a646355415893449d3768cda588af451c274f13263300a251dc11a575bc4c9bd210
languageName: node
linkType: hard
-"@webassemblyjs/helper-numbers@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/helper-numbers@npm:1.11.6"
+"@webassemblyjs/helper-numbers@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/helper-numbers@npm:1.13.2"
dependencies:
- "@webassemblyjs/floating-point-hex-parser": "npm:1.11.6"
- "@webassemblyjs/helper-api-error": "npm:1.11.6"
+ "@webassemblyjs/floating-point-hex-parser": "npm:1.13.2"
+ "@webassemblyjs/helper-api-error": "npm:1.13.2"
"@xtuc/long": "npm:4.2.2"
- checksum: 10c0/c7d5afc0ff3bd748339b466d8d2f27b908208bf3ff26b2e8e72c39814479d486e0dca6f3d4d776fd9027c1efe05b5c0716c57a23041eb34473892b2731c33af3
+ checksum: 10c0/9c46852f31b234a8fb5a5a9d3f027bc542392a0d4de32f1a9c0075d5e8684aa073cb5929b56df565500b3f9cc0a2ab983b650314295b9bf208d1a1651bfc825a
languageName: node
linkType: hard
-"@webassemblyjs/helper-wasm-bytecode@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.11.6"
- checksum: 10c0/79d2bebdd11383d142745efa32781249745213af8e022651847382685ca76709f83e1d97adc5f0d3c2b8546bf02864f8b43a531fdf5ca0748cb9e4e0ef2acaa5
+"@webassemblyjs/helper-wasm-bytecode@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.13.2"
+ checksum: 10c0/c4355d14f369b30cf3cbdd3acfafc7d0488e086be6d578e3c9780bd1b512932352246be96e034e2a7fcfba4f540ec813352f312bfcbbfe5bcfbf694f82ccc682
languageName: node
linkType: hard
-"@webassemblyjs/helper-wasm-section@npm:1.12.1":
- version: 1.12.1
- resolution: "@webassemblyjs/helper-wasm-section@npm:1.12.1"
+"@webassemblyjs/helper-wasm-section@npm:1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/helper-wasm-section@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.12.1"
- "@webassemblyjs/helper-buffer": "npm:1.12.1"
- "@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
- "@webassemblyjs/wasm-gen": "npm:1.12.1"
- checksum: 10c0/0546350724d285ae3c26e6fc444be4c3b5fb824f3be0ec8ceb474179dc3f4430336dd2e36a44b3e3a1a6815960e5eec98cd9b3a8ec66dc53d86daedd3296a6a2
+ "@webassemblyjs/ast": "npm:1.14.1"
+ "@webassemblyjs/helper-buffer": "npm:1.14.1"
+ "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
+ "@webassemblyjs/wasm-gen": "npm:1.14.1"
+ checksum: 10c0/1f9b33731c3c6dbac3a9c483269562fa00d1b6a4e7133217f40e83e975e636fd0f8736e53abd9a47b06b66082ecc976c7384391ab0a68e12d509ea4e4b948d64
languageName: node
linkType: hard
-"@webassemblyjs/ieee754@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/ieee754@npm:1.11.6"
+"@webassemblyjs/ieee754@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/ieee754@npm:1.13.2"
dependencies:
"@xtuc/ieee754": "npm:^1.2.0"
- checksum: 10c0/59de0365da450322c958deadade5ec2d300c70f75e17ae55de3c9ce564deff5b429e757d107c7ec69bd0ba169c6b6cc2ff66293ab7264a7053c829b50ffa732f
+ checksum: 10c0/2e732ca78c6fbae3c9b112f4915d85caecdab285c0b337954b180460290ccd0fb00d2b1dc4bb69df3504abead5191e0d28d0d17dfd6c9d2f30acac8c4961c8a7
languageName: node
linkType: hard
-"@webassemblyjs/leb128@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/leb128@npm:1.11.6"
+"@webassemblyjs/leb128@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/leb128@npm:1.13.2"
dependencies:
"@xtuc/long": "npm:4.2.2"
- checksum: 10c0/cb344fc04f1968209804de4da018679c5d4708a03b472a33e0fa75657bb024978f570d3ccf9263b7f341f77ecaa75d0e051b9cd4b7bb17a339032cfd1c37f96e
+ checksum: 10c0/dad5ef9e383c8ab523ce432dfd80098384bf01c45f70eb179d594f85ce5db2f80fa8c9cba03adafd85684e6d6310f0d3969a882538975989919329ac4c984659
languageName: node
linkType: hard
-"@webassemblyjs/utf8@npm:1.11.6":
- version: 1.11.6
- resolution: "@webassemblyjs/utf8@npm:1.11.6"
- checksum: 10c0/14d6c24751a89ad9d801180b0d770f30a853c39f035a15fbc96266d6ac46355227abd27a3fd2eeaa97b4294ced2440a6b012750ae17bafe1a7633029a87b6bee
+"@webassemblyjs/utf8@npm:1.13.2":
+ version: 1.13.2
+ resolution: "@webassemblyjs/utf8@npm:1.13.2"
+ checksum: 10c0/d3fac9130b0e3e5a1a7f2886124a278e9323827c87a2b971e6d0da22a2ba1278ac9f66a4f2e363ecd9fac8da42e6941b22df061a119e5c0335f81006de9ee799
languageName: node
linkType: hard
-"@webassemblyjs/wasm-edit@npm:^1.12.1":
- version: 1.12.1
- resolution: "@webassemblyjs/wasm-edit@npm:1.12.1"
+"@webassemblyjs/wasm-edit@npm:^1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/wasm-edit@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.12.1"
- "@webassemblyjs/helper-buffer": "npm:1.12.1"
- "@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
- "@webassemblyjs/helper-wasm-section": "npm:1.12.1"
- "@webassemblyjs/wasm-gen": "npm:1.12.1"
- "@webassemblyjs/wasm-opt": "npm:1.12.1"
- "@webassemblyjs/wasm-parser": "npm:1.12.1"
- "@webassemblyjs/wast-printer": "npm:1.12.1"
- checksum: 10c0/972f5e6c522890743999e0ed45260aae728098801c6128856b310dd21f1ee63435fc7b518e30e0ba1cdafd0d1e38275829c1e4451c3536a1d9e726e07a5bba0b
+ "@webassemblyjs/ast": "npm:1.14.1"
+ "@webassemblyjs/helper-buffer": "npm:1.14.1"
+ "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
+ "@webassemblyjs/helper-wasm-section": "npm:1.14.1"
+ "@webassemblyjs/wasm-gen": "npm:1.14.1"
+ "@webassemblyjs/wasm-opt": "npm:1.14.1"
+ "@webassemblyjs/wasm-parser": "npm:1.14.1"
+ "@webassemblyjs/wast-printer": "npm:1.14.1"
+ checksum: 10c0/5ac4781086a2ca4b320bdbfd965a209655fe8a208ca38d89197148f8597e587c9a2c94fb6bd6f1a7dbd4527c49c6844fcdc2af981f8d793a97bf63a016aa86d2
languageName: node
linkType: hard
-"@webassemblyjs/wasm-gen@npm:1.12.1":
- version: 1.12.1
- resolution: "@webassemblyjs/wasm-gen@npm:1.12.1"
+"@webassemblyjs/wasm-gen@npm:1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/wasm-gen@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.12.1"
- "@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
- "@webassemblyjs/ieee754": "npm:1.11.6"
- "@webassemblyjs/leb128": "npm:1.11.6"
- "@webassemblyjs/utf8": "npm:1.11.6"
- checksum: 10c0/1e257288177af9fa34c69cab94f4d9036ebed611f77f3897c988874e75182eeeec759c79b89a7a49dd24624fc2d3d48d5580b62b67c4a1c9bfbdcd266b281c16
+ "@webassemblyjs/ast": "npm:1.14.1"
+ "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
+ "@webassemblyjs/ieee754": "npm:1.13.2"
+ "@webassemblyjs/leb128": "npm:1.13.2"
+ "@webassemblyjs/utf8": "npm:1.13.2"
+ checksum: 10c0/d678810d7f3f8fecb2e2bdadfb9afad2ec1d2bc79f59e4711ab49c81cec578371e22732d4966f59067abe5fba8e9c54923b57060a729d28d408e608beef67b10
languageName: node
linkType: hard
-"@webassemblyjs/wasm-opt@npm:1.12.1":
- version: 1.12.1
- resolution: "@webassemblyjs/wasm-opt@npm:1.12.1"
+"@webassemblyjs/wasm-opt@npm:1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/wasm-opt@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.12.1"
- "@webassemblyjs/helper-buffer": "npm:1.12.1"
- "@webassemblyjs/wasm-gen": "npm:1.12.1"
- "@webassemblyjs/wasm-parser": "npm:1.12.1"
- checksum: 10c0/992a45e1f1871033c36987459436ab4e6430642ca49328e6e32a13de9106fe69ae6c0ac27d7050efd76851e502d11cd1ac0e06b55655dfa889ad82f11a2712fb
+ "@webassemblyjs/ast": "npm:1.14.1"
+ "@webassemblyjs/helper-buffer": "npm:1.14.1"
+ "@webassemblyjs/wasm-gen": "npm:1.14.1"
+ "@webassemblyjs/wasm-parser": "npm:1.14.1"
+ checksum: 10c0/515bfb15277ee99ba6b11d2232ddbf22aed32aad6d0956fe8a0a0a004a1b5a3a277a71d9a3a38365d0538ac40d1b7b7243b1a244ad6cd6dece1c1bb2eb5de7ee
languageName: node
linkType: hard
-"@webassemblyjs/wasm-parser@npm:1.12.1, @webassemblyjs/wasm-parser@npm:^1.12.1":
- version: 1.12.1
- resolution: "@webassemblyjs/wasm-parser@npm:1.12.1"
+"@webassemblyjs/wasm-parser@npm:1.14.1, @webassemblyjs/wasm-parser@npm:^1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/wasm-parser@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.12.1"
- "@webassemblyjs/helper-api-error": "npm:1.11.6"
- "@webassemblyjs/helper-wasm-bytecode": "npm:1.11.6"
- "@webassemblyjs/ieee754": "npm:1.11.6"
- "@webassemblyjs/leb128": "npm:1.11.6"
- "@webassemblyjs/utf8": "npm:1.11.6"
- checksum: 10c0/e85cec1acad07e5eb65b92d37c8e6ca09c6ca50d7ca58803a1532b452c7321050a0328c49810c337cc2dfd100c5326a54d5ebd1aa5c339ebe6ef10c250323a0e
+ "@webassemblyjs/ast": "npm:1.14.1"
+ "@webassemblyjs/helper-api-error": "npm:1.13.2"
+ "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2"
+ "@webassemblyjs/ieee754": "npm:1.13.2"
+ "@webassemblyjs/leb128": "npm:1.13.2"
+ "@webassemblyjs/utf8": "npm:1.13.2"
+ checksum: 10c0/95427b9e5addbd0f647939bd28e3e06b8deefdbdadcf892385b5edc70091bf9b92fa5faac3fce8333554437c5d85835afef8c8a7d9d27ab6ba01ffab954db8c6
languageName: node
linkType: hard
-"@webassemblyjs/wast-printer@npm:1.12.1":
- version: 1.12.1
- resolution: "@webassemblyjs/wast-printer@npm:1.12.1"
+"@webassemblyjs/wast-printer@npm:1.14.1":
+ version: 1.14.1
+ resolution: "@webassemblyjs/wast-printer@npm:1.14.1"
dependencies:
- "@webassemblyjs/ast": "npm:1.12.1"
+ "@webassemblyjs/ast": "npm:1.14.1"
"@xtuc/long": "npm:4.2.2"
- checksum: 10c0/39bf746eb7a79aa69953f194943bbc43bebae98bd7cadd4d8bc8c0df470ca6bf9d2b789effaa180e900fab4e2691983c1f7d41571458bd2a26267f2f0c73705a
+ checksum: 10c0/8d7768608996a052545251e896eac079c98e0401842af8dd4de78fba8d90bd505efb6c537e909cd6dae96e09db3fa2e765a6f26492553a675da56e2db51f9d24
languageName: node
linkType: hard
@@ -3961,10 +3961,10 @@ __metadata:
languageName: node
linkType: hard
-"globals@npm:15.12.0":
- version: 15.12.0
- resolution: "globals@npm:15.12.0"
- checksum: 10c0/f34e0a1845b694f45188331742af9f488b07ba7440a06e9d2039fce0386fbbfc24afdbb9846ebdccd4092d03644e43081c49eb27b30f4b88e43af156e1c1dc34
+"globals@npm:15.13.0":
+ version: 15.13.0
+ resolution: "globals@npm:15.13.0"
+ checksum: 10c0/640365115ca5f81d91e6a7667f4935021705e61a1a5a76a6ec5c3a5cdf6e53f165af7f9db59b7deb65cf2e1f83d03ac8d6660d0b14c569c831a9b6483eeef585
languageName: node
linkType: hard
@@ -4369,7 +4369,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "jenkins-ui@workspace:."
dependencies:
- "@babel/cli": "npm:7.25.9"
+ "@babel/cli": "npm:7.26.4"
"@babel/core": "npm:7.26.0"
"@babel/preset-env": "npm:7.26.0"
"@eslint/js": "npm:9.16.0"
@@ -4380,7 +4380,7 @@ __metadata:
eslint: "npm:9.16.0"
eslint-config-prettier: "npm:9.1.0"
eslint-formatter-checkstyle: "npm:8.40.0"
- globals: "npm:15.12.0"
+ globals: "npm:15.13.0"
handlebars: "npm:4.7.8"
handlebars-loader: "npm:1.7.3"
hotkeys-js: "npm:3.12.2"
@@ -4391,16 +4391,16 @@ __metadata:
postcss-loader: "npm:8.1.1"
postcss-preset-env: "npm:10.1.1"
postcss-scss: "npm:4.0.9"
- prettier: "npm:3.4.1"
- sass: "npm:1.81.0"
- sass-loader: "npm:16.0.3"
+ prettier: "npm:3.4.2"
+ sass: "npm:1.82.0"
+ sass-loader: "npm:16.0.4"
sortablejs: "npm:1.15.6"
style-loader: "npm:4.0.0"
stylelint: "npm:16.11.0"
stylelint-checkstyle-reporter: "npm:1.0.0"
stylelint-config-standard: "npm:36.0.1"
tippy.js: "npm:6.3.7"
- webpack: "npm:5.96.1"
+ webpack: "npm:5.97.1"
webpack-cli: "npm:5.1.4"
webpack-remove-empty-scripts: "npm:1.0.4"
window-handle: "npm:1.0.1"
@@ -6113,12 +6113,12 @@ __metadata:
languageName: node
linkType: hard
-"prettier@npm:3.4.1":
- version: 3.4.1
- resolution: "prettier@npm:3.4.1"
+"prettier@npm:3.4.2":
+ version: 3.4.2
+ resolution: "prettier@npm:3.4.2"
bin:
prettier: bin/prettier.cjs
- checksum: 10c0/2d6cc3101ad9de72b49c59339480b0983e6ff6742143da0c43f476bf3b5ef88ede42ebd9956d7a0a8fa59f7a5990e8ef03c9ad4c37f7e4c9e5db43ee0853156c
+ checksum: 10c0/99e076a26ed0aba4ebc043880d0f08bbb8c59a4c6641cdee6cdadf2205bdd87aa1d7823f50c3aea41e015e99878d37c58d7b5f0e663bba0ef047f94e36b96446
languageName: node
linkType: hard
@@ -6355,9 +6355,9 @@ __metadata:
languageName: node
linkType: hard
-"sass-loader@npm:16.0.3":
- version: 16.0.3
- resolution: "sass-loader@npm:16.0.3"
+"sass-loader@npm:16.0.4":
+ version: 16.0.4
+ resolution: "sass-loader@npm:16.0.4"
dependencies:
neo-async: "npm:^2.6.2"
peerDependencies:
@@ -6377,13 +6377,13 @@ __metadata:
optional: true
webpack:
optional: true
- checksum: 10c0/2dc188dd0d5276ed0251eee7f245848ccf9df6ec121227462403f322c17a3dbe100fb60d47968f078e585e4aced452eb7fa1a8e55b415d5de3151fa1bbf2d561
+ checksum: 10c0/d57c5fa35620e9022cfa3e5d49f3f9b3e54fb8b2fa9d021c10fe26c8c2f77103e038b6540eb20123a6f73aef23d2beb04033d3b7772588ca3f3c0ba2a4ee40ac
languageName: node
linkType: hard
-"sass@npm:1.81.0":
- version: 1.81.0
- resolution: "sass@npm:1.81.0"
+"sass@npm:1.82.0":
+ version: 1.82.0
+ resolution: "sass@npm:1.82.0"
dependencies:
"@parcel/watcher": "npm:^2.4.1"
chokidar: "npm:^4.0.0"
@@ -6394,7 +6394,7 @@ __metadata:
optional: true
bin:
sass: sass.js
- checksum: 10c0/9c59b3c9b4231c18fcb4583cc232dbc4de501ddc11101b7a025e44833e3f3ce6031546dc1cd109ee9f04ebcfb1fe30ff870810af33b8feb9aa9e36dfba9ec1ef
+ checksum: 10c0/7f86fe6ade4f6018862c448ed69d5c52f485b0125c9dab24e63f679739a04cc7c56562d588e3cf16b5efb4d2c4d0530e62740e1cfd273e2e3707d04d11011736
languageName: node
linkType: hard
@@ -7066,15 +7066,15 @@ __metadata:
languageName: node
linkType: hard
-"webpack@npm:5.96.1":
- version: 5.96.1
- resolution: "webpack@npm:5.96.1"
+"webpack@npm:5.97.1":
+ version: 5.97.1
+ resolution: "webpack@npm:5.97.1"
dependencies:
"@types/eslint-scope": "npm:^3.7.7"
"@types/estree": "npm:^1.0.6"
- "@webassemblyjs/ast": "npm:^1.12.1"
- "@webassemblyjs/wasm-edit": "npm:^1.12.1"
- "@webassemblyjs/wasm-parser": "npm:^1.12.1"
+ "@webassemblyjs/ast": "npm:^1.14.1"
+ "@webassemblyjs/wasm-edit": "npm:^1.14.1"
+ "@webassemblyjs/wasm-parser": "npm:^1.14.1"
acorn: "npm:^8.14.0"
browserslist: "npm:^4.24.0"
chrome-trace-event: "npm:^1.0.2"
@@ -7098,7 +7098,7 @@ __metadata:
optional: true
bin:
webpack: bin/webpack.js
- checksum: 10c0/ae6052fde9a546f79f14987b65823ba4024c6642a8489339ecfee7a351dff93325842aad453295bbdc6b65fb1690e4ef07529db63aa84ece55c7869e991a0039
+ checksum: 10c0/a12d3dc882ca582075f2c4bd88840be8307427245c90a8a0e0b372d73560df13fcf25a61625c9e7edc964981d16b5a8323640562eb48347cf9dd2f8bd1b39d35
languageName: node
linkType: hard