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'));