diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java index c2b048b54e0..589abbda561 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1882,7 +1882,7 @@ public abstract class HtmlDocletWriter { String tagText = headingContent.replaceAll("\\s+", " "); IndexItem item = IndexItem.of(element, node, tagText, getTagletWriterInstance(context).getHolderName(element), - resources.getText("doclet.Section"), + "", new DocLink(path, id)); configuration.indexBuilder.add(item); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java index 87d0fa95bf3..14cf7f2daea 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -200,9 +200,6 @@ public class IndexWriter extends HtmlDocletWriter { case PACKAGE -> { dt = HtmlTree.DT(getPackageLink((PackageElement) element, Text.of(label))); - if (configuration.showModules) { - item.setContainingModule(utils.getFullyQualifiedName(utils.containingModule(element))); - } dt.add(" - ").add(contents.package_).add(" " + label); } @@ -259,7 +256,14 @@ public class IndexWriter extends HtmlDocletWriter { var labelLink = HtmlTree.A(itemPath, Text.of(item.getLabel())); var dt = HtmlTree.DT(labelLink.setStyle(HtmlStyles.searchTagLink)); dt.add(" - "); - dt.add(contents.getContent("doclet.Search_tag_in", item.getHolder())); + var tagKindKey = switch (item.getKind()) { + case SEARCH_ITEM -> "doclet.Search_tag_in"; + case SYSTEM_PROPERTY -> "doclet.System_property_in"; + case SECTION -> "doclet.Section_in"; + case EXTERNAL_SPEC -> "doclet.External_specification_in"; + default -> throw new Error(); + }; + dt.add(contents.getContent(tagKindKey, item.getHolder())); target.add(dt); var dd = HtmlTree.DD(); if (item.getDescription().isEmpty()) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchWriter.java index 673bd35049f..7d97dd71865 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SearchWriter.java @@ -39,6 +39,8 @@ import jdk.javadoc.internal.html.HtmlTag; import jdk.javadoc.internal.html.HtmlTree; import jdk.javadoc.internal.html.Text; +import javax.lang.model.element.ModuleElement; + /** * Generates the search landing page for the generated API documentation. */ @@ -70,16 +72,8 @@ public class SearchWriter extends HtmlDocletWriter { */ protected void addSearchFileContents(Content contentTree) { - String copyText = resources.getText("doclet.Copy_to_clipboard"); - String copiedText = resources.getText("doclet.Copied_to_clipboard"); - String copyUrlText = resources.getText("doclet.Copy_url_to_clipboard"); - Content helpSection = Text.EMPTY; - // Suppress link to help page if no help page is generated or a custom help page is used. - HtmlOptions options = configuration.getOptions(); - if (!options.noHelp() && options.helpFile().isEmpty()) { - Content helpLink = HtmlTree.A("help-doc.html#search", contents.getContent("doclet.search.help_page_link")); - helpSection = HtmlTree.P(contents.getContent("doclet.search.help_page_info", helpLink)); - } + var moduleSelector = createModuleSelector(); + var resourceSection = createResourceSection(); contentTree.add(HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, HtmlStyles.title, contents.getContent("doclet.search.main_heading"))) @@ -89,31 +83,13 @@ public class SearchWriter extends HtmlDocletWriter { .put(HtmlAttr.AUTOCOMPLETE, "off") .put(HtmlAttr.SPELLCHECK, "false")) .add(HtmlTree.INPUT(HtmlAttr.InputType.RESET, HtmlId.of("page-search-reset")) - .put(HtmlAttr.VALUE, resources.getText("doclet.search_reset")) - .put(HtmlAttr.STYLE, "margin: 6px;")) + .put(HtmlAttr.TABINDEX, "-1") + .put(HtmlAttr.VALUE, resources.getText("doclet.search_reset"))) + .add(moduleSelector) .add(HtmlTree.DETAILS(HtmlStyles.pageSearchDetails) .add(HtmlTree.SUMMARY(contents.getContent("doclet.search.show_more")) .setId(HtmlId.of("page-search-expand"))))) - .add(HtmlTree.DIV(HtmlStyles.pageSearchInfo, helpSection) - .add(HtmlTree.P(contents.getContent("doclet.search.keyboard_info", - HtmlTree.KBD(Text.of("Ctrl")), HtmlTree.KBD(Text.of("Cmd")), - new ContentBuilder(HtmlTree.KBD(Entity.of("leftarrow")), Text.of("/"), - HtmlTree.KBD(Entity.of("rightarrow")))))) - .add(HtmlTree.P(contents.getContent("doclet.search.browser_info"))) - .add(HtmlTree.SPAN(Text.of("link")) - .setId(HtmlId.of("page-search-link"))) - .add(HtmlTree.BUTTON(HtmlId.of("page-search-copy")) - .add(HtmlTree.of(HtmlTag.IMG) - .put(HtmlAttr.SRC, pathToRoot.resolve(DocPaths.RESOURCE_FILES) - .resolve(DocPaths.CLIPBOARD_SVG).getPath()) - .put(HtmlAttr.ALT, copyUrlText)) - .add(HtmlTree.SPAN(Text.of(copyText)) - .put(HtmlAttr.DATA_COPIED, copiedText)) - .addStyle(HtmlStyles.copy) - .put(HtmlAttr.ARIA_LABEL, copyUrlText)) - .add(HtmlTree.P(HtmlTree.INPUT(HtmlAttr.InputType.CHECKBOX, HtmlId.of("search-redirect"))) - .add(HtmlTree.LABEL("search-redirect", - contents.getContent("doclet.search.redirect"))))) + .add(resourceSection) .add(HtmlTree.P(contents.getContent("doclet.search.loading")) .setId(HtmlId.of("page-search-notify"))) .add(HtmlTree.DIV(HtmlTree.DIV(HtmlId.of("result-container")) @@ -123,4 +99,61 @@ public class SearchWriter extends HtmlDocletWriter { .add(HtmlTree.SCRIPT(pathToRoot.resolve(DocPaths.SCRIPT_FILES) .resolve(DocPaths.SEARCH_PAGE_JS).getPath()))); } + + private Content createModuleSelector() { + + if (!configuration.showModules) { + return Text.EMPTY; + } + + var select = HtmlTree.of(HtmlTag.SELECT) + .setId(HtmlId.of("search-modules")) + .add(HtmlTree.of(HtmlTag.OPTION) + .put(HtmlAttr.VALUE, "") + .add(contents.getContent("doclet.search.all_modules"))); + + for (ModuleElement module : configuration.modules) { + select.add(HtmlTree.of(HtmlTag.OPTION) + .put(HtmlAttr.VALUE, module.getQualifiedName().toString()) + .add(Text.of(module.getQualifiedName().toString()))); + } + return new ContentBuilder(contents.getContent("doclet.search.in", select)); + } + + private Content createResourceSection() { + + String copyText = resources.getText("doclet.Copy_to_clipboard"); + String copiedText = resources.getText("doclet.Copied_to_clipboard"); + String copyUrlText = resources.getText("doclet.Copy_url_to_clipboard"); + Content helpSection = Text.EMPTY; + + // Suppress link to help page if no help page is generated or a custom help page is used. + HtmlOptions options = configuration.getOptions(); + if (!options.noHelp() && options.helpFile().isEmpty()) { + Content helpLink = HtmlTree.A("help-doc.html#search", contents.getContent("doclet.search.help_page_link")); + helpSection = HtmlTree.P(contents.getContent("doclet.search.help_page_info", helpLink)); + } + + return HtmlTree.DIV(HtmlStyles.pageSearchInfo, helpSection) + .add(HtmlTree.P(contents.getContent("doclet.search.keyboard_info", + HtmlTree.KBD(Entity.of("downarrow")), HtmlTree.KBD(Entity.of("uparrow")), + new ContentBuilder(HtmlTree.KBD(Entity.of("leftarrow")), Text.of("/"), + HtmlTree.KBD(Entity.of("rightarrow")))))) + .add(HtmlTree.P(contents.getContent("doclet.search.browser_info"))) + .add(HtmlTree.SPAN(Text.of("link")) + .setId(HtmlId.of("page-search-link"))) + .add(HtmlTree.BUTTON(HtmlId.of("page-search-copy")) + .add(HtmlTree.of(HtmlTag.IMG) + .put(HtmlAttr.SRC, pathToRoot.resolve(DocPaths.RESOURCE_FILES) + .resolve(DocPaths.CLIPBOARD_SVG).getPath()) + .put(HtmlAttr.ALT, copyUrlText)) + .add(HtmlTree.SPAN(Text.of(copyText)) + .put(HtmlAttr.DATA_COPIED, copiedText)) + .addStyle(HtmlStyles.copy) + .put(HtmlAttr.ARIA_LABEL, copyUrlText)) + .add(HtmlTree.P(HtmlTree.INPUT(HtmlAttr.InputType.CHECKBOX, HtmlId.of("search-redirect"))) + .add(HtmlTree.LABEL("search-redirect", + contents.getContent("doclet.search.redirect")))); + } + } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search-page.js b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search-page.js index dbfb00a1a1a..ec0d815eea4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search-page.js +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search-page.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ @@ -24,32 +24,35 @@ $(function() { copyToClipboard(this.previousSibling.innerText); switchCopyLabel(this, this.lastElementChild); } - copy.click(copyLink); + copy.on("click", copyLink); copy[0].onmouseenter = function() {}; - redirect.click(setSearchUrlTemplate); + redirect.on("click", setSearchUrlTemplate); setSearchUrlTemplate(); copy.prop("disabled", false); redirect.prop("disabled", false); - expand.click(function (e) { + expand.on("click", function (e) { var searchInfo = $("div.page-search-info"); if(this.parentElement.hasAttribute("open")) { - searchInfo.attr("style", "border-width: 0;"); + searchInfo.attr("style", " display:none;"); } else { - searchInfo.attr("style", "border-width: 1px;").height(searchInfo.prop("scrollHeight")); + searchInfo.attr("style", "display:block;"); } }); }); $(window).on("load", function() { var input = $("#page-search-input"); var reset = $("#page-search-reset"); + var modules = $("#search-modules"); var notify = $("#page-search-notify"); var resultSection = $("div#result-section"); var resultContainer = $("div#result-container"); + var selectedLink; var searchTerm = ""; var activeTab = ""; var fixedTab = false; var visibleTabs = []; var feelingLucky = false; + const MIN_TABBED_RESULTS = 10; function renderResults(result) { if (!result.length) { notify.html(messages.noResult); @@ -71,14 +74,8 @@ $(window).on("load", function() { var arr = r[item.category]; arr.push(item); } - if (!activeTab || r[activeTab].length === 0 || !fixedTab) { - Object.keys(r).reduce(function(prev, curr) { - if (r[curr].length > 0 && r[curr][0].score > prev) { - activeTab = curr; - return r[curr][0].score; - } - return prev; - }, 0); + if (!activeTab || r[activeTab].length === 0) { + activeTab = Object.keys(r).find(category => r[category].length > 0); } if (feelingLucky && activeTab) { notify.html(messages.redirecting) @@ -86,13 +83,11 @@ $(window).on("load", function() { window.location = getURL(firstItem.indexItem, firstItem.category); return; } - if (result.length > 20) { - if (searchTerm[searchTerm.length - 1] === ".") { - if (activeTab === "types" && r["members"].length > r["types"].length) { - activeTab = "members"; - } else if (activeTab === "packages" && r["types"].length > r["packages"].length) { - activeTab = "types"; - } + if (searchTerm.endsWith(".") && result.length > MIN_TABBED_RESULTS) { + if (activeTab === "types" && r["members"].length > r["types"].length) { + activeTab = "members"; + } else if (activeTab === "packages" && r["types"].length > r["packages"].length) { + activeTab = "types"; } } var categoryCount = Object.keys(r).reduce(function(prev, curr) { @@ -104,87 +99,94 @@ $(window).on("load", function() { var id = "#result-tab-" + key.replace("searchTags", "search_tags"); if (r[key].length) { var count = r[key].length >= 1000 ? "999+" : r[key].length; - if (result.length > 20 && categoryCount > 1) { - var button = $("").appendTo(tabContainer); - button.click(key, function(e) { - fixedTab = true; - renderResult(e.data, $(this)); - }); + if (result.length > MIN_TABBED_RESULTS && categoryCount > 1) { + let button = $("