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 47b2322226ee8..948ae0f61ff7e 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 @@ -327,6 +327,9 @@ protected void generateOtherFiles(ClassTree classTree) 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.MOON_SVG, DocPaths.RESOURCE_FILES.resolve(DocPaths.MOON_SVG), true); + copyResource(DocPaths.SUN_SVG, DocPaths.RESOURCE_FILES.resolve(DocPaths.SUN_SVG), true); + copyResource(DocPaths.SYSTEM_SVG, DocPaths.RESOURCE_FILES.resolve(DocPaths.SYSTEM_SVG), true); if (options.createIndex()) { copyResource(DocPaths.SEARCH_JS_TEMPLATE, DocPaths.SCRIPT_FILES.resolve(DocPaths.SEARCH_JS), true); 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 42d93c41e116a..c257e1e153c86 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 @@ -114,6 +114,11 @@ public class HtmlIds { 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"); + static final HtmlId THEME_BUTTON = HtmlId.of("theme-button"); + static final HtmlId THEME_DARK = HtmlId.of("theme-dark"); + static final HtmlId THEME_LIGHT = HtmlId.of("theme-light"); + static final HtmlId THEME_OS = HtmlId.of("theme-os"); + static final HtmlId THEME_PANEL = HtmlId.of("theme-panel"); static final HtmlId UNNAMED_PACKAGE_ANCHOR = HtmlId.of("unnamed-package"); private static final String FIELDS_INHERITANCE = "fields-inherited-from-class-"; private static final String METHODS_INHERITANCE = "methods-inherited-from-class-"; 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 61af26259af4e..3d45812563575 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 @@ -543,8 +543,32 @@ public Content getContent() { navContent.add(navList); var aboutDiv = HtmlTree.DIV(HtmlStyles.aboutLanguage, aboutContent); navContent.add(aboutDiv); + var selectTheme = contents.getContent("doclet.theme.select_theme"); + navContent.add(HtmlTree.BUTTON(HtmlIds.THEME_BUTTON) + .add(HtmlTree.IMG(pathToRoot.resolve(DocPaths.RESOURCE_FILES).resolve(DocPaths.SUN_SVG), + selectTheme.toString()).addStyle(HtmlIds.THEME_LIGHT.name())) + .add(HtmlTree.IMG(pathToRoot.resolve(DocPaths.RESOURCE_FILES).resolve(DocPaths.MOON_SVG), + selectTheme.toString()).addStyle(HtmlIds.THEME_DARK.name())) + .add(HtmlTree.IMG(pathToRoot.resolve(DocPaths.RESOURCE_FILES).resolve(DocPaths.SYSTEM_SVG), + selectTheme.toString()).addStyle(HtmlIds.THEME_OS.name())) + .put(HtmlAttr.ARIA_LABEL, selectTheme.toString())); + navContent.add(HtmlTree.DIV(HtmlIds.THEME_PANEL) + .add(HtmlTree.DIV(selectTheme)) + .add(HtmlTree.DIV(HtmlTree.LABEL(HtmlIds.THEME_LIGHT.name(), Text.EMPTY) + .add(HtmlTree.INPUT(HtmlAttr.InputType.RADIO, HtmlIds.THEME_LIGHT) + .put(HtmlAttr.NAME, "theme").put(HtmlAttr.VALUE, HtmlIds.THEME_LIGHT.name())) + .add(HtmlTree.SPAN(contents.getContent("doclet.theme.light")))) + .add(HtmlTree.LABEL(HtmlIds.THEME_DARK.name(), Text.EMPTY) + .add(HtmlTree.INPUT(HtmlAttr.InputType.RADIO, HtmlIds.THEME_DARK) + .put(HtmlAttr.NAME, "theme").put(HtmlAttr.VALUE, HtmlIds.THEME_DARK.name())) + .add(HtmlTree.SPAN(contents.getContent("doclet.theme.dark")))) + .add(HtmlTree.LABEL(HtmlIds.THEME_OS.name(), Text.EMPTY) + .add(HtmlTree.INPUT(HtmlAttr.InputType.RADIO, HtmlIds.THEME_OS) + .put(HtmlAttr.NAME, "theme").put(HtmlAttr.VALUE, HtmlIds.THEME_OS.name())) + .add(HtmlTree.SPAN(contents.getContent("doclet.theme.system")))))); navigationBar.add(HtmlTree.DIV(HtmlStyles.topNav, navContent).setId(HtmlIds.NAVBAR_TOP)); + var subNavContent = HtmlTree.DIV(HtmlStyles.navContent); List subNavLinks = new ArrayList<>(); switch (documentedPage) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/glass.svg b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/glass.svg index ff7df85e8f66e..c979c9f3d83ec 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/glass.svg +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/glass.svg @@ -8,6 +8,6 @@ --> - - - \ No newline at end of file + + + diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/highlight.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/highlight.css index 145c1c7f5d281..050c27f1bb87f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/highlight.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/highlight.css @@ -65,3 +65,188 @@ /* ignored */ } +body.theme-dark { + .hljs-title.function_, + .hljs-template-variable { + color: #66bcce; + } + .hljs-code, + .hljs-comment, + .hljs-quote { + color:#999999; + font-style: italic; + } + .hljs-meta { + color: #836F00; + } + .hljs-symbol, + .hljs-template-tag, + .hljs-keyword, + .hljs-literal, + .hljs-name, + .hljs-built_in, + .hljs-char.escape_ { + color: #88aece; + } + .hljs-variable, + .hljs-property, + .hljs-attr, + .hljs-section { + color: #c59bc1; + } + .hljs-attribute { + color: #c59bc1; + } + .hljs-regexp, + .hljs-number { + color: #cfe374; + } + .hljs-link { + color: #b5bd68; + } + .hljs-string { + color: #b5bd68; + } + .hljs-doctag { + text-decoration: underline; + } + .hljs-emphasis { + font-style: italic; + } + .hljs-strong { + font-weight: bold; + } + .hljs-subst, + .hljs-title, + .hljs-params, + .hljs-bullet, + .hljs-formula, + .hljs-tag, + .hljs-type { + /* ignored */ + } +} + +@media (prefers-color-scheme: dark) { + .hljs-title.function_, + .hljs-template-variable { + color: #66bcce; + } + .hljs-code, + .hljs-comment, + .hljs-quote { + color:#999999; + font-style: italic; + } + .hljs-meta { + color: #836F00; + } + .hljs-symbol, + .hljs-template-tag, + .hljs-keyword, + .hljs-literal, + .hljs-name, + .hljs-built_in, + .hljs-char.escape_ { + color: #88aece; + } + .hljs-variable, + .hljs-property, + .hljs-attr, + .hljs-section { + color: #c59bc1; + } + .hljs-attribute { + color: #c59bc1; + } + .hljs-regexp, + .hljs-number { + color: #cfe374; + } + .hljs-link { + color: #b5bd68; + } + .hljs-string { + color: #b5bd68; + } + .hljs-doctag { + text-decoration: underline; + } + .hljs-emphasis { + font-style: italic; + } + .hljs-strong { + font-weight: bold; + } + .hljs-subst, + .hljs-title, + .hljs-params, + .hljs-bullet, + .hljs-formula, + .hljs-tag, + .hljs-type { + /* ignored */ + } + + body.theme-light { + .hljs-title.function_, + .hljs-template-variable { + color: #00738F; + } + .hljs-code, + .hljs-comment, + .hljs-quote { + color: #6e6e71; + font-style: italic; + } + .hljs-meta { + color: #836F00; + } + .hljs-symbol, + .hljs-template-tag, + .hljs-keyword, + .hljs-literal, + .hljs-name, + .hljs-built_in, + .hljs-char.escape_ { + color: #0C40C2; + } + .hljs-variable, + .hljs-property, + .hljs-attr, + .hljs-section { + color: #841191; + } + .hljs-attribute { + color: #164ad9; + } + .hljs-regexp, + .hljs-number { + color: #104BEB; + } + .hljs-link { + color: #47688a; + } + .hljs-string { + color: #008313; + } + .hljs-doctag { + text-decoration: underline; + } + .hljs-emphasis { + font-style: italic; + } + .hljs-strong { + font-weight: bold; + } + .hljs-subst, + .hljs-title, + .hljs-params, + .hljs-bullet, + .hljs-formula, + .hljs-tag, + .hljs-type { + /* ignored */ + } + } +} diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/moon.svg b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/moon.svg new file mode 100644 index 0000000000000..856a8ffeeec21 --- /dev/null +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/moon.svg @@ -0,0 +1,15 @@ + + + + + + + + + + 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 index d3b59f4f40bea..b8e8ebc535adf 100644 --- 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 @@ -351,6 +351,40 @@ document.addEventListener("DOMContentLoaded", function(e) { const mainnav = navbar.querySelector("ul.nav-list"); const toggleButton = document.querySelector("button#navbar-toggle-button"); const tocMenu = sidebar ? sidebar.cloneNode(true) : null; + const themeButton = document.querySelector("button#theme-button"); + const themePanel = document.querySelector("div#theme-panel"); + var themePanelVisible = false; + themeButton.addEventListener("click", e => { + if (!themePanelVisible) { + themePanel.style.display = "block"; + themeButton.setAttribute("aria-expanded", "true"); + themePanelVisible = true; + e.stopPropagation(); + } + }); + function closeThemePanel(e) { + if (themePanelVisible && (!e || !themePanel.contains(e.target))) { + themePanel.style.removeProperty("display"); + themeButton.setAttribute("aria-expanded", "false"); + themePanelVisible = false; + } + } + themePanel.querySelectorAll("input").forEach(input => { + input.removeAttribute("disabled"); + input.addEventListener("change", e => { + setTheme(e.target.value); + }) + }); + const THEMES = ["theme-light", "theme-dark", "theme-os"]; + function setTheme(theme) { + THEMES.forEach(t => { + if (t !== theme) document.body.classList.remove(t); + }); + document.body.classList.add(theme); + localStorage.setItem("theme", theme); + document.getElementById(theme).checked = true; + } + setTheme(localStorage.getItem("theme") || THEMES[0]); makeFilterWidget(sidebar, updateToc); if (tocMenu) { navbar.appendChild(tocMenu); @@ -362,6 +396,7 @@ document.addEventListener("DOMContentLoaded", function(e) { return; } if (!isInput(e.target) && keymap.has(e.key)) { + closeThemePanel(); var elem = keymap.get(e.key); if (elem === filterInput && !elem.offsetParent) { elem = getVisibleFilterInput(true); @@ -370,6 +405,7 @@ document.addEventListener("DOMContentLoaded", function(e) { elem.select(); e.preventDefault(); } else if (e.key === "Escape") { + closeThemePanel(); if (expanded) { collapse(); e.preventDefault(); @@ -457,6 +493,7 @@ document.addEventListener("DOMContentLoaded", function(e) { }); } document.querySelector("main").addEventListener("click", collapse); + document.querySelector("body").addEventListener("click", closeThemePanel); document.querySelectorAll("h1, h2, h3, h4, h5, h6") .forEach((hdr, idx) => { // Create anchor links for headers with an associated id attribute diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties index 76b223bf130b9..631d8fcf5c52f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties @@ -194,6 +194,10 @@ doclet.Window_Help_title=API Help doclet.references={0} references doclet.Window_Search_title=Search doclet.search.main_heading=Search +doclet.theme.select_theme=Select Theme +doclet.theme.light=Light +doclet.theme.dark=Dark +doclet.theme.system=System Setting # label for link/button element to show the information below doclet.search.show_more=Additional resources 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 2c10cb3bc6f82..99a9e12ccf455 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 @@ -28,13 +28,35 @@ /* Line height for continuous text blocks */ --block-line-height: 1.5; --code-line-height: 1.6; + /* Navigation bar and content area dimensions */ + --top-nav-height: 44px; + --sub-nav-height: 36px; + --nav-height: calc(var(--top-nav-height) + var(--sub-nav-height)); + --max-content-width: 1500px; + --content-margin: 0 auto; + /* Inline SVG icons for dark theme */ + --right-svg-dark: url('data:image/svg+xml; utf8, \ + \ + \ + '); + --glass-svg-dark: url('data:image/svg+xml; utf8, \ + \ + \ + '); + --x-svg-dark: url('data:image/svg+xml; utf8, \ + \ + \ + '); +} +body { /* Text colors for body and block elements */ --body-text-color: #282828; --block-text-color: #282828; /* Background colors for various elements */ --body-background-color: #ffffff; --section-background-color: var(--body-background-color); - --detail-background-color: #ffffff; + --detail-background-color: var(--body-background-color); --code-background-color: #f5f5f5; --mark-background-color: #f7f7f7; --detail-block-color: #f4f4f4; @@ -76,7 +98,7 @@ /* Search input colors */ --search-input-background-color: #ffffff; --search-input-text-color: #000000; - --search-input-placeholder-color: #909090; + --search-input-placeholder-color: #757575; /* Highlight color for active search tag target */ --search-tag-highlight-color: #ffff66; /* Copy button colors and filters */ @@ -86,12 +108,155 @@ /* 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: 36px; - --nav-height: calc(var(--top-nav-height) + var(--sub-nav-height)); - --max-content-width: 1500px; - --content-margin: 0 auto; +} + +body.theme-dark { + --body-text-color: #e8e8e8; + --block-text-color: #e8e8e8; + --body-background-color: #222528; + --section-background-color: var(--body-background-color); + --detail-background-color: var(--body-background-color); + --code-background-color: #303940; + --mark-background-color: #313131; + --detail-block-color: #f4f4f4; + --navbar-background-color: #395A6F; + --navbar-text-color: #ffffff; + --subnav-background-color: #3d454d; + --subnav-link-color: #f5ae29; + --member-heading-background-color: var(--subnav-background-color); + --selected-background-color: #f8981d; + --selected-text-color: #253441; + --selected-link-color: #4a698a; + --table-header-color: #38444d; + --even-row-color: #222528; + --odd-row-color: #2d3135; + --title-color: #fff; + --link-color: #e6a52a; + --link-color-active: #ffb45b; + --toc-background-color: #31363c; + --toc-highlight-color: var(--subnav-background-color); + --toc-hover-color: #3f4146; + --snippet-background-color: #2d363c; + --snippet-text-color: var(--block-text-color); + --snippet-highlight-color: #f7c590; + --pre-background-color: var(--snippet-background-color); + --pre-text-color: var(--snippet-text-color); + --border-color: #444444; + --table-border-color: #717171; + --tab-border-radius: 2px 2px 0 0; + --search-input-background-color: #303030; + --search-input-text-color: #d0d0d0; + --search-input-placeholder-color: #979797; + --search-tag-highlight-color: #ffff66; + --button-border-color: #909090; + --button-active-filter: brightness(96%); + --button-focus-filter: brightness(104%); + --invalid-tag-background-color: #ffe6e6; + --invalid-tag-text-color: #000000; + div.main-grid img { + filter: invert(100%) sepia(4%) saturate(98%) hue-rotate(212deg) brightness(160%) contrast(160%); + } +} + +/* + * Dark theme + */ +@media (prefers-color-scheme: dark) { + body { + --body-text-color: #e8e8e8; + --block-text-color: #e8e8e8; + --body-background-color: #222528; + --section-background-color: var(--body-background-color); + --detail-background-color: var(--body-background-color); + --code-background-color: #303940; + --mark-background-color: #313131; + --detail-block-color: #f4f4f4; + --navbar-background-color: #395A6F; + --navbar-text-color: #ffffff; + --subnav-background-color: #3d454d; + --subnav-link-color: #f5ae29; + --member-heading-background-color: var(--subnav-background-color); + --selected-background-color: #f8981d; + --selected-text-color: #253441; + --selected-link-color: #4a698a; + --table-header-color: #38444d; + --even-row-color: #222528; + --odd-row-color: #2d3135; + --title-color: #fff; + --link-color: #e6a52a; + --link-color-active: #ffb45b; + --toc-background-color: #31363c; + --toc-highlight-color: var(--subnav-background-color); + --toc-hover-color: #3f4146; + --snippet-background-color: #2d363c; + --snippet-text-color: var(--block-text-color); + --snippet-highlight-color: #f7c590; + --pre-background-color: var(--snippet-background-color); + --pre-text-color: var(--snippet-text-color); + --border-color: #444444; + --table-border-color: #717171; + --tab-border-radius: 2px 2px 0 0; + --search-input-background-color: #303030; + --search-input-text-color: #d0d0d0; + --search-input-placeholder-color: #979797; + --search-tag-highlight-color: #ffff66; + --button-border-color: #909090; + --button-active-filter: brightness(96%); + --button-focus-filter: brightness(104%); + --invalid-tag-background-color: #ffe6e6; + --invalid-tag-text-color: #000000; + div.main-grid img { + filter: invert(100%) sepia(4%) saturate(98%) hue-rotate(212deg) brightness(160%) contrast(160%); + } + } + + body.theme-light { + --body-text-color: #282828; + --block-text-color: #282828; + --body-background-color: #ffffff; + --section-background-color: var(--body-background-color); + --detail-background-color: var(--body-background-color); + --code-background-color: #f5f5f5; + --mark-background-color: #f7f7f7; + --detail-block-color: #f4f4f4; + --navbar-background-color: #4D7A97; + --navbar-text-color: #ffffff; + --subnav-background-color: #dee3e9; + --subnav-link-color: #47688a; + --member-heading-background-color: var(--subnav-background-color); + --selected-background-color: #f8981d; + --selected-text-color: #253441; + --selected-link-color: #4a698a; + --table-header-color: #ebeff4; + --even-row-color: #ffffff; + --odd-row-color: #f0f0f2; + --title-color: #2c4557; + --link-color: #437291; + --link-color-active: #bb7a2a; + --toc-background-color: #f8f8f8; + --toc-highlight-color: var(--subnav-background-color); + --toc-hover-color: #e9ecf0; + --snippet-background-color: #f2f2f4; + --snippet-text-color: var(--block-text-color); + --snippet-highlight-color: #f7c590; + --pre-background-color: var(--snippet-background-color); + --pre-text-color: var(--snippet-text-color); + --border-color: #e6e6e6; + --table-border-color: #000000; + --tab-border-radius: 2px 2px 0 0; + --search-input-background-color: #ffffff; + --search-input-text-color: #000000; + --search-input-placeholder-color: #757575; + --search-tag-highlight-color: #ffff66; + --button-border-color: #b0b8c8; + --button-active-filter: brightness(96%); + --button-focus-filter: brightness(104%); + --invalid-tag-background-color: #ffe6e6; + --invalid-tag-text-color: #000000; + div.main-grid img { + filter: none; + } + } } /* * Styles for individual HTML elements. @@ -186,7 +351,7 @@ hr { */ .about-language { flex: 0 0 auto; - padding:0 20px; + padding:0 15px; margin:0; font-size:0.915em; max-width: 50%; @@ -215,6 +380,7 @@ hr { height: 100%; max-width: var(--max-content-width); margin: var(--content-margin); + position: relative; } .top-nav { background-color:var(--navbar-background-color); @@ -236,6 +402,62 @@ hr { button#navbar-toggle-button { display:none; } +button#theme-button { + width: 34px; + height: 34px; + padding: 5px; + margin-right: 4px; + background-color: transparent; + border: 1px solid transparent; + border-radius: 6px; + cursor: pointer; +} +button#theme-button:hover, +button#theme-button:focus-visible { + border: 1px solid var(--button-border-color); +} +button#theme-button img { + display: none; +} +body.theme-light button#theme-button img.theme-light { + display: inline; +} +body.theme-dark button#theme-button img.theme-dark { + display: inline; +} +body.theme-os button#theme-button img.theme-os { + display: inline; +} +div#theme-panel { + display: none; + position: absolute; + top: calc(var(--top-nav-height) - 2px); + right: 6px; + z-index: 8; + background-color: var(--toc-background-color); + color: var(--body-text-color); + padding: 4px; + white-space: nowrap; + border: 1px solid var(--border-color); + border-radius: 6px; + border-top-right-radius: 0; + box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); + +} +div#theme-panel div:first-child { + font-weight: bold; + font-size: 16px; +} +div#theme-panel div { + padding: 8px; +} +div#theme-panel label { + margin-right: 8px; + cursor: pointer; +} +div#theme-panel input { + margin-right: 4px; +} ul.nav-list { display:inline-flex; margin:0; @@ -281,6 +503,17 @@ ol.sub-nav-list li:not(:first-child) { padding-left: 17px; list-style: none; } +body.theme-dark ol.sub-nav-list li:not(:first-child) { + background-image: var(--right-svg-dark); +} +@media (prefers-color-scheme: dark) { + ol.sub-nav-list li:not(:first-child) { + background-image: var(--right-svg-dark); + } + body.theme-light ol.sub-nav-list li:not(:first-child) { + background-image: url("right.svg"); + } +} ol.sub-nav-list a { padding: 3px; } @@ -1015,7 +1248,7 @@ li.ui-static-link a, li.ui-static-link a:visited { .ui-autocomplete .search-result-desc { font-size: var(--nav-font-size); padding: 2px 4px; - color: #404040; + color: var(--block-text-color); overflow: hidden; text-overflow: ellipsis; } @@ -1023,7 +1256,7 @@ li.ui-static-link a, li.ui-static-link a:visited { font-weight:bold; } .ui-menu .ui-state-active .search-result-desc { - color: #383838; + color: var(--selected-text-color); } .ui-menu .ui-menu-item-wrapper { padding: 3px 4px; @@ -1042,6 +1275,17 @@ input[type="text"] { font-size: var(--nav-font-size); height: 19px; } +body.theme-dark input[type="text"] { + background-image: var(--glass-svg-dark); +} +@media (prefers-color-scheme: dark) { + input[type="text"] { + background-image: var(--glass-svg-dark); + } + body.theme-light input[type="text"] { + background-image: url('glass.svg'); + } +} input#page-search-input { width: calc(180px + 10vw); margin: 10px 0; @@ -1069,6 +1313,21 @@ input#reset-search, input.reset-filter, input#page-search-reset { font-size:0; visibility:hidden; } +body.theme-dark input#reset-search, +body.theme-dark input.reset-filter, +body.theme-dark input#page-search-reset { + background-image: var(--x-svg-dark); +} +@media (prefers-color-scheme: dark) { + input#reset-search, input.reset-filter, input#page-search-reset { + background-image: var(--x-svg-dark); + } + body.theme-light input#reset-search, + body.theme-light input.reset-filter, + body.theme-light input#page-search-reset { + background-image: url('x.svg'); + } +} input#reset-search { position:absolute; right:5px; @@ -1101,6 +1360,7 @@ select#search-modules { } kbd { background-color: #eeeeee; + color: #282828; border: 1px solid #b0b0b0; border-radius: 3px; padding: 0 4px; @@ -1160,6 +1420,7 @@ div#result-container { #result-container div.result-table > a.search-result-link:focus-visible, #result-container div.result-table > a.search-result-link.selected { background-color: var(--selected-background-color); + color: var(--selected-text-color); outline: none; } #result-container div.result-table > a.search-result-link .search-result-label { @@ -1168,7 +1429,6 @@ div#result-container { } #result-container div.result-table > a.search-result-link .search-result-desc { font-size: var(--nav-font-size); - color: #404040; overflow: hidden; text-overflow: ellipsis; } @@ -1502,17 +1762,6 @@ table.striped > tbody > tr > th { .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: visible; @@ -1603,7 +1852,6 @@ table.striped > tbody > tr > th { } @media screen and (max-width: 800px) { .about-language { - padding: 0 16px; max-width: 90%; } ul.nav-list li { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/sun.svg b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/sun.svg new file mode 100644 index 0000000000000..e8fa03499acc3 --- /dev/null +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/sun.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/system.svg b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/system.svg new file mode 100644 index 0000000000000..982d69242da1d --- /dev/null +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/system.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/x.svg b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/x.svg index 1efb410924132..34a942ffff10b 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/x.svg +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/x.svg @@ -8,6 +8,6 @@ --> - - - \ No newline at end of file + + + 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 21f1267361954..ca17da44da2bb 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 @@ -115,6 +115,15 @@ public static DocPath indexN(int n) { /** The name of the right pointing angle icon. */ public static final DocPath RIGHT_SVG = DocPath.create("right.svg"); + /** The name of the moon icon for the dark theme. */ + public static final DocPath MOON_SVG = DocPath.create("moon.svg"); + + /** The name of the sun icon for the light theme. */ + public static final DocPath SUN_SVG = DocPath.create("sun.svg"); + + /** The name of the sun icon for the theme set by system setting. */ + public static final DocPath SYSTEM_SVG = DocPath.create("system.svg"); + /** The name of the syntax highlighting style sheet. */ public static final DocPath HIGHLIGHT_CSS = DocPath.create("highlight.css"); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/html/HtmlAttr.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/html/HtmlAttr.java index 10aa7c0c57b26..2ef3ae9db2a06 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/html/HtmlAttr.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/html/HtmlAttr.java @@ -203,6 +203,7 @@ public String toString() { public enum InputType { CHECKBOX, + RADIO, RESET, TEXT; diff --git a/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java b/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java index ee1fa538a57d6..ba846c293a23b 100644 --- a/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java +++ b/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java @@ -143,6 +143,9 @@ void run() throws Exception { "search-result-desc", "search-result-label", "search-result-link", "selected", "sort-asc", "sort-desc", "two-column-search-results", "visible"); + // used for themes + removeAll(styleSheetNames, "theme-dark", "theme-light", "theme-os"); + // very JDK specific styleSheetNames.remove("module-graph"); styleSheetNames.remove("sealed-graph"); diff --git a/test/langtools/jdk/javadoc/doclet/testSpecTag/TestSpecTag.java b/test/langtools/jdk/javadoc/doclet/testSpecTag/TestSpecTag.java index 98b9b2232a226..7181b4f931ed7 100644 --- a/test/langtools/jdk/javadoc/doclet/testSpecTag/TestSpecTag.java +++ b/test/langtools/jdk/javadoc/doclet/testSpecTag/TestSpecTag.java @@ -127,18 +127,6 @@ public void testNavigation(Path base) throws IOException {
  • Search
  • Help
  • - - - - """); } diff --git a/test/langtools/jdk/javadoc/tool/api/basic/APITest.java b/test/langtools/jdk/javadoc/tool/api/basic/APITest.java index 2d45d6c7a8f0f..522f3327959e1 100644 --- a/test/langtools/jdk/javadoc/tool/api/basic/APITest.java +++ b/test/langtools/jdk/javadoc/tool/api/basic/APITest.java @@ -209,8 +209,11 @@ protected void error(String msg) { "resource-files/jquery-ui.min.css", "resource-files/left.svg", "resource-files/link.svg", + "resource-files/moon.svg", "resource-files/right.svg", "resource-files/stylesheet.css", + "resource-files/sun.svg", + "resource-files/system.svg", "resource-files/x.svg", "resource-files/fonts/dejavu.css", "resource-files/fonts/DejaVuLGCSans-Bold.woff",