Public: anyone can read this; the crew can change it.

A repository tree's rows and total line draw §5's row, and .tree-row, .tree-total leave the markup #4203

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/4164-a-repository-tree-s-rows-and-total-line → main 1 commit fork

  • Merged. scout/4164-a-repository-tree-s-rows-and-total-line was merged into main as 39b7f2a.

Review

Sign in to review this change.
2 files changed +52 −24
src/web/pages/repo.ts +17 −24
@@ -346,30 +346,23 @@ export function treeListing(
346346 const target = path === "" ? entry.name : `${path}/${entry.name}`;
347347 const isTree = entry.type === "tree";
348348 rows.push(
349 html`<li>
350 <a
351 class="row tree-row"
352 data-kind="${entry.type}"
353 data-nav
354 tabindex="-1"
355 href="${base}/${isTree ? "tree" : "blob"}/${encoded}/${target}"
356 >
357 <span class="row-lead">${icon(isTree ? "folder" : "file")}</span>
358 <span class="row-main"
359 ><span class="row-title">${entry.name}</span></span
360 >
361 ${when(
362 entry.size >= 0,
363 () =>
364 html`<span class="row-trail muted small num"
349 row({
350 href: `${base}/${isTree ? "tree" : "blob"}/${encoded}/${target}`,
351 lead: icon(isTree ? "folder" : "file"),
352 title: entry.name,
353 trail:
354 entry.size >= 0
355 ? html`<span class="muted small num"
365356 >${sizeWithTokens(entry.size, target)}</span
366 >`,
367 )}
368 </a>
369 </li>`,
357 >`
358 : html``,
359 nav: true,
360 data: { kind: entry.type },
361 }),
370362 );
371363 }
372 return html`${listCard(rows)}${directoryTotal(entries)}`;
364 const total = directoryTotal(entries);
365 return listCard(rows, total.text.trim() === "" ? {} : { foot: total });
373366 }
374367
375368 /**
@@ -390,13 +383,13 @@ export function directoryTotal(entries: readonly TreeEntry[]): Html {
390383 tokens += estimateTokens(entry.size, entry.name) ?? 0;
391384 }
392385 if (files === 0) return html``;
393 return html`<p
394 class="muted small num tree-total"
386 return html`<span
387 class="muted small num"
395388 title="Files at this level only; subdirectories are not counted"
396389 >
397390 ${files.toLocaleString("en-US")} file${files === 1 ? "" : "s"} here ·
398391 ${fileSize(bytes)} · ${tokenCount(tokens, "estimated")}
399 </p>`;
392 </span>`;
400393 }
401394
402395 /**
test/tree-listing.test.ts added +35
@@ -0,0 +1,35 @@
1 /** A directory listing is §5's rows and card foot, not page-local markup (#4164). */
2
3 import { describe, expect, test } from "bun:test";
4 import { treeListing } from "../src/web/pages/repo.ts";
5
6 const entries = [
7 { mode: "040000", type: "tree", sha: "a".repeat(40), size: -1, name: "src" },
8 { mode: "100644", type: "blob", sha: "b".repeat(40), size: 2048, name: "a<b>.md" },
9 { mode: "100644", type: "blob", sha: "c".repeat(40), size: 100, name: "x.ts" },
10 ] as const;
11
12 describe("treeListing", () => {
13 const out = treeListing("/o/r", "main", "lib", entries as never).text;
14
15 test("the page-local names are gone", () => {
16 expect(out).not.toContain("tree-row");
17 expect(out).not.toContain("tree-total");
18 });
19
20 test("rows, links, sizes and the total are all there", () => {
21 expect(out).toContain('class="row"');
22 expect(out).toContain('href="/o/r/tree/main/lib/src"');
23 expect(out).toContain('href="/o/r/blob/main/lib/x.ts"');
24 expect(out).toContain('href="/o/r/tree/main"'); // ..
25 expect(out).toContain("a&lt;b&gt;.md");
26 expect(out).toContain("row-trail");
27 expect(out).toContain('class="card-foot"');
28 expect(out).toMatch(/2 files here/);
29 });
30
31 test("no files, no foot", () => {
32 const none = treeListing("/o/r", "main", "", [entries[0]] as never).text;
33 expect(none).not.toContain("card-foot");
34 });
35 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs