@certrev/cert-block 1.2.0-canary.6 → 1.2.0-canary.7

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/CHANGELOG.md CHANGED
@@ -5,6 +5,34 @@ change the rendered cert output and never break a compiling integration** (regis
5
5
  exports, types). Anything that would alter what a visitor sees, or require integration changes,
6
6
  is announced loudly here first.
7
7
 
8
+ ## 1.2.0-canary.7 · 2026-10-06
9
+
10
+ Still on the `canary` dist-tag. **The reader face's avatar shows the person's initials where it has no photo to
11
+ paint** (Owen's answer to the judge's question d4c7cfe0: "Initials in every reader face without a photo (author and
12
+ reviewer)"). Only a reader face's avatars change. Every other face, the options-only card, a revoked or failed card,
13
+ the stylesheet, the sidebar flow rules, the modal, the design pin, `CERT_FONT_FACE_CSS` and `@certrev/cert-contract`
14
+ are byte for byte as in canary.6. No integration needs a code change.
15
+
16
+ - **The initials.** The silhouette is now the fallback for a name with no initials, not for a missing photo. A photo
17
+ that is missing or unsafe, `display.showExpertPhoto: false`, and a def that hides `reviewerPhoto` (which used to
18
+ remove the avatar altogether, and now removes the photo: its URL is never written) all paint the initials. The
19
+ initials are fixed bytes that the portal's Liquid and PHP twins also print:
20
+ - trim the name, split on single spaces and skip the empty parts (so "Jane Doe", with two spaces, is "JD");
21
+ - drop a leading dr, mr, mrs, ms, prof or mx (with or without the dot);
22
+ - take the first character of each of the first two parts left, and uppercase;
23
+ - paint exactly `<svg viewBox="0 0 40 40" aria-hidden="true" focusable="false"><text x="20" y="20"
24
+ text-anchor="middle" dominant-baseline="central" font-size="15" font-weight="700">JD</text></svg>`, escaped.
25
+
26
+ This applies to every avatar of the face: the sidebar reviewer, the banner and memo reviewer, and the banner's
27
+ writer under the writer's own name. A photo that is painted is the same `<img>` as before.
28
+ - **Same bytes as 1.2.0.** `src/reader/face.ts` and `src/reader/render.ts` are exactly the stable 1.2.0 re-cut's.
29
+ The two differ in what 1.2.0 adds besides: hydrating from the server's read, stripping hidden fields from the
30
+ payload, and a card stylesheet without the remote font faces. Those are not in this canary.
31
+ - **Tests.** `reader-initials.test.ts` (new) pins the spec cell by cell against the portal's Liquid oracle
32
+ (`oracle-extra.json`, regenerated at portal 2e35e014a5 with the new names cells). `reader-byline.test.ts`,
33
+ `reader-face-avatars.test.tsx` and six reader goldens now expect the initials where they expected a silhouette,
34
+ or no avatar.
35
+
8
36
  ## 1.2.0-canary.6 · 2026-10-06
9
37
 
10
38
  Still on the `canary` dist-tag. It lets the reader sidebar card's float out of its Builder block, so on a Builder
package/README.md CHANGED
@@ -750,7 +750,7 @@ published at `@certrev/cert-block/fixtures`).
750
750
 
751
751
  ## Version
752
752
 
753
- `1.2.0-canary.6`: see [CHANGELOG.md](./CHANGELOG.md) for the release history and the semver contract
753
+ `1.2.0-canary.7`: see [CHANGELOG.md](./CHANGELOG.md) for the release history and the semver contract
754
754
  (patch/minor never change the rendered cert output or break a compiling integration). Publishes
755
755
  **publicly** to npm as `@certrev/cert-block` (`publishConfig.access: public`) via GitHub Actions
756
756
  trusted publishing (OIDC); the internal `@certrev` GitHub-Packages channel mirrors it.
