Compare commits
No commits in common. "fe0c1e2b537924a4c4da03b5c4f9af769e6ef391" and "197e0ab19a01d9f65aaa669710cdd50c243213b7" have entirely different histories.
fe0c1e2b53
...
197e0ab19a
12 changed files with 7 additions and 332 deletions
|
|
@ -41,10 +41,6 @@ Host runtime: `/etc/caddy/secrets/dossiers-ngi-basicauth.txt` (root-only).
|
||||||
SoT: `koopa-admin-secrets-enc` (git-crypt) → `koopa/home-hernani/caddy/`.
|
SoT: `koopa-admin-secrets-enc` (git-crypt) → `koopa/home-hernani/caddy/`.
|
||||||
Hosts: `dossiers.ngi` / `dossiers.2.ngi` / `dossiers.3.ngi`.hacktivism.ch
|
Hosts: `dossiers.ngi` / `dossiers.2.ngi` / `dossiers.3.ngi`.hacktivism.ch
|
||||||
|
|
||||||
HTTP→HTTPS 308 for `dossiers.ngi` (add host to the shared ACME list, leave
|
|
||||||
HTTPS body alone): `scripts/dossiers-ngi/apply-dossiers-ngi-http-308.sh`
|
|
||||||
then `sudo ~/bin/caddy-apply`.
|
|
||||||
|
|
||||||
## silverbullet.hacktivism.ch — merge + basic_auth
|
## silverbullet.hacktivism.ch — merge + basic_auth
|
||||||
|
|
||||||
After podman cutover (`scripts/notes/cutover-to-silverbullet.sh --apply`) and DNS:
|
After podman cutover (`scripts/notes/cutover-to-silverbullet.sh --apply`) and DNS:
|
||||||
|
|
|
||||||
|
|
@ -136,30 +136,5 @@ sudo ~/bin/caddy-apply
|
||||||
|
|
||||||
Stanza SoT: `scripts/dossiers-ngi/caddy-dossiers-ngi.snippet`.
|
Stanza SoT: `scripts/dossiers-ngi/caddy-dossiers-ngi.snippet`.
|
||||||
|
|
||||||
## HTTP → HTTPS 308
|
|
||||||
|
|
||||||
Shared Caddy HTTP list already `redir https://{host}{uri} permanent` (308).
|
|
||||||
`dossiers.ngi.hacktivism.ch` was missing there → HTTP `200` empty body /
|
|
||||||
Firefox `NS_ERROR_NET_EMPTY_RESPONSE`. HTTPS site body stays untouched.
|
|
||||||
|
|
||||||
On koopa (hernani, then root apply):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# SoT: scripts/dossiers-ngi/apply-dossiers-ngi-http-308.sh
|
|
||||||
cp /path/to/apply-dossiers-ngi-http-308.sh ~/bin/
|
|
||||||
chmod +x ~/bin/apply-dossiers-ngi-http-308.sh
|
|
||||||
bash ~/bin/apply-dossiers-ngi-http-308.sh
|
|
||||||
sudo ~/bin/caddy-apply
|
|
||||||
```
|
|
||||||
|
|
||||||
Smoke after apply:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -sSI http://dossiers.ngi.hacktivism.ch/ | grep -Ei 'HTTP|location'
|
|
||||||
# 308 Location: https://dossiers.ngi.hacktivism.ch/
|
|
||||||
```
|
|
||||||
|
|
||||||
`.2` / `.3` stay off this list unless `SITE=` is set.
|
|
||||||
|
|
||||||
|
|
||||||
Caddy edition map must list each `editions/<slug>` explicitly. A map output of `{http.request.cookie.tdpd_edition}` did not expand on Caddy v2.11.4 (only `flask` worked → 404 for `main`/views). After new tips appear, refresh the snippet map (or regenerate from `ls editions`) before `apply-dossiers-ngi-edition-switch` + `caddy-apply`.
|
Caddy edition map must list each `editions/<slug>` explicitly. A map output of `{http.request.cookie.tdpd_edition}` did not expand on Caddy v2.11.4 (only `flask` worked → 404 for `main`/views). After new tips appear, refresh the snippet map (or regenerate from `ls editions`) before `apply-dossiers-ngi-edition-switch` + `caddy-apply`.
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,7 @@
|
||||||
handle @use {
|
handle @use {
|
||||||
header Set-Cookie "tdpd_edition={re.use.1}; Path=/; Max-Age=31536000; SameSite=Lax"
|
header Set-Cookie "tdpd_edition={re.use.1}; Path=/; Max-Age=31536000; SameSite=Lax"
|
||||||
header Cache-Control "private, no-store"
|
header Cache-Control "private, no-store"
|
||||||
# Keep the caller's path (?next=). Never bounce to /. No next → bar page.
|
redir * / 302
|
||||||
@next query_regexp next ^(/|/[^/].*)$
|
|
||||||
redir @next {query.next} 302
|
|
||||||
redir * /_cascade/ 302
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handle /_cascade/* {
|
handle /_cascade/* {
|
||||||
|
|
|
||||||
|
|
@ -118,24 +118,3 @@ a.cascade-tree-row.is-active:hover {
|
||||||
color: #8a96a3;
|
color: #8a96a3;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
.cascade-hint {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 45rem;
|
|
||||||
margin: 0.15rem auto 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 0.2rem 0.35rem;
|
|
||||||
color: #f0c674;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.cascade-hint[hidden] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.cascade-missing-msg {
|
|
||||||
max-width: 45rem;
|
|
||||||
margin: 1.5rem auto;
|
|
||||||
padding: 0 0.75rem;
|
|
||||||
color: #c8d0d8;
|
|
||||||
font-family: ui-sans-serif, system-ui, sans-serif;
|
|
||||||
font-size: 1rem;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<link rel="stylesheet" href="/_cascade/bar.css">
|
<link rel="stylesheet" href="/_cascade/bar.css">
|
||||||
<nav class="cascade-bar" aria-label="cascade builds" id="cascade-bar">
|
<nav class="cascade-bar" aria-label="cascade builds" id="cascade-bar">
|
||||||
<div class="cascade-tree" id="cascade-tree" role="tree">Loading builds…</div>
|
<div class="cascade-tree" id="cascade-tree" role="tree">Loading builds…</div>
|
||||||
<div class="cascade-hint" id="cascade-hint" role="status" hidden></div>
|
|
||||||
</nav>
|
</nav>
|
||||||
<script src="/_cascade/bar.js" defer></script>
|
<script src="/_cascade/bar.js" defer></script>
|
||||||
|
|
|
||||||
|
|
@ -25,99 +25,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setEditionCookie(edition) {
|
|
||||||
document.cookie =
|
|
||||||
"tdpd_edition=" +
|
|
||||||
encodeURIComponent(edition) +
|
|
||||||
"; Path=/; Max-Age=31536000; SameSite=Lax";
|
|
||||||
}
|
|
||||||
|
|
||||||
function keepPath() {
|
|
||||||
return location.pathname + location.search;
|
|
||||||
}
|
|
||||||
|
|
||||||
function useHref(edition) {
|
|
||||||
var path = keepPath();
|
|
||||||
var href = "/_cascade/use/" + encodeURIComponent(edition);
|
|
||||||
if (!path || path.indexOf("/_cascade/use/") === 0) return href;
|
|
||||||
return href + "?next=" + encodeURIComponent(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
function hintEl() {
|
|
||||||
return document.getElementById("cascade-hint");
|
|
||||||
}
|
|
||||||
|
|
||||||
function showHint(msg) {
|
|
||||||
var el = hintEl();
|
|
||||||
if (!el) {
|
|
||||||
var bar = document.getElementById("cascade-bar");
|
|
||||||
if (!bar) return;
|
|
||||||
el = document.createElement("div");
|
|
||||||
el.id = "cascade-hint";
|
|
||||||
el.className = "cascade-hint";
|
|
||||||
el.setAttribute("role", "status");
|
|
||||||
bar.appendChild(el);
|
|
||||||
}
|
|
||||||
el.hidden = false;
|
|
||||||
el.textContent = msg;
|
|
||||||
pinBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearHint() {
|
|
||||||
var el = hintEl();
|
|
||||||
if (!el) return;
|
|
||||||
el.hidden = true;
|
|
||||||
el.textContent = "";
|
|
||||||
pinBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function responseKeepsBar(res, text) {
|
|
||||||
if (res && res.ok) return true;
|
|
||||||
var body = text || "";
|
|
||||||
return (
|
|
||||||
body.indexOf("cascade-bar") !== -1 ||
|
|
||||||
body.indexOf("cascade-missing") !== -1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchEdition(edition, branchLabel) {
|
|
||||||
var prev = cookieEdition();
|
|
||||||
var here = keepPath() || "/";
|
|
||||||
var label = branchLabel || edition;
|
|
||||||
if (!edition) return;
|
|
||||||
if (edition === prev) {
|
|
||||||
clearHint();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setEditionCookie(edition);
|
|
||||||
fetch(here, { cache: "no-store", credentials: "same-origin" })
|
|
||||||
.then(function (res) {
|
|
||||||
return res.text().then(function (text) {
|
|
||||||
return { res: res, text: text };
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(function (got) {
|
|
||||||
if (responseKeepsBar(got.res, got.text)) {
|
|
||||||
location.replace(here + location.hash);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setEditionCookie(prev);
|
|
||||||
showHint(
|
|
||||||
"This path is not in " +
|
|
||||||
label +
|
|
||||||
". Choose another branch above."
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch(function () {
|
|
||||||
setEditionCookie(prev);
|
|
||||||
showHint(
|
|
||||||
"This path is not in " +
|
|
||||||
label +
|
|
||||||
". Choose another branch above."
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function esc(s) {
|
function esc(s) {
|
||||||
return String(s)
|
return String(s)
|
||||||
.replace(/&/g, "&")
|
.replace(/&/g, "&")
|
||||||
|
|
@ -369,8 +276,8 @@
|
||||||
var parent = row.parent || "";
|
var parent = row.parent || "";
|
||||||
var isDefault = branch === defaultBranch;
|
var isDefault = branch === defaultBranch;
|
||||||
html.push(
|
html.push(
|
||||||
'<a class="cascade-tree-row" role="treeitem" href="' +
|
'<a class="cascade-tree-row" role="treeitem" href="/_cascade/use/' +
|
||||||
esc(useHref(edition)) +
|
esc(edition) +
|
||||||
'" data-edition="' +
|
'" data-edition="' +
|
||||||
esc(edition) +
|
esc(edition) +
|
||||||
'" data-branch="' +
|
'" data-branch="' +
|
||||||
|
|
@ -426,9 +333,7 @@
|
||||||
.catch(function () {
|
.catch(function () {
|
||||||
if (!soft && mount && !mount.querySelector("a[data-edition]")) {
|
if (!soft && mount && !mount.querySelector("a[data-edition]")) {
|
||||||
mount.innerHTML =
|
mount.innerHTML =
|
||||||
'<a class="cascade-tree-row" href="' +
|
'<a class="cascade-tree-row" href="/_cascade/use/flask" data-edition="flask" data-branch="flask"><span class="cascade-name"><code>flask</code></span></a>' +
|
||||||
esc(useHref("flask")) +
|
|
||||||
'" data-edition="flask" data-branch="flask"><span class="cascade-name"><code>flask</code></span></a>' +
|
|
||||||
'<span class="tip"> (branch-status unavailable)</span>';
|
'<span class="tip"> (branch-status unavailable)</span>';
|
||||||
markActive(mount, cookieEdition());
|
markActive(mount, cookieEdition());
|
||||||
pinBar();
|
pinBar();
|
||||||
|
|
@ -436,26 +341,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("click", function (ev) {
|
|
||||||
var a = ev.target.closest
|
|
||||||
? ev.target.closest("a.cascade-tree-row[data-edition]")
|
|
||||||
: null;
|
|
||||||
if (!a || ev.defaultPrevented) return;
|
|
||||||
if (ev.button !== 0 || ev.metaKey || ev.ctrlKey || ev.shiftKey || ev.altKey)
|
|
||||||
return;
|
|
||||||
ev.preventDefault();
|
|
||||||
switchEdition(
|
|
||||||
a.getAttribute("data-edition"),
|
|
||||||
a.getAttribute("data-branch") || a.getAttribute("data-edition")
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (document.body && document.body.classList.contains("cascade-missing")) {
|
|
||||||
showHint(
|
|
||||||
"This path is not in the current branch. Choose another branch above."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadStatus(false);
|
loadStatus(false);
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
loadStatus(true);
|
loadStatus(true);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
<body>
|
<body>
|
||||||
<nav class="cascade-bar" aria-label="cascade builds" id="cascade-bar">
|
<nav class="cascade-bar" aria-label="cascade builds" id="cascade-bar">
|
||||||
<div class="cascade-tree" id="cascade-tree" role="tree">Loading builds…</div>
|
<div class="cascade-tree" id="cascade-tree" role="tree">Loading builds…</div>
|
||||||
<div class="cascade-hint" id="cascade-hint" role="status" hidden></div>
|
|
||||||
</nav>
|
</nav>
|
||||||
<p>Stuck on an edition without a bar? Pick a build above, or <a href="/_cascade/use/flask">reset to flask</a>.</p>
|
<p>Stuck on an edition without a bar? Pick a build above, or <a href="/_cascade/use/flask">reset to flask</a>.</p>
|
||||||
<script src="/_cascade/bar.js" defer></script>
|
<script src="/_cascade/bar.js" defer></script>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<title>path not in this branch</title>
|
|
||||||
<link rel="stylesheet" href="/_cascade/bar.css">
|
|
||||||
</head>
|
|
||||||
<body class="cascade-missing">
|
|
||||||
<nav class="cascade-bar" aria-label="cascade builds" id="cascade-bar">
|
|
||||||
<div class="cascade-tree" id="cascade-tree" role="tree">Loading builds…</div>
|
|
||||||
<div class="cascade-hint" id="cascade-hint" role="status" hidden></div>
|
|
||||||
</nav>
|
|
||||||
<p class="cascade-missing-msg">This address is not in the current branch. Choose another branch above.</p>
|
|
||||||
<script src="/_cascade/bar.js" defer></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -118,24 +118,3 @@ a.cascade-tree-row.is-active:hover {
|
||||||
color: #8a96a3;
|
color: #8a96a3;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
.cascade-hint {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 45rem;
|
|
||||||
margin: 0.15rem auto 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 0.2rem 0.35rem;
|
|
||||||
color: #f0c674;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.cascade-hint[hidden] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.cascade-missing-msg {
|
|
||||||
max-width: 45rem;
|
|
||||||
margin: 1.5rem auto;
|
|
||||||
padding: 0 0.75rem;
|
|
||||||
color: #c8d0d8;
|
|
||||||
font-family: ui-sans-serif, system-ui, sans-serif;
|
|
||||||
font-size: 1rem;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<link rel="stylesheet" href="/_cascade/bar.css">
|
<link rel="stylesheet" href="/_cascade/bar.css">
|
||||||
<nav class="cascade-bar" aria-label="cascade builds" id="cascade-bar">
|
<nav class="cascade-bar" aria-label="cascade builds" id="cascade-bar">
|
||||||
<div class="cascade-tree" id="cascade-tree" role="tree">Loading builds…</div>
|
<div class="cascade-tree" id="cascade-tree" role="tree">Loading builds…</div>
|
||||||
<div class="cascade-hint" id="cascade-hint" role="status" hidden></div>
|
|
||||||
</nav>
|
</nav>
|
||||||
<script src="/_cascade/bar.js" defer></script>
|
<script src="/_cascade/bar.js" defer></script>
|
||||||
|
|
|
||||||
|
|
@ -25,99 +25,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setEditionCookie(edition) {
|
|
||||||
document.cookie =
|
|
||||||
"tdpd_edition=" +
|
|
||||||
encodeURIComponent(edition) +
|
|
||||||
"; Path=/; Max-Age=31536000; SameSite=Lax";
|
|
||||||
}
|
|
||||||
|
|
||||||
function keepPath() {
|
|
||||||
return location.pathname + location.search;
|
|
||||||
}
|
|
||||||
|
|
||||||
function useHref(edition) {
|
|
||||||
var path = keepPath();
|
|
||||||
var href = "/_cascade/use/" + encodeURIComponent(edition);
|
|
||||||
if (!path || path.indexOf("/_cascade/use/") === 0) return href;
|
|
||||||
return href + "?next=" + encodeURIComponent(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
function hintEl() {
|
|
||||||
return document.getElementById("cascade-hint");
|
|
||||||
}
|
|
||||||
|
|
||||||
function showHint(msg) {
|
|
||||||
var el = hintEl();
|
|
||||||
if (!el) {
|
|
||||||
var bar = document.getElementById("cascade-bar");
|
|
||||||
if (!bar) return;
|
|
||||||
el = document.createElement("div");
|
|
||||||
el.id = "cascade-hint";
|
|
||||||
el.className = "cascade-hint";
|
|
||||||
el.setAttribute("role", "status");
|
|
||||||
bar.appendChild(el);
|
|
||||||
}
|
|
||||||
el.hidden = false;
|
|
||||||
el.textContent = msg;
|
|
||||||
pinBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearHint() {
|
|
||||||
var el = hintEl();
|
|
||||||
if (!el) return;
|
|
||||||
el.hidden = true;
|
|
||||||
el.textContent = "";
|
|
||||||
pinBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
function responseKeepsBar(res, text) {
|
|
||||||
if (res && res.ok) return true;
|
|
||||||
var body = text || "";
|
|
||||||
return (
|
|
||||||
body.indexOf("cascade-bar") !== -1 ||
|
|
||||||
body.indexOf("cascade-missing") !== -1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchEdition(edition, branchLabel) {
|
|
||||||
var prev = cookieEdition();
|
|
||||||
var here = keepPath() || "/";
|
|
||||||
var label = branchLabel || edition;
|
|
||||||
if (!edition) return;
|
|
||||||
if (edition === prev) {
|
|
||||||
clearHint();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setEditionCookie(edition);
|
|
||||||
fetch(here, { cache: "no-store", credentials: "same-origin" })
|
|
||||||
.then(function (res) {
|
|
||||||
return res.text().then(function (text) {
|
|
||||||
return { res: res, text: text };
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(function (got) {
|
|
||||||
if (responseKeepsBar(got.res, got.text)) {
|
|
||||||
location.replace(here + location.hash);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setEditionCookie(prev);
|
|
||||||
showHint(
|
|
||||||
"This path is not in " +
|
|
||||||
label +
|
|
||||||
". Choose another branch above."
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch(function () {
|
|
||||||
setEditionCookie(prev);
|
|
||||||
showHint(
|
|
||||||
"This path is not in " +
|
|
||||||
label +
|
|
||||||
". Choose another branch above."
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function esc(s) {
|
function esc(s) {
|
||||||
return String(s)
|
return String(s)
|
||||||
.replace(/&/g, "&")
|
.replace(/&/g, "&")
|
||||||
|
|
@ -369,8 +276,8 @@
|
||||||
var parent = row.parent || "";
|
var parent = row.parent || "";
|
||||||
var isDefault = branch === defaultBranch;
|
var isDefault = branch === defaultBranch;
|
||||||
html.push(
|
html.push(
|
||||||
'<a class="cascade-tree-row" role="treeitem" href="' +
|
'<a class="cascade-tree-row" role="treeitem" href="/_cascade/use/' +
|
||||||
esc(useHref(edition)) +
|
esc(edition) +
|
||||||
'" data-edition="' +
|
'" data-edition="' +
|
||||||
esc(edition) +
|
esc(edition) +
|
||||||
'" data-branch="' +
|
'" data-branch="' +
|
||||||
|
|
@ -426,9 +333,7 @@
|
||||||
.catch(function () {
|
.catch(function () {
|
||||||
if (!soft && mount && !mount.querySelector("a[data-edition]")) {
|
if (!soft && mount && !mount.querySelector("a[data-edition]")) {
|
||||||
mount.innerHTML =
|
mount.innerHTML =
|
||||||
'<a class="cascade-tree-row" href="' +
|
'<a class="cascade-tree-row" href="/_cascade/use/flask" data-edition="flask" data-branch="flask"><span class="cascade-name"><code>flask</code></span></a>' +
|
||||||
esc(useHref("flask")) +
|
|
||||||
'" data-edition="flask" data-branch="flask"><span class="cascade-name"><code>flask</code></span></a>' +
|
|
||||||
'<span class="tip"> (branch-status unavailable)</span>';
|
'<span class="tip"> (branch-status unavailable)</span>';
|
||||||
markActive(mount, cookieEdition());
|
markActive(mount, cookieEdition());
|
||||||
pinBar();
|
pinBar();
|
||||||
|
|
@ -436,26 +341,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("click", function (ev) {
|
|
||||||
var a = ev.target.closest
|
|
||||||
? ev.target.closest("a.cascade-tree-row[data-edition]")
|
|
||||||
: null;
|
|
||||||
if (!a || ev.defaultPrevented) return;
|
|
||||||
if (ev.button !== 0 || ev.metaKey || ev.ctrlKey || ev.shiftKey || ev.altKey)
|
|
||||||
return;
|
|
||||||
ev.preventDefault();
|
|
||||||
switchEdition(
|
|
||||||
a.getAttribute("data-edition"),
|
|
||||||
a.getAttribute("data-branch") || a.getAttribute("data-edition")
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (document.body && document.body.classList.contains("cascade-missing")) {
|
|
||||||
showHint(
|
|
||||||
"This path is not in the current branch. Choose another branch above."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadStatus(false);
|
loadStatus(false);
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
loadStatus(true);
|
loadStatus(true);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
<body>
|
<body>
|
||||||
<nav class="cascade-bar" aria-label="cascade builds" id="cascade-bar">
|
<nav class="cascade-bar" aria-label="cascade builds" id="cascade-bar">
|
||||||
<div class="cascade-tree" id="cascade-tree" role="tree">Loading builds…</div>
|
<div class="cascade-tree" id="cascade-tree" role="tree">Loading builds…</div>
|
||||||
<div class="cascade-hint" id="cascade-hint" role="status" hidden></div>
|
|
||||||
</nav>
|
</nav>
|
||||||
<p>Stuck on an edition without a bar? Pick a build above, or <a href="/_cascade/use/flask">reset to flask</a>.</p>
|
<p>Stuck on an edition without a bar? Pick a build above, or <a href="/_cascade/use/flask">reset to flask</a>.</p>
|
||||||
<script src="/_cascade/bar.js" defer></script>
|
<script src="/_cascade/bar.js" defer></script>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue