diff --git a/make/Docs.gmk b/make/Docs.gmk index 5f9ec99fcae..1e104b16834 100644 --- a/make/Docs.gmk +++ b/make/Docs.gmk @@ -139,11 +139,6 @@ ifeq ($(IS_DRAFT), true) endif DRAFT_TEXT := This specification is not final and is subject to change. \ Use is subject to license terms. - - # Workaround stylesheet bug - HEADER_STYLE := style="margin-top: 9px;" -else - HEADER_STYLE := style="margin-top: 14px;" endif # $1 - Relative prefix to COPYRIGHT_URL @@ -339,7 +334,7 @@ define SetupApiDocsGenerationBody $1_DOC_TITLE := $$($1_LONG_NAME)
Version $$(VERSION_SPECIFICATION) API \ Specification $1_WINDOW_TITLE := $$(subst &,&,$$($1_SHORT_NAME))$$(DRAFT_MARKER_TITLE) - $1_HEADER_TITLE :=
$$($1_SHORT_NAME) \ + $1_HEADER_TITLE :=
$$($1_SHORT_NAME) \ $$(DRAFT_MARKER_STR)
ifneq ($$($1_OTHER_VERSIONS), ) $1_JAVADOC_BOTTOM := $$(call JAVADOC_BOTTOM, Other versions.) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java index b6c56dd47b0..caeb6c35e6d 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -220,6 +220,7 @@ public abstract class AbstractMemberWriter { Content member = getMemberSummaryHeader(target); summaryTreeList.forEach(member::add); buildSummary(target, member); + writer.tableOfContents.addLink(HtmlIds.forMemberSummary(kind), getSummaryLabel()); } } @@ -306,6 +307,20 @@ public abstract class AbstractMemberWriter { return out; } + private Content getSummaryLabel() { + return switch (kind) { + case FIELDS -> contents.fieldSummaryLabel; + case METHODS -> contents.methodSummary; + case CONSTRUCTORS -> contents.constructorSummaryLabel; + case ENUM_CONSTANTS -> contents.enumConstantSummary; + case NESTED_CLASSES -> contents.nestedClassSummary; + case PROPERTIES -> contents.propertySummaryLabel; + case ANNOTATION_TYPE_MEMBER_OPTIONAL -> contents.annotateTypeOptionalMemberSummaryLabel; + case ANNOTATION_TYPE_MEMBER_REQUIRED -> contents.annotateTypeRequiredMemberSummaryLabel; + default -> throw new IllegalArgumentException(kind.toString()); + }; + } + /** * Returns the member summary header for the given class. * diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeMemberWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeMemberWriter.java index d943a603958..6c0337513d0 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeMemberWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeMemberWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -90,6 +90,8 @@ public class AnnotationTypeMemberWriter extends AbstractMemberWriter { addAnnotationDetailsMarker(target); Content annotationDetailsHeader = getAnnotationDetailsHeader(); Content memberList = getMemberList(); + writer.tableOfContents.addLink(HtmlIds.ANNOTATION_TYPE_ELEMENT_DETAIL, contents.annotationTypeDetailsLabel); + writer.tableOfContents.pushNestedList(); for (Element member : members) { currentMember = member; @@ -98,9 +100,12 @@ public class AnnotationTypeMemberWriter extends AbstractMemberWriter { buildAnnotationTypeMemberChildren(div); annotationContent.add(div); memberList.add(writer.getMemberListItem(annotationContent)); + writer.tableOfContents.addLink(htmlIds.forMember(typeElement, (ExecutableElement) member), + Text.of(name(member))); } Content annotationDetails = getAnnotationDetails(annotationDetailsHeader, memberList); target.add(annotationDetails); + writer.tableOfContents.popNestedList(); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java index 322659c6a46..e0b126dfacf 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -34,6 +34,7 @@ import java.util.SortedSet; import java.util.TreeSet; import javax.lang.model.element.Element; +import javax.lang.model.element.ModuleElement; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic; @@ -42,6 +43,7 @@ import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.TagName; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; +import jdk.javadoc.internal.doclets.formats.html.markup.Text; import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode; import jdk.javadoc.internal.doclets.toolkit.DocletException; import jdk.javadoc.internal.doclets.toolkit.util.ClassTree; @@ -418,14 +420,19 @@ public class ClassUseWriter extends SubWriterHolderWriter { @Override protected Navigation getNavBar(PageMode pageMode, Element element) { - Content mdleLinkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement), - contents.moduleLabel); - Content classLinkContent = getLink(new HtmlLinkInfo( - configuration, HtmlLinkInfo.Kind.PLAIN, typeElement) - .label(resources.getText("doclet.Class")) - .skipPreview(true)); - return super.getNavBar(pageMode, element) - .setNavLinkModule(mdleLinkContent) - .setNavLinkClass(classLinkContent); + List subnavLinks = new ArrayList<>(); + if (configuration.showModules) { + ModuleElement mdle = utils.elementUtils.getModuleOf(typeElement); + subnavLinks.add(getModuleLink(mdle, Text.of(mdle.getQualifiedName()))); + } + PackageElement pkg = utils.containingPackage(typeElement); + subnavLinks.add(getPackageLink(pkg, getLocalizedPackageName(pkg))); + subnavLinks.add(getLink( + new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.PLAIN, typeElement) + .style(HtmlStyle.currentSelection) + .skipPreview(true))); + + return super.getNavBar(pageMode, element).setSubNavLinks(subnavLinks); } } + diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java index dcbc78f7107..f74921464bb 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -48,7 +48,6 @@ import com.sun.source.doctree.DocTree; import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; -import jdk.javadoc.internal.doclets.formats.html.markup.Entity; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; @@ -61,7 +60,6 @@ import jdk.javadoc.internal.doclets.toolkit.util.ClassTree; import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper; import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; import jdk.javadoc.internal.doclets.toolkit.util.DocPath; -import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable; /** * Generate the Class Information Page. @@ -435,24 +433,6 @@ public class ClassWriter extends SubWriterHolderWriter { protected Content getHeader(String header) { HtmlTree body = getBody(getWindowTitle(utils.getSimpleName(typeElement))); var div = HtmlTree.DIV(HtmlStyle.header); - if (configuration.showModules) { - ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(typeElement); - var classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInType, contents.moduleLabel); - var moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classModuleLabel); - moduleNameDiv.add(Entity.NO_BREAK_SPACE); - moduleNameDiv.add(getModuleLink(mdle, - Text.of(mdle.getQualifiedName()))); - div.add(moduleNameDiv); - } - PackageElement pkg = utils.containingPackage(typeElement); - if (!pkg.isUnnamed()) { - var classPackageLabel = HtmlTree.SPAN(HtmlStyle.packageLabelInType, contents.packageLabel); - var pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classPackageLabel); - pkgNameDiv.add(Entity.NO_BREAK_SPACE); - Content pkgNameContent = getPackageLink(pkg, getLocalizedPackageName(pkg)); - pkgNameDiv.add(pkgNameContent); - div.add(pkgNameDiv); - } HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_AND_BOUNDS, typeElement) .linkToSelf(false); // Let's not link to ourselves in the header @@ -472,21 +452,17 @@ public class ClassWriter extends SubWriterHolderWriter { @Override protected Navigation getNavBar(PageMode pageMode, Element element) { - Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(element), - contents.moduleLabel); - return super.getNavBar(pageMode, element) - .setNavLinkModule(linkContent) - .setSubNavLinks(() -> { - List list = new ArrayList<>(); - VisibleMemberTable vmt = configuration.getVisibleMemberTable(typeElement); - Set summarySet = - VisibleMemberTable.Kind.forSummariesOf(element.getKind()); - for (VisibleMemberTable.Kind kind : summarySet) { - list.add(links.createLink(HtmlIds.forMemberSummary(kind), - contents.getNavLinkLabelContent(kind), vmt.hasVisibleMembers(kind))); - } - return list; - }); + List subnavLinks = new ArrayList<>(); + if (configuration.showModules) { + ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(typeElement); + subnavLinks.add(getModuleLink(mdle, Text.of(mdle.getQualifiedName()))); + } + PackageElement pkg = utils.containingPackage(typeElement); + subnavLinks.add(getPackageLink(pkg, getLocalizedPackageName(pkg))); + subnavLinks.add(getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.PLAIN, typeElement) + .style(HtmlStyle.currentSelection) + .skipPreview(true))); + return super.getNavBar(pageMode, element).setSubNavLinks(subnavLinks); } protected void addFooter() { @@ -520,10 +496,13 @@ public class ClassWriter extends SubWriterHolderWriter { protected void addClassDescription(Content classInfo) { addPreviewInfo(classInfo); + tableOfContents.addLink(HtmlIds.TOP_OF_PAGE, contents.descriptionLabel); if (!options.noComment()) { // generate documentation for the class. if (!utils.getFullBody(typeElement).isEmpty()) { + tableOfContents.pushNestedList(); addInlineComment(typeElement, classInfo); + tableOfContents.popNestedList(); } } } @@ -535,7 +514,9 @@ public class ClassWriter extends SubWriterHolderWriter { protected void addClassTagInfo(Content classInfo) { if (!options.noComment()) { // Print Information about all the tags here + tableOfContents.pushNestedList(); addTagsInfo(typeElement, classInfo); + tableOfContents.popNestedList(); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriter.java index 9522c2e321f..5bddac0622c 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -50,7 +50,6 @@ import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode; import jdk.javadoc.internal.doclets.formats.html.markup.Text; import jdk.javadoc.internal.doclets.toolkit.DocletException; import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; -import jdk.javadoc.internal.doclets.toolkit.util.DocLink; import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; import jdk.javadoc.internal.doclets.toolkit.util.IndexItem; import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable; @@ -144,16 +143,18 @@ public class ConstantsSummaryWriter extends HtmlDocletWriter { * Builds the list of contents for the groups of packages appearing in the constants summary page. */ protected void buildContents() { - Content contentList = getContentsHeader(); + tableOfContents.addLink(HtmlIds.TOP_OF_PAGE, Text.of(resources.getText("doclet.Constants_Summary"))) + .pushNestedList(); packageGroupHeadings.clear(); for (PackageElement pkg : configuration.packages) { String abbrevPackageName = getAbbrevPackageName(pkg); if (hasConstantField(pkg) && !packageGroupHeadings.contains(abbrevPackageName)) { - addLinkToPackageContent(abbrevPackageName, contentList); + addLinkToTableOfContents(abbrevPackageName); packageGroupHeadings.add(abbrevPackageName); } } - addContentsList(contentList); + tableOfContents.popNestedList(); + bodyContents.setSideContent(tableOfContents.toContent(true)); } /** @@ -322,42 +323,27 @@ public class ConstantsSummaryWriter extends HtmlDocletWriter { } Content getHeader() { - String label = resources.getText("doclet.Constants_Summary"); - HtmlTree body = getBody(getWindowTitle(label)); - bodyContents.setHeader(getHeader(PageMode.CONSTANT_VALUES)); - return body; + String label = resources.getText("doclet.Constants_Summary"); + HtmlTree body = getBody(getWindowTitle(label)); + bodyContents.setHeader(getHeader(PageMode.CONSTANT_VALUES)); + Content titleContent = contents.constantsSummaryTitle; + var pHeading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING, + HtmlStyle.title, titleContent); + var div = HtmlTree.DIV(HtmlStyle.header, pHeading); + bodyContents.addMainContent(div); + return body; } - Content getContentsHeader() { + Content getContentsHeader() { return HtmlTree.UL(HtmlStyle.contentsList); } - void addLinkToPackageContent(String abbrevPackageName, Content content) { - //add link to summary - Content link; + void addLinkToTableOfContents(String abbrevPackageName) { if (abbrevPackageName.isEmpty()) { - link = links.createLink(HtmlIds.UNNAMED_PACKAGE_ANCHOR, - contents.defaultPackageLabel, ""); + tableOfContents.addLink(HtmlIds.UNNAMED_PACKAGE_ANCHOR, contents.defaultPackageLabel); } else { - Content packageNameContent = Text.of(abbrevPackageName + ".*"); - link = links.createLink(DocLink.fragment(abbrevPackageName), - packageNameContent, ""); + tableOfContents.addLink(HtmlId.of(abbrevPackageName), Text.of(abbrevPackageName + ".*")); } - content.add(HtmlTree.LI(link)); - } - - void addContentsList(Content content) { - Content titleContent = contents.constantsSummaryTitle; - var pHeading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING, - HtmlStyle.title, titleContent); - var div = HtmlTree.DIV(HtmlStyle.header, pHeading); - bodyContents.addMainContent(div); - Content headingContent = contents.contentsHeading; - var heading = HtmlTree.HEADING_TITLE(Headings.CONTENT_HEADING, - headingContent); - var section = HtmlTree.SECTION(HtmlStyle.packages, heading); - section.add(content); - bodyContents.addMainContent(section); } void addPackageGroup(String abbrevPackageName, Content toContent) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriter.java index 643a144b5e5..5782dcd06a4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstructorWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -102,6 +102,8 @@ public class ConstructorWriter extends AbstractExecutableMemberWriter { Content constructorDetailsHeader = getConstructorDetailsHeader(target); Content memberList = getMemberList(); + writer.tableOfContents.addLink(HtmlIds.CONSTRUCTOR_DETAIL, contents.constructorDetailsLabel); + writer.tableOfContents.pushNestedList(); for (Element constructor : constructors) { currentConstructor = (ExecutableElement)constructor; @@ -114,9 +116,13 @@ public class ConstructorWriter extends AbstractExecutableMemberWriter { buildTagInfo(div); constructorContent.add(div); memberList.add(getMemberListItem(constructorContent)); + writer.tableOfContents.addLink(htmlIds.forMember(currentConstructor), + Text.of(utils.getSimpleName(constructor) + + utils.makeSignature(currentConstructor, typeElement, false, true))); } Content constructorDetails = getConstructorDetails(constructorDetailsHeader, memberList); target.add(constructorDetails); + writer.tableOfContents.popNestedList(); } } 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 2c1ab3ae882..3afccd55ba1 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -104,6 +104,7 @@ public class Contents { public final Content functionalInterfaceMessage; public final Content helpLabel; public final Content helpSubNavLabel; + public final Content hideSidebar; public final Content hierarchyForAllPackages; public final Content implementation; public final Content implementingClassesLabel; @@ -169,9 +170,11 @@ public class Contents { public final Content referencedIn; public final Content relatedPackages; public final Content returns; + public final Content searchLabel; public final Content seeAlso; public final Content serializedForm; public final Content servicesLabel; + public final Content showSidebar; public final Content specificationLabel; public final Content specifiedByLabel; public final Content subclassesLabel; @@ -179,6 +182,7 @@ public class Contents { public final Content summaryLabel; public final Content systemPropertiesLabel; public final Content systemPropertiesSummaryLabel; + public final Content tableOfContentsLabel; public final Content throws_; public final Content treeLabel; public final Content typeLabel; @@ -253,6 +257,7 @@ public class Contents { functionalInterfaceMessage = getContent("doclet.Functional_Interface_Message"); helpLabel = getContent("doclet.Help"); helpSubNavLabel = getContent("doclet.Help_Sub_Nav"); + hideSidebar = getContent("doclet.hide_sidebar"); hierarchyForAllPackages = getContent("doclet.Hierarchy_For_All_Packages"); implementation = getContent("doclet.Implementation"); implementingClassesLabel = getContent("doclet.Implementing_Classes"); @@ -318,9 +323,11 @@ public class Contents { referencedIn = getContent("doclet.ReferencedIn"); relatedPackages = getContent("doclet.Related_Packages"); returns = getContent("doclet.Returns"); + searchLabel = getContent("doclet.search"); seeAlso = getContent("doclet.See_Also"); serializedForm = getContent("doclet.Serialized_Form"); servicesLabel = getContent("doclet.Services"); + showSidebar = getContent("doclet.show_sidebar"); specificationLabel = getContent("doclet.Specification"); specifiedByLabel = getContent("doclet.Specified_By"); subclassesLabel = getContent("doclet.Subclasses"); @@ -328,6 +335,7 @@ public class Contents { summaryLabel = getContent("doclet.Summary"); systemPropertiesLabel = getContent("doclet.systemProperties"); systemPropertiesSummaryLabel = getContent("doclet.systemPropertiesSummary"); + tableOfContentsLabel = getContent("doclet.table_of_contents"); throws_ = getContent("doclet.Throws"); treeLabel = getContent("doclet.Tree"); typeLabel = getContent("doclet.Type"); @@ -434,7 +442,7 @@ public class Contents { * @param items the items * @return the composition */ - public Content join(Content separator, Collection items) { + public Content join(Content separator, Collection items) { Content result = new ContentBuilder(); boolean first = true; for (Content c : items) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java index b670faeade9..bc0f1e52bbd 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -107,7 +107,7 @@ public class DeprecatedListWriter extends SummaryListWriter subnavLinks = new ArrayList<>(); var pkg = dfElement.getPackageElement(); - Content mdleLinkContent = getModuleLink(utils.elementUtils.getModuleOf(element), - contents.moduleLabel); - Content pkgLinkContent = getPackageLink(pkg, contents.packageLabel); - return super.getNavBar(pageMode, element) - .setNavLinkModule(mdleLinkContent) - .setNavLinkPackage(pkgLinkContent); + if (configuration.showModules) { + var mdle = utils.elementUtils.getModuleOf(element); + subnavLinks.add(links.createLink(pathToRoot.resolve(docPaths.moduleSummary(mdle)), + Text.of(mdle.getQualifiedName()), + pkg.isUnnamed() ? HtmlStyle.currentSelection : null, "")); + } + if (!pkg.isUnnamed()) { + subnavLinks.add(links.createLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY), + getLocalizedPackageName(pkg), HtmlStyle.currentSelection, "")); + } + return super.getNavBar(pageMode, element).setSubNavLinks(subnavLinks); } @Override diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriter.java index 3dc91f05c8f..d60fd355027 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -69,6 +69,8 @@ public class EnumConstantWriter extends AbstractMemberWriter { if (!enumConstants.isEmpty()) { Content enumConstantsDetailsHeader = getEnumConstantsDetailsHeader(target); Content memberList = getMemberList(); + writer.tableOfContents.addLink(HtmlIds.ENUM_CONSTANT_DETAIL, contents.enumConstantDetailLabel); + writer.tableOfContents.pushNestedList(); for (Element enumConstant : enumConstants) { currentElement = (VariableElement)enumConstant; @@ -81,10 +83,12 @@ public class EnumConstantWriter extends AbstractMemberWriter { buildTagInfo(div); enumConstantContent.add(div); memberList.add(getMemberListItem(enumConstantContent)); + writer.tableOfContents.addLink(htmlIds.forMember(currentElement), Text.of(name(currentElement))); } Content enumConstantDetails = getEnumConstantsDetails( enumConstantsDetailsHeader, memberList); target.add(enumConstantDetails); + writer.tableOfContents.popNestedList(); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriter.java index 9c5dfcb2aad..c72521b73b2 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -79,6 +79,8 @@ public class FieldWriter extends AbstractMemberWriter { if (!fields.isEmpty()) { Content fieldDetailsHeader = getFieldDetailsHeader(target); Content memberList = getMemberList(); + writer.tableOfContents.addLink(HtmlIds.FIELD_DETAIL, contents.fieldDetailsLabel); + writer.tableOfContents.pushNestedList(); for (Element element : fields) { currentElement = (VariableElement)element; @@ -91,9 +93,11 @@ public class FieldWriter extends AbstractMemberWriter { buildTagInfo(div); fieldContent.add(div); memberList.add(getMemberListItem(fieldContent)); + writer.tableOfContents.addLink(htmlIds.forMember(currentElement), Text.of(name(element))); } Content fieldDetails = getFieldDetails(fieldDetailsHeader, memberList); target.add(fieldDetails); + writer.tableOfContents.popNestedList(); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Headings.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Headings.java index 4725c8eb903..84b2fda4da4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Headings.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Headings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -122,14 +122,4 @@ class Headings { static class TypeUse { static final TagName SUMMARY_HEADING = TagName.H2; } - - /** - * Headings for index frames pages. - */ - static class IndexFrames { - /** Heading for a list of module names in an index frame. */ - static final TagName MODULE_HEADING = TagName.H2; - /** Heading for a list of package names in an index frame. */ - static final TagName PACKAGE_HEADING = TagName.H2; - } } 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 1adff39ff1a..1f396d49eed 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -26,7 +26,6 @@ package jdk.javadoc.internal.doclets.formats.html; import java.util.List; -import javax.lang.model.element.Element; import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; @@ -37,7 +36,6 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode; import jdk.javadoc.internal.doclets.formats.html.markup.Text; import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; -import jdk.javadoc.internal.doclets.toolkit.util.DocLink; import jdk.javadoc.internal.doclets.toolkit.util.DocPath; import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; @@ -85,6 +83,7 @@ public class HelpWriter extends HtmlDocletWriter { body.add(new BodyContents() .setHeader(getHeader(PageMode.HELP)) .addMainContent(helpFileContent) + .setSideContent(tableOfContents.toContent(false)) .setFooter(getFooter())); printHtmlDocument(null, "help", body); } @@ -101,27 +100,18 @@ public class HelpWriter extends HtmlDocletWriter { * */ protected void addHelpFileContents(Content content) { - var mainTOC = HtmlTree.UL(HtmlStyle.helpTOC); - - content.add(HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, HtmlStyle.title, - getContent("doclet.help.main_heading"))) - .add(mainTOC) + var mainHeading = getContent("doclet.help.main_heading"); + tableOfContents.addLink(HtmlIds.TOP_OF_PAGE, mainHeading); + tableOfContents.pushNestedList(); + content.add(HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, HtmlStyle.title, mainHeading)) .add(new HtmlTree(TagName.HR)) - .add(getNavigationSection(mainTOC)) + .add(getNavigationSection()) .add(new HtmlTree(TagName.HR)) - .add(getPageKindSection(mainTOC)) + .add(getPageKindSection()) .add(new HtmlTree(TagName.HR)) .add(HtmlTree.SPAN(HtmlStyle.helpFootnote, getContent("doclet.help.footnote"))); - } - - @Override - protected Navigation getNavBar(PageMode pageMode, Element element) { - return super.getNavBar(pageMode, element) - .setSubNavLinks(() -> List.of( - links.createLink(HtmlIds.HELP_NAVIGATION, contents.navHelpNavigation), - links.createLink(HtmlIds.HELP_PAGES, contents.navHelpPages)) - ); + tableOfContents.popNestedList(); } /** @@ -133,11 +123,9 @@ public class HelpWriter extends HtmlDocletWriter { *
  • Search * * - * @param mainTOC the main table-of-contents - * * @return the content containing the help */ - private Content getNavigationSection(HtmlTree mainTOC) { + private Content getNavigationSection() { Content content = new ContentBuilder(); Content navHeading = contents.getContent("doclet.help.navigation.head"); @@ -156,15 +144,16 @@ public class HelpWriter extends HtmlDocletWriter { } content.add(navSection); - var subTOC = HtmlTree.UL(HtmlStyle.helpSubTOC); + tableOfContents.addLink(HtmlIds.HELP_NAVIGATION, navHeading); + tableOfContents.pushNestedList(); HtmlTree section; // Search if (options.createIndex()) { - section = newHelpSection(getContent("doclet.help.search.head"), PageMode.SEARCH, subTOC); + section = newHelpSection(getContent("doclet.help.search.head"), PageMode.SEARCH); var searchIntro = HtmlTree.P(getContent("doclet.help.search.intro")); - var searchExamples = HtmlTree.UL(HtmlStyle.helpSectionList); + var searchExamples = HtmlTree.OL(HtmlStyle.tocList); for (String[] example : SEARCH_EXAMPLES) { searchExamples.add(HtmlTree.LI( getContent("doclet.help.search.example", @@ -179,10 +168,7 @@ public class HelpWriter extends HtmlDocletWriter { .add(searchRefer); navSection.add(section); } - - mainTOC.add(HtmlTree.LI(new ContentBuilder( - links.createLink(DocLink.fragment(HtmlIds.HELP_NAVIGATION.name()), navHeading), - Text.of(": "), subTOC))); + tableOfContents.popNestedList(); return content; } @@ -200,23 +186,22 @@ public class HelpWriter extends HtmlDocletWriter { *
  • Index info: all packages, all classes, full index * * - * @param mainTOC the main table-of-contents - * * @return the content containing the help */ - private Content getPageKindSection(HtmlTree mainTOC) { + private Content getPageKindSection() { Content pageKindsHeading = contents.getContent("doclet.help.page_kinds.head"); var pageKindsSection = HtmlTree.DIV(HtmlStyle.subTitle) .add(HtmlTree.HEADING(Headings.CONTENT_HEADING, pageKindsHeading).setId(HtmlIds.HELP_PAGES)) .add(contents.getContent("doclet.help.page_kinds.intro")); - var subTOC = HtmlTree.UL(HtmlStyle.helpSubTOC); + tableOfContents.addLink(HtmlIds.HELP_PAGES, pageKindsHeading); + tableOfContents.pushNestedList(); HtmlTree section; // Overview if (options.createOverview()) { - section = newHelpSection(contents.overviewLabel, PageMode.OVERVIEW, subTOC); + section = newHelpSection(contents.overviewLabel, PageMode.OVERVIEW); String overviewKey = configuration.showModules ? "doclet.help.overview.modules.body" : "doclet.help.overview.packages.body"; @@ -226,7 +211,7 @@ public class HelpWriter extends HtmlDocletWriter { // Module if (configuration.showModules) { - section = newHelpSection(contents.moduleLabel, PageMode.MODULE, subTOC); + section = newHelpSection(contents.moduleLabel, PageMode.MODULE); Content moduleIntro = getContent("doclet.help.module.intro"); var modulePara = HtmlTree.P(moduleIntro); section.add(modulePara) @@ -238,7 +223,7 @@ public class HelpWriter extends HtmlDocletWriter { } // Package - section = newHelpSection(contents.packageLabel, PageMode.PACKAGE, subTOC) + section = newHelpSection(contents.packageLabel, PageMode.PACKAGE) .add(HtmlTree.P(getContent("doclet.help.package.intro"))) .add(newHelpSectionList( contents.interfaces, @@ -260,7 +245,7 @@ public class HelpWriter extends HtmlDocletWriter { Text.of(" "), getContent("doclet.help.class_interface.property")); - section = newHelpSection(getContent("doclet.help.class_interface.head"), PageMode.CLASS, subTOC) + section = newHelpSection(getContent("doclet.help.class_interface.head"), PageMode.CLASS) .add(HtmlTree.P(getContent("doclet.help.class_interface.intro"))) .add(newHelpSectionList( getContent("doclet.help.class_interface.inheritance_diagram"), @@ -291,20 +276,20 @@ public class HelpWriter extends HtmlDocletWriter { .add(HtmlTree.P(getContent("doclet.help.class_interface.member_order"))); pageKindsSection.add(section); - section = newHelpSection(getContent("doclet.help.other_files.head"), PageMode.DOC_FILE, subTOC) + section = newHelpSection(getContent("doclet.help.other_files.head"), PageMode.DOC_FILE) .add(HtmlTree.P(getContent("doclet.help.other_files.body"))); pageKindsSection.add(section); // Class Use if (options.classUse()) { - section = newHelpSection(getContent("doclet.help.use.head"), PageMode.USE, subTOC) + section = newHelpSection(getContent("doclet.help.use.head"), PageMode.USE) .add(HtmlTree.P(getContent("doclet.help.use.body"))); pageKindsSection.add(section); } // Tree if (options.createTree()) { - section = newHelpSection(getContent("doclet.help.tree.head"), PageMode.TREE, subTOC); + section = newHelpSection(getContent("doclet.help.tree.head"), PageMode.TREE); Content treeIntro = getContent("doclet.help.tree.intro", links.createLink(DocPaths.OVERVIEW_TREE, resources.getText("doclet.Class_Hierarchy")), HtmlTree.CODE(Text.of("java.lang.Object"))); @@ -317,7 +302,7 @@ public class HelpWriter extends HtmlDocletWriter { // Preview if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.PREVIEW)) { - section = newHelpSection(contents.previewAPI, PageMode.PREVIEW, subTOC); + section = newHelpSection(contents.previewAPI, PageMode.PREVIEW); Content previewBody = getContent("doclet.help.preview.body", links.createLink(DocPaths.PREVIEW_LIST, contents.previewAPI)); section.add(HtmlTree.P(previewBody)); @@ -326,7 +311,7 @@ public class HelpWriter extends HtmlDocletWriter { // New if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.NEW)) { - section = newHelpSection(contents.newAPI, PageMode.NEW, subTOC); + section = newHelpSection(contents.newAPI, PageMode.NEW); Content newBody = getContent("doclet.help.new.body", links.createLink(DocPaths.NEW_LIST, contents.newAPI)); section.add(HtmlTree.P(newBody)); @@ -335,7 +320,7 @@ public class HelpWriter extends HtmlDocletWriter { // Deprecated if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.DEPRECATED)) { - section = newHelpSection(contents.deprecatedAPI, PageMode.DEPRECATED, subTOC); + section = newHelpSection(contents.deprecatedAPI, PageMode.DEPRECATED); Content deprBody = getContent("doclet.help.deprecated.body", links.createLink(DocPaths.DEPRECATED_LIST, resources.getText("doclet.Deprecated_API"))); section.add(HtmlTree.P(deprBody)); @@ -344,7 +329,7 @@ public class HelpWriter extends HtmlDocletWriter { // Restricted if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.RESTRICTED)) { - section = newHelpSection(contents.restrictedMethods, PageMode.RESTRICTED, subTOC); + section = newHelpSection(contents.restrictedMethods, PageMode.RESTRICTED); Content restrictedBody = getContent("doclet.help.restricted.body", links.createLink(DocPaths.RESTRICTED_LIST, resources.getText("doclet.Restricted_Methods"))); section.add(HtmlTree.P(restrictedBody)); @@ -353,7 +338,7 @@ public class HelpWriter extends HtmlDocletWriter { // Constant Field Values if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.CONSTANT_VALUES)) { - section = newHelpSection(contents.constantsSummaryTitle, PageMode.CONSTANT_VALUES, subTOC); + section = newHelpSection(contents.constantsSummaryTitle, PageMode.CONSTANT_VALUES); Content constantsBody = getContent("doclet.help.constants.body", links.createLink(DocPaths.CONSTANT_VALUES, resources.getText("doclet.Constants_Summary"))); section.add(HtmlTree.P(constantsBody)); @@ -362,14 +347,14 @@ public class HelpWriter extends HtmlDocletWriter { // Serialized Form if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.SERIALIZED_FORM)) { - section = newHelpSection(contents.serializedForm, PageMode.SERIALIZED_FORM, subTOC) + section = newHelpSection(contents.serializedForm, PageMode.SERIALIZED_FORM) .add(HtmlTree.P(getContent("doclet.help.serial_form.body"))); pageKindsSection.add(section); } // System Properties if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.SYSTEM_PROPERTIES)) { - section = newHelpSection(contents.systemPropertiesLabel, PageMode.SYSTEM_PROPERTIES, subTOC); + section = newHelpSection(contents.systemPropertiesLabel, PageMode.SYSTEM_PROPERTIES); Content sysPropsBody = getContent("doclet.help.systemProperties.body", links.createLink(DocPaths.SYSTEM_PROPERTIES, resources.getText("doclet.systemProperties"))); section.add(HtmlTree.P(sysPropsBody)); @@ -378,7 +363,7 @@ public class HelpWriter extends HtmlDocletWriter { // External Specification if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.EXTERNAL_SPECS)) { - section = newHelpSection(contents.externalSpecifications, PageMode.EXTERNAL_SPECS, subTOC); + section = newHelpSection(contents.externalSpecifications, PageMode.EXTERNAL_SPECS); Content extSpecsBody = getContent("doclet.help.externalSpecifications.body", links.createLink(DocPaths.EXTERNAL_SPECS, resources.getText("doclet.External_Specifications"))); section.add(HtmlTree.P(extSpecsBody)); @@ -388,12 +373,12 @@ public class HelpWriter extends HtmlDocletWriter { // Index if (options.createIndex()) { if (!configuration.packages.isEmpty()) { - section = newHelpSection(getContent("doclet.help.all_packages.head"), PageMode.ALL_PACKAGES, subTOC) + section = newHelpSection(getContent("doclet.help.all_packages.head"), PageMode.ALL_PACKAGES) .add(HtmlTree.P(getContent("doclet.help.all_packages.body", allPackagesLink))); pageKindsSection.add(section); } - section = newHelpSection(getContent("doclet.help.all_classes.head"), PageMode.ALL_CLASSES, subTOC) + section = newHelpSection(getContent("doclet.help.all_classes.head"), PageMode.ALL_CLASSES) .add(HtmlTree.P(getContent("doclet.help.all_classes.body", allClassesLink))); pageKindsSection.add(section); @@ -403,14 +388,11 @@ public class HelpWriter extends HtmlDocletWriter { links.add(", "); } links.add(allClassesLink); - section = newHelpSection(getContent("doclet.help.index.head"), PageMode.INDEX, subTOC) + section = newHelpSection(getContent("doclet.help.index.head"), PageMode.INDEX) .add(HtmlTree.P(getContent("doclet.help.index.body", indexLink, links))); pageKindsSection.add(section); } - - mainTOC.add(HtmlTree.LI(new ContentBuilder( - links.createLink(DocLink.fragment(HtmlIds.HELP_PAGES.name()), pageKindsHeading), - Text.of(": "), subTOC))); + tableOfContents.popNestedList(); return pageKindsSection; } @@ -427,17 +409,16 @@ public class HelpWriter extends HtmlDocletWriter { return contents.getContent(key, arg1, arg2); } - private HtmlTree newHelpSection(Content headingContent, HtmlTree toc, HtmlId id) { - Content link = links.createLink(DocLink.fragment(id.name()), headingContent); - toc.add(HtmlTree.LI(link)); + private HtmlTree newHelpSection(Content headingContent, HtmlId id) { + tableOfContents.addLink(id, headingContent); return HtmlTree.SECTION(HtmlStyle.helpSection, HtmlTree.HEADING(Headings.SUB_HEADING, headingContent)) .setId(id); } - private HtmlTree newHelpSection(Content headingContent, Navigation.PageMode pm, HtmlTree toc) { - return newHelpSection(headingContent, toc, htmlIds.forPage(pm)); + private HtmlTree newHelpSection(Content headingContent, Navigation.PageMode pm) { + return newHelpSection(headingContent, htmlIds.forPage(pm)); } private HtmlTree newHelpSectionList(Content first, Content... rest) { 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 93fdbad6eb5..86fc0daedd0 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -233,7 +233,6 @@ public class HtmlDoclet extends AbstractDoclet { messages.error("doclet.No_Non_Deprecated_Classes_To_Document"); return; } - boolean nodeprecated = options.noDeprecated(); copyFile(options.helpFile(), DocPath.empty); copyFile(options.stylesheetFile(), DocPaths.RESOURCE_FILES); for (String stylesheet : options.additionalStylesheets()) { @@ -309,7 +308,7 @@ public class HtmlDoclet extends AbstractDoclet { if (options.stylesheetFile().length() == 0) { copyResource(DocPaths.STYLESHEET, DocPaths.RESOURCE_FILES.resolve(DocPaths.STYLESHEET), true); } - copyResource(DocPaths.SCRIPT_JS, DocPaths.SCRIPT_FILES.resolve(DocPaths.SCRIPT_JS), true); + copyResource(DocPaths.SCRIPT_JS_TEMPLATE, DocPaths.SCRIPT_FILES.resolve(DocPaths.SCRIPT_JS), true); copyResource(DocPaths.CLIPBOARD_SVG, DocPaths.RESOURCE_FILES.resolve(DocPaths.CLIPBOARD_SVG), true); copyResource(DocPaths.LINK_SVG, DocPaths.RESOURCE_FILES.resolve(DocPaths.LINK_SVG), true); 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 c1f2f8d7a63..73ce7bb784f 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, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -31,6 +31,7 @@ import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; @@ -70,6 +71,7 @@ import com.sun.source.doctree.EndElementTree; import com.sun.source.doctree.EntityTree; import com.sun.source.doctree.ErroneousTree; import com.sun.source.doctree.EscapeTree; +import com.sun.source.doctree.IndexTree; import com.sun.source.doctree.InheritDocTree; import com.sun.source.doctree.InlineTagTree; import com.sun.source.doctree.LinkTree; @@ -82,11 +84,13 @@ import com.sun.source.util.SimpleDocTreeVisitor; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.Entity; import jdk.javadoc.internal.doclets.formats.html.markup.Head; +import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocument; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlId; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; import jdk.javadoc.internal.doclets.formats.html.markup.Links; +import jdk.javadoc.internal.doclets.formats.html.markup.ListBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml; import jdk.javadoc.internal.doclets.formats.html.markup.Script; import jdk.javadoc.internal.doclets.formats.html.markup.TagName; @@ -162,6 +166,8 @@ public abstract class HtmlDocletWriter { private final Set headingIds = new HashSet<>(); + protected final TableOfContents tableOfContents; + /** * To check whether the repeated annotations is documented or not. */ @@ -217,6 +223,7 @@ public abstract class HtmlDocletWriter { this.pathToRoot = path.parent().invert(); this.docPaths = configuration.docPaths; this.mainBodyScript = new Script(); + this.tableOfContents = new TableOfContents(this); if (generating) { writeGenerating(); @@ -1465,6 +1472,15 @@ public abstract class HtmlDocletWriter { sb.append(text.getBody()); } else if (docTree instanceof LiteralTree literal) { sb.append(literal.getBody().getBody()); + } else if (docTree instanceof IndexTree index) { + DocTree searchTerm = index.getSearchTerm(); + String tagText = (searchTerm instanceof TextTree tt) ? tt.getBody() : ""; + if (tagText.charAt(0) == '"' && tagText.charAt(tagText.length() - 1) == '"') { + tagText = tagText.substring(1, tagText.length() - 1); + } + sb.append(tagText); + } else if (docTree instanceof EntityTree entity) { + sb.append(utils.docTrees.getCharacters(entity)); } else if (docTree instanceof LinkTree link) { var label = link.getLabel(); sb.append(label.isEmpty() ? link.getReference().getSignature() : label.toString()); @@ -1483,6 +1499,8 @@ public abstract class HtmlDocletWriter { HtmlId htmlId = htmlIds.forHeading(headingContent, headingIds); id = htmlId.name(); attrs.add("id=\"").add(htmlId.name()).add("\""); + } else { + headingIds.add(id); } // Generate index item if (!headingContent.isEmpty() && configuration.indexBuilder != null) { @@ -1493,6 +1511,10 @@ public abstract class HtmlDocletWriter { new DocLink(path, id)); configuration.indexBuilder.add(item); } + // Record second-level headings for use in table of contents + if (tableOfContents != null && node.getName().toString().equalsIgnoreCase("h2")) { + tableOfContents.addLink(HtmlId.of(id), Text.of(headingContent)); + } } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIds.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIds.java index 5237811ab8e..10e91cc1204 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIds.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIds.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -67,6 +67,7 @@ public class HtmlIds { private final HtmlConfiguration configuration; private final Utils utils; + static final HtmlId TOP_OF_PAGE = HtmlId.of(""); // empty fragment/id indicates top of page static final HtmlId ALL_CLASSES_TABLE = HtmlId.of("all-classes-table"); static final HtmlId ALL_MODULES_TABLE = HtmlId.of("all-modules-table"); static final HtmlId ALL_PACKAGES_TABLE = HtmlId.of("all-packages-table"); @@ -90,7 +91,6 @@ public class HtmlIds { static final HtmlId METHOD_SUMMARY_TABLE = HtmlId.of("method-summary-table"); static final HtmlId MODULES = HtmlId.of("modules-summary"); static final HtmlId MODULE_DESCRIPTION = HtmlId.of("module-description"); - static final HtmlId NAVBAR_SUB_LIST = HtmlId.of("navbar-sub-list"); static final HtmlId NAVBAR_TOGGLE_BUTTON = HtmlId.of("navbar-toggle-button"); static final HtmlId NAVBAR_TOP = HtmlId.of("navbar-top"); static final HtmlId NAVBAR_TOP_FIRSTROW = HtmlId.of("navbar-top-firstrow"); @@ -101,7 +101,7 @@ public class HtmlIds { static final HtmlId PROPERTY_DETAIL = HtmlId.of("property-detail"); static final HtmlId PROPERTY_SUMMARY = HtmlId.of("property-summary"); static final HtmlId RELATED_PACKAGE_SUMMARY = HtmlId.of("related-package-summary"); - static final HtmlId RESET_BUTTON = HtmlId.of("reset-button"); + static final HtmlId RESET_SEARCH = HtmlId.of("reset-search"); static final HtmlId SEARCH_INPUT = HtmlId.of("search-input"); static final HtmlId SERVICES = HtmlId.of("services-summary"); static final HtmlId SKIP_NAVBAR_TOP = HtmlId.of("skip-navbar-top"); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java index df9dd9b77ae..f2acb86f19e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.Set; -import java.util.function.Consumer; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkInfo.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkInfo.java index 053959d5546..c2c79e850b8 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkInfo.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -85,7 +85,7 @@ public class HtmlLinkInfo { private Kind context = Kind.PLAIN; // The fragment of the link. - private String fragment = ""; + private String fragment = null; // The member this link points to (if any). private Element targetMember; 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 5ca903b49d2..ff2761b8ecb 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, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -285,9 +285,9 @@ public class IndexWriter extends HtmlDocletWriter { var div = HtmlTree.DIV(HtmlStyle.deprecationBlock); if (utils.isDeprecated(element)) { div.add(span); - List tags = utils.getDeprecatedTrees(element); + var tags = utils.getDeprecatedTrees(element); if (!tags.isEmpty()) - addInlineDeprecatedComment(element, tags.get(0), div); + addInlineDeprecatedComment(element, tags.getFirst(), div); content.add(div); } else { TypeElement encl = utils.getEnclosingTypeElement(element); @@ -350,7 +350,7 @@ public class IndexWriter extends HtmlDocletWriter { } content.add(new HtmlTree(TagName.BR)); - List pageLinks = Stream.of(IndexItem.Category.values()) + var pageLinks = Stream.of(IndexItem.Category.values()) .flatMap(c -> mainIndex.getItems(c).stream()) .filter(i -> !(i.isElementItem() || i.isTagItem())) .sorted((i1,i2)-> utils.compareStrings(i1.getLabel(), i2.getLabel())) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriter.java index 4cb066f0adf..5f20f360eb6 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -101,6 +101,8 @@ public class MethodWriter extends AbstractExecutableMemberWriter { if (!methods.isEmpty()) { Content methodDetailsHeader = getMethodDetailsHeader(detailsList); Content memberList = writer.getMemberList(); + writer.tableOfContents.addLink(HtmlIds.METHOD_DETAIL, contents.methodDetailLabel); + writer.tableOfContents.pushNestedList(); for (Element method : methods) { currentMethod = (ExecutableElement)method; @@ -114,9 +116,13 @@ public class MethodWriter extends AbstractExecutableMemberWriter { buildTagInfo(div); methodContent.add(div); memberList.add(writer.getMemberListItem(methodContent)); + writer.tableOfContents.addLink(htmlIds.forMember(currentMethod), + Text.of(utils.getSimpleName(method) + + utils.makeSignature(currentMethod, typeElement, false, true))); } Content methodDetails = getMethodDetails(methodDetailsHeader, memberList); detailsList.add(methodDetails); + writer.tableOfContents.popNestedList(); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java index c9e1f4afaaf..bf362e478ff 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -251,8 +251,11 @@ public class ModuleWriter extends HtmlDocletWriter { * be added */ protected void buildModuleDescription(Content moduleContent) { + tableOfContents.addLink(HtmlIds.TOP_OF_PAGE, contents.navDescription); if (!options.noComment()) { + tableOfContents.pushNestedList(); addModuleDescription(moduleContent); + tableOfContents.popNestedList(); } } @@ -274,16 +277,10 @@ public class ModuleWriter extends HtmlDocletWriter { @Override protected Navigation getNavBar(PageMode pageMode, Element element) { return super.getNavBar(pageMode, element) - .setSubNavLinks(() -> List.of( - links.createLink(HtmlIds.MODULE_DESCRIPTION, contents.navDescription, - !utils.getFullBody(mdle).isEmpty() && !options.noComment()), - links.createLink(HtmlIds.MODULES, contents.navModules, - display(requires) || display(indirectModules)), - links.createLink(HtmlIds.PACKAGES, contents.navPackages, - display(packages) || display(indirectPackages) || display(indirectOpenPackages)), - links.createLink(HtmlIds.SERVICES, contents.navServices, - displayServices(uses, usesTrees) || displayServices(provides.keySet(), providesTrees)) - )); + .setSubNavLinks(List.of( + links.createLink(pathToRoot.resolve(docPaths.moduleSummary(mdle)), + Text.of(mdle.getQualifiedName()), + HtmlStyle.currentSelection, ""))); } protected Content getContentHeader() { @@ -536,6 +533,7 @@ public class ModuleWriter extends HtmlDocletWriter { protected void addModulesSummary(Content summariesList) { if (display(requires) || display(indirectModules)) { + tableOfContents.addLink(HtmlIds.MODULES, contents.navModules); TableHeader requiresTableHeader = new TableHeader(contents.modifierLabel, contents.moduleLabel, contents.descriptionLabel); @@ -580,6 +578,7 @@ public class ModuleWriter extends HtmlDocletWriter { protected void addPackagesSummary(Content summariesList) { if (display(packages) || display(indirectPackages) || display(indirectOpenPackages)) { + tableOfContents.addLink(HtmlIds.PACKAGES, contents.navPackages); var section = HtmlTree.SECTION(HtmlStyle.packagesSummary) .setId(HtmlIds.PACKAGES); addSummaryHeader(MarkerComments.START_OF_PACKAGES_SUMMARY, contents.navPackages, section); @@ -750,6 +749,7 @@ public class ModuleWriter extends HtmlDocletWriter { boolean haveProvides = displayServices(provides.keySet(), providesTrees); if (haveProvides || haveUses) { + tableOfContents.addLink(HtmlIds.SERVICES, contents.navServices); var section = HtmlTree.SECTION(HtmlStyle.servicesSummary) .setId(HtmlIds.SERVICES); addSummaryHeader(MarkerComments.START_OF_SERVICES_SUMMARY, contents.navServices, section); @@ -889,6 +889,7 @@ public class ModuleWriter extends HtmlDocletWriter { protected void addModuleContent(Content source) { bodyContents.addMainContent(source); + bodyContents.setSideContent(tableOfContents.toContent(false)); } protected void addModuleFooter() { 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 9b5b5fc0848..82ae036ee83 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 @@ -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 @@ -27,7 +27,6 @@ package jdk.javadoc.internal.doclets.formats.html; import java.util.ArrayList; import java.util.List; -import java.util.Set; import javax.lang.model.element.Element; import javax.lang.model.element.ModuleElement; @@ -67,14 +66,9 @@ public class Navigation { private final DocPath pathToRoot; private final Links links; private final PageMode documentedPage; - private Content navLinkModule; - private Content navLinkPackage; - private Content navLinkClass; private Content userHeader; private final String rowListTitle; - private final Content searchLabel; - private final String searchPlaceholder; - private SubNavLinks subNavLinks; + private List subNavLinks = List.of(); public enum PageMode { ALL_CLASSES, @@ -99,18 +93,6 @@ public class Navigation { USE } - /** - * An interface to provide links for the subnavigation area. - */ - public interface SubNavLinks { - /** - * {@return a list of links to display in the subnavigation area} - * Links should be wrapped in {@code HtmlTree.LI} elements as they are - * displayed within an unordered list. - */ - List getSubNavLinks(); - } - /** * Creates a {@code Navigation} object for a specific file, to be written in a specific HTML * version. @@ -131,23 +113,6 @@ public class Navigation { this.pathToRoot = path.parent().invert(); this.links = new Links(path); this.rowListTitle = configuration.getDocResources().getText("doclet.Navigation"); - this.searchLabel = contents.getContent("doclet.search"); - this.searchPlaceholder = configuration.getDocResources().getText("doclet.search_placeholder"); - } - - public Navigation setNavLinkModule(Content navLinkModule) { - this.navLinkModule = navLinkModule; - return this; - } - - public Navigation setNavLinkPackage(Content navLinkPackage) { - this.navLinkPackage = navLinkPackage; - return this; - } - - public Navigation setNavLinkClass(Content navLinkClass) { - this.navLinkClass = navLinkClass; - return this; } public Navigation setUserHeader(Content userHeader) { @@ -155,7 +120,7 @@ public class Navigation { return this; } - public Navigation setSubNavLinks(SubNavLinks subNavLinks) { + public Navigation setSubNavLinks(List subNavLinks) { this.subNavLinks = subNavLinks; return this; } @@ -169,35 +134,28 @@ public class Navigation { switch (documentedPage) { case OVERVIEW: addActivePageLink(target, contents.overviewLabel, options.createOverview()); - addModuleLink(target); - addPackageLink(target); - addPageLabel(target, contents.classLabel, true); - addPageLabel(target, contents.useLabel, options.classUse()); addTreeLink(target); addPreviewLink(target); addNewLink(target); addDeprecatedLink(target); addIndexLink(target); + addSearchLink(target); addHelpLink(target); break; case MODULE: addOverviewLink(target); addActivePageLink(target, contents.moduleLabel, configuration.showModules); - addPackageLink(target); - addPageLabel(target, contents.classLabel, true); - addPageLabel(target, contents.useLabel, options.classUse()); addTreeLink(target); addPreviewLink(target); addNewLink(target); addDeprecatedLink(target); addIndexLink(target); + addSearchLink(target); addHelpLink(target); break; case PACKAGE: addOverviewLink(target); - addModuleOfElementLink(target); addActivePageLink(target, contents.packageLabel, true); - addPageLabel(target, contents.classLabel, true); if (options.classUse()) { addItemToList(target, links.createLink(DocPaths.PACKAGE_USE, contents.useLabel, "")); @@ -210,12 +168,11 @@ public class Navigation { addNewLink(target); addDeprecatedLink(target); addIndexLink(target); + addSearchLink(target); addHelpLink(target); break; case CLASS: addOverviewLink(target); - addModuleOfElementLink(target); - addPackageSummaryLink(target); addActivePageLink(target, contents.classLabel, true); if (options.classUse()) { addItemToList(target, links.createLink(DocPaths.CLASS_USE.resolve(path.basename()), @@ -229,48 +186,49 @@ public class Navigation { addNewLink(target); addDeprecatedLink(target); addIndexLink(target); + addSearchLink(target); addHelpLink(target); break; case USE: addOverviewLink(target); - addModuleOfElementLink(target); - if (element instanceof PackageElement) { - addPackageSummaryLink(target); - addPageLabel(target, contents.classLabel, true); - } else { - addPackageOfElementLink(target); - addItemToList(target, navLinkClass); + // Class-use page is still generated for deprecated classes with + // -nodeprecated option, make sure not to link to non-existent page. + if (!options.noDeprecated() || !configuration.utils.isDeprecated(element)) { + addPageElementLink(target); } addActivePageLink(target, contents.useLabel, options.classUse()); - if (element instanceof PackageElement) { - addItemToList(target, links.createLink(DocPaths.PACKAGE_TREE, contents.treeLabel)); - } else { - addItemToList(target, configuration.utils.isEnclosingPackageIncluded((TypeElement) element) - ? links.createLink(DocPath.parent.resolve(DocPaths.PACKAGE_TREE), contents.treeLabel) - : links.createLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), contents.treeLabel)); + if (options.createTree()) { + if (configuration.utils.isPackage(element)) { + addItemToList(target, links.createLink(DocPaths.PACKAGE_TREE, contents.treeLabel)); + } else { + addItemToList(target, configuration.utils.isEnclosingPackageIncluded((TypeElement) element) + ? links.createLink(DocPath.parent.resolve(DocPaths.PACKAGE_TREE), contents.treeLabel) + : links.createLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), contents.treeLabel)); + } } addPreviewLink(target); addNewLink(target); addDeprecatedLink(target); addIndexLink(target); + addSearchLink(target); addHelpLink(target); break; case TREE: addOverviewLink(target); - if (element == null) { - addPageLabel(target, contents.moduleLabel, configuration.showModules); - addPageLabel(target, contents.packageLabel, true); - } else { - addModuleOfElementLink(target); - addPackageSummaryLink(target); + if (element != null && !configuration.utils.isModule(element)) { + addPageElementLink(target); + if (options.classUse()) { + if (configuration.utils.isPackage(element) || configuration.utils.isTypeElement(element)) { + addItemToList(target, links.createLink(DocPaths.PACKAGE_USE, contents.useLabel)); + } + } } - addPageLabel(target, contents.classLabel, true); - addPageLabel(target, contents.useLabel, options.classUse()); addActivePageLink(target, contents.treeLabel, options.createTree()); addPreviewLink(target); addNewLink(target); addDeprecatedLink(target); addIndexLink(target); + addSearchLink(target); addHelpLink(target); break; case DEPRECATED: @@ -278,11 +236,8 @@ public class Navigation { case HELP: case PREVIEW: case NEW: + case SEARCH: addOverviewLink(target); - addModuleLink(target); - addPackageLink(target); - addPageLabel(target, contents.classLabel, true); - addPageLabel(target, contents.useLabel, options.classUse()); addTreeLink(target); if (documentedPage == PageMode.PREVIEW) { addActivePageLink(target, contents.previewLabel, @@ -307,6 +262,11 @@ public class Navigation { } else { addIndexLink(target); } + if (documentedPage == PageMode.SEARCH) { + addActivePageLink(target, contents.searchLabel, options.createIndex()); + } else { + addSearchLink(target); + } if (documentedPage == PageMode.HELP) { addActivePageLink(target, contents.helpLabel, !options.noHelp()); } else { @@ -319,31 +279,40 @@ public class Navigation { case EXTERNAL_SPECS: case RESTRICTED: case SERIALIZED_FORM: - case SEARCH: case SYSTEM_PROPERTIES: addOverviewLink(target); - addModuleLink(target); - addPackageLink(target); - addPageLabel(target, contents.classLabel, true); - addPageLabel(target, contents.useLabel, options.classUse()); addTreeLink(target); addPreviewLink(target); addNewLink(target); addDeprecatedLink(target); addIndexLink(target); + addSearchLink(target); addHelpLink(target); break; case DOC_FILE: addOverviewLink(target); - addModuleOfElementLink(target); - addItemToList(target, navLinkPackage); - addPageLabel(target, contents.classLabel, true); - addPageLabel(target, contents.useLabel, options.classUse()); - addTreeLink(target); + if (element != null) { + addPageElementLink(target); + if (options.classUse()) { + if (configuration.utils.isPackage(element)) { + addItemToList(target, links.createLink(pathToRoot.resolve( + configuration.docPaths.forPackage((PackageElement) element) + .resolve(DocPaths.PACKAGE_USE)), contents.useLabel)); + } + } + if (options.createTree() && configuration.utils.isPackage(element)) { + addItemToList(target, links.createLink(pathToRoot.resolve( + configuration.docPaths.forPackage((PackageElement) element) + .resolve(DocPaths.PACKAGE_TREE)), contents.treeLabel)); + } else { + addTreeLink(target); + } + } addPreviewLink(target); addNewLink(target); addDeprecatedLink(target); addIndexLink(target); + addSearchLink(target); addHelpLink(target); break; default: @@ -355,59 +324,11 @@ public class Navigation { * Adds the summary links to the subnavigation. * * @param target the content to which the subnavigation will be added - * @param nested whether to create a flat or nested list */ - private void addSummaryLinks(Content target, boolean nested) { - switch (documentedPage) { - case MODULE, PACKAGE, CLASS, HELP -> { - List listContents = subNavLinks.getSubNavLinks() - .stream().map(HtmlTree::LI).toList(); - if (!listContents.isEmpty()) { - Content label = switch (documentedPage) { - case MODULE -> contents.moduleSubNavLabel; - case PACKAGE -> contents.packageSubNavLabel; - case CLASS -> contents.summaryLabel; - case HELP -> contents.helpSubNavLabel; - default -> Text.EMPTY; - }; - if (nested) { - target.add(HtmlTree.LI(HtmlTree.P(label)) - .add(new HtmlTree(TagName.UL).add(listContents))); - } else { - target.add(HtmlTree.LI(label).add(Entity.NO_BREAK_SPACE)); - addListToNav(listContents, target); - } - } - } - } - } - - /** - * Adds the detail links to subnavigation. - * - * @param target the content to which the links will be added - * @param nested whether to create a flat or nested list - */ - private void addDetailLinks(Content target, boolean nested) { - if (documentedPage == PageMode.CLASS) { - List listContents = new ArrayList<>(); - VisibleMemberTable vmt = configuration.getVisibleMemberTable((TypeElement) element); - Set detailSet = VisibleMemberTable.Kind.forDetailsOf(element.getKind()); - for (VisibleMemberTable.Kind kind : detailSet) { - addTypeDetailLink(kind, !vmt.getVisibleMembers(kind).isEmpty(), listContents); - } - if (!listContents.isEmpty()) { - if (nested) { - var li = HtmlTree.LI(HtmlTree.P(contents.detailLabel)); - li.add(new HtmlTree(TagName.UL).add(listContents)); - target.add(li); - } else { - var li = HtmlTree.LI(contents.detailLabel); - li.add(Entity.NO_BREAK_SPACE); - target.add(li); - addListToNav(listContents, target); - } - } + private void addSummaryLinks(Content target) { + List listContents = subNavLinks.stream().map(HtmlTree::LI).toList(); + if (!listContents.isEmpty()) { + addListToNav(listContents, target); } } @@ -420,12 +341,12 @@ public class Navigation { */ protected void addTypeDetailLink(VisibleMemberTable.Kind kind, boolean link, List listContents) { addContentToList(listContents, switch (kind) { - case CONSTRUCTORS -> links.createLink(HtmlIds.CONSTRUCTOR_DETAIL, contents.navConstructor, link); - case ENUM_CONSTANTS -> links.createLink(HtmlIds.ENUM_CONSTANT_DETAIL, contents.navEnum, link); - case FIELDS -> links.createLink(HtmlIds.FIELD_DETAIL, contents.navField, link); - case METHODS -> links.createLink(HtmlIds.METHOD_DETAIL, contents.navMethod, link); - case PROPERTIES -> links.createLink(HtmlIds.PROPERTY_DETAIL, contents.navProperty, link); - case ANNOTATION_TYPE_MEMBER -> links.createLink(HtmlIds.ANNOTATION_TYPE_ELEMENT_DETAIL, + case CONSTRUCTORS -> links.createLinkOrLabel(HtmlIds.CONSTRUCTOR_DETAIL, contents.navConstructor, link); + case ENUM_CONSTANTS -> links.createLinkOrLabel(HtmlIds.ENUM_CONSTANT_DETAIL, contents.navEnum, link); + case FIELDS -> links.createLinkOrLabel(HtmlIds.FIELD_DETAIL, contents.navField, link); + case METHODS -> links.createLinkOrLabel(HtmlIds.METHOD_DETAIL, contents.navMethod, link); + case PROPERTIES -> links.createLinkOrLabel(HtmlIds.PROPERTY_DETAIL, contents.navProperty, link); + case ANNOTATION_TYPE_MEMBER -> links.createLinkOrLabel(HtmlIds.ANNOTATION_TYPE_ELEMENT_DETAIL, contents.navAnnotationTypeMember, link); default -> Text.EMPTY; }); @@ -441,14 +362,11 @@ public class Navigation { private void addListToNav(List listContents, Content target) { int count = 0; - for (Content liContent : listContents) { - if (count < listContents.size() - 1) { - liContent.add(Entity.NO_BREAK_SPACE); - liContent.add("|"); - liContent.add(Entity.NO_BREAK_SPACE); + for (Content item : listContents) { + target.add(item); + if (count++ < listContents.size() - 1) { + target.add(Entity.NO_BREAK_SPACE).add(Entity.of("gt")).add(Entity.NO_BREAK_SPACE); } - target.add(liContent); - count++; } } @@ -458,41 +376,25 @@ public class Navigation { } } - private void addPageLabel(Content target, Content label, boolean display) { - if (display) { - target.add(HtmlTree.LI(label)); - } - } - + /** + * Adds a link to the overview page if indicated by the configuration. + * Otherwise a link to the first module or package is added. + * + * @param target content to add the link to + */ private void addOverviewLink(Content target) { if (options.createOverview()) { target.add(HtmlTree.LI(links.createLink(pathToRoot.resolve(DocPaths.INDEX), contents.overviewLabel, ""))); - } - } - - private void addModuleLink(Content target) { - if (configuration.showModules) { - if (configuration.modules.size() == 1) { - ModuleElement mdle = configuration.modules.first(); + } else if (configuration.showModules && configuration.modules.size() > 0) { + ModuleElement mdle = configuration.modules.first(); + if (!mdle.equals(element)) { boolean included = configuration.utils.isIncluded(mdle); target.add(HtmlTree.LI((included) ? links.createLink(pathToRoot.resolve(configuration.docPaths.moduleSummary(mdle)), contents.moduleLabel, "") : contents.moduleLabel)); - } else if (!configuration.modules.isEmpty()) { - addPageLabel(target, contents.moduleLabel, true); } - } - } - - private void addModuleOfElementLink(Content target) { - if (configuration.showModules) { - target.add(HtmlTree.LI(navLinkModule)); - } - } - - private void addPackageLink(Content target) { - if (configuration.packages.size() == 1) { + } else if (configuration.packages.size() > 0 && !(element instanceof PackageElement)) { PackageElement packageElement = configuration.packages.first(); boolean included = packageElement != null && configuration.utils.isIncluded(packageElement); if (!included) { @@ -512,22 +414,23 @@ public class Navigation { packageElement, pathToRoot, DocPaths.PACKAGE_SUMMARY.getPath()); if (crossPkgLink != null) { target.add(HtmlTree.LI(links.createLink(crossPkgLink, contents.packageLabel))); - } else { - target.add(HtmlTree.LI(contents.packageLabel)); } } - } else if (!configuration.packages.isEmpty()) { - addPageLabel(target, contents.packageLabel, true); } } - private void addPackageOfElementLink(Content target) { - target.add(HtmlTree.LI(links.createLink(DocPath.parent.resolve(DocPaths.PACKAGE_SUMMARY), - contents.packageLabel))); - } - private void addPackageSummaryLink(Content target) { - target.add(HtmlTree.LI(links.createLink(DocPaths.PACKAGE_SUMMARY, contents.packageLabel))); + private void addPageElementLink(Content list) { + Content link = switch (element) { + case ModuleElement mdle -> links.createLink(pathToRoot.resolve( + configuration.docPaths.moduleSummary(mdle)), contents.moduleLabel); + case PackageElement pkg -> links.createLink(pathToRoot.resolve( + configuration.docPaths.forPackage(pkg).resolve(DocPaths.PACKAGE_SUMMARY)), contents.packageLabel); + case TypeElement type -> links.createLink(pathToRoot.resolve( + configuration.docPaths.forClass(type)), contents.classLabel); + default -> throw new RuntimeException(); + }; + list.add(HtmlTree.LI(link)); } private void addTreeLink(Content target) { @@ -571,6 +474,13 @@ public class Navigation { } } + private void addSearchLink(Content target) { + if (options.createIndex()) { + target.add(HtmlTree.LI(links.createLink( + pathToRoot.resolve(DocPaths.SEARCH_PAGE), contents.searchLabel, ""))); + } + } + private void addHelpLink(Content target) { if (!options.noHelp()) { String helpfile = options.helpFile(); @@ -588,16 +498,17 @@ public class Navigation { } private void addSearch(Content target) { - String reset = "reset"; - var inputText = HtmlTree.INPUT("text", HtmlIds.SEARCH_INPUT) - .put(HtmlAttr.PLACEHOLDER, searchPlaceholder); - var inputReset = HtmlTree.INPUT(reset, HtmlIds.RESET_BUTTON) - .put(HtmlAttr.VALUE, reset); - var searchDiv = HtmlTree.DIV(HtmlStyle.navListSearch, - links.createLink(pathToRoot.resolve(DocPaths.SEARCH_PAGE), - searchLabel, "")); - searchDiv.add(inputText); - searchDiv.add(inputReset); + var resources = configuration.getDocResources(); + var inputText = HtmlTree.INPUT(HtmlAttr.InputType.TEXT, HtmlIds.SEARCH_INPUT) + .put(HtmlAttr.PLACEHOLDER, resources.getText("doclet.search_placeholder")) + .put(HtmlAttr.ARIA_LABEL, resources.getText("doclet.search_in_documentation")) + .put(HtmlAttr.AUTOCOMPLETE, "off") + .put(HtmlAttr.AUTOCAPITALIZE, "off"); + var inputReset = HtmlTree.INPUT(HtmlAttr.InputType.RESET, HtmlIds.RESET_SEARCH) + .put(HtmlAttr.VALUE, resources.getText("doclet.search_reset")); + var searchDiv = HtmlTree.DIV(HtmlStyle.navListSearch) + .add(inputText) + .add(inputReset); target.add(searchDiv); } @@ -612,58 +523,46 @@ public class Navigation { } var navigationBar = HtmlTree.NAV(); - var navDiv = new HtmlTree(TagName.DIV); + var navContent = new HtmlTree(TagName.DIV); Content skipNavLinks = contents.getContent("doclet.Skip_navigation_links"); String toggleNavLinks = configuration.getDocResources().getText("doclet.Toggle_navigation_links"); navigationBar.add(MarkerComments.START_OF_TOP_NAVBAR); // The mobile menu button uses three empty spans to produce its animated icon HtmlTree iconSpan = HtmlTree.SPAN(HtmlStyle.navBarToggleIcon).add(Entity.NO_BREAK_SPACE); - navDiv.setStyle(HtmlStyle.topNav) - .setId(HtmlIds.NAVBAR_TOP) - .add(new HtmlTree(TagName.BUTTON).setId(HtmlIds.NAVBAR_TOGGLE_BUTTON) - .put(HtmlAttr.ARIA_CONTROLS, HtmlIds.NAVBAR_TOP.name()) - .put(HtmlAttr.ARIA_EXPANDED, String.valueOf(false)) - .put(HtmlAttr.ARIA_LABEL, toggleNavLinks) - .add(iconSpan) - .add(iconSpan) - .add(iconSpan)) + navContent.setStyle(HtmlStyle.navContent).add(HtmlTree.DIV(HtmlStyle.navMenuButton, + new HtmlTree(TagName.BUTTON).setId(HtmlIds.NAVBAR_TOGGLE_BUTTON) + .put(HtmlAttr.ARIA_CONTROLS, HtmlIds.NAVBAR_TOP.name()) + .put(HtmlAttr.ARIA_EXPANDED, String.valueOf(false)) + .put(HtmlAttr.ARIA_LABEL, toggleNavLinks) + .add(iconSpan) + .add(iconSpan) + .add(iconSpan))) .add(HtmlTree.DIV(HtmlStyle.skipNav, links.createLink(HtmlIds.SKIP_NAVBAR_TOP, skipNavLinks, skipNavLinks.toString()))); Content aboutContent = userHeader; - boolean addSearch = options.createIndex() && documentedPage != PageMode.SEARCH; - var aboutDiv = HtmlTree.DIV(HtmlStyle.aboutLanguage, aboutContent); - navDiv.add(aboutDiv); var navList = new HtmlTree(TagName.UL) .setId(HtmlIds.NAVBAR_TOP_FIRSTROW) .setStyle(HtmlStyle.navList) .put(HtmlAttr.TITLE, rowListTitle); addMainNavLinks(navList); - navDiv.add(navList); - var ulNavSummaryRight = HtmlTree.UL(HtmlStyle.subNavListSmall); - addSummaryLinks(ulNavSummaryRight, true); - addDetailLinks(ulNavSummaryRight, true); - navDiv.add(ulNavSummaryRight); - navigationBar.add(navDiv); + navContent.add(navList); + var aboutDiv = HtmlTree.DIV(HtmlStyle.aboutLanguage, aboutContent); + navContent.add(aboutDiv); + navigationBar.add(HtmlTree.DIV(HtmlStyle.topNav, navContent).setId(HtmlIds.NAVBAR_TOP)); - var subDiv = HtmlTree.DIV(HtmlStyle.subNav); + var subNavContent = HtmlTree.DIV(HtmlStyle.navContent); - var div = new HtmlTree(TagName.DIV).setId(HtmlIds.NAVBAR_SUB_LIST); - // Add the summary links if present. - var ulNavSummary = HtmlTree.UL(HtmlStyle.subNavList); - addSummaryLinks(ulNavSummary, false); - div.add(ulNavSummary); - // Add the detail links if present. - var ulNavDetail = HtmlTree.UL(HtmlStyle.subNavList); - addDetailLinks(ulNavDetail, false); - div.add(ulNavDetail); - subDiv.add(div); + // Add the breadcrumb navigation links if present. + var ulBreadcrumbNav = HtmlTree.OL(HtmlStyle.subNavList); + addSummaryLinks(ulBreadcrumbNav); + subNavContent.addUnchecked(ulBreadcrumbNav); - if (addSearch) { - addSearch(subDiv); + if (options.createIndex() && documentedPage != PageMode.SEARCH) { + addSearch(subNavContent); } - navigationBar.add(subDiv); + navigationBar.add(HtmlTree.DIV(HtmlStyle.subNav, subNavContent)); navigationBar.add(MarkerComments.END_OF_TOP_NAVBAR); navigationBar.add(HtmlTree.SPAN(HtmlStyle.skipNav) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NewAPIListWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NewAPIListWriter.java index 901b5e6e8c4..d035e0f1d95 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NewAPIListWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NewAPIListWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -88,7 +88,7 @@ public class NewAPIListWriter extends SummaryListWriter { String release = releases.get(i); HtmlId htmlId = HtmlId.of("release-" + releaseIndex); tabs.add(Text.of(" ")).add(HtmlTree.LABEL(htmlId.name(), - HtmlTree.INPUT("checkbox", htmlId) + HtmlTree.INPUT(HtmlAttr.InputType.CHECKBOX, htmlId) .put(HtmlAttr.CHECKED, "") .put(HtmlAttr.ONCLICK, "toggleGlobal(this, '" + releaseIndex + "', 3)")) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java index 5627ebdcc5a..1ee24042002 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -33,10 +33,14 @@ import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; +import jdk.javadoc.internal.doclets.formats.html.markup.Text; import jdk.javadoc.internal.doclets.toolkit.util.ClassTree; import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; +import java.util.ArrayList; +import java.util.List; + /** * Class to generate Tree page for a package. The name of the file generated is @@ -128,10 +132,14 @@ public class PackageTreeWriter extends AbstractTreeWriter { @Override protected Navigation getNavBar(PageMode pageMode, Element element) { - Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement), - contents.moduleLabel); - return super.getNavBar(pageMode, element) - .setNavLinkModule(linkContent); + List subnavLinks = new ArrayList<>(); + if (configuration.showModules) { + var mdle = utils.elementUtils.getModuleOf(packageElement); + subnavLinks.add(getModuleLink(mdle, Text.of(mdle.getQualifiedName()))); + } + subnavLinks.add(links.createLink(pathString(packageElement, DocPaths.PACKAGE_SUMMARY), + getLocalizedPackageName(packageElement), HtmlStyle.currentSelection, "")); + return super.getNavBar(pageMode, element).setSubNavLinks(subnavLinks); } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java index cdd531af4a0..75009ad2066 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -25,6 +25,8 @@ package jdk.javadoc.internal.doclets.formats.html; +import java.util.ArrayList; +import java.util.List; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; @@ -216,9 +218,13 @@ public class PackageUseWriter extends SubWriterHolderWriter { @Override protected Navigation getNavBar(PageMode pageMode, Element element) { - Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(element), - contents.moduleLabel); - return super.getNavBar(pageMode, element) - .setNavLinkModule(linkContent); + List subnavLinks = new ArrayList<>(); + if (configuration.showModules) { + var mdle = utils.elementUtils.getModuleOf(packageElement); + subnavLinks.add(getModuleLink(mdle, Text.of(mdle.getQualifiedName()))); + } + subnavLinks.add(links.createLink(pathString(packageElement, DocPaths.PACKAGE_SUMMARY), + getLocalizedPackageName(packageElement), HtmlStyle.currentSelection, "")); + return super.getNavBar(pageMode, element).setSubNavLinks(subnavLinks); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriter.java index 55be119f350..f9d3164a1d5 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -42,7 +42,6 @@ import com.sun.source.doctree.DeprecatedTree; import com.sun.source.doctree.DocTree; import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; -import jdk.javadoc.internal.doclets.formats.html.markup.Entity; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.TagName; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; @@ -72,7 +71,7 @@ public class PackageWriter extends HtmlDocletWriter { /** * The HTML element for the section tag being written. */ - private final HtmlTree section = HtmlTree.SECTION(HtmlStyle.packageDescription); + private final HtmlTree section = HtmlTree.SECTION(HtmlStyle.packageDescription, new ContentBuilder()); private final BodyContents bodyContents = new BodyContents(); @@ -179,9 +178,13 @@ public class PackageWriter extends HtmlDocletWriter { * be added */ protected void buildPackageDescription(Content packageContent) { - if (!options.noComment()) { - addPackageDescription(packageContent); + tableOfContents.addLink(HtmlIds.TOP_OF_PAGE, contents.navDescription); + if (options.noComment()) { + return; } + tableOfContents.pushNestedList(); + addPackageDescription(packageContent); + tableOfContents.popNestedList(); } /** @@ -190,24 +193,16 @@ public class PackageWriter extends HtmlDocletWriter { * @param packageContent the content to which the package tags will be added */ protected void buildPackageTags(Content packageContent) { - if (!options.noComment()) { - addPackageTags(packageContent); + if (options.noComment()) { + return; } + addPackageTags(packageContent); } protected Content getPackageHeader() { String packageName = getLocalizedPackageName(packageElement).toString(); HtmlTree body = getBody(getWindowTitle(packageName)); var div = HtmlTree.DIV(HtmlStyle.header); - if (configuration.showModules) { - ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(packageElement); - var classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInPackage, contents.moduleLabel); - var moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classModuleLabel); - moduleNameDiv.add(Entity.NO_BREAK_SPACE); - moduleNameDiv.add(getModuleLink(mdle, - Text.of(mdle.getQualifiedName().toString()))); - div.add(moduleNameDiv); - } Content packageHead = new ContentBuilder(); if (!packageElement.isUnnamed()) { packageHead.add(contents.packageLabel).add(" "); @@ -275,17 +270,15 @@ public class PackageWriter extends HtmlDocletWriter { @Override protected Navigation getNavBar(PageMode pageMode, Element element) { - Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement), - contents.moduleLabel); - return super.getNavBar(pageMode, element) - .setNavLinkModule(linkContent) - .setSubNavLinks(() -> List.of( - links.createLink(HtmlIds.PACKAGE_DESCRIPTION, contents.navDescription, - !utils.getFullBody(packageElement).isEmpty() && !options.noComment()), - links.createLink(HtmlIds.RELATED_PACKAGE_SUMMARY, contents.relatedPackages, - relatedPackages != null && !relatedPackages.isEmpty()), - links.createLink(HtmlIds.CLASS_SUMMARY, contents.navClassesAndInterfaces, - allClasses != null && !allClasses.isEmpty()))); + List subnavLinks = new ArrayList<>(); + if (configuration.showModules) { + ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(packageElement); + subnavLinks.add(links.createLink(pathToRoot.resolve(docPaths.moduleSummary(mdle)), + Text.of(mdle.getQualifiedName()))); + } + subnavLinks.add(links.createLink(pathString(packageElement, DocPaths.PACKAGE_SUMMARY), + getLocalizedPackageName(packageElement), HtmlStyle.currentSelection, "")); + return super.getNavBar(pageMode, element).setSubNavLinks(subnavLinks); } /** @@ -319,8 +312,7 @@ public class PackageWriter extends HtmlDocletWriter { TableHeader tableHeader= showModules ? new TableHeader(contents.moduleLabel, contents.packageLabel, contents.descriptionLabel) : new TableHeader(contents.packageLabel, contents.descriptionLabel); - addPackageSummary(relatedPackages, contents.relatedPackages, tableHeader, - summaryContent, showModules); + addRelatedPackageSummary(tableHeader, summaryContent, showModules); } /** @@ -359,17 +351,18 @@ public class PackageWriter extends HtmlDocletWriter { } } if (!table.isEmpty()) { + tableOfContents.addLink(HtmlIds.CLASS_SUMMARY, contents.navClassesAndInterfaces); target.add(HtmlTree.LI(table)); } } - protected void addPackageSummary(List packages, Content label, - TableHeader tableHeader, Content summaryContent, - boolean showModules) { - if (!packages.isEmpty()) { + protected void addRelatedPackageSummary(TableHeader tableHeader, Content summaryContent, + boolean showModules) { + if (!relatedPackages.isEmpty()) { + tableOfContents.addLink(HtmlIds.RELATED_PACKAGE_SUMMARY, contents.relatedPackages); var table = new Table(HtmlStyle.summaryTable) .setId(HtmlIds.RELATED_PACKAGE_SUMMARY) - .setCaption(label) + .setCaption(contents.relatedPackages) .setHeader(tableHeader); if (showModules) { table.setColumnStyles(HtmlStyle.colPlain, HtmlStyle.colFirst, HtmlStyle.colLast); @@ -377,7 +370,7 @@ public class PackageWriter extends HtmlDocletWriter { table.setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast); } - for (PackageElement pkg : packages) { + for (PackageElement pkg : relatedPackages) { Content packageLink = getPackageLink(pkg, Text.of(pkg.getQualifiedName())); Content moduleLink = Text.EMPTY; if (showModules) { @@ -427,6 +420,7 @@ public class PackageWriter extends HtmlDocletWriter { protected void addPackageContent(Content packageContent) { bodyContents.addMainContent(packageContent); + bodyContents.setSideContent(tableOfContents.toContent(false)); } protected void addPackageFooter() { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PreviewListWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PreviewListWriter.java index 6003d3215f2..0f14098a326 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PreviewListWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PreviewListWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -88,7 +88,7 @@ public class PreviewListWriter extends SummaryListWriter HtmlId htmlId = HtmlId.of("feature-" + index); String jepUrl = resources.getText("doclet.Preview_JEP_URL", jep.number()); list.add(HtmlTree.LI(HtmlTree.LABEL(htmlId.name(), - HtmlTree.INPUT("checkbox", htmlId) + HtmlTree.INPUT(HtmlAttr.InputType.CHECKBOX, htmlId) .put(HtmlAttr.CHECKED, "") .put(HtmlAttr.ONCLICK, "toggleGlobal(this, '" + index + "', 3)")) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriter.java index a78fe0a484c..41a59c8a30c 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -74,6 +74,8 @@ public class PropertyWriter extends AbstractMemberWriter { if (!properties.isEmpty()) { Content propertyDetailsHeader = getPropertyDetailsHeader(detailsList); Content memberList = getMemberList(); + writer.tableOfContents.addLink(HtmlIds.PROPERTY_DETAIL, contents.propertyDetailsLabel); + writer.tableOfContents.pushNestedList(); for (Element property : properties) { currentProperty = (ExecutableElement)property; @@ -86,9 +88,12 @@ public class PropertyWriter extends AbstractMemberWriter { buildTagInfo(div); propertyContent.add(div); memberList.add(getMemberListItem(propertyContent)); + writer.tableOfContents.addLink(htmlIds.forProperty(currentProperty), + Text.of(utils.getPropertyLabel(name(property)))); } Content propertyDetails = getPropertyDetails(propertyDetailsHeader, memberList); detailsList.add(propertyDetails); + writer.tableOfContents.popNestedList(); } } 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 938895d0678..feee351870b 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -81,9 +81,12 @@ public class SearchWriter extends HtmlDocletWriter { contentTree.add(HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, HtmlStyle.title, contents.getContent("doclet.search.main_heading"))) - .add(HtmlTree.DIV(HtmlTree.INPUT("text", HtmlId.of("page-search-input")) - .put(HtmlAttr.PLACEHOLDER, resources.getText("doclet.search_placeholder"))) - .add(HtmlTree.INPUT("reset", HtmlId.of("page-search-reset")) + .add(HtmlTree.DIV(HtmlTree.INPUT(HtmlAttr.InputType.TEXT, HtmlId.of("page-search-input")) + .put(HtmlAttr.PLACEHOLDER, resources.getText("doclet.search_placeholder")) + .put(HtmlAttr.ARIA_LABEL, resources.getText("doclet.search_in_documentation")) + .put(HtmlAttr.AUTOCOMPLETE, "off") + .put(HtmlAttr.AUTOCAPITALIZE, "off")) + .add(HtmlTree.INPUT(HtmlAttr.InputType.RESET, HtmlId.of("page-search-reset")) .put(HtmlAttr.VALUE, resources.getText("doclet.search_reset")) .put(HtmlAttr.STYLE, "margin: 6px;")) .add(HtmlTree.DETAILS(HtmlStyle.pageSearchDetails) @@ -104,7 +107,7 @@ public class SearchWriter extends HtmlDocletWriter { .addStyle(HtmlStyle.copy) .put(HtmlAttr.ARIA_LABEL, copyUrlText) .setId(HtmlId.of("page-search-copy"))) - .add(HtmlTree.P(HtmlTree.INPUT("checkbox", HtmlId.of("search-redirect"))) + .add(HtmlTree.P(HtmlTree.INPUT(HtmlAttr.InputType.CHECKBOX, HtmlId.of("search-redirect"))) .add(HtmlTree.LABEL("search-redirect", contents.getContent("doclet.search.redirect"))))) .add(new HtmlTree(TagName.P) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java index 08743dcba2f..3926d4e9a4c 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -187,10 +187,11 @@ public abstract class SubWriterHolderWriter extends HtmlDocletWriter { /** * Add the class content. * - * @param source class content which will be added to the documentation + * @param classContent class content which will be added to the documentation */ - public void addClassContent(Content source) { - bodyContents.addMainContent(source); + public void addClassContent(Content classContent) { + bodyContents.addMainContent(classContent); + bodyContents.setSideContent(tableOfContents.toContent(true)); } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SummaryListWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SummaryListWriter.java index f69d8078b47..c478907270c 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SummaryListWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SummaryListWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,6 @@ package jdk.javadoc.internal.doclets.formats.html; -import java.util.Arrays; import java.util.SortedSet; import javax.lang.model.element.Element; @@ -154,16 +153,14 @@ public abstract class SummaryListWriter extends // The script below enables checkboxes in the page and invokes their click handler // to restore any previous state when the page is loaded via back/forward button. bodyContents.addMainContent(new Script(""" - document.addEventListener("DOMContentLoaded", function(e) { - document.querySelectorAll('input[type="checkbox"]').forEach( - function(c) { + document.addEventListener("DOMContentLoaded", (e) => { + document.querySelectorAll('main input[type="checkbox"]').forEach((c) => { c.disabled = false; c.onclick(); }); }); window.addEventListener("load", function(e) { - document.querySelectorAll('input[type="checkbox"]').forEach( - function(c) { + document.querySelectorAll('main input[type="checkbox"]').forEach((c) => { c.onclick(); }); }); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TableOfContents.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TableOfContents.java new file mode 100644 index 00000000000..8d478f8fa02 --- /dev/null +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TableOfContents.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 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 jdk.javadoc.internal.doclets.formats.html.markup.Entity; +import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr; +import jdk.javadoc.internal.doclets.formats.html.markup.HtmlId; +import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; +import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; +import jdk.javadoc.internal.doclets.formats.html.markup.ListBuilder; +import jdk.javadoc.internal.doclets.formats.html.markup.TagName; +import jdk.javadoc.internal.doclets.formats.html.markup.Text; + +/** + * A class used by various {@link HtmlDocletWriter} subclasses to build tables of contents. + */ +public class TableOfContents { + private final ListBuilder listBuilder; + private final HtmlDocletWriter writer; + + /** + * Constructor + * @param writer the writer + */ + public TableOfContents(HtmlDocletWriter writer) { + this.writer = writer; + listBuilder = new ListBuilder(HtmlTree.OL(HtmlStyle.tocList)); + } + + /** + * Adds a link to the table of contents. + * @param id the link fragment + * @param label the link label + * @return this object + */ + public TableOfContents addLink(HtmlId id, Content label) { + listBuilder.add(writer.links.createLink(id, label).put(HtmlAttr.TABINDEX, "0")); + return this; + } + + /** + * Adds a new nested list to add new items to. + */ + public void pushNestedList() { + listBuilder.pushNestedList(HtmlTree.OL(HtmlStyle.tocList)); + } + + /** + * Closes the current nested list and go back to the parent list. + */ + public void popNestedList() { + listBuilder.popNestedList(); + } + + /** + * Returns a content object containing the table of contents, consisting + * of a header and the contents list itself. If the contents list is empty, + * an empty content object is returned. + * + * @param hasFilterInput whether to add a filter text input + * @return a content object + */ + protected Content toContent(boolean hasFilterInput) { + if (listBuilder.isEmpty()) { + return Text.EMPTY; + } + var content = HtmlTree.NAV() + .setStyle(HtmlStyle.toc) + .put(HtmlAttr.ARIA_LABEL, writer.resources.getText("doclet.table_of_contents")); + var header = HtmlTree.DIV(HtmlStyle.tocHeader, writer.contents.contentsHeading); + if (hasFilterInput) { + header.add(Entity.NO_BREAK_SPACE) + .add(HtmlTree.INPUT(HtmlAttr.InputType.TEXT, HtmlStyle.filterInput) + .put(HtmlAttr.PLACEHOLDER, writer.resources.getText("doclet.filter_label")) + .put(HtmlAttr.ARIA_LABEL, writer.resources.getText("doclet.filter_table_of_contents")) + .put(HtmlAttr.AUTOCOMPLETE, "off") + .put(HtmlAttr.AUTOCAPITALIZE, "off")) + .add(HtmlTree.INPUT(HtmlAttr.InputType.RESET, HtmlStyle.resetFilter) + .put(HtmlAttr.VALUE, writer.resources.getText("doclet.filter_reset"))); + } + content.add(header); + content.add(new HtmlTree(TagName.BUTTON).addStyle(HtmlStyle.hideSidebar) + .add(HtmlTree.SPAN(writer.contents.hideSidebar).add(Entity.NO_BREAK_SPACE)) + .add(Entity.LEFT_POINTING_ANGLE)); + content.add(new HtmlTree(TagName.BUTTON).addStyle(HtmlStyle.showSidebar) + .add(Entity.RIGHT_POINTING_ANGLE) + .add(HtmlTree.SPAN(Entity.NO_BREAK_SPACE).add(writer.contents.showSidebar))); + return content.add(listBuilder); + } + +} diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/BodyContents.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/BodyContents.java index b40514b4119..71bf1f265cf 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/BodyContents.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/BodyContents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -37,12 +37,14 @@ import java.util.Objects; * Content for the {@code } element. * * The content is a {@code
    } element that contains a - * header that is always visible, and main content that - * can be scrolled if necessary. + * header that is always visible, main content that + * can be scrolled if necessary, and optional side and footer + * contents that are only rendered if available. */ public class BodyContents extends Content { private final List mainContents = new ArrayList<>(); + private Content side = null; private Content header = null; private Content footer = null; @@ -51,6 +53,11 @@ public class BodyContents extends Content { return this; } + public BodyContents setSideContent(Content side) { + this.side = Objects.requireNonNull(side); + return this; + } + public BodyContents setHeader(Content header) { this.header = Objects.requireNonNull(header); return this; @@ -89,7 +96,10 @@ public class BodyContents extends Content { return new ContentBuilder() .add(header) - .add(HtmlTree.MAIN().add(mainContents)) - .add(footer == null ? Text.EMPTY : footer); + .add(HtmlTree.DIV(HtmlStyle.mainGrid) + .add(side == null ? Text.EMPTY : side) + .add(HtmlTree.MAIN() + .add(mainContents) + .add(footer == null ? Text.EMPTY : footer))); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Entity.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Entity.java index 50ee53a2c75..c96063d703f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Entity.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Entity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -38,6 +38,8 @@ public class Entity extends Content { public static final Entity GREATER_THAN = new Entity(">"); public static final Entity AMPERSAND = new Entity("&"); public static final Entity NO_BREAK_SPACE = new Entity(" "); + public static final Entity LEFT_POINTING_ANGLE = new Entity("❮"); + public static final Entity RIGHT_POINTING_ANGLE = new Entity("❯"); public final String text; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java index 2935cbf8616..77d09c7226e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -351,7 +351,7 @@ public class Head extends Content { if (index) { if (pathToRoot != null && mainBodyScript != null) { String ptrPath = pathToRoot.isEmpty() ? "." : pathToRoot.getPath(); - mainBodyScript.append("var pathtoroot = ") + mainBodyScript.append("const pathtoroot = ") .appendStringLiteral(ptrPath + "/") .append(";\n") .append("loadScripts(document, 'script');"); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlAttr.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlAttr.java index 0379d7ada61..8fe06640907 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlAttr.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -38,6 +38,8 @@ public enum HtmlAttr { ARIA_LABELLEDBY("aria-labelledby"), ARIA_ORIENTATION("aria-orientation"), ARIA_SELECTED("aria-selected"), + AUTOCOMPLETE, + AUTOCAPITALIZE, CHECKED, CLASS, CLEAR, @@ -91,6 +93,23 @@ public enum HtmlAttr { } } + public enum InputType { + + CHECKBOX, + RESET, + TEXT; + + private final String type; + + InputType() { + type = Utils.toLowerCase(name()); + } + + public String toString() { + return type; + } + } + HtmlAttr() { this.value = Utils.toLowerCase(name()); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java index c6e1263d665..35a52b0c05d 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -54,7 +54,13 @@ public enum HtmlStyle { // // // The following constants are used for the main navigation bar that appears in the - // {@code header} and {@code footer} elements on each page. + // {@code header} element on each page, as well as the side navigation bar that displays + // the table of contents on some pages. + + /** + * The class for the link representing the current element in breadcrumb navigation and table of contents. + */ + currentSelection, /** * The class for the overall {@code div} element containing the {@code header} element for the page. @@ -67,6 +73,21 @@ public enum HtmlStyle { */ aboutLanguage, + /** + * The class for the {@code input} element to filter items in the table of contents. + */ + filterInput, + + /** + * The class for the {@code button} element to hide the sidebar. + */ + hideSidebar, + + /** + * The class for the {@code div} element containing the sidebar and main content. + */ + mainGrid, + /** * The class for the highlighted item in the list of navigation links, indicating * the current page. @@ -79,6 +100,16 @@ public enum HtmlStyle { */ navBarToggleIcon, + /** + * The class for the {@code div} element containing navigation elements. + */ + navContent, + + /** + * The class for the {@code div} element containing the button to show or hide the menu. + */ + navMenuButton, + /** * The class for the primary list of navigation links. */ @@ -89,6 +120,16 @@ public enum HtmlStyle { */ navListSearch, + /** + * The class for the reset button in the sidebar filter input element. + */ + resetFilter, + + /** + * The class for the {@code button} element to show the sidebar. + */ + showSidebar, + /** * The class for a {@code div} element containing a link to skip the navigation header. * The element is typically invisible, but may be used when navigating the page @@ -107,9 +148,19 @@ public enum HtmlStyle { subNavList, /** - * The class for the list of subsidiary navigation links for smaller displays. + * The class for a {@code nav} element containing a table of contents. */ - subNavListSmall, + toc, + + /** + * The class for the {@code div} element representing the header of the table of contents. + */ + tocHeader, + + /** + * The class used for list elements in the table of contents. + */ + tocList, // @@ -124,21 +175,6 @@ public enum HtmlStyle { */ header, - /** - * The class for the "module" label in the heading for a package declaration. - */ - moduleLabelInPackage, - - /** - * The class for the "module" label in the heading for a type declaration. - */ - moduleLabelInType, - - /** - * The class for the "package" label in the heading for a type declaration. - */ - packageLabelInType, - /** * The class for the element containing the label and name for the module * or package that precedes the main title for the declaration of a diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java index d296aa4c83b..0ec4033a929 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -586,13 +586,26 @@ public class HtmlTree extends Content { * @param id the id * @return the element */ - public static HtmlTree INPUT(String type, HtmlId id) { + public static HtmlTree INPUT(HtmlAttr.InputType type, HtmlId id) { return new HtmlTree(TagName.INPUT) - .put(HtmlAttr.TYPE, type) + .put(HtmlAttr.TYPE, type.toString()) .setId(id) .put(HtmlAttr.DISABLED, ""); } + /** + * Creates an HTML {@code INPUT} element with the given type + * and style. The element is marked as initially disabled. + * @param type the input type + * @param style the input style + * @return the element + */ + public static HtmlTree INPUT(HtmlAttr.InputType type, HtmlStyle style) { + return new HtmlTree(TagName.INPUT) + .put(HtmlAttr.TYPE, type.toString()) + .setStyle(style) + .put(HtmlAttr.DISABLED, ""); + } /** * Creates an HTML {@code LABEL} element with the given content. * @@ -718,6 +731,17 @@ public class HtmlTree extends Content { .add(body); } + /** + * Creates an HTML {@code OL} element with the given style. + * + * @param style the style + * @return the element + */ + public static HtmlTree OL(HtmlStyle style) { + return new HtmlTree(TagName.OL) + .setStyle(style); + } + /** * Creates an HTML {@code P} element with some content. * diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java index cfdc3cda5c6..a0bd0b3dd04 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -53,7 +53,7 @@ public class Links { * @param label the content for the link * @return the link */ - public Content createLink(HtmlId id, Content label) { + public HtmlTree createLink(HtmlId id, Content label) { DocLink l = DocLink.fragment(id.name()); return createLink(l, label, ""); } @@ -67,7 +67,7 @@ public class Links { * @param link whether to create a link or just return the label * @return the link or just the label */ - public Content createLink(HtmlId id, Content label, boolean link) { + public Content createLinkOrLabel(HtmlId id, Content label, boolean link) { return link ? createLink(id, label) : label; } @@ -80,7 +80,7 @@ public class Links { * * @return the link */ - public Content createLink(HtmlId id, Content label, String title) { + public HtmlTree createLink(HtmlId id, Content label, String title) { DocLink l = DocLink.fragment(id.name()); return createLink(l, label, title); } @@ -92,7 +92,7 @@ public class Links { * @param label the content for the link * @return the link */ - public Content createLink(DocPath path, String label) { + public HtmlTree createLink(DocPath path, String label) { return createLink(path, Text.of(label), null, ""); } @@ -103,7 +103,7 @@ public class Links { * @param label the content for the link * @return the link */ - public Content createLink(DocPath path, Content label) { + public HtmlTree createLink(DocPath path, Content label) { return createLink(path, label, ""); } @@ -117,7 +117,7 @@ public class Links { * @param title the title for the link * @return the link */ - public Content createLink(DocPath path, Content label, HtmlStyle style, String title) { + public HtmlTree createLink(DocPath path, Content label, HtmlStyle style, String title) { return createLink(new DocLink(path), label, style, title); } @@ -129,7 +129,7 @@ public class Links { * @param title the title for the link * @return the link */ - public Content createLink(DocPath path, Content label, String title) { + public HtmlTree createLink(DocPath path, Content label, String title) { return createLink(new DocLink(path), label, title); } @@ -152,7 +152,7 @@ public class Links { * @param title the title for the link * @return the link */ - public Content createLink(DocLink link, Content label, String title) { + public HtmlTree createLink(DocLink link, Content label, String title) { var anchor = HtmlTree.A(link.relativizeAgainst(file).toString(), label); if (title != null && title.length() != 0) { anchor.put(HtmlAttr.TITLE, title); @@ -170,7 +170,7 @@ public class Links { * @param title the title for the link * @return the link */ - public Content createLink(DocLink link, Content label, HtmlStyle style, + public HtmlTree createLink(DocLink link, Content label, HtmlStyle style, String title) { return createLink(link, label, style, title, false); } @@ -186,7 +186,7 @@ public class Links { * @param isExternal is the link external to the generated documentation * @return the link */ - public Content createLink(DocLink link, Content label, HtmlStyle style, + public HtmlTree createLink(DocLink link, Content label, HtmlStyle style, String title, boolean isExternal) { var l = HtmlTree.A(link.relativizeAgainst(file).toString(), label); if (style != null) { @@ -209,7 +209,7 @@ public class Links { * @param label the content for the link * @return the link */ - public Content createExternalLink(DocLink link, Content label) { + public HtmlTree createExternalLink(DocLink link, Content label) { return HtmlTree.A(link.relativizeAgainst(file).toString(), label) .setStyle(HtmlStyle.externalLink); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/ListBuilder.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/ListBuilder.java new file mode 100644 index 00000000000..603e5717895 --- /dev/null +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/ListBuilder.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 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.markup; + +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.NoSuchElementException; +import java.util.Objects; + +import jdk.javadoc.internal.doclets.formats.html.Content; + +/** + * A utility class for building nested HTML lists. This class is implemented as a + * stack of nested list/item pairs where list items are added to the inner-most + * list and nested lists are added to the current list item of the inner-most list. + * Lists can be added to and removed from the stack using the {@link #pushNestedList} + * and {@link #popNestedList} methods. + */ +public class ListBuilder extends Content { + + private final HtmlTree root; + private record Pair(HtmlTree list, HtmlTree item) {} + private final Deque stack = new ArrayDeque<>(); + private HtmlTree currentList; + private HtmlTree currentItem; + + /** + * Creates a new list builder. + * + * @param list the root list element + */ + public ListBuilder(HtmlTree list) { + Objects.requireNonNull(list, "Root list element is required"); + root = currentList = list; + } + + /** + * Adds a new list item with the given content to the current list. The last added list item + * will also be used as container when pushing a new nested list. + * + * @param listItemContent the content for the new list item. + * @return this list builder + */ + public ListBuilder add(Content listItemContent) { + currentItem = HtmlTree.LI(listItemContent); + currentList.addUnchecked(currentItem); + return this; + } + + /** + * Adds a new nested list to the current list item and makes it the recipient for new list items. + * Note that the nested list is added even if empty; use {@code addNested} to avoid adding empty + * lists. + * + * @param list the nested list + * @return this list builder + */ + public ListBuilder pushNestedList(HtmlTree list) { + Objects.requireNonNull(currentItem, "List item required for nested list"); + stack.push(new Pair(currentList, currentItem)); + currentList = list; + currentItem = null; + return this; + } + + /** + * Pops the current list from the stack and returns to adding list items to the parent list. + * + * @return this list builder + * @throws NoSuchElementException if the stack is empty + */ + public ListBuilder popNestedList() { + Pair pair = stack.pop(); + // First restore currentItem and add nested list to it before restoring currentList to outer list. + currentItem = pair.item; + currentItem.add(currentList); + currentList = pair.list; + return this; + } + + @Override + public boolean write(Writer writer, String newline, boolean atNewline) throws IOException { + return root.write(writer, newline, atNewline); + } + + @Override + public boolean isEmpty() { + return root.isEmpty(); + } +} diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/TagName.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/TagName.java index 18b4f71ad13..67635e18377 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/TagName.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/TagName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -35,6 +35,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.Utils; */ public enum TagName { A, + ASIDE, BUTTON, BLOCKQUOTE, BODY, diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script.js b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script.js deleted file mode 100644 index cd9ee635e04..00000000000 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script.js +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2013, 2023, 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. - */ - -var moduleSearchIndex; -var packageSearchIndex; -var typeSearchIndex; -var memberSearchIndex; -var tagSearchIndex; - -var oddRowColor = "odd-row-color"; -var evenRowColor = "even-row-color"; -var sortAsc = "sort-asc"; -var sortDesc = "sort-desc"; -var tableTab = "table-tab"; -var activeTableTab = "active-table-tab"; - -function loadScripts(doc, tag) { - createElem(doc, tag, 'script-files/search.js'); - - createElem(doc, tag, 'module-search-index.js'); - createElem(doc, tag, 'package-search-index.js'); - createElem(doc, tag, 'type-search-index.js'); - createElem(doc, tag, 'member-search-index.js'); - createElem(doc, tag, 'tag-search-index.js'); -} - -function createElem(doc, tag, path) { - var script = doc.createElement(tag); - var scriptElement = doc.getElementsByTagName(tag)[0]; - script.src = pathtoroot + path; - scriptElement.parentNode.insertBefore(script, scriptElement); -} - -// Helper for making content containing release names comparable lexicographically -function makeComparable(s) { - return s.toLowerCase().replace(/(\d+)/g, - function(n, m) { - return ("000" + m).slice(-4); - }); -} - -// Switches between two styles depending on a condition -function toggleStyle(classList, condition, trueStyle, falseStyle) { - if (condition) { - classList.remove(falseStyle); - classList.add(trueStyle); - } else { - classList.remove(trueStyle); - classList.add(falseStyle); - } -} - -// Sorts the rows in a table lexicographically by the content of a specific column -function sortTable(header, columnIndex, columns) { - var container = header.parentElement; - var descending = header.classList.contains(sortAsc); - container.querySelectorAll("div.table-header").forEach( - function(header) { - header.classList.remove(sortAsc); - header.classList.remove(sortDesc); - } - ) - var cells = container.children; - var rows = []; - for (var i = columns; i < cells.length; i += columns) { - rows.push(Array.prototype.slice.call(cells, i, i + columns)); - } - var comparator = function(a, b) { - var ka = makeComparable(a[columnIndex].textContent); - var kb = makeComparable(b[columnIndex].textContent); - if (ka < kb) - return descending ? 1 : -1; - if (ka > kb) - return descending ? -1 : 1; - return 0; - }; - var sorted = rows.sort(comparator); - var visible = 0; - sorted.forEach(function(row) { - if (row[0].style.display !== 'none') { - var isEvenRow = visible++ % 2 === 0; - } - row.forEach(function(cell) { - toggleStyle(cell.classList, isEvenRow, evenRowColor, oddRowColor); - container.appendChild(cell); - }) - }); - toggleStyle(header.classList, descending, sortDesc, sortAsc); -} - -// Toggles the visibility of a table category in all tables in a page -function toggleGlobal(checkbox, selected, columns) { - var display = checkbox.checked ? '' : 'none'; - document.querySelectorAll("div.table-tabs").forEach(function(t) { - var id = t.parentElement.getAttribute("id"); - var selectedClass = id + "-tab" + selected; - // if selected is empty string it selects all uncategorized entries - var selectUncategorized = !Boolean(selected); - var visible = 0; - document.querySelectorAll('div.' + id) - .forEach(function(elem) { - if (selectUncategorized) { - if (elem.className.indexOf(selectedClass) === -1) { - elem.style.display = display; - } - } else if (elem.classList.contains(selectedClass)) { - elem.style.display = display; - } - if (elem.style.display === '') { - var isEvenRow = visible++ % (columns * 2) < columns; - toggleStyle(elem.classList, isEvenRow, evenRowColor, oddRowColor); - } - }); - var displaySection = visible === 0 ? 'none' : ''; - t.parentElement.style.display = displaySection; - document.querySelector("li#contents-" + id).style.display = displaySection; - }) -} - -// Shows the elements of a table belonging to a specific category -function show(tableId, selected, columns) { - if (tableId !== selected) { - document.querySelectorAll('div.' + tableId + ':not(.' + selected + ')') - .forEach(function(elem) { - elem.style.display = 'none'; - }); - } - document.querySelectorAll('div.' + selected) - .forEach(function(elem, index) { - elem.style.display = ''; - var isEvenRow = index % (columns * 2) < columns; - toggleStyle(elem.classList, isEvenRow, evenRowColor, oddRowColor); - }); - updateTabs(tableId, selected); -} - -function updateTabs(tableId, selected) { - document.querySelector('div#' + tableId +' .summary-table') - .setAttribute('aria-labelledby', selected); - document.querySelectorAll('button[id^="' + tableId + '"]') - .forEach(function(tab, index) { - if (selected === tab.id || (tableId === selected && index === 0)) { - tab.className = activeTableTab; - tab.setAttribute('aria-selected', true); - tab.setAttribute('tabindex',0); - } else { - tab.className = tableTab; - tab.setAttribute('aria-selected', false); - tab.setAttribute('tabindex',-1); - } - }); -} - -function switchTab(e) { - var selected = document.querySelector('[aria-selected=true]'); - if (selected) { - if ((e.keyCode === 37 || e.keyCode === 38) && selected.previousSibling) { - // left or up arrow key pressed: move focus to previous tab - selected.previousSibling.click(); - selected.previousSibling.focus(); - e.preventDefault(); - } else if ((e.keyCode === 39 || e.keyCode === 40) && selected.nextSibling) { - // right or down arrow key pressed: move focus to next tab - selected.nextSibling.click(); - selected.nextSibling.focus(); - e.preventDefault(); - } - } -} - -var updateSearchResults = function() {}; - -function indexFilesLoaded() { - return moduleSearchIndex - && packageSearchIndex - && typeSearchIndex - && memberSearchIndex - && tagSearchIndex; -} -// Copy the contents of the local snippet to the clipboard -function copySnippet(button) { - copyToClipboard(button.nextElementSibling.innerText); - switchCopyLabel(button, button.firstElementChild); -} -function copyToClipboard(content) { - var textarea = document.createElement("textarea"); - textarea.style.height = 0; - document.body.appendChild(textarea); - textarea.value = content; - textarea.select(); - document.execCommand("copy"); - document.body.removeChild(textarea); -} -function switchCopyLabel(button, span) { - var copied = span.getAttribute("data-copied"); - button.classList.add("visible"); - var initialLabel = span.innerHTML; - span.innerHTML = copied; - setTimeout(function() { - button.classList.remove("visible"); - setTimeout(function() { - if (initialLabel !== copied) { - span.innerHTML = initialLabel; - } - }, 100); - }, 1900); -} -// Dynamically set scroll margin to accomodate for draft header -document.addEventListener("DOMContentLoaded", function(e) { - document.querySelectorAll(':not(input)[id]').forEach( - function(c) { - c.style["scroll-margin-top"] = Math.ceil(document.querySelector("header").offsetHeight) + "px" - }); -}); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script.js.template b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script.js.template new file mode 100644 index 00000000000..b0ba71ab71f --- /dev/null +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script.js.template @@ -0,0 +1,481 @@ +/* + * Copyright (c) 2013, 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. + */ + +var moduleSearchIndex; +var packageSearchIndex; +var typeSearchIndex; +var memberSearchIndex; +var tagSearchIndex; + +var oddRowColor = "odd-row-color"; +var evenRowColor = "even-row-color"; +var sortAsc = "sort-asc"; +var sortDesc = "sort-desc"; +var tableTab = "table-tab"; +var activeTableTab = "active-table-tab"; + +const linkIcon = "##REPLACE:doclet.Link_icon##"; +const linkToSection = "##REPLACE:doclet.Link_to_section##"; + +function loadScripts(doc, tag) { + createElem(doc, tag, 'script-files/search.js'); + + createElem(doc, tag, 'module-search-index.js'); + createElem(doc, tag, 'package-search-index.js'); + createElem(doc, tag, 'type-search-index.js'); + createElem(doc, tag, 'member-search-index.js'); + createElem(doc, tag, 'tag-search-index.js'); +} + +function createElem(doc, tag, path) { + var script = doc.createElement(tag); + var scriptElement = doc.getElementsByTagName(tag)[0]; + script.src = pathtoroot + path; + scriptElement.parentNode.insertBefore(script, scriptElement); +} + +// Helper for making content containing release names comparable lexicographically +function makeComparable(s) { + return s.toLowerCase().replace(/(\d+)/g, + function(n, m) { + return ("000" + m).slice(-4); + }); +} + +// Switches between two styles depending on a condition +function toggleStyle(classList, condition, trueStyle, falseStyle) { + if (condition) { + classList.remove(falseStyle); + classList.add(trueStyle); + } else { + classList.remove(trueStyle); + classList.add(falseStyle); + } +} + +// Sorts the rows in a table lexicographically by the content of a specific column +function sortTable(header, columnIndex, columns) { + var container = header.parentElement; + var descending = header.classList.contains(sortAsc); + container.querySelectorAll("div.table-header").forEach( + function(header) { + header.classList.remove(sortAsc); + header.classList.remove(sortDesc); + } + ) + var cells = container.children; + var rows = []; + for (var i = columns; i < cells.length; i += columns) { + rows.push(Array.prototype.slice.call(cells, i, i + columns)); + } + var comparator = function(a, b) { + var ka = makeComparable(a[columnIndex].textContent); + var kb = makeComparable(b[columnIndex].textContent); + if (ka < kb) + return descending ? 1 : -1; + if (ka > kb) + return descending ? -1 : 1; + return 0; + }; + var sorted = rows.sort(comparator); + var visible = 0; + sorted.forEach(function(row) { + if (row[0].style.display !== 'none') { + var isEvenRow = visible++ % 2 === 0; + } + row.forEach(function(cell) { + toggleStyle(cell.classList, isEvenRow, evenRowColor, oddRowColor); + container.appendChild(cell); + }) + }); + toggleStyle(header.classList, descending, sortDesc, sortAsc); +} + +// Toggles the visibility of a table category in all tables in a page +function toggleGlobal(checkbox, selected, columns) { + var display = checkbox.checked ? '' : 'none'; + document.querySelectorAll("div.table-tabs").forEach(function(t) { + var id = t.parentElement.getAttribute("id"); + var selectedClass = id + "-tab" + selected; + // if selected is empty string it selects all uncategorized entries + var selectUncategorized = !Boolean(selected); + var visible = 0; + document.querySelectorAll('div.' + id) + .forEach(function(elem) { + if (selectUncategorized) { + if (elem.className.indexOf(selectedClass) === -1) { + elem.style.display = display; + } + } else if (elem.classList.contains(selectedClass)) { + elem.style.display = display; + } + if (elem.style.display === '') { + var isEvenRow = visible++ % (columns * 2) < columns; + toggleStyle(elem.classList, isEvenRow, evenRowColor, oddRowColor); + } + }); + var displaySection = visible === 0 ? 'none' : ''; + t.parentElement.style.display = displaySection; + document.querySelector("li#contents-" + id).style.display = displaySection; + }) +} + +// Shows the elements of a table belonging to a specific category +function show(tableId, selected, columns) { + if (tableId !== selected) { + document.querySelectorAll('div.' + tableId + ':not(.' + selected + ')') + .forEach(function(elem) { + elem.style.display = 'none'; + }); + } + document.querySelectorAll('div.' + selected) + .forEach(function(elem, index) { + elem.style.display = ''; + var isEvenRow = index % (columns * 2) < columns; + toggleStyle(elem.classList, isEvenRow, evenRowColor, oddRowColor); + }); + updateTabs(tableId, selected); +} + +function updateTabs(tableId, selected) { + document.querySelector('div#' + tableId +' .summary-table') + .setAttribute('aria-labelledby', selected); + document.querySelectorAll('button[id^="' + tableId + '"]') + .forEach(function(tab, index) { + if (selected === tab.id || (tableId === selected && index === 0)) { + tab.className = activeTableTab; + tab.setAttribute('aria-selected', true); + tab.setAttribute('tabindex',0); + } else { + tab.className = tableTab; + tab.setAttribute('aria-selected', false); + tab.setAttribute('tabindex',-1); + } + }); +} + +function switchTab(e) { + var selected = document.querySelector('[aria-selected=true]'); + if (selected) { + if ((e.keyCode === 37 || e.keyCode === 38) && selected.previousSibling) { + // left or up arrow key pressed: move focus to previous tab + selected.previousSibling.click(); + selected.previousSibling.focus(); + e.preventDefault(); + } else if ((e.keyCode === 39 || e.keyCode === 40) && selected.nextSibling) { + // right or down arrow key pressed: move focus to next tab + selected.nextSibling.click(); + selected.nextSibling.focus(); + e.preventDefault(); + } + } +} + +var updateSearchResults = function() {}; + +function indexFilesLoaded() { + return moduleSearchIndex + && packageSearchIndex + && typeSearchIndex + && memberSearchIndex + && tagSearchIndex; +} +// Copy the contents of the local snippet to the clipboard +function copySnippet(button) { + copyToClipboard(button.nextElementSibling.innerText); + switchCopyLabel(button, button.firstElementChild); +} +function copyToClipboard(content) { + var textarea = document.createElement("textarea"); + textarea.style.height = 0; + document.body.appendChild(textarea); + textarea.value = content; + textarea.select(); + document.execCommand("copy"); + document.body.removeChild(textarea); +} +function switchCopyLabel(button, span) { + var copied = span.getAttribute("data-copied"); + button.classList.add("visible"); + var initialLabel = span.innerHTML; + span.innerHTML = copied; + setTimeout(function() { + button.classList.remove("visible"); + setTimeout(function() { + if (initialLabel !== copied) { + span.innerHTML = initialLabel; + } + }, 100); + }, 1900); +} +function setTopMargin() { + // Dynamically set scroll margin to accomodate for draft header + var headerHeight = Math.ceil(document.querySelector("header").offsetHeight); + document.querySelector(":root") + .style.setProperty("--nav-height", headerHeight + "px"); +} +document.addEventListener("readystatechange", (e) => { + if (document.readyState === "interactive") { + setTopMargin(); + } + if (sessionStorage.getItem("sidebar") === "hidden") { + const sidebar = document.querySelector(".main-grid nav.toc"); + if (sidebar) sidebar.classList.add("hide-sidebar"); + } +}); +document.addEventListener("DOMContentLoaded", function(e) { + setTopMargin(); + // Make sure current element is visible in breadcrumb navigation on small displays + const subnav = document.querySelector("ol.sub-nav-list"); + if (subnav && subnav.lastElementChild) { + subnav.lastElementChild.scrollIntoView({ behavior: "instant", inline: "start", block: "nearest" }); + } + // Clone TOC sidebar to header for mobile navigation + const navbar = document.querySelector("div#navbar-top"); + const sidebar = document.querySelector(".main-grid nav.toc"); + const main = document.querySelector(".main-grid main"); + const mainnav = navbar.querySelector("ul.nav-list"); + const toggleButton = document.querySelector("button#navbar-toggle-button"); + const toc = sidebar ? sidebar.cloneNode(true) : null; + if (toc) { + navbar.appendChild(toc); + } + document.querySelectorAll("input.filter-input").forEach(function(input) { + input.removeAttribute("disabled"); + input.value = ""; + input.addEventListener("input", function(e) { + const pattern = input.value ? input.value.trim() + .replace(/[\[\]{}()*+?.\\^$|]/g, '\\$&') + .replace(/\s+/g, ".*") : ""; + input.nextElementSibling.style.display = pattern ? "inline" : "none"; + const filter = new RegExp(pattern, "i"); + input.parentNode.parentNode.querySelectorAll("ol.toc-list li").forEach((li) => { + if (filter.test(li.innerText)) { + li.removeAttribute("style"); + } else { + li.style.display = "none"; + } + }); + if (expanded) { + expand(); + } + }); + }); + document.querySelectorAll("input.reset-filter").forEach((button) => { + button.removeAttribute("disabled"); + button.addEventListener("click", (e) => { + const input = button.previousElementSibling; + input.value = ""; + input.dispatchEvent(new InputEvent("input")); + input.focus(); + if (expanded) { + expand(); + } else { + prevHash = null; + handleScroll(); + } + }) + }); + var expanded = false; + var windowWidth; + function collapse() { + if (expanded) { + mainnav.removeAttribute("style"); + if (toc) { + toc.removeAttribute("style"); + } + toggleButton.classList.remove("expanded") + toggleButton.setAttribute("aria-expanded", "false"); + expanded = false; + } + } + function expand() { + expanded = true; + mainnav.style.display = "block"; + mainnav.style.removeProperty("height"); + var maxHeight = window.innerHeight - subnav.offsetTop + 4; + var expandedHeight = Math.min(maxHeight, mainnav.scrollHeight + 10); + if (toc) { + toc.style.display = "flex"; + expandedHeight = Math.min(maxHeight, + Math.max(expandedHeight, toc.querySelector("div.toc-header").offsetHeight + + toc.querySelector("ol.toc-list").scrollHeight + 10)); + toc.style.height = expandedHeight + "px"; + } + mainnav.style.height = expandedHeight + "px"; + toggleButton.classList.add("expanded"); + toggleButton.setAttribute("aria-expanded", "true"); + windowWidth = window.innerWidth; + } + toggleButton.addEventListener("click", (e) => { + if (expanded) { + collapse(); + } else { + expand(); + } + }); + if (toc) { + toc.querySelectorAll("a").forEach((link) => { + link.addEventListener("click", collapse); + }); + } + document.addEventListener('keydown', (e) => { + if (e.key === "Escape") collapse(); + }); + document.querySelector("main").addEventListener("click", collapse); + const searchInput = document.getElementById("search-input"); + if (searchInput) searchInput.addEventListener("focus", collapse); + document.querySelectorAll("h1, h2, h3, h4, h5, h6") + .forEach((hdr, idx) => { + // Create anchor links for headers with an associated id attribute + var id = hdr.getAttribute("id") || hdr.parentElement.getAttribute("id") + || (hdr.querySelector("a") && hdr.querySelector("a").getAttribute("id")); + if (id) { + var template = document.createElement('template'); + template.innerHTML =" " + linkIcon +""; + hdr.append(...template.content.childNodes); + } + }); + var sections; + var scrollTimeout; + var scrollTimeoutNeeded; + var prevHash; + function initSectionData() { + sections = [{ id: "", top: 0 }].concat(Array.from(main.querySelectorAll("section[id], h2[id], h2 a[id], div[id]")) + .filter((e) => { + return sidebar.querySelector("a[href=\"#" + encodeURI(e.getAttribute("id")) + "\"]") !== null + }).map((e) => { + return { + id: e.getAttribute("id"), + top: e.offsetTop + }; + })); + } + function setScrollTimeout() { + clearTimeout(scrollTimeout); + scrollTimeoutNeeded = false; + scrollTimeout = setTimeout(() => { + scrollTimeout = null; + handleScroll(); + }, 50); + } + function handleScroll() { + if (!sidebar || !sidebar.offsetParent || sidebar.classList.contains("hide-sidebar")) { + return; + } + if (scrollTimeout || scrollTimeoutNeeded) { + setScrollTimeout(); + return; + } + var scrollTop = document.documentElement.scrollTop; + var scrollHeight = document.documentElement.scrollHeight; + var currHash = null; + if (scrollHeight - scrollTop < window.innerHeight + 10) { + // Select last item if at bottom of the page + currHash = "#" + encodeURI(sections.at(-1).id); + } else { + for (var i = 0; i < sections.length; i++) { + var top = sections[i].top; + var bottom = sections[i + 1] ? sections[i + 1].top : scrollHeight; + if (top + ((bottom - top) / 2) > scrollTop || bottom > scrollTop + (window.innerHeight / 3)) { + currHash = "#" + encodeURI(sections[i].id); + break; + } + } + } + if (currHash !== prevHash) { + setSelected(currHash); + } + } + function setSelected(hash) { + var prev = sidebar.querySelector("a.current-selection"); + if (prev) + prev.classList.remove("current-selection"); + prevHash = hash; + if (hash) { + var curr = sidebar.querySelector("ol.toc-list a[href=\"" + hash + "\"]"); + if (curr) { + curr.classList.add("current-selection"); + curr.scrollIntoView({ behavior: "instant", block: "nearest" }); + } + } + } + if (sidebar) { + initSectionData(); + document.querySelectorAll("a[href^='#']").forEach((link) => { + link.addEventListener("click", (e) => { + scrollTimeoutNeeded = true; + setSelected(link.getAttribute("href")); + }) + }); + sidebar.querySelector("button.hide-sidebar").addEventListener("click", () => { + sidebar.classList.add("hide-sidebar"); + sessionStorage.setItem("sidebar", "hidden"); + }); + sidebar.querySelector("button.show-sidebar").addEventListener("click", () => { + sidebar.classList.remove("hide-sidebar"); + sessionStorage.removeItem("sidebar"); + initSectionData(); + handleScroll(); + }); + window.addEventListener("hashchange", (e) => { + scrollTimeoutNeeded = true; + }); + if (document.location.hash) { + scrollTimeoutNeeded = true; + setSelected(document.location.hash); + } else { + handleScroll(); + } + window.addEventListener("scroll", handleScroll); + window.addEventListener("scrollend", () => { + if (scrollTimeout) { + clearTimeout(scrollTimeout); + scrollTimeout = null; + handleScroll(); + } + }) + } + // Resize handler + function handleResize(e) { + if (expanded) { + if (windowWidth != window.innerWidth) { + collapse(); + } else { + expand(); + } + } + if (sections) { + initSectionData(); + prevHash = null; + handleScroll(); + } + setTopMargin(); + } + window.addEventListener("orientationchange", handleResize); + window.addEventListener("resize", handleResize); +}); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js.template b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js.template index f98a2faf035..c864787bf2f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js.template +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -31,8 +31,6 @@ const messages = { loading: "##REPLACE:doclet.search.loading##", searching: "##REPLACE:doclet.search.searching##", redirecting: "##REPLACE:doclet.search.redirecting##", - linkIcon: "##REPLACE:doclet.Link_icon##", - linkToSection: "##REPLACE:doclet.Link_to_section##" } const categories = { modules: "##REPLACE:doclet.search.modules##", @@ -255,9 +253,6 @@ function rateNoise(str) { function doSearch(request, response) { var term = request.term.trim(); var maxResults = request.maxResults || MAX_RESULTS; - if (term.length === 0) { - return this.close(); - } var matcher = { plainMatcher: createMatcher(term, false), camelCaseMatcher: createMatcher(term, true) @@ -407,52 +402,18 @@ $.widget("custom.catcomplete", $.ui.autocomplete, { } }); $(function() { - var expanded = false; - var windowWidth; - function collapse() { - if (expanded) { - $("div#navbar-top").removeAttr("style"); - $("button#navbar-toggle-button") - .removeClass("expanded") - .attr("aria-expanded", "false"); - expanded = false; - } - } - $("button#navbar-toggle-button").click(function (e) { - if (expanded) { - collapse(); - } else { - var navbar = $("div#navbar-top"); - navbar.height(navbar.prop("scrollHeight")); - $("button#navbar-toggle-button") - .addClass("expanded") - .attr("aria-expanded", "true"); - expanded = true; - windowWidth = window.innerWidth; - } - }); - $("ul.sub-nav-list-small li a").click(collapse); - $("input#search-input").focus(collapse); - $("main").click(collapse); - $("section[id] > :header, :header[id], :header:has(a[id])").each(function(idx, el) { - // Create anchor links for headers with an associated id attribute - var hdr = $(el); - var id = hdr.attr("id") || hdr.parent("section").attr("id") || hdr.children("a").attr("id"); - if (id) { - hdr.append(" " + messages.linkIcon +""); - } - }); - $(window).on("orientationchange", collapse).on("resize", function(e) { - if (expanded && windowWidth !== window.innerWidth) collapse(); - }); var search = $("#search-input"); - var reset = $("#reset-button"); + var reset = $("#reset-search"); search.catcomplete({ minLength: 1, delay: 200, - source: doSearch, + source: function(request, response) { + reset.css("display", "inline"); + if (request.term.trim() === "") { + return this.close(); + } + return doSearch(request, response); + }, response: function(event, ui) { if (!ui.content.length) { ui.content.push({ l: messages.noResult }); @@ -460,6 +421,12 @@ $(function() { $("#search-input").empty(); } }, + close: function(event, ui) { + reset.css("display", search.val() ? "inline" : "none"); + }, + change: function(event, ui) { + reset.css("display", search.val() ? "inline" : "none"); + }, autoFocus: true, focus: function(event, ui) { return false; @@ -480,6 +447,7 @@ $(function() { reset.prop("disabled", false); reset.click(function() { search.val('').focus(); + reset.css("display", "none"); }); search.focus(); }); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css index 46c39a0918b..ab9201fbc86 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css @@ -15,7 +15,11 @@ --code-font-family: 'DejaVu Sans Mono', monospace; /* Base font sizes for body and code elements */ --body-font-size: 14px; + --block-font-size: 14px; --code-font-size: 14px; + --nav-font-size: 13.2px; + /* Line height for continuous text blocks */ + --block-line-height: 1.4em; /* Text colors for body and block elements */ --body-text-color: #353833; --block-text-color: #474747; @@ -59,6 +63,11 @@ /* Colors for invalid tag notifications */ --invalid-tag-background-color: #ffe6e6; --invalid-tag-text-color: #000000; + /* Navigation bar dimensions */ + --top-nav-height: 44px; + --sub-nav-height: 34px; + --nav-height: calc(var(--top-nav-height) + var(--sub-nav-height)); + scroll-behavior: smooth; } /* * Styles for individual HTML elements. @@ -76,28 +85,20 @@ body { height:100%; width:100%; } -iframe { - margin:0; - padding:0; - height:100%; - width:100%; - overflow-y:scroll; - border:none; -} -:not(input)[id] { - scroll-margin-top: 78px; +main [id] { + scroll-margin-top: calc(var(--nav-height) + 6px); } a:link, a:visited { text-decoration:none; color:var(--link-color); } -a[href]:hover, a[href]:focus { +a[href]:hover, a[href]:active { text-decoration:none; color:var(--link-color-active); } pre { font-family:var(--code-font-family); - font-size:1em; + font-size:var(--code-font-size); } h1 { font-size:1.428em; @@ -130,8 +131,6 @@ code, tt { :not(h1, h2, h3, h4, h5, h6) > code, :not(h1, h2, h3, h4, h5, h6) > tt { font-size:var(--code-font-size); - padding-top:4px; - margin-top:8px; line-height:1.4em; } dt code { @@ -152,6 +151,9 @@ button { font-family: var(--body-font-family); font-size: 1em; } +hr { + border-color: #aaa; +} /* * Styles for HTML generated by javadoc. * @@ -162,14 +164,14 @@ button { * Styles for document title and copyright. */ .about-language { - float:right; - padding:0 21px 8px 8px; + flex: 0 0 auto; + padding:0 20px; + margin:0; font-size:0.915em; - margin-top:-9px; - height:2.9em; + max-width: 50%; + white-space: nowrap; } .legal-copy { - margin-left:.5em; } /* * Styles for navigation bar. @@ -178,83 +180,102 @@ button { header { position:sticky; top:0; - z-index:1; + z-index:2; background: var(--body-background-color); } } +.nav-content { + display:flex; + flex-direction: row; + align-items: center; + width: 100%; + height: 100%; +} .top-nav { background-color:var(--navbar-background-color); color:var(--navbar-text-color); - float:left; width:100%; - clear:right; - min-height:2.8em; - padding:10px 0 0 0; - overflow:hidden; + height:var(--top-nav-height); + overflow:visible; font-size:0.857em; + position:relative; +} +.top-nav nav.toc { + display: none; + flex-direction: column; +} +.top-nav nav.toc button.show-sidebar, +.top-nav nav.toc button.hide-sidebar { + display: none; } button#navbar-toggle-button { display:none; } -ul.sub-nav-list-small { - display: none; -} -.sub-nav { - background-color:var(--subnav-background-color); - float:left; - width:100%; - overflow:hidden; - font-size:0.857em; -} -.sub-nav div { - clear:left; - float:left; - padding:6px; - text-transform:uppercase; -} -.sub-nav .sub-nav-list { - padding-top:4px; -} ul.nav-list { - display:block; - margin:0 25px 0 0; - padding:0; -} -ul.sub-nav-list { - float:left; - margin:0 25px 0 0; - padding:0; + display:inline-flex; + margin:0; + padding-left:4px; + flex: 1 1 auto; + white-space: nowrap; } ul.nav-list li { list-style:none; - float:left; padding: 5px 6px; text-transform:uppercase; + height: 1.2em; +} +div.sub-nav { + background-color:var(--subnav-background-color); + width:100%; + overflow:hidden; + font-size:var(--nav-font-size); + height: var(--sub-nav-height); +} +ol.sub-nav-list { + flex: 1 1 90%; + line-height: 1.8em; + display: inline-flex; + overflow: auto; + scroll-snap-type: x mandatory; + scroll-padding-left: 13px; + scrollbar-width: none; + padding-left:6px; + white-space: nowrap; + margin:0; +} +ol.sub-nav-list::-webkit-scrollbar { + display: none; +} +ol.sub-nav-list li { + list-style:none; + scroll-snap-align: start; +} +ol.sub-nav-list a { + padding: 3px; +} +ol.sub-nav-list a.current-selection { + background-color: var(--section-background-color); + border-radius: 4px; } .sub-nav .nav-list-search { - float:right; + flex: 1 1 10%; margin:0; padding:6px; - clear:none; - text-align:right; position:relative; + white-space: nowrap; } -ul.sub-nav-list li { - list-style:none; - float:left; -} -.top-nav a:link, .top-nav a:active, .top-nav a:visited { +.top-nav .nav-list a:link, .top-nav .nav-list a:active, .top-nav .nav-list a:visited { color:var(--navbar-text-color); text-decoration:none; text-transform:uppercase; } -.top-nav a:hover { +.top-nav .nav-list a:hover { color:var(--link-color-active); } .nav-bar-cell1-rev { background-color:var(--selected-background-color); color:var(--selected-text-color); - margin: auto 5px; + margin: 0 5px; } .skip-nav { position:absolute; @@ -298,6 +319,7 @@ body.module-declaration-page .block-list h2 { font-style: italic; padding:0; margin:15px 0; + overflow-x:auto; } body.class-declaration-page .summary h3, body.class-declaration-page .details h3 { @@ -310,6 +332,18 @@ body.class-declaration-page .details h3 { /* * Styles for page layout containers. */ +.main-grid { + display: flex; + flex-direction: row; +} +.main-grid main { + flex: 2.6 1 0; + min-width: 240px +} +.main-grid nav.toc { + flex: 1 1 0; + min-width: 240px; +} main { clear:both; padding:10px 20px; @@ -328,7 +362,7 @@ dl.notes > dt { } dl.notes > dd { margin:5px 10px 10px 0; - font-size:1em; + font-size:var(--block-font-size); font-family:var(--block-font-family) } dl.name-value > dt { @@ -342,6 +376,120 @@ dl.name-value > dd { font-size:1.1em; display:inline; } +/* + * Styles for table of contents. + */ +.main-grid nav.toc { + background-color: var(--section-background-color); + border-right: 1px solid var(--border-color); + position: sticky; + top: calc(var(--nav-height)); + max-height: calc(100vh - var(--nav-height)); + display: flex; + flex-direction: column; + font-family: var(--body-font-family); + z-index: 1; +} +.main-grid nav.toc div.toc-header { + background-color: var(--section-background-color); + border-right: 1px solid var(--border-color); + top: var(--nav-height); + z-index: 1; + padding: 15px 20px; +} +.main-grid nav.toc > ol.toc-list { + max-height: calc(100vh - var(--nav-height) - 100px); + padding-left: 12px; +} +.main-grid nav.toc button { + position: absolute; + bottom: 16px; + z-index: 3; + background-color: var(--section-background-color); + color: #666666; + font-size: 0.76rem; + border: none; + cursor: pointer; + padding: 6px 10px; + white-space: nowrap; +} +.main-grid nav.toc button.hide-sidebar { + right: 0; +} +.main-grid nav.toc button.show-sidebar { + left: 0; + display: none; +} +.main-grid nav.toc button span { + display: none; +} +.main-grid nav.toc button:hover { + color: var(--body-text-color); + border: 1px solid var(--subnav-background-color); +} +.main-grid nav.toc button:active { + background-color: var(--subnav-background-color); + color: var(--link-color-active); +} +.main-grid nav.toc button:hover span, +.main-grid nav.toc button:active span { + display: inline; +} +.main-grid nav.toc button:hover { + box-shadow: 1px 1px 5px rgba(0,0,0,0.2); +} +.main-grid nav.toc.hide-sidebar { + min-width: revert; + max-width: 28px; +} +.main-grid nav.toc.hide-sidebar div.toc-header, +.main-grid nav.toc.hide-sidebar ol.toc-list, +.main-grid nav.toc.hide-sidebar button.hide-sidebar { + display: none; +} +.main-grid nav.toc.hide-sidebar button.show-sidebar { + display: inline; +} +nav.toc div.toc-header { + padding: 15px; + display: inline-flex; + align-items: center; + color: var(--body-text-color); + background-color: var(--body-background-color); + font-size: 0.856em; + font-weight: bold; + white-space: nowrap; + overflow-x: hidden; + position: sticky; + min-height: 20px; +} +nav.toc > ol.toc-list { + overflow: hidden auto; + overscroll-behavior: contain; +} +nav.toc ol.toc-list { + list-style: none; + padding-left: 8px; + margin: 0; +} +nav.toc ol.toc-list ol.toc-list { + margin-left: 8px; +} +nav.toc ol.toc-list li { + margin: 0; + font-size: var(--nav-font-size); + overflow-x: hidden; +} +a.current-selection { + font-weight: bold; +} +nav.toc a { + display: block; + padding: 8px; +} +nav.toc a.current-selection { + background-color: var(--subnav-background-color); +} /* * Styles for lists. */ @@ -359,11 +507,14 @@ div.inheritance { div.inheritance div.inheritance { margin-left:2em; } +main > div.inheritance { + overflow-x:auto; +} ul.block-list, ul.details-list, ul.member-list, ul.summary-list { - margin:10px 0 10px 0; + margin:4px 0 10px 0; padding:0; } ul.block-list > li, @@ -599,8 +750,9 @@ div.checkboxes > label > input { * Styles for contents. */ div.block { - font-size:var(--body-font-size); + font-size:var(--block-font-size); font-family:var(--block-font-family); + line-height:var(--block-line-height); } .col-last div { padding-top:0; @@ -646,7 +798,6 @@ div.block { color:var(--block-text-color); } .deprecated-label, .description-from-type-label, .implementation-label, .member-name-link, -.module-label-in-package, .module-label-in-type, .package-label-in-type, .package-hierarchy-label, .type-name-label, .type-name-link, .search-tag-link, .preview-label, .restricted-label { font-weight:bold; } @@ -686,9 +837,6 @@ details summary { main, nav, header, footer, section { display:block; } -nav { - overflow:hidden; -} /* * Styles for javadoc search. */ @@ -712,15 +860,14 @@ nav { .ui-autocomplete { max-height:85%; max-width:65%; - overflow-y:auto; - overflow-x:auto; + overflow:auto; white-space:nowrap; box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); overscroll-behavior: contain; } ul.ui-autocomplete { position:fixed; - z-index:1; + z-index:10; background-color: var(--body-background-color); } ul.ui-autocomplete li { @@ -738,7 +885,7 @@ ul.ui-autocomplete li.ui-static-link { font-family: var(--body-font-family); font-size: 0.93em; font-weight: bolder; - z-index: 2; + z-index: 10; } li.ui-static-link a, li.ui-static-link a:visited { text-decoration:none; @@ -756,7 +903,11 @@ li.ui-static-link a, li.ui-static-link a:visited { padding-top: 0.4em; padding-bottom: 0.4em; } -#search-input, #page-search-input { +.ui-menu .ui-menu-item-wrapper { + padding-top: 5px; + padding-bottom: 5px; +} +input[type="text"] { background-image:url('glass.png'); background-size:13px; background-repeat:no-repeat; @@ -764,14 +915,27 @@ li.ui-static-link a, li.ui-static-link a:visited { background-color: var(--search-input-background-color); color: var(--search-input-text-color); border-color: var(--border-color); + border-radius: 4px; padding-left:20px; - width: 250px; + font-size: var(--nav-font-size); + height: 17px; +} +input#search-input, input#page-search-input { + width: calc(180px + 10vw); margin: 0; } -#search-input { - margin-left: 4px; +input#search-input { + margin: 0 4px; + padding-right: 18px; + max-width: 340px; } -#reset-button { +input.filter-input { + width: 40%; + max-width: 140px; + margin: 0 4px; + padding-right: 18px; +} +input#reset-search, input.reset-filter { background-color: transparent; background-image:url('x.png'); background-repeat:no-repeat; @@ -780,12 +944,20 @@ li.ui-static-link a, li.ui-static-link a:visited { border-radius:0; width:12px; height:12px; - position:absolute; - right:12px; - top:10px; font-size:0; + display:none; } -::placeholder { +input#reset-search { + position:absolute; + right:15px; + top:11px; +} +input.reset-filter { + position: relative; + right: 20px; + top: 0; +} +input::placeholder { color:var(--search-input-placeholder-color); opacity: 1; } @@ -849,7 +1021,7 @@ span#page-search-link { .module-graph:hover span, .sealed-graph:hover span { display:block; margin: -100px 0 0 100px; - z-index: 1; + z-index: 5; } .inherited-list { margin: 10px 0 10px 0; @@ -874,6 +1046,10 @@ section.class-description { .vertical-separator { padding: 0 5px; } +.help-section { + font-size: var(--block-font-size); + line-height: var(--block-line-height); +} ul.help-section-list { margin: 0; } @@ -1100,22 +1276,67 @@ table.striped > tbody > tr > th { /** * Tweak style for small screens. */ +@media screen and (max-width: 1050px) { + .summary section[class$="-summary"], .details section[class$="-details"], + .class-uses .detail, .serialized-class-details { + padding: 0 10px 5px 8px; + } + input#search-input { + width: 22vw; + } +} @media screen and (max-width: 920px) { + .main-grid nav.toc { + display: none; + } + .top-nav nav.toc { + display: none; + position: absolute; + top: var(--top-nav-height); + left: 40vw; + width: 60vw; + z-index: 7; + background-color: var(--section-background-color); + box-sizing: border-box; + } + .top-nav nav.toc div.toc-header { + padding: 6px 15px; + font-size: 0.94em; + background-color: var(--section-background-color); + top: calc(var(--top-nav-height) + 10px); + } + .top-nav nav.toc ol.toc-list li { + font-size: 1.04em; + } + nav.toc a:link, nav.toc a:visited { + text-decoration:none; + color:var(--link-color); + } + nav.toc a[href]:hover, nav.toc a[href]:focus { + text-decoration:none; + color:var(--link-color-active); + } + :root { + scroll-behavior: auto; + } header { max-height: 100vh; - overflow-y: auto; + overflow-y: visible; + overscroll-behavior: contain; } - div#navbar-top { - height: 2.8em; - transition: height 0.35s ease; + nav { + overflow: visible; } ul.nav-list { - display: block; + display: none; + position: absolute; + top: var(--top-nav-height); + overflow: auto; + z-index: 7; + background-color: var(--navbar-background-color); width: 40%; - float:left; - clear: left; - margin: 10px 0 0 0; padding: 0; + box-sizing: border-box; } ul.nav-list li { float: none; @@ -1123,51 +1344,21 @@ table.striped > tbody > tr > th { margin-left: 10px; margin-top: 2px; } - ul.sub-nav-list-small { - display:block; - height: 100%; - width: 50%; - float: right; - clear: right; - background-color: var(--subnav-background-color); - color: var(--body-text-color); - margin: 6px 0 0 0; - padding: 0; - } - ul.sub-nav-list-small ul { - padding-left: 20px; - } - ul.sub-nav-list-small a:link, ul.sub-nav-list-small a:visited { - color:var(--link-color); - } - ul.sub-nav-list-small a:hover { - color:var(--link-color-active); - } - ul.sub-nav-list-small li { - list-style:none; - float:none; - padding: 6px; - margin-top: 1px; - text-transform:uppercase; - } - ul.sub-nav-list-small > li { - margin-left: 10px; - } - ul.sub-nav-list-small li p { - margin: 5px 0; - } - div#navbar-sub-list { - display: none; - } .top-nav a:link, .top-nav a:active, .top-nav a:visited { display: block; } + .top-nav div.nav-menu-button { + flex: 1 1 auto; + } + .sub-nav ol.sub-nav-list { + margin-left: 4px; + padding-left: 4px; + } button#navbar-toggle-button { width: 3.4em; height: 2.8em; background-color: transparent; display: block; - float: left; border: 0; margin: 0 10px; cursor: pointer; @@ -1177,9 +1368,8 @@ table.striped > tbody > tr > th { display: block; width: 24px; height: 3px; - margin: 1px 0 4px 0; + margin: 4px 0; border-radius: 2px; - transition: all 0.1s; background-color: var(--navbar-text-color); } button#navbar-toggle-button.expanded span.nav-bar-toggle-icon:nth-child(1) { @@ -1199,50 +1389,30 @@ table.striped > tbody > tr > th { @media screen and (max-width: 800px) { .about-language { padding-right: 16px; + max-width: 90%; } ul.nav-list li { margin-left: 5px; } - ul.sub-nav-list-small > li { - margin-left: 5px; - } main { - padding: 10px; - } - .summary section[class$="-summary"], .details section[class$="-details"], - .class-uses .detail, .serialized-class-details { - padding: 0 8px 5px 8px; + padding: 10px 12px; } body { -webkit-text-size-adjust: none; } } -@media screen and (max-width: 400px) { - .about-language { - font-size: 10px; - padding-right: 12px; - } -} -@media screen and (max-width: 400px) { - .nav-list-search { - width: 94%; - } - #search-input, #page-search-input { - width: 70%; - } -} -@media screen and (max-width: 320px) { - .nav-list-search > label { +@media screen and (max-width: 600px) { + .nav-list-search > a { display: none; } - .nav-list-search { - width: 90%; + input#search-input { + width: 18vw; } - #search-input, #page-search-input { - width: 80%; + .summary section[class$="-summary"], .details section[class$="-details"], + .class-uses .detail, .serialized-class-details { + padding: 0; } } - pre.snippet { background-color: var(--snippet-background-color); color: var(--snippet-text-color); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties index 00da1793393..7c5b43d35df 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 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 @@ -232,8 +232,9 @@ doclet.Modifier=Modifier doclet.Type=Type doclet.Modifier_and_Type=Modifier and Type doclet.Implementation=Implementation(s): -doclet.search=SEARCH +doclet.search=Search doclet.search_placeholder=Search +doclet.search_in_documentation=Search in documentation doclet.search_reset=Reset doclet.Field=Field doclet.Property=Property @@ -247,6 +248,12 @@ doclet.Enum_Constant=Enum Constant doclet.Description=Description doclet.ConstantField=Constant Field doclet.Value=Value +doclet.table_of_contents=Table of contents +doclet.hide_sidebar=Hide sidebar +doclet.show_sidebar=Show sidebar +doclet.filter_label=Filter +doclet.filter_table_of_contents=Filter table of contents +doclet.filter_reset=Reset doclet.linkMismatch_PackagedLinkedtoModule=The code being documented uses packages in the unnamed module, \ but the packages defined in {0} are in named modules. doclet.linkMismatch_ModuleLinkedtoPackage=The code being documented uses modules but the packages defined \ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocLink.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocLink.java index 05119e25012..9764e9134b6 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocLink.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocLink.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -90,7 +90,7 @@ public class DocLink { DocPath newPath = base.relativize(path); // avoid generating an empty link by using the basename of the path if necessary - if (newPath.isEmpty() && isEmpty(fragment)) { + if (newPath.isEmpty() && fragment == null) { newPath = path.basename(); } return new DocLink(newPath, fragment); @@ -121,18 +121,14 @@ public class DocLink { @Override public String toString() { // common fast path - if (path != null && isEmpty(fragment)) + if (path != null && fragment == null) return path.getPath(); StringBuilder sb = new StringBuilder(); if (path != null) sb.append(path.getPath()); - if (!isEmpty(fragment)) + if (fragment != null) sb.append("#").append(fragment); return sb.toString(); } - - private static boolean isEmpty(String s) { - return (s == null) || s.isEmpty(); - } } 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 4f3c10df887..0f329eebcd6 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -94,6 +94,9 @@ public class DocPaths { /** The name of the default javascript file. */ public static final DocPath SCRIPT_JS = DocPath.create("script.js"); + /** The name of the template of the default javascript file. */ + public static final DocPath SCRIPT_JS_TEMPLATE = DocPath.create("script.js.template"); + /** The name of the copy-to-clipboard icon file. */ public static final DocPath CLIPBOARD_SVG = DocPath.create("copy.svg"); diff --git a/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java b/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java index 524048e5069..84b5e96e547 100644 --- a/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java +++ b/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -68,19 +68,19 @@ public class TestAnchorNames extends JavadocTester { """

    Nested Class Summary

    """, - "", + "", """

    Method Summary

    """, - "
    ", + "", """

    Field Details

    """, - "
    ", + "", """

    Constructor Details

    """, - "
    "); + ""); // Test some members and link to these members checkOutput("pkg1/RegClass.html", true, diff --git a/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java b/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java index c53c3342bbc..9235fcd8215 100644 --- a/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java +++ b/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -52,11 +52,11 @@ public class TestAnnotationTypes extends JavadocTester { checkOutput("pkg/AnnotationTypeField.html", true, """ -
  • Summary: 
  • -
  • Field | 
  • """, +
  • Field Summary
  • """, """ -
  • Detail: 
  • -
  • Field | 
  • """, +
  • Field Details +
      +
    1. DEFAULT_NAME
    2. """, "", "

      Field Summary

      ", """ @@ -73,18 +73,17 @@ public class TestAnnotationTypes extends JavadocTester { checkOutput("pkg/AnnotationType.html", true, """ - """, - """ - """); +
        +
      1. Description
      2. +
      3. Required Element Summary
      4. +
      5. Optional Element Summary
      6. +
      7. Element Details +
          +
        1. value
        2. +
        3. optional
        4. +
        +
      8. +
      """); checkOutput("pkg/AnnotationType.html", true, """ diff --git a/test/langtools/jdk/javadoc/doclet/testConstantValuesPage/TestConstantValuesPage.java b/test/langtools/jdk/javadoc/doclet/testConstantValuesPage/TestConstantValuesPage.java index a796d6f0d19..d078c19644a 100644 --- a/test/langtools/jdk/javadoc/doclet/testConstantValuesPage/TestConstantValuesPage.java +++ b/test/langtools/jdk/javadoc/doclet/testConstantValuesPage/TestConstantValuesPage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -107,13 +107,17 @@ public class TestConstantValuesPage extends JavadocTester { checkOutput("constant-values.html", true, """ -
      -

      Contents

      - -
      """); +
    + """); } /** @@ -140,12 +144,16 @@ public class TestConstantValuesPage extends JavadocTester { checkOutput("constant-values.html", true, """ -
    -

    Contents

    - -
    """); + """); } /** @@ -179,13 +187,17 @@ public class TestConstantValuesPage extends JavadocTester { checkOutput("constant-values.html", true, """ -
    -

    Contents

    - -
    """); + """); } /** @@ -245,13 +257,17 @@ public class TestConstantValuesPage extends JavadocTester { checkOutput("constant-values.html", true, """ -
    -

    Contents

    - -
    """); + """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java b/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java index 5883bc928ae..addd93caca2 100644 --- a/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java +++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -56,17 +56,17 @@ public class TestCopyFiles extends JavadocTester { "Hello World" (phi-WINDOW-TITLE-phi)""", "phi-TOP-phi", // check top navbar - "phi-HEADER-phi", """ - Module""", - """ - Package""", - """ - Tree""", + Tree""", """ Deprecated""", """ Index""", + "phi-HEADER-phi", + """ + acme.mdle""", + """ + p""", """ In a named module acme.module and named package p.""", "
    Since:Module""", - """ - Package""", - """ - Tree""", + Tree""", """ Deprecated""", """ Index""", + "phi-HEADER-phi", + """ + acme.mdle""", + """ + p""", """ In a named module acme.module and named package p.""", "
    Since:Module""", - """ - Package""", - """ - Tree""", + Tree""", """ Deprecated""", """ Index""", + "phi-HEADER-phi", + """ + acme2.mdle""", + """ + p2""", "SubSubReadme.html at third level of doc-file directory.", // check footer "phi-BOTTOM-phi" diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java b/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java index 890d6860e8f..53868e0859b 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -188,13 +188,12 @@ public class TestHtmlVersion extends JavadocTester {
    +
    """, """