@justai/cuts 0.21.0 → 0.23.0
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/package.json +1 -1
- package/src/Base.astro +17 -1
- package/src/LangPicker.astro +8 -1
package/package.json
CHANGED
package/src/Base.astro
CHANGED
|
@@ -296,7 +296,23 @@ const localePath = (l: string) => (l === defaultLocale ? "/" : `/${l}/`);
|
|
|
296
296
|
if (localStorage.getItem("consent")) return;
|
|
297
297
|
try { if (sessionStorage.getItem("consent-later")) return; } catch (_) {}
|
|
298
298
|
if (!document.getElementById("kernel")) return; // no kernel = not a content page (e.g. 404) — don't ask for consent on a dead end
|
|
299
|
-
|
|
299
|
+
// WHERE CONSENT IS LEGALLY ASKED — and a timezone is a PROXY for that, never the thing
|
|
300
|
+
// itself. `Europe/` carries almost all of the region list in the head, but not all of it:
|
|
301
|
+
// an EEA country can sit in another continent's zone entirely, and those visitors were
|
|
302
|
+
// DENIED by the regional default while never being offered the dialog — no path to
|
|
303
|
+
// consent at all. Twelve zones, measured, listed here with the country that owns them.
|
|
304
|
+
// The two lists are siblings: if the region array up there ever changes, this changes too.
|
|
305
|
+
var tz = Intl.DateTimeFormat().resolvedOptions().timeZone || "";
|
|
306
|
+
var asked = tz.indexOf("Europe/") === 0 || [
|
|
307
|
+
"Asia/Nicosia", "Asia/Famagusta", // Cyprus
|
|
308
|
+
"Atlantic/Canary", // Spain — Canary Islands
|
|
309
|
+
"Atlantic/Azores", "Atlantic/Madeira", // Portugal
|
|
310
|
+
"Atlantic/Reykjavik", // Iceland
|
|
311
|
+
"Arctic/Longyearbyen", // Norway — Svalbard
|
|
312
|
+
"America/Guadeloupe", "America/Martinique", "America/Cayenne", // France — outermost
|
|
313
|
+
"Indian/Reunion", "Indian/Mayotte" // regions; EU law applies
|
|
314
|
+
].indexOf(tz) >= 0;
|
|
315
|
+
if (!asked) return;
|
|
300
316
|
// the first second belongs to the kernel; the question arrives on the second beat
|
|
301
317
|
setTimeout(open, 700);
|
|
302
318
|
} catch (_) {}
|
package/src/LangPicker.astro
CHANGED
|
@@ -24,7 +24,14 @@ const { current, locales, localeNames, localePath, label, searchLabel } = Astro.
|
|
|
24
24
|
<button class="trigger" type="button" aria-haspopup="listbox" aria-expanded="false" data-trigger aria-label={`${label}: ${current.toUpperCase()}`} title={label}>{current.toUpperCase()}</button>
|
|
25
25
|
|
|
26
26
|
<div class="menu" role="listbox" data-menu hidden>
|
|
27
|
-
|
|
27
|
+
{/* `name` and not `id`: a form field with neither makes the browser complain that it cannot
|
|
28
|
+
autofill (Chrome's Issues panel flags it on every page of the fleet, since this cut is on
|
|
29
|
+
every page). `name` answers it without the one risk an `id` would carry — an id must be
|
|
30
|
+
unique in a document, so a persona that ever renders two pickers would ship invalid HTML,
|
|
31
|
+
and a shared cut must be safe to place twice. Prefixed `lang-` so it cannot collide with a
|
|
32
|
+
persona's own field of the same idea. The value is never submitted: this input lives in no
|
|
33
|
+
form and filters the list client-side. */}
|
|
34
|
+
<input type="search" class="search" name="lang-search" placeholder={searchLabel} autocomplete="off" spellcheck="false" data-search aria-label={searchLabel} />
|
|
28
35
|
<div class="list" data-list>
|
|
29
36
|
{locales.map((l) => (
|
|
30
37
|
<a
|