Public: anyone can read this; the crew can change it.
An issue page with Edit open has no sideways scroll at 390px, with a look on the pull #10110
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/10074-an-issue-page-with-edit-open-has-no-side → main 3 commits fork
4 files
changed +25
−4
docs/design/areas/edit.md +2
| @@ -13,3 +13,5 @@ section keeps `.editor-commit` for its spacing). Field names and the `data-previ | ||
| 13 | 13 | |
| 14 | 14 | The issue page's folded Edit form is the same: plain title and body fields and Save, no box (`.card` and `.comment-form` |
| 15 | 15 | are gone from it), spaced like the home composer. It adds no component class. |
| 16 | ||
| 17 | With `?edit=1` the fold is drawn open (no script), which is what the preview's phone look of the issue page takes (#10074); `test/issue-fit.test.ts` holds it and measures no sideways scroll at 390 px. |
src/spawn/preview-looks.ts +4
| @@ -80,6 +80,9 @@ export const PREVIEW_NEXT_PAGE = `${PREVIEW_REPO_HOME}/next`; | ||
| 80 | 80 | /** The sample's first issue, whose long title and comments must wrap at a 390 px phone (#9384). */ |
| 81 | 81 | export const PREVIEW_ISSUE_PAGE = `${PREVIEW_REPO_HOME}/issues/1`; |
| 82 | 82 | |
| 83 | /** The same issue with its Edit fold open, for its phone look (#10074). */ | |
| 84 | export const PREVIEW_ISSUE_EDIT_PAGE = `${PREVIEW_ISSUE_PAGE}?edit=1`; | |
| 85 | ||
| 83 | 86 | /** The commits list, whose long messages must wrap at a 390 px phone (#9348). */ |
| 84 | 87 | export const PREVIEW_COMMITS_PAGE = `${PREVIEW_REPO_HOME}/commits`; |
| 85 | 88 | |
| @@ -137,6 +140,7 @@ export const PREVIEW_OWNER_LOOKS: readonly OwnerLook[] = [ | ||
| 137 | 140 | PREVIEW_COMMITS_PAGE, |
| 138 | 141 | PREVIEW_ISSUES_PAGE, |
| 139 | 142 | PREVIEW_ISSUE_PAGE, |
| 143 | PREVIEW_ISSUE_EDIT_PAGE, | |
| 140 | 144 | PREVIEW_RESILIENCE_PAGE, |
| 141 | 145 | PREVIEW_SEARCH_PAGE, |
| 142 | 146 | ...PREVIEW_SETTINGS_PAGES, |
src/web/pages/thread.ts +3 −3
| @@ -306,8 +306,8 @@ export interface ConversationOptions { | ||
| 306 | 306 | * the body as they stand, one form, one Save. Folded away until asked for, |
| 307 | 307 | * since most visits read and few rewrite. |
| 308 | 308 | */ |
| 309 | function editForm(issue: Issue, action: string): Html { | |
| 310 | return html`<details class="tl-edit" id="edit"> | |
| 309 | function editForm(issue: Issue, action: string, open: boolean): Html { | |
| 310 | return html`<details class="tl-edit" id="edit"${open ? html` open` : null}> | |
| 311 | 311 | <summary class="muted small">${icon("pencil")} Edit</summary> |
| 312 | 312 | <form class="mt" method="post" action="${action}"> |
| 313 | 313 | <label class="sr-only" for="edit-title">Title</label> |
| @@ -415,7 +415,7 @@ export function conversation( | ||
| 415 | 415 | return { |
| 416 | 416 | node: html`<div class="timeline" id="conversation"> |
| 417 | 417 | ${opening}${when(options.editAction, (action) => |
| 418 | editForm(issue, action), | |
| 418 | editForm(issue, action, ctx.url.searchParams.get("edit") === "1"), | |
| 419 | 419 | )}${planCard(ctx.app.db, issue)}${earlier}${shown.map((e) => e.node)} |
| 420 | 420 | </div>`, |
| 421 | 421 | lastCommentId: comments.length > 0 ? comments[comments.length - 1]!.id : "", |
test/issue-fit.test.ts +16 −1
| @@ -14,7 +14,7 @@ import { createApp, type App } from "../src/app.ts"; | ||
| 14 | 14 | import { createSession } from "../src/core/sessions.ts"; |
| 15 | 15 | import { createUser } from "../src/core/users.ts"; |
| 16 | 16 | import { serve, type Servers } from "../src/http/server.ts"; |
| 17 | import { PREVIEW_ISSUE_PAGE, PREVIEW_OWNER_LOOKS } from "../src/spawn/preview-looks.ts"; | |
| 17 | import { PREVIEW_ISSUE_EDIT_PAGE, PREVIEW_ISSUE_PAGE, PREVIEW_OWNER_LOOKS } from "../src/spawn/preview-looks.ts"; | |
| 18 | 18 | import { utilities as base } from "../src/web/style/base.ts"; |
| 19 | 19 | import { components } from "../src/web/style/components.ts"; |
| 20 | 20 | import { content } from "../src/web/style/content.ts"; |
| @@ -86,11 +86,26 @@ test("the owner's phone look takes an issue's page", () => { | ||
| 86 | 86 | expect(PREVIEW_OWNER_LOOKS).toContainEqual({ page: PREVIEW_ISSUE_PAGE, kind: "phone" }); |
| 87 | 87 | }); |
| 88 | 88 | |
| 89 | test("?edit=1 opens the Edit fold, and the phone look takes it (#10074)", async () => { | |
| 90 | const closed = await (await fetch(`${servers.url}/alice/fit/issues/1`, { headers: { cookie } })).text(); | |
| 91 | const open = await (await fetch(`${servers.url}/alice/fit/issues/1?edit=1`, { headers: { cookie } })).text(); | |
| 92 | expect(closed).toMatch(/<details class="tl-edit" id="edit"\s*>/); | |
| 93 | expect(open).toMatch(/<details class="tl-edit" id="edit" open\s*>/); | |
| 94 | expect(PREVIEW_OWNER_LOOKS).toContainEqual({ page: PREVIEW_ISSUE_EDIT_PAGE, kind: "phone" }); | |
| 95 | }); | |
| 96 | ||
| 89 | 97 | const found = findChromium(); |
| 90 | 98 | const chromium = found !== undefined && chromiumRuns(found) ? found : undefined; |
| 91 | 99 | if (chromium === undefined) console.log("SKIPPING: no chromium that starts here, so the issue page is not measured"); |
| 92 | 100 | |
| 93 | 101 | describe.skipIf(chromium === undefined)("measured at 390x844", () => { |
| 102 | test("no sideways scroll with Edit open", async () => { | |
| 103 | const measure = `(() => JSON.stringify({ scrollWidth: document.documentElement.scrollWidth, viewportWidth: document.documentElement.clientWidth, open: document.querySelector("#edit")?.open === true }))()`; | |
| 104 | const m = JSON.parse(await evaluateLoaded(chromium!, `${servers.url}/alice/fit/issues/1?edit=1`, { width: 390, height: 844 }, [{ name: "forge_session", value: cookie.split("=")[1]! }], measure)); | |
| 105 | expect(m.open).toBe(true); | |
| 106 | expect(m.scrollWidth).toBeLessThanOrEqual(m.viewportWidth); | |
| 107 | }, 30_000); | |
| 108 | ||
| 94 | 109 | test("no sideways scroll", async () => { |
| 95 | 110 | const measure = `(() => JSON.stringify({ scrollWidth: document.documentElement.scrollWidth, viewportWidth: document.documentElement.clientWidth, |
| 96 | 111 | comments: document.querySelectorAll(".comment").length }))()`; |