8273034: Make javadoc navigation collapsible on small displays

Reviewed-by: jjg
This commit is contained in:
Hannes Wallnöfer 2021-09-24 08:51:55 +00:00
parent bb74ae87ab
commit 1d44014171
10 changed files with 243 additions and 85 deletions

View File

@ -89,6 +89,8 @@ 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");
static final HtmlId NESTED_CLASS_SUMMARY = HtmlId.of("nested-class-summary");

View File

@ -350,21 +350,28 @@ public class Navigation {
* Adds the summary links to the sub-navigation.
*
* @param tree the content tree to which the sub-navigation will added
* @param nested whether to create a flat or nested list
*/
private void addSummaryLinks(Content tree) {
private void addSummaryLinks(Content tree, boolean nested) {
switch (documentedPage) {
case MODULE, PACKAGE, CLASS, HELP -> {
List<? extends Content> listContents = subNavLinks.getSubNavLinks()
.stream().map(HtmlTree::LI).toList();
if (!listContents.isEmpty()) {
tree.add(HtmlTree.LI(switch (documentedPage) {
Content label = switch (documentedPage) {
case MODULE -> contents.moduleSubNavLabel;
case PACKAGE -> contents.packageSubNavLabel;
case CLASS -> contents.summaryLabel;
case HELP -> contents.helpSubNavLabel;
default -> Text.EMPTY;
}).add(Entity.NO_BREAK_SPACE));
addListToNav(listContents, tree);
};
if (nested) {
tree.add(HtmlTree.LI(HtmlTree.P(label))
.add(new HtmlTree(TagName.UL).add(listContents)));
} else {
tree.add(HtmlTree.LI(label).add(Entity.NO_BREAK_SPACE));
addListToNav(listContents, tree);
}
}
}
}
@ -374,8 +381,9 @@ public class Navigation {
* Adds the detail links to sub-navigation.
*
* @param tree the content tree to which the links will be added
* @param nested whether to create a flat or nested list
*/
private void addDetailLinks(Content tree) {
private void addDetailLinks(Content tree, boolean nested) {
if (documentedPage == PageMode.CLASS) {
List<Content> listContents = new ArrayList<>();
VisibleMemberTable vmt = configuration.getVisibleMemberTable((TypeElement) element);
@ -394,10 +402,16 @@ public class Navigation {
}
}
if (!listContents.isEmpty()) {
Content li = HtmlTree.LI(contents.detailLabel);
li.add(Entity.NO_BREAK_SPACE);
tree.add(li);
addListToNav(listContents, tree);
if (nested) {
Content li = HtmlTree.LI(HtmlTree.P(contents.detailLabel));
li.add(new HtmlTree(TagName.UL).add(listContents));
tree.add(li);
} else {
Content li = HtmlTree.LI(contents.detailLabel);
li.add(Entity.NO_BREAK_SPACE);
tree.add(li);
addListToNav(listContents, tree);
}
}
}
}
@ -605,9 +619,17 @@ public class Navigation {
HtmlTree navDiv = new HtmlTree(TagName.DIV);
Content skipNavLinks = contents.getContent("doclet.Skip_navigation_links");
String toggleNavLinks = configuration.getDocResources().getText("doclet.Toggle_navigation_links");
tree.add(MarkerComments.START_OF_TOP_NAVBAR);
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(HtmlTree.SPAN(HtmlStyle.navBarToggleIcon, HtmlTree.EMPTY))
.add(HtmlTree.SPAN(HtmlStyle.navBarToggleIcon, HtmlTree.EMPTY))
.add(HtmlTree.SPAN(HtmlStyle.navBarToggleIcon, HtmlTree.EMPTY)))
.add(HtmlTree.DIV(HtmlStyle.skipNav,
links.createLink(HtmlIds.SKIP_NAVBAR_TOP, skipNavLinks,
skipNavLinks.toString())));
@ -622,18 +644,22 @@ public class Navigation {
.put(HtmlAttr.TITLE, rowListTitle);
addMainNavLinks(navList);
navDiv.add(navList);
HtmlTree ulNavSummaryRight = new HtmlTree(TagName.UL).setStyle(HtmlStyle.subNavListSmall);
addSummaryLinks(ulNavSummaryRight, true);
addDetailLinks(ulNavSummaryRight, true);
navDiv.add(ulNavSummaryRight);
tree.add(navDiv);
HtmlTree subDiv = new HtmlTree(TagName.DIV).setStyle(HtmlStyle.subNav);
HtmlTree div = new HtmlTree(TagName.DIV);
HtmlTree div = new HtmlTree(TagName.DIV).setId(HtmlIds.NAVBAR_SUB_LIST);
// Add the summary links if present.
HtmlTree ulNavSummary = new HtmlTree(TagName.UL).setStyle(HtmlStyle.subNavList);
addSummaryLinks(ulNavSummary);
addSummaryLinks(ulNavSummary, false);
div.add(ulNavSummary);
// Add the detail links if present.
HtmlTree ulNavDetail = new HtmlTree(TagName.UL).setStyle(HtmlStyle.subNavList);
addDetailLinks(ulNavDetail);
addDetailLinks(ulNavDetail, false);
div.add(ulNavDetail);
subDiv.add(div);

View File

@ -38,6 +38,8 @@ import jdk.javadoc.internal.doclets.toolkit.util.Utils;
public enum HtmlAttr {
ALT,
ARIA_CONTROLS("aria-controls"),
ARIA_EXPANDED("aria-expanded"),
ARIA_LABEL("aria-label"),
ARIA_LABELLEDBY("aria-labelledby"),
ARIA_ORIENTATION("aria-orientation"),
ARIA_SELECTED("aria-selected"),

View File

@ -103,6 +103,11 @@ public enum HtmlStyle {
// The etymology of the name is a mystery.
navBarCell1Rev,
/**
* The class for the navigation bar toggle button for smaller displays.
*/
navBarToggleIcon,
/**
* The class for the primary list of navigation links.
*/
@ -130,6 +135,11 @@ public enum HtmlStyle {
*/
subNavList,
/**
* The class for the list of subsidiary navigation links for smaller displays.
*/
subNavListSmall,
//</editor-fold>
//<editor-fold desc="header (title block)">

View File

@ -291,6 +291,35 @@ function doSearch(request, response) {
response(result);
}
$(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 {
$("div#navbar-top").height($("#navbar-top").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);
$(window).on("orientationchange", collapse).on("resize", function(e) {
if (expanded && windowWidth !== window.innerWidth) collapse();
});
$("#search-input").catcomplete({
minLength: 1,
delay: 300,

View File

@ -78,6 +78,7 @@ doclet.Window_Single_Index=Index
doclet.Window_Split_Index={0}-Index
doclet.Help=Help
doclet.Skip_navigation_links=Skip navigation links
doclet.Toggle_navigation_links=Toggle navigation links
doclet.Navigation=Navigation
doclet.navDeprecated=Deprecated
doclet.Window_Deprecated_List=Deprecated List

View File

@ -128,17 +128,17 @@ button {
* Styles for navigation bar.
*/
@media screen {
.flex-box {
div.flex-box {
position:fixed;
display:flex;
flex-direction:column;
height: 100%;
width: 100%;
}
.flex-header {
header.flex-header {
flex: 0 0 auto;
}
.flex-content {
div.flex-content {
flex: 1 1 auto;
overflow-y: auto;
}
@ -155,6 +155,12 @@ button {
overflow:hidden;
font-size:12px;
}
button#navbar-toggle-button {
display:none;
}
ul.sub-nav-list-small {
display: none;
}
.sub-nav {
background-color:#dee3e9;
float:left;
@ -165,11 +171,11 @@ button {
.sub-nav div {
clear:left;
float:left;
padding:0 0 5px 6px;
padding:6px;
text-transform:uppercase;
}
.sub-nav .nav-list {
padding-top:5px;
.sub-nav .sub-nav-list {
padding-top:4px;
}
ul.nav-list {
display:block;
@ -189,28 +195,23 @@ ul.nav-list li {
}
.sub-nav .nav-list-search {
float:right;
margin:0 0 0 0;
padding:5px 6px;
margin:0;
padding:6px;
clear:none;
}
.nav-list-search label {
text-align:right;
position:relative;
right:-16px;
}
ul.sub-nav-list li {
list-style:none;
float:left;
padding-top:10px;
}
.top-nav a:link, .top-nav a:active, .top-nav a:visited {
color:#FFFFFF;
color:#ffffff;
text-decoration:none;
text-transform:uppercase;
}
.top-nav a:hover {
text-decoration:none;
color:#bb7a2a;
text-transform:uppercase;
}
.nav-bar-cell1-rev {
background-color:#F8981D;
@ -626,23 +627,22 @@ ul.ui-autocomplete li {
background-repeat:no-repeat;
background-position:2px 3px;
padding-left:20px;
position:relative;
right:-18px;
width:400px;
width: 250px;
margin: 0;
}
#reset-button {
background-color: rgb(255,255,255);
background-color: transparent;
background-image:url('resources/x.png');
background-position:center;
background-repeat:no-repeat;
background-size:12px;
border:0 none;
width:16px;
height:16px;
position:relative;
left:-4px;
top:-4px;
font-size:0px;
background-size:contain;
border:0;
border-radius:0;
width:12px;
height:12px;
position:absolute;
right:12px;
top:10px;
font-size:0;
}
.watermark {
color:#545454;
@ -807,34 +807,113 @@ table.striped > tbody > tr > th {
font-weight: normal;
}
/**
* Tweak font sizes and paddings for small screens.
* Tweak style for small screens.
*/
@media screen and (max-width: 1050px) {
#search-input {
width: 300px;
@media screen and (max-width: 920px) {
header.flex-header {
max-height: 100vh;
overflow-y: auto;
}
div#navbar-top {
height: 2.8em;
transition: height 0.35s ease;
}
ul.nav-list {
display: block;
width: 40%;
float:left;
clear: left;
margin: 10px 0 0 0;
padding: 0;
}
ul.nav-list li {
float: none;
padding: 6px;
margin-left: 10px;
margin-top: 2px;
}
ul.sub-nav-list-small {
display:block;
height: 100%;
width: 50%;
float: right;
clear: right;
background-color: #dee3e9;
color: #353833;
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:#4A6782;
}
ul.sub-nav-list-small a:hover {
color:#bb7a2a;
}
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;
}
button#navbar-toggle-button {
width: 3.4em;
height: 2.8em;
background-color: transparent;
display: block;
float: left;
border: 0;
margin: 0 10px;
cursor: pointer;
font-size: 10px;
}
button#navbar-toggle-button .nav-bar-toggle-icon {
display: block;
width: 24px;
height: 3px;
margin: 1px 0 4px 0;
border-radius: 2px;
transition: all 0.1s;
background-color: #ffffff;
}
button#navbar-toggle-button.expanded span.nav-bar-toggle-icon:nth-child(1) {
transform: rotate(45deg);
transform-origin: 10% 10%;
width: 26px;
}
button#navbar-toggle-button.expanded span.nav-bar-toggle-icon:nth-child(2) {
opacity: 0;
}
button#navbar-toggle-button.expanded span.nav-bar-toggle-icon:nth-child(3) {
transform: rotate(-45deg);
transform-origin: 10% 90%;
width: 26px;
}
}
@media screen and (max-width: 800px) {
#search-input {
width: 200px;
}
.top-nav,
.bottom-nav {
font-size: 11px;
padding-top: 6px;
}
.sub-nav {
font-size: 11px;
}
.about-language {
padding-right: 16px;
}
ul.nav-list li,
.sub-nav .nav-list-search {
padding: 6px;
ul.nav-list li {
margin-left: 5px;
}
ul.sub-nav-list li {
padding-top: 5px;
ul.sub-nav-list-small > li {
margin-left: 5px;
}
main {
padding: 10px;
@ -847,22 +926,31 @@ table.striped > tbody > tr > th {
-webkit-text-size-adjust: none;
}
}
@media screen and (max-width: 500px) {
#search-input {
width: 150px;
}
.top-nav,
.bottom-nav {
font-size: 10px;
}
.sub-nav {
font-size: 10px;
}
@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 {
width: 70%;
}
}
@media screen and (max-width: 320px) {
.nav-list-search > label {
display: none;
}
.nav-list-search {
width: 90%;
}
#search-input {
width: 80%;
}
}
pre.snippet {
background-color: #ebecee;

View File

@ -151,7 +151,7 @@ public class CheckStylesheetClasses {
// (a) it is a poorly chosen name
// (b) it does not seem to be used in make/Docs.gmk or anywhere else
removeAll(styleSheetNames, "all-classes-container", "all-packages-container",
"bottom-nav", "clear", "constant-values-container", "deprecated-content",
"clear", "constant-values-container", "deprecated-content", "expanded",
"footer", "hidden", "override-specify-label", "serialized-class-details",
"tab", "table-sub-heading-color");

View File

@ -52,7 +52,7 @@ public class TestPackageSummary extends JavadocTester {
checkOutput("pkg/package-summary.html", true,
"""
<div class="sub-nav">
<div>
<div id="navbar-sub-list">
<ul class="sub-nav-list">
<li>Package:&nbsp;</li>
<li>Description&nbsp;|&nbsp;</li>
@ -63,7 +63,7 @@ public class TestPackageSummary extends JavadocTester {
checkOutput("pkg1/package-summary.html", true,
"""
<div class="sub-nav">
<div>
<div id="navbar-sub-list">
<ul class="sub-nav-list">
<li>Package:&nbsp;</li>
<li><a href="#package-description">Description</a>&nbsp;|&nbsp;</li>
@ -74,7 +74,7 @@ public class TestPackageSummary extends JavadocTester {
checkOutput("pkg1/sub/package-summary.html", true,
"""
<div class="sub-nav">
<div>
<div id="navbar-sub-list">
<ul class="sub-nav-list">
<li>Package:&nbsp;</li>
<li>Description&nbsp;|&nbsp;</li>

View File

@ -180,18 +180,18 @@ public class TestStylesheet extends JavadocTester {
}""",
"""
#reset-button {
background-color: rgb(255,255,255);
background-color: transparent;
background-image:url('resources/x.png');
background-position:center;
background-repeat:no-repeat;
background-size:12px;
border:0 none;
width:16px;
height:16px;
position:relative;
left:-4px;
top:-4px;
font-size:0px;
background-size:contain;
border:0;
border-radius:0;
width:12px;
height:12px;
position:absolute;
right:12px;
top:10px;
font-size:0;
}""",
"""
.watermark {