Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit acccd44

Browse files
committedApr 10, 2021
Support dark mode and theme switching
1 parent b0e3615 commit acccd44

File tree

13 files changed

+1076
-3388
lines changed

13 files changed

+1076
-3388
lines changed
 

Diff for: ‎.github/workflows/ci.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ jobs:
118118
- name: Test assets
119119
run: |
120120
cd .node
121-
OLD=`cksum ../Resources/all.min.css`
121+
OLD=`cksum ../Sources/swift-doc/Resources/all.min.css`
122122
npm run build
123-
NEW=`cksum ../Resources/all.min.css`
123+
NEW=`cksum ../Sources/swift-doc/Resources/all.min.css`
124124
if [[ "$OLD" != "$NEW" ]]; then
125125
echo "Regenerated assets differ from committed version"
126126
exit -1

Diff for: ‎.node/package-lock.json

+724-3,285
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: ‎.node/package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
"not dead"
66
],
77
"scripts": {
8-
"watch": "postcss -w ../Assets/**/*.css -o ../Resources/all.min.css --config ./postcss.config.js",
9-
"build": "postcss ../Assets/**/*.css -o ../Resources/all.min.css --config ./postcss.config.js"
8+
"watch": "concurrently \"postcss -w ../Assets/**/*.css -o ../Sources/swift-doc/Resources/all.min.css --config ./postcss.config.js\" \"tsc -w\"",
9+
"build": "tsc && postcss ../Assets/**/*.css -o ../Sources/swift-doc/Resources/all.min.css --config ./postcss.config.js"
1010
},
11-
"dependencies": {
11+
"devDependencies": {
12+
"concurrently": "^5.2.0",
1213
"cssnano": "^4.1.10",
1314
"postcss-cli": "^7.1.0",
14-
"postcss-preset-env": "^6.7.0"
15-
},
16-
"devDependencies": {
15+
"postcss-preset-env": "^6.7.0",
16+
"typescript": "~3.9.7",
1717
"is-svg": ">=4.2.2"
1818
}
1919
}

Diff for: ‎.node/tsconfig.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"files": ["../Assets/ts/theme-switching.ts"],
3+
"compilerOptions": {
4+
"outFile": "../Sources/swift-doc/Resources/all.js"
5+
}
6+
}

Diff for: ‎Assets/css/all.css

+113-85
Original file line numberDiff line numberDiff line change
@@ -74,92 +74,89 @@
7474
}
7575
}
7676

