108 lines
6.1 KiB
HTML
108 lines
6.1 KiB
HTML
{{define "layout"}}<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content" />
|
|
<title>{{.Title}}</title>
|
|
<link rel="icon" href="{{asset "favicon.ico"}}" />
|
|
<link rel="preload" href="/_/fonts/IosevkaEtoile.woff2" as="font" type="font/woff2" crossorigin />
|
|
<link rel="preload" href="/_/fonts/IosevkaSlab.woff2" as="font" type="font/woff2" crossorigin />
|
|
<link rel="stylesheet" href="{{asset "style.css"}}" />
|
|
<script src="{{asset "vendor/htmx.min.js"}}" defer></script>
|
|
<script src="{{asset "hx.js"}}" defer></script>
|
|
<script src="{{asset "modal.js"}}"></script>
|
|
<script src="{{asset "global-shortcuts.js"}}"></script>
|
|
<script src="{{asset "history-nav.js"}}"></script>
|
|
<script src="{{asset "scroll-sync.js"}}" defer></script>
|
|
<script src="{{asset "search-suggest.js"}}" defer></script>
|
|
<script src="{{asset "tree-picker.js"}}"></script>
|
|
<script src="{{asset "companion.js"}}" defer></script>
|
|
{{if not .EditMode}}<script src="{{asset "overlay.js"}}" defer></script>
|
|
<script src="{{asset "page/actions.js"}}"></script>
|
|
<script src="{{asset "search/actions.js"}}"></script>{{end}}
|
|
</head>
|
|
{{/* Outside the editor, links to pages are boosted: htmx swaps .shell
|
|
(plus title and page actions, see "partial") instead of loading a new
|
|
document. hx.js decides which links count as pages. A view can opt out by
|
|
overriding "boost" (the canvas does: it saves on pagehide). */}}
|
|
<body{{if not .EditMode}}{{block "boost" .}} hx-boost="true"{{end}}{{end}}>
|
|
<header>
|
|
<nav class="breadcrumb row">
|
|
<a href="/" tabindex="-1" title="Home"><svg class="logo" viewBox="0 0 26.052269 26.052269" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="currentColor" stroke-linejoin="miter" transform="matrix(0.05463483,8.1519706e-6,-8.1519706e-6,0.05463483,-64.560546,-24.6949)"><rect x="1188.537" y="457.92056" width="461.87488" height="462.15189" stroke-width="20.2288"/><path d="m1348.9955 456.59572.046 309.36839" stroke-width="19.6849"/><path d="m1200.3996 765.80237 441.8362-.0659" stroke-width="19.6849"/><path d="m1648.2897 620.244-299.2012.0446" stroke-width="20.5676"/><path d="m1491.6148 909.24806-.021-136.93117" stroke-width="19.6849"/><rect x="1191.6504" y="461.66092" width="457.09634" height="457.09634" stroke-width="19.6761"/></g></svg><span class="app-name"> datascape</span></a>
|
|
</nav>
|
|
{{if not .EditMode}}
|
|
<form class="search-form" action="/" method="get">
|
|
<input class="input search-input" type="search" name="q" value="{{block "searchQuery" .}}{{end}}" placeholder="Search…" title="Search (F)" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />
|
|
</form>
|
|
{{end}}
|
|
<div class="header-actions row">
|
|
{{if .EditMode}}{{block "headerActions" .}}{{end}}{{else}}
|
|
{{maintenanceWidget}}
|
|
<span class="dropdown actions">
|
|
<button type="button" class="btn actions-toggle" data-action="actions-menu" aria-haspopup="true" aria-expanded="false" title="Actions">ACTIONS</button>
|
|
<div class="dropdown-menu align-right actions-menu">
|
|
{{template "page-actions" .}}
|
|
</div>
|
|
</span>
|
|
{{end}}
|
|
</div>
|
|
</header>
|
|
<div class="shell" hx-history-elt hx-history="false">{{template "shell" .}}</div>
|
|
{{block "extras" .}}{{end}}
|
|
<div id="modal-host"></div>
|
|
</body>
|
|
</html>
|
|
{{end}}
|
|
|
|
{{/* The page-specific header actions; the partial swaps them out-of-band
|
|
(the attribute is inert in a full page). */}}
|
|
{{define "page-actions"}}<div id="page-actions" class="page-actions" hx-swap-oob="true">
|
|
<div class="actions-special">
|
|
<button type="button" class="btn btn-block" title="Folders" onclick="openOverlay(document.querySelector('.tree-scroll'))">FOLDERS</button>
|
|
</div>
|
|
{{template "headerActions" .}}
|
|
</div>{{end}}
|
|
|
|
{{define "shell"}}
|
|
{{if not .EditMode}}<aside class="tree-sidebar col">
|
|
<nav class="tree-scroll" aria-label="Folders">{{.Tree}}</nav>
|
|
<script>
|
|
// Full page loads: keep the rail's scroll position (before first
|
|
// paint, so it doesn't jump), then reveal the active row. Boosted
|
|
// navigation keeps it itself (hx.js); this script re-runs then and
|
|
// bails out.
|
|
(function () {
|
|
if (document.readyState !== "loading") return;
|
|
var el = document.currentScript.previousElementSibling;
|
|
try { el.scrollTop = +sessionStorage.getItem("tree-scroll") || 0; } catch (e) {}
|
|
var active = el.querySelector(".tree-row.is-active");
|
|
if (active) active.scrollIntoView({ block: "nearest" });
|
|
addEventListener("pagehide", function () {
|
|
var cur = document.querySelector(".tree-scroll");
|
|
try { sessionStorage.setItem("tree-scroll", cur ? cur.scrollTop : 0); } catch (e) {}
|
|
});
|
|
})();
|
|
</script>
|
|
</aside>{{end}}
|
|
<div class="center">
|
|
<main>
|
|
{{block "content" .}}{{end}}
|
|
</main>
|
|
<footer>
|
|
<span class="muted">Request: {{.RenderMS}} ms</span>
|
|
{{block "footerExtras" .}}{{end}}
|
|
<span class="dropdown companion-status" data-companion-status hidden>
|
|
<button type="button" class="btn btn-small companion-icon" data-action="companion-toggle" title="Companion status" aria-label="Companion status">○</button>
|
|
<div class="dropdown-menu align-right open-up companion-flyout"></div>
|
|
</span>
|
|
</footer>
|
|
</div>
|
|
{{if not .EditMode}}{{block "aside" .}}{{end}}{{end}}
|
|
{{end}}
|
|
|
|
{{/* Response to boosted navigation and history restores (hx.js swaps it into
|
|
.shell): the title, the page actions out-of-band, and the shell's content. */}}
|
|
{{define "partial"}}<title>{{.Title}}</title>
|
|
{{template "page-actions" .}}
|
|
{{template "shell" .}}{{end}}
|