Show tracker type in cookie banner trackers list
The themed banner and headless cookie list exposed only the tracker name, description, and duration, so trackers that share a name but differ in technology were indistinguishable to visitors. Add the tracker type to the headless CookieItem model and render it as a labeled "Type: <value>" detail under the tracker name, with an explicit aria-label for assistive technology. Tracker type names are Web platform API names (Cookie, Local storage, IndexedDB, ...), so they are kept canonical while only the surrounding label is localized. Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
|
||||
import type { CookieItem } from "../types";
|
||||
import { humanizeDuration } from "../cookie-utils";
|
||||
import { getCookieDetailLabels } from "../i18n";
|
||||
import { getCookieDetailLabels, getTrackerTypeLabel, interpolate } from "../i18n";
|
||||
import { ProboElement } from "./base";
|
||||
import type { ProboCategory } from "./category";
|
||||
import type { ProboCookieBannerRoot } from "./cookie-banner-root";
|
||||
@@ -55,19 +55,28 @@ export class ProboCookieList extends ProboElement {
|
||||
? humanizeDuration(cookie.max_age_seconds, lang)
|
||||
: humanizeDuration(0, lang);
|
||||
|
||||
const type = getTrackerTypeLabel(cookie.tracker_type);
|
||||
|
||||
const wrapper = document.createElement("probo-cookie");
|
||||
wrapper.setAttribute("name", cookie.name);
|
||||
const clone = this.template.content.cloneNode(true) as DocumentFragment;
|
||||
this.fillSlots(clone, {
|
||||
name: cookie.name,
|
||||
type,
|
||||
duration,
|
||||
description: cookie.description,
|
||||
});
|
||||
this.fillLabels(clone, labels, {
|
||||
type,
|
||||
description: cookie.description,
|
||||
duration,
|
||||
});
|
||||
|
||||
const typeEl = clone.querySelector<HTMLElement>(".cookie-type");
|
||||
if (typeEl && labels.label_type) {
|
||||
typeEl.setAttribute("aria-label", interpolate(labels.label_type, { value: type }));
|
||||
}
|
||||
|
||||
wrapper.appendChild(clone);
|
||||
this.appendChild(wrapper);
|
||||
}
|
||||
|
||||
@@ -43,16 +43,30 @@ export function interpolate(
|
||||
}
|
||||
|
||||
const COOKIE_DETAIL_LABELS: Record<string, Record<string, string>> = {
|
||||
en: { label_description: "Description: {{value}}", label_duration: "Duration: {{value}}" },
|
||||
fr: { label_description: "Description : {{value}}", label_duration: "Durée : {{value}}" },
|
||||
de: { label_description: "Beschreibung: {{value}}", label_duration: "Dauer: {{value}}" },
|
||||
es: { label_description: "Descripción: {{value}}", label_duration: "Duración: {{value}}" },
|
||||
en: { label_type: "Type: {{value}}", label_description: "Description: {{value}}", label_duration: "Duration: {{value}}" },
|
||||
fr: { label_type: "Type : {{value}}", label_description: "Description : {{value}}", label_duration: "Durée : {{value}}" },
|
||||
de: { label_type: "Typ: {{value}}", label_description: "Beschreibung: {{value}}", label_duration: "Dauer: {{value}}" },
|
||||
es: { label_type: "Tipo: {{value}}", label_description: "Descripción: {{value}}", label_duration: "Duración: {{value}}" },
|
||||
};
|
||||
|
||||
export function getCookieDetailLabels(lang: string): Record<string, string> {
|
||||
return COOKIE_DETAIL_LABELS[lang] ?? COOKIE_DETAIL_LABELS.en;
|
||||
}
|
||||
|
||||
// Tracker type names are Web platform API names (proper nouns), so they are
|
||||
// not translated; only the surrounding "Type:" label is localized.
|
||||
const TRACKER_TYPE_LABELS: Record<string, string> = {
|
||||
COOKIE: "Cookie",
|
||||
LOCAL_STORAGE: "Local storage",
|
||||
SESSION_STORAGE: "Session storage",
|
||||
INDEXED_DB: "IndexedDB",
|
||||
CACHE_STORAGE: "Cache storage",
|
||||
};
|
||||
|
||||
export function getTrackerTypeLabel(type: string): string {
|
||||
return TRACKER_TYPE_LABELS[type] ?? type;
|
||||
}
|
||||
|
||||
const GPC_LABELS: Record<string, string> = {
|
||||
en: "Opt-Out Preference Signal Honored",
|
||||
fr: "Signal de préférence de désinscription respecté",
|
||||
|
||||
@@ -353,6 +353,10 @@ export const THEMED_STYLES = `
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.cookie-type {
|
||||
font-size: calc(var(--_font-size) - 3px);
|
||||
}
|
||||
|
||||
.cookie-detail {
|
||||
color: var(--_text);
|
||||
font-weight: 500;
|
||||
|
||||
@@ -99,6 +99,7 @@ export class ProboThemedBanner extends HTMLElement {
|
||||
<template>
|
||||
<div class="cookie-item">
|
||||
<span class="cookie-name" data-slot="name"></span>
|
||||
<span class="cookie-detail cookie-type" data-label="label_type"><span data-slot="type"></span></span>
|
||||
<span class="cookie-detail" data-label="label_description"><span data-slot="description"></span></span>
|
||||
<span class="cookie-detail" data-label="label_duration"><span data-slot="duration"></span></span>
|
||||
</div>
|
||||
|
||||
@@ -14,8 +14,16 @@
|
||||
|
||||
import type { BannerTexts } from "./i18n";
|
||||
|
||||
export type TrackerType =
|
||||
| "COOKIE"
|
||||
| "LOCAL_STORAGE"
|
||||
| "SESSION_STORAGE"
|
||||
| "INDEXED_DB"
|
||||
| "CACHE_STORAGE";
|
||||
|
||||
export interface CookieItem {
|
||||
name: string;
|
||||
tracker_type: TrackerType;
|
||||
max_age_seconds: number | null;
|
||||
description: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user