@issuegraph/editor 0.10.0 → 0.22.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -7
- package/dist/a11y/baseline.d.ts.map +1 -1
- package/dist/a11y/baseline.js +4 -0
- package/dist/a11y/baseline.js.map +1 -1
- package/dist/audit/findings.d.ts +107 -1
- package/dist/audit/findings.d.ts.map +1 -1
- package/dist/audit/findings.js +113 -6
- package/dist/audit/findings.js.map +1 -1
- package/dist/audit/panel.d.ts +277 -0
- package/dist/audit/panel.d.ts.map +1 -0
- package/dist/audit/panel.js +462 -0
- package/dist/audit/panel.js.map +1 -0
- package/dist/audit/refused.d.ts +99 -0
- package/dist/audit/refused.d.ts.map +1 -0
- package/dist/audit/refused.js +276 -0
- package/dist/audit/refused.js.map +1 -0
- package/dist/audit/styles.d.ts +1 -1
- package/dist/audit/styles.d.ts.map +1 -1
- package/dist/audit/styles.js +428 -0
- package/dist/audit/styles.js.map +1 -1
- package/dist/audit/surface.d.ts +54 -12
- package/dist/audit/surface.d.ts.map +1 -1
- package/dist/audit/surface.js +53 -13
- package/dist/audit/surface.js.map +1 -1
- package/dist/create/draft.d.ts +19 -0
- package/dist/create/draft.d.ts.map +1 -1
- package/dist/create/draft.js +21 -0
- package/dist/create/draft.js.map +1 -1
- package/dist/create/keys.d.ts +68 -8
- package/dist/create/keys.d.ts.map +1 -1
- package/dist/create/keys.js +43 -5
- package/dist/create/keys.js.map +1 -1
- package/dist/index.d.ts +38 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -13
- package/dist/index.js.map +1 -1
- package/dist/overlay/render.d.ts +11 -3
- package/dist/overlay/render.d.ts.map +1 -1
- package/dist/overlay/render.js +22 -6
- package/dist/overlay/render.js.map +1 -1
- package/dist/overlay/request.d.ts +71 -0
- package/dist/overlay/request.d.ts.map +1 -0
- package/dist/overlay/request.js +129 -0
- package/dist/overlay/request.js.map +1 -0
- package/dist/overlay/styles.d.ts +1 -1
- package/dist/overlay/styles.d.ts.map +1 -1
- package/dist/overlay/styles.js +38 -7
- package/dist/overlay/styles.js.map +1 -1
- package/dist/reevaluate/parts.d.ts +130 -0
- package/dist/reevaluate/parts.d.ts.map +1 -0
- package/dist/reevaluate/parts.js +260 -0
- package/dist/reevaluate/parts.js.map +1 -0
- package/dist/reevaluate/render.d.ts +18 -11
- package/dist/reevaluate/render.d.ts.map +1 -1
- package/dist/reevaluate/render.js +21 -135
- package/dist/reevaluate/render.js.map +1 -1
- package/dist/reevaluate/styles.d.ts +1 -1
- package/dist/reevaluate/styles.d.ts.map +1 -1
- package/dist/reevaluate/styles.js +26 -0
- package/dist/reevaluate/styles.js.map +1 -1
- package/dist/reevaluate/view.d.ts +16 -1
- package/dist/reevaluate/view.d.ts.map +1 -1
- package/dist/reevaluate/view.js +21 -1
- package/dist/reevaluate/view.js.map +1 -1
- package/dist/reevaluate/words.d.ts +7 -0
- package/dist/reevaluate/words.d.ts.map +1 -1
- package/dist/scale/ladder.d.ts +62 -6
- package/dist/scale/ladder.d.ts.map +1 -1
- package/dist/scale/ladder.js +119 -8
- package/dist/scale/ladder.js.map +1 -1
- package/dist/scale/render.d.ts +44 -0
- package/dist/scale/render.d.ts.map +1 -1
- package/dist/scale/render.js +197 -27
- package/dist/scale/render.js.map +1 -1
- package/dist/scale/styles.d.ts +11 -5
- package/dist/scale/styles.d.ts.map +1 -1
- package/dist/scale/styles.js +133 -4
- package/dist/scale/styles.js.map +1 -1
- package/dist/workspace/host.d.ts +83 -1
- package/dist/workspace/host.d.ts.map +1 -1
- package/dist/workspace/host.js +197 -4
- package/dist/workspace/host.js.map +1 -1
- package/dist/workspace/inspector.d.ts +33 -7
- package/dist/workspace/inspector.d.ts.map +1 -1
- package/dist/workspace/inspector.js +15 -0
- package/dist/workspace/inspector.js.map +1 -1
- package/dist/workspace/mount.d.ts +23 -1
- package/dist/workspace/mount.d.ts.map +1 -1
- package/dist/workspace/mount.js +500 -17
- package/dist/workspace/mount.js.map +1 -1
- package/dist/workspace/rail.d.ts +5 -2
- package/dist/workspace/rail.d.ts.map +1 -1
- package/dist/workspace/rail.js.map +1 -1
- package/dist/workspace/render.d.ts +379 -3
- package/dist/workspace/render.d.ts.map +1 -1
- package/dist/workspace/render.js +893 -133
- package/dist/workspace/render.js.map +1 -1
- package/dist/workspace/selection.d.ts +11 -0
- package/dist/workspace/selection.d.ts.map +1 -1
- package/dist/workspace/selection.js +10 -0
- package/dist/workspace/selection.js.map +1 -1
- package/dist/workspace/styles.d.ts +1 -1
- package/dist/workspace/styles.d.ts.map +1 -1
- package/dist/workspace/styles.js +868 -18
- package/dist/workspace/styles.js.map +1 -1
- package/package.json +3 -3
package/dist/audit/styles.js
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
* There is no transition, no animation and no `@keyframes` here, and there is a
|
|
34
34
|
* test that says so.
|
|
35
35
|
*/
|
|
36
|
+
import { AUDIT_KIND_ATTRIBUTE } from "./panel.js";
|
|
36
37
|
import { AUDIT_SEVERITY_ATTRIBUTE } from "./surface.js";
|
|
37
38
|
export const auditStylesheet = `
|
|
38
39
|
.ig-audit {
|
|
@@ -68,5 +69,432 @@ export const auditStylesheet = `
|
|
|
68
69
|
[${AUDIT_SEVERITY_ATTRIBUTE}] {
|
|
69
70
|
box-shadow: inset var(--ig-stroke-audit) 0 0 0 var(--ig-edge-serialize-with);
|
|
70
71
|
}
|
|
72
|
+
|
|
73
|
+
/* §17d'S PANEL. Note what it does NOT select on: ${AUDIT_SEVERITY_ATTRIBUTE},
|
|
74
|
+
whose rule immediately above is deliberately unqualified because it lands on a
|
|
75
|
+
row the VIEWER rendered. A chip wearing that attribute would draw the rail's
|
|
76
|
+
gold bar whatever hue the class table gave it, which is the four-hue mapping
|
|
77
|
+
below defeated by one attribute. Chips carry ${AUDIT_KIND_ATTRIBUTE}. */
|
|
78
|
+
/* IT IS THE SELECTION'S PEER, NOT ITS HEADING, so it carries its own padding:
|
|
79
|
+
it is a sibling of .ig-inspector inside the zone rather than a child, and
|
|
80
|
+
that column's padding does not reach it.
|
|
81
|
+
|
|
82
|
+
IT DECLARES NO SIZE OF ITS OWN, AND THAT IS THE LAYERING. Issue 177 gave the
|
|
83
|
+
audit half the inspector column, scrolling itself past that — and since the
|
|
84
|
+
fourth class moved to ./refused.ts the half belongs to the REGION holding both
|
|
85
|
+
surfaces rather than to this panel. Either way it is a fact about SHARING A
|
|
86
|
+
COLUMN, not a fact about the panel, so it is declared by the composition that
|
|
87
|
+
owns the zone. See workspace/styles.ts.
|
|
88
|
+
|
|
89
|
+
The difference is reachable rather than theoretical: renderAuditPanel and
|
|
90
|
+
this stylesheet are both public exports, so a consumer can draw the panel
|
|
91
|
+
outside renderWorkspace. Capping it there would hide findings behind an inner
|
|
92
|
+
scrollbar with half the container left empty and no selection detail to
|
|
93
|
+
reserve the space for. A leaf that sized itself would be wrong in every
|
|
94
|
+
composition but one. */
|
|
95
|
+
.ig-audit-panel {
|
|
96
|
+
border-bottom: var(--ig-stroke) solid var(--ig-line);
|
|
97
|
+
display: flex;
|
|
98
|
+
flex-direction: column;
|
|
99
|
+
font-family: var(--ig-font-ui);
|
|
100
|
+
gap: var(--ig-space-snug);
|
|
101
|
+
min-height: 0;
|
|
102
|
+
padding: var(--ig-space);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* THE RING FOR THE PANEL'S OWN TAB STOP. Unscoped, unlike the sizing above,
|
|
106
|
+
because the tabindex is in this leaf's MARKUP and is therefore carried into
|
|
107
|
+
every composition: a focusable element that shows nothing on focus is a stop
|
|
108
|
+
a keyboard reader lands on blind, wherever it is drawn.
|
|
109
|
+
|
|
110
|
+
INSET, WHICH IS THE VIEWER'S OWN IDIOM for exactly this shape — its sheet
|
|
111
|
+
draws every focus ring at a negative offset. Drawn outward it would sit on
|
|
112
|
+
the panel's border box against the zone's edge and the column's own scroll,
|
|
113
|
+
where the top and bottom of the ring are the first thing clipped. */
|
|
114
|
+
.ig-audit-panel:focus-visible {
|
|
115
|
+
outline: var(--ig-focus-ring) solid var(--ig-focus);
|
|
116
|
+
outline-offset: calc(var(--ig-focus-ring) * -1);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.ig-audit-panel-head {
|
|
120
|
+
align-items: center;
|
|
121
|
+
display: flex;
|
|
122
|
+
gap: var(--ig-space-tight);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* THE GOLD IS THE AMBIENT MARK'S, not a fifth hue. §17d names one attention
|
|
126
|
+
colour and the rail bar already spends it; the panel head answering in the
|
|
127
|
+
same gold is what makes the count and the list read as one thing. */
|
|
128
|
+
.ig-audit-mark {
|
|
129
|
+
color: var(--ig-edge-serialize-with);
|
|
130
|
+
font-size: var(--ig-font-size-small);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.ig-audit-panel-count {
|
|
134
|
+
color: var(--ig-edge-serialize-with);
|
|
135
|
+
font-family: var(--ig-font-mono);
|
|
136
|
+
font-size: var(--ig-font-size-small);
|
|
137
|
+
font-variant-numeric: tabular-nums;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.ig-audit-panel-heading {
|
|
141
|
+
color: var(--ig-edge-serialize-with);
|
|
142
|
+
font-weight: inherit;
|
|
143
|
+
margin: 0;
|
|
144
|
+
font-family: var(--ig-font-mono);
|
|
145
|
+
font-size: var(--ig-font-size-small);
|
|
146
|
+
letter-spacing: var(--ig-tracking-group);
|
|
147
|
+
text-transform: uppercase;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* NO CAP ON THE LIST, AND THAT IS STILL RIGHT — the bound belongs to the PANEL
|
|
151
|
+
above, not here. Three caps were tried on this element (a fixed length, a
|
|
152
|
+
share of a flex column, that share measured on the right box) and each was
|
|
153
|
+
correct about the previous one's defect while the column stayed the thing
|
|
154
|
+
that could not be bounded from in here. It still cannot: the list has no
|
|
155
|
+
padding, so a scroll container here computes overflow-x to auto and clips the
|
|
156
|
+
focus ring on every card control. The panel carries the share and the
|
|
157
|
+
scrolling; see the rule above. */
|
|
158
|
+
.ig-audit-list {
|
|
159
|
+
display: flex;
|
|
160
|
+
flex-direction: column;
|
|
161
|
+
gap: var(--ig-space-snug);
|
|
162
|
+
list-style: none;
|
|
163
|
+
margin: 0;
|
|
164
|
+
padding: 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.ig-audit-card {
|
|
168
|
+
display: flex;
|
|
169
|
+
flex-direction: column;
|
|
170
|
+
gap: var(--ig-space-micro);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.ig-audit-chip {
|
|
174
|
+
align-self: flex-start;
|
|
175
|
+
border: var(--ig-stroke) solid var(--ig-line);
|
|
176
|
+
border-radius: var(--ig-radius-small);
|
|
177
|
+
font-family: var(--ig-font-mono);
|
|
178
|
+
font-size: var(--ig-font-size-pill);
|
|
179
|
+
padding: 0 var(--ig-space-tight);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.ig-audit-title {
|
|
183
|
+
color: var(--ig-text);
|
|
184
|
+
font-size: var(--ig-font-size);
|
|
185
|
+
margin: 0;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* SENTENCE-LENGTH COPY TAKES --ig-text-body, NEVER --ig-text-muted. SPEC's
|
|
189
|
+
closing note measures muted at 4.65:1 on a plain surface and about 0.4 less
|
|
190
|
+
inside a tint, which drops it under AA — so muted is reserved there for short
|
|
191
|
+
mono labels, and a finding's detail is a sentence. */
|
|
192
|
+
.ig-audit-detail {
|
|
193
|
+
color: var(--ig-text-body);
|
|
194
|
+
font-size: var(--ig-font-size-compact);
|
|
195
|
+
line-height: var(--ig-line-height);
|
|
196
|
+
margin: 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* MUTED IS CORRECT HERE, ON THE SAME RULE .ig-audit-refused-source ends this
|
|
200
|
+
file with: the note above reserves muted for SHORT MONO LABELS, and a cycle's
|
|
201
|
+
walk is one — refs and separators, no prose. Length is not the test and could
|
|
202
|
+
not be: a large ring draws a long line, which is what the wrap below is for.
|
|
203
|
+
What muted is reserved AGAINST is sentence-length COPY. The detail rule one block up takes --ig-text-body because it IS a
|
|
204
|
+
sentence, so it is the wrong neighbour to copy.
|
|
205
|
+
|
|
206
|
+
break-word, NOT anywhere. A ref is a token worth keeping whole; the refused
|
|
207
|
+
block accepts mid-token breaks because it quotes arbitrary body text, and a
|
|
208
|
+
walk is a list of identifiers a reader has to be able to match against the
|
|
209
|
+
rail. */
|
|
210
|
+
.ig-audit-walk {
|
|
211
|
+
color: var(--ig-text-muted);
|
|
212
|
+
font-family: var(--ig-font-mono);
|
|
213
|
+
font-size: var(--ig-font-size-compact);
|
|
214
|
+
line-height: var(--ig-line-height);
|
|
215
|
+
margin: 0;
|
|
216
|
+
overflow-wrap: break-word;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.ig-audit-show {
|
|
220
|
+
align-self: flex-start;
|
|
221
|
+
background: none;
|
|
222
|
+
border: var(--ig-stroke) solid var(--ig-line);
|
|
223
|
+
border-radius: var(--ig-radius-small);
|
|
224
|
+
color: var(--ig-text);
|
|
225
|
+
cursor: pointer;
|
|
226
|
+
font: inherit;
|
|
227
|
+
font-size: var(--ig-font-size-meta);
|
|
228
|
+
padding: var(--ig-space-micro) var(--ig-space-tight);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.ig-audit-show:hover {
|
|
232
|
+
border-color: var(--ig-accent);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.ig-audit-show:focus-visible {
|
|
236
|
+
outline: var(--ig-focus-ring) solid var(--ig-focus);
|
|
237
|
+
outline-offset: var(--ig-space-micro);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* 17d'S REMEDIES. A row of them under the card's sentence.
|
|
241
|
+
|
|
242
|
+
THEY TAKE THE SAME CHROME AS .ig-audit-show DELIBERATELY. A remedy and the
|
|
243
|
+
navigation control beside it do the same KIND of thing — both publish a
|
|
244
|
+
selection and neither writes — so drawing the remedies louder would promise
|
|
245
|
+
an action they do not perform. 3's whole point is that the judgment stays
|
|
246
|
+
with the owner, and a button styled like a commit invites a click that is
|
|
247
|
+
not one.
|
|
248
|
+
|
|
249
|
+
WRAPS, because the stale card carries two of them inside a panel of fixed
|
|
250
|
+
width whose cards also indent. A row that cannot wrap pushes its second
|
|
251
|
+
control out of the panel, which is the shape the relationship row one sheet
|
|
252
|
+
over already had to solve. (Worded around two particular verbs on purpose:
|
|
253
|
+
acceptance scans this sheet's PROSE as well as its declarations for the
|
|
254
|
+
vocabulary of a remedy that acts by itself, and it cannot tell a comment
|
|
255
|
+
from a control. Both spellings of that idea are therefore unusable here,
|
|
256
|
+
including in a note explaining why.)
|
|
257
|
+
|
|
258
|
+
(The width itself is 3's number and lives in workspace/styles.ts, where the
|
|
259
|
+
overlay is positioned. Naming it here would put a length in a sheet whose
|
|
260
|
+
own guard reads comments as well as declarations - which is how this
|
|
261
|
+
paragraph was first written, and caught.) */
|
|
262
|
+
.ig-audit-remedies {
|
|
263
|
+
display: flex;
|
|
264
|
+
flex-wrap: wrap;
|
|
265
|
+
gap: var(--ig-space-tight);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.ig-audit-remedy {
|
|
269
|
+
background: none;
|
|
270
|
+
border: var(--ig-stroke) solid var(--ig-line);
|
|
271
|
+
border-radius: var(--ig-radius-small);
|
|
272
|
+
color: var(--ig-text);
|
|
273
|
+
cursor: pointer;
|
|
274
|
+
font: inherit;
|
|
275
|
+
font-size: var(--ig-font-size-meta);
|
|
276
|
+
padding: var(--ig-space-micro) var(--ig-space-tight);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.ig-audit-remedy:hover {
|
|
280
|
+
border-color: var(--ig-accent);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.ig-audit-remedy:focus-visible {
|
|
284
|
+
outline: var(--ig-focus-ring) solid var(--ig-focus);
|
|
285
|
+
outline-offset: var(--ig-space-micro);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* 17d'S OWN ENTRY POINT - 'filter the rail to these' - in the panel head.
|
|
289
|
+
|
|
290
|
+
IT SITS AT THE END OF THE HEAD ROW, after the count and the heading, which is
|
|
291
|
+
where the frame draws it. margin-inline-start: auto rather than a width on
|
|
292
|
+
the heading, so the head stays one flex row whatever the host's word is.
|
|
293
|
+
|
|
294
|
+
aria-pressed IS STYLED, NOT JUST PUBLISHED. 2's ruling is that a filter
|
|
295
|
+
which is visibly on, states what it hides and clears in one click is not a
|
|
296
|
+
refusal - so 'visibly on' is a requirement here rather than a nicety. */
|
|
297
|
+
.ig-audit-filter {
|
|
298
|
+
background: none;
|
|
299
|
+
border: var(--ig-stroke) solid var(--ig-line);
|
|
300
|
+
border-radius: var(--ig-radius-small);
|
|
301
|
+
color: var(--ig-text-muted);
|
|
302
|
+
cursor: pointer;
|
|
303
|
+
font: inherit;
|
|
304
|
+
font-size: var(--ig-font-size-meta);
|
|
305
|
+
margin-inline-start: auto;
|
|
306
|
+
padding: var(--ig-space-micro) var(--ig-space-tight);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.ig-audit-filter[aria-pressed='true'] {
|
|
310
|
+
border-color: var(--ig-accent);
|
|
311
|
+
color: var(--ig-accent);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.ig-audit-filter:focus-visible {
|
|
315
|
+
outline: var(--ig-focus-ring) solid var(--ig-focus);
|
|
316
|
+
outline-offset: var(--ig-space-micro);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/* ONE RULE PER CLASS, WRITTEN OUT, never through an intermediate property: the
|
|
320
|
+
viewer's own badge sheet records why — a \--ig-audit-hue\ set here and read
|
|
321
|
+
here names something no theme and no layout declares, and the token scan
|
|
322
|
+
exists to refuse exactly that.
|
|
323
|
+
|
|
324
|
+
THE TINTS ARE THE VIEWER'S RECIPE, not new numbers. \--ig-tint-fill\ and
|
|
325
|
+
\--ig-tint-border\ are what \.ig-badge[data-edge]\ already mixes an edge hue
|
|
326
|
+
with, and they are the frame's own chip wash to within a point.
|
|
327
|
+
|
|
328
|
+
THE TEXT IS THE BASE HUE. The frame lightens each chip's label a step off the
|
|
329
|
+
hue it tints with; those derivatives have no token, and a literal here is
|
|
330
|
+
refused by the scan two files over, so the label takes the hue itself. */
|
|
331
|
+
.ig-audit-chip[${AUDIT_KIND_ATTRIBUTE}='cycle'] {
|
|
332
|
+
background: color-mix(in srgb, var(--ig-edge-blocked-by) var(--ig-tint-fill), transparent);
|
|
333
|
+
border-color: color-mix(in srgb, var(--ig-edge-blocked-by) var(--ig-tint-border), transparent);
|
|
334
|
+
color: var(--ig-edge-blocked-by);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
.ig-audit-chip[${AUDIT_KIND_ATTRIBUTE}='stale-blocker'] {
|
|
338
|
+
background: color-mix(in srgb, var(--ig-edge-serialize-with) var(--ig-tint-fill), transparent);
|
|
339
|
+
border-color: color-mix(in srgb, var(--ig-edge-serialize-with) var(--ig-tint-border), transparent);
|
|
340
|
+
color: var(--ig-edge-serialize-with);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.ig-audit-chip[${AUDIT_KIND_ATTRIBUTE}='dead-duplicate-ref'] {
|
|
344
|
+
background: color-mix(in srgb, var(--ig-edge-duplicate-of) var(--ig-tint-fill), transparent);
|
|
345
|
+
border-color: color-mix(in srgb, var(--ig-edge-duplicate-of) var(--ig-tint-border), transparent);
|
|
346
|
+
color: var(--ig-edge-duplicate-of);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.ig-audit-chip[${AUDIT_KIND_ATTRIBUTE}='encoding-refused'] {
|
|
350
|
+
background: color-mix(in srgb, var(--ig-edge-blocked-by) var(--ig-tint-fill), transparent);
|
|
351
|
+
border-color: color-mix(in srgb, var(--ig-edge-blocked-by) var(--ig-tint-border), transparent);
|
|
352
|
+
color: var(--ig-edge-blocked-by);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/* ---- §17d's fourth class, drawn outside the panel (./refused.ts) ---- */
|
|
356
|
+
|
|
357
|
+
/* NO SIZE OF ITS OWN, THE SAME ANSWER .ig-audit-panel GIVES ABOVE. This block
|
|
358
|
+
and that panel are the two members of .ig-audit-overlay, which is what the
|
|
359
|
+
inspector zone actually holds, and how much of the zone's single track that
|
|
360
|
+
region may take is a fact about SHARING A COLUMN rather than a fact about
|
|
361
|
+
either leaf. So the share is declared once by the composition that owns the
|
|
362
|
+
zone — see workspace/styles.ts, which bounds the region alone. */
|
|
363
|
+
.ig-audit-refused {
|
|
364
|
+
display: flex;
|
|
365
|
+
flex-direction: column;
|
|
366
|
+
font-family: var(--ig-font-ui);
|
|
367
|
+
gap: var(--ig-space-snug);
|
|
368
|
+
min-height: 0;
|
|
369
|
+
padding: var(--ig-space);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/* THE RING FOR THIS BLOCK'S TAB STOP, unscoped for the reason the panel's is:
|
|
373
|
+
the tabindex is in this leaf's MARKUP, so it is carried into every
|
|
374
|
+
composition, and a focusable element that shows nothing on focus is a stop a
|
|
375
|
+
keyboard reader lands on blind. Inset, the viewer's idiom, so a ring at the
|
|
376
|
+
zone's edge is not the first thing the column's scroll clips. */
|
|
377
|
+
.ig-audit-refused:focus-visible {
|
|
378
|
+
outline: var(--ig-focus-ring) solid var(--ig-focus);
|
|
379
|
+
outline-offset: calc(var(--ig-focus-ring) * -1);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/* THE SAME HEADING TREATMENT AS THE PANEL'S, because they are peers in one
|
|
383
|
+
column and §17d draws them as one section. A second treatment would say they
|
|
384
|
+
were two unrelated things. */
|
|
385
|
+
.ig-audit-refused-heading {
|
|
386
|
+
color: var(--ig-edge-blocked-by);
|
|
387
|
+
font-family: var(--ig-font-mono);
|
|
388
|
+
font-size: var(--ig-font-size-small);
|
|
389
|
+
font-weight: inherit;
|
|
390
|
+
letter-spacing: var(--ig-tracking-group);
|
|
391
|
+
margin: 0;
|
|
392
|
+
text-transform: uppercase;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.ig-audit-refused-list {
|
|
396
|
+
display: flex;
|
|
397
|
+
flex-direction: column;
|
|
398
|
+
gap: var(--ig-space-snug);
|
|
399
|
+
list-style: none;
|
|
400
|
+
margin: 0;
|
|
401
|
+
padding: 0;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/* THE CARD IS DRAWN, UNLIKE THE PANEL'S. The frame gives this one a surface and
|
|
405
|
+
a border because it sits alone rather than in a list of like items — it is
|
|
406
|
+
the one finding that is about an ISSUE rather than a relationship, and the
|
|
407
|
+
box is what says so. */
|
|
408
|
+
.ig-audit-refused-card {
|
|
409
|
+
background: var(--ig-surface-2);
|
|
410
|
+
border: var(--ig-stroke) solid var(--ig-card-line);
|
|
411
|
+
border-radius: var(--ig-radius);
|
|
412
|
+
display: flex;
|
|
413
|
+
flex-direction: column;
|
|
414
|
+
gap: var(--ig-space-tight);
|
|
415
|
+
padding: var(--ig-space-tight);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.ig-audit-refused-head {
|
|
419
|
+
align-items: center;
|
|
420
|
+
display: flex;
|
|
421
|
+
gap: var(--ig-space-tight);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.ig-audit-refused-ref {
|
|
425
|
+
color: var(--ig-text);
|
|
426
|
+
font-family: var(--ig-font-mono);
|
|
427
|
+
font-size: var(--ig-font-size-meta);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/* ONE BLOCK, TWO LINES — the diagnostic and, under it, the line the reader
|
|
431
|
+
stopped on. pre-wrap because the source line is RAW BODY TEXT: it carries
|
|
432
|
+
its own leading space and its own length, and collapsing either would show a
|
|
433
|
+
reader something other than what is in their issue. overflow-wrap keeps a
|
|
434
|
+
long unbroken line inside the column instead of widening the track. */
|
|
435
|
+
.ig-audit-refused-reason {
|
|
436
|
+
display: flex;
|
|
437
|
+
flex-direction: column;
|
|
438
|
+
font-family: var(--ig-font-mono);
|
|
439
|
+
font-size: var(--ig-font-size-meta);
|
|
440
|
+
gap: var(--ig-space-micro);
|
|
441
|
+
overflow-wrap: anywhere;
|
|
442
|
+
white-space: pre-wrap;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
.ig-audit-refused-diagnostic {
|
|
446
|
+
color: var(--ig-text-body);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/* MUTED IS CORRECT HERE AND NOWHERE NEAR A SENTENCE. SPEC's closing note puts
|
|
450
|
+
muted under AA for sentence-length copy, which is why .ig-audit-detail
|
|
451
|
+
takes --ig-text-body — but this is a short mono quotation of the reader's own
|
|
452
|
+
input, the exact shape muted is reserved for, and the frame draws it a step
|
|
453
|
+
back from the diagnostic it belongs to. */
|
|
454
|
+
.ig-audit-refused-source {
|
|
455
|
+
color: var(--ig-text-muted);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.ig-audit-refused-controls {
|
|
459
|
+
display: flex;
|
|
460
|
+
flex-wrap: wrap;
|
|
461
|
+
gap: var(--ig-space-tight);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/* ONE TREATMENT FOR BOTH CONTROLS, THOUGH ONE IS AN ANCHOR AND ONE A BUTTON.
|
|
465
|
+
The element differs because what they DO differs — the link leaves the
|
|
466
|
+
document and must say so to assistive technology — but they sit side by side
|
|
467
|
+
in the frame as one pair of moves, and drawing them differently would imply a
|
|
468
|
+
difference in weight that §17d does not make. */
|
|
469
|
+
.ig-audit-refused-open,
|
|
470
|
+
.ig-audit-refused-rewrite {
|
|
471
|
+
align-items: center;
|
|
472
|
+
background: none;
|
|
473
|
+
border: var(--ig-stroke) solid var(--ig-line);
|
|
474
|
+
border-radius: var(--ig-radius-small);
|
|
475
|
+
color: var(--ig-text);
|
|
476
|
+
cursor: pointer;
|
|
477
|
+
display: inline-flex;
|
|
478
|
+
font: inherit;
|
|
479
|
+
font-size: var(--ig-font-size-meta);
|
|
480
|
+
gap: var(--ig-space-micro);
|
|
481
|
+
padding: var(--ig-space-micro) var(--ig-space-tight);
|
|
482
|
+
text-decoration: none;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.ig-audit-refused-open:hover,
|
|
486
|
+
.ig-audit-refused-rewrite:hover {
|
|
487
|
+
border-color: var(--ig-accent);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
.ig-audit-refused-open:focus-visible,
|
|
491
|
+
.ig-audit-refused-rewrite:focus-visible {
|
|
492
|
+
outline: var(--ig-focus-ring) solid var(--ig-focus);
|
|
493
|
+
outline-offset: var(--ig-space-micro);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.ig-audit-refused-away {
|
|
497
|
+
color: var(--ig-text-muted);
|
|
498
|
+
}
|
|
71
499
|
`;
|
|
72
500
|
//# sourceMappingURL=styles.js.map
|
package/dist/audit/styles.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/audit/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAExD,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+B5B,wBAAwB
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/audit/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAExD,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+B5B,wBAAwB;;;;oDAIyB,wBAAwB;;;;kDAI1B,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8PrD,oBAAoB;;;;;;iBAMpB,oBAAoB;;;;;;iBAMpB,oBAAoB;;;;;;iBAMpB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsJpC,CAAC"}
|
package/dist/audit/surface.d.ts
CHANGED
|
@@ -17,10 +17,16 @@
|
|
|
17
17
|
* ## Why the bar is CSS on an attribute rather than a drawn element
|
|
18
18
|
*
|
|
19
19
|
* The rows belong to `@issuegraph/viewer`, which stamps `KEY_ATTRIBUTE` on
|
|
20
|
-
* them. Layer 2 composes layer 1 through its public surface, and
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* them. Layer 2 composes layer 1 through its public surface, and rewriting a
|
|
21
|
+
* row's `class` from out here is reaching past that surface — so a bar drawn as
|
|
22
|
+
* an element would mean this layer assembling markup for a row it does not own.
|
|
23
|
+
*
|
|
24
|
+
* ONE CLAUSE OF THIS USED TO READ "and the viewer's markup primitive is
|
|
25
|
+
* deliberately not on it", and that was never true after `renderMarkup` was
|
|
26
|
+
* exported one pull request later. It is public, and five sibling leaves import
|
|
27
|
+
* it — `scale/render.ts`, `picker/render.ts`, `workspace/render.ts`,
|
|
28
|
+
* `reevaluate/render.ts`, `firstpass/render.ts`. The escaping was never what
|
|
29
|
+
* made the bar an attribute; OWNERSHIP OF THE ROW is, and that part stands.
|
|
24
30
|
*
|
|
25
31
|
* An attribute plus a stylesheet needs neither. {@link auditRowAttributes}
|
|
26
32
|
* answers what an affected row carries, `./styles.ts` draws the bar from it,
|
|
@@ -30,10 +36,18 @@
|
|
|
30
36
|
* ## Nothing here renders host text
|
|
31
37
|
*
|
|
32
38
|
* The only value that reaches the markup is a COUNT, and a count is a number.
|
|
33
|
-
* That is
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
39
|
+
* That is what makes {@link renderAuditHeader} safe while it concatenates by
|
|
40
|
+
* hand, and it is a boundary rather than a happy accident: a finding's `detail`
|
|
41
|
+
* is prose about issues a host supplied. Findings travel as data; whatever
|
|
42
|
+
* lists them owns their escaping.
|
|
43
|
+
*
|
|
44
|
+
* ## And `./panel.ts` is the lister that rule predicted
|
|
45
|
+
*
|
|
46
|
+
* §17d's findings list is drawn there, not here, and it owns its escaping the
|
|
47
|
+
* way every other leaf does — an `ElementSpec` tree the caller renders through
|
|
48
|
+
* the viewer's `renderMarkup`. So the rule above is unchanged rather than
|
|
49
|
+
* relaxed: this module still renders no host text, and the module that does
|
|
50
|
+
* builds no markup by hand.
|
|
37
51
|
*
|
|
38
52
|
* @see https://github.com/autnmy/issuegraph/blob/main/SPEC.md
|
|
39
53
|
*/
|
|
@@ -52,6 +66,16 @@ export declare const AUDIT_COUNT_ATTRIBUTE = "data-ig-audit-count";
|
|
|
52
66
|
* matching on a class name that is a styling hook rather than a contract.
|
|
53
67
|
*/
|
|
54
68
|
export declare const AUDIT_FILTER_ATTRIBUTE = "data-ig-audit-filter";
|
|
69
|
+
/**
|
|
70
|
+
* The attribute marking the header's panel control.
|
|
71
|
+
*
|
|
72
|
+
* SEPARATE FROM THE FILTER, because §17d gives the header count exactly one
|
|
73
|
+
* job — *"always the same click"* — and `RULINGS.md` §3 says what that click
|
|
74
|
+
* does: the panel is *"a transient overlay anchored to the header count"*. The
|
|
75
|
+
* filter is drawn INSIDE the panel, where §17d draws it (*"filter the rail to
|
|
76
|
+
* these"*), so one control no longer carries two meanings.
|
|
77
|
+
*/
|
|
78
|
+
export declare const AUDIT_PANEL_ATTRIBUTE = "data-ig-audit-panel";
|
|
55
79
|
/** What one affected row is told about itself. */
|
|
56
80
|
export interface AuditRow {
|
|
57
81
|
readonly ref: IssueRef;
|
|
@@ -105,8 +129,13 @@ export interface AuditOverlay {
|
|
|
105
129
|
* Project findings onto the two things the ambient surface draws.
|
|
106
130
|
*
|
|
107
131
|
* Pure, and a function of the findings alone: it neither re-detects anything
|
|
108
|
-
* nor reads the document, so the count on screen and
|
|
109
|
-
* never disagree about what was found.
|
|
132
|
+
* nor reads the document, so the count on screen and what is drawn behind it
|
|
133
|
+
* can never disagree about what was found.
|
|
134
|
+
*
|
|
135
|
+
* "WHAT IS DRAWN" IS TWO SURFACES, NOT ONE. `./panel.ts` lists the three
|
|
136
|
+
* relationship classes and `./refused.ts` draws the fourth, so this count is a
|
|
137
|
+
* count of both together — which is why it stays every finding while the
|
|
138
|
+
* panel's own head counts only its cards. See {@link renderAuditHeader}.
|
|
110
139
|
*/
|
|
111
140
|
export declare function auditOverlay(input: AuditInput): AuditOverlay;
|
|
112
141
|
/**
|
|
@@ -137,8 +166,15 @@ export declare function auditFilterKeeps(overlay: AuditOverlay, ref: IssueRef):
|
|
|
137
166
|
*/
|
|
138
167
|
export declare function heaviestRow(overlay: AuditOverlay, refs: readonly IssueRef[]): AuditRow | undefined;
|
|
139
168
|
export interface AuditHeaderOptions {
|
|
140
|
-
/**
|
|
141
|
-
|
|
169
|
+
/**
|
|
170
|
+
* Whether §17d's overlay is open. Defaults to `false`.
|
|
171
|
+
*
|
|
172
|
+
* WAS `filtered`, AND THE SWAP IS THE RULING. This button used to toggle the
|
|
173
|
+
* rail filter; §3 makes it the panel's anchor instead, and the filter moves
|
|
174
|
+
* into the panel head. A host that bound to the old meaning gets a compile
|
|
175
|
+
* error rather than a control that silently does something else.
|
|
176
|
+
*/
|
|
177
|
+
readonly open?: boolean | undefined;
|
|
142
178
|
}
|
|
143
179
|
/**
|
|
144
180
|
* The persistent header count, as markup.
|
|
@@ -148,6 +184,12 @@ export interface AuditHeaderOptions {
|
|
|
148
184
|
* that appears when there is bad news is a control the eye has to re-find, and
|
|
149
185
|
* §17d's whole ask is that the audit never demands attention it has not earned.
|
|
150
186
|
*
|
|
187
|
+
* IT COUNTS EVERY FINDING, ACROSS BOTH SURFACES THAT DRAW THEM. `./panel.ts`
|
|
188
|
+
* lists three classes and `./refused.ts` draws the fourth, and a reader works
|
|
189
|
+
* through all four — so splitting this number would hand them two to add up
|
|
190
|
+
* for one question. This one is in the workspace CHROME, beside both; the
|
|
191
|
+
* panel's own head is enclosed by its list and counts that list alone.
|
|
192
|
+
*
|
|
151
193
|
* A `button` with `aria-pressed`, because a filter toggle is a toggle: it has
|
|
152
194
|
* two states and a screen reader has to be able to say which one is on.
|
|
153
195
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../../src/audit/surface.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../../src/audit/surface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGlD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEzF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAExD,kFAAkF;AAClF,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAE3D;;;GAGG;AACH,eAAO,MAAM,sBAAsB,yBAAyB,CAAC;AAE7D;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAE3D,kDAAkD;AAClD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;IACnC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,QAAQ,GAAG,SAAS,CAAC;IACzD,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;CAC5C;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,CAmE5D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,QAAQ,GACZ,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAIlC;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAE9E;AAUD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,SAAS,QAAQ,EAAE,GACxB,QAAQ,GAAG,SAAS,CAQtB;AAED,MAAM,WAAW,kBAAkB;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,GAAE,kBAAuB,GAAG,MAAM,CAiBjG"}
|
package/dist/audit/surface.js
CHANGED
|
@@ -17,10 +17,16 @@
|
|
|
17
17
|
* ## Why the bar is CSS on an attribute rather than a drawn element
|
|
18
18
|
*
|
|
19
19
|
* The rows belong to `@issuegraph/viewer`, which stamps `KEY_ATTRIBUTE` on
|
|
20
|
-
* them. Layer 2 composes layer 1 through its public surface, and
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* them. Layer 2 composes layer 1 through its public surface, and rewriting a
|
|
21
|
+
* row's `class` from out here is reaching past that surface — so a bar drawn as
|
|
22
|
+
* an element would mean this layer assembling markup for a row it does not own.
|
|
23
|
+
*
|
|
24
|
+
* ONE CLAUSE OF THIS USED TO READ "and the viewer's markup primitive is
|
|
25
|
+
* deliberately not on it", and that was never true after `renderMarkup` was
|
|
26
|
+
* exported one pull request later. It is public, and five sibling leaves import
|
|
27
|
+
* it — `scale/render.ts`, `picker/render.ts`, `workspace/render.ts`,
|
|
28
|
+
* `reevaluate/render.ts`, `firstpass/render.ts`. The escaping was never what
|
|
29
|
+
* made the bar an attribute; OWNERSHIP OF THE ROW is, and that part stands.
|
|
24
30
|
*
|
|
25
31
|
* An attribute plus a stylesheet needs neither. {@link auditRowAttributes}
|
|
26
32
|
* answers what an affected row carries, `./styles.ts` draws the bar from it,
|
|
@@ -30,10 +36,18 @@
|
|
|
30
36
|
* ## Nothing here renders host text
|
|
31
37
|
*
|
|
32
38
|
* The only value that reaches the markup is a COUNT, and a count is a number.
|
|
33
|
-
* That is
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
39
|
+
* That is what makes {@link renderAuditHeader} safe while it concatenates by
|
|
40
|
+
* hand, and it is a boundary rather than a happy accident: a finding's `detail`
|
|
41
|
+
* is prose about issues a host supplied. Findings travel as data; whatever
|
|
42
|
+
* lists them owns their escaping.
|
|
43
|
+
*
|
|
44
|
+
* ## And `./panel.ts` is the lister that rule predicted
|
|
45
|
+
*
|
|
46
|
+
* §17d's findings list is drawn there, not here, and it owns its escaping the
|
|
47
|
+
* way every other leaf does — an `ElementSpec` tree the caller renders through
|
|
48
|
+
* the viewer's `renderMarkup`. So the rule above is unchanged rather than
|
|
49
|
+
* relaxed: this module still renders no host text, and the module that does
|
|
50
|
+
* builds no markup by hand.
|
|
37
51
|
*
|
|
38
52
|
* @see https://github.com/autnmy/issuegraph/blob/main/SPEC.md
|
|
39
53
|
*/
|
|
@@ -51,13 +65,28 @@ export const AUDIT_COUNT_ATTRIBUTE = 'data-ig-audit-count';
|
|
|
51
65
|
* matching on a class name that is a styling hook rather than a contract.
|
|
52
66
|
*/
|
|
53
67
|
export const AUDIT_FILTER_ATTRIBUTE = 'data-ig-audit-filter';
|
|
68
|
+
/**
|
|
69
|
+
* The attribute marking the header's panel control.
|
|
70
|
+
*
|
|
71
|
+
* SEPARATE FROM THE FILTER, because §17d gives the header count exactly one
|
|
72
|
+
* job — *"always the same click"* — and `RULINGS.md` §3 says what that click
|
|
73
|
+
* does: the panel is *"a transient overlay anchored to the header count"*. The
|
|
74
|
+
* filter is drawn INSIDE the panel, where §17d draws it (*"filter the rail to
|
|
75
|
+
* these"*), so one control no longer carries two meanings.
|
|
76
|
+
*/
|
|
77
|
+
export const AUDIT_PANEL_ATTRIBUTE = 'data-ig-audit-panel';
|
|
54
78
|
const CLASS_ORDER = new Map(AUDIT_CLASSES.map((kind, index) => [kind, index]));
|
|
55
79
|
/**
|
|
56
80
|
* Project findings onto the two things the ambient surface draws.
|
|
57
81
|
*
|
|
58
82
|
* Pure, and a function of the findings alone: it neither re-detects anything
|
|
59
|
-
* nor reads the document, so the count on screen and
|
|
60
|
-
* never disagree about what was found.
|
|
83
|
+
* nor reads the document, so the count on screen and what is drawn behind it
|
|
84
|
+
* can never disagree about what was found.
|
|
85
|
+
*
|
|
86
|
+
* "WHAT IS DRAWN" IS TWO SURFACES, NOT ONE. `./panel.ts` lists the three
|
|
87
|
+
* relationship classes and `./refused.ts` draws the fourth, so this count is a
|
|
88
|
+
* count of both together — which is why it stays every finding while the
|
|
89
|
+
* panel's own head counts only its cards. See {@link renderAuditHeader}.
|
|
61
90
|
*/
|
|
62
91
|
export function auditOverlay(input) {
|
|
63
92
|
// IT RUNS THE AUDIT RATHER THAN ACCEPTING ONE. Taking a finding list made
|
|
@@ -183,16 +212,27 @@ export function heaviestRow(overlay, refs) {
|
|
|
183
212
|
* that appears when there is bad news is a control the eye has to re-find, and
|
|
184
213
|
* §17d's whole ask is that the audit never demands attention it has not earned.
|
|
185
214
|
*
|
|
215
|
+
* IT COUNTS EVERY FINDING, ACROSS BOTH SURFACES THAT DRAW THEM. `./panel.ts`
|
|
216
|
+
* lists three classes and `./refused.ts` draws the fourth, and a reader works
|
|
217
|
+
* through all four — so splitting this number would hand them two to add up
|
|
218
|
+
* for one question. This one is in the workspace CHROME, beside both; the
|
|
219
|
+
* panel's own head is enclosed by its list and counts that list alone.
|
|
220
|
+
*
|
|
186
221
|
* A `button` with `aria-pressed`, because a filter toggle is a toggle: it has
|
|
187
222
|
* two states and a screen reader has to be able to say which one is on.
|
|
188
223
|
*/
|
|
189
224
|
export function renderAuditHeader(overlay, options = {}) {
|
|
190
225
|
const count = String(overlay.count);
|
|
191
|
-
const
|
|
226
|
+
const open = options.open === true;
|
|
192
227
|
return [
|
|
193
228
|
`<div class="ig-audit" ${AUDIT_COUNT_ATTRIBUTE}="${count}">`,
|
|
194
|
-
|
|
195
|
-
`
|
|
229
|
+
// `aria-expanded`, NOT `aria-pressed`. The two say different things and the
|
|
230
|
+
// button's job changed underneath it: `pressed` describes a toggle that is
|
|
231
|
+
// ON — the old filter — while `expanded` describes a control that DISCLOSES
|
|
232
|
+
// something, which is what an overlay anchored here is. A reader told
|
|
233
|
+
// "pressed" would be waiting for a state, not for a panel.
|
|
234
|
+
`<button type="button" class="ig-audit-toggle" aria-expanded="${String(open)}"`,
|
|
235
|
+
` ${AUDIT_PANEL_ATTRIBUTE}>`,
|
|
196
236
|
`<span class="ig-audit-count">${count}</span>`,
|
|
197
237
|
`<span class="ig-audit-label">audit</span>`,
|
|
198
238
|
`</button>`,
|