oficina / sheets Public

Clone
git clone https://amadan.net/oficina/sheets

Plain git — no account needed to clone.

Download

Download this file

1{{define "layout"}}<!doctype html>
2{{/* layout — every page's document: the head, the estilo bar and <main>.
3
4 The bar is estilo's (chrome.Bar, built once per request in
5 chrome.go), in place of the rastrillo topbar markup this file used to
6 write out itself: that bar was 45px signed out and 51px signed in,
7 because the Create and Import buttons were taller than it, so signing
8 in moved the whole page. estilo's is 52px at every width, signed in
9 or out, with the account always last in the same corner.
10
11 data-theme is written into the first bytes of the response, from a
12 cookie read server-side (chrome.Appearance). AGENTS.md: light/dark
13 must resolve before first paint, because cell fills resolve against
14 the theme and a late preference repaints every coloured cell. It is
15 ABSENT for "system", and that is the mechanism, not an omission:
16 theme.css's whole toggle is :root[data-theme="light"] and
17 :root[data-theme="dark"], and with no attribute the browser resolves
18 against the OS.
19
20 The <title> is built here and only here, "{part} · {part} · Sheets",
21 so no handler can drift from the suite's separator (spec §10).
22
23 <meta charset> comes first, before anything that could be read as
24 text. The stylesheets are in the suite's fixed order: tokens, theme,
25 brand, then estilo's base, menu and chrome, then the app's own. */}}
26<html lang="en" dir="ltr"{{with .Frame.Theme}} data-theme="{{.}}"{{end}}>
27<head>
28<meta charset="utf-8">
29<meta name="viewport" content="width=device-width, initial-scale=1">
30<title>{{range .Frame.TitleParts}}{{.}} · {{end}}{{.Frame.Chrome.App.Name}}</title>
31<link rel="icon" type="image/png" sizes="32x32" href="{{asset "static/brand/icon-32.png"}}">
32<link rel="icon" type="image/svg+xml" href="{{asset "static/brand/icon.svg"}}">
33<link rel="apple-touch-icon" sizes="180x180" href="{{asset "static/brand/apple-touch-icon.png"}}">
34<link rel="stylesheet" href="/static/estilo/fonts/v1/fonts.css">
35<link rel="stylesheet" href="{{asset "static/tokens.css"}}">
36<link rel="stylesheet" href="{{asset "static/estilo/busy.css"}}">
37<link rel="stylesheet" href="{{asset "static/theme.css"}}">
38<link rel="stylesheet" href="{{asset "static/brand/brand.css"}}">
39<link rel="stylesheet" href="{{asset "static/estilo/base.css"}}">
40<link rel="stylesheet" href="{{asset "static/estilo/menu.css"}}">
41<link rel="stylesheet" href="{{asset "static/estilo/chrome.css"}}">
42<link rel="stylesheet" href="{{asset "static/estilo/sky.css"}}">
43<link rel="stylesheet" href="{{asset "static/sheets.css"}}">
44{{/* First of every script: while a modal dialog is open, key and
45 clipboard events stop at the window before any page listener hears
46 them (static/modal.js). */}}
47<script defer src="{{asset "static/modal.js"}}"></script>
48<script defer src="{{asset "static/rastrillo.js"}}"></script>
49<script defer src="{{asset "static/estilo/busy.js"}}"></script>
50<script defer src="{{asset "static/estilo/chrome.js"}}"></script>
51{{iconAssets}}
52{{block "head" .}}{{end}}
53</head>
54<body>
55{{/* [estilo-shell] wraps every page. On the grid it is
56 estilo-shell="fill": exactly the viewport, the bar at its 52px and
57 the grid's <main> taking the rest (estilo chrome.css). That is why
58 the grid can fill the screen without this app subtracting a bar
59 height it would have to guess. The "main" block lets the grid page
60 supply its own <main>, without rst-page's padding and max width. */}}
61<div estilo-shell{{with .Frame.Shell}}="{{.}}"{{end}}>
62<a rst-skip href="#main">{{.Frame.Chrome.Labels.Skip}}</a>
63{{template "estilo-bar" .Frame.Chrome}}
64{{block "main" .}}<main rst-page id="main">{{template "content" .}}</main>{{end}}
65</div>
66{{if .Frame.Shortcuts}}{{template "shortcuts-dialog" .Frame.Keys}}{{end}}
67</body>
68</html>
69{{end}}
70
71{{/* The keyboard shortcuts, opened from the account menu's Help
72 ("Keyboard shortcuts…"). It used to be the Help menu on the grid's
73 menu bar, a definition list inside a dropdown; Help moved into the
74 account menu with every other app's (spec §8.2), and a list of keys
75 is not a menu. A native <dialog>, so it sits in the top layer above
76 the bar (spec §5.3), and it opens with the platform's invoker
77 command, so no script is needed. The labels are this request's
78 platform's (menu.Shortcut): ⌘Z on a Mac, Ctrl+Z elsewhere. */}}
79{{define "shortcuts-dialog"}}<dialog id="sheets-shortcuts" data-shortcuts aria-labelledby="sheets-shortcuts-title">
80<form method="dialog">
81<h2 id="sheets-shortcuts-title">Keyboard shortcuts</h2>
82<dl>
83<dt><kbd>{{.undo}}</kbd></dt><dd>Undo your last edit</dd>
84<dt><kbd>{{.bold}}</kbd></dt><dd>Bold</dd>
85<dt><kbd>{{.italic}}</kbd></dt><dd>Italic</dd>
86<dt><kbd>{{.cut}}</kbd></dt><dd>Cut</dd>
87<dt><kbd>{{.copy}}</kbd></dt><dd>Copy</dd>
88<dt><kbd>{{.paste}}</kbd></dt><dd>Paste</dd>
89<dt><kbd>{{.filldown}}</kbd></dt><dd>Fill down</dd>
90<dt><kbd>{{.delete}}</kbd></dt><dd>Clear the selected cells</dd>
91<dt><kbd>{{.enter}}</kbd></dt><dd>Commit and move down</dd>
92<dt><kbd>{{.tab}}</kbd></dt><dd>Commit and move right</dd>
93<dt><kbd>{{.esc}}</kbd></dt><dd>Abandon the edit</dd>
94</dl>
95<div data-shortcuts-foot><button rst-btn="primary" type="submit" autofocus>Done</button></div>
96</form>
97</dialog>{{end}}
98
99{{define "contrast-notice"}}
100{{if .}}
101{{/* Spec §11.1: a retained fill can be unreadable, and that is
102 correct. We render an imported file as authored — silently
103 correcting it would lie about the document — so the obligation
104 that follows is to say so and leave the decision to the person.
105 This is that, and it is deliberately a notice rather than a
106 change to any cell. A warning (the shared chrome spec's §4): it
107 used to say rst-callout="warn", which is no rastrillo tone, so it
108 rendered as a neutral grey note. */}}
109<div rst-callout rst-tone="warning">
110<span rst-callout-ic aria-hidden="true">{{icon "alert-triangle"}}</span>
111<div rst-callout-body>
112<p><strong>Imported colours below the contrast floor.</strong>
113These cells came from a file pairing a fill and a text colour under
114WCAG AA's 4.5:1: {{range $i, $ref := .}}{{if $i}}, {{end}}<code>{{$ref}}</code>{{end}}</p>
115<p>They are shown exactly as the file wrote them. Changing a colour is
116yours to decide, not ours to do quietly.</p>
117</div>
118</div>
119{{end}}
120{{end}}
121