c15t 1.6.0 → 1.7.0
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/CHANGELOG.md +30 -0
- package/dist/index.cjs +658 -98
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +632 -93
- package/dist/libs/fetch-consent-banner.d.ts +2 -0
- package/dist/libs/fetch-consent-banner.d.ts.map +1 -1
- package/dist/libs/gtm.d.ts +7 -0
- package/dist/libs/gtm.d.ts.map +1 -1
- package/dist/libs/has.d.ts +9 -0
- package/dist/libs/has.d.ts.map +1 -1
- package/dist/libs/iframe-blocker/core.d.ts +90 -0
- package/dist/libs/iframe-blocker/core.d.ts.map +1 -0
- package/dist/libs/iframe-blocker/index.d.ts +3 -0
- package/dist/libs/iframe-blocker/index.d.ts.map +1 -0
- package/dist/libs/iframe-blocker/store.d.ts +35 -0
- package/dist/libs/iframe-blocker/store.d.ts.map +1 -0
- package/dist/libs/iframe-blocker/types.d.ts +26 -0
- package/dist/libs/iframe-blocker/types.d.ts.map +1 -0
- package/dist/libs/save-consents.d.ts +3 -0
- package/dist/libs/save-consents.d.ts.map +1 -1
- package/dist/libs/script-loader/core.d.ts +117 -0
- package/dist/libs/script-loader/core.d.ts.map +1 -0
- package/dist/libs/script-loader/index.d.ts +10 -0
- package/dist/libs/script-loader/index.d.ts.map +1 -0
- package/dist/libs/script-loader/store.d.ts +58 -0
- package/dist/libs/script-loader/store.d.ts.map +1 -0
- package/dist/libs/script-loader/types.d.ts +160 -0
- package/dist/libs/script-loader/types.d.ts.map +1 -0
- package/dist/libs/script-loader/utils.d.ts +56 -0
- package/dist/libs/script-loader/utils.d.ts.map +1 -0
- package/dist/libs/tracking-blocker.d.ts +53 -4
- package/dist/libs/tracking-blocker.d.ts.map +1 -1
- package/dist/store.d.ts +38 -3
- package/dist/store.d.ts.map +1 -1
- package/dist/store.initial-state.d.ts +1 -8
- package/dist/store.initial-state.d.ts.map +1 -1
- package/dist/store.type.d.ts +52 -0
- package/dist/store.type.d.ts.map +1 -1
- package/dist/types/callbacks.d.ts +21 -0
- package/dist/types/callbacks.d.ts.map +1 -1
- package/dist/types/compliance.d.ts +2 -0
- package/dist/types/compliance.d.ts.map +1 -1
- package/dist/types/gdpr.d.ts +23 -0
- package/dist/types/gdpr.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -29
- package/dist/types/index.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -26,16 +26,23 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
26
26
|
__webpack_require__.d(__webpack_exports__, {
|
|
27
27
|
CustomClient: ()=>CustomClient,
|
|
28
28
|
consentTypes: ()=>gdpr_consentTypes,
|
|
29
|
-
C15tClient: ()=>C15tClient,
|
|
30
|
-
defaultTranslationConfig: ()=>defaultTranslationConfig,
|
|
31
|
-
deepMergeTranslations: ()=>translations_namespaceObject.deepMergeTranslations,
|
|
32
29
|
mergeTranslationConfigs: ()=>translations_namespaceObject.mergeTranslationConfigs,
|
|
30
|
+
prepareTranslationConfig: ()=>translations_namespaceObject.prepareTranslationConfig,
|
|
31
|
+
deepMergeTranslations: ()=>translations_namespaceObject.deepMergeTranslations,
|
|
33
32
|
createTrackingBlocker: ()=>createTrackingBlocker,
|
|
33
|
+
loadScripts: ()=>loadScripts,
|
|
34
|
+
getLoadedScriptIds: ()=>getLoadedScriptIds,
|
|
35
|
+
createConsentManagerStore: ()=>createConsentManagerStore,
|
|
36
|
+
unloadScripts: ()=>unloadScripts,
|
|
37
|
+
allConsentNames: ()=>allConsentNames,
|
|
38
|
+
C15tClient: ()=>C15tClient,
|
|
39
|
+
defaultTranslationConfig: ()=>defaultTranslationConfig,
|
|
34
40
|
configureConsentManager: ()=>configureConsentManager,
|
|
41
|
+
createIframeBlocker: ()=>createIframeBlocker,
|
|
35
42
|
detectBrowserLanguage: ()=>translations_namespaceObject.detectBrowserLanguage,
|
|
36
|
-
|
|
43
|
+
isScriptLoaded: ()=>isScriptLoaded,
|
|
37
44
|
OfflineClient: ()=>OfflineClient,
|
|
38
|
-
|
|
45
|
+
updateScripts: ()=>core_updateScripts,
|
|
39
46
|
API_ENDPOINTS: ()=>API_ENDPOINTS
|
|
40
47
|
});
|
|
41
48
|
const translations_namespaceObject = require("@c15t/translations");
|
|
@@ -643,6 +650,526 @@ function configureConsentManager(options) {
|
|
|
643
650
|
clientRegistry.set(cacheKey, client);
|
|
644
651
|
return client;
|
|
645
652
|
}
|
|
653
|
+
const gdpr_consentTypes = [
|
|
654
|
+
{
|
|
655
|
+
defaultValue: true,
|
|
656
|
+
description: 'These trackers are used for activities that are strictly necessary to operate or deliver the service you requested from us and, therefore, do not require you to consent.',
|
|
657
|
+
disabled: true,
|
|
658
|
+
display: true,
|
|
659
|
+
gdprType: 1,
|
|
660
|
+
name: 'necessary'
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
defaultValue: false,
|
|
664
|
+
description: 'These trackers enable basic interactions and functionalities that allow you to access selected features of our service and facilitate your communication with us.',
|
|
665
|
+
display: false,
|
|
666
|
+
gdprType: 2,
|
|
667
|
+
name: 'functionality'
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
defaultValue: false,
|
|
671
|
+
description: 'These trackers help us to measure traffic and analyze your behavior to improve our service.',
|
|
672
|
+
display: false,
|
|
673
|
+
gdprType: 4,
|
|
674
|
+
name: 'measurement'
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
defaultValue: false,
|
|
678
|
+
description: 'These trackers help us to improve the quality of your user experience and enable interactions with external content, networks, and platforms.',
|
|
679
|
+
display: false,
|
|
680
|
+
gdprType: 3,
|
|
681
|
+
name: 'experience'
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
defaultValue: false,
|
|
685
|
+
description: 'These trackers help us to deliver personalized ads or marketing content to you, and to measure their performance.',
|
|
686
|
+
display: false,
|
|
687
|
+
gdprType: 5,
|
|
688
|
+
name: 'marketing'
|
|
689
|
+
}
|
|
690
|
+
];
|
|
691
|
+
const allConsentNames = gdpr_consentTypes.map((consent)=>consent.name);
|
|
692
|
+
function validateNonEmptyConditions(conditions, conditionType) {
|
|
693
|
+
if (0 === conditions.length) throw new TypeError(`${conditionType} condition cannot be empty`);
|
|
694
|
+
}
|
|
695
|
+
function evaluateCategoryCondition(category, consents) {
|
|
696
|
+
if (!(category in consents)) throw new Error(`Consent category "${category}" not found in consent state`);
|
|
697
|
+
return consents[category] || false;
|
|
698
|
+
}
|
|
699
|
+
function evaluateAndCondition(andCondition, consents) {
|
|
700
|
+
const andConditions = Array.isArray(andCondition) ? andCondition : [
|
|
701
|
+
andCondition
|
|
702
|
+
];
|
|
703
|
+
validateNonEmptyConditions(andConditions, 'AND');
|
|
704
|
+
return andConditions.every((subCondition)=>evaluateConditionRecursive(subCondition, consents));
|
|
705
|
+
}
|
|
706
|
+
function evaluateOrCondition(orCondition, consents) {
|
|
707
|
+
const orConditions = Array.isArray(orCondition) ? orCondition : [
|
|
708
|
+
orCondition
|
|
709
|
+
];
|
|
710
|
+
validateNonEmptyConditions(orConditions, 'OR');
|
|
711
|
+
return orConditions.some((subCondition)=>evaluateConditionRecursive(subCondition, consents));
|
|
712
|
+
}
|
|
713
|
+
function evaluateConditionRecursive(condition, consents) {
|
|
714
|
+
if ('string' == typeof condition) return evaluateCategoryCondition(condition, consents);
|
|
715
|
+
if ('object' == typeof condition && null !== condition) {
|
|
716
|
+
if ('and' in condition) return evaluateAndCondition(condition.and, consents);
|
|
717
|
+
if ('or' in condition) return evaluateOrCondition(condition.or, consents);
|
|
718
|
+
if ('not' in condition) return !evaluateConditionRecursive(condition.not, consents);
|
|
719
|
+
}
|
|
720
|
+
throw new TypeError(`Invalid condition structure: ${JSON.stringify(condition)}`);
|
|
721
|
+
}
|
|
722
|
+
function has_has(condition, consents) {
|
|
723
|
+
return evaluateConditionRecursive(condition, consents);
|
|
724
|
+
}
|
|
725
|
+
function extractConsentNamesFromCondition(condition) {
|
|
726
|
+
const categories = new Set();
|
|
727
|
+
function recurse(cond) {
|
|
728
|
+
if ('string' == typeof cond) return void categories.add(cond);
|
|
729
|
+
if ('object' == typeof cond && null !== cond) {
|
|
730
|
+
if ('and' in cond) {
|
|
731
|
+
const conditions = Array.isArray(cond.and) ? cond.and : [
|
|
732
|
+
cond.and
|
|
733
|
+
];
|
|
734
|
+
conditions.forEach(recurse);
|
|
735
|
+
} else if ('or' in cond) {
|
|
736
|
+
const conditions = Array.isArray(cond.or) ? cond.or : [
|
|
737
|
+
cond.or
|
|
738
|
+
];
|
|
739
|
+
conditions.forEach(recurse);
|
|
740
|
+
} else if ('not' in cond) recurse(cond.not);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
recurse(condition);
|
|
744
|
+
return Array.from(categories);
|
|
745
|
+
}
|
|
746
|
+
function createDefaultConsentState() {
|
|
747
|
+
return {
|
|
748
|
+
experience: false,
|
|
749
|
+
functionality: false,
|
|
750
|
+
marketing: false,
|
|
751
|
+
measurement: false,
|
|
752
|
+
necessary: true
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
function determineRequiredConsent(iframe) {
|
|
756
|
+
const categoryAttr = iframe.getAttribute('data-category');
|
|
757
|
+
if (!categoryAttr) return;
|
|
758
|
+
if (!allConsentNames.includes(categoryAttr)) throw new Error(`Invalid category attribute "${categoryAttr}" on iframe. Must be one of: ${allConsentNames.join(', ')}`);
|
|
759
|
+
return categoryAttr;
|
|
760
|
+
}
|
|
761
|
+
function processIframeElement(iframe, consents) {
|
|
762
|
+
const dataSrc = iframe.getAttribute('data-src');
|
|
763
|
+
const requiredConsent = determineRequiredConsent(iframe);
|
|
764
|
+
if (!requiredConsent) return;
|
|
765
|
+
const hasConsent = has_has(requiredConsent, consents);
|
|
766
|
+
if (hasConsent) {
|
|
767
|
+
if (dataSrc && !iframe.src) {
|
|
768
|
+
iframe.src = dataSrc;
|
|
769
|
+
iframe.removeAttribute('data-src');
|
|
770
|
+
}
|
|
771
|
+
} else if (iframe.src) iframe.removeAttribute('src');
|
|
772
|
+
}
|
|
773
|
+
function createIframeBlocker(config = {}, initialConsents) {
|
|
774
|
+
const blockerConfig = {
|
|
775
|
+
disableAutomaticBlocking: false,
|
|
776
|
+
...config
|
|
777
|
+
};
|
|
778
|
+
let consents = initialConsents || createDefaultConsentState();
|
|
779
|
+
function processIframes() {
|
|
780
|
+
const iframes = document.querySelectorAll('iframe');
|
|
781
|
+
iframes.forEach((iframe)=>{
|
|
782
|
+
processIframeElement(iframe, consents);
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
function setupMutationObserver() {
|
|
786
|
+
const observer = new MutationObserver((mutations)=>{
|
|
787
|
+
mutations.forEach((mutation)=>{
|
|
788
|
+
mutation.addedNodes.forEach((node)=>{
|
|
789
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
790
|
+
const element = node;
|
|
791
|
+
if (element.tagName && 'IFRAME' === element.tagName.toUpperCase()) processIframeElement(element, consents);
|
|
792
|
+
const iframes = element.querySelectorAll?.('iframe');
|
|
793
|
+
if (iframes) iframes.forEach((iframe)=>{
|
|
794
|
+
processIframeElement(iframe, consents);
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
});
|
|
799
|
+
});
|
|
800
|
+
observer.observe(document.body, {
|
|
801
|
+
childList: true,
|
|
802
|
+
subtree: true
|
|
803
|
+
});
|
|
804
|
+
return observer;
|
|
805
|
+
}
|
|
806
|
+
let mutationObserver = null;
|
|
807
|
+
if (!blockerConfig.disableAutomaticBlocking) {
|
|
808
|
+
processIframes();
|
|
809
|
+
mutationObserver = setupMutationObserver();
|
|
810
|
+
}
|
|
811
|
+
return {
|
|
812
|
+
updateConsents: (newConsents)=>{
|
|
813
|
+
consents = {
|
|
814
|
+
...consents,
|
|
815
|
+
...newConsents
|
|
816
|
+
};
|
|
817
|
+
processIframes();
|
|
818
|
+
},
|
|
819
|
+
processIframes,
|
|
820
|
+
destroy: ()=>{
|
|
821
|
+
if (mutationObserver) {
|
|
822
|
+
mutationObserver.disconnect();
|
|
823
|
+
mutationObserver = null;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
function getIframeConsentCategories() {
|
|
829
|
+
if ('undefined' == typeof document) return [];
|
|
830
|
+
const iframes = document.querySelectorAll('iframe[data-category]');
|
|
831
|
+
const categories = new Set();
|
|
832
|
+
iframes.forEach((iframe)=>{
|
|
833
|
+
const categoryAttr = iframe.getAttribute('data-category');
|
|
834
|
+
if (!categoryAttr) return;
|
|
835
|
+
const category = categoryAttr.trim();
|
|
836
|
+
if (allConsentNames.includes(category)) categories.add(category);
|
|
837
|
+
});
|
|
838
|
+
return Array.from(categories);
|
|
839
|
+
}
|
|
840
|
+
function processAllIframes(consents) {
|
|
841
|
+
if ('undefined' == typeof document) return;
|
|
842
|
+
const iframes = document.querySelectorAll('iframe');
|
|
843
|
+
iframes.forEach((iframe)=>{
|
|
844
|
+
processIframeElement(iframe, consents);
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
function setupIframeObserver(getConsents, onCategoriesDiscovered) {
|
|
848
|
+
const observer = new MutationObserver((mutations)=>{
|
|
849
|
+
const currentConsents = getConsents();
|
|
850
|
+
let hasNewCategories = false;
|
|
851
|
+
mutations.forEach((mutation)=>{
|
|
852
|
+
mutation.addedNodes.forEach((node)=>{
|
|
853
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
854
|
+
const element = node;
|
|
855
|
+
if (element.tagName && 'IFRAME' === element.tagName.toUpperCase()) {
|
|
856
|
+
processIframeElement(element, currentConsents);
|
|
857
|
+
if (element.hasAttribute('data-category')) hasNewCategories = true;
|
|
858
|
+
}
|
|
859
|
+
const iframes = element.querySelectorAll?.('iframe');
|
|
860
|
+
if (iframes && iframes.length > 0) iframes.forEach((iframe)=>{
|
|
861
|
+
processIframeElement(iframe, currentConsents);
|
|
862
|
+
if (iframe.hasAttribute('data-category')) hasNewCategories = true;
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
});
|
|
866
|
+
});
|
|
867
|
+
if (hasNewCategories && onCategoriesDiscovered) {
|
|
868
|
+
const categories = getIframeConsentCategories();
|
|
869
|
+
if (categories.length > 0) onCategoriesDiscovered(categories);
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
observer.observe(document.body, {
|
|
873
|
+
childList: true,
|
|
874
|
+
subtree: true
|
|
875
|
+
});
|
|
876
|
+
return observer;
|
|
877
|
+
}
|
|
878
|
+
function generateRandomScriptId() {
|
|
879
|
+
if ('undefined' != typeof crypto && crypto.randomUUID) return crypto.randomUUID().replace(/-/g, '').substring(0, 8);
|
|
880
|
+
if ('undefined' != typeof crypto && crypto.getRandomValues) {
|
|
881
|
+
const array = new Uint8Array(4);
|
|
882
|
+
crypto.getRandomValues(array);
|
|
883
|
+
return Array.from(array, (byte)=>byte.toString(36)).join('').padEnd(8, '0').substring(0, 8);
|
|
884
|
+
}
|
|
885
|
+
const randomStr = Math.random().toString(36).substring(2);
|
|
886
|
+
return randomStr.padEnd(8, '0').substring(0, 8);
|
|
887
|
+
}
|
|
888
|
+
function getScriptElementId(scriptId, anonymizeId, scriptIdMap) {
|
|
889
|
+
if (anonymizeId) {
|
|
890
|
+
if (scriptIdMap[scriptId]) return scriptIdMap[scriptId];
|
|
891
|
+
scriptIdMap[scriptId] = generateRandomScriptId();
|
|
892
|
+
return scriptIdMap[scriptId];
|
|
893
|
+
}
|
|
894
|
+
return `c15t-script-${scriptId}`;
|
|
895
|
+
}
|
|
896
|
+
const loadedScripts = new Map();
|
|
897
|
+
function hasLoadedScript(src) {
|
|
898
|
+
return loadedScripts.has(src);
|
|
899
|
+
}
|
|
900
|
+
function getLoadedScript(src) {
|
|
901
|
+
return loadedScripts.get(src);
|
|
902
|
+
}
|
|
903
|
+
function setLoadedScript(src, element) {
|
|
904
|
+
loadedScripts.set(src, element);
|
|
905
|
+
}
|
|
906
|
+
function deleteLoadedScript(src) {
|
|
907
|
+
loadedScripts.delete(src);
|
|
908
|
+
}
|
|
909
|
+
function utils_getLoadedScriptsSnapshot() {
|
|
910
|
+
return loadedScripts;
|
|
911
|
+
}
|
|
912
|
+
function loadScripts(scripts, consents, scriptIdMap = {}) {
|
|
913
|
+
const loadedScriptIds = [];
|
|
914
|
+
scripts.forEach((script)=>{
|
|
915
|
+
if (!script.alwaysLoad && !has_has(script.category, consents)) return;
|
|
916
|
+
if (hasLoadedScript(script.id)) return void script.onConsentChange?.({
|
|
917
|
+
id: script.id,
|
|
918
|
+
elementId: getScriptElementId(script.id, false !== script.anonymizeId, scriptIdMap),
|
|
919
|
+
hasConsent: has_has(script.category, consents),
|
|
920
|
+
consents
|
|
921
|
+
});
|
|
922
|
+
if (script.src && script.textContent) throw new Error(`Script '${script.id}' cannot have both 'src' and 'textContent'. Choose one.`);
|
|
923
|
+
if (!script.src && !script.textContent && !script.callbackOnly) throw new Error(`Script '${script.id}' must have either 'src', 'textContent', or 'callbackOnly' set to true.`);
|
|
924
|
+
if (true === script.callbackOnly) {
|
|
925
|
+
const shouldAnonymize = false !== script.anonymizeId;
|
|
926
|
+
const elementId = getScriptElementId(script.id, shouldAnonymize, scriptIdMap);
|
|
927
|
+
const callbackInfo = {
|
|
928
|
+
id: script.id,
|
|
929
|
+
elementId,
|
|
930
|
+
consents,
|
|
931
|
+
hasConsent: has_has(script.category, consents)
|
|
932
|
+
};
|
|
933
|
+
if (script.onBeforeLoad) script.onBeforeLoad(callbackInfo);
|
|
934
|
+
if (script.onLoad) script.onLoad(callbackInfo);
|
|
935
|
+
setLoadedScript(script.id, null);
|
|
936
|
+
loadedScriptIds.push(script.id);
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
939
|
+
const shouldAnonymize = false !== script.anonymizeId;
|
|
940
|
+
const elementId = getScriptElementId(script.id, shouldAnonymize, scriptIdMap);
|
|
941
|
+
if (true === script.persistAfterConsentRevoked) {
|
|
942
|
+
const existingElement = document.getElementById(elementId);
|
|
943
|
+
if (existingElement) {
|
|
944
|
+
const callbackInfo = {
|
|
945
|
+
id: script.id,
|
|
946
|
+
hasConsent: has_has(script.category, consents),
|
|
947
|
+
elementId,
|
|
948
|
+
consents,
|
|
949
|
+
element: existingElement
|
|
950
|
+
};
|
|
951
|
+
script.onConsentChange?.(callbackInfo);
|
|
952
|
+
script.onLoad?.(callbackInfo);
|
|
953
|
+
setLoadedScript(script.id, existingElement);
|
|
954
|
+
loadedScriptIds.push(script.id);
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
const scriptElement = document.createElement("script");
|
|
959
|
+
scriptElement.id = elementId;
|
|
960
|
+
if (script.src) scriptElement.src = script.src;
|
|
961
|
+
else if (script.textContent) scriptElement.textContent = script.textContent;
|
|
962
|
+
if (script.fetchPriority) scriptElement.fetchPriority = script.fetchPriority;
|
|
963
|
+
if (script.async) scriptElement.async = true;
|
|
964
|
+
if (script.defer) scriptElement.defer = true;
|
|
965
|
+
if (script.nonce) scriptElement.nonce = script.nonce;
|
|
966
|
+
if (script.attributes) Object.entries(script.attributes).forEach(([key, value])=>{
|
|
967
|
+
scriptElement.setAttribute(key, value);
|
|
968
|
+
});
|
|
969
|
+
const callbackInfo = {
|
|
970
|
+
id: script.id,
|
|
971
|
+
hasConsent: has_has(script.category, consents),
|
|
972
|
+
elementId,
|
|
973
|
+
consents,
|
|
974
|
+
element: scriptElement
|
|
975
|
+
};
|
|
976
|
+
if (script.onLoad) if (script.textContent) setTimeout(()=>{
|
|
977
|
+
script.onLoad?.({
|
|
978
|
+
...callbackInfo
|
|
979
|
+
});
|
|
980
|
+
}, 0);
|
|
981
|
+
else scriptElement.addEventListener('load', ()=>{
|
|
982
|
+
script.onLoad?.({
|
|
983
|
+
...callbackInfo
|
|
984
|
+
});
|
|
985
|
+
});
|
|
986
|
+
if (script.onError) script.textContent || scriptElement.addEventListener('error', ()=>{
|
|
987
|
+
script.onError?.({
|
|
988
|
+
...callbackInfo,
|
|
989
|
+
error: new Error(`Failed to load script: ${script.src}`)
|
|
990
|
+
});
|
|
991
|
+
});
|
|
992
|
+
if (script.onBeforeLoad) script.onBeforeLoad(callbackInfo);
|
|
993
|
+
document.head.appendChild(scriptElement);
|
|
994
|
+
setLoadedScript(script.id, scriptElement);
|
|
995
|
+
loadedScriptIds.push(script.id);
|
|
996
|
+
});
|
|
997
|
+
return loadedScriptIds;
|
|
998
|
+
}
|
|
999
|
+
function unloadScripts(scripts, consents, scriptIdMap = {}) {
|
|
1000
|
+
const unloadedScriptIds = [];
|
|
1001
|
+
scripts.forEach((script)=>{
|
|
1002
|
+
if (!hasLoadedScript(script.id)) return;
|
|
1003
|
+
if (script.alwaysLoad) return;
|
|
1004
|
+
if (!has_has(script.category, consents)) {
|
|
1005
|
+
const scriptElement = getLoadedScript(script.id);
|
|
1006
|
+
const elementId = scriptIdMap[script.id] || `c15t-script-${script.id}`;
|
|
1007
|
+
if (true === script.callbackOnly || null === scriptElement) {
|
|
1008
|
+
const callbackInfo = {
|
|
1009
|
+
id: script.id,
|
|
1010
|
+
elementId,
|
|
1011
|
+
consents,
|
|
1012
|
+
hasConsent: has_has(script.category, consents)
|
|
1013
|
+
};
|
|
1014
|
+
if (script.onDelete) script.onDelete(callbackInfo);
|
|
1015
|
+
deleteLoadedScript(script.id);
|
|
1016
|
+
unloadedScriptIds.push(script.id);
|
|
1017
|
+
} else if (scriptElement) {
|
|
1018
|
+
const callbackInfo = {
|
|
1019
|
+
id: script.id,
|
|
1020
|
+
elementId,
|
|
1021
|
+
consents,
|
|
1022
|
+
hasConsent: has_has(script.category, consents),
|
|
1023
|
+
element: scriptElement
|
|
1024
|
+
};
|
|
1025
|
+
if (script.onDelete) script.onDelete(callbackInfo);
|
|
1026
|
+
if (script.persistAfterConsentRevoked) {
|
|
1027
|
+
deleteLoadedScript(script.id);
|
|
1028
|
+
unloadedScriptIds.push(script.id);
|
|
1029
|
+
} else {
|
|
1030
|
+
scriptElement.remove();
|
|
1031
|
+
deleteLoadedScript(script.id);
|
|
1032
|
+
unloadedScriptIds.push(script.id);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
});
|
|
1037
|
+
return unloadedScriptIds;
|
|
1038
|
+
}
|
|
1039
|
+
function core_updateScripts(scripts, consents, scriptIdMap = {}) {
|
|
1040
|
+
const unloaded = unloadScripts(scripts, consents, scriptIdMap);
|
|
1041
|
+
const loaded = loadScripts(scripts, consents, scriptIdMap);
|
|
1042
|
+
return {
|
|
1043
|
+
loaded,
|
|
1044
|
+
unloaded
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
function isScriptLoaded(scriptId) {
|
|
1048
|
+
return hasLoadedScript(scriptId);
|
|
1049
|
+
}
|
|
1050
|
+
function getLoadedScriptIds() {
|
|
1051
|
+
return Array.from(utils_getLoadedScriptsSnapshot().keys());
|
|
1052
|
+
}
|
|
1053
|
+
function reloadScript(scriptId, scripts, consents, scriptIdMap = {}) {
|
|
1054
|
+
const script = scripts.find((s)=>s.id === scriptId);
|
|
1055
|
+
if (!script) return false;
|
|
1056
|
+
if (hasLoadedScript(scriptId)) {
|
|
1057
|
+
const scriptElement = getLoadedScript(scriptId);
|
|
1058
|
+
const elementId = scriptIdMap[scriptId] || `c15t-script-${scriptId}`;
|
|
1059
|
+
if (true === script.callbackOnly || null === scriptElement) {
|
|
1060
|
+
const callbackInfo = {
|
|
1061
|
+
id: scriptId,
|
|
1062
|
+
elementId,
|
|
1063
|
+
consents,
|
|
1064
|
+
hasConsent: has_has(script.category, consents)
|
|
1065
|
+
};
|
|
1066
|
+
if (script.onDelete) script.onDelete(callbackInfo);
|
|
1067
|
+
deleteLoadedScript(scriptId);
|
|
1068
|
+
} else if (scriptElement) {
|
|
1069
|
+
const callbackInfo = {
|
|
1070
|
+
id: scriptId,
|
|
1071
|
+
elementId,
|
|
1072
|
+
consents,
|
|
1073
|
+
hasConsent: has_has(script.category, consents),
|
|
1074
|
+
element: scriptElement
|
|
1075
|
+
};
|
|
1076
|
+
if (script.onDelete) script.onDelete(callbackInfo);
|
|
1077
|
+
if (!script.persistAfterConsentRevoked) scriptElement.remove();
|
|
1078
|
+
deleteLoadedScript(scriptId);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
if (!script.alwaysLoad && !has_has(script.category, consents)) return false;
|
|
1082
|
+
loadScripts([
|
|
1083
|
+
script
|
|
1084
|
+
], consents, scriptIdMap);
|
|
1085
|
+
return true;
|
|
1086
|
+
}
|
|
1087
|
+
function createScriptManager(getState, setState, trackingBlocker) {
|
|
1088
|
+
const updateScriptsFn = ()=>{
|
|
1089
|
+
const { scripts, consents, scriptIdMap } = getState();
|
|
1090
|
+
const result = core_updateScripts(scripts, consents, scriptIdMap);
|
|
1091
|
+
const newLoadedScripts = {
|
|
1092
|
+
...getState().loadedScripts
|
|
1093
|
+
};
|
|
1094
|
+
result.loaded.forEach((id)=>{
|
|
1095
|
+
newLoadedScripts[id] = true;
|
|
1096
|
+
});
|
|
1097
|
+
result.unloaded.forEach((id)=>{
|
|
1098
|
+
newLoadedScripts[id] = false;
|
|
1099
|
+
});
|
|
1100
|
+
setState({
|
|
1101
|
+
loadedScripts: newLoadedScripts
|
|
1102
|
+
});
|
|
1103
|
+
return result;
|
|
1104
|
+
};
|
|
1105
|
+
return {
|
|
1106
|
+
updateScripts: ()=>updateScriptsFn(),
|
|
1107
|
+
setScripts: (scripts)=>{
|
|
1108
|
+
if (trackingBlocker) trackingBlocker.destroy();
|
|
1109
|
+
const state = getState();
|
|
1110
|
+
const newScriptIdMap = {
|
|
1111
|
+
...state.scriptIdMap
|
|
1112
|
+
};
|
|
1113
|
+
scripts.forEach((script)=>{
|
|
1114
|
+
if (false !== script.anonymizeId) newScriptIdMap[script.id] = generateRandomScriptId();
|
|
1115
|
+
});
|
|
1116
|
+
const newCategories = scripts.flatMap((script)=>extractConsentNamesFromCondition(script.category));
|
|
1117
|
+
const allCategories = [
|
|
1118
|
+
...new Set([
|
|
1119
|
+
...state.gdprTypes,
|
|
1120
|
+
...newCategories
|
|
1121
|
+
])
|
|
1122
|
+
];
|
|
1123
|
+
setState({
|
|
1124
|
+
scripts: [
|
|
1125
|
+
...state.scripts,
|
|
1126
|
+
...scripts
|
|
1127
|
+
],
|
|
1128
|
+
scriptIdMap: newScriptIdMap,
|
|
1129
|
+
gdprTypes: allCategories
|
|
1130
|
+
});
|
|
1131
|
+
updateScriptsFn();
|
|
1132
|
+
},
|
|
1133
|
+
removeScript: (scriptId)=>{
|
|
1134
|
+
const state = getState();
|
|
1135
|
+
const script = state.scripts.find((s)=>s.id === scriptId);
|
|
1136
|
+
if (hasLoadedScript(scriptId)) {
|
|
1137
|
+
const scriptElement = getLoadedScript(scriptId);
|
|
1138
|
+
if (scriptElement) {
|
|
1139
|
+
const elementId = state.scriptIdMap[scriptId] || `c15t-script-${scriptId}`;
|
|
1140
|
+
const callbackInfo = {
|
|
1141
|
+
id: scriptId,
|
|
1142
|
+
elementId,
|
|
1143
|
+
consents: state.consents,
|
|
1144
|
+
element: scriptElement,
|
|
1145
|
+
hasConsent: has_has(script?.category ?? 'necessary', state.consents)
|
|
1146
|
+
};
|
|
1147
|
+
if (script?.onDelete) script.onDelete(callbackInfo);
|
|
1148
|
+
scriptElement.remove();
|
|
1149
|
+
deleteLoadedScript(scriptId);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
const newScriptIdMap = {
|
|
1153
|
+
...state.scriptIdMap
|
|
1154
|
+
};
|
|
1155
|
+
delete newScriptIdMap[scriptId];
|
|
1156
|
+
setState({
|
|
1157
|
+
scripts: state.scripts.filter((script)=>script.id !== scriptId),
|
|
1158
|
+
loadedScripts: {
|
|
1159
|
+
...state.loadedScripts,
|
|
1160
|
+
[scriptId]: false
|
|
1161
|
+
},
|
|
1162
|
+
scriptIdMap: newScriptIdMap
|
|
1163
|
+
});
|
|
1164
|
+
},
|
|
1165
|
+
reloadScript: (scriptId)=>{
|
|
1166
|
+
const state = getState();
|
|
1167
|
+
return reloadScript(scriptId, state.scripts, state.consents, state.scriptIdMap);
|
|
1168
|
+
},
|
|
1169
|
+
isScriptLoaded: (scriptId)=>isScriptLoaded(scriptId),
|
|
1170
|
+
getLoadedScriptIds: ()=>getLoadedScriptIds()
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
646
1173
|
const DEFAULT_DOMAIN_CONSENT_MAP = {
|
|
647
1174
|
'www.google-analytics.com': 'measurement',
|
|
648
1175
|
'analytics.google.com': 'measurement',
|
|
@@ -788,7 +1315,7 @@ const DEFAULT_DOMAIN_CONSENT_MAP = {
|
|
|
788
1315
|
'app.contentsquare.com': 'experience'
|
|
789
1316
|
};
|
|
790
1317
|
const tracking_domains = DEFAULT_DOMAIN_CONSENT_MAP;
|
|
791
|
-
function
|
|
1318
|
+
function tracking_blocker_createDefaultConsentState() {
|
|
792
1319
|
return {
|
|
793
1320
|
experience: false,
|
|
794
1321
|
functionality: false,
|
|
@@ -808,7 +1335,7 @@ function createTrackingBlocker(config = {}, initialConsents) {
|
|
|
808
1335
|
...config.domainConsentMap
|
|
809
1336
|
}
|
|
810
1337
|
};
|
|
811
|
-
let consents = initialConsents ||
|
|
1338
|
+
let consents = initialConsents || tracking_blocker_createDefaultConsentState();
|
|
812
1339
|
const originalFetch = window.fetch;
|
|
813
1340
|
const originalXHR = window.XMLHttpRequest;
|
|
814
1341
|
function normalizeDomain(domain) {
|
|
@@ -889,7 +1416,7 @@ function hasConsentFor(consentType, consents, honorDoNotTrack) {
|
|
|
889
1416
|
const effectiveConsents = getEffectiveConsents(consents, honorDoNotTrack);
|
|
890
1417
|
return effectiveConsents[consentType] || false;
|
|
891
1418
|
}
|
|
892
|
-
function
|
|
1419
|
+
function hasConsented(consentInfo) {
|
|
893
1420
|
return null !== consentInfo;
|
|
894
1421
|
}
|
|
895
1422
|
function checkLocalStorageAccess(set) {
|
|
@@ -908,16 +1435,17 @@ function checkLocalStorageAccess(set) {
|
|
|
908
1435
|
}
|
|
909
1436
|
return false;
|
|
910
1437
|
}
|
|
911
|
-
function updateStore(data, { set, get, initialTranslationConfig }, hasLocalStorageAccess) {
|
|
1438
|
+
function updateStore(data, { set, get, initialTranslationConfig, trackingBlocker }, hasLocalStorageAccess) {
|
|
912
1439
|
const { consentInfo, ignoreGeoLocation, callbacks, setDetectedCountry } = get();
|
|
913
1440
|
const { translations, location, showConsentBanner } = data;
|
|
1441
|
+
const shouldAutoGrantConsents = data.jurisdiction?.code === 'NONE' && !data.showConsentBanner;
|
|
914
1442
|
const updatedStore = {
|
|
915
1443
|
isLoadingConsentInfo: false,
|
|
916
1444
|
branding: data.branding ?? 'c15t',
|
|
917
1445
|
...null === consentInfo ? {
|
|
918
1446
|
showPopup: showConsentBanner && hasLocalStorageAccess || ignoreGeoLocation
|
|
919
1447
|
} : {},
|
|
920
|
-
...
|
|
1448
|
+
...shouldAutoGrantConsents && {
|
|
921
1449
|
consents: {
|
|
922
1450
|
necessary: true,
|
|
923
1451
|
functionality: true,
|
|
@@ -934,7 +1462,8 @@ function updateStore(data, { set, get, initialTranslationConfig }, hasLocalStora
|
|
|
934
1462
|
},
|
|
935
1463
|
jurisdictionInfo: data.jurisdiction
|
|
936
1464
|
};
|
|
937
|
-
|
|
1465
|
+
translations?.language && translations?.translations;
|
|
1466
|
+
{
|
|
938
1467
|
const translationConfig = (0, translations_namespaceObject.prepareTranslationConfig)({
|
|
939
1468
|
translations: {
|
|
940
1469
|
[translations.language]: translations.translations
|
|
@@ -948,6 +1477,15 @@ function updateStore(data, { set, get, initialTranslationConfig }, hasLocalStora
|
|
|
948
1477
|
updatedStore.hasFetchedBanner = true;
|
|
949
1478
|
updatedStore.lastBannerFetchData = data;
|
|
950
1479
|
set(updatedStore);
|
|
1480
|
+
if (shouldAutoGrantConsents) callbacks?.onConsentSet?.({
|
|
1481
|
+
preferences: {
|
|
1482
|
+
necessary: true,
|
|
1483
|
+
functionality: true,
|
|
1484
|
+
experience: true,
|
|
1485
|
+
marketing: true,
|
|
1486
|
+
measurement: true
|
|
1487
|
+
}
|
|
1488
|
+
});
|
|
951
1489
|
callbacks?.onBannerFetched?.({
|
|
952
1490
|
showConsentBanner: data.showConsentBanner,
|
|
953
1491
|
jurisdiction: data.jurisdiction,
|
|
@@ -957,24 +1495,26 @@ function updateStore(data, { set, get, initialTranslationConfig }, hasLocalStora
|
|
|
957
1495
|
translations: translations.translations
|
|
958
1496
|
}
|
|
959
1497
|
});
|
|
1498
|
+
trackingBlocker?.updateConsents(get().consents);
|
|
1499
|
+
get().updateScripts();
|
|
960
1500
|
}
|
|
961
1501
|
async function fetchConsentBannerInfo(config) {
|
|
962
1502
|
const { get, set, manager, initialData } = config;
|
|
963
|
-
const {
|
|
964
|
-
if ('undefined' == typeof window
|
|
965
|
-
isLoadingConsentInfo: false
|
|
966
|
-
});
|
|
1503
|
+
const { callbacks } = get();
|
|
1504
|
+
if ('undefined' == typeof window) return;
|
|
967
1505
|
const hasLocalStorageAccess = checkLocalStorageAccess(set);
|
|
968
1506
|
if (!hasLocalStorageAccess) return;
|
|
969
1507
|
set({
|
|
970
1508
|
isLoadingConsentInfo: true
|
|
971
1509
|
});
|
|
972
|
-
if (initialData) {
|
|
1510
|
+
if (initialData) try {
|
|
973
1511
|
const showConsentBanner = await initialData;
|
|
974
1512
|
if (showConsentBanner) {
|
|
975
1513
|
updateStore(showConsentBanner, config, true);
|
|
976
1514
|
return showConsentBanner;
|
|
977
1515
|
}
|
|
1516
|
+
} catch (error) {
|
|
1517
|
+
throw error;
|
|
978
1518
|
}
|
|
979
1519
|
try {
|
|
980
1520
|
const { data, error } = await manager.showConsentBanner({
|
|
@@ -1078,78 +1618,49 @@ function updateGTMConsent(consentState) {
|
|
|
1078
1618
|
if (!window.gtag) return;
|
|
1079
1619
|
window.gtag('consent', 'update', mapConsentStateToGTM(consentState));
|
|
1080
1620
|
}
|
|
1081
|
-
function
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1621
|
+
function createIframeManager(get, _set) {
|
|
1622
|
+
let observer = null;
|
|
1623
|
+
let isInitialized = false;
|
|
1624
|
+
return {
|
|
1625
|
+
initializeIframeBlocker: ()=>{
|
|
1626
|
+
if (isInitialized) return;
|
|
1627
|
+
if ('undefined' == typeof document) return;
|
|
1628
|
+
const state = get();
|
|
1629
|
+
if (state.iframeBlockerConfig?.disableAutomaticBlocking) return;
|
|
1630
|
+
const discoverAndRegisterCategories = ()=>{
|
|
1631
|
+
const iframeCategories = getIframeConsentCategories();
|
|
1632
|
+
if (iframeCategories.length > 0) get().updateConsentCategories(iframeCategories);
|
|
1633
|
+
};
|
|
1634
|
+
if ('loading' === document.readyState) document.addEventListener('DOMContentLoaded', discoverAndRegisterCategories);
|
|
1635
|
+
else discoverAndRegisterCategories();
|
|
1636
|
+
setTimeout(discoverAndRegisterCategories, 100);
|
|
1637
|
+
processAllIframes(state.consents);
|
|
1638
|
+
observer = setupIframeObserver(()=>get().consents, (categories)=>get().updateConsentCategories(categories));
|
|
1639
|
+
isInitialized = true;
|
|
1640
|
+
},
|
|
1641
|
+
updateIframeConsents: ()=>{
|
|
1642
|
+
if (!isInitialized) return;
|
|
1643
|
+
if ('undefined' == typeof document) return;
|
|
1644
|
+
const state = get();
|
|
1645
|
+
const { consents, iframeBlockerConfig } = state;
|
|
1646
|
+
if (iframeBlockerConfig?.disableAutomaticBlocking) return;
|
|
1647
|
+
processAllIframes(consents);
|
|
1648
|
+
},
|
|
1649
|
+
destroyIframeBlocker: ()=>{
|
|
1650
|
+
if (!isInitialized) return;
|
|
1651
|
+
if ('undefined' == typeof document) return;
|
|
1652
|
+
const state = get();
|
|
1653
|
+
const { iframeBlockerConfig } = state;
|
|
1654
|
+
if (iframeBlockerConfig?.disableAutomaticBlocking) return;
|
|
1655
|
+
if (observer) {
|
|
1656
|
+
observer.disconnect();
|
|
1657
|
+
observer = null;
|
|
1658
|
+
}
|
|
1659
|
+
isInitialized = false;
|
|
1660
|
+
}
|
|
1661
|
+
};
|
|
1113
1662
|
}
|
|
1114
|
-
const
|
|
1115
|
-
{
|
|
1116
|
-
defaultValue: true,
|
|
1117
|
-
description: 'These trackers are used for activities that are strictly necessary to operate or deliver the service you requested from us and, therefore, do not require you to consent.',
|
|
1118
|
-
disabled: true,
|
|
1119
|
-
display: true,
|
|
1120
|
-
gdprType: 1,
|
|
1121
|
-
name: 'necessary'
|
|
1122
|
-
},
|
|
1123
|
-
{
|
|
1124
|
-
defaultValue: false,
|
|
1125
|
-
description: 'These trackers enable basic interactions and functionalities that allow you to access selected features of our service and facilitate your communication with us.',
|
|
1126
|
-
display: false,
|
|
1127
|
-
gdprType: 2,
|
|
1128
|
-
name: 'functionality'
|
|
1129
|
-
},
|
|
1130
|
-
{
|
|
1131
|
-
defaultValue: false,
|
|
1132
|
-
description: 'These trackers help us to measure traffic and analyze your behavior to improve our service.',
|
|
1133
|
-
display: false,
|
|
1134
|
-
gdprType: 4,
|
|
1135
|
-
name: 'measurement'
|
|
1136
|
-
},
|
|
1137
|
-
{
|
|
1138
|
-
defaultValue: false,
|
|
1139
|
-
description: 'These trackers help us to improve the quality of your user experience and enable interactions with external content, networks, and platforms.',
|
|
1140
|
-
display: false,
|
|
1141
|
-
gdprType: 3,
|
|
1142
|
-
name: 'experience'
|
|
1143
|
-
},
|
|
1144
|
-
{
|
|
1145
|
-
defaultValue: false,
|
|
1146
|
-
description: 'These trackers help us to deliver personalized ads or marketing content to you, and to measure their performance.',
|
|
1147
|
-
display: false,
|
|
1148
|
-
gdprType: 5,
|
|
1149
|
-
name: 'marketing'
|
|
1150
|
-
}
|
|
1151
|
-
];
|
|
1152
|
-
const version = '1.6.0';
|
|
1663
|
+
const version = '1.7.0';
|
|
1153
1664
|
const STORAGE_KEY = 'privacy-consent-storage';
|
|
1154
1665
|
const initialState = {
|
|
1155
1666
|
config: {
|
|
@@ -1206,6 +1717,9 @@ const initialState = {
|
|
|
1206
1717
|
translationConfig: defaultTranslationConfig,
|
|
1207
1718
|
includeNonDisplayedConsents: false,
|
|
1208
1719
|
consentTypes: gdpr_consentTypes,
|
|
1720
|
+
iframeBlockerConfig: {
|
|
1721
|
+
disableAutomaticBlocking: false
|
|
1722
|
+
},
|
|
1209
1723
|
ignoreGeoLocation: false,
|
|
1210
1724
|
privacySettings: {
|
|
1211
1725
|
honorDoNotTrack: true
|
|
@@ -1223,13 +1737,17 @@ const initialState = {
|
|
|
1223
1737
|
setLocationInfo: ()=>{},
|
|
1224
1738
|
getDisplayedConsents: ()=>[],
|
|
1225
1739
|
hasConsented: ()=>false,
|
|
1226
|
-
setTranslationConfig: ()=>{}
|
|
1740
|
+
setTranslationConfig: ()=>{},
|
|
1741
|
+
scripts: [],
|
|
1742
|
+
loadedScripts: {},
|
|
1743
|
+
scriptIdMap: {}
|
|
1227
1744
|
};
|
|
1228
1745
|
async function saveConsents({ manager, type, get, set, trackingBlocker }) {
|
|
1229
|
-
const { callbacks, selectedConsents, consents, consentTypes } = get();
|
|
1746
|
+
const { callbacks, selectedConsents, consents, consentTypes, updateScripts, updateIframeConsents, gdprTypes } = get();
|
|
1230
1747
|
const newConsents = selectedConsents ?? consents ?? {};
|
|
1231
|
-
if ('all' === type)
|
|
1232
|
-
|
|
1748
|
+
if ('all' === type) {
|
|
1749
|
+
for (const consent of consentTypes)if (gdprTypes.includes(consent.name)) newConsents[consent.name] = true;
|
|
1750
|
+
} else if ('necessary' === type) for (const consent of consentTypes)newConsents[consent.name] = 'necessary' === consent.name;
|
|
1233
1751
|
const consentInfo = {
|
|
1234
1752
|
time: Date.now(),
|
|
1235
1753
|
type: type
|
|
@@ -1242,7 +1760,9 @@ async function saveConsents({ manager, type, get, set, trackingBlocker }) {
|
|
|
1242
1760
|
});
|
|
1243
1761
|
await new Promise((resolve)=>setTimeout(resolve, 0));
|
|
1244
1762
|
trackingBlocker?.updateConsents(newConsents);
|
|
1763
|
+
updateIframeConsents();
|
|
1245
1764
|
updateGTMConsent(newConsents);
|
|
1765
|
+
updateScripts();
|
|
1246
1766
|
try {
|
|
1247
1767
|
localStorage.setItem(STORAGE_KEY, JSON.stringify({
|
|
1248
1768
|
consents: newConsents,
|
|
@@ -1287,13 +1807,17 @@ const getStoredConsent = ()=>{
|
|
|
1287
1807
|
const createConsentManagerStore = (manager, options = {})=>{
|
|
1288
1808
|
const { namespace = 'c15tStore', trackingBlockerConfig, isConsentDomain = false, translationConfig } = options;
|
|
1289
1809
|
const storedConsent = getStoredConsent();
|
|
1290
|
-
const
|
|
1810
|
+
const shouldDisableTrackingBlocker = options.scripts && options.scripts.length > 0;
|
|
1811
|
+
const trackingBlocker = 'undefined' == typeof window || shouldDisableTrackingBlocker ? null : createTrackingBlocker(trackingBlockerConfig || {}, storedConsent?.consents || initialState.consents);
|
|
1291
1812
|
const store = (0, vanilla_namespaceObject.createStore)((set, get)=>({
|
|
1292
1813
|
...initialState,
|
|
1814
|
+
gdprTypes: options.initialGdprTypes ?? initialState.gdprTypes,
|
|
1293
1815
|
ignoreGeoLocation: options.ignoreGeoLocation ?? false,
|
|
1294
1816
|
config: options.config ?? initialState.config,
|
|
1817
|
+
iframeBlockerConfig: options.iframeBlockerConfig ?? initialState.iframeBlockerConfig,
|
|
1295
1818
|
isConsentDomain,
|
|
1296
1819
|
callbacks: options.callbacks ?? initialState.callbacks,
|
|
1820
|
+
scripts: options.scripts ?? initialState.scripts,
|
|
1297
1821
|
translationConfig: translationConfig || initialState.translationConfig,
|
|
1298
1822
|
...storedConsent ? {
|
|
1299
1823
|
consents: storedConsent.consents,
|
|
@@ -1392,6 +1916,9 @@ const createConsentManagerStore = (manager, options = {})=>{
|
|
|
1392
1916
|
[name]: callback
|
|
1393
1917
|
}
|
|
1394
1918
|
}));
|
|
1919
|
+
if ('onConsentSet' === name && callback && 'function' == typeof callback) callback?.({
|
|
1920
|
+
preferences: currentState.consents
|
|
1921
|
+
});
|
|
1395
1922
|
if ('onBannerFetched' === name && currentState.hasFetchedBanner && currentState.lastBannerFetchData && callback && 'function' == typeof callback) {
|
|
1396
1923
|
const { lastBannerFetchData } = currentState;
|
|
1397
1924
|
callback?.({
|
|
@@ -1416,7 +1943,8 @@ const createConsentManagerStore = (manager, options = {})=>{
|
|
|
1416
1943
|
initialData: options._initialData,
|
|
1417
1944
|
initialTranslationConfig: options.initialTranslationConfig,
|
|
1418
1945
|
get,
|
|
1419
|
-
set
|
|
1946
|
+
set,
|
|
1947
|
+
trackingBlocker
|
|
1420
1948
|
}),
|
|
1421
1949
|
getDisplayedConsents: ()=>{
|
|
1422
1950
|
const { gdprTypes, consentTypes } = get();
|
|
@@ -1424,7 +1952,7 @@ const createConsentManagerStore = (manager, options = {})=>{
|
|
|
1424
1952
|
},
|
|
1425
1953
|
hasConsented: ()=>{
|
|
1426
1954
|
const { consentInfo } = get();
|
|
1427
|
-
return
|
|
1955
|
+
return hasConsented(consentInfo);
|
|
1428
1956
|
},
|
|
1429
1957
|
getEffectiveConsents: ()=>{
|
|
1430
1958
|
const { consents, privacySettings } = get();
|
|
@@ -1436,14 +1964,29 @@ const createConsentManagerStore = (manager, options = {})=>{
|
|
|
1436
1964
|
},
|
|
1437
1965
|
has: (condition)=>{
|
|
1438
1966
|
const { consents } = get();
|
|
1439
|
-
return
|
|
1967
|
+
return has_has(condition, consents);
|
|
1440
1968
|
},
|
|
1441
1969
|
setTranslationConfig: (config)=>{
|
|
1442
1970
|
set({
|
|
1443
1971
|
translationConfig: config
|
|
1444
1972
|
});
|
|
1445
|
-
}
|
|
1973
|
+
},
|
|
1974
|
+
updateConsentCategories: (newCategories)=>{
|
|
1975
|
+
const allCategories = [
|
|
1976
|
+
...new Set([
|
|
1977
|
+
...get().gdprTypes,
|
|
1978
|
+
...newCategories
|
|
1979
|
+
])
|
|
1980
|
+
];
|
|
1981
|
+
set({
|
|
1982
|
+
gdprTypes: allCategories
|
|
1983
|
+
});
|
|
1984
|
+
},
|
|
1985
|
+
...createScriptManager(get, set, trackingBlocker),
|
|
1986
|
+
...createIframeManager(get, set)
|
|
1446
1987
|
}));
|
|
1988
|
+
store.getState().initializeIframeBlocker();
|
|
1989
|
+
if (options.scripts && options.scripts.length > 0) store.getState().updateConsentCategories(options.scripts.flatMap((script)=>extractConsentNamesFromCondition(script.category)));
|
|
1447
1990
|
if ('undefined' != typeof window) {
|
|
1448
1991
|
window[namespace] = store;
|
|
1449
1992
|
if (options.unstable_googleTagManager) try {
|
|
@@ -1454,7 +1997,10 @@ const createConsentManagerStore = (manager, options = {})=>{
|
|
|
1454
1997
|
} catch (e) {
|
|
1455
1998
|
console.error('Failed to setup Google Tag Manager:', e);
|
|
1456
1999
|
}
|
|
1457
|
-
|
|
2000
|
+
store.getState().callbacks.onConsentSet?.({
|
|
2001
|
+
preferences: store.getState().consents
|
|
2002
|
+
});
|
|
2003
|
+
store.getState().fetchConsentBannerInfo();
|
|
1458
2004
|
}
|
|
1459
2005
|
return store;
|
|
1460
2006
|
};
|
|
@@ -1462,29 +2008,43 @@ exports.API_ENDPOINTS = __webpack_exports__.API_ENDPOINTS;
|
|
|
1462
2008
|
exports.C15tClient = __webpack_exports__.C15tClient;
|
|
1463
2009
|
exports.CustomClient = __webpack_exports__.CustomClient;
|
|
1464
2010
|
exports.OfflineClient = __webpack_exports__.OfflineClient;
|
|
2011
|
+
exports.allConsentNames = __webpack_exports__.allConsentNames;
|
|
1465
2012
|
exports.configureConsentManager = __webpack_exports__.configureConsentManager;
|
|
1466
2013
|
exports.consentTypes = __webpack_exports__.consentTypes;
|
|
1467
2014
|
exports.createConsentManagerStore = __webpack_exports__.createConsentManagerStore;
|
|
2015
|
+
exports.createIframeBlocker = __webpack_exports__.createIframeBlocker;
|
|
1468
2016
|
exports.createTrackingBlocker = __webpack_exports__.createTrackingBlocker;
|
|
1469
2017
|
exports.deepMergeTranslations = __webpack_exports__.deepMergeTranslations;
|
|
1470
2018
|
exports.defaultTranslationConfig = __webpack_exports__.defaultTranslationConfig;
|
|
1471
2019
|
exports.detectBrowserLanguage = __webpack_exports__.detectBrowserLanguage;
|
|
2020
|
+
exports.getLoadedScriptIds = __webpack_exports__.getLoadedScriptIds;
|
|
2021
|
+
exports.isScriptLoaded = __webpack_exports__.isScriptLoaded;
|
|
2022
|
+
exports.loadScripts = __webpack_exports__.loadScripts;
|
|
1472
2023
|
exports.mergeTranslationConfigs = __webpack_exports__.mergeTranslationConfigs;
|
|
1473
2024
|
exports.prepareTranslationConfig = __webpack_exports__.prepareTranslationConfig;
|
|
2025
|
+
exports.unloadScripts = __webpack_exports__.unloadScripts;
|
|
2026
|
+
exports.updateScripts = __webpack_exports__.updateScripts;
|
|
1474
2027
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
1475
2028
|
"API_ENDPOINTS",
|
|
1476
2029
|
"C15tClient",
|
|
1477
2030
|
"CustomClient",
|
|
1478
2031
|
"OfflineClient",
|
|
2032
|
+
"allConsentNames",
|
|
1479
2033
|
"configureConsentManager",
|
|
1480
2034
|
"consentTypes",
|
|
1481
2035
|
"createConsentManagerStore",
|
|
2036
|
+
"createIframeBlocker",
|
|
1482
2037
|
"createTrackingBlocker",
|
|
1483
2038
|
"deepMergeTranslations",
|
|
1484
2039
|
"defaultTranslationConfig",
|
|
1485
2040
|
"detectBrowserLanguage",
|
|
2041
|
+
"getLoadedScriptIds",
|
|
2042
|
+
"isScriptLoaded",
|
|
2043
|
+
"loadScripts",
|
|
1486
2044
|
"mergeTranslationConfigs",
|
|
1487
|
-
"prepareTranslationConfig"
|
|
2045
|
+
"prepareTranslationConfig",
|
|
2046
|
+
"unloadScripts",
|
|
2047
|
+
"updateScripts"
|
|
1488
2048
|
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
1489
2049
|
Object.defineProperty(exports, '__esModule', {
|
|
1490
2050
|
value: true
|