@ecomconsult/consentkit 0.5.5 → 0.5.6

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 CHANGED
@@ -555,6 +555,11 @@ Removing it is a supported, first-class option — no obligation, no nag:
555
555
  node tools/build-inline.mjs --langs=en,ru --no-branding # block without it
556
556
  ```
557
557
 
558
+ The line is `branding.poweredBy.text`; with `language: 'auto'` supply
559
+ `branding.poweredBy.texts` instead — `{ ru: '…', ro: '…', en: '…' }`, resolved
560
+ against the language the banner actually picked (`texts[lang]` → base code →
561
+ `texts.en` → `text`), so the attribution matches what the visitor is reading.
562
+
558
563
  If you write the config by hand, simply omit the `branding` object; nothing
559
564
  renders without it. Either way costs you ~200 bytes, not a licence: the client
560
565
  is MIT and the line is yours to drop.
@@ -28,7 +28,7 @@ export function undecidedState() {
28
28
  */
29
29
  export function createStub() {
30
30
  const stub = {
31
- version: '0.5.5',
31
+ version: '0.5.6',
32
32
  config: {},
33
33
  init: function () { return undecidedState(); },
34
34
  allowed: function (cat) { return cat === 'necessary'; },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecomconsult/consentkit",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "description": "GDPR cookie consent core with blocking engine, Shadow DOM UI and Google Consent Mode v2. Zero dependencies, no build step.",
5
5
  "repository": {
6
6
  "type": "git",
package/src/ck-core.js CHANGED
@@ -1537,7 +1537,7 @@
1537
1537
  // Public API
1538
1538
  // ---------------------------------------------------------------------------
1539
1539
  var ConsentKit = {
1540
- version: '0.5.5',
1540
+ version: '0.5.6',
1541
1541
  config: config,
1542
1542
 
1543
1543
  init: function (userConfig) {
@@ -348,6 +348,34 @@
348
348
  return out.join('\n');
349
349
  }
350
350
 
351
+ /* Pick the attribution line for the language the banner actually resolved to.
352
+
353
+ A SaaS server renders one config per site but cannot know the visitor's
354
+ language: with `language: 'auto'` the code that decides is ck-ui's
355
+ resolveLang(), in the browser, long after the config was serialised. So a
356
+ single `poweredBy.text` produced "Made by E-COM Consult" under a fully
357
+ Russian banner. `poweredBy.texts` lets the server send every line it has
358
+ and leaves the choice here, where the resolved language is known.
359
+
360
+ host.lang is the code ck-ui resolved ('ru', 'pt-br', ...). It is optional
361
+ on purpose: a page still running an older cached ck-ui.js passes no lang,
362
+ and that must degrade to the English/`text` line rather than throw. */
363
+ function pickPoweredByText(texts, lang, str) {
364
+ if (!texts || typeof texts !== 'object' || Array.isArray(texts)) return null;
365
+ var code = (typeof lang === 'string') ? lang.toLowerCase() : '';
366
+ // Own keys only. ck-ui's resolveLang() can only return a real locale key or
367
+ // 'en', so 'constructor' never arrives through the normal path — but `host`
368
+ // is caller-supplied on a published extension entry point, and reading an
369
+ // inherited key would hand str() a function instead of a missing line.
370
+ // Values go through str() as well, so anything non-string falls through.
371
+ function own(k) {
372
+ return (k && Object.prototype.hasOwnProperty.call(texts, k)) ? str(texts[k]) : null;
373
+ }
374
+ var hit = own(code);
375
+ if (!hit && code.length > 2) hit = own(code.slice(0, 2)); // ru-RU -> ru
376
+ return hit || own('en');
377
+ }
378
+
351
379
  /* Powered-by line. true -> localised default; object -> caller's text/url.
352
380
  Rendered after the actions in DOM order and styled quiet on purpose. */
353
381
  function buildPoweredBy(cfg, host) {
@@ -361,7 +389,8 @@
361
389
  if (pb === true) {
362
390
  text = T.poweredBy; // en fallback guaranteed by STR_KEYS
363
391
  } else if (typeof pb === 'object' && !Array.isArray(pb)) {
364
- text = str(pb.text) || T.poweredBy;
392
+ // texts[lang] -> texts[base] -> texts.en -> text -> T.poweredBy
393
+ text = pickPoweredByText(pb.texts, host.lang, str) || str(pb.text) || T.poweredBy;
365
394
  url = safeLinkUrl(pb.url);
366
395
  } else {
367
396
  return null;
@@ -467,12 +496,26 @@
467
496
  styling, so a config that gains a logo after the first ck:init has to
468
497
  rebuild rather than restyle. Returns '-' when there is no branding config,
469
498
  which is what keeps an unbranded page's signature stable. */
499
+ function textsSig(texts) {
500
+ if (!texts || typeof texts !== 'object' || Array.isArray(texts)) return '-';
501
+ var keys = [], k;
502
+ for (k in texts) {
503
+ if (Object.prototype.hasOwnProperty.call(texts, k) && str(texts[k])) keys.push(k);
504
+ }
505
+ keys.sort();
506
+ var out = [];
507
+ for (var i = 0; i < keys.length; i++) out.push(keys[i] + '=' + str(texts[keys[i]]));
508
+ return out.join(',');
509
+ }
510
+
470
511
  function brandSignature(cfg) {
471
512
  var b = brandingCfg(cfg);
472
513
  if (!b) return '-';
473
514
  var pb = b.poweredBy;
515
+ // texts is folded in with sorted keys so the signature is stable across key
516
+ // order — without it a server swapping only `texts` would not remount.
474
517
  var pbSig = (pb && typeof pb === 'object')
475
- ? 'o:' + String(pb.text || '') + ':' + String(pb.url || '')
518
+ ? 'o:' + String(pb.text || '') + ':' + String(pb.url || '') + ':' + textsSig(pb.texts)
476
519
  : String(!!pb);
477
520
  // Logos are hashed by length + head so a long data: URI does not bloat the key.
478
521
  function tag(v) {
package/src/ck-ui.js CHANGED
@@ -370,8 +370,12 @@
370
370
  return (b && typeof b === 'object') ? b : null;
371
371
  }
372
372
 
373
+ /* LANG travels with T: an extension that renders language-dependent text of
374
+ its own (branding.poweredBy.texts) needs the code the banner resolved to,
375
+ which only this file knows — the config may say 'auto' and the answer then
376
+ comes from the visitor's browser at mount time. */
373
377
  function extHost() {
374
- return { el: el, str: str, T: T };
378
+ return { el: el, str: str, T: T, lang: LANG };
375
379
  }
376
380
 
377
381
  function buildBrandLogo(cfg) {
@@ -427,6 +431,7 @@
427
431
  var mountedSig = null;
428
432
  var host = null, root = null;
429
433
  var T = DICT.en;
434
+ var LANG = 'en'; // the code T was built from, reassigned per mount
430
435
  var nodes = {}; // banner/panel/fab refs
431
436
  var switches = {}; // category -> button
432
437
  var panelOpen = false;
@@ -1649,7 +1654,8 @@
1649
1654
  }
1650
1655
 
1651
1656
  var table = localeTable(); // read at render time
1652
- T = buildStrings(resolveLang(cfg && cfg.language, table), table);
1657
+ LANG = resolveLang(cfg && cfg.language, table);
1658
+ T = buildStrings(LANG, table);
1653
1659
 
1654
1660
  host = document.getElementById('ck-root');
1655
1661
  if (!host) {