@@ -2,11 +2,15 @@ export type ReaderFaceSize = '' | 'sm' | 'lg';
2
2
  export interface ReaderFaceInput {
3
3
  /** The photo URL on the envelope. */
4
4
  readonly photo: unknown;
5
- /** Whether to ATTEMPT the photo: false never reads the URL (the silhouette shows). */
5
+ /** Whether to ATTEMPT the photo: false never reads the URL (the initials show). */
6
6
  readonly show: boolean;
7
+ /** The person's display name, the initials' source; a hostile type reads as no name. */
8
+ readonly name: unknown;
7
9
  readonly size: ReaderFaceSize;
8
10
  /** The pixel width the resizer is asked for. */
9
11
  readonly width: number;
10
12
  }
11
- export declare function readerFace({ photo, show, size, width }: ReaderFaceInput): string;
13
+ /** The initials of a display name by the spec above: '' when the name leaves no first character to take. */
14
+ export declare function initialsOf(name: unknown): string;
15
+ export declare function readerFace({ photo, show, name, size, width }: ReaderFaceInput): string;
12
16
  //# sourceMappingURL=face.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"face.d.ts","sourceRoot":"","sources":["../../src/reader/face.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AAE7C,MAAM,WAAW,eAAe;IAC/B,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,sFAAsF;IACtF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,gDAAgD;IAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACtB;AAOD,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,eAAe,GAAG,MAAM,CAUhF"}
