@financial-times/cmp-client 2.0.4-alpha → 2.0.5-beta.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/dist/client.d.ts +3 -63
- package/dist/client.d.ts.map +1 -0
- package/dist/consent-ready/index.d.ts +5 -0
- package/dist/consent-ready/index.d.ts.map +1 -0
- package/dist/consent-ready/utils/__fixtures__/strings.d.ts +9 -0
- package/dist/consent-ready/utils/__fixtures__/strings.d.ts.map +1 -0
- package/dist/consent-ready/utils/__tests__/check-consent.test.d.ts +2 -0
- package/dist/consent-ready/utils/__tests__/check-consent.test.d.ts.map +1 -0
- package/dist/consent-ready/utils/__tests__/get-parsed-consent.test.d.ts +2 -0
- package/dist/consent-ready/utils/__tests__/get-parsed-consent.test.d.ts.map +1 -0
- package/dist/consent-ready/utils/__tests__/validators.test.d.ts +2 -0
- package/dist/consent-ready/utils/__tests__/validators.test.d.ts.map +1 -0
- package/dist/consent-ready/utils/get-consent-payload.d.ts +18 -0
- package/dist/consent-ready/utils/get-consent-payload.d.ts.map +1 -0
- package/dist/consent-ready/utils/get-parsed-consent.d.ts +14 -0
- package/dist/consent-ready/utils/get-parsed-consent.d.ts.map +1 -0
- package/dist/consent-ready/utils/has-consent-changed.d.ts +3 -0
- package/dist/consent-ready/utils/has-consent-changed.d.ts.map +1 -0
- package/dist/consent-ready/utils/validators.d.ts +16 -0
- package/dist/consent-ready/utils/validators.d.ts.map +1 -0
- package/dist/html/__tests__/cmp-footer-links.test.d.ts +2 -0
- package/dist/html/__tests__/cmp-footer-links.test.d.ts.map +1 -0
- package/dist/html/cmp-footer-link.d.ts +8 -0
- package/dist/html/cmp-footer-link.d.ts.map +1 -0
- package/dist/html/cmp-scripts.d.ts +16 -0
- package/dist/html/cmp-scripts.d.ts.map +1 -0
- package/dist/{client.cjs → index.cjs} +409 -158
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/{client.js → index.js} +408 -157
- package/dist/lib/constants.d.ts +13 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/{debug.d.ts → lib/debug.d.ts} +12 -13
- package/dist/lib/debug.d.ts.map +1 -0
- package/dist/{properties.d.ts → lib/properties.d.ts} +17 -19
- package/dist/lib/properties.d.ts.map +1 -0
- package/dist/utils/dom.d.ts +3 -0
- package/dist/utils/dom.d.ts.map +1 -0
- package/package.json +20 -30
- package/typings/globals.d.ts +20 -0
- package/typings/modules.d.ts +1 -0
- package/typings/types.d.ts +88 -0
- package/dist/debug.cjs +0 -32
- package/dist/debug.js +0 -32
- package/dist/properties.cjs +0 -21
- package/dist/properties.js +0 -21
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => {
|
|
4
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
return value;
|
|
6
|
+
};
|
|
7
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
|
|
2
8
|
const request = (url, { credentials = "omit" } = {}) => {
|
|
3
9
|
return fetch(`https://session-next.ft.com${url}`, {
|
|
4
10
|
credentials,
|
|
@@ -69,10 +75,68 @@ const getUuid = () => {
|
|
|
69
75
|
}
|
|
70
76
|
return requests.uuid;
|
|
71
77
|
};
|
|
78
|
+
const SOURCEPOINT_CONSENT_SOURCE = "sourcepoint-cmp";
|
|
79
|
+
const SOURCEPOINT_FOW_SCOPE = "FTPINK";
|
|
80
|
+
const CONSENT_COOKIE_NAME = "FTConsent";
|
|
81
|
+
const SOURCEPOINT_FOW_ID = "sourcepointCmp/VngD.XycZut.595cp9fWdp5XYP9vlFvk";
|
|
82
|
+
const FT_COOKIE_DOMAIN = ".ft.com";
|
|
83
|
+
const FT_CONSENT_PROXY_HOST = "https://consent.ft.com";
|
|
84
|
+
const legislation = {
|
|
85
|
+
CCPA: "ccpa",
|
|
86
|
+
GDPR: "gdpr"
|
|
87
|
+
};
|
|
88
|
+
const iabCustomCategories = {
|
|
89
|
+
permutiveAds: {
|
|
90
|
+
purposes: [2, 4, 8, 9],
|
|
91
|
+
iabVendors: [361],
|
|
92
|
+
customVendors: [],
|
|
93
|
+
specialFeatures: []
|
|
94
|
+
},
|
|
95
|
+
demographicAds: {
|
|
96
|
+
purposes: [3, 4, 7, 9, 10],
|
|
97
|
+
iabVendors: [],
|
|
98
|
+
customVendors: [],
|
|
99
|
+
specialFeatures: []
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const defaults = {
|
|
103
|
+
joinHref: true,
|
|
104
|
+
gdpr: {},
|
|
105
|
+
ccpa: {}
|
|
106
|
+
};
|
|
107
|
+
const FT_DOTCOM_LOCAL = {
|
|
108
|
+
...defaults,
|
|
109
|
+
accountId: 1906,
|
|
110
|
+
baseEndpoint: "https://cdn.privacy-mgmt.com",
|
|
111
|
+
propertyHref: "https://local.ft.com"
|
|
112
|
+
};
|
|
113
|
+
const FT_DOTCOM_PROD = {
|
|
114
|
+
...defaults,
|
|
115
|
+
accountId: 1906,
|
|
116
|
+
baseEndpoint: "https://cdn.privacy-mgmt.com",
|
|
117
|
+
propertyId: 31642
|
|
118
|
+
};
|
|
119
|
+
const properties = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
120
|
+
__proto__: null,
|
|
121
|
+
FT_DOTCOM_LOCAL,
|
|
122
|
+
FT_DOTCOM_PROD
|
|
123
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
124
|
+
function createContentScript(content) {
|
|
125
|
+
const s = document.createElement("script");
|
|
126
|
+
s.innerHTML = content;
|
|
127
|
+
return s;
|
|
128
|
+
}
|
|
129
|
+
function createSourceScript(src) {
|
|
130
|
+
const s = document.createElement("script");
|
|
131
|
+
s.src = src;
|
|
132
|
+
return s;
|
|
133
|
+
}
|
|
72
134
|
function encodeConfig(obj) {
|
|
73
135
|
let str = "";
|
|
136
|
+
if (!obj)
|
|
137
|
+
return str;
|
|
74
138
|
for (const [key, val] of Object.entries(obj)) {
|
|
75
|
-
switch (typeof
|
|
139
|
+
switch (typeof val) {
|
|
76
140
|
case "function":
|
|
77
141
|
str += `${key}:${val.toString().replace(/"/g, "'").replace(/\s/g, "")},`;
|
|
78
142
|
break;
|
|
@@ -100,13 +164,42 @@ const scriptContent = {
|
|
|
100
164
|
tcfStub: `"use strict";function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(){var t=function(){var t,e,o=[],n=window,r=n;for(;r;){try{if(r.frames.__tcfapiLocator){t=r;break}}catch(t){}if(r===n.top)break;r=r.parent}t||(!function t(){var e=n.document,o=!!n.frames.__tcfapiLocator;if(!o)if(e.body){var r=e.createElement("iframe");r.style.cssText="display:none",r.name="__tcfapiLocator",e.body.appendChild(r)}else setTimeout(t,5);return!o}(),n.__tcfapi=function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];if(!n.length)return o;"setGdprApplies"===n[0]?n.length>3&&2===parseInt(n[1],10)&&"boolean"==typeof n[3]&&(e=n[3],"function"==typeof n[2]&&n[2]("set",!0)):"ping"===n[0]?"function"==typeof n[2]&&n[2]({gdprApplies:e,cmpLoaded:!1,cmpStatus:"stub"}):o.push(n)},n.addEventListener("message",(function(t){var e="string"==typeof t.data,o={};if(e)try{o=JSON.parse(t.data)}catch(t){}else o=t.data;var n="object"===_typeof(o)&&null!==o?o.__tcfapiCall:null;n&&window.__tcfapi(n.command,n.version,(function(o,r){var a={__tcfapiReturn:{returnValue:o,success:r,callId:n.callId}};t&&t.source&&t.source.postMessage&&t.source.postMessage(e?JSON.stringify(a):a,"*")}),n.parameter)}),!1))};"undefined"!=typeof module?module.exports=t:t()}();`,
|
|
101
165
|
uspStub: `"use strict";(function () { var e = false; var c = window; var t = document; function r() { if (!c.frames["__uspapiLocator"]) { if (t.body) { var a = t.body; var e = t.createElement("iframe"); e.style.cssText = "display:none"; e.name = "__uspapiLocator"; a.appendChild(e) } else { setTimeout(r, 5) } } } r(); function p() { var a = arguments; __uspapi.a = __uspapi.a || []; if (!a.length) { return __uspapi.a } else if (a[0] === "ping") { a[2]({ gdprAppliesGlobally: e, cmpLoaded: false }, true) } else { __uspapi.a.push([].slice.apply(a)) } } function l(t) { var r = typeof t.data === "string"; try { var a = r ? JSON.parse(t.data) : t.data; if (a.__cmpCall) { var n = a.__cmpCall; c.__uspapi(n.command, n.parameter, function (a, e) { var c = { __cmpReturn: { returnValue: a, success: e, callId: n.callId } }; t.source.postMessage(r ? JSON.stringify(c) : c, "*") }) } } catch (a) { } } if (typeof __uspapi !== "function") { c.__uspapi = p; __uspapi.msgHandler = l; c.addEventListener("message", l, false) } })();`
|
|
102
166
|
};
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
167
|
+
function getCmpScripts(config) {
|
|
168
|
+
const fragment = document.createDocumentFragment();
|
|
169
|
+
fragment.appendChild(createContentScript(scriptContent.tcfStub));
|
|
170
|
+
fragment.appendChild(createContentScript(scriptContent.uspStub));
|
|
171
|
+
fragment.appendChild(createContentScript(scriptContent.getSPConfig(config)));
|
|
172
|
+
fragment.appendChild(createSourceScript(scriptSources.cmpFrames));
|
|
173
|
+
return fragment;
|
|
174
|
+
}
|
|
175
|
+
function getConsentPayload(parsedConsent, { shouldUpdateConsentStore, formOfWordsId, cookieDomain }) {
|
|
176
|
+
const categoryNames = Object.keys(parsedConsent);
|
|
177
|
+
const data = categoryNames.reduce(
|
|
178
|
+
(payload, categoryName) => {
|
|
179
|
+
payload[categoryName] = {
|
|
180
|
+
onsite: {
|
|
181
|
+
status: parsedConsent[categoryName],
|
|
182
|
+
lbi: false,
|
|
183
|
+
source: SOURCEPOINT_CONSENT_SOURCE,
|
|
184
|
+
fow: formOfWordsId
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
return payload;
|
|
188
|
+
},
|
|
189
|
+
{}
|
|
190
|
+
);
|
|
191
|
+
if (!shouldUpdateConsentStore) {
|
|
192
|
+
return { data };
|
|
193
|
+
} else {
|
|
194
|
+
return {
|
|
195
|
+
setConsentCookie: true,
|
|
196
|
+
formOfWordsId,
|
|
197
|
+
consentSource: SOURCEPOINT_CONSENT_SOURCE,
|
|
198
|
+
cookieDomain,
|
|
199
|
+
data
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
110
203
|
class DecodingError extends Error {
|
|
111
204
|
/**
|
|
112
205
|
* constructor - constructs an DecodingError
|
|
@@ -195,6 +288,10 @@ class Base64Url {
|
|
|
195
288
|
return result;
|
|
196
289
|
}
|
|
197
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Base 64 URL character set. Different from standard Base64 char set
|
|
293
|
+
* in that '+' and '/' are replaced with '-' and '_'.
|
|
294
|
+
*/
|
|
198
295
|
__publicField(Base64Url, "DICT", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
|
|
199
296
|
__publicField(Base64Url, "REVERSE_DICT", /* @__PURE__ */ new Map([
|
|
200
297
|
["A", 0],
|
|
@@ -262,26 +359,29 @@ __publicField(Base64Url, "REVERSE_DICT", /* @__PURE__ */ new Map([
|
|
|
262
359
|
["-", 62],
|
|
263
360
|
["_", 63]
|
|
264
361
|
]));
|
|
362
|
+
/**
|
|
363
|
+
* log2(64) = 6
|
|
364
|
+
*/
|
|
265
365
|
__publicField(Base64Url, "BASIS", 6);
|
|
266
366
|
__publicField(Base64Url, "LCM", 24);
|
|
267
|
-
const _ConsentLanguages = class
|
|
367
|
+
const _ConsentLanguages = class _ConsentLanguages {
|
|
268
368
|
has(key) {
|
|
269
|
-
return
|
|
369
|
+
return _ConsentLanguages.langSet.has(key);
|
|
270
370
|
}
|
|
271
371
|
parseLanguage(lang) {
|
|
272
372
|
lang = lang.toUpperCase();
|
|
273
373
|
const primaryLanguage = lang.split("-")[0];
|
|
274
374
|
if (lang.length >= 2 && primaryLanguage.length == 2) {
|
|
275
|
-
if (
|
|
375
|
+
if (_ConsentLanguages.langSet.has(lang)) {
|
|
276
376
|
return lang;
|
|
277
|
-
} else if (
|
|
377
|
+
} else if (_ConsentLanguages.langSet.has(primaryLanguage)) {
|
|
278
378
|
return primaryLanguage;
|
|
279
379
|
}
|
|
280
380
|
const fullPrimaryLang = primaryLanguage + "-" + primaryLanguage;
|
|
281
|
-
if (
|
|
381
|
+
if (_ConsentLanguages.langSet.has(fullPrimaryLang)) {
|
|
282
382
|
return fullPrimaryLang;
|
|
283
383
|
}
|
|
284
|
-
for (const supportedLang of
|
|
384
|
+
for (const supportedLang of _ConsentLanguages.langSet) {
|
|
285
385
|
if (supportedLang.indexOf(lang) !== -1 || supportedLang.indexOf(primaryLanguage) !== -1) {
|
|
286
386
|
return supportedLang;
|
|
287
387
|
}
|
|
@@ -290,10 +390,10 @@ const _ConsentLanguages = class _ConsentLanguages2 {
|
|
|
290
390
|
throw new Error(`unsupported language ${lang}`);
|
|
291
391
|
}
|
|
292
392
|
forEach(callback) {
|
|
293
|
-
|
|
393
|
+
_ConsentLanguages.langSet.forEach(callback);
|
|
294
394
|
}
|
|
295
395
|
get size() {
|
|
296
|
-
return
|
|
396
|
+
return _ConsentLanguages.langSet.size;
|
|
297
397
|
}
|
|
298
398
|
};
|
|
299
399
|
__publicField(_ConsentLanguages, "langSet", /* @__PURE__ */ new Set([
|
|
@@ -424,7 +524,7 @@ var RestrictionType;
|
|
|
424
524
|
RestrictionType2[RestrictionType2["REQUIRE_CONSENT"] = 1] = "REQUIRE_CONSENT";
|
|
425
525
|
RestrictionType2[RestrictionType2["REQUIRE_LI"] = 2] = "REQUIRE_LI";
|
|
426
526
|
})(RestrictionType || (RestrictionType = {}));
|
|
427
|
-
const _PurposeRestriction = class
|
|
527
|
+
const _PurposeRestriction = class _PurposeRestriction extends Cloneable {
|
|
428
528
|
/**
|
|
429
529
|
* constructor
|
|
430
530
|
*
|
|
@@ -447,7 +547,7 @@ const _PurposeRestriction = class _PurposeRestriction2 extends Cloneable {
|
|
|
447
547
|
}
|
|
448
548
|
static unHash(hash) {
|
|
449
549
|
const splitUp = hash.split(this.hashSeparator);
|
|
450
|
-
const purpRestriction = new
|
|
550
|
+
const purpRestriction = new _PurposeRestriction();
|
|
451
551
|
if (splitUp.length !== 2) {
|
|
452
552
|
throw new TCModelError("hash", hash);
|
|
453
553
|
}
|
|
@@ -459,7 +559,7 @@ const _PurposeRestriction = class _PurposeRestriction2 extends Cloneable {
|
|
|
459
559
|
if (!this.isValid()) {
|
|
460
560
|
throw new Error("cannot hash invalid PurposeRestriction");
|
|
461
561
|
}
|
|
462
|
-
return `${this.purposeId}${
|
|
562
|
+
return `${this.purposeId}${_PurposeRestriction.hashSeparator}${this.restrictionType}`;
|
|
463
563
|
}
|
|
464
564
|
/**
|
|
465
565
|
* @return {number} The purpose Id associated with a publisher
|
|
@@ -489,7 +589,15 @@ let PurposeRestriction = _PurposeRestriction;
|
|
|
489
589
|
class PurposeRestrictionVector extends Cloneable {
|
|
490
590
|
constructor() {
|
|
491
591
|
super(...arguments);
|
|
592
|
+
/**
|
|
593
|
+
* if this originatd from an encoded string we'll need a place to store the
|
|
594
|
+
* bit length; it can be set and got from here
|
|
595
|
+
*/
|
|
492
596
|
__publicField(this, "bitLength", 0);
|
|
597
|
+
/**
|
|
598
|
+
* a map indexed by a string which will be a 'hash' of the purpose and
|
|
599
|
+
* restriction type.
|
|
600
|
+
*/
|
|
493
601
|
__publicField(this, "map", /* @__PURE__ */ new Map());
|
|
494
602
|
__publicField(this, "gvl_");
|
|
495
603
|
}
|
|
@@ -726,6 +834,12 @@ var Segment;
|
|
|
726
834
|
})(Segment || (Segment = {}));
|
|
727
835
|
class SegmentIDs {
|
|
728
836
|
}
|
|
837
|
+
/**
|
|
838
|
+
* 0 = default - reserved for core string (does not need to be present in the core string)
|
|
839
|
+
* 1 = OOB vendors disclosed
|
|
840
|
+
* 2 = OOB vendors allowed
|
|
841
|
+
* 3 = PublisherTC
|
|
842
|
+
*/
|
|
729
843
|
__publicField(SegmentIDs, "ID_TO_KEY", [
|
|
730
844
|
Segment.CORE,
|
|
731
845
|
Segment.VENDORS_DISCLOSED,
|
|
@@ -741,6 +855,10 @@ __publicField(SegmentIDs, "KEY_TO_ID", {
|
|
|
741
855
|
class Vector extends Cloneable {
|
|
742
856
|
constructor() {
|
|
743
857
|
super(...arguments);
|
|
858
|
+
/**
|
|
859
|
+
* if this originatd from an encoded string we'll need a place to store the
|
|
860
|
+
* bit length; it can be set and got from here
|
|
861
|
+
*/
|
|
744
862
|
__publicField(this, "bitLength", 0);
|
|
745
863
|
__publicField(this, "maxId_", 0);
|
|
746
864
|
__publicField(this, "set_", /* @__PURE__ */ new Set());
|
|
@@ -1484,7 +1602,7 @@ class Json {
|
|
|
1484
1602
|
return this.absCall(url, null, sendCookies, timeout);
|
|
1485
1603
|
}
|
|
1486
1604
|
}
|
|
1487
|
-
const _GVL = class
|
|
1605
|
+
const _GVL = class _GVL extends Cloneable {
|
|
1488
1606
|
/**
|
|
1489
1607
|
* @param {VersionOrVendorList} [versionOrVendorList] - can be either a
|
|
1490
1608
|
* [[VendorList]] object or a version number represented as a string or
|
|
@@ -1493,31 +1611,94 @@ const _GVL = class _GVL2 extends Cloneable {
|
|
|
1493
1611
|
*/
|
|
1494
1612
|
constructor(versionOrVendorList) {
|
|
1495
1613
|
super();
|
|
1614
|
+
/**
|
|
1615
|
+
* @param {Promise} resolved when this GVL object is populated with the data
|
|
1616
|
+
* or rejected if there is an error.
|
|
1617
|
+
*/
|
|
1496
1618
|
__publicField(this, "readyPromise");
|
|
1619
|
+
/**
|
|
1620
|
+
* @param {number} gvlSpecificationVersion - schema version for the GVL that is used
|
|
1621
|
+
*/
|
|
1497
1622
|
__publicField(this, "gvlSpecificationVersion");
|
|
1623
|
+
/**
|
|
1624
|
+
* @param {number} incremented with each published file change
|
|
1625
|
+
*/
|
|
1498
1626
|
__publicField(this, "vendorListVersion");
|
|
1627
|
+
/**
|
|
1628
|
+
* @param {number} tcfPolicyVersion - The TCF MO will increment this value
|
|
1629
|
+
* whenever a GVL change (such as adding a new Purpose or Feature or a change
|
|
1630
|
+
* in Purpose wording) legally invalidates existing TC Strings and requires
|
|
1631
|
+
* CMPs to re-establish transparency and consent from users. If the policy
|
|
1632
|
+
* version number in the latest GVL is different from the value in your TC
|
|
1633
|
+
* String, then you need to re-establish transparency and consent for that
|
|
1634
|
+
* user. A version 1 format TC String is considered to have a version value
|
|
1635
|
+
* of 1.
|
|
1636
|
+
*/
|
|
1499
1637
|
__publicField(this, "tcfPolicyVersion");
|
|
1638
|
+
/**
|
|
1639
|
+
* @param {string | Date} lastUpdated - the date in which the vendor list
|
|
1640
|
+
* json file was last updated.
|
|
1641
|
+
*/
|
|
1500
1642
|
__publicField(this, "lastUpdated");
|
|
1643
|
+
/**
|
|
1644
|
+
* @param {IntMap<Purpose>} a collection of [[Purpose]]s
|
|
1645
|
+
*/
|
|
1501
1646
|
__publicField(this, "purposes");
|
|
1647
|
+
/**
|
|
1648
|
+
* @param {IntMap<Purpose>} a collection of [[Purpose]]s
|
|
1649
|
+
*/
|
|
1502
1650
|
__publicField(this, "specialPurposes");
|
|
1651
|
+
/**
|
|
1652
|
+
* @param {IntMap<Feature>} a collection of [[Feature]]s
|
|
1653
|
+
*/
|
|
1503
1654
|
__publicField(this, "features");
|
|
1655
|
+
/**
|
|
1656
|
+
* @param {IntMap<Feature>} a collection of [[Feature]]s
|
|
1657
|
+
*/
|
|
1504
1658
|
__publicField(this, "specialFeatures");
|
|
1659
|
+
/**
|
|
1660
|
+
* @param {boolean} internal reference of when the GVL is ready to be used
|
|
1661
|
+
*/
|
|
1505
1662
|
__publicField(this, "isReady_", false);
|
|
1663
|
+
/**
|
|
1664
|
+
* @param {IntMap<Vendor>} a collection of [[Vendor]]s
|
|
1665
|
+
*/
|
|
1506
1666
|
__publicField(this, "vendors_");
|
|
1507
1667
|
__publicField(this, "vendorIds");
|
|
1668
|
+
/**
|
|
1669
|
+
* @param {IntMap<Vendor>} a collection of [[Vendor]]. Used as a backup if a whitelist is sets
|
|
1670
|
+
*/
|
|
1508
1671
|
__publicField(this, "fullVendorList");
|
|
1672
|
+
/**
|
|
1673
|
+
* @param {ByPurposeVendorMap} vendors by purpose
|
|
1674
|
+
*/
|
|
1509
1675
|
__publicField(this, "byPurposeVendorMap");
|
|
1676
|
+
/**
|
|
1677
|
+
* @param {IDSetMap} vendors by special purpose
|
|
1678
|
+
*/
|
|
1510
1679
|
__publicField(this, "bySpecialPurposeVendorMap");
|
|
1680
|
+
/**
|
|
1681
|
+
* @param {IDSetMap} vendors by feature
|
|
1682
|
+
*/
|
|
1511
1683
|
__publicField(this, "byFeatureVendorMap");
|
|
1684
|
+
/**
|
|
1685
|
+
* @param {IDSetMap} vendors by special feature
|
|
1686
|
+
*/
|
|
1512
1687
|
__publicField(this, "bySpecialFeatureVendorMap");
|
|
1688
|
+
/**
|
|
1689
|
+
* @param {IntMap<Stack>} a collection of [[Stack]]s
|
|
1690
|
+
*/
|
|
1513
1691
|
__publicField(this, "stacks");
|
|
1692
|
+
/**
|
|
1693
|
+
* @param {IntMap<DataCategory>} a collection of [[DataCategory]]s
|
|
1694
|
+
*/
|
|
1514
1695
|
__publicField(this, "dataCategories");
|
|
1515
1696
|
__publicField(this, "lang_");
|
|
1516
1697
|
__publicField(this, "cacheLang_");
|
|
1517
1698
|
__publicField(this, "isLatest", false);
|
|
1518
|
-
let url =
|
|
1519
|
-
this.lang_ =
|
|
1520
|
-
this.cacheLang_ =
|
|
1699
|
+
let url = _GVL.baseUrl;
|
|
1700
|
+
this.lang_ = _GVL.DEFAULT_LANGUAGE;
|
|
1701
|
+
this.cacheLang_ = _GVL.DEFAULT_LANGUAGE;
|
|
1521
1702
|
if (this.isVendorList(versionOrVendorList)) {
|
|
1522
1703
|
this.populate(versionOrVendorList);
|
|
1523
1704
|
this.readyPromise = Promise.resolve();
|
|
@@ -1527,20 +1708,20 @@ const _GVL = class _GVL2 extends Cloneable {
|
|
|
1527
1708
|
}
|
|
1528
1709
|
if (versionOrVendorList > 0) {
|
|
1529
1710
|
const version = versionOrVendorList;
|
|
1530
|
-
if (
|
|
1531
|
-
this.populate(
|
|
1711
|
+
if (_GVL.CACHE.has(version)) {
|
|
1712
|
+
this.populate(_GVL.CACHE.get(version));
|
|
1532
1713
|
this.readyPromise = Promise.resolve();
|
|
1533
1714
|
} else {
|
|
1534
|
-
url +=
|
|
1715
|
+
url += _GVL.versionedFilename.replace("[VERSION]", String(version));
|
|
1535
1716
|
this.readyPromise = this.fetchJson(url);
|
|
1536
1717
|
}
|
|
1537
1718
|
} else {
|
|
1538
|
-
if (
|
|
1539
|
-
this.populate(
|
|
1719
|
+
if (_GVL.CACHE.has(_GVL.LATEST_CACHE_KEY)) {
|
|
1720
|
+
this.populate(_GVL.CACHE.get(_GVL.LATEST_CACHE_KEY));
|
|
1540
1721
|
this.readyPromise = Promise.resolve();
|
|
1541
1722
|
} else {
|
|
1542
1723
|
this.isLatest = true;
|
|
1543
|
-
this.readyPromise = this.fetchJson(url +
|
|
1724
|
+
this.readyPromise = this.fetchJson(url + _GVL.latestFilename);
|
|
1544
1725
|
}
|
|
1545
1726
|
}
|
|
1546
1727
|
}
|
|
@@ -1597,11 +1778,11 @@ const _GVL = class _GVL2 extends Cloneable {
|
|
|
1597
1778
|
*/
|
|
1598
1779
|
static emptyLanguageCache(lang) {
|
|
1599
1780
|
let result = false;
|
|
1600
|
-
if (lang == null &&
|
|
1601
|
-
|
|
1781
|
+
if (lang == null && _GVL.LANGUAGE_CACHE.size > 0) {
|
|
1782
|
+
_GVL.LANGUAGE_CACHE = /* @__PURE__ */ new Map();
|
|
1602
1783
|
result = true;
|
|
1603
1784
|
} else if (typeof lang === "string" && this.consentLanguages.has(lang.toUpperCase())) {
|
|
1604
|
-
|
|
1785
|
+
_GVL.LANGUAGE_CACHE.delete(lang.toUpperCase());
|
|
1605
1786
|
result = true;
|
|
1606
1787
|
}
|
|
1607
1788
|
return result;
|
|
@@ -1616,17 +1797,17 @@ const _GVL = class _GVL2 extends Cloneable {
|
|
|
1616
1797
|
static emptyCache(vendorListVersion) {
|
|
1617
1798
|
let retr = false;
|
|
1618
1799
|
if (Number.isInteger(vendorListVersion) && vendorListVersion >= 0) {
|
|
1619
|
-
|
|
1800
|
+
_GVL.CACHE.delete(vendorListVersion);
|
|
1620
1801
|
retr = true;
|
|
1621
1802
|
} else if (vendorListVersion === void 0) {
|
|
1622
|
-
|
|
1803
|
+
_GVL.CACHE = /* @__PURE__ */ new Map();
|
|
1623
1804
|
retr = true;
|
|
1624
1805
|
}
|
|
1625
1806
|
return retr;
|
|
1626
1807
|
}
|
|
1627
1808
|
cacheLanguage() {
|
|
1628
|
-
if (!
|
|
1629
|
-
|
|
1809
|
+
if (!_GVL.LANGUAGE_CACHE.has(this.cacheLang_)) {
|
|
1810
|
+
_GVL.LANGUAGE_CACHE.set(this.cacheLang_, {
|
|
1630
1811
|
purposes: this.purposes,
|
|
1631
1812
|
specialPurposes: this.specialPurposes,
|
|
1632
1813
|
features: this.features,
|
|
@@ -1676,25 +1857,25 @@ const _GVL = class _GVL2 extends Cloneable {
|
|
|
1676
1857
|
async changeLanguage(lang) {
|
|
1677
1858
|
let parsedLanguage = lang;
|
|
1678
1859
|
try {
|
|
1679
|
-
parsedLanguage =
|
|
1860
|
+
parsedLanguage = _GVL.consentLanguages.parseLanguage(lang);
|
|
1680
1861
|
} catch (e) {
|
|
1681
1862
|
throw new GVLError("Error during parsing the language: " + e.message);
|
|
1682
1863
|
}
|
|
1683
1864
|
const cacheLang = lang.toUpperCase();
|
|
1684
|
-
if (parsedLanguage.toLowerCase() ===
|
|
1865
|
+
if (parsedLanguage.toLowerCase() === _GVL.DEFAULT_LANGUAGE.toLowerCase() && !_GVL.LANGUAGE_CACHE.has(cacheLang)) {
|
|
1685
1866
|
return;
|
|
1686
1867
|
}
|
|
1687
1868
|
if (parsedLanguage !== this.lang_) {
|
|
1688
1869
|
this.lang_ = parsedLanguage;
|
|
1689
|
-
if (
|
|
1690
|
-
const cached =
|
|
1870
|
+
if (_GVL.LANGUAGE_CACHE.has(cacheLang)) {
|
|
1871
|
+
const cached = _GVL.LANGUAGE_CACHE.get(cacheLang);
|
|
1691
1872
|
for (const prop in cached) {
|
|
1692
1873
|
if (cached.hasOwnProperty(prop)) {
|
|
1693
1874
|
this[prop] = cached[prop];
|
|
1694
1875
|
}
|
|
1695
1876
|
}
|
|
1696
1877
|
} else {
|
|
1697
|
-
const url =
|
|
1878
|
+
const url = _GVL.baseUrl + _GVL.languageFilename.replace("[LANG]", this.lang_.toLowerCase());
|
|
1698
1879
|
try {
|
|
1699
1880
|
await this.fetchJson(url);
|
|
1700
1881
|
this.cacheLang_ = cacheLang;
|
|
@@ -1731,10 +1912,10 @@ const _GVL = class _GVL2 extends Cloneable {
|
|
|
1731
1912
|
this.mapVendors();
|
|
1732
1913
|
this.isReady_ = true;
|
|
1733
1914
|
if (this.isLatest) {
|
|
1734
|
-
|
|
1915
|
+
_GVL.CACHE.set(_GVL.LATEST_CACHE_KEY, this.getJson());
|
|
1735
1916
|
}
|
|
1736
|
-
if (!
|
|
1737
|
-
|
|
1917
|
+
if (!_GVL.CACHE.has(this.vendorListVersion)) {
|
|
1918
|
+
_GVL.CACHE.set(this.vendorListVersion, this.getJson());
|
|
1738
1919
|
}
|
|
1739
1920
|
}
|
|
1740
1921
|
this.cacheLanguage();
|
|
@@ -1897,8 +2078,8 @@ const _GVL = class _GVL2 extends Cloneable {
|
|
|
1897
2078
|
* @return {GVL}
|
|
1898
2079
|
*/
|
|
1899
2080
|
clone() {
|
|
1900
|
-
const result = new
|
|
1901
|
-
if (this.lang_ !==
|
|
2081
|
+
const result = new _GVL(this.getJson());
|
|
2082
|
+
if (this.lang_ !== _GVL.DEFAULT_LANGUAGE) {
|
|
1902
2083
|
result.changeLanguage(this.lang_);
|
|
1903
2084
|
}
|
|
1904
2085
|
return result;
|
|
@@ -1912,10 +2093,47 @@ __publicField(_GVL, "LANGUAGE_CACHE", /* @__PURE__ */ new Map());
|
|
|
1912
2093
|
__publicField(_GVL, "CACHE", /* @__PURE__ */ new Map());
|
|
1913
2094
|
__publicField(_GVL, "LATEST_CACHE_KEY", 0);
|
|
1914
2095
|
__publicField(_GVL, "DEFAULT_LANGUAGE", "EN");
|
|
2096
|
+
/**
|
|
2097
|
+
* Set of available consent languages published by the IAB
|
|
2098
|
+
*/
|
|
1915
2099
|
__publicField(_GVL, "consentLanguages", new ConsentLanguages());
|
|
1916
2100
|
__publicField(_GVL, "baseUrl_");
|
|
2101
|
+
/**
|
|
2102
|
+
* @static
|
|
2103
|
+
* @param {string} - the latest is assumed to be vendor-list.json because
|
|
2104
|
+
* that is what the iab uses, but it could be different... if you want
|
|
2105
|
+
*/
|
|
1917
2106
|
__publicField(_GVL, "latestFilename", "vendor-list.json");
|
|
2107
|
+
/**
|
|
2108
|
+
* @static
|
|
2109
|
+
* @param {string} - the versioned name is assumed to be
|
|
2110
|
+
* vendor-list-v[VERSION].json where [VERSION] will be replaced with the
|
|
2111
|
+
* specified version. But it could be different... if you want just make
|
|
2112
|
+
* sure to include the [VERSION] macro if you have a numbering scheme, it's a
|
|
2113
|
+
* simple string substitution.
|
|
2114
|
+
*
|
|
2115
|
+
* eg.
|
|
2116
|
+
* ```javascript
|
|
2117
|
+
* GVL.baseUrl = "http://www.mydomain.com/iabcmp/";
|
|
2118
|
+
* GVL.versionedFilename = "vendorlist?getVersion=[VERSION]";
|
|
2119
|
+
* ```
|
|
2120
|
+
*/
|
|
1918
2121
|
__publicField(_GVL, "versionedFilename", "archives/vendor-list-v[VERSION].json");
|
|
2122
|
+
/**
|
|
2123
|
+
* @param {string} - Translations of the names and descriptions for Purposes,
|
|
2124
|
+
* Special Purposes, Features, and Special Features to non-English languages
|
|
2125
|
+
* are contained in a file where attributes containing English content
|
|
2126
|
+
* (except vendor declaration information) are translated. The iab publishes
|
|
2127
|
+
* one following the scheme below where the LANG is the iso639-1 language
|
|
2128
|
+
* code. For a list of available translations
|
|
2129
|
+
* [please go here](https://register.consensu.org/Translation).
|
|
2130
|
+
*
|
|
2131
|
+
* eg.
|
|
2132
|
+
* ```javascript
|
|
2133
|
+
* GVL.baseUrl = "http://www.mydomain.com/iabcmp/";
|
|
2134
|
+
* GVL.languageFilename = "purposes?getPurposes=[LANG]";
|
|
2135
|
+
* ```
|
|
2136
|
+
*/
|
|
1919
2137
|
__publicField(_GVL, "languageFilename", "purposes-[LANG].json");
|
|
1920
2138
|
let GVL = _GVL;
|
|
1921
2139
|
class TCModel extends Cloneable {
|
|
@@ -1941,20 +2159,83 @@ class TCModel extends Cloneable {
|
|
|
1941
2159
|
__publicField(this, "cmpVersion_", 0);
|
|
1942
2160
|
__publicField(this, "vendorListVersion_", 0);
|
|
1943
2161
|
__publicField(this, "numCustomPurposes_", 0);
|
|
2162
|
+
// Member Variable for GVL
|
|
1944
2163
|
__publicField(this, "gvl_");
|
|
1945
2164
|
__publicField(this, "created");
|
|
1946
2165
|
__publicField(this, "lastUpdated");
|
|
2166
|
+
/**
|
|
2167
|
+
* The TCF designates certain Features as special, that is, a CMP must afford
|
|
2168
|
+
* the user a means to opt in to their use. These Special Features are
|
|
2169
|
+
* published and numbered in the GVL separately from normal Features.
|
|
2170
|
+
* Provides for up to 12 special features.
|
|
2171
|
+
*/
|
|
1947
2172
|
__publicField(this, "specialFeatureOptins", new Vector());
|
|
2173
|
+
/**
|
|
2174
|
+
* Renamed from `PurposesAllowed` in TCF v1.1
|
|
2175
|
+
* The user’s consent value for each Purpose established on the legal basis
|
|
2176
|
+
* of consent. Purposes are published in the Global Vendor List (see. [[GVL]]).
|
|
2177
|
+
*/
|
|
1948
2178
|
__publicField(this, "purposeConsents", new Vector());
|
|
2179
|
+
/**
|
|
2180
|
+
* The user’s permission for each Purpose established on the legal basis of
|
|
2181
|
+
* legitimate interest. If the user has exercised right-to-object for a
|
|
2182
|
+
* purpose.
|
|
2183
|
+
*/
|
|
1949
2184
|
__publicField(this, "purposeLegitimateInterests", new Vector());
|
|
2185
|
+
/**
|
|
2186
|
+
* The user’s consent value for each Purpose established on the legal basis
|
|
2187
|
+
* of consent, for the publisher. Purposes are published in the Global
|
|
2188
|
+
* Vendor List.
|
|
2189
|
+
*/
|
|
1950
2190
|
__publicField(this, "publisherConsents", new Vector());
|
|
2191
|
+
/**
|
|
2192
|
+
* The user’s permission for each Purpose established on the legal basis of
|
|
2193
|
+
* legitimate interest. If the user has exercised right-to-object for a
|
|
2194
|
+
* purpose.
|
|
2195
|
+
*/
|
|
1951
2196
|
__publicField(this, "publisherLegitimateInterests", new Vector());
|
|
2197
|
+
/**
|
|
2198
|
+
* The user’s consent value for each Purpose established on the legal basis
|
|
2199
|
+
* of consent, for the publisher. Purposes are published in the Global
|
|
2200
|
+
* Vendor List.
|
|
2201
|
+
*/
|
|
1952
2202
|
__publicField(this, "publisherCustomConsents", new Vector());
|
|
2203
|
+
/**
|
|
2204
|
+
* The user’s permission for each Purpose established on the legal basis of
|
|
2205
|
+
* legitimate interest. If the user has exercised right-to-object for a
|
|
2206
|
+
* purpose that is established in the publisher's custom purposes.
|
|
2207
|
+
*/
|
|
1953
2208
|
__publicField(this, "publisherCustomLegitimateInterests", new Vector());
|
|
2209
|
+
/**
|
|
2210
|
+
* set by a publisher if they wish to collect consent and LI Transparency for
|
|
2211
|
+
* purposes outside of the TCF
|
|
2212
|
+
*/
|
|
1954
2213
|
__publicField(this, "customPurposes");
|
|
2214
|
+
/**
|
|
2215
|
+
* Each [[Vendor]] is keyed by id. Their consent value is true if it is in
|
|
2216
|
+
* the Vector
|
|
2217
|
+
*/
|
|
1955
2218
|
__publicField(this, "vendorConsents", new Vector());
|
|
2219
|
+
/**
|
|
2220
|
+
* Each [[Vendor]] is keyed by id. Whether their Legitimate Interests
|
|
2221
|
+
* Disclosures have been established is stored as boolean.
|
|
2222
|
+
* see: [[Vector]]
|
|
2223
|
+
*/
|
|
1956
2224
|
__publicField(this, "vendorLegitimateInterests", new Vector());
|
|
2225
|
+
/**
|
|
2226
|
+
* The value included for disclosed vendors signals which vendors have been
|
|
2227
|
+
* disclosed to the user in the interface surfaced by the CMP. This section
|
|
2228
|
+
* content is required when writing a TC string to the global (consensu)
|
|
2229
|
+
* scope. When a CMP has read from and is updating a TC string from the
|
|
2230
|
+
* global consensu.org storage, the CMP MUST retain the existing disclosure
|
|
2231
|
+
* information and only add information for vendors that it has disclosed
|
|
2232
|
+
* that had not been disclosed by other CMPs in prior interactions with this
|
|
2233
|
+
* device/user agent.
|
|
2234
|
+
*/
|
|
1957
2235
|
__publicField(this, "vendorsDisclosed", new Vector());
|
|
2236
|
+
/**
|
|
2237
|
+
* Signals which vendors the publisher permits to use OOB legal bases.
|
|
2238
|
+
*/
|
|
1958
2239
|
__publicField(this, "vendorsAllowed", new Vector());
|
|
1959
2240
|
__publicField(this, "publisherRestrictions", new PurposeRestrictionVector());
|
|
1960
2241
|
if (gvl) {
|
|
@@ -2336,6 +2617,9 @@ class TCModel extends Cloneable {
|
|
|
2336
2617
|
this.lastUpdated = utcDate;
|
|
2337
2618
|
}
|
|
2338
2619
|
}
|
|
2620
|
+
/**
|
|
2621
|
+
* Set of available consent languages published by the IAB
|
|
2622
|
+
*/
|
|
2339
2623
|
__publicField(TCModel, "consentLanguages", GVL.consentLanguages);
|
|
2340
2624
|
class TCString {
|
|
2341
2625
|
/**
|
|
@@ -2389,20 +2673,6 @@ class TCString {
|
|
|
2389
2673
|
return tcModel;
|
|
2390
2674
|
}
|
|
2391
2675
|
}
|
|
2392
|
-
const iabCustomCategories = {
|
|
2393
|
-
permutiveAds: {
|
|
2394
|
-
purposes: [2, 4, 8, 9],
|
|
2395
|
-
iabVendors: [361],
|
|
2396
|
-
customVendors: [],
|
|
2397
|
-
specialFeatures: []
|
|
2398
|
-
},
|
|
2399
|
-
demographicAds: {
|
|
2400
|
-
purposes: [3, 4, 7, 9, 10],
|
|
2401
|
-
iabVendors: [],
|
|
2402
|
-
customVendors: [],
|
|
2403
|
-
specialFeatures: []
|
|
2404
|
-
}
|
|
2405
|
-
};
|
|
2406
2676
|
function isValidGdprValue(val) {
|
|
2407
2677
|
if (val === null) {
|
|
2408
2678
|
return true;
|
|
@@ -2444,10 +2714,6 @@ function validateIabConsentCategory(categoryName) {
|
|
|
2444
2714
|
throw new Error("Provided custom category identifier does not exist. Please check");
|
|
2445
2715
|
}
|
|
2446
2716
|
}
|
|
2447
|
-
const legislation = {
|
|
2448
|
-
CCPA: "ccpa",
|
|
2449
|
-
GDPR: "gdpr"
|
|
2450
|
-
};
|
|
2451
2717
|
function checkConsentFor(categoryName, consentState) {
|
|
2452
2718
|
validateIabConsentCategory(categoryName);
|
|
2453
2719
|
validateRawConsentState(consentState);
|
|
@@ -2477,47 +2743,29 @@ function getParsedConsent(rawConsentState) {
|
|
|
2477
2743
|
return parsedConsent;
|
|
2478
2744
|
}, {});
|
|
2479
2745
|
}
|
|
2480
|
-
function
|
|
2481
|
-
const
|
|
2482
|
-
"
|
|
2746
|
+
function getConsentCookieValue() {
|
|
2747
|
+
const cookies = Object.fromEntries(
|
|
2748
|
+
document.cookie.split("; ").map((cookie) => cookie.split("="))
|
|
2749
|
+
);
|
|
2750
|
+
const encodedValue = cookies[CONSENT_COOKIE_NAME];
|
|
2751
|
+
if (!encodedValue)
|
|
2752
|
+
return {};
|
|
2753
|
+
const decodedValue = decodeURIComponent(encodedValue);
|
|
2754
|
+
return Object.fromEntries(
|
|
2755
|
+
decodedValue.split(",").map((consent) => {
|
|
2756
|
+
const [category, value] = consent.split(":");
|
|
2757
|
+
const booleanConsent = [category, value === "on" ? true : false];
|
|
2758
|
+
return booleanConsent;
|
|
2759
|
+
})
|
|
2483
2760
|
);
|
|
2484
|
-
if (cookieLink) {
|
|
2485
|
-
cookieLink.href = "#";
|
|
2486
|
-
cookieLink.setAttribute("onclick", "window._sp_.gdpr.loadPrivacyManagerModal(827767);");
|
|
2487
|
-
cookieLink.dataset.cmpLink = "updated";
|
|
2488
|
-
return true;
|
|
2489
|
-
} else {
|
|
2490
|
-
console.warn("CMP Footer Link was not found and not updated");
|
|
2491
|
-
return false;
|
|
2492
|
-
}
|
|
2493
2761
|
}
|
|
2494
|
-
|
|
2495
|
-
const
|
|
2496
|
-
const
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
onsite: {
|
|
2502
|
-
status: parsedConsent[categoryName],
|
|
2503
|
-
lbi: false,
|
|
2504
|
-
source: SOURCEPOINT_CONSENT_SOURCE,
|
|
2505
|
-
fow: formOfWordsId
|
|
2506
|
-
}
|
|
2507
|
-
};
|
|
2508
|
-
return payload;
|
|
2509
|
-
}, {});
|
|
2510
|
-
if (!shouldUpdateConsentStore) {
|
|
2511
|
-
return { data };
|
|
2512
|
-
} else {
|
|
2513
|
-
return {
|
|
2514
|
-
setConsentCookie: true,
|
|
2515
|
-
formOfWordsId,
|
|
2516
|
-
consentSource: SOURCEPOINT_CONSENT_SOURCE,
|
|
2517
|
-
cookieDomain,
|
|
2518
|
-
data
|
|
2519
|
-
};
|
|
2520
|
-
}
|
|
2762
|
+
function hasConsentChanged(parsedConsent) {
|
|
2763
|
+
const categories = Object.keys(parsedConsent);
|
|
2764
|
+
const previousConsent = getConsentCookieValue();
|
|
2765
|
+
return categories.some((category) => {
|
|
2766
|
+
const adaptedCategoryName = `${category.toLowerCase()}Onsite`;
|
|
2767
|
+
return parsedConsent[category] !== previousConsent[adaptedCategoryName];
|
|
2768
|
+
});
|
|
2521
2769
|
}
|
|
2522
2770
|
async function saveConsent(consentEndpoint, payload) {
|
|
2523
2771
|
try {
|
|
@@ -2538,7 +2786,7 @@ async function saveConsent(consentEndpoint, payload) {
|
|
|
2538
2786
|
}
|
|
2539
2787
|
function consentReadyHandlerFn(props) {
|
|
2540
2788
|
const { userId, consentProxyHost, cookieDomain, formOfWordsId, useConsentStore } = props;
|
|
2541
|
-
return async (legislation2, _, consentString, consentMeta)
|
|
2789
|
+
return async function consentReadyHandler(legislation2, _, consentString, consentMeta) {
|
|
2542
2790
|
const activeLegislation = consentMeta.applies ? legislation2 : "gdpr";
|
|
2543
2791
|
if (activeLegislation !== legislation2 || !consentString) {
|
|
2544
2792
|
return;
|
|
@@ -2557,7 +2805,7 @@ function consentReadyHandlerFn(props) {
|
|
|
2557
2805
|
if (shouldUpdateConsentStore) {
|
|
2558
2806
|
consentEndpoint = `${consentProxyHost}/__consent/consent-record/${SOURCEPOINT_FOW_SCOPE}/${userId}`;
|
|
2559
2807
|
}
|
|
2560
|
-
const payload =
|
|
2808
|
+
const payload = getConsentPayload(parsedConsent, {
|
|
2561
2809
|
formOfWordsId,
|
|
2562
2810
|
cookieDomain,
|
|
2563
2811
|
shouldUpdateConsentStore
|
|
@@ -2566,51 +2814,6 @@ function consentReadyHandlerFn(props) {
|
|
|
2566
2814
|
document.dispatchEvent(new CustomEvent("oCookieMessage.act", { bubbles: true }));
|
|
2567
2815
|
};
|
|
2568
2816
|
}
|
|
2569
|
-
function hasConsentChanged(parsedConsent) {
|
|
2570
|
-
const categories = Object.keys(parsedConsent);
|
|
2571
|
-
const previousConsent = getConsentCookieValue();
|
|
2572
|
-
return categories.some((category) => {
|
|
2573
|
-
const adaptedCategoryName = `${category.toLowerCase()}Onsite`;
|
|
2574
|
-
return parsedConsent[category] !== previousConsent[adaptedCategoryName];
|
|
2575
|
-
});
|
|
2576
|
-
}
|
|
2577
|
-
function getConsentCookieValue() {
|
|
2578
|
-
const cookies = Object.fromEntries(
|
|
2579
|
-
document.cookie.split("; ").map((cookie) => cookie.split("="))
|
|
2580
|
-
);
|
|
2581
|
-
const encodedValue = cookies[CONSENT_COOKIE_NAME];
|
|
2582
|
-
if (!encodedValue)
|
|
2583
|
-
return {};
|
|
2584
|
-
const decodedValue = decodeURIComponent(encodedValue);
|
|
2585
|
-
return Object.fromEntries(
|
|
2586
|
-
decodedValue.split(",").map((consent) => {
|
|
2587
|
-
const [category, value] = consent.split(":");
|
|
2588
|
-
const booleanConsent = [category, value === "on" ? true : false];
|
|
2589
|
-
return booleanConsent;
|
|
2590
|
-
})
|
|
2591
|
-
);
|
|
2592
|
-
}
|
|
2593
|
-
const SOURCEPOINT_FOW_ID = "sourcepointCmp/VngD.XycZut.595cp9fWdp5XYP9vlFvk";
|
|
2594
|
-
const FT_COOKIE_DOMAIN = ".ft.com";
|
|
2595
|
-
const FT_CONSENT_PROXY_HOST = "https://consent.ft.com";
|
|
2596
|
-
function createContentScript(content) {
|
|
2597
|
-
const s = document.createElement("script");
|
|
2598
|
-
s.innerHTML = content;
|
|
2599
|
-
return s;
|
|
2600
|
-
}
|
|
2601
|
-
function createSourceScript(src) {
|
|
2602
|
-
const s = document.createElement("script");
|
|
2603
|
-
s.src = src;
|
|
2604
|
-
return s;
|
|
2605
|
-
}
|
|
2606
|
-
function getCmpScripts(config) {
|
|
2607
|
-
const fragment = document.createDocumentFragment();
|
|
2608
|
-
fragment.appendChild(createContentScript(scriptContent.tcfStub));
|
|
2609
|
-
fragment.appendChild(createContentScript(scriptContent.uspStub));
|
|
2610
|
-
fragment.appendChild(createContentScript(scriptContent.getSPConfig(config)));
|
|
2611
|
-
fragment.appendChild(createSourceScript(scriptSources.cmpFrames));
|
|
2612
|
-
return fragment;
|
|
2613
|
-
}
|
|
2614
2817
|
async function initSourcepointCmp({
|
|
2615
2818
|
propertyConfig = FT_DOTCOM_PROD,
|
|
2616
2819
|
userId,
|
|
@@ -2620,11 +2823,10 @@ async function initSourcepointCmp({
|
|
|
2620
2823
|
formOfWordsId = SOURCEPOINT_FOW_ID,
|
|
2621
2824
|
useConsentStore = true
|
|
2622
2825
|
}) {
|
|
2623
|
-
|
|
2624
|
-
if (!maybeUserId && useFTSession) {
|
|
2826
|
+
if (!userId && useFTSession) {
|
|
2625
2827
|
try {
|
|
2626
2828
|
const response = await getUuid();
|
|
2627
|
-
|
|
2829
|
+
userId = response == null ? void 0 : response.uuid;
|
|
2628
2830
|
} catch (error) {
|
|
2629
2831
|
console.error(error);
|
|
2630
2832
|
}
|
|
@@ -2632,8 +2834,8 @@ async function initSourcepointCmp({
|
|
|
2632
2834
|
if (!(propertyConfig == null ? void 0 : propertyConfig.accountId)) {
|
|
2633
2835
|
throw new Error("Please pass a valid property config");
|
|
2634
2836
|
}
|
|
2635
|
-
if (
|
|
2636
|
-
propertyConfig.authId =
|
|
2837
|
+
if (userId) {
|
|
2838
|
+
propertyConfig.authId = userId;
|
|
2637
2839
|
}
|
|
2638
2840
|
const scripts = getCmpScripts(propertyConfig);
|
|
2639
2841
|
document.head.appendChild(scripts);
|
|
@@ -2641,7 +2843,7 @@ async function initSourcepointCmp({
|
|
|
2641
2843
|
window._sp_.addEventListener(
|
|
2642
2844
|
"onConsentReady",
|
|
2643
2845
|
consentReadyHandlerFn({
|
|
2644
|
-
userId
|
|
2846
|
+
userId,
|
|
2645
2847
|
consentProxyHost,
|
|
2646
2848
|
cookieDomain,
|
|
2647
2849
|
formOfWordsId,
|
|
@@ -2650,8 +2852,57 @@ async function initSourcepointCmp({
|
|
|
2650
2852
|
);
|
|
2651
2853
|
});
|
|
2652
2854
|
}
|
|
2855
|
+
const events = {
|
|
2856
|
+
onMessageChoiceSelect: (...args) => {
|
|
2857
|
+
console.log("[event] onMessageChoiceSelect", args);
|
|
2858
|
+
},
|
|
2859
|
+
onMessageReady: (...args) => {
|
|
2860
|
+
console.log("[event] onMessageReady", args);
|
|
2861
|
+
},
|
|
2862
|
+
onMessageChoiceError: (...args) => {
|
|
2863
|
+
console.log("[event] onMessageChoiceError", args);
|
|
2864
|
+
},
|
|
2865
|
+
onPrivacyManagerAction: (...args) => {
|
|
2866
|
+
console.log("[event] onPrivacyManagerAction", args);
|
|
2867
|
+
},
|
|
2868
|
+
onPMCancel: (...args) => {
|
|
2869
|
+
console.log("[event] onPMCancel", args);
|
|
2870
|
+
},
|
|
2871
|
+
onMessageReceiveData: (...args) => {
|
|
2872
|
+
console.log("[event] onMessageReceiveData", args);
|
|
2873
|
+
},
|
|
2874
|
+
onSPPMObjectReady: (...args) => {
|
|
2875
|
+
console.log("[event] onSPPMObjectReady", args);
|
|
2876
|
+
},
|
|
2877
|
+
onConsentReady: (...args) => {
|
|
2878
|
+
console.log("[event] onConsentReady", args);
|
|
2879
|
+
},
|
|
2880
|
+
onError: (...args) => {
|
|
2881
|
+
console.log("[event] onError", args);
|
|
2882
|
+
}
|
|
2883
|
+
};
|
|
2884
|
+
const debug = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2885
|
+
__proto__: null,
|
|
2886
|
+
events
|
|
2887
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
2888
|
+
function updateFooterLinkCMP() {
|
|
2889
|
+
const cookieLink = document.querySelector(
|
|
2890
|
+
"[href='https://www.ft.com/preferences/manage-cookies']"
|
|
2891
|
+
);
|
|
2892
|
+
if (cookieLink) {
|
|
2893
|
+
cookieLink.href = "#";
|
|
2894
|
+
cookieLink.setAttribute("onclick", "window._sp_.gdpr.loadPrivacyManagerModal(827767);");
|
|
2895
|
+
cookieLink.dataset.cmpLink = "updated";
|
|
2896
|
+
return true;
|
|
2897
|
+
} else {
|
|
2898
|
+
console.warn("CMP Footer Link was not found and not updated");
|
|
2899
|
+
return false;
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2653
2902
|
export {
|
|
2903
|
+
debug,
|
|
2654
2904
|
getCmpScripts,
|
|
2655
2905
|
initSourcepointCmp,
|
|
2906
|
+
properties,
|
|
2656
2907
|
updateFooterLinkCMP
|
|
2657
2908
|
};
|