@scalemule/news-publication 0.0.10 → 0.0.12
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/cookie-consent.css +131 -0
- package/dist/{chunk-RNXTBN5Z.js → chunk-CWZWU4HE.js} +96 -1
- package/dist/{chunk-5QHNNRVQ.js → chunk-EKQXS63J.js} +21 -7
- package/dist/{chunk-AYSBXLOT.js → chunk-ZSA6YQBV.js} +1 -1
- package/dist/cookie-consent-banner.cjs +102 -6
- package/dist/cookie-consent-banner.d.cts +5 -1
- package/dist/cookie-consent-banner.d.ts +5 -1
- package/dist/cookie-consent-banner.js +2 -2
- package/dist/cookie-settings-view.js +2 -2
- package/dist/index.cjs +119 -6
- package/dist/index.d.cts +23 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.js +3 -3
- package/marketplace.css +79 -19
- package/package.json +1 -1
- package/tokens/broadsheet.css +28 -0
package/cookie-consent.css
CHANGED
|
@@ -417,3 +417,134 @@
|
|
|
417
417
|
align-items: center;
|
|
418
418
|
gap: 0.75rem;
|
|
419
419
|
}
|
|
420
|
+
|
|
421
|
+
/* ==========================================================================
|
|
422
|
+
Dark Theme (Evening Edition) support
|
|
423
|
+
========================================================================== */
|
|
424
|
+
:root[data-theme="dark"] .sm-cookie-banner-card,
|
|
425
|
+
[data-theme="dark"] .sm-cookie-banner-card,
|
|
426
|
+
.publication[data-theme="dark"] .sm-cookie-banner-card {
|
|
427
|
+
background: rgba(22, 26, 23, 0.96);
|
|
428
|
+
border-color: rgba(255, 255, 255, 0.12);
|
|
429
|
+
color: #eaece8;
|
|
430
|
+
box-shadow: 0 20px 40px -15px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.08);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
:root[data-theme="dark"] .sm-cookie-banner-title,
|
|
434
|
+
[data-theme="dark"] .sm-cookie-banner-title,
|
|
435
|
+
.publication[data-theme="dark"] .sm-cookie-banner-title {
|
|
436
|
+
color: #ffffff;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
:root[data-theme="dark"] .sm-cookie-banner-text,
|
|
440
|
+
[data-theme="dark"] .sm-cookie-banner-text,
|
|
441
|
+
.publication[data-theme="dark"] .sm-cookie-banner-text {
|
|
442
|
+
color: #c5cbc6;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
:root[data-theme="dark"] .sm-cookie-banner-link,
|
|
446
|
+
[data-theme="dark"] .sm-cookie-banner-link,
|
|
447
|
+
.publication[data-theme="dark"] .sm-cookie-banner-link {
|
|
448
|
+
color: #ffffff;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
:root[data-theme="dark"] .sm-cookie-btn-secondary,
|
|
452
|
+
[data-theme="dark"] .sm-cookie-btn-secondary,
|
|
453
|
+
.publication[data-theme="dark"] .sm-cookie-btn-secondary {
|
|
454
|
+
background: rgba(255, 255, 255, 0.1);
|
|
455
|
+
color: #ffffff;
|
|
456
|
+
border-color: rgba(255, 255, 255, 0.18);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
:root[data-theme="dark"] .sm-cookie-btn-secondary:hover,
|
|
460
|
+
[data-theme="dark"] .sm-cookie-btn-secondary:hover,
|
|
461
|
+
.publication[data-theme="dark"] .sm-cookie-btn-secondary:hover {
|
|
462
|
+
background: rgba(255, 255, 255, 0.18);
|
|
463
|
+
border-color: rgba(255, 255, 255, 0.3);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
:root[data-theme="dark"] .sm-cookie-details-modal,
|
|
467
|
+
[data-theme="dark"] .sm-cookie-details-modal,
|
|
468
|
+
.publication[data-theme="dark"] .sm-cookie-details-modal {
|
|
469
|
+
background: #161a17;
|
|
470
|
+
color: #eaece8;
|
|
471
|
+
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
:root[data-theme="dark"] .sm-cookie-details-header,
|
|
475
|
+
[data-theme="dark"] .sm-cookie-details-header,
|
|
476
|
+
.publication[data-theme="dark"] .sm-cookie-details-header {
|
|
477
|
+
border-bottom-color: #29302a;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
:root[data-theme="dark"] .sm-cookie-details-title,
|
|
481
|
+
[data-theme="dark"] .sm-cookie-details-title,
|
|
482
|
+
.publication[data-theme="dark"] .sm-cookie-details-title {
|
|
483
|
+
color: #ffffff;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
:root[data-theme="dark"] .sm-cookie-details-close,
|
|
487
|
+
[data-theme="dark"] .sm-cookie-details-close,
|
|
488
|
+
.publication[data-theme="dark"] .sm-cookie-details-close {
|
|
489
|
+
color: #959e96;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
:root[data-theme="dark"] .sm-cookie-details-close:hover,
|
|
493
|
+
[data-theme="dark"] .sm-cookie-details-close:hover,
|
|
494
|
+
.publication[data-theme="dark"] .sm-cookie-details-close:hover {
|
|
495
|
+
background: rgba(255, 255, 255, 0.08);
|
|
496
|
+
color: #ffffff;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
:root[data-theme="dark"] .sm-cookie-category,
|
|
500
|
+
[data-theme="dark"] .sm-cookie-category,
|
|
501
|
+
.publication[data-theme="dark"] .sm-cookie-category {
|
|
502
|
+
background: #1a1e1b;
|
|
503
|
+
border-color: #29302a;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
:root[data-theme="dark"] .sm-cookie-cat-title,
|
|
507
|
+
[data-theme="dark"] .sm-cookie-cat-title,
|
|
508
|
+
.publication[data-theme="dark"] .sm-cookie-cat-title {
|
|
509
|
+
color: #ffffff;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
:root[data-theme="dark"] .sm-cookie-cat-desc,
|
|
513
|
+
[data-theme="dark"] .sm-cookie-cat-desc,
|
|
514
|
+
.publication[data-theme="dark"] .sm-cookie-cat-desc {
|
|
515
|
+
color: #959e96;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
:root[data-theme="dark"] .sm-cookie-table-wrapper,
|
|
519
|
+
[data-theme="dark"] .sm-cookie-table-wrapper,
|
|
520
|
+
.publication[data-theme="dark"] .sm-cookie-table-wrapper {
|
|
521
|
+
border-color: #29302a;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
:root[data-theme="dark"] .sm-cookie-table th,
|
|
525
|
+
[data-theme="dark"] .sm-cookie-table th,
|
|
526
|
+
.publication[data-theme="dark"] .sm-cookie-table th {
|
|
527
|
+
background: #131514;
|
|
528
|
+
color: #959e96;
|
|
529
|
+
border-bottom-color: #29302a;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
:root[data-theme="dark"] .sm-cookie-table td,
|
|
533
|
+
[data-theme="dark"] .sm-cookie-table td,
|
|
534
|
+
.publication[data-theme="dark"] .sm-cookie-table td {
|
|
535
|
+
color: #eaece8;
|
|
536
|
+
border-bottom-color: #29302a;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
:root[data-theme="dark"] .sm-cookie-code,
|
|
540
|
+
[data-theme="dark"] .sm-cookie-code,
|
|
541
|
+
.publication[data-theme="dark"] .sm-cookie-code {
|
|
542
|
+
background: #252b27;
|
|
543
|
+
color: #ffffff;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
:root[data-theme="dark"] .sm-cookie-save-bar,
|
|
547
|
+
[data-theme="dark"] .sm-cookie-save-bar,
|
|
548
|
+
.publication[data-theme="dark"] .sm-cookie-save-bar {
|
|
549
|
+
border-top-color: #29302a;
|
|
550
|
+
}
|
|
@@ -157,6 +157,101 @@ function getCookieConsent() {
|
|
|
157
157
|
}
|
|
158
158
|
return memoryConsent;
|
|
159
159
|
}
|
|
160
|
+
var EU_EEA_UK_COUNTRIES = /* @__PURE__ */ new Set([
|
|
161
|
+
"AT",
|
|
162
|
+
"BE",
|
|
163
|
+
"BG",
|
|
164
|
+
"HR",
|
|
165
|
+
"CY",
|
|
166
|
+
"CZ",
|
|
167
|
+
"DK",
|
|
168
|
+
"EE",
|
|
169
|
+
"FI",
|
|
170
|
+
"FR",
|
|
171
|
+
"DE",
|
|
172
|
+
"GR",
|
|
173
|
+
"HU",
|
|
174
|
+
"IE",
|
|
175
|
+
"IT",
|
|
176
|
+
"LV",
|
|
177
|
+
"LT",
|
|
178
|
+
"LU",
|
|
179
|
+
"MT",
|
|
180
|
+
"NL",
|
|
181
|
+
"PL",
|
|
182
|
+
"PT",
|
|
183
|
+
"RO",
|
|
184
|
+
"SK",
|
|
185
|
+
"SI",
|
|
186
|
+
"ES",
|
|
187
|
+
"SE",
|
|
188
|
+
"IS",
|
|
189
|
+
"LI",
|
|
190
|
+
"NO",
|
|
191
|
+
"GB",
|
|
192
|
+
"CH"
|
|
193
|
+
]);
|
|
194
|
+
function isGeoConsentRequired(countryCode) {
|
|
195
|
+
if (countryCode && typeof countryCode === "string") {
|
|
196
|
+
const code = countryCode.trim().toUpperCase();
|
|
197
|
+
if (code.length === 2) {
|
|
198
|
+
return EU_EEA_UK_COUNTRIES.has(code);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (typeof window !== "undefined") {
|
|
202
|
+
try {
|
|
203
|
+
const cached = readCookie("sm_geo_country") || window.localStorage?.getItem("sm_geo_country");
|
|
204
|
+
if (cached && typeof cached === "string" && cached.length === 2) {
|
|
205
|
+
return EU_EEA_UK_COUNTRIES.has(cached.toUpperCase());
|
|
206
|
+
}
|
|
207
|
+
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
208
|
+
if (tz) {
|
|
209
|
+
if (/^(America|US|Canada|Pacific)\//i.test(tz)) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
if (/^(Europe|Atlantic\/Reykjavik|Atlantic\/Canary|Atlantic\/Faeroe|Atlantic\/Madeira|Atlantic\/Azores|WET|CET|EET|GMT)/i.test(tz)) {
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
} catch {
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
function checkUrlConsentBridge() {
|
|
222
|
+
if (typeof window === "undefined") return false;
|
|
223
|
+
try {
|
|
224
|
+
const url = new URL(window.location.href);
|
|
225
|
+
const param = url.searchParams.get("sm_consent");
|
|
226
|
+
if (!param) return false;
|
|
227
|
+
if (param === "accepted" || param === "1" || param === "all") {
|
|
228
|
+
acceptAllCookies();
|
|
229
|
+
} else if (param === "rejected" || param === "0" || param === "essential") {
|
|
230
|
+
rejectOptionalCookies();
|
|
231
|
+
} else {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
url.searchParams.delete("sm_consent");
|
|
235
|
+
const newSearch = url.searchParams.toString() ? `?${url.searchParams.toString()}` : "";
|
|
236
|
+
window.history.replaceState(null, "", `${url.pathname}${newSearch}${url.hash}`);
|
|
237
|
+
return true;
|
|
238
|
+
} catch {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function decorateNetworkUrl(targetUrl) {
|
|
243
|
+
const consent = getCookieConsent();
|
|
244
|
+
if (!consent) return targetUrl;
|
|
245
|
+
try {
|
|
246
|
+
const base = typeof window !== "undefined" ? window.location.origin : "https://localhost";
|
|
247
|
+
const url = new URL(targetUrl, base);
|
|
248
|
+
const value = consent.preferences.performance || consent.preferences.advertising ? "1" : "0";
|
|
249
|
+
url.searchParams.set("sm_consent", value);
|
|
250
|
+
return url.toString();
|
|
251
|
+
} catch {
|
|
252
|
+
return targetUrl;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
160
255
|
function hasConsented() {
|
|
161
256
|
return getCookieConsent() !== null;
|
|
162
257
|
}
|
|
@@ -256,4 +351,4 @@ async function recordConsentToCompliance(record, options) {
|
|
|
256
351
|
}
|
|
257
352
|
}
|
|
258
353
|
|
|
259
|
-
export { COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, acceptAllCookies, clearCookieConsent, getCookieConsent, hasConsented, isCategoryAllowed, recordConsentToCompliance, rejectOptionalCookies, setCookieConsent };
|
|
354
|
+
export { COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, acceptAllCookies, checkUrlConsentBridge, clearCookieConsent, decorateNetworkUrl, getCookieConsent, hasConsented, isCategoryAllowed, isGeoConsentRequired, recordConsentToCompliance, rejectOptionalCookies, setCookieConsent };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { hasConsented, COOKIE_CONSENT_EVENT, acceptAllCookies, recordConsentToCompliance, rejectOptionalCookies } from './chunk-
|
|
2
|
+
import { checkUrlConsentBridge, hasConsented, isGeoConsentRequired, COOKIE_CONSENT_EVENT, acceptAllCookies, recordConsentToCompliance, rejectOptionalCookies } from './chunk-CWZWU4HE.js';
|
|
3
3
|
import { useState, useEffect } from 'react';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -9,16 +9,30 @@ function CookieConsentBanner({
|
|
|
9
9
|
settingsUrl = "/cookies",
|
|
10
10
|
className = "",
|
|
11
11
|
publicationSlug,
|
|
12
|
-
complianceEndpoint = "/api/compliance/consent"
|
|
12
|
+
complianceEndpoint = "/api/compliance/consent",
|
|
13
|
+
countryCode,
|
|
14
|
+
forceShow = false
|
|
13
15
|
}) {
|
|
14
16
|
const [mounted, setMounted] = useState(false);
|
|
15
17
|
const [visible, setVisible] = useState(false);
|
|
16
18
|
useEffect(() => {
|
|
17
19
|
setMounted(true);
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
return
|
|
20
|
+
if (checkUrlConsentBridge()) {
|
|
21
|
+
setVisible(false);
|
|
22
|
+
return;
|
|
21
23
|
}
|
|
24
|
+
if (hasConsented()) {
|
|
25
|
+
setVisible(false);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (!forceShow && !isGeoConsentRequired(countryCode)) {
|
|
29
|
+
setVisible(false);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const timer = window.setTimeout(() => setVisible(true), 300);
|
|
33
|
+
return () => window.clearTimeout(timer);
|
|
34
|
+
}, [countryCode, forceShow]);
|
|
35
|
+
useEffect(() => {
|
|
22
36
|
const onConsentChange = () => {
|
|
23
37
|
if (hasConsented()) {
|
|
24
38
|
setVisible(false);
|
|
@@ -45,11 +59,11 @@ function CookieConsentBanner({
|
|
|
45
59
|
});
|
|
46
60
|
};
|
|
47
61
|
const defaultText = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
48
|
-
"We use cookies and
|
|
62
|
+
"We use cookies and device data to analyze performance, support local sponsors, and remember your reading preferences across our news network. View",
|
|
49
63
|
" ",
|
|
50
64
|
/* @__PURE__ */ jsx("a", { href: settingsUrl, className: "sm-cookie-banner-link", children: "Cookie Settings" }),
|
|
51
65
|
" ",
|
|
52
|
-
"for
|
|
66
|
+
"for details."
|
|
53
67
|
] });
|
|
54
68
|
return /* @__PURE__ */ jsx(
|
|
55
69
|
"aside",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { getCookieConsent, DEFAULT_PREFERENCES_ACCEPTED, COOKIE_CATEGORIES, setCookieConsent, recordConsentToCompliance, DEFAULT_PREFERENCES_REJECTED } from './chunk-
|
|
2
|
+
import { getCookieConsent, DEFAULT_PREFERENCES_ACCEPTED, COOKIE_CATEGORIES, setCookieConsent, recordConsentToCompliance, DEFAULT_PREFERENCES_REJECTED } from './chunk-CWZWU4HE.js';
|
|
3
3
|
import { useState, useEffect } from 'react';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -53,6 +53,88 @@ function getCookieConsent() {
|
|
|
53
53
|
}
|
|
54
54
|
return memoryConsent;
|
|
55
55
|
}
|
|
56
|
+
var EU_EEA_UK_COUNTRIES = /* @__PURE__ */ new Set([
|
|
57
|
+
"AT",
|
|
58
|
+
"BE",
|
|
59
|
+
"BG",
|
|
60
|
+
"HR",
|
|
61
|
+
"CY",
|
|
62
|
+
"CZ",
|
|
63
|
+
"DK",
|
|
64
|
+
"EE",
|
|
65
|
+
"FI",
|
|
66
|
+
"FR",
|
|
67
|
+
"DE",
|
|
68
|
+
"GR",
|
|
69
|
+
"HU",
|
|
70
|
+
"IE",
|
|
71
|
+
"IT",
|
|
72
|
+
"LV",
|
|
73
|
+
"LT",
|
|
74
|
+
"LU",
|
|
75
|
+
"MT",
|
|
76
|
+
"NL",
|
|
77
|
+
"PL",
|
|
78
|
+
"PT",
|
|
79
|
+
"RO",
|
|
80
|
+
"SK",
|
|
81
|
+
"SI",
|
|
82
|
+
"ES",
|
|
83
|
+
"SE",
|
|
84
|
+
"IS",
|
|
85
|
+
"LI",
|
|
86
|
+
"NO",
|
|
87
|
+
"GB",
|
|
88
|
+
"CH"
|
|
89
|
+
]);
|
|
90
|
+
function isGeoConsentRequired(countryCode) {
|
|
91
|
+
if (countryCode && typeof countryCode === "string") {
|
|
92
|
+
const code = countryCode.trim().toUpperCase();
|
|
93
|
+
if (code.length === 2) {
|
|
94
|
+
return EU_EEA_UK_COUNTRIES.has(code);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (typeof window !== "undefined") {
|
|
98
|
+
try {
|
|
99
|
+
const cached = readCookie("sm_geo_country") || window.localStorage?.getItem("sm_geo_country");
|
|
100
|
+
if (cached && typeof cached === "string" && cached.length === 2) {
|
|
101
|
+
return EU_EEA_UK_COUNTRIES.has(cached.toUpperCase());
|
|
102
|
+
}
|
|
103
|
+
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
104
|
+
if (tz) {
|
|
105
|
+
if (/^(America|US|Canada|Pacific)\//i.test(tz)) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
if (/^(Europe|Atlantic\/Reykjavik|Atlantic\/Canary|Atlantic\/Faeroe|Atlantic\/Madeira|Atlantic\/Azores|WET|CET|EET|GMT)/i.test(tz)) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
} catch {
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
function checkUrlConsentBridge() {
|
|
118
|
+
if (typeof window === "undefined") return false;
|
|
119
|
+
try {
|
|
120
|
+
const url = new URL(window.location.href);
|
|
121
|
+
const param = url.searchParams.get("sm_consent");
|
|
122
|
+
if (!param) return false;
|
|
123
|
+
if (param === "accepted" || param === "1" || param === "all") {
|
|
124
|
+
acceptAllCookies();
|
|
125
|
+
} else if (param === "rejected" || param === "0" || param === "essential") {
|
|
126
|
+
rejectOptionalCookies();
|
|
127
|
+
} else {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
url.searchParams.delete("sm_consent");
|
|
131
|
+
const newSearch = url.searchParams.toString() ? `?${url.searchParams.toString()}` : "";
|
|
132
|
+
window.history.replaceState(null, "", `${url.pathname}${newSearch}${url.hash}`);
|
|
133
|
+
return true;
|
|
134
|
+
} catch {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
56
138
|
function hasConsented() {
|
|
57
139
|
return getCookieConsent() !== null;
|
|
58
140
|
}
|
|
@@ -129,16 +211,30 @@ function CookieConsentBanner({
|
|
|
129
211
|
settingsUrl = "/cookies",
|
|
130
212
|
className = "",
|
|
131
213
|
publicationSlug,
|
|
132
|
-
complianceEndpoint = "/api/compliance/consent"
|
|
214
|
+
complianceEndpoint = "/api/compliance/consent",
|
|
215
|
+
countryCode,
|
|
216
|
+
forceShow = false
|
|
133
217
|
}) {
|
|
134
218
|
const [mounted, setMounted] = react.useState(false);
|
|
135
219
|
const [visible, setVisible] = react.useState(false);
|
|
136
220
|
react.useEffect(() => {
|
|
137
221
|
setMounted(true);
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
return
|
|
222
|
+
if (checkUrlConsentBridge()) {
|
|
223
|
+
setVisible(false);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (hasConsented()) {
|
|
227
|
+
setVisible(false);
|
|
228
|
+
return;
|
|
141
229
|
}
|
|
230
|
+
if (!forceShow && !isGeoConsentRequired(countryCode)) {
|
|
231
|
+
setVisible(false);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const timer = window.setTimeout(() => setVisible(true), 300);
|
|
235
|
+
return () => window.clearTimeout(timer);
|
|
236
|
+
}, [countryCode, forceShow]);
|
|
237
|
+
react.useEffect(() => {
|
|
142
238
|
const onConsentChange = () => {
|
|
143
239
|
if (hasConsented()) {
|
|
144
240
|
setVisible(false);
|
|
@@ -161,11 +257,11 @@ function CookieConsentBanner({
|
|
|
161
257
|
endpoint: complianceEndpoint});
|
|
162
258
|
};
|
|
163
259
|
const defaultText = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
164
|
-
"We use cookies and
|
|
260
|
+
"We use cookies and device data to analyze performance, support local sponsors, and remember your reading preferences across our news network. View",
|
|
165
261
|
" ",
|
|
166
262
|
/* @__PURE__ */ jsxRuntime.jsx("a", { href: settingsUrl, className: "sm-cookie-banner-link", children: "Cookie Settings" }),
|
|
167
263
|
" ",
|
|
168
|
-
"for
|
|
264
|
+
"for details."
|
|
169
265
|
] });
|
|
170
266
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
171
267
|
"aside",
|
|
@@ -13,7 +13,11 @@ interface CookieConsentBannerProps {
|
|
|
13
13
|
publicationSlug?: string;
|
|
14
14
|
/** Compliance recording endpoint. Default: "/api/compliance/consent" */
|
|
15
15
|
complianceEndpoint?: string;
|
|
16
|
+
/** Explicit ISO 3166-1 alpha-2 country code (e.g. from server headers or GeoIP) */
|
|
17
|
+
countryCode?: string | null;
|
|
18
|
+
/** Force display of banner regardless of visitor geography */
|
|
19
|
+
forceShow?: boolean;
|
|
16
20
|
}
|
|
17
|
-
declare function CookieConsentBanner({ title, text, settingsUrl, className, publicationSlug, complianceEndpoint, }: CookieConsentBannerProps): react__default.JSX.Element | null;
|
|
21
|
+
declare function CookieConsentBanner({ title, text, settingsUrl, className, publicationSlug, complianceEndpoint, countryCode, forceShow, }: CookieConsentBannerProps): react__default.JSX.Element | null;
|
|
18
22
|
|
|
19
23
|
export { CookieConsentBanner, type CookieConsentBannerProps };
|
|
@@ -13,7 +13,11 @@ interface CookieConsentBannerProps {
|
|
|
13
13
|
publicationSlug?: string;
|
|
14
14
|
/** Compliance recording endpoint. Default: "/api/compliance/consent" */
|
|
15
15
|
complianceEndpoint?: string;
|
|
16
|
+
/** Explicit ISO 3166-1 alpha-2 country code (e.g. from server headers or GeoIP) */
|
|
17
|
+
countryCode?: string | null;
|
|
18
|
+
/** Force display of banner regardless of visitor geography */
|
|
19
|
+
forceShow?: boolean;
|
|
16
20
|
}
|
|
17
|
-
declare function CookieConsentBanner({ title, text, settingsUrl, className, publicationSlug, complianceEndpoint, }: CookieConsentBannerProps): react__default.JSX.Element | null;
|
|
21
|
+
declare function CookieConsentBanner({ title, text, settingsUrl, className, publicationSlug, complianceEndpoint, countryCode, forceShow, }: CookieConsentBannerProps): react__default.JSX.Element | null;
|
|
18
22
|
|
|
19
23
|
export { CookieConsentBanner, type CookieConsentBannerProps };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { CookieConsentBanner } from './chunk-
|
|
3
|
-
import './chunk-
|
|
2
|
+
export { CookieConsentBanner } from './chunk-EKQXS63J.js';
|
|
3
|
+
import './chunk-CWZWU4HE.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { CookieSettingsView } from './chunk-
|
|
3
|
-
import './chunk-
|
|
2
|
+
export { CookieSettingsView } from './chunk-ZSA6YQBV.js';
|
|
3
|
+
import './chunk-CWZWU4HE.js';
|
package/dist/index.cjs
CHANGED
|
@@ -942,6 +942,101 @@ function getCookieConsent() {
|
|
|
942
942
|
}
|
|
943
943
|
return memoryConsent;
|
|
944
944
|
}
|
|
945
|
+
var EU_EEA_UK_COUNTRIES = /* @__PURE__ */ new Set([
|
|
946
|
+
"AT",
|
|
947
|
+
"BE",
|
|
948
|
+
"BG",
|
|
949
|
+
"HR",
|
|
950
|
+
"CY",
|
|
951
|
+
"CZ",
|
|
952
|
+
"DK",
|
|
953
|
+
"EE",
|
|
954
|
+
"FI",
|
|
955
|
+
"FR",
|
|
956
|
+
"DE",
|
|
957
|
+
"GR",
|
|
958
|
+
"HU",
|
|
959
|
+
"IE",
|
|
960
|
+
"IT",
|
|
961
|
+
"LV",
|
|
962
|
+
"LT",
|
|
963
|
+
"LU",
|
|
964
|
+
"MT",
|
|
965
|
+
"NL",
|
|
966
|
+
"PL",
|
|
967
|
+
"PT",
|
|
968
|
+
"RO",
|
|
969
|
+
"SK",
|
|
970
|
+
"SI",
|
|
971
|
+
"ES",
|
|
972
|
+
"SE",
|
|
973
|
+
"IS",
|
|
974
|
+
"LI",
|
|
975
|
+
"NO",
|
|
976
|
+
"GB",
|
|
977
|
+
"CH"
|
|
978
|
+
]);
|
|
979
|
+
function isGeoConsentRequired(countryCode) {
|
|
980
|
+
if (countryCode && typeof countryCode === "string") {
|
|
981
|
+
const code = countryCode.trim().toUpperCase();
|
|
982
|
+
if (code.length === 2) {
|
|
983
|
+
return EU_EEA_UK_COUNTRIES.has(code);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
if (typeof window !== "undefined") {
|
|
987
|
+
try {
|
|
988
|
+
const cached = readCookie("sm_geo_country") || window.localStorage?.getItem("sm_geo_country");
|
|
989
|
+
if (cached && typeof cached === "string" && cached.length === 2) {
|
|
990
|
+
return EU_EEA_UK_COUNTRIES.has(cached.toUpperCase());
|
|
991
|
+
}
|
|
992
|
+
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
993
|
+
if (tz) {
|
|
994
|
+
if (/^(America|US|Canada|Pacific)\//i.test(tz)) {
|
|
995
|
+
return false;
|
|
996
|
+
}
|
|
997
|
+
if (/^(Europe|Atlantic\/Reykjavik|Atlantic\/Canary|Atlantic\/Faeroe|Atlantic\/Madeira|Atlantic\/Azores|WET|CET|EET|GMT)/i.test(tz)) {
|
|
998
|
+
return true;
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
} catch {
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
return false;
|
|
1005
|
+
}
|
|
1006
|
+
function checkUrlConsentBridge() {
|
|
1007
|
+
if (typeof window === "undefined") return false;
|
|
1008
|
+
try {
|
|
1009
|
+
const url = new URL(window.location.href);
|
|
1010
|
+
const param = url.searchParams.get("sm_consent");
|
|
1011
|
+
if (!param) return false;
|
|
1012
|
+
if (param === "accepted" || param === "1" || param === "all") {
|
|
1013
|
+
acceptAllCookies();
|
|
1014
|
+
} else if (param === "rejected" || param === "0" || param === "essential") {
|
|
1015
|
+
rejectOptionalCookies();
|
|
1016
|
+
} else {
|
|
1017
|
+
return false;
|
|
1018
|
+
}
|
|
1019
|
+
url.searchParams.delete("sm_consent");
|
|
1020
|
+
const newSearch = url.searchParams.toString() ? `?${url.searchParams.toString()}` : "";
|
|
1021
|
+
window.history.replaceState(null, "", `${url.pathname}${newSearch}${url.hash}`);
|
|
1022
|
+
return true;
|
|
1023
|
+
} catch {
|
|
1024
|
+
return false;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
function decorateNetworkUrl(targetUrl) {
|
|
1028
|
+
const consent = getCookieConsent();
|
|
1029
|
+
if (!consent) return targetUrl;
|
|
1030
|
+
try {
|
|
1031
|
+
const base = typeof window !== "undefined" ? window.location.origin : "https://localhost";
|
|
1032
|
+
const url = new URL(targetUrl, base);
|
|
1033
|
+
const value = consent.preferences.performance || consent.preferences.advertising ? "1" : "0";
|
|
1034
|
+
url.searchParams.set("sm_consent", value);
|
|
1035
|
+
return url.toString();
|
|
1036
|
+
} catch {
|
|
1037
|
+
return targetUrl;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
945
1040
|
function hasConsented() {
|
|
946
1041
|
return getCookieConsent() !== null;
|
|
947
1042
|
}
|
|
@@ -1046,16 +1141,30 @@ function CookieConsentBanner({
|
|
|
1046
1141
|
settingsUrl = "/cookies",
|
|
1047
1142
|
className = "",
|
|
1048
1143
|
publicationSlug,
|
|
1049
|
-
complianceEndpoint = "/api/compliance/consent"
|
|
1144
|
+
complianceEndpoint = "/api/compliance/consent",
|
|
1145
|
+
countryCode,
|
|
1146
|
+
forceShow = false
|
|
1050
1147
|
}) {
|
|
1051
1148
|
const [mounted, setMounted] = react.useState(false);
|
|
1052
1149
|
const [visible, setVisible] = react.useState(false);
|
|
1053
1150
|
react.useEffect(() => {
|
|
1054
1151
|
setMounted(true);
|
|
1055
|
-
if (
|
|
1056
|
-
|
|
1057
|
-
return
|
|
1152
|
+
if (checkUrlConsentBridge()) {
|
|
1153
|
+
setVisible(false);
|
|
1154
|
+
return;
|
|
1058
1155
|
}
|
|
1156
|
+
if (hasConsented()) {
|
|
1157
|
+
setVisible(false);
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
if (!forceShow && !isGeoConsentRequired(countryCode)) {
|
|
1161
|
+
setVisible(false);
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
const timer = window.setTimeout(() => setVisible(true), 300);
|
|
1165
|
+
return () => window.clearTimeout(timer);
|
|
1166
|
+
}, [countryCode, forceShow]);
|
|
1167
|
+
react.useEffect(() => {
|
|
1059
1168
|
const onConsentChange = () => {
|
|
1060
1169
|
if (hasConsented()) {
|
|
1061
1170
|
setVisible(false);
|
|
@@ -1078,11 +1187,11 @@ function CookieConsentBanner({
|
|
|
1078
1187
|
endpoint: complianceEndpoint});
|
|
1079
1188
|
};
|
|
1080
1189
|
const defaultText = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1081
|
-
"We use cookies and
|
|
1190
|
+
"We use cookies and device data to analyze performance, support local sponsors, and remember your reading preferences across our news network. View",
|
|
1082
1191
|
" ",
|
|
1083
1192
|
/* @__PURE__ */ jsxRuntime.jsx("a", { href: settingsUrl, className: "sm-cookie-banner-link", children: "Cookie Settings" }),
|
|
1084
1193
|
" ",
|
|
1085
|
-
"for
|
|
1194
|
+
"for details."
|
|
1086
1195
|
] });
|
|
1087
1196
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1088
1197
|
"aside",
|
|
@@ -1662,6 +1771,7 @@ exports.CookieConsentBanner = CookieConsentBanner;
|
|
|
1662
1771
|
exports.CookieSettingsView = CookieSettingsView;
|
|
1663
1772
|
exports.DEFAULT_PREFERENCES_ACCEPTED = DEFAULT_PREFERENCES_ACCEPTED;
|
|
1664
1773
|
exports.DEFAULT_PREFERENCES_REJECTED = DEFAULT_PREFERENCES_REJECTED;
|
|
1774
|
+
exports.EU_EEA_UK_COUNTRIES = EU_EEA_UK_COUNTRIES;
|
|
1665
1775
|
exports.EVENTS = EVENTS;
|
|
1666
1776
|
exports.FEATURE_NAMES = FEATURE_NAMES;
|
|
1667
1777
|
exports.JOB_EMPLOYMENT_TYPES = JOB_EMPLOYMENT_TYPES;
|
|
@@ -1691,6 +1801,7 @@ exports.attribution = attribution;
|
|
|
1691
1801
|
exports.briefSummary = briefSummary;
|
|
1692
1802
|
exports.canHostMeetup = canHostMeetup;
|
|
1693
1803
|
exports.categoryLabel = categoryLabel;
|
|
1804
|
+
exports.checkUrlConsentBridge = checkUrlConsentBridge;
|
|
1694
1805
|
exports.classifiedPath = classifiedPath;
|
|
1695
1806
|
exports.classifiedSearchPath = classifiedSearchPath;
|
|
1696
1807
|
exports.clearCookieConsent = clearCookieConsent;
|
|
@@ -1700,6 +1811,7 @@ exports.composeEdition = composeEdition;
|
|
|
1700
1811
|
exports.dealDollars = dealDollars;
|
|
1701
1812
|
exports.dealGoPath = dealGoPath;
|
|
1702
1813
|
exports.dealsFeedPath = dealsFeedPath;
|
|
1814
|
+
exports.decorateNetworkUrl = decorateNetworkUrl;
|
|
1703
1815
|
exports.defaultRevalidateTargets = defaultRevalidateTargets;
|
|
1704
1816
|
exports.definePublication = definePublication;
|
|
1705
1817
|
exports.displayHeadline = displayHeadline;
|
|
@@ -1719,6 +1831,7 @@ exports.isAdult = isAdult;
|
|
|
1719
1831
|
exports.isCategoryAllowed = isCategoryAllowed;
|
|
1720
1832
|
exports.isClassifiedCategory = isClassifiedCategory;
|
|
1721
1833
|
exports.isEmploymentType = isEmploymentType;
|
|
1834
|
+
exports.isGeoConsentRequired = isGeoConsentRequired;
|
|
1722
1835
|
exports.jobEmployerBody = jobEmployerBody;
|
|
1723
1836
|
exports.jobOpeningBody = jobOpeningBody;
|
|
1724
1837
|
exports.jobPostingBody = jobPostingBody;
|
package/dist/index.d.cts
CHANGED
|
@@ -280,6 +280,28 @@ declare const COOKIE_CATEGORIES: CookieCategoryDefinition[];
|
|
|
280
280
|
* Checks HTTP cookie first, then localStorage fallback, then in-memory state.
|
|
281
281
|
*/
|
|
282
282
|
declare function getCookieConsent(): CookieConsentRecord | null;
|
|
283
|
+
/**
|
|
284
|
+
* ISO 3166-1 alpha-2 country codes for EU/EEA member states and the UK/Switzerland
|
|
285
|
+
* subject to the GDPR and ePrivacy Directive prior-consent requirement.
|
|
286
|
+
*/
|
|
287
|
+
declare const EU_EEA_UK_COUNTRIES: Set<string>;
|
|
288
|
+
/**
|
|
289
|
+
* Determine if cookie consent prior-opt-in banner is required based on visitor geography.
|
|
290
|
+
* For US readers (including California CCPA/CPRA), opt-in banners are not required.
|
|
291
|
+
* Returns true ONLY if the visitor is identified as being within an EU/EEA/UK jurisdiction.
|
|
292
|
+
*/
|
|
293
|
+
declare function isGeoConsentRequired(countryCode?: string | null): boolean;
|
|
294
|
+
/**
|
|
295
|
+
* Checks for a cross-domain network consent signal in the URL query (?sm_consent=accepted|rejected|1|0).
|
|
296
|
+
* If present, silently records the consent choice locally and removes the param from the address bar.
|
|
297
|
+
* Returns true if a consent signal was processed.
|
|
298
|
+
*/
|
|
299
|
+
declare function checkUrlConsentBridge(): boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Appends the current consent decision to an outgoing URL within the newspaper network
|
|
302
|
+
* so sister publications can adopt the user's choice without requiring a new banner prompt.
|
|
303
|
+
*/
|
|
304
|
+
declare function decorateNetworkUrl(targetUrl: string): string;
|
|
283
305
|
/**
|
|
284
306
|
* Check if the user has already provided an explicit consent decision.
|
|
285
307
|
*/
|
|
@@ -356,4 +378,4 @@ declare function subscribeTheme(listener: () => void): () => void;
|
|
|
356
378
|
*/
|
|
357
379
|
declare function themeInitScript(): string;
|
|
358
380
|
|
|
359
|
-
export { ANALYTICS_COOKIE, ANALYTICS_VERSION, type Attribution, BROADSHEET_THEME, COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, type CookieCategory, type CookieCategoryDefinition, type CookieConsentRecord, type CookieDisclosure, type CookiePreferences, CouponOffer, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, HomepageSelection, LAYOUT_COOKIE, NEWS_CACHE, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, SESSION_IDLE_MS, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, acceptAllCookies, activeNearby, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, clearCookieConsent, clearTheme, composeEdition, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getCookieConsent, getStoredTheme, getSystemTheme, hasConsented, inventoryCacheOptions, isCategoryAllowed, llmsText, matchesStoryTag, nearbyUpdates, newsArticleJsonLd, normalizedText, publicHttps, publicUrl, publicationJsonLd, publicationMeta, recordConsentToCompliance, referralCode, rejectOptionalCookies, resolveCoupon, resolveEffectiveTheme, resolveLayout, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setCookieConsent, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
|
|
381
|
+
export { ANALYTICS_COOKIE, ANALYTICS_VERSION, type Attribution, BROADSHEET_THEME, COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, type CookieCategory, type CookieCategoryDefinition, type CookieConsentRecord, type CookieDisclosure, type CookiePreferences, CouponOffer, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, HomepageSelection, LAYOUT_COOKIE, NEWS_CACHE, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, SESSION_IDLE_MS, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, acceptAllCookies, activeNearby, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, checkUrlConsentBridge, clearCookieConsent, clearTheme, composeEdition, decorateNetworkUrl, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getCookieConsent, getStoredTheme, getSystemTheme, hasConsented, inventoryCacheOptions, isCategoryAllowed, isGeoConsentRequired, llmsText, matchesStoryTag, nearbyUpdates, newsArticleJsonLd, normalizedText, publicHttps, publicUrl, publicationJsonLd, publicationMeta, recordConsentToCompliance, referralCode, rejectOptionalCookies, resolveCoupon, resolveEffectiveTheme, resolveLayout, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setCookieConsent, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
|
package/dist/index.d.ts
CHANGED
|
@@ -280,6 +280,28 @@ declare const COOKIE_CATEGORIES: CookieCategoryDefinition[];
|
|
|
280
280
|
* Checks HTTP cookie first, then localStorage fallback, then in-memory state.
|
|
281
281
|
*/
|
|
282
282
|
declare function getCookieConsent(): CookieConsentRecord | null;
|
|
283
|
+
/**
|
|
284
|
+
* ISO 3166-1 alpha-2 country codes for EU/EEA member states and the UK/Switzerland
|
|
285
|
+
* subject to the GDPR and ePrivacy Directive prior-consent requirement.
|
|
286
|
+
*/
|
|
287
|
+
declare const EU_EEA_UK_COUNTRIES: Set<string>;
|
|
288
|
+
/**
|
|
289
|
+
* Determine if cookie consent prior-opt-in banner is required based on visitor geography.
|
|
290
|
+
* For US readers (including California CCPA/CPRA), opt-in banners are not required.
|
|
291
|
+
* Returns true ONLY if the visitor is identified as being within an EU/EEA/UK jurisdiction.
|
|
292
|
+
*/
|
|
293
|
+
declare function isGeoConsentRequired(countryCode?: string | null): boolean;
|
|
294
|
+
/**
|
|
295
|
+
* Checks for a cross-domain network consent signal in the URL query (?sm_consent=accepted|rejected|1|0).
|
|
296
|
+
* If present, silently records the consent choice locally and removes the param from the address bar.
|
|
297
|
+
* Returns true if a consent signal was processed.
|
|
298
|
+
*/
|
|
299
|
+
declare function checkUrlConsentBridge(): boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Appends the current consent decision to an outgoing URL within the newspaper network
|
|
302
|
+
* so sister publications can adopt the user's choice without requiring a new banner prompt.
|
|
303
|
+
*/
|
|
304
|
+
declare function decorateNetworkUrl(targetUrl: string): string;
|
|
283
305
|
/**
|
|
284
306
|
* Check if the user has already provided an explicit consent decision.
|
|
285
307
|
*/
|
|
@@ -356,4 +378,4 @@ declare function subscribeTheme(listener: () => void): () => void;
|
|
|
356
378
|
*/
|
|
357
379
|
declare function themeInitScript(): string;
|
|
358
380
|
|
|
359
|
-
export { ANALYTICS_COOKIE, ANALYTICS_VERSION, type Attribution, BROADSHEET_THEME, COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, type CookieCategory, type CookieCategoryDefinition, type CookieConsentRecord, type CookieDisclosure, type CookiePreferences, CouponOffer, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, HomepageSelection, LAYOUT_COOKIE, NEWS_CACHE, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, SESSION_IDLE_MS, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, acceptAllCookies, activeNearby, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, clearCookieConsent, clearTheme, composeEdition, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getCookieConsent, getStoredTheme, getSystemTheme, hasConsented, inventoryCacheOptions, isCategoryAllowed, llmsText, matchesStoryTag, nearbyUpdates, newsArticleJsonLd, normalizedText, publicHttps, publicUrl, publicationJsonLd, publicationMeta, recordConsentToCompliance, referralCode, rejectOptionalCookies, resolveCoupon, resolveEffectiveTheme, resolveLayout, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setCookieConsent, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
|
|
381
|
+
export { ANALYTICS_COOKIE, ANALYTICS_VERSION, type Attribution, BROADSHEET_THEME, COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, type CookieCategory, type CookieCategoryDefinition, type CookieConsentRecord, type CookieDisclosure, type CookiePreferences, CouponOffer, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, HomepageSelection, LAYOUT_COOKIE, NEWS_CACHE, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, SESSION_IDLE_MS, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, acceptAllCookies, activeNearby, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, checkUrlConsentBridge, clearCookieConsent, clearTheme, composeEdition, decorateNetworkUrl, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getCookieConsent, getStoredTheme, getSystemTheme, hasConsented, inventoryCacheOptions, isCategoryAllowed, isGeoConsentRequired, llmsText, matchesStoryTag, nearbyUpdates, newsArticleJsonLd, normalizedText, publicHttps, publicUrl, publicationJsonLd, publicationMeta, recordConsentToCompliance, referralCode, rejectOptionalCookies, resolveCoupon, resolveEffectiveTheme, resolveLayout, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setCookieConsent, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
|
package/dist/index.js
CHANGED
|
@@ -3,9 +3,9 @@ import { definePublication } from './chunk-C7JTEHTH.js';
|
|
|
3
3
|
export { BROADSHEET_THEME, FEATURE_NAMES, LAYOUT_COOKIE, acceptRemoteRecord, acceptSnapshot, definePublication, featureEnabled, parseSnapshot, publicationFromSnapshot, publicationRecord, resolveLayout, snapshotFromRecord, syncPublication } from './chunk-C7JTEHTH.js';
|
|
4
4
|
export { CLASSIFIED_CATEGORIES, JOB_EMPLOYMENT_TYPES, categoryLabel, classifiedPath, classifiedSearchPath, clipChars, dealDollars, dealGoPath, dealsFeedPath, employmentLabel, isClassifiedCategory, isEmploymentType, jobEmployerBody, jobOpeningBody, jobPostingBody, prepareClassified, prepareJobPost, publicJobPath, publicJobsPath } from './chunk-C7ZPLH2K.js';
|
|
5
5
|
export { MEET_ACTIVITIES, activityLabel, canHostMeetup, isAdult, prepareMeetup, screenMessage } from './chunk-GB36YM56.js';
|
|
6
|
-
export { CookieConsentBanner } from './chunk-
|
|
7
|
-
export { CookieSettingsView } from './chunk-
|
|
8
|
-
export { COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, acceptAllCookies, clearCookieConsent, getCookieConsent, hasConsented, isCategoryAllowed, recordConsentToCompliance, rejectOptionalCookies, setCookieConsent } from './chunk-
|
|
6
|
+
export { CookieConsentBanner } from './chunk-EKQXS63J.js';
|
|
7
|
+
export { CookieSettingsView } from './chunk-ZSA6YQBV.js';
|
|
8
|
+
export { COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, acceptAllCookies, checkUrlConsentBridge, clearCookieConsent, decorateNetworkUrl, getCookieConsent, hasConsented, isCategoryAllowed, isGeoConsentRequired, recordConsentToCompliance, rejectOptionalCookies, setCookieConsent } from './chunk-CWZWU4HE.js';
|
|
9
9
|
|
|
10
10
|
// src/preset.ts
|
|
11
11
|
var walnutCreekTimes = definePublication({
|
package/marketplace.css
CHANGED
|
@@ -1,24 +1,49 @@
|
|
|
1
|
-
|
|
1
|
+
/* ScaleMule News Publication - Marketplace (Jobs & Classifieds) */
|
|
2
|
+
.np-market { max-width: 820px; color: var(--pub-ink, #171917); }
|
|
2
3
|
.np-market h1 {
|
|
3
4
|
font: 600 clamp(36px, 4vw, 52px)/1.08 var(--pub-serif);
|
|
4
5
|
letter-spacing: -0.03em;
|
|
5
6
|
margin: 0 0 12px;
|
|
7
|
+
color: var(--pub-ink, #171917);
|
|
6
8
|
}
|
|
7
9
|
.np-market .lead { max-width: 62ch; font: 18px/1.65 var(--pub-serif); color: var(--pub-muted, #545c55); margin: 0 0 28px; }
|
|
8
10
|
.np-market .actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 28px; }
|
|
9
11
|
.np-market .primary, .np-market .secondary {
|
|
10
12
|
display: inline-flex;
|
|
11
13
|
align-items: center;
|
|
14
|
+
justify-content: center;
|
|
12
15
|
min-height: 44px;
|
|
13
|
-
padding: 10px
|
|
16
|
+
padding: 10px 18px;
|
|
14
17
|
font: 700 13px/1.2 var(--pub-sans);
|
|
15
18
|
text-decoration: none;
|
|
16
19
|
cursor: pointer;
|
|
20
|
+
border-radius: 3px;
|
|
21
|
+
transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
|
|
22
|
+
}
|
|
23
|
+
.np-market .primary {
|
|
24
|
+
background: var(--pub-accent, #bb171d);
|
|
25
|
+
color: #ffffff;
|
|
26
|
+
border: 1px solid var(--pub-accent, #bb171d);
|
|
27
|
+
}
|
|
28
|
+
.np-market .secondary {
|
|
29
|
+
background: var(--pub-soft, #f5f6f3);
|
|
30
|
+
color: var(--pub-ink, #171917);
|
|
31
|
+
border: 1px solid var(--pub-rule, #d7dcd7);
|
|
32
|
+
}
|
|
33
|
+
.np-market .primary:hover {
|
|
34
|
+
background: var(--pub-paper, #ffffff);
|
|
35
|
+
color: var(--pub-accent, #bb171d);
|
|
36
|
+
border-color: var(--pub-accent, #bb171d);
|
|
37
|
+
}
|
|
38
|
+
.np-market .secondary:hover {
|
|
39
|
+
background: var(--pub-paper, #ffffff);
|
|
40
|
+
color: var(--pub-accent, #bb171d);
|
|
41
|
+
border-color: var(--pub-accent, #bb171d);
|
|
42
|
+
}
|
|
43
|
+
.np-market .primary:disabled, .np-market .secondary:disabled {
|
|
44
|
+
opacity: 0.65;
|
|
45
|
+
cursor: wait;
|
|
17
46
|
}
|
|
18
|
-
.np-market .primary { background: var(--pub-accent, #bb171d); color: #fff; border: 0; }
|
|
19
|
-
.np-market .secondary { background: #fff; color: var(--pub-ink, #171917); border: 1px solid var(--pub-ink, #171917); }
|
|
20
|
-
.np-market .primary:hover, .np-market .secondary:hover { color: var(--pub-accent, #bb171d); }
|
|
21
|
-
.np-market .primary:hover { background: #fff; border: 1px solid var(--pub-accent, #bb171d); }
|
|
22
47
|
.np-market .list { display: grid; }
|
|
23
48
|
.np-market .item {
|
|
24
49
|
display: block;
|
|
@@ -27,37 +52,72 @@
|
|
|
27
52
|
text-decoration: none;
|
|
28
53
|
color: inherit;
|
|
29
54
|
}
|
|
30
|
-
.np-market .item h2 { font: 600 26px/1.2 var(--pub-serif); margin: 0 0 6px; }
|
|
55
|
+
.np-market .item h2 { font: 600 26px/1.2 var(--pub-serif); margin: 0 0 6px; color: var(--pub-ink, #171917); }
|
|
31
56
|
.np-market .item:hover h2 { color: var(--pub-accent, #bb171d); text-decoration: underline; text-underline-offset: 4px; }
|
|
32
57
|
.np-market .meta { font: 13px/1.5 var(--pub-sans); color: var(--pub-muted, #545c55); }
|
|
33
58
|
.np-market .meta a:hover { color: var(--pub-accent, #bb171d); }
|
|
34
|
-
.np-market .body { white-space: pre-wrap; font: 18px/1.65 var(--pub-serif); }
|
|
59
|
+
.np-market .body { white-space: pre-wrap; font: 18px/1.65 var(--pub-serif); color: var(--pub-ink, #171917); }
|
|
35
60
|
.np-market .search { display: flex; gap: 8px; margin: 0 0 20px; }
|
|
36
|
-
.np-market .search input {
|
|
61
|
+
.np-market .search input {
|
|
62
|
+
flex: 1;
|
|
63
|
+
min-height: 44px;
|
|
64
|
+
border: 1px solid var(--pub-rule, #8a918b);
|
|
65
|
+
padding: 10px 14px;
|
|
66
|
+
font: 16px/1.4 var(--pub-sans);
|
|
67
|
+
background: var(--pub-paper, #ffffff);
|
|
68
|
+
color: var(--pub-ink, #171917);
|
|
69
|
+
border-radius: 3px;
|
|
70
|
+
}
|
|
71
|
+
.np-market .search input:focus-visible {
|
|
72
|
+
outline: 3px solid #a95c00;
|
|
73
|
+
outline-offset: 2px;
|
|
74
|
+
border-color: var(--pub-ink, #171917);
|
|
75
|
+
}
|
|
37
76
|
.np-market .form { display: grid; gap: 14px; max-width: 560px; }
|
|
38
|
-
.np-market .form label { display: grid; gap: 6px; font: 700 13px/1.3 var(--pub-sans); }
|
|
77
|
+
.np-market .form label { display: grid; gap: 6px; font: 700 13px/1.3 var(--pub-sans); color: var(--pub-ink, #171917); }
|
|
39
78
|
.np-market .form input, .np-market .form select, .np-market .form textarea {
|
|
40
79
|
min-height: 44px;
|
|
41
|
-
border: 1px solid #8a918b;
|
|
80
|
+
border: 1px solid var(--pub-rule, #8a918b);
|
|
42
81
|
padding: 10px 12px;
|
|
43
82
|
font: 16px/1.4 var(--pub-sans);
|
|
44
|
-
background: #
|
|
45
|
-
color:
|
|
83
|
+
background: var(--pub-paper, #ffffff);
|
|
84
|
+
color: var(--pub-ink, #171917);
|
|
85
|
+
border-radius: 3px;
|
|
86
|
+
}
|
|
87
|
+
.np-market .form input:focus-visible, .np-market .form select:focus-visible, .np-market .form textarea:focus-visible {
|
|
88
|
+
outline: 3px solid #a95c00;
|
|
89
|
+
outline-offset: 2px;
|
|
90
|
+
border-color: var(--pub-ink, #171917);
|
|
46
91
|
}
|
|
47
92
|
.np-market .form textarea { min-height: 140px; resize: vertical; }
|
|
48
93
|
.np-market .error { color: var(--pub-accent, #bb171d); font: 14px/1.4 var(--pub-sans); }
|
|
49
94
|
.np-market .empty { border-block: 1px solid var(--pub-rule, #d7dcd7); padding: 32px 0; max-width: 640px; }
|
|
50
|
-
.np-market .empty h2 { font: 600 28px/1.15 var(--pub-serif); }
|
|
95
|
+
.np-market .empty h2 { font: 600 28px/1.15 var(--pub-serif); color: var(--pub-ink, #171917); }
|
|
51
96
|
.np-market .filter { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 20px; }
|
|
52
97
|
.np-market .filter a {
|
|
98
|
+
display: inline-flex;
|
|
99
|
+
align-items: center;
|
|
53
100
|
min-height: 36px;
|
|
54
|
-
padding: 6px
|
|
101
|
+
padding: 6px 14px;
|
|
55
102
|
border: 1px solid var(--pub-rule, #d7dcd7);
|
|
56
|
-
background: #
|
|
103
|
+
background: var(--pub-soft, #f5f6f3);
|
|
57
104
|
font: 13px/1.4 var(--pub-sans);
|
|
58
105
|
text-decoration: none;
|
|
59
|
-
color:
|
|
106
|
+
color: var(--pub-ink, #171917);
|
|
107
|
+
border-radius: 3px;
|
|
108
|
+
transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
|
|
109
|
+
}
|
|
110
|
+
.np-market .filter a:hover {
|
|
111
|
+
background: var(--pub-paper, #ffffff);
|
|
112
|
+
border-color: var(--pub-accent, #bb171d);
|
|
113
|
+
color: var(--pub-accent, #bb171d);
|
|
114
|
+
}
|
|
115
|
+
.np-market .filter a.on {
|
|
116
|
+
background: var(--pub-paper, #ffffff);
|
|
117
|
+
border-color: var(--pub-accent, #bb171d);
|
|
118
|
+
color: var(--pub-accent, #bb171d);
|
|
119
|
+
font-weight: 700;
|
|
120
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
60
121
|
}
|
|
61
|
-
.np-market .filter a.on, .np-market .filter a:hover { border-color: var(--pub-ink, #171917); color: var(--pub-accent, #bb171d); }
|
|
62
122
|
.np-market .deals { margin: 0 0 28px; }
|
|
63
|
-
.np-market .deals h2 { font: 600 22px/1.2 var(--pub-serif); margin: 0 0 8px; }
|
|
123
|
+
.np-market .deals h2 { font: 600 22px/1.2 var(--pub-serif); margin: 0 0 8px; color: var(--pub-ink, #171917); }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scalemule/news-publication",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "Shared server framework for ScaleMule local news publications. Walnut Creek Times is the broadsheet default; each paper supplies its own identity and feature flags.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
package/tokens/broadsheet.css
CHANGED
|
@@ -58,6 +58,12 @@
|
|
|
58
58
|
--pub-soft: #f5f6f3;
|
|
59
59
|
--pub-sponsor: #173d32;
|
|
60
60
|
--pub-selection-bg: #f6dcdd;
|
|
61
|
+
--pub-tag-topic-bg: #ffffff;
|
|
62
|
+
--pub-tag-topic-text: #4b5563;
|
|
63
|
+
--pub-tag-topic-border: #e2ded4;
|
|
64
|
+
--pub-tag-hood-bg: #f4f7f5;
|
|
65
|
+
--pub-tag-hood-text: #1a4237;
|
|
66
|
+
--pub-tag-hood-border: #cadcd3;
|
|
61
67
|
}
|
|
62
68
|
|
|
63
69
|
/* Broadsheet Evening Edition: Dark Mode */
|
|
@@ -72,6 +78,12 @@
|
|
|
72
78
|
--pub-soft: #1a1e1b;
|
|
73
79
|
--pub-sponsor: #244b3e;
|
|
74
80
|
--pub-selection-bg: #52191d;
|
|
81
|
+
--pub-tag-topic-bg: #1c211e;
|
|
82
|
+
--pub-tag-topic-text: #c5cbc6;
|
|
83
|
+
--pub-tag-topic-border: #323b34;
|
|
84
|
+
--pub-tag-hood-bg: rgba(36, 75, 62, 0.35);
|
|
85
|
+
--pub-tag-hood-text: #8ed6b2;
|
|
86
|
+
--pub-tag-hood-border: #2a5242;
|
|
75
87
|
}
|
|
76
88
|
|
|
77
89
|
/* System Preference Mode (Default when not explicitly forced) */
|
|
@@ -86,6 +98,12 @@
|
|
|
86
98
|
--pub-soft: #1a1e1b;
|
|
87
99
|
--pub-sponsor: #244b3e;
|
|
88
100
|
--pub-selection-bg: #52191d;
|
|
101
|
+
--pub-tag-topic-bg: #1c211e;
|
|
102
|
+
--pub-tag-topic-text: #c5cbc6;
|
|
103
|
+
--pub-tag-topic-border: #323b34;
|
|
104
|
+
--pub-tag-hood-bg: rgba(36, 75, 62, 0.35);
|
|
105
|
+
--pub-tag-hood-text: #8ed6b2;
|
|
106
|
+
--pub-tag-hood-border: #2a5242;
|
|
89
107
|
}
|
|
90
108
|
}
|
|
91
109
|
|
|
@@ -101,6 +119,16 @@
|
|
|
101
119
|
}
|
|
102
120
|
.publication [id] { scroll-margin-top: 24px; }
|
|
103
121
|
.publication ::selection { background: var(--pub-selection-bg, #f6dcdd); color: var(--pub-ink); }
|
|
122
|
+
|
|
123
|
+
/* Base broadsheet form & input styles */
|
|
124
|
+
.publication input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
|
|
125
|
+
.publication select,
|
|
126
|
+
.publication textarea {
|
|
127
|
+
background-color: var(--pub-paper);
|
|
128
|
+
color: var(--pub-ink);
|
|
129
|
+
border: 1px solid var(--pub-rule);
|
|
130
|
+
}
|
|
131
|
+
|
|
104
132
|
@media (min-width: 960px) {
|
|
105
133
|
.publication { --pub-width: 1280px; }
|
|
106
134
|
}
|