@ecomconsult/consentkit 0.5.1 → 0.5.2
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/npm/internal-stub.mjs +1 -1
- package/package.json +1 -1
- package/src/ck-core.js +1 -1
- package/src/ck-debug.js +22 -5
- package/src/ck-ui.js +124 -1
package/npm/internal-stub.mjs
CHANGED
|
@@ -28,7 +28,7 @@ export function undecidedState() {
|
|
|
28
28
|
*/
|
|
29
29
|
export function createStub() {
|
|
30
30
|
const stub = {
|
|
31
|
-
version: '0.5.
|
|
31
|
+
version: '0.5.2',
|
|
32
32
|
config: {},
|
|
33
33
|
init: function () { return undecidedState(); },
|
|
34
34
|
allowed: function (cat) { return cat === 'necessary'; },
|
package/package.json
CHANGED
package/src/ck-core.js
CHANGED
package/src/ck-debug.js
CHANGED
|
@@ -203,9 +203,10 @@
|
|
|
203
203
|
themeMode: 'тема',
|
|
204
204
|
themeModeLight: 'светлая',
|
|
205
205
|
themeModeDark: 'тёмная',
|
|
206
|
-
themeFont: '
|
|
207
|
-
themeFontInherit: '
|
|
206
|
+
themeFont: 'Шрифт',
|
|
207
|
+
themeFontInherit: 'наследуется',
|
|
208
208
|
themeFontSystem: 'системный',
|
|
209
|
+
themeFontPage: 'со страницы',
|
|
209
210
|
themeRadius: 'скругления',
|
|
210
211
|
themeCard: 'карточка',
|
|
211
212
|
themeBtn: 'кнопки',
|
|
@@ -262,9 +263,10 @@
|
|
|
262
263
|
themeMode: 'theme',
|
|
263
264
|
themeModeLight: 'light',
|
|
264
265
|
themeModeDark: 'dark',
|
|
265
|
-
themeFont: '
|
|
266
|
-
themeFontInherit: '
|
|
266
|
+
themeFont: 'Font',
|
|
267
|
+
themeFontInherit: 'inherited',
|
|
267
268
|
themeFontSystem: 'system',
|
|
269
|
+
themeFontPage: 'from the page',
|
|
268
270
|
themeRadius: 'radii',
|
|
269
271
|
themeCard: 'card',
|
|
270
272
|
themeBtn: 'buttons',
|
|
@@ -598,6 +600,21 @@
|
|
|
598
600
|
return typeof r === 'number' && isFinite(r) ? (Math.round(r * 100) / 100) + ':1' : '?';
|
|
599
601
|
}
|
|
600
602
|
|
|
603
|
+
/* «Шрифт: <значение> (со страницы | системный | наследуется)».
|
|
604
|
+
theme.font:'system' is a fixed stack; otherwise the UI samples real page
|
|
605
|
+
text and only falls back to CSS `inherit` when the page states no family of
|
|
606
|
+
its own — the three cases have to be told apart, because «наследуется» on a
|
|
607
|
+
site whose body is unstyled is exactly the Times bug being diagnosed. */
|
|
608
|
+
function fontRow(built, T) {
|
|
609
|
+
if (built.font !== 'inherit') return built.font + ' (' + T.themeFontSystem + ')';
|
|
610
|
+
var page = null;
|
|
611
|
+
try {
|
|
612
|
+
if (CK && typeof CK._resolvePageFont === 'function') page = CK._resolvePageFont();
|
|
613
|
+
} catch (e) { page = null; }
|
|
614
|
+
return page ? page + ' (' + T.themeFontPage + ')'
|
|
615
|
+
: 'inherit (' + T.themeFontInherit + ')';
|
|
616
|
+
}
|
|
617
|
+
|
|
601
618
|
// Resolved lazily, not at parse time: this file runs before ConsentKit.init()
|
|
602
619
|
// has merged the site's config, so asking for the language now would always
|
|
603
620
|
// read the built-in default. Re-resolved on every render so a page that
|
|
@@ -749,7 +766,7 @@
|
|
|
749
766
|
sT.appendChild(defs([
|
|
750
767
|
[T.themeMode, (dark ? T.themeModeDark : T.themeModeLight) +
|
|
751
768
|
(built.mode === 'auto' ? ' (auto)' : '')],
|
|
752
|
-
[T.themeFont, built
|
|
769
|
+
[T.themeFont, fontRow(built, T)],
|
|
753
770
|
[T.themeRadius, T.themeCard + ' ' + built.radius.card + 'px · ' +
|
|
754
771
|
T.themeBtn + ' ' + built.radius.button + 'px'],
|
|
755
772
|
[T.themeLink, lkTxt]
|
package/src/ck-ui.js
CHANGED
|
@@ -663,6 +663,109 @@
|
|
|
663
663
|
return (theme && theme.font === 'system') ? SYSTEM_FONT : 'inherit';
|
|
664
664
|
}
|
|
665
665
|
|
|
666
|
+
/* CSS `inherit` on the shadow root takes the family of the HOST <div>, which
|
|
667
|
+
hangs off <body>. On a site that sets its typeface on inner blocks and not
|
|
668
|
+
on body/html, body's computed family IS the browser default (Times), so the
|
|
669
|
+
banner came out in Times on a page that is entirely sans-serif. Reading the
|
|
670
|
+
family off real page TEXT instead is what «как на сайте» was always meant
|
|
671
|
+
to mean.
|
|
672
|
+
|
|
673
|
+
Split in two: pickPageFont is pure arithmetic over already-collected
|
|
674
|
+
samples (unit-testable in node, published on _contrast), resolvePageFont
|
|
675
|
+
does the DOM reading. */
|
|
676
|
+
|
|
677
|
+
// Families are compared as CSS grammar, not as strings: '"Google Sans"' and
|
|
678
|
+
// 'google sans' name the same face, and only the UA default must be rejected.
|
|
679
|
+
function normFamily(v) {
|
|
680
|
+
if (typeof v !== 'string') return '';
|
|
681
|
+
return v.replace(/["']/g, '').replace(/\s*,\s*/g, ',').trim().toLowerCase();
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/* First sample whose family differs from the UA default wins; null when the
|
|
685
|
+
page never states a family of its own (the caller then keeps `inherit`).
|
|
686
|
+
`samples` is [{ family }] in priority order. */
|
|
687
|
+
function pickPageFont(samples, uaDefault) {
|
|
688
|
+
if (!samples || typeof samples.length !== 'number') return null;
|
|
689
|
+
var ua = normFamily(uaDefault);
|
|
690
|
+
for (var i = 0; i < samples.length; i++) {
|
|
691
|
+
var s = samples[i];
|
|
692
|
+
var fam = s && typeof s.family === 'string' ? s.family.trim() : '';
|
|
693
|
+
if (!fam) continue; // unstyled / detached element
|
|
694
|
+
var norm = normFamily(fam);
|
|
695
|
+
if (!norm) continue;
|
|
696
|
+
if (ua && norm === ua) continue; // still the browser default
|
|
697
|
+
// The value lands in a generated stylesheet. getComputedStyle normalises,
|
|
698
|
+
// but a family that could close the declaration is never worth the risk.
|
|
699
|
+
if (/[;{}]|\/\*/.test(fam)) continue;
|
|
700
|
+
return fam;
|
|
701
|
+
}
|
|
702
|
+
return null;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// Ordered so the first hit is the most representative body text on the page.
|
|
706
|
+
var FONT_PROBES = ['main p', 'article p', '[role=main] p', 'p', 'h1', 'h2', 'a', 'button', 'li'];
|
|
707
|
+
|
|
708
|
+
function visibleOutsideHost(el) {
|
|
709
|
+
if (!el) return false;
|
|
710
|
+
if (host && (el === host || (host.contains && host.contains(el)))) return false;
|
|
711
|
+
try {
|
|
712
|
+
if (el.offsetParent !== null) return true;
|
|
713
|
+
return !!(el.getClientRects && el.getClientRects().length > 0);
|
|
714
|
+
} catch (e) { return false; }
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// The UA default is whatever an element states no opinion about, measured
|
|
718
|
+
// INSIDE the shadow root so `:host{all:initial}` is already in force.
|
|
719
|
+
function uaDefaultFamily() {
|
|
720
|
+
if (!root || typeof document === 'undefined') return '';
|
|
721
|
+
var probe = null;
|
|
722
|
+
try {
|
|
723
|
+
probe = document.createElement('span');
|
|
724
|
+
probe.style.setProperty('font-family', 'initial');
|
|
725
|
+
root.appendChild(probe);
|
|
726
|
+
return window.getComputedStyle(probe).fontFamily || '';
|
|
727
|
+
} catch (e) {
|
|
728
|
+
return '';
|
|
729
|
+
} finally {
|
|
730
|
+
try { if (probe && probe.parentNode) probe.parentNode.removeChild(probe); } catch (e2) { /* noop */ }
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// Cached at applyTheme time so the debug panel (which may open long before or
|
|
735
|
+
// after a remount) quotes the value the banner actually painted.
|
|
736
|
+
var pageFont = null;
|
|
737
|
+
|
|
738
|
+
function resolvePageFont() {
|
|
739
|
+
if (typeof document === 'undefined') return pageFont;
|
|
740
|
+
try {
|
|
741
|
+
var ua = uaDefaultFamily();
|
|
742
|
+
var samples = [];
|
|
743
|
+
var body = document.body;
|
|
744
|
+
if (body) {
|
|
745
|
+
try { samples.push({ family: window.getComputedStyle(body).fontFamily }); } catch (e) { /* noop */ }
|
|
746
|
+
}
|
|
747
|
+
for (var i = 0; i < FONT_PROBES.length; i++) {
|
|
748
|
+
// First VISIBLE match, not the first match if it happens to be visible:
|
|
749
|
+
// the leading <p> on a real page is often hidden a11y text, a template
|
|
750
|
+
// or an inert modal, and skipping straight to the next selector would
|
|
751
|
+
// throw away the page's body copy. Capped so a long article does not
|
|
752
|
+
// cost a layout read per node.
|
|
753
|
+
var el = null, list = null;
|
|
754
|
+
try { list = document.querySelectorAll(FONT_PROBES[i]); } catch (e) { list = null; }
|
|
755
|
+
if (!list) continue;
|
|
756
|
+
for (var j = 0; j < list.length && j < 5; j++) {
|
|
757
|
+
if (visibleOutsideHost(list[j])) { el = list[j]; break; }
|
|
758
|
+
}
|
|
759
|
+
if (!el) continue;
|
|
760
|
+
try { samples.push({ family: window.getComputedStyle(el).fontFamily }); } catch (e) { /* noop */ }
|
|
761
|
+
}
|
|
762
|
+
pageFont = pickPageFont(samples, ua);
|
|
763
|
+
} catch (e) {
|
|
764
|
+
pageFont = null;
|
|
765
|
+
}
|
|
766
|
+
return pageFont;
|
|
767
|
+
}
|
|
768
|
+
|
|
666
769
|
/* --------------------------------------------------- button resolution */
|
|
667
770
|
|
|
668
771
|
var BTN_ROLES = ['accept', 'reject', 'settings'];
|
|
@@ -919,9 +1022,21 @@
|
|
|
919
1022
|
function applyTheme(cfg) {
|
|
920
1023
|
if (!host || !nodes.themeStyle) return;
|
|
921
1024
|
var built = buildThemeCss(cfg);
|
|
1025
|
+
// `inherit` would take the family of the host <div> — i.e. of <body>, which
|
|
1026
|
+
// on many sites still carries the browser default. Overwrite the token with
|
|
1027
|
+
// the family real page text is set in. Appended AFTER built.css so the two
|
|
1028
|
+
// equal-specificity :host rules resolve in source order; buildThemeCss stays
|
|
1029
|
+
// pure and DOM-free (the theme editor and the debug panel both call it).
|
|
1030
|
+
var fontCss = '';
|
|
1031
|
+
if (built.font === 'inherit') {
|
|
1032
|
+
var page = resolvePageFont();
|
|
1033
|
+
if (page) fontCss = '\n:host{--ck-font:' + page + '}';
|
|
1034
|
+
} else {
|
|
1035
|
+
pageFont = null; // theme.font:'system' opts out
|
|
1036
|
+
}
|
|
922
1037
|
// Brand rules ride along in the same sheet: the dark/light logo swap depends
|
|
923
1038
|
// on theme.mode, so it must be rebuilt whenever the palette is.
|
|
924
|
-
nodes.themeStyle.textContent = built.css + '\n' + buildBrandCss(cfg); // replace, never append
|
|
1039
|
+
nodes.themeStyle.textContent = built.css + fontCss + '\n' + buildBrandCss(cfg); // replace, never append
|
|
925
1040
|
host.classList.remove('ck-mode-dark', 'ck-mode-light');
|
|
926
1041
|
if (built.mode === 'dark') host.classList.add('ck-mode-dark');
|
|
927
1042
|
else if (built.mode === 'light') host.classList.add('ck-mode-light');
|
|
@@ -1437,9 +1552,17 @@
|
|
|
1437
1552
|
resolveButtonStyles: resolveButtonStyles,
|
|
1438
1553
|
resolveRadius: resolveRadius,
|
|
1439
1554
|
resolveFont: resolveFont,
|
|
1555
|
+
pickPageFont: pickPageFont,
|
|
1440
1556
|
resolveDetails: resolveDetails,
|
|
1441
1557
|
buildThemeCss: buildThemeCss
|
|
1442
1558
|
};
|
|
1559
|
+
// The page-font probe reads the DOM, so it is not part of the pure block —
|
|
1560
|
+
// but the debug panel must be able to quote the family the banner painted
|
|
1561
|
+
// rather than guess at it. Safe to call before mount: with no shadow root
|
|
1562
|
+
// to measure the UA default against it simply returns the cache (null).
|
|
1563
|
+
ck._resolvePageFont = function () {
|
|
1564
|
+
return (typeof document === 'undefined' || !root) ? pageFont : resolvePageFont();
|
|
1565
|
+
};
|
|
1443
1566
|
})();
|
|
1444
1567
|
|
|
1445
1568
|
// SSR-safe: with no DOM there is nothing to render or listen to, so importing
|