77-
/*
78-
@media (prefers-color-scheme: dark) {
79-
:root {
80-
--system-red: rgb(255, 69, 58);
81-
--system-orange: rgb(255, 159, 10);
82-
--system-yellow: rgb(255, 214, 10);
83-
--system-green: rgb(48, 209, 88);
84-
--system-teal: rgb(100, 210, 255);
85-
--system-blue: rgb(10, 132, 255);
86-
--system-indigo: rgb(94, 92, 230);
87-
--system-purple: rgb(191, 90, 242);
88-
--system-pink: rgb(255, 55, 95);
89-
--system-gray: rgb(142, 142, 147);
90-
--system-gray2: rgb(99, 99, 102);
91-
--system-gray3: rgb(72, 72, 74);
92-
--system-gray4: rgb(58, 58, 60);
93-
--system-gray5: rgb(44, 44, 46);
94-
--system-gray6: rgb(28, 28, 30);
95-
96-
--label: rgb(255, 255, 255);
97-
--secondary-label: rgb(235, 235, 245);
98-
--tertiary-label: rgb(235, 235, 245);
99-
--quaternary-label: rgb(235, 235, 245);
100-
--placeholder-text: rgb(235, 235, 245);
101-
--link: rgb(9, 132, 255);
102-
--separator: rgb(44, 44, 46);
103-
--opaque-separator: rgb(56, 56, 58);
104-
--system-fill: rgb(120, 120, 128);
105-
--secondary-system-fill: rgb(120, 120, 128);
106-
--tertiary-system-fill: rgb(118, 118, 128);
107-
--quaternary-system-fill: rgb(118, 118, 128);
108-
--system-background: rgb(0, 0, 0);
109-
--secondary-system-background: rgb(28, 28, 30);
110-
--tertiary-system-background: rgb(44, 44, 46);
111-
--system-grouped-background: rgb(0, 0, 0);
112-
--secondary-system-grouped-background: rgb(28, 28, 30);
113-
--tertiary-system-grouped-background: rgb(44, 44, 46);
114-
}
77+
.dark-theme {
78+
--system-red: rgb(255, 69, 58);
79+
--system-orange: rgb(255, 159, 10);
80+
--system-yellow: rgb(255, 214, 10);
81+
--system-green: rgb(48, 209, 88);
82+
--system-teal: rgb(100, 210, 255);
83+
--system-blue: rgb(10, 132, 255);
84+
--system-indigo: rgb(94, 92, 230);
85+
--system-purple: rgb(191, 90, 242);
86+
--system-pink: rgb(255, 55, 95);
87+
--system-gray: rgb(142, 142, 147);
88+
--system-gray2: rgb(99, 99, 102);
89+
--system-gray3: rgb(72, 72, 74);
90+
--system-gray4: rgb(58, 58, 60);
91+
--system-gray5: rgb(44, 44, 46);
92+
--system-gray6: rgb(28, 28, 30);
93+
94+
--label: rgb(255, 255, 255);
95+
--secondary-label: rgb(235, 235, 245);
96+
--tertiary-label: rgb(235, 235, 245);
97+
--quaternary-label: rgb(235, 235, 245);
98+
--placeholder-text: rgb(235, 235, 245);
99+
--link: rgb(9, 132, 255);
100+
--separator: rgb(44, 44, 46);
101+
--opaque-separator: rgb(56, 56, 58);
102+
--system-fill: rgb(120, 120, 128);
103+
--secondary-system-fill: rgb(120, 120, 128);
104+
--tertiary-system-fill: rgb(118, 118, 128);
105+
--quaternary-system-fill: rgb(118, 118, 128);
106+
--system-background: rgb(0, 0, 0);
107+
--secondary-system-background: rgb(28, 28, 30);
108+
--tertiary-system-background: rgb(44, 44, 46);
109+
--system-grouped-background: rgb(0, 0, 0);
110+
--secondary-system-grouped-background: rgb(28, 28, 30);
111+
--tertiary-system-grouped-background: rgb(44, 44, 46);
112+
}
115113

116-
@supports (color: color(display-p3 1 1 1)) {
117-
:root {
118-
--system-red: color(display-p3 1 0.4118 0.3804);
119-
--system-orange: color(display-p3 1 0.702 0.251);
120-
--system-yellow: color(display-p3 1 0.8314 0.149);
121-
--system-green: color(display-p3 0.1882 0.8588 0.3569);
122-
--system-teal: color(display-p3 0.4392 0.8431 1);
123-
--system-blue: color(display-p3 0.251 0.6118 1);
124-
--system-indigo: color(display-p3 0.4902 0.4784 1);
125-
--system-purple: color(display-p3 0.8549 0.5608 1);
126-
--system-pink: color(display-p3 1 0.3922 0.5098);
127-
--system-gray: color(display-p3 0.6824 0.6824 0.698);
128-
--system-gray2: color(display-p3 0.4863 0.4863 0.502);
129-
--system-gray3: color(display-p3 0.3294 0.3294 0.3373);
130-
--system-gray4: color(display-p3 0.2667 0.2667 0.2745);
131-
--system-gray5: color(display-p3 0.2118 0.2118 0.2196);
132-
--system-gray6: color(display-p3 0.1412 0.1412 0.149);
133-
134-
--label: color(display-p3 1 1 1);
135-
--secondary-label: color(display-p3 0.9216 0.9216 0.9608);
136-
--tertiary-label: color(display-p3 0.9216 0.9216 0.9608);
137-
--quaternary-label: color(display-p3 0.9216 0.9216 0.9608);
138-
--placeholder-text: color(display-p3 0.9216 0.9216 0.9608);
139-
--link: color(display-p3 0.03529 0.5176 1);
140-
--separator: color(display-p3 0.2118 0.2118 0.2196);
141-
--opaque-separator: color(display-p3 0.2196 0.2196 0.2275);
142-
--system-fill: color(display-p3 0.4706 0.4706 0.502);
143-
--secondary-system-fill: color(display-p3 0.4706 0.4706 0.502);
144-
--tertiary-system-fill: color(display-p3 0.4627 0.4627 0.502);
145-
--quaternary-system-fill: color(display-p3 0.4627 0.4627 0.502);
146-
--system-background: color(display-p3 0 0 0);
147-
--secondary-system-background: color(
148-
display-p3 0.1412 0.1412 0.149
149-
);
150-
--tertiary-system-background: color(
151-
display-p3 0.2118 0.2118 0.2196
152-
);
153-
--system-grouped-background: color(display-p3 0 0 0);
154-
--secondary-system-grouped-background: color(
155-
display-p3 0.1412 0.1412 0.149
156-
);
157-
--tertiary-system-grouped-background: color(
158-
display-p3 0.2118 0.2118 0.2196
159-
);
160-
}
161-
}
162-
} */
114+
@supports (color: color(display-p3 1 1 1)) {
115+
.dark-theme {
116+
--system-red: color(display-p3 1 0.4118 0.3804);
117+
--system-orange: color(display-p3 1 0.702 0.251);
118+
--system-yellow: color(display-p3 1 0.8314 0.149);
119+
--system-green: color(display-p3 0.1882 0.8588 0.3569);
120+
--system-teal: color(display-p3 0.4392 0.8431 1);
121+
--system-blue: color(display-p3 0.251 0.6118 1);
122+
--system-indigo: color(display-p3 0.4902 0.4784 1);
123+
--system-purple: color(display-p3 0.8549 0.5608 1);
124+
--system-pink: color(display-p3 1 0.3922 0.5098);
125+
--system-gray: color(display-p3 0.6824 0.6824 0.698);
126+
--system-gray2: color(display-p3 0.4863 0.4863 0.502);
127+
--system-gray3: color(display-p3 0.3294 0.3294 0.3373);
128+
--system-gray4: color(display-p3 0.2667 0.2667 0.2745);
129+
--system-gray5: color(display-p3 0.2118 0.2118 0.2196);
130+
--system-gray6: color(display-p3 0.1412 0.1412 0.149);
131+
132+
--label: color(display-p3 1 1 1);
133+
--secondary-label: color(display-p3 0.9216 0.9216 0.9608);
134+
--tertiary-label: color(display-p3 0.9216 0.9216 0.9608);
135+
--quaternary-label: color(display-p3 0.9216 0.9216 0.9608);
136+
--placeholder-text: color(display-p3 0.9216 0.9216 0.9608);
137+
--link: color(display-p3 0.03529 0.5176 1);
138+
--separator: color(display-p3 0.2118 0.2118 0.2196);
139+
--opaque-separator: color(display-p3 0.2196 0.2196 0.2275);
140+
--system-fill: color(display-p3 0.4706 0.4706 0.502);
141+
--secondary-system-fill: color(display-p3 0.4706 0.4706 0.502);
142+
--tertiary-system-fill: color(display-p3 0.4627 0.4627 0.502);
143+
--quaternary-system-fill: color(display-p3 0.4627 0.4627 0.502);
144+
--system-background: color(display-p3 0 0 0);
145+
--secondary-system-background: color(
146+
display-p3 0.1412 0.1412 0.149
147+
);
148+
--tertiary-system-background: color(
149+
display-p3 0.2118 0.2118 0.2196
150+
);
151+
--system-grouped-background: color(display-p3 0 0 0);
152+
--secondary-system-grouped-background: color(
153+
display-p3 0.1412 0.1412 0.149
154+
);
155+
--tertiary-system-grouped-background: color(
156+
display-p3 0.2118 0.2118 0.2196
157+
);
158+
}
159+
}
163160

164161
:root {
165162
--large-title: 600 32pt / 39pt sans-serif;
@@ -474,6 +471,10 @@ select {
474471
outline: 0;
475472
z-index: 9;
476473
}
474+
475+
& option {
476+
color: #3c3c43;
477+
}
477478
}
478479

479480
input[type="file"] {
@@ -674,6 +675,8 @@ body {
674675
& > header {
675676
font: var(--title-1);
676677
padding: 0.5em 0;
678+
display: flex;
679+
align-items: center;
677680

678681
& a {
679682
color: var(--label);
@@ -690,6 +693,31 @@ body {
690693
color: var(--secondary-label);
691694
letter-spacing: 0.1ch;
692695
}
696+
& label {
697+
padding-bottom: 4px;
698+
font: var(--caption-1);
699+
}
700+
& .theme-select-container {
701+
display: flex;
702+
flex-direction: column;
703+
}
704+
& select {
705+
color: var(--secondary-label);
706+
font: var(--caption-1);
707+
width: auto;
708+
border: 1px solid var(--label);
709+
710+
/* Simple down-pointing rectangle positioned on the right side of the input */
711+
background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%238a8a8a%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E');
712+
background-repeat: no-repeat, repeat;
713+
background-position: right .7em top 50%, 0 0;
714+
background-size: .65em auto, 100%;
715+
padding-right: 1.8em;
716+
}
717+
& .spacer {
718+
flex-grow: 1;
719+
}
720+
693721
}
694722

695723
& > footer {

Diff for: ‎Assets/ts/theme-switching.ts

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
type ThemeChoice = "light" | "dark" | "auto";
2+
const themeQuery = window.matchMedia('(prefers-color-scheme: dark)');
3+
const localStorageKey = "picked-theme";
4+
let autoTheme = false;
5+
6+
// load initial theme before load event to prevent flashing of background color on navigation
7+
let initialTheme = window.localStorage.getItem(localStorageKey) ?? "auto";
8+
setPickedTheme(initialTheme as ThemeChoice);
9+
10+
window.addEventListener("load", () => {
11+
const themeSwitcher = window.document.getElementById("theme-switcher") as HTMLSelectElement;
12+
13+
themeSwitcher.addEventListener("change", (themePickedEvent: Event) => {
14+
const newValue = (themePickedEvent.target as HTMLSelectElement).value
15+
setPickedTheme(newValue as ThemeChoice);
16+
});
17+
18+
themeQuery.addEventListener?.("change", (systemThemeChangeEvent) => {
19+
const systemTheme = systemThemeChangeEvent.matches ? "dark" : "light";
20+
updateDropdownLabel(systemTheme);
21+
if (autoTheme) {
22+
applyTheme(systemTheme);
23+
}
24+
})
25+
26+
setInitialTheme(themeSwitcher);
27+
checkThemingSupport();
28+
})
29+
30+
/**
31+
* Sets the correct theme based on what's in storage, and updates the theme switcher dropdown with the correct initial value.
32+
*/
33+
function setInitialTheme(themeSwitcher: HTMLSelectElement) {
34+
let initialTheme = window.localStorage.getItem(localStorageKey) ?? "auto";
35+
themeSwitcher.value = initialTheme;
36+
setPickedTheme(initialTheme as ThemeChoice);
37+
const systemTheme = themeQuery.matches ? "dark" : "light";
38+
updateDropdownLabel(systemTheme);
39+
}
40+
41+
/**
42+
* Updates the styles of the page to reflect a new theme
43+
*/
44+
function applyTheme(newTheme: "light" | "dark") {
45+
const otherTheme = newTheme == "light" ? "dark" : "light";
46+
window.document.documentElement.classList.remove(`${otherTheme}-theme`);
47+
window.document.documentElement.classList.add(`${newTheme}-theme`);
48+
}
49+
50+
/**
51+
* Saves a newly picked theme to storage and applies the theme.
52+
* If the new theme is "auto", the correct theme will be applied based on the system settings.
53+
*/
54+
function setPickedTheme(newTheme: ThemeChoice) {
55+
window.localStorage.setItem(localStorageKey, newTheme);
56+
autoTheme = newTheme === "auto";
57+
if (newTheme === "auto") {
58+
const systemTheme = themeQuery.matches ? "dark" : "light";
59+
applyTheme(systemTheme);
60+
} else {
61+
applyTheme(newTheme);
62+
}
63+
}
64+
65+
/**
66+
* Updates the "Auto" choice of the theme dropdown to reflect the current system theme - either "Auto (light)" or "Auto (dark)"
67+
*/
68+
function updateDropdownLabel(systemTheme: "light" | "dark") {
69+
window.document.getElementById('theme-option-auto').innerText = `Auto (${systemTheme})`;
70+
}
71+
72+
/**
73+
* Checks whether color-scheme is a supported feature of the browser.
74+
* If it is not, removes the auto option from the dropdown.
75+
*/
76+
function checkThemingSupport() {
77+
const darkQuery = window.matchMedia('(prefers-color-scheme: dark)');
78+
const lightQuery = window.matchMedia('(prefers-color-scheme: light)');
79+
// If neither query matches, we know that the browser doesn't support theming.
80+
if (!darkQuery.matches && !lightQuery.matches) {
81+
const themeOptionAuto = window.document.getElementById('theme-option-auto');
82+
// IE doesn't support element.remove()
83+
themeOptionAuto.parentNode.removeChild(themeOptionAuto);
84+
}
85+
// If the browser does not support css properties, we do not allow theme switching.
86+
const customProperty = getComputedStyle(document.body).getPropertyValue("--body");
87+
if (!customProperty) {
88+
(document.querySelector(".theme-select-container") as HTMLDivElement).style.display = 'none';
89+
}
90+
}

Diff for: ‎Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
"repositoryURL": "https://github.com/SwiftDocOrg/swift-cmark.git",
5252
"state": {
5353
"branch": null,
54-
"revision": "2a766030bee955b4806044fd7aca1b6884475138",
55-
"version": "0.28.3+20200110.2a76603"
54+
"revision": "1168665f6b36be747ffe6b7b90bc54cfc17f42b7",
55+
"version": "0.28.3+20200207.1168665"
5656
}
5757
},
5858
{

Diff for: ‎Package.swift

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ let package = Package(
4343
.product(name: "SwiftSyntaxHighlighter", package: "SwiftSyntaxHighlighter"),
4444
.product(name: "Logging", package: "swift-log"),
4545
.product(name: "LoggingGitHubActions", package: "LoggingGitHubActions")
46+
],
47+
resources: [
48+
.copy("Resources/all.js"),
49+
.copy("Resources/all.min.css"),
4650
]
4751
),
4852
.target(

Diff for: ‎Resources/all.min.css

-1
This file was deleted.

Diff for: ‎Sources/swift-doc/Resources/all.js

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
var _a;
2+
var themeQuery = window.matchMedia('(prefers-color-scheme: dark)');
3+
var localStorageKey = "picked-theme";
4+
var autoTheme = false;
5+
// load initial theme before load event to prevent flashing of background color on navigation
6+
var initialTheme = (_a = window.localStorage.getItem(localStorageKey)) !== null && _a !== void 0 ? _a : "auto";
7+
setPickedTheme(initialTheme);
8+
window.addEventListener("load", function () {
9+
var _a;
10+
var themeSwitcher = window.document.getElementById("theme-switcher");
11+
themeSwitcher.addEventListener("change", function (themePickedEvent) {
12+
var newValue = themePickedEvent.target.value;
13+
setPickedTheme(newValue);
14+
});
15+
(_a = themeQuery.addEventListener) === null || _a === void 0 ? void 0 : _a.call(themeQuery, "change", function (systemThemeChangeEvent) {
16+
var systemTheme = systemThemeChangeEvent.matches ? "dark" : "light";
17+
updateDropdownLabel(systemTheme);
18+
if (autoTheme) {
19+
applyTheme(systemTheme);
20+
}
21+
});
22+
setInitialTheme(themeSwitcher);
23+
checkThemingSupport();
24+
});
25+
/**
26+
* Sets the correct theme based on what's in storage, and updates the theme switcher dropdown with the correct initial value.
27+
*/
28+
function setInitialTheme(themeSwitcher) {
29+
var _a;
30+
var initialTheme = (_a = window.localStorage.getItem(localStorageKey)) !== null && _a !== void 0 ? _a : "auto";
31+
themeSwitcher.value = initialTheme;
32+
setPickedTheme(initialTheme);
33+
var systemTheme = themeQuery.matches ? "dark" : "light";
34+
updateDropdownLabel(systemTheme);
35+
}
36+
/**
37+
* Updates the styles of the page to reflect a new theme
38+
*/
39+
function applyTheme(newTheme) {
40+
var otherTheme = newTheme == "light" ? "dark" : "light";
41+
window.document.documentElement.classList.remove(otherTheme + "-theme");
42+
window.document.documentElement.classList.add(newTheme + "-theme");
43+
}
44+
/**
45+
* Saves a newly picked theme to storage and applies the theme.
46+
* If the new theme is "auto", the correct theme will be applied based on the system settings.
47+
*/
48+
function setPickedTheme(newTheme) {
49+
window.localStorage.setItem(localStorageKey, newTheme);
50+
autoTheme = newTheme === "auto";
51+
if (newTheme === "auto") {
52+
var systemTheme = themeQuery.matches ? "dark" : "light";
53+
applyTheme(systemTheme);
54+
}
55+
else {
56+
applyTheme(newTheme);
57+
}
58+
}
59+
/**
60+
* Updates the "Auto" choice of the theme dropdown to reflect the current system theme - either "Auto (light)" or "Auto (dark)"
61+
*/
62+
function updateDropdownLabel(systemTheme) {
63+
window.document.getElementById('theme-option-auto').innerText = "Auto (" + systemTheme + ")";
64+
}
65+
/**
66+
* Checks whether color-scheme is a supported feature of the browser.
67+
* If it is not, removes the auto option from the dropdown.
68+
*/
69+
function checkThemingSupport() {
70+
var darkQuery = window.matchMedia('(prefers-color-scheme: dark)');
71+
var lightQuery = window.matchMedia('(prefers-color-scheme: light)');
72+
// If neither query matches, we know that the browser doesn't support theming.
73+
if (!darkQuery.matches && !lightQuery.matches) {
74+
var themeOptionAuto = window.document.getElementById('theme-option-auto');
75+
// IE doesn't support element.remove()
76+
themeOptionAuto.parentNode.removeChild(themeOptionAuto);
77+
}
78+
// If the browser does not support css properties, we do not allow theme switching.
79+
var customProperty = getComputedStyle(document.body).getPropertyValue("--body");
80+
if (!customProperty) {
81+
document.querySelector(".theme-select-container").style.display = 'none';
82+
}
83+
}

Diff for: ‎Sources/swift-doc/Resources/all.min.css

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: ‎Sources/swift-doc/Subcommands/Generate.swift

+26
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,11 @@ extension SwiftDoc {
126126

127127
if case .html = format {
128128
let cssData = try fetchRemoteCSS()
129+
let jsData = try fetchRemoteJS()
129130
let cssURL = outputDirectoryURL.appendingPathComponent("all.css")
130131
try writeFile(cssData, to: cssURL)
132+
let jsURL = outputDirectoryURL.appendingPathComponent("all.js")
133+
try writeFile(jsData, to: jsURL)
131134
}
132135

133136
} catch {
@@ -138,6 +141,29 @@ extension SwiftDoc {
138141
}
139142

140143
func fetchRemoteCSS() throws -> Data {
144+
#if swift(>=5.3)
145+
let cssURL = Bundle.module.url(forResource: "all.min", withExtension: "css")!
146+
return try Data(contentsOf: cssURL)
147+
#else
141148
let url = URL(string: "https://raw.githubusercontent.com/SwiftDocOrg/swift-doc/master/Resources/all.min.css")!
142149
return try Data(contentsOf: url)
150+
#endif
151+
}
152+
153+
func fetchRemoteJS() throws -> Data {
154+
#if swift(>=5.3)
155+
let jsURL = Bundle.module.url(forResource: "all", withExtension: "js")!
156+
return try Data(contentsOf: jsURL)
157+
#else
158+
// When using Swift Package Manager versions that don't support bundled resources, just hide the theme select drop-down.
159+
let fallbackJS = """
160+
var hideThemeSelect = function() {
161+
document.querySelector(".theme-select-container").style.display = "none";
162+
}
163+
// hiding the element in `requestAnimationFrame` causes the function to be called after the element exists,
164+
// but fast enough that the element does not flash on the screen.
165+
window.requestAnimationFrame(hideThemeSelect)
166+
"""
167+
return Data(fallbackJS.utf8)
168+
#endif
143169
}

Diff for: ‎Sources/swift-doc/Supporting Types/Layout.swift

+19-7
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,28 @@ func layout(_ page: Page) -> HTML {
1313
<meta name="viewport" content="width=device-width, initial-scale=1.0">
1414
<title>\#(page.module.name) - \#(page.title)</title>
1515
<link rel="stylesheet" type="text/css" href="\#(path(for: "all.css", with: page.baseURL))" media="all" />
16+
<script src="\#(path(for: "all.js", with: page.baseURL))"></script>
1617
</head>
1718
<body>
1819
<header>
19-
<a href="\#(page.baseURL)">
20-
<strong>
21-
\#(page.module.name)
22-
</strong>
23-
<span>Documentation</span>
24-
</a>
25-
<sup>Beta</sup>
20+
<div class="title-container">
21+
<a href="\#(page.baseURL)">
22+
<strong>
23+
\#(page.module.name)
24+
</strong>
25+
<span>Documentation</span>
26+
</a>
27+
<sup>Beta</sup>
28+
</div>
29+
<span class="spacer"></span>
30+
<div class="theme-select-container">
31+
<label for="theme-switcher">Theme:</label>
32+
<select name="theme" id="theme-switcher">
33+
<option id="theme-option-auto" value="auto">Auto (light)</option>
34+
<option value="light">Light</option>
35+
<option value="dark">Dark</option>
36+
</select>
37+
</div>
2638
</header>
2739
2840
<!--

0 commit comments

Comments
 (0)
This repository has been archived.