feat(web): expand directories in place in the Files view
- commit
- 39ca311756f5cde2a82d8cd77938f885034a3d50
- author
- brice · · 2026-10-11 18:29 UTC
- parent
- bfab294
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
43 files · +534 -331
M cmd/ermite/testdata/web/blob-binary.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/blob-code.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/blob-empty.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/blob-image.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/blob-markdown.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/blob-svg.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/blob-text.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/blob-too-large.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/blob-trojan.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commit-big.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commit-binary.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commit-merge.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commit-modify-split.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commit-modify.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commit-rename.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commit-root.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commit-trojan.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commits-page2.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commits-path.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commits-root.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/commits-small.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/empty.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/home.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/not-found-page.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/not-found.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | 22 | <body data-ref="" data-sha="" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/refs.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/summary.html +2 -0
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
M cmd/ermite/testdata/web/tree-nested.html +3 -7
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -106,7 +108,7 @@ | |||
| 106 | 108 | <th class="c-when">date</th> | |
| 107 | 109 | </tr> | |
| 108 | 110 | </thead> | |
| 109 | - | <tbody id="tree-rows" data-rows> | |
| 111 | + | <tbody id="tree-rows" data-rows hx-on:click="ermiteTree.click(event)"> | |
| 110 | 112 | <tr data-cursor> | |
| 111 | 113 | <td class="cur" aria-hidden="true"> | |
| 112 | 114 | </td> | |
| @@ -341,12 +343,6 @@ | |||
| 341 | 343 | <span class="k">tag</span> | |
| 342 | 344 | </a> | |
| 343 | 345 | </li> | |
| 344 | - | <li data-k="file src/lib/util.go"> | |
| 345 | - | <a href="/files/blob/main/src/lib/util.go" tabindex="-1"> | |
| 346 | - | <span class="lbl">src/lib/util.go</span> | |
| 347 | - | <span class="k">file</span> | |
| 348 | - | </a> | |
| 349 | - | </li> | |
| 350 | 346 | </ul> | |
| 351 | 347 | <p class="panel-foot"> | |
| 352 | 348 | <span> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
| @@ -106,7 +108,7 @@ | |||||
| 106 | <th class="c-when">date</th> | 108 | <th class="c-when">date</th> | ||
| 107 | </tr> | 109 | </tr> | ||
| 108 | </thead> | 110 | </thead> | ||
| 109 | - | <tbody id="tree-rows" data-rows> | 111 | + | <tbody id="tree-rows" data-rows hx-on:click="ermiteTree.click(event)"> |
| 110 | <tr data-cursor> | 112 | <tr data-cursor> | ||
| 111 | <td class="cur" aria-hidden="true"> | 113 | <td class="cur" aria-hidden="true"> | ||
| 112 | </td> | 114 | </td> | ||
| @@ -341,12 +343,6 @@ | |||||
| 341 | <span class="k">tag</span> | 343 | <span class="k">tag</span> | ||
| 342 | </a> | 344 | </a> | ||
| 343 | </li> | 345 | </li> | ||
| 344 | - | <li data-k="file src/lib/util.go"> | |||
| 345 | - | <a href="/files/blob/main/src/lib/util.go" tabindex="-1"> | |||
| 346 | - | <span class="lbl">src/lib/util.go</span> | |||
| 347 | - | <span class="k">file</span> | |||
| 348 | - | </a> | |||
| 349 | - | </li> | |||
| 350 | </ul> | 346 | </ul> | ||
| 351 | <p class="panel-foot"> | 347 | <p class="panel-foot"> | ||
| 352 | <span> | 348 | <span> | ||
M cmd/ermite/testdata/web/tree-root.html +7 -83
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -100,13 +102,13 @@ | |||
| 100 | 102 | <th class="c-when">date</th> | |
| 101 | 103 | </tr> | |
| 102 | 104 | </thead> | |
| 103 | - | <tbody id="tree-rows" data-rows> | |
| 105 | + | <tbody id="tree-rows" data-rows hx-on:click="ermiteTree.click(event)"> | |
| 104 | 106 | <tr data-cursor> | |
| 105 | 107 | <td class="cur" aria-hidden="true"> | |
| 106 | 108 | </td> | |
| 107 | - | <td class="c-kind" aria-hidden="true">▾</td> | |
| 109 | + | <td class="c-kind" aria-hidden="true">▸</td> | |
| 108 | 110 | <td class="c-name"> | |
| 109 | - | <a href="/files/tree/main/docs">docs/</a> | |
| 111 | + | <a href="/files/tree/main/docs" data-expand="/files/tree/main/docs?rows" aria-expanded="false">docs/</a> | |
| 110 | 112 | </td> | |
| 111 | 113 | <td class="c-size num dim">-</td> | |
| 112 | 114 | <td class="c-sub dim"> | |
| @@ -120,9 +122,9 @@ | |||
| 120 | 122 | <tr> | |
| 121 | 123 | <td class="cur" aria-hidden="true"> | |
| 122 | 124 | </td> | |
| 123 | - | <td class="c-kind" aria-hidden="true">▾</td> | |
| 125 | + | <td class="c-kind" aria-hidden="true">▸</td> | |
| 124 | 126 | <td class="c-name"> | |
| 125 | - | <a href="/files/tree/main/src">src/</a> | |
| 127 | + | <a href="/files/tree/main/src" data-expand="/files/tree/main/src?rows" aria-expanded="false">src/</a> | |
| 126 | 128 | </td> | |
| 127 | 129 | <td class="c-size num dim">-</td> | |
| 128 | 130 | <td class="c-sub dim"> | |
| @@ -568,84 +570,6 @@ | |||
| 568 | 570 | <span class="k">tag</span> | |
| 569 | 571 | </a> | |
| 570 | 572 | </li> | |
| 571 | - | <li data-k="file readme.md"> | |
| 572 | - | <a href="/files/blob/main/README.md" tabindex="-1"> | |
| 573 | - | <span class="lbl">README.md</span> | |
| 574 | - | <span class="k">file</span> | |
| 575 | - | </a> | |
| 576 | - | </li> | |
| 577 | - | <li data-k="file big.txt"> | |
| 578 | - | <a href="/files/blob/main/big.txt" tabindex="-1"> | |
| 579 | - | <span class="lbl">big.txt</span> | |
| 580 | - | <span class="k">file</span> | |
| 581 | - | </a> | |
| 582 | - | </li> | |
| 583 | - | <li data-k="file data.bin"> | |
| 584 | - | <a href="/files/blob/main/data.bin" tabindex="-1"> | |
| 585 | - | <span class="lbl">data.bin</span> | |
| 586 | - | <span class="k">file</span> | |
| 587 | - | </a> | |
| 588 | - | </li> | |
| 589 | - | <li data-k="file empty.txt"> | |
| 590 | - | <a href="/files/blob/main/empty.txt" tabindex="-1"> | |
| 591 | - | <span class="lbl">empty.txt</span> | |
| 592 | - | <span class="k">file</span> | |
| 593 | - | </a> | |
| 594 | - | </li> | |
| 595 | - | <li data-k="file evil.go"> | |
| 596 | - | <a href="/files/blob/main/evil.go" tabindex="-1"> | |
| 597 | - | <span class="lbl">evil.go</span> | |
| 598 | - | <span class="k">file</span> | |
| 599 | - | </a> | |
| 600 | - | </li> | |
| 601 | - | <li data-k="file fake.jpg"> | |
| 602 | - | <a href="/files/blob/main/fake.jpg" tabindex="-1"> | |
| 603 | - | <span class="lbl">fake.jpg</span> | |
| 604 | - | <span class="k">file</span> | |
| 605 | - | </a> | |
| 606 | - | </li> | |
| 607 | - | <li data-k="file fake.png"> | |
| 608 | - | <a href="/files/blob/main/fake.png" tabindex="-1"> | |
| 609 | - | <span class="lbl">fake.png</span> | |
| 610 | - | <span class="k">file</span> | |
| 611 | - | </a> | |
| 612 | - | </li> | |
| 613 | - | <li data-k="file lines.txt"> | |
| 614 | - | <a href="/files/blob/main/lines.txt" tabindex="-1"> | |
| 615 | - | <span class="lbl">lines.txt</span> | |
| 616 | - | <span class="k">file</span> | |
| 617 | - | </a> | |
| 618 | - | </li> | |
| 619 | - | <li data-k="file logo.svg"> | |
| 620 | - | <a href="/files/blob/main/logo.svg" tabindex="-1"> | |
| 621 | - | <span class="lbl">logo.svg</span> | |
| 622 | - | <span class="k">file</span> | |
| 623 | - | </a> | |
| 624 | - | </li> | |
| 625 | - | <li data-k="file main.go"> | |
| 626 | - | <a href="/files/blob/main/main.go" tabindex="-1"> | |
| 627 | - | <span class="lbl">main.go</span> | |
| 628 | - | <span class="k">file</span> | |
| 629 | - | </a> | |
| 630 | - | </li> | |
| 631 | - | <li data-k="file notes.txt"> | |
| 632 | - | <a href="/files/blob/main/notes.txt" tabindex="-1"> | |
| 633 | - | <span class="lbl">notes.txt</span> | |
| 634 | - | <span class="k">file</span> | |
| 635 | - | </a> | |
| 636 | - | </li> | |
| 637 | - | <li data-k="file page.html"> | |
| 638 | - | <a href="/files/blob/main/page.html" tabindex="-1"> | |
| 639 | - | <span class="lbl">page.html</span> | |
| 640 | - | <span class="k">file</span> | |
| 641 | - | </a> | |
| 642 | - | </li> | |
| 643 | - | <li data-k="file pic.png"> | |
| 644 | - | <a href="/files/blob/main/pic.png" tabindex="-1"> | |
| 645 | - | <span class="lbl">pic.png</span> | |
| 646 | - | <span class="k">file</span> | |
| 647 | - | </a> | |
| 648 | - | </li> | |
| 649 | 573 | </ul> | |
| 650 | 574 | <p class="panel-foot"> | |
| 651 | 575 | <span> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
| @@ -100,13 +102,13 @@ | |||||
| 100 | <th class="c-when">date</th> | 102 | <th class="c-when">date</th> | ||
| 101 | </tr> | 103 | </tr> | ||
| 102 | </thead> | 104 | </thead> | ||
| 103 | - | <tbody id="tree-rows" data-rows> | 105 | + | <tbody id="tree-rows" data-rows hx-on:click="ermiteTree.click(event)"> |
| 104 | <tr data-cursor> | 106 | <tr data-cursor> | ||
| 105 | <td class="cur" aria-hidden="true"> | 107 | <td class="cur" aria-hidden="true"> | ||
| 106 | </td> | 108 | </td> | ||
| 107 | - | <td class="c-kind" aria-hidden="true">▾</td> | 109 | + | <td class="c-kind" aria-hidden="true">▸</td> |
| 108 | <td class="c-name"> | 110 | <td class="c-name"> | ||
| 109 | - | <a href="/files/tree/main/docs">docs/</a> | 111 | + | <a href="/files/tree/main/docs" data-expand="/files/tree/main/docs?rows" aria-expanded="false">docs/</a> |
| 110 | </td> | 112 | </td> | ||
| 111 | <td class="c-size num dim">-</td> | 113 | <td class="c-size num dim">-</td> | ||
| 112 | <td class="c-sub dim"> | 114 | <td class="c-sub dim"> | ||
| @@ -120,9 +122,9 @@ | |||||
| 120 | <tr> | 122 | <tr> | ||
| 121 | <td class="cur" aria-hidden="true"> | 123 | <td class="cur" aria-hidden="true"> | ||
| 122 | </td> | 124 | </td> | ||
| 123 | - | <td class="c-kind" aria-hidden="true">▾</td> | 125 | + | <td class="c-kind" aria-hidden="true">▸</td> |
| 124 | <td class="c-name"> | 126 | <td class="c-name"> | ||
| 125 | - | <a href="/files/tree/main/src">src/</a> | 127 | + | <a href="/files/tree/main/src" data-expand="/files/tree/main/src?rows" aria-expanded="false">src/</a> |
| 126 | </td> | 128 | </td> | ||
| 127 | <td class="c-size num dim">-</td> | 129 | <td class="c-size num dim">-</td> | ||
| 128 | <td class="c-sub dim"> | 130 | <td class="c-sub dim"> | ||
| @@ -568,84 +570,6 @@ | |||||
| 568 | <span class="k">tag</span> | 570 | <span class="k">tag</span> | ||
| 569 | </a> | 571 | </a> | ||
| 570 | </li> | 572 | </li> | ||
| 571 | - | <li data-k="file readme.md"> | |||
| 572 | - | <a href="/files/blob/main/README.md" tabindex="-1"> | |||
| 573 | - | <span class="lbl">README.md</span> | |||
| 574 | - | <span class="k">file</span> | |||
| 575 | - | </a> | |||
| 576 | - | </li> | |||
| 577 | - | <li data-k="file big.txt"> | |||
| 578 | - | <a href="/files/blob/main/big.txt" tabindex="-1"> | |||
| 579 | - | <span class="lbl">big.txt</span> | |||
| 580 | - | <span class="k">file</span> | |||
| 581 | - | </a> | |||
| 582 | - | </li> | |||
| 583 | - | <li data-k="file data.bin"> | |||
| 584 | - | <a href="/files/blob/main/data.bin" tabindex="-1"> | |||
| 585 | - | <span class="lbl">data.bin</span> | |||
| 586 | - | <span class="k">file</span> | |||
| 587 | - | </a> | |||
| 588 | - | </li> | |||
| 589 | - | <li data-k="file empty.txt"> | |||
| 590 | - | <a href="/files/blob/main/empty.txt" tabindex="-1"> | |||
| 591 | - | <span class="lbl">empty.txt</span> | |||
| 592 | - | <span class="k">file</span> | |||
| 593 | - | </a> | |||
| 594 | - | </li> | |||
| 595 | - | <li data-k="file evil.go"> | |||
| 596 | - | <a href="/files/blob/main/evil.go" tabindex="-1"> | |||
| 597 | - | <span class="lbl">evil.go</span> | |||
| 598 | - | <span class="k">file</span> | |||
| 599 | - | </a> | |||
| 600 | - | </li> | |||
| 601 | - | <li data-k="file fake.jpg"> | |||
| 602 | - | <a href="/files/blob/main/fake.jpg" tabindex="-1"> | |||
| 603 | - | <span class="lbl">fake.jpg</span> | |||
| 604 | - | <span class="k">file</span> | |||
| 605 | - | </a> | |||
| 606 | - | </li> | |||
| 607 | - | <li data-k="file fake.png"> | |||
| 608 | - | <a href="/files/blob/main/fake.png" tabindex="-1"> | |||
| 609 | - | <span class="lbl">fake.png</span> | |||
| 610 | - | <span class="k">file</span> | |||
| 611 | - | </a> | |||
| 612 | - | </li> | |||
| 613 | - | <li data-k="file lines.txt"> | |||
| 614 | - | <a href="/files/blob/main/lines.txt" tabindex="-1"> | |||
| 615 | - | <span class="lbl">lines.txt</span> | |||
| 616 | - | <span class="k">file</span> | |||
| 617 | - | </a> | |||
| 618 | - | </li> | |||
| 619 | - | <li data-k="file logo.svg"> | |||
| 620 | - | <a href="/files/blob/main/logo.svg" tabindex="-1"> | |||
| 621 | - | <span class="lbl">logo.svg</span> | |||
| 622 | - | <span class="k">file</span> | |||
| 623 | - | </a> | |||
| 624 | - | </li> | |||
| 625 | - | <li data-k="file main.go"> | |||
| 626 | - | <a href="/files/blob/main/main.go" tabindex="-1"> | |||
| 627 | - | <span class="lbl">main.go</span> | |||
| 628 | - | <span class="k">file</span> | |||
| 629 | - | </a> | |||
| 630 | - | </li> | |||
| 631 | - | <li data-k="file notes.txt"> | |||
| 632 | - | <a href="/files/blob/main/notes.txt" tabindex="-1"> | |||
| 633 | - | <span class="lbl">notes.txt</span> | |||
| 634 | - | <span class="k">file</span> | |||
| 635 | - | </a> | |||
| 636 | - | </li> | |||
| 637 | - | <li data-k="file page.html"> | |||
| 638 | - | <a href="/files/blob/main/page.html" tabindex="-1"> | |||
| 639 | - | <span class="lbl">page.html</span> | |||
| 640 | - | <span class="k">file</span> | |||
| 641 | - | </a> | |||
| 642 | - | </li> | |||
| 643 | - | <li data-k="file pic.png"> | |||
| 644 | - | <a href="/files/blob/main/pic.png" tabindex="-1"> | |||
| 645 | - | <span class="lbl">pic.png</span> | |||
| 646 | - | <span class="k">file</span> | |||
| 647 | - | </a> | |||
| 648 | - | </li> | |||
| 649 | </ul> | 573 | </ul> | ||
| 650 | <p class="panel-foot"> | 574 | <p class="panel-foot"> | ||
| 651 | <span> | 575 | <span> | ||
M cmd/ermite/testdata/web/tree-slash-ref.html +3 -7
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="feature/x" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -103,7 +105,7 @@ | |||
| 103 | 105 | <th class="c-when">date</th> | |
| 104 | 106 | </tr> | |
| 105 | 107 | </thead> | |
| 106 | - | <tbody id="tree-rows" data-rows> | |
| 108 | + | <tbody id="tree-rows" data-rows hx-on:click="ermiteTree.click(event)"> | |
| 107 | 109 | <tr data-cursor> | |
| 108 | 110 | <td class="cur" aria-hidden="true"> | |
| 109 | 111 | </td> | |
| @@ -338,12 +340,6 @@ | |||
| 338 | 340 | <span class="k">tag</span> | |
| 339 | 341 | </a> | |
| 340 | 342 | </li> | |
| 341 | - | <li data-k="file x/y.txt"> | |
| 342 | - | <a href="/files/blob/feature/x/x/y.txt" tabindex="-1"> | |
| 343 | - | <span class="lbl">x/y.txt</span> | |
| 344 | - | <span class="k">file</span> | |
| 345 | - | </a> | |
| 346 | - | </li> | |
| 347 | 343 | </ul> | |
| 348 | 344 | <p class="panel-foot"> | |
| 349 | 345 | <span> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="feature/x" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="feature/x" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
| @@ -103,7 +105,7 @@ | |||||
| 103 | <th class="c-when">date</th> | 105 | <th class="c-when">date</th> | ||
| 104 | </tr> | 106 | </tr> | ||
| 105 | </thead> | 107 | </thead> | ||
| 106 | - | <tbody id="tree-rows" data-rows> | 108 | + | <tbody id="tree-rows" data-rows hx-on:click="ermiteTree.click(event)"> |
| 107 | <tr data-cursor> | 109 | <tr data-cursor> | ||
| 108 | <td class="cur" aria-hidden="true"> | 110 | <td class="cur" aria-hidden="true"> | ||
| 109 | </td> | 111 | </td> | ||
| @@ -338,12 +340,6 @@ | |||||
| 338 | <span class="k">tag</span> | 340 | <span class="k">tag</span> | ||
| 339 | </a> | 341 | </a> | ||
| 340 | </li> | 342 | </li> | ||
| 341 | - | <li data-k="file x/y.txt"> | |||
| 342 | - | <a href="/files/blob/feature/x/x/y.txt" tabindex="-1"> | |||
| 343 | - | <span class="lbl">x/y.txt</span> | |||
| 344 | - | <span class="k">file</span> | |||
| 345 | - | </a> | |||
| 346 | - | </li> | |||
| 347 | </ul> | 343 | </ul> | ||
| 348 | <p class="panel-foot"> | 344 | <p class="panel-foot"> | ||
| 349 | <span> | 345 | <span> | ||
M cmd/ermite/testdata/web/tree-subdir.html +3 -13
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | </script> | |
| 17 | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | |
| 18 | 18 | </script> | |
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |
| 20 | + | </script> | |
| 19 | 21 | </head> | |
| 20 | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | |
| 21 | 23 | <a class="skip" href="#main">skip to content</a> | |
| @@ -103,7 +105,7 @@ | |||
| 103 | 105 | <th class="c-when">date</th> | |
| 104 | 106 | </tr> | |
| 105 | 107 | </thead> | |
| 106 | - | <tbody id="tree-rows" data-rows> | |
| 108 | + | <tbody id="tree-rows" data-rows hx-on:click="ermiteTree.click(event)"> | |
| 107 | 109 | <tr data-cursor> | |
| 108 | 110 | <td class="cur" aria-hidden="true"> | |
| 109 | 111 | </td> | |
| @@ -363,18 +365,6 @@ | |||
| 363 | 365 | <span class="k">tag</span> | |
| 364 | 366 | </a> | |
| 365 | 367 | </li> | |
| 366 | - | <li data-k="file docs/readme.md"> | |
| 367 | - | <a href="/files/blob/main/docs/README.md" tabindex="-1"> | |
| 368 | - | <span class="lbl">docs/README.md</span> | |
| 369 | - | <span class="k">file</span> | |
| 370 | - | </a> | |
| 371 | - | </li> | |
| 372 | - | <li data-k="file docs/guide.md"> | |
| 373 | - | <a href="/files/blob/main/docs/guide.md" tabindex="-1"> | |
| 374 | - | <span class="lbl">docs/guide.md</span> | |
| 375 | - | <span class="k">file</span> | |
| 376 | - | </a> | |
| 377 | - | </li> | |
| 378 | 368 | </ul> | |
| 379 | 369 | <p class="panel-foot"> | |
| 380 | 370 | <span> | |
| @@ -16,6 +16,8 @@ | |||||
| 16 | </script> | 16 | </script> | ||
| 17 | <script src="/-/static/js/ermite.HASH.js" defer> | 17 | <script src="/-/static/js/ermite.HASH.js" defer> | ||
| 18 | </script> | 18 | </script> | ||
| 19 | + | <script src="/-/static/js/files.HASH.js" defer> | |||
| 20 | + | </script> | |||
| 19 | </head> | 21 | </head> | ||
| 20 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | 22 | <body data-ref="main" data-sha="SHA40" data-sel="" data-nav=""> | ||
| 21 | <a class="skip" href="#main">skip to content</a> | 23 | <a class="skip" href="#main">skip to content</a> | ||
| @@ -103,7 +105,7 @@ | |||||
| 103 | <th class="c-when">date</th> | 105 | <th class="c-when">date</th> | ||
| 104 | </tr> | 106 | </tr> | ||
| 105 | </thead> | 107 | </thead> | ||
| 106 | - | <tbody id="tree-rows" data-rows> | 108 | + | <tbody id="tree-rows" data-rows hx-on:click="ermiteTree.click(event)"> |
| 107 | <tr data-cursor> | 109 | <tr data-cursor> | ||
| 108 | <td class="cur" aria-hidden="true"> | 110 | <td class="cur" aria-hidden="true"> | ||
| 109 | </td> | 111 | </td> | ||
| @@ -363,18 +365,6 @@ | |||||
| 363 | <span class="k">tag</span> | 365 | <span class="k">tag</span> | ||
| 364 | </a> | 366 | </a> | ||
| 365 | </li> | 367 | </li> | ||
| 366 | - | <li data-k="file docs/readme.md"> | |||
| 367 | - | <a href="/files/blob/main/docs/README.md" tabindex="-1"> | |||
| 368 | - | <span class="lbl">docs/README.md</span> | |||
| 369 | - | <span class="k">file</span> | |||
| 370 | - | </a> | |||
| 371 | - | </li> | |||
| 372 | - | <li data-k="file docs/guide.md"> | |||
| 373 | - | <a href="/files/blob/main/docs/guide.md" tabindex="-1"> | |||
| 374 | - | <span class="lbl">docs/guide.md</span> | |||
| 375 | - | <span class="k">file</span> | |||
| 376 | - | </a> | |||
| 377 | - | </li> | |||
| 378 | </ul> | 368 | </ul> | ||
| 379 | <p class="panel-foot"> | 369 | <p class="panel-foot"> | ||
| 380 | <span> | 370 | <span> | ||
M cmd/ermite/web_files_test.go +42 -0
| @@ -100,6 +100,48 @@ func TestWebFilesGolden(t *testing.T) { | |||
| 100 | 100 | } | |
| 101 | 101 | } | |
| 102 | 102 | ||
| 103 | + | // AC1, AC2, AC7: ?rows answers the entries of a directory as table rows only, | |
| 104 | + | // for the Files view to insert under the directory; a private repository is | |
| 105 | + | // the 404 of a missing one. | |
| 106 | + | func TestWebTreeRows(t *testing.T) { | |
| 107 | + | h := newHarness(t, harnessOpts{}) | |
| 108 | + | h.webFilesRepo("files") | |
| 109 | + | h.seed("secret-sauce", domain.VisibilityPrivate, "dir/a.txt") | |
| 110 | + | ||
| 111 | + | // The page links its directories to their rows. | |
| 112 | + | _, _, page := h.get("/files/tree/main") | |
| 113 | + | assert.Contains(t, page, `href="/files/tree/main/docs" data-expand="/files/tree/main/docs?rows" aria-expanded="false"`) | |
| 114 | + | assert.Contains(t, page, `<script src="/-/static/js/files.`) | |
| 115 | + | assert.NotContains(t, page, "main.go</span>", "the palette lists no file") | |
| 116 | + | ||
| 117 | + | status, hdr, body := h.get("/files/tree/main/docs?rows") | |
| 118 | + | require.Equal(t, 200, status) | |
| 119 | + | assert.Equal(t, "no-cache", hdr.Get("Cache-Control")) | |
| 120 | + | assert.Contains(t, hdr.Get("Content-Type"), "text/html") | |
| 121 | + | assert.NotContains(t, body, "<html") | |
| 122 | + | assert.NotContains(t, body, "<table") | |
| 123 | + | assert.Equal(t, 2, strings.Count(body, "<tr"), "one row per entry") | |
| 124 | + | assert.Contains(t, body, `<a href="/files/blob/main/docs/README.md">README.md</a>`) | |
| 125 | + | assert.Contains(t, body, `<a href="/files/blob/main/docs/guide.md">guide.md</a>`) | |
| 126 | + | assert.NotContains(t, body, "data-cursor", "the cursor stays on the page") | |
| 127 | + | assertNoInline(t, body) | |
| 128 | + | ||
| 129 | + | // A subdirectory row can be opened in turn. | |
| 130 | + | _, _, body = h.get("/files/tree/main/src?rows") | |
| 131 | + | assert.Contains(t, body, `href="/files/tree/main/src/lib" data-expand="/files/tree/main/src/lib?rows" aria-expanded="false"`) | |
| 132 | + | assert.Contains(t, body, "▸") | |
| 133 | + | _, _, body = h.get("/files/tree/main/src/lib?rows") | |
| 134 | + | assert.Contains(t, body, `href="/files/blob/main/src/lib/util.go"`) | |
| 135 | + | assert.NotContains(t, body, "data-expand") | |
| 136 | + | ||
| 137 | + | // Not found, and private as anonymous: the 404 page, nothing of the rows. | |
| 138 | + | for _, p := range []string{"/files/tree/main/nope?rows", "/secret-sauce/tree/main/dir?rows", "/secret-sauce/tree/main?rows"} { | |
| 139 | + | status, _, body = h.get(p) | |
| 140 | + | assert.Equal(t, 404, status, p) | |
| 141 | + | assert.NotContains(t, body, "a.txt", p) | |
| 142 | + | } | |
| 143 | + | } | |
| 144 | + | ||
| 103 | 145 | // Ref names with a slash are found by their longest prefix, and a commit id | |
| 104 | 146 | // works where a ref does. | |
| 105 | 147 | func TestWebFilesRefs(t *testing.T) { | |
| @@ -100,6 +100,48 @@ func TestWebFilesGolden(t *testing.T) { | |||||
| 100 | } | 100 | } | ||
| 101 | } | 101 | } | ||
| 102 | 102 | ||||
| 103 | + | // AC1, AC2, AC7: ?rows answers the entries of a directory as table rows only, | |||
| 104 | + | // for the Files view to insert under the directory; a private repository is | |||
| 105 | + | // the 404 of a missing one. | |||
| 106 | + | func TestWebTreeRows(t *testing.T) { | |||
| 107 | + | h := newHarness(t, harnessOpts{}) | |||
| 108 | + | h.webFilesRepo("files") | |||
| 109 | + | h.seed("secret-sauce", domain.VisibilityPrivate, "dir/a.txt") | |||
| 110 | + | ||||
| 111 | + | // The page links its directories to their rows. | |||
| 112 | + | _, _, page := h.get("/files/tree/main") | |||
| 113 | + | assert.Contains(t, page, `href="/files/tree/main/docs" data-expand="/files/tree/main/docs?rows" aria-expanded="false"`) | |||
| 114 | + | assert.Contains(t, page, `<script src="/-/static/js/files.`) | |||
| 115 | + | assert.NotContains(t, page, "main.go</span>", "the palette lists no file") | |||
| 116 | + | ||||
| 117 | + | status, hdr, body := h.get("/files/tree/main/docs?rows") | |||
| 118 | + | require.Equal(t, 200, status) | |||
| 119 | + | assert.Equal(t, "no-cache", hdr.Get("Cache-Control")) | |||
| 120 | + | assert.Contains(t, hdr.Get("Content-Type"), "text/html") | |||
| 121 | + | assert.NotContains(t, body, "<html") | |||
| 122 | + | assert.NotContains(t, body, "<table") | |||
| 123 | + | assert.Equal(t, 2, strings.Count(body, "<tr"), "one row per entry") | |||
| 124 | + | assert.Contains(t, body, `<a href="/files/blob/main/docs/README.md">README.md</a>`) | |||
| 125 | + | assert.Contains(t, body, `<a href="/files/blob/main/docs/guide.md">guide.md</a>`) | |||
| 126 | + | assert.NotContains(t, body, "data-cursor", "the cursor stays on the page") | |||
| 127 | + | assertNoInline(t, body) | |||
| 128 | + | ||||
| 129 | + | // A subdirectory row can be opened in turn. | |||
| 130 | + | _, _, body = h.get("/files/tree/main/src?rows") | |||
| 131 | + | assert.Contains(t, body, `href="/files/tree/main/src/lib" data-expand="/files/tree/main/src/lib?rows" aria-expanded="false"`) | |||
| 132 | + | assert.Contains(t, body, "▸") | |||
| 133 | + | _, _, body = h.get("/files/tree/main/src/lib?rows") | |||
| 134 | + | assert.Contains(t, body, `href="/files/blob/main/src/lib/util.go"`) | |||
| 135 | + | assert.NotContains(t, body, "data-expand") | |||
| 136 | + | ||||
| 137 | + | // Not found, and private as anonymous: the 404 page, nothing of the rows. | |||
| 138 | + | for _, p := range []string{"/files/tree/main/nope?rows", "/secret-sauce/tree/main/dir?rows", "/secret-sauce/tree/main?rows"} { | |||
| 139 | + | status, _, body = h.get(p) | |||
| 140 | + | assert.Equal(t, 404, status, p) | |||
| 141 | + | assert.NotContains(t, body, "a.txt", p) | |||
| 142 | + | } | |||
| 143 | + | } | |||
| 144 | + | ||||
| 103 | // Ref names with a slash are found by their longest prefix, and a commit id | 145 | // Ref names with a slash are found by their longest prefix, and a commit id | ||
| 104 | // works where a ref does. | 146 | // works where a ref does. | ||
| 105 | func TestWebFilesRefs(t *testing.T) { | 147 | func TestWebFilesRefs(t *testing.T) { | ||
M internal/adapters/web/ASSETS.md +1 -0
| @@ -9,6 +9,7 @@ content-hashed names. Nothing is fetched at runtime. | |||
| 9 | 9 | | `static/js/hx-live.min.js` | htmx 4 `hx-live` extension | `mockups/assets/htmx/ext/hx-live.min.js` | `adf9b90949d57baf20dc2eaf1d1fd46c81347ac82c090a5e2912ce6b37726734` | | |
| 10 | 10 | | `static/js/hx-sse.min.js` | htmx 4 `hx-sse` extension | `mockups/assets/htmx/ext/hx-sse.min.js` | `8a834680c4000a9034d79228872372a92e140c810a075cb6d4a76690dfc13085` | | |
| 11 | 11 | | `static/js/ermite.js` | key sequences to `k-*` events | `mockups/d/js/ermite.js` | | | |
| 12 | + | | `static/js/files.js` | the Files view: directories open in place (`window.ermiteTree`) | written here | | | |
| 12 | 13 | | `static/css/56-chroma.css` | syntax classes of the code view, mapped to the `--syn-*` tokens (no colour of its own) | generated by `go run scripts/chroma-css.go` from chroma's token classes | | | |
| 13 | 14 | | `static/css/*.css` | native CSS, served as one stylesheet in name order; relative `url(fonts/…)` and `url(icons/…)` become hashed URLs | written here | | | |
| 14 | 15 | | `static/fonts/atkinson-next.woff2`, `atkinson-next-italic.woff2` | Atkinson Hyperlegible Next, variable weight, latin subset (SIL OFL 1.1, `static/fonts/OFL-next.txt`) | Google Fonts | `18b2a1a39a2fa298b0ba5390aca68462669826c90925656f1c1f6796e0e1bbaf`, `4a5037bfaf6680f40147407407ec09fa42925774bde809a579283d27f9f08106` | | |
| @@ -9,6 +9,7 @@ content-hashed names. Nothing is fetched at runtime. | |||||
| 9 | | `static/js/hx-live.min.js` | htmx 4 `hx-live` extension | `mockups/assets/htmx/ext/hx-live.min.js` | `adf9b90949d57baf20dc2eaf1d1fd46c81347ac82c090a5e2912ce6b37726734` | | 9 | | `static/js/hx-live.min.js` | htmx 4 `hx-live` extension | `mockups/assets/htmx/ext/hx-live.min.js` | `adf9b90949d57baf20dc2eaf1d1fd46c81347ac82c090a5e2912ce6b37726734` | | ||
| 10 | | `static/js/hx-sse.min.js` | htmx 4 `hx-sse` extension | `mockups/assets/htmx/ext/hx-sse.min.js` | `8a834680c4000a9034d79228872372a92e140c810a075cb6d4a76690dfc13085` | | 10 | | `static/js/hx-sse.min.js` | htmx 4 `hx-sse` extension | `mockups/assets/htmx/ext/hx-sse.min.js` | `8a834680c4000a9034d79228872372a92e140c810a075cb6d4a76690dfc13085` | | ||
| 11 | | `static/js/ermite.js` | key sequences to `k-*` events | `mockups/d/js/ermite.js` | | | 11 | | `static/js/ermite.js` | key sequences to `k-*` events | `mockups/d/js/ermite.js` | | | ||
| 12 | + | | `static/js/files.js` | the Files view: directories open in place (`window.ermiteTree`) | written here | | | |||
| 12 | | `static/css/56-chroma.css` | syntax classes of the code view, mapped to the `--syn-*` tokens (no colour of its own) | generated by `go run scripts/chroma-css.go` from chroma's token classes | | | 13 | | `static/css/56-chroma.css` | syntax classes of the code view, mapped to the `--syn-*` tokens (no colour of its own) | generated by `go run scripts/chroma-css.go` from chroma's token classes | | | ||
| 13 | | `static/css/*.css` | native CSS, served as one stylesheet in name order; relative `url(fonts/…)` and `url(icons/…)` become hashed URLs | written here | | | 14 | | `static/css/*.css` | native CSS, served as one stylesheet in name order; relative `url(fonts/…)` and `url(icons/…)` become hashed URLs | written here | | | ||
| 14 | | `static/fonts/atkinson-next.woff2`, `atkinson-next-italic.woff2` | Atkinson Hyperlegible Next, variable weight, latin subset (SIL OFL 1.1, `static/fonts/OFL-next.txt`) | Google Fonts | `18b2a1a39a2fa298b0ba5390aca68462669826c90925656f1c1f6796e0e1bbaf`, `4a5037bfaf6680f40147407407ec09fa42925774bde809a579283d27f9f08106` | | 15 | | `static/fonts/atkinson-next.woff2`, `atkinson-next-italic.woff2` | Atkinson Hyperlegible Next, variable weight, latin subset (SIL OFL 1.1, `static/fonts/OFL-next.txt`) | Google Fonts | `18b2a1a39a2fa298b0ba5390aca68462669826c90925656f1c1f6796e0e1bbaf`, `4a5037bfaf6680f40147407407ec09fa42925774bde809a579283d27f9f08106` | | ||
M internal/adapters/web/assets.go +2 -1
| @@ -23,7 +23,7 @@ const StaticPrefix = "/-/static/" | |||
| 23 | 23 | // Assets are the URLs of the assets a page loads. Their names carry a hash of | |
| 24 | 24 | // the content, so they can be cached for ever. | |
| 25 | 25 | type Assets struct { | |
| 26 | - | CSS, HTMX, Live, SSE, App, Icon string | |
| 26 | + | CSS, HTMX, Live, SSE, App, Files, Icon string | |
| 27 | 27 | // Font is the UI font, preloaded by every page. | |
| 28 | 28 | Font string | |
| 29 | 29 | // Rules is the speculation rules file named by the Speculation-Rules header. | |
| @@ -52,6 +52,7 @@ var scripts = []struct { | |||
| 52 | 52 | {"hx-live.min.js", func(a *Assets, u string) { a.Live = u }}, | |
| 53 | 53 | {"hx-sse.min.js", func(a *Assets, u string) { a.SSE = u }}, | |
| 54 | 54 | {"ermite.js", func(a *Assets, u string) { a.App = u }}, | |
| 55 | + | {"files.js", func(a *Assets, u string) { a.Files = u }}, | |
| 55 | 56 | } | |
| 56 | 57 | ||
| 57 | 58 | // sheetAssets are the files the stylesheet references as url(<dir>/<file>): | |
| @@ -23,7 +23,7 @@ const StaticPrefix = "/-/static/" | |||||
| 23 | // Assets are the URLs of the assets a page loads. Their names carry a hash of | 23 | // Assets are the URLs of the assets a page loads. Their names carry a hash of | ||
| 24 | // the content, so they can be cached for ever. | 24 | // the content, so they can be cached for ever. | ||
| 25 | type Assets struct { | 25 | type Assets struct { | ||
| 26 | - | CSS, HTMX, Live, SSE, App, Icon string | 26 | + | CSS, HTMX, Live, SSE, App, Files, Icon string |
| 27 | // Font is the UI font, preloaded by every page. | 27 | // Font is the UI font, preloaded by every page. | ||
| 28 | Font string | 28 | Font string | ||
| 29 | // Rules is the speculation rules file named by the Speculation-Rules header. | 29 | // Rules is the speculation rules file named by the Speculation-Rules header. | ||
| @@ -52,6 +52,7 @@ var scripts = []struct { | |||||
| 52 | {"hx-live.min.js", func(a *Assets, u string) { a.Live = u }}, | 52 | {"hx-live.min.js", func(a *Assets, u string) { a.Live = u }}, | ||
| 53 | {"hx-sse.min.js", func(a *Assets, u string) { a.SSE = u }}, | 53 | {"hx-sse.min.js", func(a *Assets, u string) { a.SSE = u }}, | ||
| 54 | {"ermite.js", func(a *Assets, u string) { a.App = u }}, | 54 | {"ermite.js", func(a *Assets, u string) { a.App = u }}, | ||
| 55 | + | {"files.js", func(a *Assets, u string) { a.Files = u }}, | |||
| 55 | } | 56 | } | ||
| 56 | 57 | ||||
| 57 | // sheetAssets are the files the stylesheet references as url(<dir>/<file>): | 58 | // sheetAssets are the files the stylesheet references as url(<dir>/<file>): | ||
M internal/adapters/web/overlays.templ +1 -1
| @@ -84,7 +84,7 @@ templ refItem(r RefItem) { | |||
| 84 | 84 | } | |
| 85 | 85 | ||
| 86 | 86 | // OverlayCmd is the ":" command line: one filterable list mixing sections, | |
| 87 | - | // refs, files of this directory and repos. | |
| 87 | + | // refs and repos. | |
| 88 | 88 | templ OverlayCmd(items []CmdItem) { | |
| 89 | 89 | <dialog id="panel-cmd" class="panel modal" aria-label="Go to" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()"> | |
| 90 | 90 | <div class="panel-head"> | |
| @@ -84,7 +84,7 @@ templ refItem(r RefItem) { | |||||
| 84 | } | 84 | } | ||
| 85 | 85 | ||||
| 86 | // OverlayCmd is the ":" command line: one filterable list mixing sections, | 86 | // OverlayCmd is the ":" command line: one filterable list mixing sections, | ||
| 87 | - | // refs, files of this directory and repos. | 87 | + | // refs and repos. |
| 88 | templ OverlayCmd(items []CmdItem) { | 88 | templ OverlayCmd(items []CmdItem) { | ||
| 89 | <dialog id="panel-cmd" class="panel modal" aria-label="Go to" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()"> | 89 | <dialog id="panel-cmd" class="panel modal" aria-label="Go to" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()"> | ||
| 90 | <div class="panel-head"> | 90 | <div class="panel-head"> | ||
M internal/adapters/web/overlays_templ.go +1 -1 generated file: collapsed
M internal/adapters/web/shell.templ +1 -0
| @@ -20,6 +20,7 @@ templ Shell(l Layout, rail templ.Component) { | |||
| 20 | 20 | <script src={ l.Assets.Live } defer></script> | |
| 21 | 21 | <script src={ l.Assets.SSE } defer></script> | |
| 22 | 22 | <script src={ l.Assets.App } defer></script> | |
| 23 | + | <script src={ l.Assets.Files } defer></script> | |
| 23 | 24 | </head> | |
| 24 | 25 | <body data-ref={ l.RefPath } data-sha={ l.SHA } data-sel="" data-nav=""> | |
| 25 | 26 | <a class="skip" href="#main">skip to content</a> | |
| @@ -20,6 +20,7 @@ templ Shell(l Layout, rail templ.Component) { | |||||
| 20 | <script src={ l.Assets.Live } defer></script> | 20 | <script src={ l.Assets.Live } defer></script> | ||
| 21 | <script src={ l.Assets.SSE } defer></script> | 21 | <script src={ l.Assets.SSE } defer></script> | ||
| 22 | <script src={ l.Assets.App } defer></script> | 22 | <script src={ l.Assets.App } defer></script> | ||
| 23 | + | <script src={ l.Assets.Files } defer></script> | |||
| 23 | </head> | 24 | </head> | ||
| 24 | <body data-ref={ l.RefPath } data-sha={ l.SHA } data-sel="" data-nav=""> | 25 | <body data-ref={ l.RefPath } data-sha={ l.SHA } data-sel="" data-nav=""> | ||
| 25 | <a class="skip" href="#main">skip to content</a> | 26 | <a class="skip" href="#main">skip to content</a> | ||
M internal/adapters/web/shell_templ.go +138 -125
| @@ -138,33 +138,46 @@ func Shell(l Layout, rail templ.Component) templ.Component { | |||
| 138 | 138 | if templ_7745c5c3_Err != nil { | |
| 139 | 139 | return templ_7745c5c3_Err | |
| 140 | 140 | } | |
| 141 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" defer></script></head><body data-ref=\"") | |
| 141 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" defer></script><script src=\"") | |
| 142 | 142 | if templ_7745c5c3_Err != nil { | |
| 143 | 143 | return templ_7745c5c3_Err | |
| 144 | 144 | } | |
| 145 | 145 | var templ_7745c5c3_Var10 string | |
| 146 | - | templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.ResolveAttributeValue(l.RefPath) | |
| 146 | + | templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.ResolveAttributeValue(l.Assets.Files) | |
| 147 | 147 | if templ_7745c5c3_Err != nil { | |
| 148 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 24, Col: 28} | |
| 148 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 23, Col: 31} | |
| 149 | 149 | } | |
| 150 | 150 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var10) | |
| 151 | 151 | if templ_7745c5c3_Err != nil { | |
| 152 | 152 | return templ_7745c5c3_Err | |
| 153 | 153 | } | |
| 154 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\" data-sha=\"") | |
| 154 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\" defer></script></head><body data-ref=\"") | |
| 155 | 155 | if templ_7745c5c3_Err != nil { | |
| 156 | 156 | return templ_7745c5c3_Err | |
| 157 | 157 | } | |
| 158 | 158 | var templ_7745c5c3_Var11 string | |
| 159 | - | templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.ResolveAttributeValue(l.SHA) | |
| 159 | + | templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.ResolveAttributeValue(l.RefPath) | |
| 160 | 160 | if templ_7745c5c3_Err != nil { | |
| 161 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 24, Col: 47} | |
| 161 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 25, Col: 28} | |
| 162 | 162 | } | |
| 163 | 163 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var11) | |
| 164 | 164 | if templ_7745c5c3_Err != nil { | |
| 165 | 165 | return templ_7745c5c3_Err | |
| 166 | 166 | } | |
| 167 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\" data-sel=\"\" data-nav=\"\"><a class=\"skip\" href=\"#main\">skip to content</a>") | |
| 167 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\" data-sha=\"") | |
| 168 | + | if templ_7745c5c3_Err != nil { | |
| 169 | + | return templ_7745c5c3_Err | |
| 170 | + | } | |
| 171 | + | var templ_7745c5c3_Var12 string | |
| 172 | + | templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.ResolveAttributeValue(l.SHA) | |
| 173 | + | if templ_7745c5c3_Err != nil { | |
| 174 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 25, Col: 47} | |
| 175 | + | } | |
| 176 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var12) | |
| 177 | + | if templ_7745c5c3_Err != nil { | |
| 178 | + | return templ_7745c5c3_Err | |
| 179 | + | } | |
| 180 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\" data-sel=\"\" data-nav=\"\"><a class=\"skip\" href=\"#main\">skip to content</a>") | |
| 168 | 181 | if templ_7745c5c3_Err != nil { | |
| 169 | 182 | return templ_7745c5c3_Err | |
| 170 | 183 | } | |
| @@ -172,48 +185,48 @@ func Shell(l Layout, rail templ.Component) templ.Component { | |||
| 172 | 185 | if templ_7745c5c3_Err != nil { | |
| 173 | 186 | return templ_7745c5c3_Err | |
| 174 | 187 | } | |
| 175 | - | var templ_7745c5c3_Var12 = []any{"work", templ.KV("has-rail", l.HasRail && rail != nil)} | |
| 176 | - | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...) | |
| 188 | + | var templ_7745c5c3_Var13 = []any{"work", templ.KV("has-rail", l.HasRail && rail != nil)} | |
| 189 | + | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var13...) | |
| 177 | 190 | if templ_7745c5c3_Err != nil { | |
| 178 | 191 | return templ_7745c5c3_Err | |
| 179 | 192 | } | |
| 180 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<div class=\"") | |
| 193 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<div class=\"") | |
| 181 | 194 | if templ_7745c5c3_Err != nil { | |
| 182 | 195 | return templ_7745c5c3_Err | |
| 183 | 196 | } | |
| 184 | - | var templ_7745c5c3_Var13 string | |
| 185 | - | templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var12).String()) | |
| 197 | + | var templ_7745c5c3_Var14 string | |
| 198 | + | templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var13).String()) | |
| 186 | 199 | if templ_7745c5c3_Err != nil { | |
| 187 | 200 | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 1, Col: 0} | |
| 188 | 201 | } | |
| 189 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var13) | |
| 202 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var14) | |
| 190 | 203 | if templ_7745c5c3_Err != nil { | |
| 191 | 204 | return templ_7745c5c3_Err | |
| 192 | 205 | } | |
| 193 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\">") | |
| 206 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\">") | |
| 194 | 207 | if templ_7745c5c3_Err != nil { | |
| 195 | 208 | return templ_7745c5c3_Err | |
| 196 | 209 | } | |
| 197 | 210 | if l.Lede != "" { | |
| 198 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<section class=\"work-lede\" aria-label=\"Description\"><p class=\"lede\">") | |
| 211 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<section class=\"work-lede\" aria-label=\"Description\"><p class=\"lede\">") | |
| 199 | 212 | if templ_7745c5c3_Err != nil { | |
| 200 | 213 | return templ_7745c5c3_Err | |
| 201 | 214 | } | |
| 202 | - | var templ_7745c5c3_Var14 string | |
| 203 | - | templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(l.Lede) | |
| 215 | + | var templ_7745c5c3_Var15 string | |
| 216 | + | templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(l.Lede) | |
| 204 | 217 | if templ_7745c5c3_Err != nil { | |
| 205 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 29, Col: 81} | |
| 218 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 30, Col: 81} | |
| 206 | 219 | } | |
| 207 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) | |
| 220 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) | |
| 208 | 221 | if templ_7745c5c3_Err != nil { | |
| 209 | 222 | return templ_7745c5c3_Err | |
| 210 | 223 | } | |
| 211 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</p></section>") | |
| 224 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</p></section>") | |
| 212 | 225 | if templ_7745c5c3_Err != nil { | |
| 213 | 226 | return templ_7745c5c3_Err | |
| 214 | 227 | } | |
| 215 | 228 | } | |
| 216 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<main id=\"main\" tabindex=\"-1\">") | |
| 229 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<main id=\"main\" tabindex=\"-1\">") | |
| 217 | 230 | if templ_7745c5c3_Err != nil { | |
| 218 | 231 | return templ_7745c5c3_Err | |
| 219 | 232 | } | |
| @@ -221,12 +234,12 @@ func Shell(l Layout, rail templ.Component) templ.Component { | |||
| 221 | 234 | if templ_7745c5c3_Err != nil { | |
| 222 | 235 | return templ_7745c5c3_Err | |
| 223 | 236 | } | |
| 224 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</main>") | |
| 237 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</main>") | |
| 225 | 238 | if templ_7745c5c3_Err != nil { | |
| 226 | 239 | return templ_7745c5c3_Err | |
| 227 | 240 | } | |
| 228 | 241 | if l.HasRail && rail != nil { | |
| 229 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "<aside class=\"rail\" aria-label=\"Context\">") | |
| 242 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<aside class=\"rail\" aria-label=\"Context\">") | |
| 230 | 243 | if templ_7745c5c3_Err != nil { | |
| 231 | 244 | return templ_7745c5c3_Err | |
| 232 | 245 | } | |
| @@ -234,12 +247,12 @@ func Shell(l Layout, rail templ.Component) templ.Component { | |||
| 234 | 247 | if templ_7745c5c3_Err != nil { | |
| 235 | 248 | return templ_7745c5c3_Err | |
| 236 | 249 | } | |
| 237 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "</aside>") | |
| 250 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</aside>") | |
| 238 | 251 | if templ_7745c5c3_Err != nil { | |
| 239 | 252 | return templ_7745c5c3_Err | |
| 240 | 253 | } | |
| 241 | 254 | } | |
| 242 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</div>") | |
| 255 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</div>") | |
| 243 | 256 | if templ_7745c5c3_Err != nil { | |
| 244 | 257 | return templ_7745c5c3_Err | |
| 245 | 258 | } | |
| @@ -267,7 +280,7 @@ func Shell(l Layout, rail templ.Component) templ.Component { | |||
| 267 | 280 | if templ_7745c5c3_Err != nil { | |
| 268 | 281 | return templ_7745c5c3_Err | |
| 269 | 282 | } | |
| 270 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</body></html>") | |
| 283 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "</body></html>") | |
| 271 | 284 | if templ_7745c5c3_Err != nil { | |
| 272 | 285 | return templ_7745c5c3_Err | |
| 273 | 286 | } | |
| @@ -293,260 +306,260 @@ func Header(l Layout) templ.Component { | |||
| 293 | 306 | }() | |
| 294 | 307 | } | |
| 295 | 308 | ctx = templ.InitializeContext(ctx) | |
| 296 | - | templ_7745c5c3_Var15 := templ.GetChildren(ctx) | |
| 297 | - | if templ_7745c5c3_Var15 == nil { | |
| 298 | - | templ_7745c5c3_Var15 = templ.NopComponent | |
| 309 | + | templ_7745c5c3_Var16 := templ.GetChildren(ctx) | |
| 310 | + | if templ_7745c5c3_Var16 == nil { | |
| 311 | + | templ_7745c5c3_Var16 = templ.NopComponent | |
| 299 | 312 | } | |
| 300 | 313 | ctx = templ.ClearChildren(ctx) | |
| 301 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<header class=\"hdr\"><div class=\"hdr-top\"><a class=\"brand\" href=\"/\" data-g=\"h\" title=\"home (g h)\"><span class=\"brand-mark\" aria-hidden=\"true\"></span> <span class=\"brand-name\">") | |
| 314 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<header class=\"hdr\"><div class=\"hdr-top\"><a class=\"brand\" href=\"/\" data-g=\"h\" title=\"home (g h)\"><span class=\"brand-mark\" aria-hidden=\"true\"></span> <span class=\"brand-name\">") | |
| 302 | 315 | if templ_7745c5c3_Err != nil { | |
| 303 | 316 | return templ_7745c5c3_Err | |
| 304 | 317 | } | |
| 305 | - | var templ_7745c5c3_Var16 string | |
| 306 | - | templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(l.Instance) | |
| 318 | + | var templ_7745c5c3_Var17 string | |
| 319 | + | templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(l.Instance) | |
| 307 | 320 | if templ_7745c5c3_Err != nil { | |
| 308 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 57, Col: 41} | |
| 321 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 58, Col: 41} | |
| 309 | 322 | } | |
| 310 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) | |
| 323 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) | |
| 311 | 324 | if templ_7745c5c3_Err != nil { | |
| 312 | 325 | return templ_7745c5c3_Err | |
| 313 | 326 | } | |
| 314 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "</span></a> ") | |
| 327 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "</span></a> ") | |
| 315 | 328 | if templ_7745c5c3_Err != nil { | |
| 316 | 329 | return templ_7745c5c3_Err | |
| 317 | 330 | } | |
| 318 | 331 | if len(l.Crumbs) > 0 { | |
| 319 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "<nav class=\"crumbs\" aria-label=\"Path\"><ol>") | |
| 332 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<nav class=\"crumbs\" aria-label=\"Path\"><ol>") | |
| 320 | 333 | if templ_7745c5c3_Err != nil { | |
| 321 | 334 | return templ_7745c5c3_Err | |
| 322 | 335 | } | |
| 323 | 336 | for _, c := range l.Crumbs { | |
| 324 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<li>") | |
| 337 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<li>") | |
| 325 | 338 | if templ_7745c5c3_Err != nil { | |
| 326 | 339 | return templ_7745c5c3_Err | |
| 327 | 340 | } | |
| 328 | 341 | if c.Href != "" { | |
| 329 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<a href=\"") | |
| 342 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<a href=\"") | |
| 330 | 343 | if templ_7745c5c3_Err != nil { | |
| 331 | 344 | return templ_7745c5c3_Err | |
| 332 | 345 | } | |
| 333 | - | var templ_7745c5c3_Var17 templ.SafeURL | |
| 334 | - | templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Href)) | |
| 346 | + | var templ_7745c5c3_Var18 templ.SafeURL | |
| 347 | + | templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Href)) | |
| 335 | 348 | if templ_7745c5c3_Err != nil { | |
| 336 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 66, Col: 38} | |
| 349 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 67, Col: 38} | |
| 337 | 350 | } | |
| 338 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) | |
| 351 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) | |
| 339 | 352 | if templ_7745c5c3_Err != nil { | |
| 340 | 353 | return templ_7745c5c3_Err | |
| 341 | 354 | } | |
| 342 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "\"") | |
| 355 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "\"") | |
| 343 | 356 | if templ_7745c5c3_Err != nil { | |
| 344 | 357 | return templ_7745c5c3_Err | |
| 345 | 358 | } | |
| 346 | 359 | if c.Current { | |
| 347 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, " aria-current=\"page\"") | |
| 360 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, " aria-current=\"page\"") | |
| 348 | 361 | if templ_7745c5c3_Err != nil { | |
| 349 | 362 | return templ_7745c5c3_Err | |
| 350 | 363 | } | |
| 351 | 364 | } | |
| 352 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, ">") | |
| 365 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, ">") | |
| 353 | 366 | if templ_7745c5c3_Err != nil { | |
| 354 | 367 | return templ_7745c5c3_Err | |
| 355 | 368 | } | |
| 356 | - | var templ_7745c5c3_Var18 string | |
| 357 | - | templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(c.Label) | |
| 369 | + | var templ_7745c5c3_Var19 string | |
| 370 | + | templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(c.Label) | |
| 358 | 371 | if templ_7745c5c3_Err != nil { | |
| 359 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 70, Col: 19} | |
| 372 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 71, Col: 19} | |
| 360 | 373 | } | |
| 361 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) | |
| 374 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) | |
| 362 | 375 | if templ_7745c5c3_Err != nil { | |
| 363 | 376 | return templ_7745c5c3_Err | |
| 364 | 377 | } | |
| 365 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "</a>") | |
| 378 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "</a>") | |
| 366 | 379 | if templ_7745c5c3_Err != nil { | |
| 367 | 380 | return templ_7745c5c3_Err | |
| 368 | 381 | } | |
| 369 | 382 | } else { | |
| 370 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "<span") | |
| 383 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "<span") | |
| 371 | 384 | if templ_7745c5c3_Err != nil { | |
| 372 | 385 | return templ_7745c5c3_Err | |
| 373 | 386 | } | |
| 374 | 387 | if c.Current { | |
| 375 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, " aria-current=\"page\"") | |
| 388 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, " aria-current=\"page\"") | |
| 376 | 389 | if templ_7745c5c3_Err != nil { | |
| 377 | 390 | return templ_7745c5c3_Err | |
| 378 | 391 | } | |
| 379 | 392 | } | |
| 380 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, ">") | |
| 393 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, ">") | |
| 381 | 394 | if templ_7745c5c3_Err != nil { | |
| 382 | 395 | return templ_7745c5c3_Err | |
| 383 | 396 | } | |
| 384 | - | var templ_7745c5c3_Var19 string | |
| 385 | - | templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(c.Label) | |
| 397 | + | var templ_7745c5c3_Var20 string | |
| 398 | + | templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(c.Label) | |
| 386 | 399 | if templ_7745c5c3_Err != nil { | |
| 387 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 76, Col: 19} | |
| 400 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 77, Col: 19} | |
| 388 | 401 | } | |
| 389 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) | |
| 402 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) | |
| 390 | 403 | if templ_7745c5c3_Err != nil { | |
| 391 | 404 | return templ_7745c5c3_Err | |
| 392 | 405 | } | |
| 393 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "</span>") | |
| 406 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "</span>") | |
| 394 | 407 | if templ_7745c5c3_Err != nil { | |
| 395 | 408 | return templ_7745c5c3_Err | |
| 396 | 409 | } | |
| 397 | 410 | } | |
| 398 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "</li>") | |
| 411 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "</li>") | |
| 399 | 412 | if templ_7745c5c3_Err != nil { | |
| 400 | 413 | return templ_7745c5c3_Err | |
| 401 | 414 | } | |
| 402 | 415 | } | |
| 403 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "</ol></nav>") | |
| 416 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "</ol></nav>") | |
| 404 | 417 | if templ_7745c5c3_Err != nil { | |
| 405 | 418 | return templ_7745c5c3_Err | |
| 406 | 419 | } | |
| 407 | 420 | } | |
| 408 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "<div class=\"hdr-acts\">") | |
| 421 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "<div class=\"hdr-acts\">") | |
| 409 | 422 | if templ_7745c5c3_Err != nil { | |
| 410 | 423 | return templ_7745c5c3_Err | |
| 411 | 424 | } | |
| 412 | 425 | if l.Ref != "" { | |
| 413 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "<button type=\"button\" class=\"btn ref\" aria-haspopup=\"dialog\" aria-controls=\"panel-refs\" aria-keyshortcuts=\"b\" title=\"switch branch or tag (b)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-refs'))\"><span class=\"ico i-branch\" aria-hidden=\"true\"></span> <span class=\"ref-name\">") | |
| 426 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "<button type=\"button\" class=\"btn ref\" aria-haspopup=\"dialog\" aria-controls=\"panel-refs\" aria-keyshortcuts=\"b\" title=\"switch branch or tag (b)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-refs'))\"><span class=\"ico i-branch\" aria-hidden=\"true\"></span> <span class=\"ref-name\">") | |
| 414 | 427 | if templ_7745c5c3_Err != nil { | |
| 415 | 428 | return templ_7745c5c3_Err | |
| 416 | 429 | } | |
| 417 | - | var templ_7745c5c3_Var20 string | |
| 418 | - | templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(l.Ref) | |
| 430 | + | var templ_7745c5c3_Var21 string | |
| 431 | + | templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(l.Ref) | |
| 419 | 432 | if templ_7745c5c3_Err != nil { | |
| 420 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 95, Col: 36} | |
| 433 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 96, Col: 36} | |
| 421 | 434 | } | |
| 422 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) | |
| 435 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) | |
| 423 | 436 | if templ_7745c5c3_Err != nil { | |
| 424 | 437 | return templ_7745c5c3_Err | |
| 425 | 438 | } | |
| 426 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "</span> <span class=\"sha\">") | |
| 439 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "</span> <span class=\"sha\">") | |
| 427 | 440 | if templ_7745c5c3_Err != nil { | |
| 428 | 441 | return templ_7745c5c3_Err | |
| 429 | 442 | } | |
| 430 | - | var templ_7745c5c3_Var21 string | |
| 431 | - | templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(l.Short) | |
| 443 | + | var templ_7745c5c3_Var22 string | |
| 444 | + | templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(l.Short) | |
| 432 | 445 | if templ_7745c5c3_Err != nil { | |
| 433 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 96, Col: 33} | |
| 446 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 97, Col: 33} | |
| 434 | 447 | } | |
| 435 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) | |
| 448 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) | |
| 436 | 449 | if templ_7745c5c3_Err != nil { | |
| 437 | 450 | return templ_7745c5c3_Err | |
| 438 | 451 | } | |
| 439 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "</span></button> ") | |
| 452 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</span></button> ") | |
| 440 | 453 | if templ_7745c5c3_Err != nil { | |
| 441 | 454 | return templ_7745c5c3_Err | |
| 442 | 455 | } | |
| 443 | 456 | } | |
| 444 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "<button type=\"button\" class=\"btn search\" aria-haspopup=\"dialog\" aria-controls=\"panel-cmd\" aria-keyshortcuts=\"Control+K :\" title=\"go to a section, ref, file or repo (ctrl k or :)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-cmd'))\"><span class=\"ico i-search\" aria-hidden=\"true\"></span> <span class=\"search-label\">Go to…</span> <kbd aria-hidden=\"true\">ctrl k</kbd></button> <button type=\"button\" class=\"btn icon\" aria-haspopup=\"dialog\" aria-controls=\"panel-help\" aria-keyshortcuts=\"?\" aria-label=\"Keyboard shortcuts\" title=\"keyboard shortcuts (?)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-help'))\">?</button> ") | |
| 457 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<button type=\"button\" class=\"btn search\" aria-haspopup=\"dialog\" aria-controls=\"panel-cmd\" aria-keyshortcuts=\"Control+K :\" title=\"go to a section, ref, file or repo (ctrl k or :)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-cmd'))\"><span class=\"ico i-search\" aria-hidden=\"true\"></span> <span class=\"search-label\">Go to…</span> <kbd aria-hidden=\"true\">ctrl k</kbd></button> <button type=\"button\" class=\"btn icon\" aria-haspopup=\"dialog\" aria-controls=\"panel-help\" aria-keyshortcuts=\"?\" aria-label=\"Keyboard shortcuts\" title=\"keyboard shortcuts (?)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-help'))\">?</button> ") | |
| 445 | 458 | if templ_7745c5c3_Err != nil { | |
| 446 | 459 | return templ_7745c5c3_Err | |
| 447 | 460 | } | |
| 448 | 461 | if SignedIn(ctx) { | |
| 449 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<form class=\"owner\" method=\"post\" action=\"/-/logout\"><span class=\"owner-badge\" title=\"signed in as the owner\">owner</span> <button type=\"submit\" class=\"btn\" title=\"sign out of this browser\">Sign out</button></form>") | |
| 462 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "<form class=\"owner\" method=\"post\" action=\"/-/logout\"><span class=\"owner-badge\" title=\"signed in as the owner\">owner</span> <button type=\"submit\" class=\"btn\" title=\"sign out of this browser\">Sign out</button></form>") | |
| 450 | 463 | if templ_7745c5c3_Err != nil { | |
| 451 | 464 | return templ_7745c5c3_Err | |
| 452 | 465 | } | |
| 453 | 466 | } | |
| 454 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</div></div>") | |
| 467 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "</div></div>") | |
| 455 | 468 | if templ_7745c5c3_Err != nil { | |
| 456 | 469 | return templ_7745c5c3_Err | |
| 457 | 470 | } | |
| 458 | 471 | if len(l.Sections) > 0 { | |
| 459 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "<nav class=\"tabs\" aria-label=\"Sections\"><ul>") | |
| 472 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<nav class=\"tabs\" aria-label=\"Sections\"><ul>") | |
| 460 | 473 | if templ_7745c5c3_Err != nil { | |
| 461 | 474 | return templ_7745c5c3_Err | |
| 462 | 475 | } | |
| 463 | 476 | for _, s := range l.Sections { | |
| 464 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<li><a href=\"") | |
| 477 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "<li><a href=\"") | |
| 465 | 478 | if templ_7745c5c3_Err != nil { | |
| 466 | 479 | return templ_7745c5c3_Err | |
| 467 | 480 | } | |
| 468 | - | var templ_7745c5c3_Var22 templ.SafeURL | |
| 469 | - | templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(s.Href)) | |
| 481 | + | var templ_7745c5c3_Var23 templ.SafeURL | |
| 482 | + | templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(s.Href)) | |
| 470 | 483 | if templ_7745c5c3_Err != nil { | |
| 471 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 127, Col: 36} | |
| 484 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 128, Col: 36} | |
| 472 | 485 | } | |
| 473 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) | |
| 486 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23)) | |
| 474 | 487 | if templ_7745c5c3_Err != nil { | |
| 475 | 488 | return templ_7745c5c3_Err | |
| 476 | 489 | } | |
| 477 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "\" data-key=\"") | |
| 490 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "\" data-key=\"") | |
| 478 | 491 | if templ_7745c5c3_Err != nil { | |
| 479 | 492 | return templ_7745c5c3_Err | |
| 480 | 493 | } | |
| 481 | - | var templ_7745c5c3_Var23 string | |
| 482 | - | templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.ResolveAttributeValue(s.Key) | |
| 494 | + | var templ_7745c5c3_Var24 string | |
| 495 | + | templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.ResolveAttributeValue(s.Key) | |
| 483 | 496 | if templ_7745c5c3_Err != nil { | |
| 484 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 128, Col: 24} | |
| 497 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 129, Col: 24} | |
| 485 | 498 | } | |
| 486 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var23) | |
| 499 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var24) | |
| 487 | 500 | if templ_7745c5c3_Err != nil { | |
| 488 | 501 | return templ_7745c5c3_Err | |
| 489 | 502 | } | |
| 490 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "\" aria-keyshortcuts=\"") | |
| 503 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "\" aria-keyshortcuts=\"") | |
| 491 | 504 | if templ_7745c5c3_Err != nil { | |
| 492 | 505 | return templ_7745c5c3_Err | |
| 493 | 506 | } | |
| 494 | - | var templ_7745c5c3_Var24 string | |
| 495 | - | templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.ResolveAttributeValue(s.Key) | |
| 507 | + | var templ_7745c5c3_Var25 string | |
| 508 | + | templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.ResolveAttributeValue(s.Key) | |
| 496 | 509 | if templ_7745c5c3_Err != nil { | |
| 497 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 129, Col: 33} | |
| 510 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 130, Col: 33} | |
| 498 | 511 | } | |
| 499 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var24) | |
| 512 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var25) | |
| 500 | 513 | if templ_7745c5c3_Err != nil { | |
| 501 | 514 | return templ_7745c5c3_Err | |
| 502 | 515 | } | |
| 503 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "\"") | |
| 516 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "\"") | |
| 504 | 517 | if templ_7745c5c3_Err != nil { | |
| 505 | 518 | return templ_7745c5c3_Err | |
| 506 | 519 | } | |
| 507 | 520 | if s.Current { | |
| 508 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, " aria-current=\"page\"") | |
| 521 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, " aria-current=\"page\"") | |
| 509 | 522 | if templ_7745c5c3_Err != nil { | |
| 510 | 523 | return templ_7745c5c3_Err | |
| 511 | 524 | } | |
| 512 | 525 | } | |
| 513 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, ">") | |
| 526 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, ">") | |
| 514 | 527 | if templ_7745c5c3_Err != nil { | |
| 515 | 528 | return templ_7745c5c3_Err | |
| 516 | 529 | } | |
| 517 | - | var templ_7745c5c3_Var25 string | |
| 518 | - | templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(s.Label) | |
| 530 | + | var templ_7745c5c3_Var26 string | |
| 531 | + | templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(s.Label) | |
| 519 | 532 | if templ_7745c5c3_Err != nil { | |
| 520 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 133, Col: 17} | |
| 533 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 134, Col: 17} | |
| 521 | 534 | } | |
| 522 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) | |
| 535 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) | |
| 523 | 536 | if templ_7745c5c3_Err != nil { | |
| 524 | 537 | return templ_7745c5c3_Err | |
| 525 | 538 | } | |
| 526 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<kbd aria-hidden=\"true\">") | |
| 539 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "<kbd aria-hidden=\"true\">") | |
| 527 | 540 | if templ_7745c5c3_Err != nil { | |
| 528 | 541 | return templ_7745c5c3_Err | |
| 529 | 542 | } | |
| 530 | - | var templ_7745c5c3_Var26 string | |
| 531 | - | templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(s.Key) | |
| 543 | + | var templ_7745c5c3_Var27 string | |
| 544 | + | templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(s.Key) | |
| 532 | 545 | if templ_7745c5c3_Err != nil { | |
| 533 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 133, Col: 50} | |
| 546 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 134, Col: 50} | |
| 534 | 547 | } | |
| 535 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) | |
| 548 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) | |
| 536 | 549 | if templ_7745c5c3_Err != nil { | |
| 537 | 550 | return templ_7745c5c3_Err | |
| 538 | 551 | } | |
| 539 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "</kbd></a></li>") | |
| 552 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "</kbd></a></li>") | |
| 540 | 553 | if templ_7745c5c3_Err != nil { | |
| 541 | 554 | return templ_7745c5c3_Err | |
| 542 | 555 | } | |
| 543 | 556 | } | |
| 544 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "</ul></nav>") | |
| 557 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "</ul></nav>") | |
| 545 | 558 | if templ_7745c5c3_Err != nil { | |
| 546 | 559 | return templ_7745c5c3_Err | |
| 547 | 560 | } | |
| 548 | 561 | } | |
| 549 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "</header>") | |
| 562 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "</header>") | |
| 550 | 563 | if templ_7745c5c3_Err != nil { | |
| 551 | 564 | return templ_7745c5c3_Err | |
| 552 | 565 | } | |
| @@ -572,38 +585,38 @@ func Footer(l Layout) templ.Component { | |||
| 572 | 585 | }() | |
| 573 | 586 | } | |
| 574 | 587 | ctx = templ.InitializeContext(ctx) | |
| 575 | - | templ_7745c5c3_Var27 := templ.GetChildren(ctx) | |
| 576 | - | if templ_7745c5c3_Var27 == nil { | |
| 577 | - | templ_7745c5c3_Var27 = templ.NopComponent | |
| 588 | + | templ_7745c5c3_Var28 := templ.GetChildren(ctx) | |
| 589 | + | if templ_7745c5c3_Var28 == nil { | |
| 590 | + | templ_7745c5c3_Var28 = templ.NopComponent | |
| 578 | 591 | } | |
| 579 | 592 | ctx = templ.ClearChildren(ctx) | |
| 580 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "<footer class=\"foot\"><span>ermite ") | |
| 593 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<footer class=\"foot\"><span>ermite ") | |
| 581 | 594 | if templ_7745c5c3_Err != nil { | |
| 582 | 595 | return templ_7745c5c3_Err | |
| 583 | 596 | } | |
| 584 | - | var templ_7745c5c3_Var28 string | |
| 585 | - | templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(l.Version) | |
| 597 | + | var templ_7745c5c3_Var29 string | |
| 598 | + | templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(l.Version) | |
| 586 | 599 | if templ_7745c5c3_Err != nil { | |
| 587 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 146, Col: 26} | |
| 600 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 147, Col: 26} | |
| 588 | 601 | } | |
| 589 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) | |
| 602 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) | |
| 590 | 603 | if templ_7745c5c3_Err != nil { | |
| 591 | 604 | return templ_7745c5c3_Err | |
| 592 | 605 | } | |
| 593 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "</span> <a href=\"") | |
| 606 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "</span> <a href=\"") | |
| 594 | 607 | if templ_7745c5c3_Err != nil { | |
| 595 | 608 | return templ_7745c5c3_Err | |
| 596 | 609 | } | |
| 597 | - | var templ_7745c5c3_Var29 templ.SafeURL | |
| 598 | - | templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(l.SourceURL)) | |
| 610 | + | var templ_7745c5c3_Var30 templ.SafeURL | |
| 611 | + | templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(l.SourceURL)) | |
| 599 | 612 | if templ_7745c5c3_Err != nil { | |
| 600 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 147, Col: 38} | |
| 613 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 148, Col: 38} | |
| 601 | 614 | } | |
| 602 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) | |
| 615 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) | |
| 603 | 616 | if templ_7745c5c3_Err != nil { | |
| 604 | 617 | return templ_7745c5c3_Err | |
| 605 | 618 | } | |
| 606 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "\" rel=\"noopener\" title=\"source of this version (AGPL-3.0-or-later)\">source</a> <span class=\"foot-keys\"><kbd>?</kbd> keyboard shortcuts</span></footer>") | |
| 619 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "\" rel=\"noopener\" title=\"source of this version (AGPL-3.0-or-later)\">source</a> <span class=\"foot-keys\"><kbd>?</kbd> keyboard shortcuts</span></footer>") | |
| 607 | 620 | if templ_7745c5c3_Err != nil { | |
| 608 | 621 | return templ_7745c5c3_Err | |
| 609 | 622 | } | |
| @@ -631,12 +644,12 @@ func Hint(l Layout) templ.Component { | |||
| 631 | 644 | }() | |
| 632 | 645 | } | |
| 633 | 646 | ctx = templ.InitializeContext(ctx) | |
| 634 | - | templ_7745c5c3_Var30 := templ.GetChildren(ctx) | |
| 635 | - | if templ_7745c5c3_Var30 == nil { | |
| 636 | - | templ_7745c5c3_Var30 = templ.NopComponent | |
| 647 | + | templ_7745c5c3_Var31 := templ.GetChildren(ctx) | |
| 648 | + | if templ_7745c5c3_Var31 == nil { | |
| 649 | + | templ_7745c5c3_Var31 = templ.NopComponent | |
| 637 | 650 | } | |
| 638 | 651 | ctx = templ.ClearChildren(ctx) | |
| 639 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "<div class=\"hint\" role=\"status\" aria-live=\"polite\"><span class=\"hint-nav\" :text=\"document.body.dataset.nav || ''\"></span> <span class=\"hint-sel\" :text=\"document.body.dataset.sel ? document.body.dataset.sel + ' · y permalink' : ''\"></span> <span class=\"hint-flash\" :text=\"document.body.dataset.flash || ''\"></span>") | |
| 652 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "<div class=\"hint\" role=\"status\" aria-live=\"polite\"><span class=\"hint-nav\" :text=\"document.body.dataset.nav || ''\"></span> <span class=\"hint-sel\" :text=\"document.body.dataset.sel ? document.body.dataset.sel + ' · y permalink' : ''\"></span> <span class=\"hint-flash\" :text=\"document.body.dataset.flash || ''\"></span>") | |
| 640 | 653 | if templ_7745c5c3_Err != nil { | |
| 641 | 654 | return templ_7745c5c3_Err | |
| 642 | 655 | } | |
| @@ -644,7 +657,7 @@ func Hint(l Layout) templ.Component { | |||
| 644 | 657 | if templ_7745c5c3_Err != nil { | |
| 645 | 658 | return templ_7745c5c3_Err | |
| 646 | 659 | } | |
| 647 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "</div>") | |
| 660 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "</div>") | |
| 648 | 661 | if templ_7745c5c3_Err != nil { | |
| 649 | 662 | return templ_7745c5c3_Err | |
| 650 | 663 | } | |
| @@ -138,33 +138,46 @@ func Shell(l Layout, rail templ.Component) templ.Component { | |||||
| 138 | if templ_7745c5c3_Err != nil { | 138 | if templ_7745c5c3_Err != nil { | ||
| 139 | return templ_7745c5c3_Err | 139 | return templ_7745c5c3_Err | ||
| 140 | } | 140 | } | ||
| 141 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" defer></script></head><body data-ref=\"") | 141 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" defer></script><script src=\"") |
| 142 | if templ_7745c5c3_Err != nil { | 142 | if templ_7745c5c3_Err != nil { | ||
| 143 | return templ_7745c5c3_Err | 143 | return templ_7745c5c3_Err | ||
| 144 | } | 144 | } | ||
| 145 | var templ_7745c5c3_Var10 string | 145 | var templ_7745c5c3_Var10 string | ||
| 146 | - | templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.ResolveAttributeValue(l.RefPath) | 146 | + | templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.ResolveAttributeValue(l.Assets.Files) |
| 147 | if templ_7745c5c3_Err != nil { | 147 | if templ_7745c5c3_Err != nil { | ||
| 148 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 24, Col: 28} | 148 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 23, Col: 31} |
| 149 | } | 149 | } | ||
| 150 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var10) | 150 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var10) | ||
| 151 | if templ_7745c5c3_Err != nil { | 151 | if templ_7745c5c3_Err != nil { | ||
| 152 | return templ_7745c5c3_Err | 152 | return templ_7745c5c3_Err | ||
| 153 | } | 153 | } | ||
| 154 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\" data-sha=\"") | 154 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\" defer></script></head><body data-ref=\"") |
| 155 | if templ_7745c5c3_Err != nil { | 155 | if templ_7745c5c3_Err != nil { | ||
| 156 | return templ_7745c5c3_Err | 156 | return templ_7745c5c3_Err | ||
| 157 | } | 157 | } | ||
| 158 | var templ_7745c5c3_Var11 string | 158 | var templ_7745c5c3_Var11 string | ||
| 159 | - | templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.ResolveAttributeValue(l.SHA) | 159 | + | templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.ResolveAttributeValue(l.RefPath) |
| 160 | if templ_7745c5c3_Err != nil { | 160 | if templ_7745c5c3_Err != nil { | ||
| 161 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 24, Col: 47} | 161 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 25, Col: 28} |
| 162 | } | 162 | } | ||
| 163 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var11) | 163 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var11) | ||
| 164 | if templ_7745c5c3_Err != nil { | 164 | if templ_7745c5c3_Err != nil { | ||
| 165 | return templ_7745c5c3_Err | 165 | return templ_7745c5c3_Err | ||
| 166 | } | 166 | } | ||
| 167 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\" data-sel=\"\" data-nav=\"\"><a class=\"skip\" href=\"#main\">skip to content</a>") | 167 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\" data-sha=\"") |
| 168 | + | if templ_7745c5c3_Err != nil { | |||
| 169 | + | return templ_7745c5c3_Err | |||
| 170 | + | } | |||
| 171 | + | var templ_7745c5c3_Var12 string | |||
| 172 | + | templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.ResolveAttributeValue(l.SHA) | |||
| 173 | + | if templ_7745c5c3_Err != nil { | |||
| 174 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 25, Col: 47} | |||
| 175 | + | } | |||
| 176 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var12) | |||
| 177 | + | if templ_7745c5c3_Err != nil { | |||
| 178 | + | return templ_7745c5c3_Err | |||
| 179 | + | } | |||
| 180 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\" data-sel=\"\" data-nav=\"\"><a class=\"skip\" href=\"#main\">skip to content</a>") | |||
| 168 | if templ_7745c5c3_Err != nil { | 181 | if templ_7745c5c3_Err != nil { | ||
| 169 | return templ_7745c5c3_Err | 182 | return templ_7745c5c3_Err | ||
| 170 | } | 183 | } | ||
| @@ -172,48 +185,48 @@ func Shell(l Layout, rail templ.Component) templ.Component { | |||||
| 172 | if templ_7745c5c3_Err != nil { | 185 | if templ_7745c5c3_Err != nil { | ||
| 173 | return templ_7745c5c3_Err | 186 | return templ_7745c5c3_Err | ||
| 174 | } | 187 | } | ||
| 175 | - | var templ_7745c5c3_Var12 = []any{"work", templ.KV("has-rail", l.HasRail && rail != nil)} | 188 | + | var templ_7745c5c3_Var13 = []any{"work", templ.KV("has-rail", l.HasRail && rail != nil)} |
| 176 | - | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...) | 189 | + | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var13...) |
| 177 | if templ_7745c5c3_Err != nil { | 190 | if templ_7745c5c3_Err != nil { | ||
| 178 | return templ_7745c5c3_Err | 191 | return templ_7745c5c3_Err | ||
| 179 | } | 192 | } | ||
| 180 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<div class=\"") | 193 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<div class=\"") |
| 181 | if templ_7745c5c3_Err != nil { | 194 | if templ_7745c5c3_Err != nil { | ||
| 182 | return templ_7745c5c3_Err | 195 | return templ_7745c5c3_Err | ||
| 183 | } | 196 | } | ||
| 184 | - | var templ_7745c5c3_Var13 string | 197 | + | var templ_7745c5c3_Var14 string |
| 185 | - | templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var12).String()) | 198 | + | templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var13).String()) |
| 186 | if templ_7745c5c3_Err != nil { | 199 | if templ_7745c5c3_Err != nil { | ||
| 187 | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 1, Col: 0} | 200 | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 1, Col: 0} | ||
| 188 | } | 201 | } | ||
| 189 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var13) | 202 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var14) |
| 190 | if templ_7745c5c3_Err != nil { | 203 | if templ_7745c5c3_Err != nil { | ||
| 191 | return templ_7745c5c3_Err | 204 | return templ_7745c5c3_Err | ||
| 192 | } | 205 | } | ||
| 193 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\">") | 206 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\">") |
| 194 | if templ_7745c5c3_Err != nil { | 207 | if templ_7745c5c3_Err != nil { | ||
| 195 | return templ_7745c5c3_Err | 208 | return templ_7745c5c3_Err | ||
| 196 | } | 209 | } | ||
| 197 | if l.Lede != "" { | 210 | if l.Lede != "" { | ||
| 198 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<section class=\"work-lede\" aria-label=\"Description\"><p class=\"lede\">") | 211 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<section class=\"work-lede\" aria-label=\"Description\"><p class=\"lede\">") |
| 199 | if templ_7745c5c3_Err != nil { | 212 | if templ_7745c5c3_Err != nil { | ||
| 200 | return templ_7745c5c3_Err | 213 | return templ_7745c5c3_Err | ||
| 201 | } | 214 | } | ||
| 202 | - | var templ_7745c5c3_Var14 string | 215 | + | var templ_7745c5c3_Var15 string |
| 203 | - | templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(l.Lede) | 216 | + | templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(l.Lede) |
| 204 | if templ_7745c5c3_Err != nil { | 217 | if templ_7745c5c3_Err != nil { | ||
| 205 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 29, Col: 81} | 218 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 30, Col: 81} |
| 206 | } | 219 | } | ||
| 207 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) | 220 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) |
| 208 | if templ_7745c5c3_Err != nil { | 221 | if templ_7745c5c3_Err != nil { | ||
| 209 | return templ_7745c5c3_Err | 222 | return templ_7745c5c3_Err | ||
| 210 | } | 223 | } | ||
| 211 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</p></section>") | 224 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</p></section>") |
| 212 | if templ_7745c5c3_Err != nil { | 225 | if templ_7745c5c3_Err != nil { | ||
| 213 | return templ_7745c5c3_Err | 226 | return templ_7745c5c3_Err | ||
| 214 | } | 227 | } | ||
| 215 | } | 228 | } | ||
| 216 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<main id=\"main\" tabindex=\"-1\">") | 229 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<main id=\"main\" tabindex=\"-1\">") |
| 217 | if templ_7745c5c3_Err != nil { | 230 | if templ_7745c5c3_Err != nil { | ||
| 218 | return templ_7745c5c3_Err | 231 | return templ_7745c5c3_Err | ||
| 219 | } | 232 | } | ||
| @@ -221,12 +234,12 @@ func Shell(l Layout, rail templ.Component) templ.Component { | |||||
| 221 | if templ_7745c5c3_Err != nil { | 234 | if templ_7745c5c3_Err != nil { | ||
| 222 | return templ_7745c5c3_Err | 235 | return templ_7745c5c3_Err | ||
| 223 | } | 236 | } | ||
| 224 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</main>") | 237 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</main>") |
| 225 | if templ_7745c5c3_Err != nil { | 238 | if templ_7745c5c3_Err != nil { | ||
| 226 | return templ_7745c5c3_Err | 239 | return templ_7745c5c3_Err | ||
| 227 | } | 240 | } | ||
| 228 | if l.HasRail && rail != nil { | 241 | if l.HasRail && rail != nil { | ||
| 229 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "<aside class=\"rail\" aria-label=\"Context\">") | 242 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<aside class=\"rail\" aria-label=\"Context\">") |
| 230 | if templ_7745c5c3_Err != nil { | 243 | if templ_7745c5c3_Err != nil { | ||
| 231 | return templ_7745c5c3_Err | 244 | return templ_7745c5c3_Err | ||
| 232 | } | 245 | } | ||
| @@ -234,12 +247,12 @@ func Shell(l Layout, rail templ.Component) templ.Component { | |||||
| 234 | if templ_7745c5c3_Err != nil { | 247 | if templ_7745c5c3_Err != nil { | ||
| 235 | return templ_7745c5c3_Err | 248 | return templ_7745c5c3_Err | ||
| 236 | } | 249 | } | ||
| 237 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "</aside>") | 250 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</aside>") |
| 238 | if templ_7745c5c3_Err != nil { | 251 | if templ_7745c5c3_Err != nil { | ||
| 239 | return templ_7745c5c3_Err | 252 | return templ_7745c5c3_Err | ||
| 240 | } | 253 | } | ||
| 241 | } | 254 | } | ||
| 242 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</div>") | 255 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</div>") |
| 243 | if templ_7745c5c3_Err != nil { | 256 | if templ_7745c5c3_Err != nil { | ||
| 244 | return templ_7745c5c3_Err | 257 | return templ_7745c5c3_Err | ||
| 245 | } | 258 | } | ||
| @@ -267,7 +280,7 @@ func Shell(l Layout, rail templ.Component) templ.Component { | |||||
| 267 | if templ_7745c5c3_Err != nil { | 280 | if templ_7745c5c3_Err != nil { | ||
| 268 | return templ_7745c5c3_Err | 281 | return templ_7745c5c3_Err | ||
| 269 | } | 282 | } | ||
| 270 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</body></html>") | 283 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "</body></html>") |
| 271 | if templ_7745c5c3_Err != nil { | 284 | if templ_7745c5c3_Err != nil { | ||
| 272 | return templ_7745c5c3_Err | 285 | return templ_7745c5c3_Err | ||
| 273 | } | 286 | } | ||
| @@ -293,260 +306,260 @@ func Header(l Layout) templ.Component { | |||||
| 293 | }() | 306 | }() | ||
| 294 | } | 307 | } | ||
| 295 | ctx = templ.InitializeContext(ctx) | 308 | ctx = templ.InitializeContext(ctx) | ||
| 296 | - | templ_7745c5c3_Var15 := templ.GetChildren(ctx) | 309 | + | templ_7745c5c3_Var16 := templ.GetChildren(ctx) |
| 297 | - | if templ_7745c5c3_Var15 == nil { | 310 | + | if templ_7745c5c3_Var16 == nil { |
| 298 | - | templ_7745c5c3_Var15 = templ.NopComponent | 311 | + | templ_7745c5c3_Var16 = templ.NopComponent |
| 299 | } | 312 | } | ||
| 300 | ctx = templ.ClearChildren(ctx) | 313 | ctx = templ.ClearChildren(ctx) | ||
| 301 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<header class=\"hdr\"><div class=\"hdr-top\"><a class=\"brand\" href=\"/\" data-g=\"h\" title=\"home (g h)\"><span class=\"brand-mark\" aria-hidden=\"true\"></span> <span class=\"brand-name\">") | 314 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<header class=\"hdr\"><div class=\"hdr-top\"><a class=\"brand\" href=\"/\" data-g=\"h\" title=\"home (g h)\"><span class=\"brand-mark\" aria-hidden=\"true\"></span> <span class=\"brand-name\">") |
| 302 | if templ_7745c5c3_Err != nil { | 315 | if templ_7745c5c3_Err != nil { | ||
| 303 | return templ_7745c5c3_Err | 316 | return templ_7745c5c3_Err | ||
| 304 | } | 317 | } | ||
| 305 | - | var templ_7745c5c3_Var16 string | 318 | + | var templ_7745c5c3_Var17 string |
| 306 | - | templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(l.Instance) | 319 | + | templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(l.Instance) |
| 307 | if templ_7745c5c3_Err != nil { | 320 | if templ_7745c5c3_Err != nil { | ||
| 308 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 57, Col: 41} | 321 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 58, Col: 41} |
| 309 | } | 322 | } | ||
| 310 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) | 323 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) |
| 311 | if templ_7745c5c3_Err != nil { | 324 | if templ_7745c5c3_Err != nil { | ||
| 312 | return templ_7745c5c3_Err | 325 | return templ_7745c5c3_Err | ||
| 313 | } | 326 | } | ||
| 314 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "</span></a> ") | 327 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "</span></a> ") |
| 315 | if templ_7745c5c3_Err != nil { | 328 | if templ_7745c5c3_Err != nil { | ||
| 316 | return templ_7745c5c3_Err | 329 | return templ_7745c5c3_Err | ||
| 317 | } | 330 | } | ||
| 318 | if len(l.Crumbs) > 0 { | 331 | if len(l.Crumbs) > 0 { | ||
| 319 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "<nav class=\"crumbs\" aria-label=\"Path\"><ol>") | 332 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<nav class=\"crumbs\" aria-label=\"Path\"><ol>") |
| 320 | if templ_7745c5c3_Err != nil { | 333 | if templ_7745c5c3_Err != nil { | ||
| 321 | return templ_7745c5c3_Err | 334 | return templ_7745c5c3_Err | ||
| 322 | } | 335 | } | ||
| 323 | for _, c := range l.Crumbs { | 336 | for _, c := range l.Crumbs { | ||
| 324 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<li>") | 337 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<li>") |
| 325 | if templ_7745c5c3_Err != nil { | 338 | if templ_7745c5c3_Err != nil { | ||
| 326 | return templ_7745c5c3_Err | 339 | return templ_7745c5c3_Err | ||
| 327 | } | 340 | } | ||
| 328 | if c.Href != "" { | 341 | if c.Href != "" { | ||
| 329 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<a href=\"") | 342 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<a href=\"") |
| 330 | if templ_7745c5c3_Err != nil { | 343 | if templ_7745c5c3_Err != nil { | ||
| 331 | return templ_7745c5c3_Err | 344 | return templ_7745c5c3_Err | ||
| 332 | } | 345 | } | ||
| 333 | - | var templ_7745c5c3_Var17 templ.SafeURL | 346 | + | var templ_7745c5c3_Var18 templ.SafeURL |
| 334 | - | templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Href)) | 347 | + | templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Href)) |
| 335 | if templ_7745c5c3_Err != nil { | 348 | if templ_7745c5c3_Err != nil { | ||
| 336 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 66, Col: 38} | 349 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 67, Col: 38} |
| 337 | } | 350 | } | ||
| 338 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) | 351 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) |
| 339 | if templ_7745c5c3_Err != nil { | 352 | if templ_7745c5c3_Err != nil { | ||
| 340 | return templ_7745c5c3_Err | 353 | return templ_7745c5c3_Err | ||
| 341 | } | 354 | } | ||
| 342 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "\"") | 355 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "\"") |
| 343 | if templ_7745c5c3_Err != nil { | 356 | if templ_7745c5c3_Err != nil { | ||
| 344 | return templ_7745c5c3_Err | 357 | return templ_7745c5c3_Err | ||
| 345 | } | 358 | } | ||
| 346 | if c.Current { | 359 | if c.Current { | ||
| 347 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, " aria-current=\"page\"") | 360 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, " aria-current=\"page\"") |
| 348 | if templ_7745c5c3_Err != nil { | 361 | if templ_7745c5c3_Err != nil { | ||
| 349 | return templ_7745c5c3_Err | 362 | return templ_7745c5c3_Err | ||
| 350 | } | 363 | } | ||
| 351 | } | 364 | } | ||
| 352 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, ">") | 365 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, ">") |
| 353 | if templ_7745c5c3_Err != nil { | 366 | if templ_7745c5c3_Err != nil { | ||
| 354 | return templ_7745c5c3_Err | 367 | return templ_7745c5c3_Err | ||
| 355 | } | 368 | } | ||
| 356 | - | var templ_7745c5c3_Var18 string | 369 | + | var templ_7745c5c3_Var19 string |
| 357 | - | templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(c.Label) | 370 | + | templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(c.Label) |
| 358 | if templ_7745c5c3_Err != nil { | 371 | if templ_7745c5c3_Err != nil { | ||
| 359 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 70, Col: 19} | 372 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 71, Col: 19} |
| 360 | } | 373 | } | ||
| 361 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) | 374 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) |
| 362 | if templ_7745c5c3_Err != nil { | 375 | if templ_7745c5c3_Err != nil { | ||
| 363 | return templ_7745c5c3_Err | 376 | return templ_7745c5c3_Err | ||
| 364 | } | 377 | } | ||
| 365 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "</a>") | 378 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "</a>") |
| 366 | if templ_7745c5c3_Err != nil { | 379 | if templ_7745c5c3_Err != nil { | ||
| 367 | return templ_7745c5c3_Err | 380 | return templ_7745c5c3_Err | ||
| 368 | } | 381 | } | ||
| 369 | } else { | 382 | } else { | ||
| 370 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "<span") | 383 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "<span") |
| 371 | if templ_7745c5c3_Err != nil { | 384 | if templ_7745c5c3_Err != nil { | ||
| 372 | return templ_7745c5c3_Err | 385 | return templ_7745c5c3_Err | ||
| 373 | } | 386 | } | ||
| 374 | if c.Current { | 387 | if c.Current { | ||
| 375 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, " aria-current=\"page\"") | 388 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, " aria-current=\"page\"") |
| 376 | if templ_7745c5c3_Err != nil { | 389 | if templ_7745c5c3_Err != nil { | ||
| 377 | return templ_7745c5c3_Err | 390 | return templ_7745c5c3_Err | ||
| 378 | } | 391 | } | ||
| 379 | } | 392 | } | ||
| 380 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, ">") | 393 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, ">") |
| 381 | if templ_7745c5c3_Err != nil { | 394 | if templ_7745c5c3_Err != nil { | ||
| 382 | return templ_7745c5c3_Err | 395 | return templ_7745c5c3_Err | ||
| 383 | } | 396 | } | ||
| 384 | - | var templ_7745c5c3_Var19 string | 397 | + | var templ_7745c5c3_Var20 string |
| 385 | - | templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(c.Label) | 398 | + | templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(c.Label) |
| 386 | if templ_7745c5c3_Err != nil { | 399 | if templ_7745c5c3_Err != nil { | ||
| 387 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 76, Col: 19} | 400 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 77, Col: 19} |
| 388 | } | 401 | } | ||
| 389 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) | 402 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) |
| 390 | if templ_7745c5c3_Err != nil { | 403 | if templ_7745c5c3_Err != nil { | ||
| 391 | return templ_7745c5c3_Err | 404 | return templ_7745c5c3_Err | ||
| 392 | } | 405 | } | ||
| 393 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "</span>") | 406 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "</span>") |
| 394 | if templ_7745c5c3_Err != nil { | 407 | if templ_7745c5c3_Err != nil { | ||
| 395 | return templ_7745c5c3_Err | 408 | return templ_7745c5c3_Err | ||
| 396 | } | 409 | } | ||
| 397 | } | 410 | } | ||
| 398 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "</li>") | 411 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "</li>") |
| 399 | if templ_7745c5c3_Err != nil { | 412 | if templ_7745c5c3_Err != nil { | ||
| 400 | return templ_7745c5c3_Err | 413 | return templ_7745c5c3_Err | ||
| 401 | } | 414 | } | ||
| 402 | } | 415 | } | ||
| 403 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "</ol></nav>") | 416 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "</ol></nav>") |
| 404 | if templ_7745c5c3_Err != nil { | 417 | if templ_7745c5c3_Err != nil { | ||
| 405 | return templ_7745c5c3_Err | 418 | return templ_7745c5c3_Err | ||
| 406 | } | 419 | } | ||
| 407 | } | 420 | } | ||
| 408 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "<div class=\"hdr-acts\">") | 421 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "<div class=\"hdr-acts\">") |
| 409 | if templ_7745c5c3_Err != nil { | 422 | if templ_7745c5c3_Err != nil { | ||
| 410 | return templ_7745c5c3_Err | 423 | return templ_7745c5c3_Err | ||
| 411 | } | 424 | } | ||
| 412 | if l.Ref != "" { | 425 | if l.Ref != "" { | ||
| 413 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "<button type=\"button\" class=\"btn ref\" aria-haspopup=\"dialog\" aria-controls=\"panel-refs\" aria-keyshortcuts=\"b\" title=\"switch branch or tag (b)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-refs'))\"><span class=\"ico i-branch\" aria-hidden=\"true\"></span> <span class=\"ref-name\">") | 426 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "<button type=\"button\" class=\"btn ref\" aria-haspopup=\"dialog\" aria-controls=\"panel-refs\" aria-keyshortcuts=\"b\" title=\"switch branch or tag (b)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-refs'))\"><span class=\"ico i-branch\" aria-hidden=\"true\"></span> <span class=\"ref-name\">") |
| 414 | if templ_7745c5c3_Err != nil { | 427 | if templ_7745c5c3_Err != nil { | ||
| 415 | return templ_7745c5c3_Err | 428 | return templ_7745c5c3_Err | ||
| 416 | } | 429 | } | ||
| 417 | - | var templ_7745c5c3_Var20 string | 430 | + | var templ_7745c5c3_Var21 string |
| 418 | - | templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(l.Ref) | 431 | + | templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(l.Ref) |
| 419 | if templ_7745c5c3_Err != nil { | 432 | if templ_7745c5c3_Err != nil { | ||
| 420 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 95, Col: 36} | 433 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 96, Col: 36} |
| 421 | } | 434 | } | ||
| 422 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) | 435 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) |
| 423 | if templ_7745c5c3_Err != nil { | 436 | if templ_7745c5c3_Err != nil { | ||
| 424 | return templ_7745c5c3_Err | 437 | return templ_7745c5c3_Err | ||
| 425 | } | 438 | } | ||
| 426 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "</span> <span class=\"sha\">") | 439 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "</span> <span class=\"sha\">") |
| 427 | if templ_7745c5c3_Err != nil { | 440 | if templ_7745c5c3_Err != nil { | ||
| 428 | return templ_7745c5c3_Err | 441 | return templ_7745c5c3_Err | ||
| 429 | } | 442 | } | ||
| 430 | - | var templ_7745c5c3_Var21 string | 443 | + | var templ_7745c5c3_Var22 string |
| 431 | - | templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(l.Short) | 444 | + | templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(l.Short) |
| 432 | if templ_7745c5c3_Err != nil { | 445 | if templ_7745c5c3_Err != nil { | ||
| 433 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 96, Col: 33} | 446 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 97, Col: 33} |
| 434 | } | 447 | } | ||
| 435 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) | 448 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) |
| 436 | if templ_7745c5c3_Err != nil { | 449 | if templ_7745c5c3_Err != nil { | ||
| 437 | return templ_7745c5c3_Err | 450 | return templ_7745c5c3_Err | ||
| 438 | } | 451 | } | ||
| 439 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "</span></button> ") | 452 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</span></button> ") |
| 440 | if templ_7745c5c3_Err != nil { | 453 | if templ_7745c5c3_Err != nil { | ||
| 441 | return templ_7745c5c3_Err | 454 | return templ_7745c5c3_Err | ||
| 442 | } | 455 | } | ||
| 443 | } | 456 | } | ||
| 444 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "<button type=\"button\" class=\"btn search\" aria-haspopup=\"dialog\" aria-controls=\"panel-cmd\" aria-keyshortcuts=\"Control+K :\" title=\"go to a section, ref, file or repo (ctrl k or :)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-cmd'))\"><span class=\"ico i-search\" aria-hidden=\"true\"></span> <span class=\"search-label\">Go to…</span> <kbd aria-hidden=\"true\">ctrl k</kbd></button> <button type=\"button\" class=\"btn icon\" aria-haspopup=\"dialog\" aria-controls=\"panel-help\" aria-keyshortcuts=\"?\" aria-label=\"Keyboard shortcuts\" title=\"keyboard shortcuts (?)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-help'))\">?</button> ") | 457 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<button type=\"button\" class=\"btn search\" aria-haspopup=\"dialog\" aria-controls=\"panel-cmd\" aria-keyshortcuts=\"Control+K :\" title=\"go to a section, ref, file or repo (ctrl k or :)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-cmd'))\"><span class=\"ico i-search\" aria-hidden=\"true\"></span> <span class=\"search-label\">Go to…</span> <kbd aria-hidden=\"true\">ctrl k</kbd></button> <button type=\"button\" class=\"btn icon\" aria-haspopup=\"dialog\" aria-controls=\"panel-help\" aria-keyshortcuts=\"?\" aria-label=\"Keyboard shortcuts\" title=\"keyboard shortcuts (?)\" hx-on:click=\"document.body.dispatchEvent(new CustomEvent('k-help'))\">?</button> ") |
| 445 | if templ_7745c5c3_Err != nil { | 458 | if templ_7745c5c3_Err != nil { | ||
| 446 | return templ_7745c5c3_Err | 459 | return templ_7745c5c3_Err | ||
| 447 | } | 460 | } | ||
| 448 | if SignedIn(ctx) { | 461 | if SignedIn(ctx) { | ||
| 449 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<form class=\"owner\" method=\"post\" action=\"/-/logout\"><span class=\"owner-badge\" title=\"signed in as the owner\">owner</span> <button type=\"submit\" class=\"btn\" title=\"sign out of this browser\">Sign out</button></form>") | 462 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "<form class=\"owner\" method=\"post\" action=\"/-/logout\"><span class=\"owner-badge\" title=\"signed in as the owner\">owner</span> <button type=\"submit\" class=\"btn\" title=\"sign out of this browser\">Sign out</button></form>") |
| 450 | if templ_7745c5c3_Err != nil { | 463 | if templ_7745c5c3_Err != nil { | ||
| 451 | return templ_7745c5c3_Err | 464 | return templ_7745c5c3_Err | ||
| 452 | } | 465 | } | ||
| 453 | } | 466 | } | ||
| 454 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</div></div>") | 467 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "</div></div>") |
| 455 | if templ_7745c5c3_Err != nil { | 468 | if templ_7745c5c3_Err != nil { | ||
| 456 | return templ_7745c5c3_Err | 469 | return templ_7745c5c3_Err | ||
| 457 | } | 470 | } | ||
| 458 | if len(l.Sections) > 0 { | 471 | if len(l.Sections) > 0 { | ||
| 459 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "<nav class=\"tabs\" aria-label=\"Sections\"><ul>") | 472 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<nav class=\"tabs\" aria-label=\"Sections\"><ul>") |
| 460 | if templ_7745c5c3_Err != nil { | 473 | if templ_7745c5c3_Err != nil { | ||
| 461 | return templ_7745c5c3_Err | 474 | return templ_7745c5c3_Err | ||
| 462 | } | 475 | } | ||
| 463 | for _, s := range l.Sections { | 476 | for _, s := range l.Sections { | ||
| 464 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<li><a href=\"") | 477 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "<li><a href=\"") |
| 465 | if templ_7745c5c3_Err != nil { | 478 | if templ_7745c5c3_Err != nil { | ||
| 466 | return templ_7745c5c3_Err | 479 | return templ_7745c5c3_Err | ||
| 467 | } | 480 | } | ||
| 468 | - | var templ_7745c5c3_Var22 templ.SafeURL | 481 | + | var templ_7745c5c3_Var23 templ.SafeURL |
| 469 | - | templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(s.Href)) | 482 | + | templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(s.Href)) |
| 470 | if templ_7745c5c3_Err != nil { | 483 | if templ_7745c5c3_Err != nil { | ||
| 471 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 127, Col: 36} | 484 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 128, Col: 36} |
| 472 | } | 485 | } | ||
| 473 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) | 486 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23)) |
| 474 | if templ_7745c5c3_Err != nil { | 487 | if templ_7745c5c3_Err != nil { | ||
| 475 | return templ_7745c5c3_Err | 488 | return templ_7745c5c3_Err | ||
| 476 | } | 489 | } | ||
| 477 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "\" data-key=\"") | 490 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "\" data-key=\"") |
| 478 | if templ_7745c5c3_Err != nil { | 491 | if templ_7745c5c3_Err != nil { | ||
| 479 | return templ_7745c5c3_Err | 492 | return templ_7745c5c3_Err | ||
| 480 | } | 493 | } | ||
| 481 | - | var templ_7745c5c3_Var23 string | 494 | + | var templ_7745c5c3_Var24 string |
| 482 | - | templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.ResolveAttributeValue(s.Key) | 495 | + | templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.ResolveAttributeValue(s.Key) |
| 483 | if templ_7745c5c3_Err != nil { | 496 | if templ_7745c5c3_Err != nil { | ||
| 484 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 128, Col: 24} | 497 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 129, Col: 24} |
| 485 | } | 498 | } | ||
| 486 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var23) | 499 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var24) |
| 487 | if templ_7745c5c3_Err != nil { | 500 | if templ_7745c5c3_Err != nil { | ||
| 488 | return templ_7745c5c3_Err | 501 | return templ_7745c5c3_Err | ||
| 489 | } | 502 | } | ||
| 490 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "\" aria-keyshortcuts=\"") | 503 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "\" aria-keyshortcuts=\"") |
| 491 | if templ_7745c5c3_Err != nil { | 504 | if templ_7745c5c3_Err != nil { | ||
| 492 | return templ_7745c5c3_Err | 505 | return templ_7745c5c3_Err | ||
| 493 | } | 506 | } | ||
| 494 | - | var templ_7745c5c3_Var24 string | 507 | + | var templ_7745c5c3_Var25 string |
| 495 | - | templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.ResolveAttributeValue(s.Key) | 508 | + | templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.ResolveAttributeValue(s.Key) |
| 496 | if templ_7745c5c3_Err != nil { | 509 | if templ_7745c5c3_Err != nil { | ||
| 497 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 129, Col: 33} | 510 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 130, Col: 33} |
| 498 | } | 511 | } | ||
| 499 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var24) | 512 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var25) |
| 500 | if templ_7745c5c3_Err != nil { | 513 | if templ_7745c5c3_Err != nil { | ||
| 501 | return templ_7745c5c3_Err | 514 | return templ_7745c5c3_Err | ||
| 502 | } | 515 | } | ||
| 503 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "\"") | 516 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "\"") |
| 504 | if templ_7745c5c3_Err != nil { | 517 | if templ_7745c5c3_Err != nil { | ||
| 505 | return templ_7745c5c3_Err | 518 | return templ_7745c5c3_Err | ||
| 506 | } | 519 | } | ||
| 507 | if s.Current { | 520 | if s.Current { | ||
| 508 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, " aria-current=\"page\"") | 521 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, " aria-current=\"page\"") |
| 509 | if templ_7745c5c3_Err != nil { | 522 | if templ_7745c5c3_Err != nil { | ||
| 510 | return templ_7745c5c3_Err | 523 | return templ_7745c5c3_Err | ||
| 511 | } | 524 | } | ||
| 512 | } | 525 | } | ||
| 513 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, ">") | 526 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, ">") |
| 514 | if templ_7745c5c3_Err != nil { | 527 | if templ_7745c5c3_Err != nil { | ||
| 515 | return templ_7745c5c3_Err | 528 | return templ_7745c5c3_Err | ||
| 516 | } | 529 | } | ||
| 517 | - | var templ_7745c5c3_Var25 string | 530 | + | var templ_7745c5c3_Var26 string |
| 518 | - | templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(s.Label) | 531 | + | templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(s.Label) |
| 519 | if templ_7745c5c3_Err != nil { | 532 | if templ_7745c5c3_Err != nil { | ||
| 520 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 133, Col: 17} | 533 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 134, Col: 17} |
| 521 | } | 534 | } | ||
| 522 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) | 535 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) |
| 523 | if templ_7745c5c3_Err != nil { | 536 | if templ_7745c5c3_Err != nil { | ||
| 524 | return templ_7745c5c3_Err | 537 | return templ_7745c5c3_Err | ||
| 525 | } | 538 | } | ||
| 526 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<kbd aria-hidden=\"true\">") | 539 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "<kbd aria-hidden=\"true\">") |
| 527 | if templ_7745c5c3_Err != nil { | 540 | if templ_7745c5c3_Err != nil { | ||
| 528 | return templ_7745c5c3_Err | 541 | return templ_7745c5c3_Err | ||
| 529 | } | 542 | } | ||
| 530 | - | var templ_7745c5c3_Var26 string | 543 | + | var templ_7745c5c3_Var27 string |
| 531 | - | templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(s.Key) | 544 | + | templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(s.Key) |
| 532 | if templ_7745c5c3_Err != nil { | 545 | if templ_7745c5c3_Err != nil { | ||
| 533 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 133, Col: 50} | 546 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 134, Col: 50} |
| 534 | } | 547 | } | ||
| 535 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) | 548 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) |
| 536 | if templ_7745c5c3_Err != nil { | 549 | if templ_7745c5c3_Err != nil { | ||
| 537 | return templ_7745c5c3_Err | 550 | return templ_7745c5c3_Err | ||
| 538 | } | 551 | } | ||
| 539 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "</kbd></a></li>") | 552 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "</kbd></a></li>") |
| 540 | if templ_7745c5c3_Err != nil { | 553 | if templ_7745c5c3_Err != nil { | ||
| 541 | return templ_7745c5c3_Err | 554 | return templ_7745c5c3_Err | ||
| 542 | } | 555 | } | ||
| 543 | } | 556 | } | ||
| 544 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "</ul></nav>") | 557 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "</ul></nav>") |
| 545 | if templ_7745c5c3_Err != nil { | 558 | if templ_7745c5c3_Err != nil { | ||
| 546 | return templ_7745c5c3_Err | 559 | return templ_7745c5c3_Err | ||
| 547 | } | 560 | } | ||
| 548 | } | 561 | } | ||
| 549 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "</header>") | 562 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "</header>") |
| 550 | if templ_7745c5c3_Err != nil { | 563 | if templ_7745c5c3_Err != nil { | ||
| 551 | return templ_7745c5c3_Err | 564 | return templ_7745c5c3_Err | ||
| 552 | } | 565 | } | ||
| @@ -572,38 +585,38 @@ func Footer(l Layout) templ.Component { | |||||
| 572 | }() | 585 | }() | ||
| 573 | } | 586 | } | ||
| 574 | ctx = templ.InitializeContext(ctx) | 587 | ctx = templ.InitializeContext(ctx) | ||
| 575 | - | templ_7745c5c3_Var27 := templ.GetChildren(ctx) | 588 | + | templ_7745c5c3_Var28 := templ.GetChildren(ctx) |
| 576 | - | if templ_7745c5c3_Var27 == nil { | 589 | + | if templ_7745c5c3_Var28 == nil { |
| 577 | - | templ_7745c5c3_Var27 = templ.NopComponent | 590 | + | templ_7745c5c3_Var28 = templ.NopComponent |
| 578 | } | 591 | } | ||
| 579 | ctx = templ.ClearChildren(ctx) | 592 | ctx = templ.ClearChildren(ctx) | ||
| 580 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "<footer class=\"foot\"><span>ermite ") | 593 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<footer class=\"foot\"><span>ermite ") |
| 581 | if templ_7745c5c3_Err != nil { | 594 | if templ_7745c5c3_Err != nil { | ||
| 582 | return templ_7745c5c3_Err | 595 | return templ_7745c5c3_Err | ||
| 583 | } | 596 | } | ||
| 584 | - | var templ_7745c5c3_Var28 string | 597 | + | var templ_7745c5c3_Var29 string |
| 585 | - | templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(l.Version) | 598 | + | templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(l.Version) |
| 586 | if templ_7745c5c3_Err != nil { | 599 | if templ_7745c5c3_Err != nil { | ||
| 587 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 146, Col: 26} | 600 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 147, Col: 26} |
| 588 | } | 601 | } | ||
| 589 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) | 602 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) |
| 590 | if templ_7745c5c3_Err != nil { | 603 | if templ_7745c5c3_Err != nil { | ||
| 591 | return templ_7745c5c3_Err | 604 | return templ_7745c5c3_Err | ||
| 592 | } | 605 | } | ||
| 593 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "</span> <a href=\"") | 606 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "</span> <a href=\"") |
| 594 | if templ_7745c5c3_Err != nil { | 607 | if templ_7745c5c3_Err != nil { | ||
| 595 | return templ_7745c5c3_Err | 608 | return templ_7745c5c3_Err | ||
| 596 | } | 609 | } | ||
| 597 | - | var templ_7745c5c3_Var29 templ.SafeURL | 610 | + | var templ_7745c5c3_Var30 templ.SafeURL |
| 598 | - | templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(l.SourceURL)) | 611 | + | templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(l.SourceURL)) |
| 599 | if templ_7745c5c3_Err != nil { | 612 | if templ_7745c5c3_Err != nil { | ||
| 600 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 147, Col: 38} | 613 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/shell.templ`, Line: 148, Col: 38} |
| 601 | } | 614 | } | ||
| 602 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) | 615 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) |
| 603 | if templ_7745c5c3_Err != nil { | 616 | if templ_7745c5c3_Err != nil { | ||
| 604 | return templ_7745c5c3_Err | 617 | return templ_7745c5c3_Err | ||
| 605 | } | 618 | } | ||
| 606 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "\" rel=\"noopener\" title=\"source of this version (AGPL-3.0-or-later)\">source</a> <span class=\"foot-keys\"><kbd>?</kbd> keyboard shortcuts</span></footer>") | 619 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "\" rel=\"noopener\" title=\"source of this version (AGPL-3.0-or-later)\">source</a> <span class=\"foot-keys\"><kbd>?</kbd> keyboard shortcuts</span></footer>") |
| 607 | if templ_7745c5c3_Err != nil { | 620 | if templ_7745c5c3_Err != nil { | ||
| 608 | return templ_7745c5c3_Err | 621 | return templ_7745c5c3_Err | ||
| 609 | } | 622 | } | ||
| @@ -631,12 +644,12 @@ func Hint(l Layout) templ.Component { | |||||
| 631 | }() | 644 | }() | ||
| 632 | } | 645 | } | ||
| 633 | ctx = templ.InitializeContext(ctx) | 646 | ctx = templ.InitializeContext(ctx) | ||
| 634 | - | templ_7745c5c3_Var30 := templ.GetChildren(ctx) | 647 | + | templ_7745c5c3_Var31 := templ.GetChildren(ctx) |
| 635 | - | if templ_7745c5c3_Var30 == nil { | 648 | + | if templ_7745c5c3_Var31 == nil { |
| 636 | - | templ_7745c5c3_Var30 = templ.NopComponent | 649 | + | templ_7745c5c3_Var31 = templ.NopComponent |
| 637 | } | 650 | } | ||
| 638 | ctx = templ.ClearChildren(ctx) | 651 | ctx = templ.ClearChildren(ctx) | ||
| 639 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "<div class=\"hint\" role=\"status\" aria-live=\"polite\"><span class=\"hint-nav\" :text=\"document.body.dataset.nav || ''\"></span> <span class=\"hint-sel\" :text=\"document.body.dataset.sel ? document.body.dataset.sel + ' · y permalink' : ''\"></span> <span class=\"hint-flash\" :text=\"document.body.dataset.flash || ''\"></span>") | 652 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "<div class=\"hint\" role=\"status\" aria-live=\"polite\"><span class=\"hint-nav\" :text=\"document.body.dataset.nav || ''\"></span> <span class=\"hint-sel\" :text=\"document.body.dataset.sel ? document.body.dataset.sel + ' · y permalink' : ''\"></span> <span class=\"hint-flash\" :text=\"document.body.dataset.flash || ''\"></span>") |
| 640 | if templ_7745c5c3_Err != nil { | 653 | if templ_7745c5c3_Err != nil { | ||
| 641 | return templ_7745c5c3_Err | 654 | return templ_7745c5c3_Err | ||
| 642 | } | 655 | } | ||
| @@ -644,7 +657,7 @@ func Hint(l Layout) templ.Component { | |||||
| 644 | if templ_7745c5c3_Err != nil { | 657 | if templ_7745c5c3_Err != nil { | ||
| 645 | return templ_7745c5c3_Err | 658 | return templ_7745c5c3_Err | ||
| 646 | } | 659 | } | ||
| 647 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "</div>") | 660 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "</div>") |
| 648 | if templ_7745c5c3_Err != nil { | 661 | if templ_7745c5c3_Err != nil { | ||
| 649 | return templ_7745c5c3_Err | 662 | return templ_7745c5c3_Err | ||
| 650 | } | 663 | } | ||
M internal/adapters/web/static/css/30-list.css +4 -1
| @@ -38,7 +38,10 @@ | |||
| 38 | 38 | } | |
| 39 | 39 | .list.tree { | |
| 40 | 40 | & .c-kind { width: 36px; color: var(--ink-mute); padding-right: 0; text-align: center; } | |
| 41 | - | & .c-name { width: 32%; font-family: var(--mono); font-size: var(--fs-s); } | |
| 41 | + | /* --depth is set by files.js on the rows opened in place */ | |
| 42 | + | & .c-name { width: 32%; font-family: var(--mono); font-size: var(--fs-s); padding-inline-start: calc(var(--s3) + var(--depth, 0) * 1.25ch); } | |
| 43 | + | & tr[aria-busy=true] .c-kind { opacity: .4; } | |
| 44 | + | & .tree-more td { padding-inline-start: calc(var(--s3) + 36px + var(--depth, 0) * 1.25ch); color: var(--ink-dim); font-size: var(--fs-s); } | |
| 42 | 45 | & .c-size { width: 90px; text-align: right; } | |
| 43 | 46 | & .c-when { width: 100px; } | |
| 44 | 47 | & .c-sub { width: auto; } | |
| @@ -38,7 +38,10 @@ | |||||
| 38 | } | 38 | } | ||
| 39 | .list.tree { | 39 | .list.tree { | ||
| 40 | & .c-kind { width: 36px; color: var(--ink-mute); padding-right: 0; text-align: center; } | 40 | & .c-kind { width: 36px; color: var(--ink-mute); padding-right: 0; text-align: center; } | ||
| 41 | - | & .c-name { width: 32%; font-family: var(--mono); font-size: var(--fs-s); } | 41 | + | /* --depth is set by files.js on the rows opened in place */ |
| 42 | + | & .c-name { width: 32%; font-family: var(--mono); font-size: var(--fs-s); padding-inline-start: calc(var(--s3) + var(--depth, 0) * 1.25ch); } | |||
| 43 | + | & tr[aria-busy=true] .c-kind { opacity: .4; } | |||
| 44 | + | & .tree-more td { padding-inline-start: calc(var(--s3) + 36px + var(--depth, 0) * 1.25ch); color: var(--ink-dim); font-size: var(--fs-s); } | |||
| 42 | & .c-size { width: 90px; text-align: right; } | 45 | & .c-size { width: 90px; text-align: right; } | ||
| 43 | & .c-when { width: 100px; } | 46 | & .c-when { width: 100px; } | ||
| 44 | & .c-sub { width: auto; } | 47 | & .c-sub { width: auto; } | ||
A internal/adapters/web/static/js/files.js +81 -0
| @@ -0,0 +1,81 @@ | |||
| 1 | + | // files.js: the Files view. A directory opens in place: its entries are | |
| 2 | + | // fetched once as table rows (the tree page with ?rows), inserted under it | |
| 3 | + | // and kept in the DOM, so closing and opening it again needs no request. | |
| 4 | + | // | |
| 5 | + | // Rows opened in place carry data-depth and the --depth custom property | |
| 6 | + | // (set through the CSSOM: the CSP forbids style attributes). Rows of the | |
| 7 | + | // page itself have depth 0. Nothing here touches the document at load; the | |
| 8 | + | // handlers are declared in the templates (hx-on:click on #tree-rows). | |
| 9 | + | window.ermiteTree = (() => { | |
| 10 | + | const depthOf = (tr) => Number(tr.dataset.depth || 0); | |
| 11 | + | const linkOf = (tr) => tr.querySelector('a[data-expand]'); | |
| 12 | + | const isOpen = (a) => a.getAttribute('aria-expanded') === 'true'; | |
| 13 | + | ||
| 14 | + | function setOpen(tr, a, open) { | |
| 15 | + | a.setAttribute('aria-expanded', open ? 'true' : 'false'); | |
| 16 | + | const kind = tr.querySelector('.c-kind'); | |
| 17 | + | if (kind) kind.textContent = open ? '▾' : '▸'; | |
| 18 | + | } | |
| 19 | + | ||
| 20 | + | // collapse hides every row under tr. | |
| 21 | + | function collapse(tr, a) { | |
| 22 | + | setOpen(tr, a, false); | |
| 23 | + | const d = depthOf(tr); | |
| 24 | + | for (let r = tr.nextElementSibling; r && depthOf(r) > d; r = r.nextElementSibling) r.hidden = true; | |
| 25 | + | } | |
| 26 | + | ||
| 27 | + | // expand shows the rows under tr that no collapsed directory between hides. | |
| 28 | + | function expand(tr, a) { | |
| 29 | + | setOpen(tr, a, true); | |
| 30 | + | const d = depthOf(tr); | |
| 31 | + | let closedAt = Infinity; // depth of the collapsed directory whose rows are skipped | |
| 32 | + | for (let r = tr.nextElementSibling; r && depthOf(r) > d; r = r.nextElementSibling) { | |
| 33 | + | const rd = depthOf(r); | |
| 34 | + | if (rd <= closedAt) closedAt = Infinity; | |
| 35 | + | r.hidden = rd > closedAt; | |
| 36 | + | const la = linkOf(r); | |
| 37 | + | if (closedAt === Infinity && la && !isOpen(la)) closedAt = rd; | |
| 38 | + | } | |
| 39 | + | } | |
| 40 | + | ||
| 41 | + | async function load(tr, a) { | |
| 42 | + | tr.setAttribute('aria-busy', 'true'); | |
| 43 | + | try { | |
| 44 | + | const res = await fetch(a.dataset.expand, { headers: { Accept: 'text/html' } }); | |
| 45 | + | if (!res.ok) throw new Error('HTTP ' + res.status); | |
| 46 | + | const t = document.createElement('template'); | |
| 47 | + | t.innerHTML = await res.text(); | |
| 48 | + | const d = depthOf(tr) + 1; | |
| 49 | + | const rows = Array.from(t.content.children); | |
| 50 | + | for (const r of rows) { | |
| 51 | + | r.dataset.depth = String(d); | |
| 52 | + | r.style.setProperty('--depth', String(d)); | |
| 53 | + | } | |
| 54 | + | tr.after(...rows); | |
| 55 | + | tr.dataset.loaded = '1'; | |
| 56 | + | tr.removeAttribute('aria-busy'); | |
| 57 | + | expand(tr, a); | |
| 58 | + | } catch (e) { | |
| 59 | + | location.href = a.href; | |
| 60 | + | } | |
| 61 | + | } | |
| 62 | + | ||
| 63 | + | function toggle(tr) { | |
| 64 | + | const a = linkOf(tr); | |
| 65 | + | if (!a || tr.getAttribute('aria-busy') === 'true') return; | |
| 66 | + | if (isOpen(a)) collapse(tr, a); | |
| 67 | + | else if (tr.dataset.loaded) expand(tr, a); | |
| 68 | + | else load(tr, a); | |
| 69 | + | } | |
| 70 | + | ||
| 71 | + | return { | |
| 72 | + | // click opens or closes the directory under a plain left click; any | |
| 73 | + | // modified or other click keeps the link's own navigation. | |
| 74 | + | click(event) { | |
| 75 | + | const a = event.target.closest('a[data-expand]'); | |
| 76 | + | if (!a || event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) return; | |
| 77 | + | event.preventDefault(); | |
| 78 | + | toggle(a.closest('tr')); | |
| 79 | + | }, | |
| 80 | + | }; | |
| 81 | + | })(); | |
| @@ -0,0 +1,81 @@ | |||||
| 1 | + | // files.js: the Files view. A directory opens in place: its entries are | |||
| 2 | + | // fetched once as table rows (the tree page with ?rows), inserted under it | |||
| 3 | + | // and kept in the DOM, so closing and opening it again needs no request. | |||
| 4 | + | // | |||
| 5 | + | // Rows opened in place carry data-depth and the --depth custom property | |||
| 6 | + | // (set through the CSSOM: the CSP forbids style attributes). Rows of the | |||
| 7 | + | // page itself have depth 0. Nothing here touches the document at load; the | |||
| 8 | + | // handlers are declared in the templates (hx-on:click on #tree-rows). | |||
| 9 | + | window.ermiteTree = (() => { | |||
| 10 | + | const depthOf = (tr) => Number(tr.dataset.depth || 0); | |||
| 11 | + | const linkOf = (tr) => tr.querySelector('a[data-expand]'); | |||
| 12 | + | const isOpen = (a) => a.getAttribute('aria-expanded') === 'true'; | |||
| 13 | + | ||||
| 14 | + | function setOpen(tr, a, open) { | |||
| 15 | + | a.setAttribute('aria-expanded', open ? 'true' : 'false'); | |||
| 16 | + | const kind = tr.querySelector('.c-kind'); | |||
| 17 | + | if (kind) kind.textContent = open ? '▾' : '▸'; | |||
| 18 | + | } | |||
| 19 | + | ||||
| 20 | + | // collapse hides every row under tr. | |||
| 21 | + | function collapse(tr, a) { | |||
| 22 | + | setOpen(tr, a, false); | |||
| 23 | + | const d = depthOf(tr); | |||
| 24 | + | for (let r = tr.nextElementSibling; r && depthOf(r) > d; r = r.nextElementSibling) r.hidden = true; | |||
| 25 | + | } | |||
| 26 | + | ||||
| 27 | + | // expand shows the rows under tr that no collapsed directory between hides. | |||
| 28 | + | function expand(tr, a) { | |||
| 29 | + | setOpen(tr, a, true); | |||
| 30 | + | const d = depthOf(tr); | |||
| 31 | + | let closedAt = Infinity; // depth of the collapsed directory whose rows are skipped | |||
| 32 | + | for (let r = tr.nextElementSibling; r && depthOf(r) > d; r = r.nextElementSibling) { | |||
| 33 | + | const rd = depthOf(r); | |||
| 34 | + | if (rd <= closedAt) closedAt = Infinity; | |||
| 35 | + | r.hidden = rd > closedAt; | |||
| 36 | + | const la = linkOf(r); | |||
| 37 | + | if (closedAt === Infinity && la && !isOpen(la)) closedAt = rd; | |||
| 38 | + | } | |||
| 39 | + | } | |||
| 40 | + | ||||
| 41 | + | async function load(tr, a) { | |||
| 42 | + | tr.setAttribute('aria-busy', 'true'); | |||
| 43 | + | try { | |||
| 44 | + | const res = await fetch(a.dataset.expand, { headers: { Accept: 'text/html' } }); | |||
| 45 | + | if (!res.ok) throw new Error('HTTP ' + res.status); | |||
| 46 | + | const t = document.createElement('template'); | |||
| 47 | + | t.innerHTML = await res.text(); | |||
| 48 | + | const d = depthOf(tr) + 1; | |||
| 49 | + | const rows = Array.from(t.content.children); | |||
| 50 | + | for (const r of rows) { | |||
| 51 | + | r.dataset.depth = String(d); | |||
| 52 | + | r.style.setProperty('--depth', String(d)); | |||
| 53 | + | } | |||
| 54 | + | tr.after(...rows); | |||
| 55 | + | tr.dataset.loaded = '1'; | |||
| 56 | + | tr.removeAttribute('aria-busy'); | |||
| 57 | + | expand(tr, a); | |||
| 58 | + | } catch (e) { | |||
| 59 | + | location.href = a.href; | |||
| 60 | + | } | |||
| 61 | + | } | |||
| 62 | + | ||||
| 63 | + | function toggle(tr) { | |||
| 64 | + | const a = linkOf(tr); | |||
| 65 | + | if (!a || tr.getAttribute('aria-busy') === 'true') return; | |||
| 66 | + | if (isOpen(a)) collapse(tr, a); | |||
| 67 | + | else if (tr.dataset.loaded) expand(tr, a); | |||
| 68 | + | else load(tr, a); | |||
| 69 | + | } | |||
| 70 | + | ||||
| 71 | + | return { | |||
| 72 | + | // click opens or closes the directory under a plain left click; any | |||
| 73 | + | // modified or other click keeps the link's own navigation. | |||
| 74 | + | click(event) { | |||
| 75 | + | const a = event.target.closest('a[data-expand]'); | |||
| 76 | + | if (!a || event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) return; | |||
| 77 | + | event.preventDefault(); | |||
| 78 | + | toggle(a.closest('tr')); | |||
| 79 | + | }, | |||
| 80 | + | }; | |||
| 81 | + | })(); | |||
M internal/adapters/web/tree.go +21 -12
| @@ -12,14 +12,14 @@ import ( | |||
| 12 | 12 | pb "bnema.dev/ermite-api/gen/ermite" | |
| 13 | 13 | ) | |
| 14 | 14 | ||
| 15 | - | // maxFileTargets bounds the files of a directory offered in the ":" list. | |
| 16 | - | const maxFileTargets = 200 | |
| 17 | - | ||
| 18 | 15 | // TreeRow is one entry of a directory. | |
| 19 | 16 | type TreeRow struct { | |
| 20 | - | Glyph string // ▾ directory, @ symbolic link, + submodule, · file | |
| 21 | - | Name string | |
| 22 | - | Href string // "" for a submodule | |
| 17 | + | Glyph string // ▸ directory, @ symbolic link, + submodule, · file | |
| 18 | + | Name string | |
| 19 | + | Href string // "" for a submodule | |
| 20 | + | // Expand is the URL of the rows of a directory (Href?rows); "" for any | |
| 21 | + | // other entry. | |
| 22 | + | Expand string | |
| 23 | 23 | Size string | |
| 24 | 24 | Subject string | |
| 25 | 25 | CHref string | |
| @@ -35,6 +35,9 @@ type TreePage struct { | |||
| 35 | 35 | Readme *Readme | |
| 36 | 36 | // Notes say what the listing leaves out. | |
| 37 | 37 | Notes []string | |
| 38 | + | // More, for the rows of a directory expanded in place, is the page of the | |
| 39 | + | // directory when it has more entries than are listed; "" otherwise. | |
| 40 | + | More string | |
| 38 | 41 | } | |
| 39 | 42 | ||
| 40 | 43 | // tree lists a directory of a ref, with the last commit of each entry, and | |
| @@ -57,14 +60,15 @@ func (s *Server) tree(ctx context.Context, r *http.Request) (templ.Component, in | |||
| 57 | 60 | entries := res.Msg.GetEntries() | |
| 58 | 61 | now := s.cfg.Now() | |
| 59 | 62 | ||
| 63 | + | rowsOnly := r.URL.Query().Has("rows") | |
| 60 | 64 | p := TreePage{} | |
| 61 | - | l := s.repoLayout(ctx, d, "tree") | |
| 62 | 65 | for i, e := range entries { | |
| 63 | - | row := TreeRow{Glyph: "·", Name: visibleText(e.GetName()), Size: humanSize(e.GetSize()), Cursor: i == 0} | |
| 66 | + | row := TreeRow{Glyph: "·", Name: visibleText(e.GetName()), Size: humanSize(e.GetSize()), Cursor: i == 0 && !rowsOnly} | |
| 64 | 67 | switch e.GetKind() { | |
| 65 | 68 | case pb.EntryKind_ENTRY_KIND_DIRECTORY: | |
| 66 | - | row.Glyph, row.Name, row.Size = "▾", row.Name+"/", "-" | |
| 69 | + | row.Glyph, row.Name, row.Size = "▸", row.Name+"/", "-" | |
| 67 | 70 | row.Href = repoHref(d.name(), "tree", t.name, e.GetPath()) | |
| 71 | + | row.Expand = row.Href + "?rows" | |
| 68 | 72 | case pb.EntryKind_ENTRY_KIND_SYMLINK: | |
| 69 | 73 | row.Glyph = "@" | |
| 70 | 74 | row.Href = repoHref(d.name(), "blob", t.name, e.GetPath()) | |
| @@ -72,9 +76,6 @@ func (s *Server) tree(ctx context.Context, r *http.Request) (templ.Component, in | |||
| 72 | 76 | row.Glyph, row.Size = "+", "-" | |
| 73 | 77 | default: | |
| 74 | 78 | row.Href = repoHref(d.name(), "blob", t.name, e.GetPath()) | |
| 75 | - | if len(l.Cmd) < maxFileTargets { | |
| 76 | - | l.Cmd = append(l.Cmd, CmdItem{Kind: "file", Label: visibleText(e.GetPath()), Href: row.Href}) | |
| 77 | - | } | |
| 78 | 79 | } | |
| 79 | 80 | if c := e.GetLastCommit(); c != nil { | |
| 80 | 81 | last := commitRow(d.name(), c, now) | |
| @@ -82,6 +83,13 @@ func (s *Server) tree(ctx context.Context, r *http.Request) (templ.Component, in | |||
| 82 | 83 | } | |
| 83 | 84 | p.Rows = append(p.Rows, row) | |
| 84 | 85 | } | |
| 86 | + | if rowsOnly { | |
| 87 | + | // The rows alone, for a directory opened in place (files.js). | |
| 88 | + | if res.Msg.GetTruncated() { | |
| 89 | + | p.More = repoHref(d.name(), "tree", t.name, t.path) | |
| 90 | + | } | |
| 91 | + | return TreeRows(p), http.StatusOK, nil | |
| 92 | + | } | |
| 85 | 93 | if res.Msg.GetTruncated() { | |
| 86 | 94 | p.Notes = append(p.Notes, "this directory has more entries than are listed here: the first "+itoa(len(entries))+" are shown.") | |
| 87 | 95 | } | |
| @@ -96,6 +104,7 @@ func (s *Server) tree(ctx context.Context, r *http.Request) (templ.Component, in | |||
| 96 | 104 | p.Readme = rd.readme | |
| 97 | 105 | } | |
| 98 | 106 | ||
| 107 | + | l := s.repoLayout(ctx, d, "tree") | |
| 99 | 108 | pinRef(&l, t) | |
| 100 | 109 | l.Crumbs = pathCrumbs(d.name(), "tree", t) | |
| 101 | 110 | if t.path == "" { | |
| @@ -12,14 +12,14 @@ import ( | |||||
| 12 | pb "bnema.dev/ermite-api/gen/ermite" | 12 | pb "bnema.dev/ermite-api/gen/ermite" | ||
| 13 | ) | 13 | ) | ||
| 14 | 14 | ||||
| 15 | - | // maxFileTargets bounds the files of a directory offered in the ":" list. | |||
| 16 | - | const maxFileTargets = 200 | |||
| 17 | - | ||||
| 18 | // TreeRow is one entry of a directory. | 15 | // TreeRow is one entry of a directory. | ||
| 19 | type TreeRow struct { | 16 | type TreeRow struct { | ||
| 20 | - | Glyph string // ▾ directory, @ symbolic link, + submodule, · file | 17 | + | Glyph string // ▸ directory, @ symbolic link, + submodule, · file |
| 21 | - | Name string | 18 | + | Name string |
| 22 | - | Href string // "" for a submodule | 19 | + | Href string // "" for a submodule |
| 20 | + | // Expand is the URL of the rows of a directory (Href?rows); "" for any | |||
| 21 | + | // other entry. | |||
| 22 | + | Expand string | |||
| 23 | Size string | 23 | Size string | ||
| 24 | Subject string | 24 | Subject string | ||
| 25 | CHref string | 25 | CHref string | ||
| @@ -35,6 +35,9 @@ type TreePage struct { | |||||
| 35 | Readme *Readme | 35 | Readme *Readme | ||
| 36 | // Notes say what the listing leaves out. | 36 | // Notes say what the listing leaves out. | ||
| 37 | Notes []string | 37 | Notes []string | ||
| 38 | + | // More, for the rows of a directory expanded in place, is the page of the | |||
| 39 | + | // directory when it has more entries than are listed; "" otherwise. | |||
| 40 | + | More string | |||
| 38 | } | 41 | } | ||
| 39 | 42 | ||||
| 40 | // tree lists a directory of a ref, with the last commit of each entry, and | 43 | // tree lists a directory of a ref, with the last commit of each entry, and | ||
| @@ -57,14 +60,15 @@ func (s *Server) tree(ctx context.Context, r *http.Request) (templ.Component, in | |||||
| 57 | entries := res.Msg.GetEntries() | 60 | entries := res.Msg.GetEntries() | ||
| 58 | now := s.cfg.Now() | 61 | now := s.cfg.Now() | ||
| 59 | 62 | ||||
| 63 | + | rowsOnly := r.URL.Query().Has("rows") | |||
| 60 | p := TreePage{} | 64 | p := TreePage{} | ||
| 61 | - | l := s.repoLayout(ctx, d, "tree") | |||
| 62 | for i, e := range entries { | 65 | for i, e := range entries { | ||
| 63 | - | row := TreeRow{Glyph: "·", Name: visibleText(e.GetName()), Size: humanSize(e.GetSize()), Cursor: i == 0} | 66 | + | row := TreeRow{Glyph: "·", Name: visibleText(e.GetName()), Size: humanSize(e.GetSize()), Cursor: i == 0 && !rowsOnly} |
| 64 | switch e.GetKind() { | 67 | switch e.GetKind() { | ||
| 65 | case pb.EntryKind_ENTRY_KIND_DIRECTORY: | 68 | case pb.EntryKind_ENTRY_KIND_DIRECTORY: | ||
| 66 | - | row.Glyph, row.Name, row.Size = "▾", row.Name+"/", "-" | 69 | + | row.Glyph, row.Name, row.Size = "▸", row.Name+"/", "-" |
| 67 | row.Href = repoHref(d.name(), "tree", t.name, e.GetPath()) | 70 | row.Href = repoHref(d.name(), "tree", t.name, e.GetPath()) | ||
| 71 | + | row.Expand = row.Href + "?rows" | |||
| 68 | case pb.EntryKind_ENTRY_KIND_SYMLINK: | 72 | case pb.EntryKind_ENTRY_KIND_SYMLINK: | ||
| 69 | row.Glyph = "@" | 73 | row.Glyph = "@" | ||
| 70 | row.Href = repoHref(d.name(), "blob", t.name, e.GetPath()) | 74 | row.Href = repoHref(d.name(), "blob", t.name, e.GetPath()) | ||
| @@ -72,9 +76,6 @@ func (s *Server) tree(ctx context.Context, r *http.Request) (templ.Component, in | |||||
| 72 | row.Glyph, row.Size = "+", "-" | 76 | row.Glyph, row.Size = "+", "-" | ||
| 73 | default: | 77 | default: | ||
| 74 | row.Href = repoHref(d.name(), "blob", t.name, e.GetPath()) | 78 | row.Href = repoHref(d.name(), "blob", t.name, e.GetPath()) | ||
| 75 | - | if len(l.Cmd) < maxFileTargets { | |||
| 76 | - | l.Cmd = append(l.Cmd, CmdItem{Kind: "file", Label: visibleText(e.GetPath()), Href: row.Href}) | |||
| 77 | - | } | |||
| 78 | } | 79 | } | ||
| 79 | if c := e.GetLastCommit(); c != nil { | 80 | if c := e.GetLastCommit(); c != nil { | ||
| 80 | last := commitRow(d.name(), c, now) | 81 | last := commitRow(d.name(), c, now) | ||
| @@ -82,6 +83,13 @@ func (s *Server) tree(ctx context.Context, r *http.Request) (templ.Component, in | |||||
| 82 | } | 83 | } | ||
| 83 | p.Rows = append(p.Rows, row) | 84 | p.Rows = append(p.Rows, row) | ||
| 84 | } | 85 | } | ||
| 86 | + | if rowsOnly { | |||
| 87 | + | // The rows alone, for a directory opened in place (files.js). | |||
| 88 | + | if res.Msg.GetTruncated() { | |||
| 89 | + | p.More = repoHref(d.name(), "tree", t.name, t.path) | |||
| 90 | + | } | |||
| 91 | + | return TreeRows(p), http.StatusOK, nil | |||
| 92 | + | } | |||
| 85 | if res.Msg.GetTruncated() { | 93 | if res.Msg.GetTruncated() { | ||
| 86 | p.Notes = append(p.Notes, "this directory has more entries than are listed here: the first "+itoa(len(entries))+" are shown.") | 94 | p.Notes = append(p.Notes, "this directory has more entries than are listed here: the first "+itoa(len(entries))+" are shown.") | ||
| 87 | } | 95 | } | ||
| @@ -96,6 +104,7 @@ func (s *Server) tree(ctx context.Context, r *http.Request) (templ.Component, in | |||||
| 96 | p.Readme = rd.readme | 104 | p.Readme = rd.readme | ||
| 97 | } | 105 | } | ||
| 98 | 106 | ||||
| 107 | + | l := s.repoLayout(ctx, d, "tree") | |||
| 99 | pinRef(&l, t) | 108 | pinRef(&l, t) | ||
| 100 | l.Crumbs = pathCrumbs(d.name(), "tree", t) | 109 | l.Crumbs = pathCrumbs(d.name(), "tree", t) | ||
| 101 | if t.path == "" { | 110 | if t.path == "" { | ||
M internal/adapters/web/tree.templ +24 -7
| @@ -21,10 +21,8 @@ templ Tree(l Layout, p TreePage) { | |||
| 21 | 21 | <thead> | |
| 22 | 22 | <tr><th class="cur"></th><th class="c-kind"></th><th class="c-name">name</th><th class="c-size">size</th><th class="c-sub">last commit</th><th class="c-who">author</th><th class="c-when">date</th></tr> | |
| 23 | 23 | </thead> | |
| 24 | - | <tbody id="tree-rows" data-rows> | |
| 25 | - | for _, r := range p.Rows { | |
| 26 | - | @TreeRowView(r) | |
| 27 | - | } | |
| 24 | + | <tbody id="tree-rows" data-rows hx-on:click="ermiteTree.click(event)"> | |
| 25 | + | @TreeRows(p) | |
| 28 | 26 | </tbody> | |
| 29 | 27 | </table> | |
| 30 | 28 | if len(p.Rows) == 0 { | |
| @@ -39,15 +37,34 @@ templ Tree(l Layout, p TreePage) { | |||
| 39 | 37 | } | |
| 40 | 38 | } | |
| 41 | 39 | ||
| 42 | - | // TreeRowView is one entry of a directory. Glyph: ▾ directory, @ symbolic | |
| 43 | - | // link, + submodule, · file. | |
| 40 | + | // TreeRows is the rows of a directory alone: what files.js inserts under a | |
| 41 | + | // directory it opens in place. When the directory has more entries than are | |
| 42 | + | // listed, the last row links to its page. | |
| 43 | + | templ TreeRows(p TreePage) { | |
| 44 | + | for _, r := range p.Rows { | |
| 45 | + | @TreeRowView(r) | |
| 46 | + | } | |
| 47 | + | if p.More != "" { | |
| 48 | + | <tr class="tree-more"><td colspan="7"><a href={ templ.SafeURL(p.More) }>more entries: open the directory</a></td></tr> | |
| 49 | + | } | |
| 50 | + | } | |
| 51 | + | ||
| 52 | + | // TreeRowView is one entry of a directory. Glyph: ▸ directory (▾ once opened | |
| 53 | + | // in place), @ symbolic link, + submodule, · file. A directory link carries | |
| 54 | + | // data-expand, the URL of its rows. | |
| 44 | 55 | templ TreeRowView(r TreeRow) { | |
| 45 | 56 | <tr data-cursor?={ r.Cursor }> | |
| 46 | 57 | <td class="cur" aria-hidden="true"></td> | |
| 47 | 58 | <td class="c-kind" aria-hidden="true">{ r.Glyph }</td> | |
| 48 | 59 | <td class="c-name"> | |
| 49 | 60 | if r.Href != "" { | |
| 50 | - | <a href={ templ.SafeURL(r.Href) }>{ r.Name }</a> | |
| 61 | + | <a | |
| 62 | + | href={ templ.SafeURL(r.Href) } | |
| 63 | + | if r.Expand != "" { | |
| 64 | + | data-expand={ r.Expand } | |
| 65 | + | aria-expanded="false" | |
| 66 | + | } | |
| 67 | + | >{ r.Name }</a> | |
| 51 | 68 | } else { | |
| 52 | 69 | { r.Name } | |
| 53 | 70 | } | |
| @@ -21,10 +21,8 @@ templ Tree(l Layout, p TreePage) { | |||||
| 21 | <thead> | 21 | <thead> | ||
| 22 | <tr><th class="cur"></th><th class="c-kind"></th><th class="c-name">name</th><th class="c-size">size</th><th class="c-sub">last commit</th><th class="c-who">author</th><th class="c-when">date</th></tr> | 22 | <tr><th class="cur"></th><th class="c-kind"></th><th class="c-name">name</th><th class="c-size">size</th><th class="c-sub">last commit</th><th class="c-who">author</th><th class="c-when">date</th></tr> | ||
| 23 | </thead> | 23 | </thead> | ||
| 24 | - | <tbody id="tree-rows" data-rows> | 24 | + | <tbody id="tree-rows" data-rows hx-on:click="ermiteTree.click(event)"> |
| 25 | - | for _, r := range p.Rows { | 25 | + | @TreeRows(p) |
| 26 | - | @TreeRowView(r) | |||
| 27 | - | } | |||
| 28 | </tbody> | 26 | </tbody> | ||
| 29 | </table> | 27 | </table> | ||
| 30 | if len(p.Rows) == 0 { | 28 | if len(p.Rows) == 0 { | ||
| @@ -39,15 +37,34 @@ templ Tree(l Layout, p TreePage) { | |||||
| 39 | } | 37 | } | ||
| 40 | } | 38 | } | ||
| 41 | 39 | ||||
| 42 | - | // TreeRowView is one entry of a directory. Glyph: ▾ directory, @ symbolic | 40 | + | // TreeRows is the rows of a directory alone: what files.js inserts under a |
| 43 | - | // link, + submodule, · file. | 41 | + | // directory it opens in place. When the directory has more entries than are |
| 42 | + | // listed, the last row links to its page. | |||
| 43 | + | templ TreeRows(p TreePage) { | |||
| 44 | + | for _, r := range p.Rows { | |||
| 45 | + | @TreeRowView(r) | |||
| 46 | + | } | |||
| 47 | + | if p.More != "" { | |||
| 48 | + | <tr class="tree-more"><td colspan="7"><a href={ templ.SafeURL(p.More) }>more entries: open the directory</a></td></tr> | |||
| 49 | + | } | |||
| 50 | + | } | |||
| 51 | + | ||||
| 52 | + | // TreeRowView is one entry of a directory. Glyph: ▸ directory (▾ once opened | |||
| 53 | + | // in place), @ symbolic link, + submodule, · file. A directory link carries | |||
| 54 | + | // data-expand, the URL of its rows. | |||
| 44 | templ TreeRowView(r TreeRow) { | 55 | templ TreeRowView(r TreeRow) { | ||
| 45 | <tr data-cursor?={ r.Cursor }> | 56 | <tr data-cursor?={ r.Cursor }> | ||
| 46 | <td class="cur" aria-hidden="true"></td> | 57 | <td class="cur" aria-hidden="true"></td> | ||
| 47 | <td class="c-kind" aria-hidden="true">{ r.Glyph }</td> | 58 | <td class="c-kind" aria-hidden="true">{ r.Glyph }</td> | ||
| 48 | <td class="c-name"> | 59 | <td class="c-name"> | ||
| 49 | if r.Href != "" { | 60 | if r.Href != "" { | ||
| 50 | - | <a href={ templ.SafeURL(r.Href) }>{ r.Name }</a> | 61 | + | <a |
| 62 | + | href={ templ.SafeURL(r.Href) } | |||
| 63 | + | if r.Expand != "" { | |||
| 64 | + | data-expand={ r.Expand } | |||
| 65 | + | aria-expanded="false" | |||
| 66 | + | } | |||
| 67 | + | >{ r.Name }</a> | |||
| 51 | } else { | 68 | } else { | ||
| 52 | { r.Name } | 69 | { r.Name } | ||
| 53 | } | 70 | } | ||