1
+ {"version":3,"file":"face.d.ts","sourceRoot":"","sources":["../../src/reader/face.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AAE7C,MAAM,WAAW,eAAe;IAC/B,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,wFAAwF;IACxF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,gDAAgD;IAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACtB;AAoBD,4GAA4G;AAC5G,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAWhD;AAQD,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,eAAe,GAAG,MAAM,CAatF"}
@@ -1,19 +1,67 @@
1
1
  /**
2
- * `certrev-reader-face`: the round avatar on a reader byline: the person's photo when there is one to show, the
3
- * silhouette when there is not. The span carries a size class (`sm` for the author, none for the banner reviewer,
4
- * `lg` for the memo and sidebar reviewer); the image is requested at `width` square through the asset resizer.
2
+ * `certrev-reader-face`: the round avatar on a reader byline: the person's photo when there is one to paint, else their
3
+ * initials, else (a person with no name to take them from) the silhouette. The span carries a size class (`sm` for the
4
+ * author, none for the banner reviewer, `lg` for the memo and sidebar reviewer); the image is requested at `width`
5
+ * square through the asset resizer.
6
+ *
7
+ * THE INITIALS ARE A BYTE SPEC the portal's Liquid snippets and the WordPress renderer repeat, so all three print the
8
+ * same bytes: trim the name and split it on single spaces (`' '`) SKIPPING empty parts (two spaces in a row are one
9
+ * gap: "Jane Doe" gives "JD"); drop the FIRST part when, lowercased, it is one of the honorifics dr, mr, mrs, ms,
10
+ * prof, mx (each with or without its trailing dot); take the first character, by code point, of each of the first two
11
+ * parts left; uppercase them. Non-empty initials paint exactly
12
+ * `<svg viewBox="0 0 40 40" aria-hidden="true" focusable="false"><text x="20" y="20" text-anchor="middle"
13
+ * dominant-baseline="central" font-size="15" font-weight="700">JD</text></svg>` (one line, the initials escaped);
14
+ * empty ones paint the silhouette as before.
15
+ *
16
+ * "A photo to paint" is `show` with a URL that passes `safeUrl`. A def that hides `reviewerPhoto`, or
17
+ * `display.showExpertPhoto: false`, passes `show: false`: the URL is never read, so it never reaches the page, and the
18
+ * avatar is the initials (a hidden photo used to remove the avatar altogether; it removes the photo now).
5
19
  */
20
+ import { asText } from '../components/escape.js';
6
21
  import { avatarUrl, cleaned, esc, safeUrl } from './helpers.js';
7
22
  const SILHOUETTE = '<svg viewBox="0 0 40 40" aria-hidden="true" focusable="false"><circle cx="20" cy="14.8" r="7"/><path d="M20 23.4c-6.9 0-12.6 4.8-13.8 11.2a20 20 0 0 0 27.6 0C32.6 28.2 26.9 23.4 20 23.4Z"/></svg>';
23
+ const HONORIFICS = new Set([
24
+ 'dr',
25
+ 'dr.',
26
+ 'mr',
27
+ 'mr.',
28
+ 'mrs',
29
+ 'mrs.',
30
+ 'ms',
31
+ 'ms.',
32
+ 'prof',
33
+ 'prof.',
34
+ 'mx',
35
+ 'mx.',
36
+ ]);
37
+ /** The initials of a display name by the spec above: '' when the name leaves no first character to take. */
38
+ export function initialsOf(name) {
39
+ const parts = asText(name)
40
+ .trim()
41
+ .split(' ')
42
+ .filter((part) => part !== '');
43
+ if (HONORIFICS.has((parts[0] ?? '').toLowerCase()))
44
+ parts.shift();
45
+ return parts
46
+ .slice(0, 2)
47
+ .map((part) => Array.from(part)[0] ?? '')
48
+ .join('')
49
+ .toUpperCase();
50
+ }
51
+ const initialsSvg = (initials) => '<svg viewBox="0 0 40 40" aria-hidden="true" focusable="false"><text x="20" y="20" text-anchor="middle" ' +
52
+ `dominant-baseline="central" font-size="15" font-weight="700">${esc(initials)}</text></svg>`;
8
53
  const DIMENSION = { '': 42, sm: 36, lg: 46 };
9
- export function readerFace({ photo, show, size, width }) {
54
+ export function readerFace({ photo, show, name, size, width }) {
10
55
  const safe = show ? cleaned(safeUrl(photo)) : '';
11
56
  const src = cleaned(avatarUrl(safe, width));
12
57
  const dim = DIMENSION[size];
13
58
  const cls = size === '' ? 'certrev-r-face' : `certrev-r-face ${esc(size)}`;
59
+ const initials = src !== '' ? '' : initialsOf(name);
14
60
  const inner = src !== ''
15
61
  ? `<img src="${esc(src)}" alt="" width="${dim}" height="${dim}" loading="lazy" decoding="async">`
16
- : SILHOUETTE;
62
+ : initials !== ''
63
+ ? initialsSvg(initials)
64
+ : SILHOUETTE;
17
65
  return `<span class="${cls}">${inner}</span>`;
18
66
  }
19
67
  //# sourceMappingURL=face.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"face.js","sourceRoot":"","sources":["../../src/reader/face.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAc/D,MAAM,UAAU,GACf,qMAAqM,CAAA;AAEtM,MAAM,SAAS,GAA6C,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAA;AAEtF,MAAM,UAAU,UAAU,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAmB;IACvE,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;IAC3C,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;IAC3B,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAAkB,GAAG,CAAC,IAAI,CAAC,EAAE,CAAA;IAC1E,MAAM,KAAK,GACV,GAAG,KAAK,EAAE;QACT,CAAC,CAAC,aAAa,GAAG,CAAC,GAAG,CAAC,mBAAmB,GAAG,aAAa,GAAG,oCAAoC;QACjG,CAAC,CAAC,UAAU,CAAA;IACd,OAAO,gBAAgB,GAAG,KAAK,KAAK,SAAS,CAAA;AAC9C,CAAC"}
1
+ {"version":3,"file":"face.js","sourceRoot":"","sources":["../../src/reader/face.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAgB/D,MAAM,UAAU,GACf,qMAAqM,CAAA;AAEtM,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC;IAC/C,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,KAAK;IACL,KAAK;IACL,MAAM;IACN,IAAI;IACJ,KAAK;IACL,MAAM;IACN,OAAO;IACP,IAAI;IACJ,KAAK;CACL,CAAC,CAAA;AAEF,4GAA4G;AAC5G,MAAM,UAAU,UAAU,CAAC,IAAa;IACvC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;SACxB,IAAI,EAAE;SACN,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAA;IAC/B,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAAE,KAAK,CAAC,KAAK,EAAE,CAAA;IACjE,OAAO,KAAK;SACV,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACxC,IAAI,CAAC,EAAE,CAAC;SACR,WAAW,EAAE,CAAA;AAChB,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAU,EAAE,CAChD,yGAAyG;IACzG,gEAAgE,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAA;AAE7F,MAAM,SAAS,GAA6C,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAA;AAEtF,MAAM,UAAU,UAAU,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAmB;IAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;IAC3C,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;IAC3B,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAAkB,GAAG,CAAC,IAAI,CAAC,EAAE,CAAA;IAC1E,MAAM,QAAQ,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;IACnD,MAAM,KAAK,GACV,GAAG,KAAK,EAAE;QACT,CAAC,CAAC,aAAa,GAAG,CAAC,GAAG,CAAC,mBAAmB,GAAG,aAAa,GAAG,oCAAoC;QACjG,CAAC,CAAC,QAAQ,KAAK,EAAE;YAChB,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC;YACvB,CAAC,CAAC,UAAU,CAAA;IACf,OAAO,gBAAgB,GAAG,KAAK,KAAK,SAAS,CAAA;AAC9C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/reader/render.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAmBxD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAE5D,wHAAwH;AACxH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEnD,MAAM,WAAW,eAAe;IAC/B,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,sGAAsG;IACtG,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,+FAA+F;IAC/F,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAA;IAC1B,2GAA2G;IAC3G,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,8FAA8F;IAC9F,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAC/B;AAiQD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAQ/D"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/reader/render.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAmBxD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAE5D,wHAAwH;AACxH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEnD,MAAM,WAAW,eAAe;IAC/B,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,sGAAsG;IACtG,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,+FAA+F;IAC/F,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAA;IAC1B,2GAA2G;IAC3G,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,8FAA8F;IAC9F,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAC/B;AA+PD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAQ/D"}
@@ -27,8 +27,10 @@
27
27
  * sentence is direct text of the scope element, which carries `data-ftc-line` itself (after the cue's " · " there
28
28
  * is a `<!-- -->`, so the cue separator and the sentence are two text nodes). The `<!-- -->` marks between
29
29
  * adjacent leaves are React's, kept so the bytes equal the Liquid snippets' and the portal's goldens;
30
- * - the def's `hidden` set removes the avatars (`reviewerPhoto`), `display.showExpertPhoto === false` keeps the
31
- * silhouette and never requests the photo, `display.showAuthor === false` drops the author column.
30
+ * - the avatars: a photo when there is one to paint, else the person's initials (`face.ts` is the byte spec), else the
31
+ * silhouette for a name with none. The def's `hidden` set holding `reviewerPhoto`, and `display.showExpertPhoto ===
32
+ * false`, keep the photo URL out of the page entirely (the avatar is the initials); neither removes the avatar.
33
+ * `display.showAuthor === false` drops the author column.
32
34
  *
33
35
  * Every interpolated field is escaped and every URL passes `safeUrl`. A hostile type (a number, an object) renders as
34
36
  * nothing, never as a throw: see `helpers.ts`.
@@ -46,8 +48,7 @@ function readFacts(input) {
46
48
  const disp = rec(content.display);
47
49
  const def = input.def;
48
50
  const rd = rec(def);
49
- const hideAvatar = contains(rd.hidden, 'reviewerPhoto');
50
- const showPhoto = disp.showExpertPhoto !== false && !hideAvatar;
51
+ const showPhoto = disp.showExpertPhoto !== false && !contains(rd.hidden, 'reviewerPhoto');
51
52
  // POR-9738: each credential's cardLabel over its bare abbreviation, joined with ', ' (labels are not trimmed).
52
53
  const labels = [];
53
54
  if (Array.isArray(expert.credentials)) {
@@ -67,7 +68,6 @@ function readFacts(input) {
67
68
  def,
68
69
  certId: asText(input.certId),
69
70
  ename: textOr(expert.displayName),
70
- hideAvatar,
71
71
  showPhoto,
72
72
  creds: labels.join(', '),
73
73
  hasCue,
@@ -144,12 +144,12 @@ function bannerCard(f) {
144
144
  const authorName = textOr(author.name);
145
145
  const authorTitle = textOr(author.title);
146
146
  const hasAuthor = f.disp.showAuthor !== false && authorName !== '' && authorName !== f.ename;
147
- const avatar = (photo, size) => f.hideAvatar ? '' : readerFace({ photo, show: f.showPhoto, size, width: 84 });
147
+ const avatar = (photo, name, size) => readerFace({ photo, show: f.showPhoto, name, size, width: 84 });
148
148
  const authorBy = hasAuthor
149
- ? `<div class="certrev-r-by">${avatar(author.photoUrl, 'sm')}<div>\n <b>${esc(authorName)}</b>` +
149
+ ? `<div class="certrev-r-by">${avatar(author.photoUrl, authorName, 'sm')}<div>\n <b>${esc(authorName)}</b>` +
150
150
  `${authorTitle !== '' ? `<em>${esc(authorTitle)}</em>` : ''}<span class="certrev-r-role">Written by</span>\n </div>\n </div>`
151
151
  : '';
152
- const expertBy = `<div class="certrev-r-by">${avatar(f.expert.photoUrl, '')}<div>\n <b>${esc(f.ename)}</b>` +
152
+ const expertBy = `<div class="certrev-r-by">${avatar(f.expert.photoUrl, f.ename, '')}<div>\n <b>${esc(f.ename)}</b>` +
153
153
  `${verifiedLine(f, true)}<span class="certrev-r-role on">Reviewed by</span>\n </div>\n </div>`;
154
154
  const certifiedAt = f.content.certifiedAt;
155
155
  const certified = isBlank(certifiedAt) ? '' : cleaned(longDate(certifiedAt));
@@ -196,7 +196,7 @@ function bannerMemo(f) {
196
196
  (f.vurl !== '' ? anchor(f.vurl, '', 'View certificate') : '') +
197
197
  '</div>'
198
198
  : '';
199
- const avatar = f.hideAvatar ? '' : readerFace({ photo: f.expert.photoUrl, show: f.showPhoto, size: 'lg', width: 112 });
199
+ const avatar = readerFace({ photo: f.expert.photoUrl, show: f.showPhoto, name: f.ename, size: 'lg', width: 112 });
200
200
  return (`${sectionOpen(f, false, `Expert memo by ${f.ename}`)}\n <div class="certrev-r-card pad">\n` +
201
201
  ' <div class="certrev-r-kick">Expert memo</div>\n' +
202
202
  ` <div class="certrev-r-memo">${avatar}<div>\n` +
@@ -213,7 +213,7 @@ function sidebar(f) {
213
213
  if (f.ename === '')
214
214
  return '';
215
215
  const bio = f.disp.showBio !== false && !isBlank(f.expert.bio) ? asText(f.expert.bio) : '';
216
- const avatar = f.hideAvatar ? '' : readerFace({ photo: f.expert.photoUrl, show: f.showPhoto, size: 'lg', width: 112 });
216
+ const avatar = readerFace({ photo: f.expert.photoUrl, show: f.showPhoto, name: f.ename, size: 'lg', width: 112 });
217
217
  const both = f.purl !== '' && f.vurl !== '';
218
218
  const links = f.purl !== '' || f.vurl !== ''
219
219
  ? `<div class="certrev-r-side-links${both ? '' : ' single'}">` +
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/reader/render.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/reader/render.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@certrev/cert-block",
3
- "version": "1.2.0-canary.6",
3
+ "version": "1.2.0-canary.7",
4
4
  "description": "Headless render edge for the CertREV CertDeliveryEnvelope: SSR-safe React cert components, a framework-agnostic <certrev-badge> Web Component, a schema.org JSON-LD projector, and a fail-closed verify layer over the shared VerdictKernel.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,8 +1,23 @@
1
1
  /**
2
- * `certrev-reader-face`: the round avatar on a reader byline: the person's photo when there is one to show, the
3
- * silhouette when there is not. The span carries a size class (`sm` for the author, none for the banner reviewer,
4
- * `lg` for the memo and sidebar reviewer); the image is requested at `width` square through the asset resizer.
2
+ * `certrev-reader-face`: the round avatar on a reader byline: the person's photo when there is one to paint, else their
3
+ * initials, else (a person with no name to take them from) the silhouette. The span carries a size class (`sm` for the
4
+ * author, none for the banner reviewer, `lg` for the memo and sidebar reviewer); the image is requested at `width`
5
+ * square through the asset resizer.
6
+ *
7
+ * THE INITIALS ARE A BYTE SPEC the portal's Liquid snippets and the WordPress renderer repeat, so all three print the
8
+ * same bytes: trim the name and split it on single spaces (`' '`) SKIPPING empty parts (two spaces in a row are one
9
+ * gap: "Jane Doe" gives "JD"); drop the FIRST part when, lowercased, it is one of the honorifics dr, mr, mrs, ms,
10
+ * prof, mx (each with or without its trailing dot); take the first character, by code point, of each of the first two
11
+ * parts left; uppercase them. Non-empty initials paint exactly
12
+ * `<svg viewBox="0 0 40 40" aria-hidden="true" focusable="false"><text x="20" y="20" text-anchor="middle"
13
+ * dominant-baseline="central" font-size="15" font-weight="700">JD</text></svg>` (one line, the initials escaped);
14
+ * empty ones paint the silhouette as before.
15
+ *
16
+ * "A photo to paint" is `show` with a URL that passes `safeUrl`. A def that hides `reviewerPhoto`, or
17
+ * `display.showExpertPhoto: false`, passes `show: false`: the URL is never read, so it never reaches the page, and the
18
+ * avatar is the initials (a hidden photo used to remove the avatar altogether; it removes the photo now).
5
19
  */
20
+ import { asText } from '../components/escape.js'
6
21
  import { avatarUrl, cleaned, esc, safeUrl } from './helpers.js'
7
22
 
8
23
  export type ReaderFaceSize = '' | 'sm' | 'lg'
@@ -10,8 +25,10 @@ export type ReaderFaceSize = '' | 'sm' | 'lg'
10
25
  export interface ReaderFaceInput {
11
26
  /** The photo URL on the envelope. */
12
27
  readonly photo: unknown
13
- /** Whether to ATTEMPT the photo: false never reads the URL (the silhouette shows). */
28
+ /** Whether to ATTEMPT the photo: false never reads the URL (the initials show). */
14
29
  readonly show: boolean
30
+ /** The person's display name, the initials' source; a hostile type reads as no name. */
31
+ readonly name: unknown
15
32
  readonly size: ReaderFaceSize
16
33
  /** The pixel width the resizer is asked for. */
17
34
  readonly width: number
@@ -20,16 +37,52 @@ export interface ReaderFaceInput {
20
37
  const SILHOUETTE =
21
38
  '<svg viewBox="0 0 40 40" aria-hidden="true" focusable="false"><circle cx="20" cy="14.8" r="7"/><path d="M20 23.4c-6.9 0-12.6 4.8-13.8 11.2a20 20 0 0 0 27.6 0C32.6 28.2 26.9 23.4 20 23.4Z"/></svg>'
22
39
 
40
+ const HONORIFICS: ReadonlySet<string> = new Set([
41
+ 'dr',
42
+ 'dr.',
43
+ 'mr',
44
+ 'mr.',
45
+ 'mrs',
46
+ 'mrs.',
47
+ 'ms',
48
+ 'ms.',
49
+ 'prof',
50
+ 'prof.',
51
+ 'mx',
52
+ 'mx.',
53
+ ])
54
+
55
+ /** The initials of a display name by the spec above: '' when the name leaves no first character to take. */
56
+ export function initialsOf(name: unknown): string {
57
+ const parts = asText(name)
58
+ .trim()
59
+ .split(' ')
60
+ .filter((part) => part !== '')
61
+ if (HONORIFICS.has((parts[0] ?? '').toLowerCase())) parts.shift()
62
+ return parts
63
+ .slice(0, 2)
64
+ .map((part) => Array.from(part)[0] ?? '')
65
+ .join('')
66
+ .toUpperCase()
67
+ }
68
+
69
+ const initialsSvg = (initials: string): string =>
70
+ '<svg viewBox="0 0 40 40" aria-hidden="true" focusable="false"><text x="20" y="20" text-anchor="middle" ' +
71
+ `dominant-baseline="central" font-size="15" font-weight="700">${esc(initials)}</text></svg>`
72
+
23
73
  const DIMENSION: Readonly<Record<ReaderFaceSize, number>> = { '': 42, sm: 36, lg: 46 }
24
74
 
25
- export function readerFace({ photo, show, size, width }: ReaderFaceInput): string {
75
+ export function readerFace({ photo, show, name, size, width }: ReaderFaceInput): string {
26
76
  const safe = show ? cleaned(safeUrl(photo)) : ''
27
77
  const src = cleaned(avatarUrl(safe, width))
28
78
  const dim = DIMENSION[size]
29
79
  const cls = size === '' ? 'certrev-r-face' : `certrev-r-face ${esc(size)}`
80
+ const initials = src !== '' ? '' : initialsOf(name)
30
81
  const inner =
31
82
  src !== ''
32
83
  ? `<img src="${esc(src)}" alt="" width="${dim}" height="${dim}" loading="lazy" decoding="async">`
33
- : SILHOUETTE
84
+ : initials !== ''
85
+ ? initialsSvg(initials)
86
+ : SILHOUETTE
34
87
  return `<span class="${cls}">${inner}</span>`
35
88
  }
@@ -27,8 +27,10 @@
27
27
  * sentence is direct text of the scope element, which carries `data-ftc-line` itself (after the cue's " · " there
28
28
  * is a `<!-- -->`, so the cue separator and the sentence are two text nodes). The `<!-- -->` marks between
29
29
  * adjacent leaves are React's, kept so the bytes equal the Liquid snippets' and the portal's goldens;
30
- * - the def's `hidden` set removes the avatars (`reviewerPhoto`), `display.showExpertPhoto === false` keeps the
31
- * silhouette and never requests the photo, `display.showAuthor === false` drops the author column.
30
+ * - the avatars: a photo when there is one to paint, else the person's initials (`face.ts` is the byte spec), else the
31
+ * silhouette for a name with none. The def's `hidden` set holding `reviewerPhoto`, and `display.showExpertPhoto ===
32
+ * false`, keep the photo URL out of the page entirely (the avatar is the initials); neither removes the avatar.
33
+ * `display.showAuthor === false` drops the author column.
32
34
  *
33
35
  * Every interpolated field is escaped and every URL passes `safeUrl`. A hostile type (a number, an object) renders as
34
36
  * nothing, never as a throw: see `helpers.ts`.
@@ -90,7 +92,7 @@ interface Facts {
90
92
  readonly def: unknown
91
93
  readonly certId: string
92
94
  readonly ename: string
93
- readonly hideAvatar: boolean
95
+ /** Whether a photo may be painted: neither `reviewerPhoto` hidden nor `showExpertPhoto: false`. */
94
96
  readonly showPhoto: boolean
95
97
  /** The joined credential labels, '' when there are none. */
96
98
  readonly creds: string
@@ -110,8 +112,7 @@ function readFacts(input: ReaderFaceInput): Facts {
110
112
  const def = input.def
111
113
  const rd = rec(def)
112
114
 
113
- const hideAvatar = contains(rd.hidden, 'reviewerPhoto')
114
- const showPhoto = disp.showExpertPhoto !== false && !hideAvatar
115
+ const showPhoto = disp.showExpertPhoto !== false && !contains(rd.hidden, 'reviewerPhoto')
115
116
 
116
117
  // POR-9738: each credential's cardLabel over its bare abbreviation, joined with ', ' (labels are not trimmed).
117
118
  const labels: string[] = []
@@ -132,7 +133,6 @@ function readFacts(input: ReaderFaceInput): Facts {
132
133
  def,
133
134
  certId: asText(input.certId),
134
135
  ename: textOr(expert.displayName),
135
- hideAvatar,
136
136
  showPhoto,
137
137
  creds: labels.join(', '),
138
138
  hasCue,
@@ -216,15 +216,15 @@ function bannerCard(f: Facts): string {
216
216
  const authorName = textOr(author.name)
217
217
  const authorTitle = textOr(author.title)
218
218
  const hasAuthor = f.disp.showAuthor !== false && authorName !== '' && authorName !== f.ename
219
- const avatar = (photo: unknown, size: 'sm' | ''): string =>
220
- f.hideAvatar ? '' : readerFace({ photo, show: f.showPhoto, size, width: 84 })
219
+ const avatar = (photo: unknown, name: string, size: 'sm' | ''): string =>
220
+ readerFace({ photo, show: f.showPhoto, name, size, width: 84 })
221
221
 
222
222
  const authorBy = hasAuthor
223
- ? `<div class="certrev-r-by">${avatar(author.photoUrl, 'sm')}<div>\n <b>${esc(authorName)}</b>` +
223
+ ? `<div class="certrev-r-by">${avatar(author.photoUrl, authorName, 'sm')}<div>\n <b>${esc(authorName)}</b>` +
224
224
  `${authorTitle !== '' ? `<em>${esc(authorTitle)}</em>` : ''}<span class="certrev-r-role">Written by</span>\n </div>\n </div>`
225
225
  : ''
226
226
  const expertBy =
227
- `<div class="certrev-r-by">${avatar(f.expert.photoUrl, '')}<div>\n <b>${esc(f.ename)}</b>` +
227
+ `<div class="certrev-r-by">${avatar(f.expert.photoUrl, f.ename, '')}<div>\n <b>${esc(f.ename)}</b>` +
228
228
  `${verifiedLine(f, true)}<span class="certrev-r-role on">Reviewed by</span>\n </div>\n </div>`
229
229
 
230
230
  const certifiedAt = f.content.certifiedAt
@@ -279,7 +279,7 @@ function bannerMemo(f: Facts): string {
279
279
  (f.vurl !== '' ? anchor(f.vurl, '', 'View certificate') : '') +
280
280
  '</div>'
281
281
  : ''
282
- const avatar = f.hideAvatar ? '' : readerFace({ photo: f.expert.photoUrl, show: f.showPhoto, size: 'lg', width: 112 })
282
+ const avatar = readerFace({ photo: f.expert.photoUrl, show: f.showPhoto, name: f.ename, size: 'lg', width: 112 })
283
283
  return (
284
284
  `${sectionOpen(f, false, `Expert memo by ${f.ename}`)}\n <div class="certrev-r-card pad">\n` +
285
285
  ' <div class="certrev-r-kick">Expert memo</div>\n' +
@@ -299,7 +299,7 @@ function bannerMemo(f: Facts): string {
299
299
  function sidebar(f: Facts): string {
300
300
  if (f.ename === '') return ''
301
301
  const bio = f.disp.showBio !== false && !isBlank(f.expert.bio) ? asText(f.expert.bio) : ''
302
- const avatar = f.hideAvatar ? '' : readerFace({ photo: f.expert.photoUrl, show: f.showPhoto, size: 'lg', width: 112 })
302
+ const avatar = readerFace({ photo: f.expert.photoUrl, show: f.showPhoto, name: f.ename, size: 'lg', width: 112 })
303
303
  const both = f.purl !== '' && f.vurl !== ''
304
304
  const links =
305
305
  f.purl !== '' || f.vurl !== ''