diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Contents.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Contents.java index f098a8dc8f3..5edcf4f839f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Contents.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Contents.java @@ -172,6 +172,7 @@ public class Contents { public final Content relatedPackages; public final Content returns; public final Content searchLabel; + public final Content searchTagsLabel; public final Content seeAlso; public final Content serializedForm; public final Content servicesLabel; @@ -325,6 +326,7 @@ public class Contents { relatedPackages = getContent("doclet.Related_Packages"); returns = getContent("doclet.Returns"); searchLabel = getContent("doclet.search"); + searchTagsLabel = getContent("doclet.searchTags"); seeAlso = getContent("doclet.See_Also"); serializedForm = getContent("doclet.Serialized_Form"); servicesLabel = getContent("doclet.Services"); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java index 1687f891896..a103ffb70fb 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java @@ -183,7 +183,7 @@ public class HelpWriter extends HtmlDocletWriter { *
  • Declaration pages: module, package, classes *
  • Derived info for declarations: use and tree *
  • General summary info: deprecated, preview - *
  • Detailed summary info: constant values, serialized form, system properties + *
  • Detailed summary info: constant values, search tags, serialized form, system properties *
  • Index info: all packages, all classes, full index * * @@ -346,6 +346,15 @@ public class HelpWriter extends HtmlDocletWriter { pageKindsSection.add(section); } + // Search Tags + if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.SEARCH_TAGS)) { + section = newHelpSection(contents.searchTagsLabel, PageMode.SEARCH_TAGS); + Content searchTagsBody = getContent("doclet.help.searchTags.body", + links.createLink(DocPaths.SEARCH_TAGS, resources.getText("doclet.searchTags"))); + section.add(HtmlTree.P(searchTagsBody)); + pageKindsSection.add(section); + } + // Serialized Form if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.SERIALIZED_FORM)) { section = newHelpSection(contents.serializedForm, PageMode.SERIALIZED_FORM) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java index 649687e19a2..ca20d065a1e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java @@ -177,7 +177,7 @@ public class HtmlConfiguration extends BaseConfiguration { // which performs a somewhat similar role public enum ConditionalPage { CONSTANT_VALUES, DEPRECATED, EXTERNAL_SPECS, PREVIEW, RESTRICTED, - SERIALIZED_FORM, SYSTEM_PROPERTIES, NEW + SEARCH_TAGS, SERIALIZED_FORM, SYSTEM_PROPERTIES, NEW } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java index 17867e368bf..193e1f3a129 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java @@ -283,6 +283,7 @@ public class HtmlDoclet extends AbstractDoclet { if (!options.noExternalSpecsPage()){ writerFactory.newExternalSpecsWriter().buildPage(); } + writerFactory.newSearchTagsWriter().buildPage(); writerFactory.newSystemPropertiesWriter().buildPage(); configuration.indexBuilder.addElements(); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexItemListWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexItemListWriter.java new file mode 100644 index 00000000000..2a581a09c62 --- /dev/null +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexItemListWriter.java @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2019, 2024, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.javadoc.internal.doclets.formats.html; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; +import java.util.WeakHashMap; +import java.util.stream.Collectors; + +import com.sun.source.doctree.DocTree; + +import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode; +import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; +import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyles; +import jdk.javadoc.internal.doclets.toolkit.DocFileElement; +import jdk.javadoc.internal.doclets.toolkit.OverviewElement; +import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; +import jdk.javadoc.internal.doclets.toolkit.util.DocPath; +import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; +import jdk.javadoc.internal.doclets.toolkit.util.IndexItem; +import jdk.javadoc.internal.html.Content; +import jdk.javadoc.internal.html.ContentBuilder; +import jdk.javadoc.internal.html.HtmlTree; +import jdk.javadoc.internal.html.Text; + +import static java.util.stream.Collectors.groupingBy; + +/** + * Generates summary files for tags represented by {@code IndexItem}. + * Supported items are search tags and system properties. + */ +public abstract class IndexItemListWriter extends HtmlDocletWriter { + + /** + * Cached contents of {@code ...} tags of the HTML pages. + */ + final Map titles = new WeakHashMap<>(); + + /** + * Constructs a IndexItemListWriter object. + * + * @param configuration The current configuration + * @param path the doc path of the file to write + */ + protected IndexItemListWriter(HtmlConfiguration configuration, DocPath path) { + super(configuration, path, false); + } + + @Override + public void buildPage() throws DocFileIOException { + boolean hasTags = configuration.indexBuilder != null + && !configuration.indexBuilder.getItems(getKind()).isEmpty(); + if (!hasTags) { + return; + } + + writeGenerating(); + configuration.conditionalPages.add(getConditionalPage()); + + String title = getPageLabel().toString(); + HtmlTree body = getBody(getWindowTitle(title)); + Content mainContent = new ContentBuilder(); + addIndexItems(mainContent); + body.add(new BodyContents() + .setHeader(getHeader(getPageMode())) + .addMainContent(HtmlTree.DIV(HtmlStyles.header, + HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, getPageLabel()))) + .addMainContent(mainContent) + .setFooter(getFooter())); + printHtmlDocument(null, title.toLowerCase(Locale.ROOT), body); + + if (configuration.indexBuilder != null) { + configuration.indexBuilder.add(IndexItem.of(IndexItem.Category.TAGS, title, path)); + } + } + + protected Map> groupTags() { + return configuration.indexBuilder.getItems(getKind()).stream() + .collect(groupingBy(IndexItem::getLabel, TreeMap::new, Collectors.toCollection(ArrayList::new))); + } + + protected Content createLink(IndexItem i) { + assert i.getDocTree().getKind() == getKind() : i; + var element = i.getElement(); + if (element instanceof OverviewElement) { + return links.createLink(pathToRoot.resolve(i.getUrl()), + resources.getText("doclet.Overview")); + } else if (element instanceof DocFileElement e) { + var fo = e.getFileObject(); + var t = titles.computeIfAbsent(e, this::getFileTitle); + if (t.isBlank()) { + // The user should probably be notified (a warning?) that this + // file does not have a title + var p = Path.of(fo.toUri()); + t = p.getFileName().toString(); + } + var b = new ContentBuilder() + .add(HtmlTree.CODE(Text.of(i.getHolder() + ": "))) + .add(t); + return links.createLink(pathToRoot.resolve(i.getUrl()), b); + } else { + // program elements should be displayed using a code font + var link = links.createLink(pathToRoot.resolve(i.getUrl()), i.getHolder()); + return HtmlTree.CODE(link); + } + } + + /** + * Adds a table with the included index items to the content. + * + * @param target the content to which the table will be added + */ + protected abstract void addIndexItems(Content target); + + /** + * {@return the kind of index item to list in this page} + */ + protected abstract DocTree.Kind getKind(); + + /** + * {@return the conditional page value} + */ + protected abstract HtmlConfiguration.ConditionalPage getConditionalPage(); + + /** + * {@return the label for the page heading} + */ + protected abstract Content getPageLabel(); + + /** + * {@return the Navigation.PageMode value} + */ + protected abstract Navigation.PageMode getPageMode(); + + // Note: The reason we can't use anonymous classes below is that HtmlDocletWriter.getBodyStyle() + // uses the writer's class name to deduce the CSS body style name. + + public static IndexItemListWriter createSystemPropertiesWriter(HtmlConfiguration configuration) { + return new SystemPropertiesWriter(configuration); + } + + public static IndexItemListWriter createSearchTagsWriter(HtmlConfiguration configuration) { + return new SearchTagsWriter(configuration); + } + + static class SystemPropertiesWriter extends IndexItemListWriter { + SystemPropertiesWriter(HtmlConfiguration configuration) { + super(configuration, DocPaths.SYSTEM_PROPERTIES); + } + + @Override + protected DocTree.Kind getKind() { + return DocTree.Kind.SYSTEM_PROPERTY; + } + + @Override + protected HtmlConfiguration.ConditionalPage getConditionalPage() { + return HtmlConfiguration.ConditionalPage.SYSTEM_PROPERTIES; + } + + @Override + protected Content getPageLabel() { + return contents.systemPropertiesLabel; + } + + @Override + protected Navigation.PageMode getPageMode() { + return PageMode.SYSTEM_PROPERTIES; + } + + /** + * Creates a 2-column table containing system properties. + * + * @param target the content to which the links will be added + */ + @Override + protected void addIndexItems(Content target) { + Map> searchIndexMap = groupTags(); + Content separator = Text.of(", "); + var table = new Table(HtmlStyles.summaryTable) + .setCaption(contents.systemPropertiesSummaryLabel) + .setHeader(new TableHeader(contents.propertyLabel, contents.referencedIn)) + .setColumnStyles(HtmlStyles.colFirst, HtmlStyles.colLast); + searchIndexMap.forEach((key, searchIndexItems) -> { + Content propertyName = Text.of(key); + Content referenceLinks = new ContentBuilder(); + for (IndexItem searchIndexItem : searchIndexItems) { + if (!referenceLinks.isEmpty()) { + referenceLinks.add(separator); + } + referenceLinks.add(createLink(searchIndexItem)); + } + table.addRow(propertyName, HtmlTree.DIV(HtmlStyles.block, referenceLinks)); + }); + target.add(table); + } + } + + static class SearchTagsWriter extends IndexItemListWriter { + SearchTagsWriter(HtmlConfiguration configuration) { + super(configuration, DocPaths.SEARCH_TAGS); + } + + @Override + protected DocTree.Kind getKind() { + return DocTree.Kind.INDEX; + } + + @Override + protected HtmlConfiguration.ConditionalPage getConditionalPage() { + return HtmlConfiguration.ConditionalPage.SEARCH_TAGS; + } + + @Override + protected Content getPageLabel() { + return contents.searchTagsLabel; + } + + @Override + protected Navigation.PageMode getPageMode() { + return PageMode.SEARCH_TAGS; + } + + /** + * Creates a 3-column table containing search tags. + * + * @param target the content to which the links will be added + */ + @Override + protected void addIndexItems(Content target) { + Map> searchIndexMap = groupTags(); + Content separator = Text.of(", "); + var table = new Table(HtmlStyles.summaryTable) + .setCaption(contents.getContent("doclet.searchTagsSummary")) + .setHeader(new TableHeader(contents.getContent("doclet.searchTag"), + contents.descriptionLabel, + contents.getContent("doclet.DefinedIn"))) + .setColumnStyles(HtmlStyles.colFirst, HtmlStyles.colSecond, HtmlStyles.colLast); + searchIndexMap.forEach((key, searchIndexItems) -> { + Content propertyName = Text.of(key); + Content referenceLinks = new ContentBuilder(); + String description = ""; + for (IndexItem searchIndexItem : searchIndexItems) { + if (!referenceLinks.isEmpty()) { + referenceLinks.add(separator); + } + referenceLinks.add(createLink(searchIndexItem)); + if (description.isEmpty()) { + description = searchIndexItem.getDescription(); + Objects.requireNonNull(description); + } + } + table.addRow(propertyName, Text.of(description), HtmlTree.DIV(HtmlStyles.block, referenceLinks)); + }); + target.add(table); + } + } +} diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java index 9d12d3bb23d..7c63a581a4f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java @@ -87,8 +87,9 @@ public class Navigation { PACKAGE, PREVIEW, RESTRICTED, - SERIALIZED_FORM, SEARCH, + SEARCH_TAGS, + SERIALIZED_FORM, SYSTEM_PROPERTIES, TREE, USE @@ -274,6 +275,7 @@ public class Navigation { case CONSTANT_VALUES: case EXTERNAL_SPECS: case RESTRICTED: + case SEARCH_TAGS: case SERIALIZED_FORM: case SYSTEM_PROPERTIES: addOverviewLink(target); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SystemPropertiesWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SystemPropertiesWriter.java deleted file mode 100644 index d7aacd3ab0f..00000000000 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SystemPropertiesWriter.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2019, 2024, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.javadoc.internal.doclets.formats.html; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; -import java.util.WeakHashMap; -import java.util.stream.Collectors; - -import com.sun.source.doctree.DocTree; - -import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode; -import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; -import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyles; -import jdk.javadoc.internal.doclets.toolkit.DocFileElement; -import jdk.javadoc.internal.doclets.toolkit.OverviewElement; -import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; -import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; -import jdk.javadoc.internal.doclets.toolkit.util.IndexItem; -import jdk.javadoc.internal.html.Content; -import jdk.javadoc.internal.html.ContentBuilder; -import jdk.javadoc.internal.html.HtmlTree; -import jdk.javadoc.internal.html.Text; - -import static java.util.stream.Collectors.groupingBy; - -/** - * Generates the file with the summary of all the system properties. - */ -public class SystemPropertiesWriter extends HtmlDocletWriter { - - /** - * Cached contents of {@code ...} tags of the HTML pages. - */ - final Map titles = new WeakHashMap<>(); - - /** - * Constructs SystemPropertiesWriter object. - * - * @param configuration The current configuration - */ - public SystemPropertiesWriter(HtmlConfiguration configuration) { - super(configuration, DocPaths.SYSTEM_PROPERTIES, false); - } - - @Override - public void buildPage() throws DocFileIOException { - boolean hasSystemProperties = configuration.indexBuilder != null - && !configuration.indexBuilder.getItems(DocTree.Kind.SYSTEM_PROPERTY).isEmpty(); - if (!hasSystemProperties) { - return; - } - - writeGenerating(); - configuration.conditionalPages.add(HtmlConfiguration.ConditionalPage.SYSTEM_PROPERTIES); - - String title = resources.getText("doclet.systemProperties"); - HtmlTree body = getBody(getWindowTitle(title)); - Content mainContent = new ContentBuilder(); - addSystemProperties(mainContent); - body.add(new BodyContents() - .setHeader(getHeader(PageMode.SYSTEM_PROPERTIES)) - .addMainContent(HtmlTree.DIV(HtmlStyles.header, - HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, - contents.getContent("doclet.systemProperties")))) - .addMainContent(mainContent) - .setFooter(getFooter())); - printHtmlDocument(null, "system properties", body); - - if (configuration.indexBuilder != null) { - configuration.indexBuilder.add(IndexItem.of(IndexItem.Category.TAGS, title, path)); - } - } - - /** - * Adds all the system properties to the content. - * - * @param target the content to which the links will be added - */ - protected void addSystemProperties(Content target) { - Map> searchIndexMap = groupSystemProperties(); - Content separator = Text.of(", "); - var table = new Table(HtmlStyles.summaryTable) - .setCaption(contents.systemPropertiesSummaryLabel) - .setHeader(new TableHeader(contents.propertyLabel, contents.referencedIn)) - .setColumnStyles(HtmlStyles.colFirst, HtmlStyles.colLast); - for (Entry> entry : searchIndexMap.entrySet()) { - Content propertyName = Text.of(entry.getKey()); - List searchIndexItems = entry.getValue(); - Content separatedReferenceLinks = new ContentBuilder(); - separatedReferenceLinks.add(createLink(searchIndexItems.get(0))); - for (int i = 1; i < searchIndexItems.size(); i++) { - separatedReferenceLinks.add(separator); - separatedReferenceLinks.add(createLink(searchIndexItems.get(i))); - } - table.addRow(propertyName, HtmlTree.DIV(HtmlStyles.block, separatedReferenceLinks)); - } - target.add(table); - } - - private Map> groupSystemProperties() { - return configuration.indexBuilder.getItems(DocTree.Kind.SYSTEM_PROPERTY).stream() - .collect(groupingBy(IndexItem::getLabel, TreeMap::new, Collectors.toCollection(ArrayList::new))); - } - - private Content createLink(IndexItem i) { - assert i.getDocTree().getKind() == DocTree.Kind.SYSTEM_PROPERTY : i; - var element = i.getElement(); - if (element instanceof OverviewElement) { - return links.createLink(pathToRoot.resolve(i.getUrl()), - resources.getText("doclet.Overview")); - } else if (element instanceof DocFileElement e) { - var fo = e.getFileObject(); - var t = titles.computeIfAbsent(e, this::getFileTitle); - if (t.isBlank()) { - // The user should probably be notified (a warning?) that this - // file does not have a title - var p = Path.of(fo.toUri()); - t = p.getFileName().toString(); - } - var b = new ContentBuilder() - .add(HtmlTree.CODE(Text.of(i.getHolder() + ": "))) - .add(t); - return links.createLink(pathToRoot.resolve(i.getUrl()), b); - } else { - // program elements should be displayed using a code font - var link = links.createLink(pathToRoot.resolve(i.getUrl()), i.getHolder()); - return HtmlTree.CODE(link); - } - } -} diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/WriterFactory.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/WriterFactory.java index 064fff0879d..d656fe35293 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/WriterFactory.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/WriterFactory.java @@ -37,7 +37,6 @@ import jdk.javadoc.internal.doclets.toolkit.DocFileElement; import jdk.javadoc.internal.doclets.toolkit.util.ClassTree; import jdk.javadoc.internal.doclets.toolkit.util.ClassUseMapper; import jdk.javadoc.internal.doclets.toolkit.util.DocPath; -import jdk.javadoc.internal.doclets.toolkit.util.IndexBuilder; import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable; /** @@ -184,6 +183,13 @@ public class WriterFactory { return new SearchWriter(configuration); } + /** + * {@return a new writer for the page listing search tags defined in the API} + */ + public HtmlDocletWriter newSearchTagsWriter() { + return IndexItemListWriter.createSearchTagsWriter(configuration); + } + /** * {@return a new writer for the page giving the serialized forms of classes and other type elements} */ @@ -195,7 +201,7 @@ public class WriterFactory { * {@return a new writer for the page listing system properties referenced in the API} */ public HtmlDocletWriter newSystemPropertiesWriter() { - return new SystemPropertiesWriter(configuration); + return IndexItemListWriter.createSystemPropertiesWriter(configuration); } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java index 35240fa69da..e13ed9393a3 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java @@ -857,6 +857,11 @@ public enum HtmlStyles implements HtmlStyle { */ searchPage, + /** + * The class of the {@code body} element for the search tags page. + */ + searchTagsPage, + /** * The class of the {@code body} element for the serialized-forms page. */ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties index bb001912229..e6faa7bbe19 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties @@ -135,6 +135,9 @@ doclet.Preview_Label=Preview doclet.Preview_Mark=PREVIEW doclet.Restricted_Methods=Restricted Methods doclet.Restricted_Mark=RESTRICTED +doclet.searchTag=Search Tag +doclet.searchTags=Search Tags +doclet.searchTagsSummary=Search Tags Summary doclet.Terminally_Deprecated=Terminally Deprecated doclet.Terminally_Deprecated_Elements=Terminally Deprecated Elements doclet.Terminally_Deprecated_In_Release=Terminally Deprecated in {0} @@ -171,6 +174,7 @@ doclet.Interfaces=Interfaces doclet.Enclosing_Class=Enclosing class: doclet.Enclosing_Interface=Enclosing interface: doclet.Inheritance_Tree=Inheritance Tree +doclet.DefinedIn=Defined In doclet.ReferencedIn=Referenced In doclet.Section=Section doclet.External_Specification=External Specification @@ -340,6 +344,9 @@ doclet.help.serial_form.body=\ # 0: link to Constant Values page doclet.help.constants.body=\ The {0} page lists the static final fields and their values. +# 0: link to Search Tags page +doclet.help.searchTags.body=\ + The {0} page lists search tags defined in the documentation. # 0: link to System Properties page doclet.help.systemProperties.body=\ The {0} page lists references to system properties. diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocPaths.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocPaths.java index 47cf3e81ebe..eb937b48e2e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocPaths.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocPaths.java @@ -175,6 +175,9 @@ public class DocPaths { /** The name of the file for search page. */ public static final DocPath SEARCH_PAGE = DocPath.create("search.html"); + /** The name of the file for search tags index page. */ + public static final DocPath SEARCH_TAGS = DocPath.create("search-tags.html"); + /** The name of the file for all system properties. */ public static final DocPath SYSTEM_PROPERTIES = DocPath.create("system-properties.html"); diff --git a/test/langtools/jdk/javadoc/doclet/testIndexInPackageFiles/TestIndexInPackageFiles.java b/test/langtools/jdk/javadoc/doclet/testIndexInPackageFiles/TestIndexInPackageFiles.java index 9e72fca9b5b..098676cff52 100644 --- a/test/langtools/jdk/javadoc/doclet/testIndexInPackageFiles/TestIndexInPackageFiles.java +++ b/test/langtools/jdk/javadoc/doclet/testIndexInPackageFiles/TestIndexInPackageFiles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8213957 8213958 + * @bug 8213957 8213958 8340565 * @summary Test use of at-index in package-iinfo and doc-files * @library /tools/lib ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -121,6 +121,23 @@ public class TestIndexInPackageFiles extends JavadocTester { test.property.1""", """ test.property.2"""); + + checkOrder("search-tags.html", + """ +
    test.name.1
    +
    additional info
    +
    + """, + """ +
    test.name.2
    +
    additional info
    +
    + """, + """ +
    test.name.3
    +
    additional info
    +
    + """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testIndexTaglet/TestIndexTaglet.java b/test/langtools/jdk/javadoc/doclet/testIndexTaglet/TestIndexTaglet.java index 1707eb52532..bc0f59cdc01 100644 --- a/test/langtools/jdk/javadoc/doclet/testIndexTaglet/TestIndexTaglet.java +++ b/test/langtools/jdk/javadoc/doclet/testIndexTaglet/TestIndexTaglet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8202462 + * @bug 8202462 8340565 * @summary {@index} may cause duplicate labels * @library /tools/lib ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -33,7 +33,6 @@ import java.nio.file.Path; -import java.nio.file.Paths; import builder.ClassBuilder; import builder.ClassBuilder.MethodBuilder; @@ -84,6 +83,21 @@ public class TestIndexTaglet extends JavadocTester { "

    Method Summary

    \n", """
    test description with search_phrase_a
    """); + + checkOrder("search-tags.html", + """ +

    Search Tags

    """, + """ +
    Search Tags Summary
    +
    +
    Search Tag
    +
    Description
    +
    Defined In
    """, + """ +
    search_phrase_a
    +
    class a
    +
    + """); } @Test @@ -130,5 +144,13 @@ public class TestIndexTaglet extends JavadocTester { This is a class. Here is foo.""", """ This is a method. Here is foo."""); + + checkOrder("search-tags.html", + """ +
    foo
    +
    first
    +
    + """); } }