diff --git a/static/storage-change-detection.html b/static/storage-change-detection.html new file mode 100644 index 000000000..83d3d5b19 --- /dev/null +++ b/static/storage-change-detection.html @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/templates/base.html b/templates/base.html index 03ecd7569..912ac2ec9 100644 --- a/templates/base.html +++ b/templates/base.html @@ -21,6 +21,8 @@ {%- block title -%} Docs.rs {%- endblock title -%} + + diff --git a/templates/rustdoc/body.html b/templates/rustdoc/body.html index 7e9a636c9..03fabd3ad 100644 --- a/templates/rustdoc/body.html +++ b/templates/rustdoc/body.html @@ -29,4 +29,16 @@ window.addEventListener("scroll", maybeFixupViewPortPosition, {"once": true}); } } + + window.addEventListener('message', function (ev) { + if (ev.data && ev.data.storage && ev.data.storage.key === 'rustdoc-theme') { + applyTheme(ev.data.storage.value); + } + }); + + diff --git a/templates/rustdoc/head.html b/templates/rustdoc/head.html index 73181e0bd..508e800ea 100644 --- a/templates/rustdoc/head.html +++ b/templates/rustdoc/head.html @@ -2,3 +2,5 @@ + + diff --git a/templates/style/_navbar.scss b/templates/style/_navbar.scss index 4aac81344..b7cb55828 100644 --- a/templates/style/_navbar.scss +++ b/templates/style/_navbar.scss @@ -5,15 +5,15 @@ div.nav-container { // Nothing is supposed to be over or hovering the top navbar. Maybe add a few others '('? :) z-index: 999; height: $top-navbar-height; - border-bottom: 1px solid $color-border; - background-color: #fff; + border-bottom: 1px solid var(--color-border); + background-color: var(--color-background); left: 0; right: 0; top: 0; position: fixed; li { - border-left: 1px solid $color-border; + border-left: 1px solid var(--color-border); } .pure-menu-has-children > .pure-menu-link:after { @@ -25,7 +25,7 @@ div.nav-container { font-weight: 400; &:hover { - color: $color-standard; + color: var(--color-standard); background-color: inherit; } } @@ -41,7 +41,7 @@ div.nav-container { float: right; max-width: 150px; display: none; - border-left: 1px solid $color-border; + border-left: 1px solid var(--color-border); @media #{$media-sm} { display: block; @@ -52,7 +52,7 @@ div.nav-container { } label { - color: #777; + color: var(--color-navbar-standard); cursor: pointer; padding-left: 0.5rem; font-size: 0.8em; @@ -63,7 +63,7 @@ div.nav-container { margin: 0 1em 0 0; font-size: 0.8em; box-shadow: none; - background-color: #fff; + background-color: var(--color-background); height: 31px; } } @@ -74,7 +74,7 @@ div.nav-container { } .pure-menu-children { - border: 1px solid $color-border; + border: 1px solid var(--color-border); border-radius: 0 0 2px 2px; margin-left: -1px; @@ -86,19 +86,19 @@ div.nav-container { // used for latest version warning .warn, .warn:hover { - color: $color-type; + color: var(--color-warn); } a.warn:hover { - color: darken($color-type, 10%); + color: var(--color-warn-hover); } // used for global alerts .error { - color: $color-red; + color: var(--color-error); &:hover { - color: darken($color-red, 10%); + color: var(--color-error-hover); } } @@ -142,7 +142,7 @@ div.nav-container { p.description { font-family: $font-family-sans; font-size: 0.8em; - color: #777; // color from pure + color: var(--color-navbar-standard); padding: 0.5em 1em; margin: 0; } @@ -152,7 +152,7 @@ div.nav-container { } div.right-border { - border-right: 1px solid $color-border; + border-right: 1px solid var(--color-border); } a.pure-menu-link { diff --git a/templates/style/_themes.scss b/templates/style/_themes.scss new file mode 100644 index 000000000..f70c8446c --- /dev/null +++ b/templates/style/_themes.scss @@ -0,0 +1,25 @@ +// Standard white theme +html { + --color-background-code: #f5f5f5; + --color-background: #fff; + --color-border-light: #eaeaea; + --color-border: #ddd; + --color-doc-link-background: #333; + --color-doc-link-hover: #3061f3; + --color-error-hover: #be2525; + --color-error: #d93d3d; + --color-macro: #068000; + --color-menu-border: #cdcdcd; + --color-menu-header-background: #e0e0e0; + --color-navbar-standard: #777; + --color-standard: #000; + --color-struct: #df3600; + --color-type: #e57300; + --color-url: #4d76ae; + --color-warn-background: #ffe5cc; + --color-warn-hover: #b25900; + --color-warn: #e57300; +} + +// To add a new theme, copy the above theme into a new `html[data-theme="name"]` +// block below and change the colors diff --git a/templates/style/_utils.scss b/templates/style/_utils.scss index e6618e648..734042dc1 100644 --- a/templates/style/_utils.scss +++ b/templates/style/_utils.scss @@ -6,13 +6,13 @@ div { .info { font-family: $font-family-sans; border-radius: 4px; - background-color: $color-background-code; + background-color: var(--color-background-code); padding: 0.4em 1em; text-align: center; margin-bottom: 10px; a { - color: $color-url; + color: var(--color-url); text-decoration: underline; } } @@ -20,6 +20,6 @@ div { .warning { @extend .info; - background-color: lighten($color-type, 45%); + background-color: var(--color-warn-background); } } diff --git a/templates/style/_vars.scss b/templates/style/_vars.scss index 2f1d829ed..273c58c43 100644 --- a/templates/style/_vars.scss +++ b/templates/style/_vars.scss @@ -5,22 +5,6 @@ $font-family-sans: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; $font-family-serif: "Source Serif Pro", Georgia, Times, "Times New Roman", serif; $font-family-mono: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", Inconsolata, monospace; -// Colors -$color-standard: #000; // pure black -$color-url: #4d76ae; // blue -$color-macro: #068000; // green -$color-struct: #df3600; // red -$color-enum: #5e9766; // light green -$color-type: #e57300; // orange -$color-keyword: #8959A8; // purple -$color-string: #718C00; // greenish -$color-macro-in-code: #3E999F; // blueish -$color-lifetime-incode: #B76514; // orangish -$color-comment-in-code: #8E908C; // light gray -$color-background-code: #F5F5F5; // lighter gray -$color-border: #ddd; // gray -$color-red: #d93d3d; // red - // Sizes $top-navbar-height: 32px; // height of the floating top navbar diff --git a/templates/style/base.scss b/templates/style/base.scss index 2562f9987..34bf099f0 100644 --- a/templates/style/base.scss +++ b/templates/style/base.scss @@ -1,5 +1,5 @@ // FIXME: Use modules -@import "vars", "rustdoc", "utils", "navbar"; +@import "vars", "rustdoc", "utils", "navbar", "themes"; html, input, @@ -7,13 +7,13 @@ select, textarea, .pure-g [class*="pure-u"] { font-family: $font-family-sans; - color: $color-standard; + color: var(--color-standard); } .pure-button-normal { - background-color: #fff; + background-color: var(--color-background); box-sizing: border-box !important; - border: 1px solid $color-border; + border: 1px solid var(--color-border); } .description { @@ -117,7 +117,7 @@ div.recent-releases-container { margin-left: 20px; a { - color: $color-url; + color: var(--color-url); } } @@ -131,7 +131,7 @@ div.recent-releases-container { .release { display: block; - border-bottom: 1px solid $color-border; + border-bottom: 1px solid var(--color-border); padding: 0.4em 1em; @media #{$media-lg} { @@ -142,7 +142,7 @@ div.recent-releases-container { .release:hover, li.selected > .release { - background-color: $color-background-code; + background-color: var(--color-background-code); } li:last-child .release { @@ -150,7 +150,7 @@ div.recent-releases-container { } .name { - color: $color-url; + color: var(--color-url); font-weight: 500; white-space: nowrap; margin: 0; @@ -178,10 +178,10 @@ div.recent-releases-container { font-weight: 500; span.fa-check { - color: $color-macro; + color: var(--color-macro); } span.fa-times { - color: $color-struct; + color: var(--color-struct); } } @@ -222,13 +222,13 @@ div.recent-releases-container { } h4 { - border-bottom-color: $color-border !important; + border-bottom-color: var(--color-border) !important; } } div.package-container { - background-color: $color-url; - color: $color-background-code; + background-color: var(--color-url); + color: var(--color-background-code); h1 { margin: 0; @@ -241,23 +241,23 @@ div.package-container { .pure-menu { .pure-menu-link { - background-color: #fff; - border-top: 1px solid $color-border; - border-left: 1px solid $color-border; - border-right: 1px solid $color-border; + background-color: var(--color-background); + border-top: 1px solid var(--color-border); + border-left: 1px solid var(--color-border); + border-right: 1px solid var(--color-border); border-top-left-radius: 4px; border-top-right-radius: 4px; - border-bottom: 2px solid $color-border; + border-bottom: 2px solid var(--color-border); padding: 0.4em 1em; } .pure-menu-active { - border-bottom: 2px solid #fff; - color: $color-standard; + border-bottom: 2px solid var(--color-background); + color: var(--color-standard); } .pure-menu-link:hover { - color: $color-standard; + color: var(--color-standard); } } } @@ -273,11 +273,11 @@ div.package-sheet-container { } .build-success { - color: $color-macro; + color: var(--color-macro); } .build-fail { - color: $color-struct; + color: var(--color-struct); } } @@ -288,10 +288,10 @@ div.package-page-container { li.pure-menu-heading { font-size: 1.3em; - color: #000; + color: var(--color-standard); font-weight: 500; text-align: center; - border-bottom: 1px solid lighten($color-border, 5%); + border-bottom: 1px solid var(--color-border-light); text-transform: none; padding-bottom: 6px; margin: 20px 5px 15px 5px; @@ -309,7 +309,7 @@ div.package-page-container { a.pure-menu-link { font-size: 14px; - color: $color-standard; + color: var(--color-standard); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -317,12 +317,12 @@ div.package-page-container { } a.pure-menu-link:hover { - background-color: $color-background-code; + background-color: var(--color-background-code); } // used for versions that failed to build a.warn { - color: $color-type; + color: var(--color-type); } div.sub-menu { @@ -350,7 +350,7 @@ div.package-page-container { font-family: $font-family-serif; a { - color: $color-url; + color: var(--color-url); } a:hover { @@ -380,12 +380,12 @@ div.package-page-container { border-collapse: collapse; border-spacing: 0; empty-cells: show; - border: 1px solid #cbcbcb; + border: 1px solid var(--color-menu-border); margin-bottom: 15px; td, th { - border-left: 1px solid #cbcbcb; + border-left: 1px solid var(--color-menu-border); border-width: 0 0 0 1px; font-size: inherit; margin: 0; @@ -399,7 +399,7 @@ div.package-page-container { } td { - border-bottom: 1px solid #cbcbcb; + border-bottom: 1px solid var(--color-menu-border); } tbody > tr:last-child > td { @@ -407,8 +407,8 @@ div.package-page-container { } thead { - background-color: #e0e0e0; - color: #000; + background-color: var(--color-menu-header-background); + color: var(--color-standard); text-align: left; vertical-align: bottom; } @@ -427,8 +427,8 @@ div.package-page-container { div.cratesfyi-package-container { text-align: left; - background-color: $color-background-code; - border-bottom: 1px solid $color-border; + background-color: var(--color-background-code); + border-bottom: 1px solid var(--color-border); margin-bottom: 20px; .container { @@ -471,7 +471,6 @@ div.cratesfyi-package-container { padding-left: 14px; .pure-menu-link { - color: #666; font-size: 14px; padding: 0.4em 1em 0.3em 1em; @@ -485,22 +484,22 @@ div.cratesfyi-package-container { } .pure-menu-active { - color: $color-standard; - background-color: #fff; - border-top: 1px solid $color-border; - border-left: 1px solid $color-border; - border-right: 1px solid $color-border; + color: var(--color-standard); + background-color: var(--color-background); + border-top: 1px solid var(--color-border); + border-left: 1px solid var(--color-border); + border-right: 1px solid var(--color-border); border-top-left-radius: 4px; border-top-right-radius: 4px; - border-bottom: 2px solid #fff; + border-bottom: 2px solid var(--color-background); } .pure-menu-active:hover { - background-color: #fff !important; + background-color: var(--color-background); } .pure-menu-link:hover { - color: #000; + color: var(--color-standard); background-color: inherit; } } @@ -512,7 +511,7 @@ div.cratesfyi-package-container { ul.pure-menu-children { left: auto; right: 0; - border: 1px solid $color-border; + border: 1px solid var(--color-border); border-radius: 2px; } @@ -529,10 +528,10 @@ div.cratesfyi-package-container { .doc-link { margin: 0 10px; height: min-content; - background: #333; - color: #fff; + background: var(--color-doc-link-background); + color: var(--color-background); padding: 10px; - border: 1px solid #333; + border: 1px solid var(--color-doc-link-background); border-radius: 5px; display: flex; @@ -542,7 +541,7 @@ div.cratesfyi-package-container { } &:hover { - border-color: #3061f3; + border-color: var(--color-doc-link-hover); } } } @@ -560,7 +559,7 @@ div.search-page-search-form { } .menu-item-divided { - border-bottom: 1px solid $color-border; + border-bottom: 1px solid var(--color-border); } .rust-navigation-item { @@ -595,7 +594,7 @@ div.search-page-search-form { } h4 { - border-bottom-color: $color-border !important; + border-bottom-color: var(--color-border) !important; } } diff --git a/templates/theme.js b/templates/theme.js new file mode 100644 index 000000000..afa4beca1 --- /dev/null +++ b/templates/theme.js @@ -0,0 +1,7 @@ +// This is a global function also called from a script in ./rustdoc/body.html +// which detects when the rustdoc theme is changed +function applyTheme(theme) { + document.documentElement.dataset.theme = theme; +} + +applyTheme(window.localStorage.getItem('rustdoc-theme'));