Skip to content

8361366: Allow sorting of member details in lexicographical order #26322

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,12 @@ protected void generateOtherFiles(ClassTree classTree)
copyResource(DocPaths.STYLESHEET, DocPaths.RESOURCE_FILES.resolve(DocPaths.STYLESHEET), true);
}
copyResource(DocPaths.SCRIPT_JS_TEMPLATE, DocPaths.SCRIPT_FILES.resolve(DocPaths.SCRIPT_JS), true);
copyResource(DocPaths.TOC_JS, DocPaths.SCRIPT_FILES.resolve(DocPaths.TOC_JS), true);
copyResource(DocPaths.LEFT_SVG, DocPaths.RESOURCE_FILES.resolve(DocPaths.LEFT_SVG), true);
copyResource(DocPaths.RIGHT_SVG, DocPaths.RESOURCE_FILES.resolve(DocPaths.RIGHT_SVG), 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);
copyResource(DocPaths.TOGGLE_SVG, DocPaths.RESOURCE_FILES.resolve(DocPaths.TOGGLE_SVG), true);

if (options.createIndex()) {
copyResource(DocPaths.SEARCH_JS_TEMPLATE, DocPaths.SCRIPT_FILES.resolve(DocPaths.SEARCH_JS), true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ public class HtmlIds {
static final HtmlId SERVICES = HtmlId.of("services-summary");
static final HtmlId SKIP_NAVBAR_TOP = HtmlId.of("skip-navbar-top");
static final HtmlId UNNAMED_PACKAGE_ANCHOR = HtmlId.of("unnamed-package");
static final String TOC_ORDER_TOGGLE = "toc-lexical-order-toggle";
static final HtmlId TOC_LIST = HtmlId.of("toc-list");
private static final String FIELDS_INHERITANCE = "fields-inherited-from-class-";
private static final String METHODS_INHERITANCE = "methods-inherited-from-class-";
private static final String NESTED_CLASSES_INHERITANCE = "nested-classes-inherited-from-class-";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ protected Content toContent(boolean hasFilterInput) {
.add(HtmlTree.INPUT(HtmlAttr.InputType.RESET, HtmlStyles.resetFilter)
.put(HtmlAttr.TABINDEX, "-1")
.put(HtmlAttr.VALUE, writer.resources.getText("doclet.filter_reset")));

header.add(Entity.NO_BREAK_SPACE)
.add(HtmlTree.BUTTON(HtmlStyles.tocSortToggle)
.put(HtmlAttr.ID, HtmlIds.TOC_ORDER_TOGGLE)
.add(HtmlTree.IMG(writer.pathToRoot.resolve(DocPaths.RESOURCE_FILES).resolve(DocPaths.TOGGLE_SVG),
writer.resources.getText("doclet.sort_table_of_contents")
))
);

}
content.add(header);
content.add(listBuilder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ private void addScripts(HtmlTree head) {
if (addDefaultScript) {
addScriptElement(head, DocPaths.SCRIPT_JS);
}
addScriptElement(head, DocPaths.TOC_JS);
if (index) {
if (pathToRoot != null && mainBodyScript != null) {
String ptrPath = pathToRoot.isEmpty() ? "." : pathToRoot.getPath();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ public enum HtmlStyles implements HtmlStyle {
*/
tocList,

/**
* The class used for lexical order toggle in the table of contents.
*/
tocSortToggle,

//</editor-fold>

//<editor-fold desc="header (title block)">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1665,3 +1665,37 @@ pre.snippet .highlighted {
display:none;
}
}

nav.toc div.toc-header .toc-sort-toggle {
display: flex;
flex-wrap: nowrap;
align-items: center;
gap: 0.5em;
overflow-x: auto;
}

nav.toc div.toc-header input.filter-input {
flex: 1 1 0;
min-width: 0;
height: 2em;
width: auto;
font-size: 1em;
background-size: 18px;
}

nav.toc div.toc-header button#toc-lexical-order-toggle {
flex: 0 0 auto;
position: static;
display: inline-flex;
align-items: center;
padding: 0.5em;
background: none;
border: none;
cursor: pointer;
}

.main-grid nav.toc button > img {
vertical-align: middle;
width: 20px;
height: 20px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
*/

const LABEL_ALPHA = "Sort lexicographically";
const LABEL_SOURCE = "Sort by source order";

document.addEventListener("DOMContentLoaded", () => {
const sidebarNav = document.querySelector(".main-grid nav.toc")
|| Array.from(document.querySelectorAll("nav.toc"))
.find(n => !n.closest("#navbar-top"));
if (!sidebarNav) return;

const btn = sidebarNav.querySelector("#toc-lexical-order-toggle");
const toc = sidebarNav.querySelector("ol.toc-list");
if (!btn || !toc) return;
const img = btn.querySelector("img");

const sections = Array.from(toc.children);

const nestedMap = new Map();
sections.forEach(section => {
const subList = section.querySelector(":scope > ol.toc-list");
if (subList) {
nestedMap.set(subList, Array.from(subList.children));
}
});

function reorder(mode) {
toc.textContent = "";
sections.forEach(li => toc.appendChild(li));

nestedMap.forEach((originalChildren, subList) => {
subList.textContent = "";
if (mode === "alpha") {
originalChildren
.slice()
.sort((a, b) =>
a.textContent.trim()
.localeCompare(b.textContent.trim(), undefined, {
numeric: true,
sensitivity: "base"
})
)
.forEach(child => subList.appendChild(child));
} else {
originalChildren.forEach(child => subList.appendChild(child));
}
});

const nextLabel = (mode === "alpha") ? LABEL_SOURCE : LABEL_ALPHA;
btn.setAttribute("aria-label", nextLabel);
if (img) img.alt = nextLabel;
localStorage.setItem("toc-order-mode", mode);
}

reorder(localStorage.getItem("toc-order-mode") || "source");

btn.addEventListener("click", () => {
const newMode = (btn.getAttribute("aria-label") === LABEL_ALPHA)
? "alpha"
: "source";
reorder(newMode);
});

btn.blur();
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ doclet.show_sidebar=Show sidebar
doclet.filter_label=Filter contents (type .)
doclet.filter_table_of_contents=Filter table of contents
doclet.filter_reset=Reset
doclet.sort_table_of_contents=Sort table of contents members in lexicographical order
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 \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ public static DocPath indexN(int n) {
/** 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 table of contents toggle javascript file. */
public static final DocPath TOC_JS = DocPath.create("toc.js");

/** The name of the copy-to-clipboard icon file. */
public static final DocPath CLIPBOARD_SVG = DocPath.create("copy.svg");

Expand All @@ -112,6 +115,9 @@ public static DocPath indexN(int n) {
/** The name of the link icon file. */
public static final DocPath LINK_SVG = DocPath.create("link.svg");

/** The name of the table of contents toggle icon file. */
public static final DocPath TOGGLE_SVG = DocPath.create("toggle.svg");

/** The name of the right pointing angle icon. */
public static final DocPath RIGHT_SVG = DocPath.create("right.svg");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ public void testPassThroughFiles(Path base) throws Exception {
"resource-files/stylesheet.css",
"script-files/script.js",
"script-files/search.js",
"script-files/search-page.js"
"script-files/search-page.js",
"script-files/toc.js"
);

for (var f : files) {
Expand Down
3 changes: 2 additions & 1 deletion test/langtools/jdk/javadoc/tool/api/basic/APITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ protected void error(String msg) {
"resource-files/right.svg",
"resource-files/stylesheet.css",
"resource-files/x.svg",
"resource-files/toggle.svg",
"resource-files/fonts/dejavu.css",
"resource-files/fonts/DejaVuLGCSans-Bold.woff",
"resource-files/fonts/DejaVuLGCSans-Bold.woff2",
Expand Down Expand Up @@ -242,6 +243,7 @@ protected void error(String msg) {
"script-files/script.js",
"script-files/search.js",
"script-files/search-page.js",
"script-files/toc.js",
"tag-search-index.js",
"type-search-index.js"
));
Expand All @@ -262,4 +264,3 @@ protected void error(String msg) {
&& !s.equals("system-properties.html"))
.collect(Collectors.toSet());
}