applet rows: hover + click-lock highlight on every .applet-list-entry.row-3col (My Posts / My Buds / My Notes / My Scrolls / My Games) — bg shifts to --secUser, title to --quiUser (overriding the inherited --terUser link color + stripping the text-shadow the global .applet-list-entry a:hover rule had been baking in), body + ts cells come up from their dimmed 0.6 / 0.5 opacity to full --priUser so the dim middle/right cols pop against the --secUser fill; new apps/applets/static/apps/applets/row-lock.js IIFE module owns the touch-persistence state machine (single _lockedRow ref, .row-locked class toggle): clicking a row not currently locked → locks (clearing any prior lock); clicking the locked row again → unlocks; clicking another row → moves the lock to the new row; clicking anywhere not inside a .row-3col → clears the lock — mirrors the note-page notes-locked click-lock state machine but lighter (no DON/DOFF, no greeting swap, no fetch), one document-level click listener bound once via _bound re-entry guard so beforeEach _init() calls in specs don't pile up handlers; loaded globally via base.html next to applets.js since the rows render on both /billboard/ + /gameboard/; padding-inline 0.5rem + border-radius 0.25rem on the row container shrinks the highlight to a chip shape so hovered rows don't bleed all the way to the applet box edge; 6 Jasmine specs in RowLockSpec.js cover the four state-machine transitions + the "child element of row still locks the parent row" affordance (since the user can tap the body cell text, not just the title link) + the "only one row carries .row-locked at a time" invariant; SpecRunner.html updated (both static_src + the static/ runtime mirror the FT reads from per the project's static-src→static copy discipline) — TDD

Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-05-13 00:27:39 -04:00
parent b2f1511c2d
commit e2040fda8f
7 changed files with 222 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
describe("RowLock", () => {
let fixture, row1, row2;
function makeRow(label) {
const li = document.createElement("li");
li.className = "applet-list-entry row-3col";
li.innerHTML = `
<a class="row-title" href="#">${label}</a>
<span class="row-body">body</span>
<time class="row-ts">ts</time>
`;
return li;
}
beforeEach(() => {
RowLock._testReset();
fixture = document.createElement("ul");
fixture.className = "applet-list";
row1 = makeRow("Row 1");
row2 = makeRow("Row 2");
fixture.appendChild(row1);
fixture.appendChild(row2);
document.body.appendChild(fixture);
RowLock._init();
});
afterEach(() => {
RowLock._testReset();
fixture.remove();
});
it("clicking a row adds .row-locked", () => {
row1.click();
expect(row1.classList.contains("row-locked")).toBe(true);
});
it("clicking the same row again clears the lock", () => {
row1.click();
row1.click();
expect(row1.classList.contains("row-locked")).toBe(false);
});
it("clicking a different row moves the lock", () => {
row1.click();
row2.click();
expect(row1.classList.contains("row-locked")).toBe(false);
expect(row2.classList.contains("row-locked")).toBe(true);
});
it("clicking outside any row clears the lock", () => {
row1.click();
document.body.click();
expect(row1.classList.contains("row-locked")).toBe(false);
});
it("clicking a child element of the row still locks the row", () => {
const body = row1.querySelector(".row-body");
body.click();
expect(row1.classList.contains("row-locked")).toBe(true);
});
it("only one row carries .row-locked at a time", () => {
row1.click();
row2.click();
const locked = document.querySelectorAll(".applet-list-entry.row-3col.row-locked");
expect(locked.length).toBe(1);
});
});

View File

@@ -28,7 +28,9 @@
<script src="SkyWheelSpec.js"></script>
<script src="NoteSpec.js"></script>
<script src="NotePageSpec.js"></script>
<script src="RowLockSpec.js"></script>
<!-- src files -->
<script src="/static/apps/applets/row-lock.js"></script>
<script src="/static/apps/dashboard/dashboard.js"></script>
<script src="/static/apps/dashboard/note.js"></script>
<script src="/static/apps/billboard/note-page.js"></script>