Skip to content

Commit d936f35

Browse files
committed
add warning banner for unreleased branch or version in the documentation
Signed-off-by: olalekan odukoya <[email protected]>
1 parent a6829d3 commit d936f35

File tree

2 files changed

+169
-6
lines changed

2 files changed

+169
-6
lines changed

docs/overrides/main.html

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
{% extends "base.html" %} {% block extrahead %} {{ super() }}
2+
<style>
3+
#version-banner {
4+
display: none;
5+
position: sticky;
6+
top: 0;
7+
left: 0;
8+
right: 0;
9+
width: 100%;
10+
background-color: #ff9800;
11+
color: white;
12+
padding: 8px 16px;
13+
text-align: center;
14+
font-size: 14px;
15+
line-height: 1.5;
16+
z-index: 10000;
17+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
18+
}
19+
20+
#version-banner a {
21+
color: white;
22+
text-decoration: underline;
23+
margin-left: 8px;
24+
}
25+
26+
#version-banner a:hover {
27+
text-decoration: none;
28+
}
29+
30+
.md-header {
31+
transition: top 0.2s ease;
32+
}
33+
</style>
34+
35+
<script>
36+
(function () {
37+
"use strict";
38+
39+
const CONFIG = {
40+
UNRELEASED_VERSION: "main",
41+
RETRY_DELAY: 500,
42+
HEADER_ADJUST_DELAY: 100,
43+
};
44+
45+
function sortVersions(a, b) {
46+
const parseVersion = (v) => v.replace(/^v/, "").split(".").map(Number);
47+
const aParts = parseVersion(a);
48+
const bParts = parseVersion(b);
49+
50+
for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
51+
const diff = (bParts[i] || 0) - (aParts[i] || 0);
52+
if (diff !== 0) return diff;
53+
}
54+
return 0;
55+
}
56+
57+
function getCurrentVersion() {
58+
const path = window.location.pathname;
59+
const versionMatch = path.match(/\/(main|v\d+\.\d+[^\/]*)/);
60+
return versionMatch ? versionMatch[1] : null;
61+
}
62+
63+
function getAvailableVersions() {
64+
const versionList = document.querySelector("ul.md-version__list");
65+
if (!versionList) return [];
66+
67+
const links = Array.from(
68+
versionList.querySelectorAll("a.md-version__link")
69+
);
70+
71+
return links
72+
.map((link) => {
73+
const href = link.href || link.getAttribute("href");
74+
const match = href.match(/\/(v\d+\.\d+[^\/]*)\//);
75+
return match ? match[1] : null;
76+
})
77+
.filter((v) => v && /^v\d+\.\d+/.test(v))
78+
.filter((v, i, arr) => arr.indexOf(v) === i);
79+
}
80+
81+
function getLatestVersionPath() {
82+
const versions = getAvailableVersions();
83+
84+
if (versions.length === 0) {
85+
const currentPath = window.location.pathname;
86+
return currentPath.replace(/\/main(\/|$)/, "/latest$1") || "/latest/";
87+
}
88+
89+
const latestVersion = versions.sort(sortVersions)[0];
90+
const currentPath = window.location.pathname;
91+
92+
return (
93+
currentPath.replace(/\/main(\/|$)/, `/${latestVersion}$1`) ||
94+
`/${latestVersion}/`
95+
);
96+
}
97+
98+
function createBanner() {
99+
const banner = document.createElement("div");
100+
banner.id = "version-banner";
101+
banner.innerHTML = `
102+
<strong>You are viewing the docs for an unreleased version.</strong>
103+
<a href="#" id="latest-version-link">Click here to go to the latest stable version.</a>
104+
`;
105+
106+
document.body.insertBefore(banner, document.body.firstChild);
107+
banner.style.display = "block";
108+
109+
return banner;
110+
}
111+
112+
function updateBannerLink(banner) {
113+
const link = banner.querySelector("#latest-version-link");
114+
if (!link) return;
115+
116+
const latestPath = getLatestVersionPath();
117+
link.href = latestPath;
118+
}
119+
120+
function adjustHeader(banner) {
121+
setTimeout(() => {
122+
const header = document.querySelector(".md-header");
123+
if (!header) return;
124+
125+
const bannerHeight = banner.offsetHeight;
126+
const headerHeight = header.offsetHeight;
127+
128+
header.style.top = `${bannerHeight}px`;
129+
document.documentElement.style.setProperty(
130+
"--md-header-height",
131+
`${bannerHeight + headerHeight}px`
132+
);
133+
document.documentElement.style.setProperty(
134+
"--md-scroll-margin",
135+
`${bannerHeight + headerHeight}px`
136+
);
137+
}, CONFIG.HEADER_ADJUST_DELAY);
138+
}
139+
140+
function init() {
141+
const currentVersion = getCurrentVersion();
142+
143+
if (currentVersion !== CONFIG.UNRELEASED_VERSION) {
144+
return;
145+
}
146+
147+
const banner = createBanner();
148+
updateBannerLink(banner);
149+
150+
setTimeout(() => updateBannerLink(banner), CONFIG.RETRY_DELAY);
151+
152+
adjustHeader(banner);
153+
}
154+
155+
if (document.readyState === "loading") {
156+
document.addEventListener("DOMContentLoaded", init);
157+
} else {
158+
init();
159+
}
160+
})();
161+
</script>
162+
{% endblock %}

docs/overrides/stylesheets/crd.css

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,13 @@ ul.crd-index {
3535
color: #fff;
3636
}
3737

38-
3938
dl.crd-meta {
4039
display: flex;
4140
flex-flow: row wrap;
4241
border-bottom: 1px solid #00000012;
4342
}
4443

45-
[data-md-color-primary=black] dl.crd-meta {
44+
[data-md-color-primary="black"] dl.crd-meta {
4645
border-bottom: 1px solid #e6e6e612;
4746
}
4847

@@ -62,13 +61,14 @@ dl.crd-meta {
6261
border-top: 1px solid #00000012;
6362
}
6463

65-
[data-md-color-primary=black] .crd-meta dt, [data-md-color-primary=black] .crd-meta dd {
64+
[data-md-color-primary="black"] .crd-meta dt,
65+
[data-md-color-primary="black"] .crd-meta dd {
6666
border-top: 1px solid #e6e6e612;
6767
}
6868

6969
.crd-meta a.version {
7070
font-family: var(--md-code-font-family);
71-
font-size:
71+
font-size: var(--md-code-font-size);
7272
margin-right: 10px;
7373
}
7474

@@ -83,8 +83,9 @@ dl.crd-meta {
8383
margin-left: -0.1em;
8484
}
8585

86-
.property-description, .property-meta {
87-
margin: 5px 0
86+
.property-description,
87+
.property-meta {
88+
margin: 5px 0;
8889
}
8990

9091
.property-title {

0 commit comments

Comments
 (0)