// `outline.js`: folding a branch of an outline.
//
// The fixture is the shape `Row::depth` describes and `node.rs` emits: a flat
// list of `[data-row]` siblings, each carrying `data-depth`, each branch
// holding a `[data-disclose]` chevron. Nothing here builds a nested list,
// because the renderer does not emit one -- the hierarchy is the numbers.
//
// r0 depth 0
// r1 depth 1 <- a branch
// r2 depth 2
// r3 depth 2
// r4 depth 1 <- r1's sibling, not its descendant
/** The outline above, in the fixture. */
const outline = () =>
fixture(
`
`,
);
/** A row's chevron. */
const chevron = (id) => document.getElementById(id).querySelector("[data-disclose]");
/** Whether a row is out of the outline the reader is looking at. */
const gone = (id) => document.getElementById(id).hidden;
describe("outline.js, as shipped", () => {
beforeEach(outline);
it("hides a branch's descendants and leaves its siblings alone", () => {
chevron("r1").click();
expect(gone("r2"), "r2 is under r1").to.equal(true);
expect(gone("r3"), "r3 is under r1").to.equal(true);
expect(gone("r4"), "r4 is a sibling, not a descendant").to.equal(false);
});
it("keeps an inner shut branch shut when the outer one reopens", () => {
// The property `settle` is a walk rather than a row-by-row toggle for:
// a reader who left an inner branch shut expects to come back to it
// shut. `quasi_router::folded` makes the same reading on the server, so
// a reload has to agree with this.
chevron("r1").click();
chevron("r0").click();
expect(gone("r1"), "r1 is under r0").to.equal(true);
chevron("r0").click();
expect(gone("r1"), "r1 comes back").to.equal(false);
expect(gone("r2"), "r2 stays shut: r1 is still collapsed").to.equal(true);
expect(gone("r3"), "r3 stays shut").to.equal(true);
});
it("says which way the chevron points, in the two places a reader reads", () => {
const shut = chevron("r1");
shut.click();
expect(shut.getAttribute("aria-expanded")).to.equal("false");
expect(shut.getAttribute("aria-label")).to.equal("Expand");
shut.click();
expect(shut.getAttribute("aria-expanded")).to.equal("true");
expect(shut.getAttribute("aria-label")).to.equal("Collapse");
});
it("does not let the fold reach the row's own act", () => {
// A chevron is a separate hit target from the label precisely so that
// pressing it is not pressing the row. A row that activates on click
// would otherwise navigate out from under the fold.
let reached = 0;
const row = document.getElementById("r1");
row.addEventListener("click", () => { reached += 1; });
chevron("r1").click();
expect(reached, "the click stopped at the chevron").to.equal(0);
});
});