@highfivve/ad-tag 5.8.17 → 5.8.21

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.
Files changed (43) hide show
  1. package/lib/ads/labelConfigService.js +14 -1
  2. package/lib/ads/modules/ad-reload/index.js +146 -142
  3. package/lib/ads/modules/adex/index.js +106 -104
  4. package/lib/ads/modules/cleanup/index.js +64 -61
  5. package/lib/ads/modules/confiant/index.js +29 -29
  6. package/lib/ads/modules/emetriq/index.js +107 -102
  7. package/lib/ads/modules/generic-skin/index.js +128 -127
  8. package/lib/ads/modules/identitylink/index.js +37 -36
  9. package/lib/ads/modules/moli-analytics/eventTracker.js +43 -0
  10. package/lib/ads/modules/moli-analytics/events/gptSlotRenderEnded.js +21 -0
  11. package/lib/ads/modules/moli-analytics/events/index.js +16 -0
  12. package/lib/ads/modules/moli-analytics/events/pageView.js +31 -0
  13. package/lib/ads/modules/moli-analytics/events/prebidAuctionEnd.js +39 -0
  14. package/lib/ads/modules/moli-analytics/events/prebidBidWon.js +23 -0
  15. package/lib/ads/modules/moli-analytics/index.js +161 -0
  16. package/lib/ads/modules/moli-analytics/session.js +60 -0
  17. package/lib/ads/modules/moli-analytics/types.js +1 -0
  18. package/lib/ads/modules/prebid-first-party-data/index.js +41 -43
  19. package/lib/ads/modules/pubstack/abTest.js +11 -0
  20. package/lib/ads/modules/pubstack/index.js +30 -28
  21. package/lib/ads/modules/sticky-footer-ad/index.js +25 -25
  22. package/lib/ads/modules/sticky-footer-ad-v2/index.js +25 -25
  23. package/lib/ads/modules/sticky-header-ad/index.js +44 -42
  24. package/lib/ads/modules/zeotap/index.js +93 -93
  25. package/lib/ads/moli.js +35 -22
  26. package/lib/bundle/adReload.js +2 -2
  27. package/lib/bundle/adex.js +2 -2
  28. package/lib/bundle/cleanup.js +2 -2
  29. package/lib/bundle/confiant.js +2 -2
  30. package/lib/bundle/emetriq.js +2 -2
  31. package/lib/bundle/identityLink.js +2 -2
  32. package/lib/bundle/moliAnalytics.js +2 -0
  33. package/lib/bundle/prebidFirstPartyData.js +2 -2
  34. package/lib/bundle/pubstack.js +2 -2
  35. package/lib/bundle/skin.js +2 -2
  36. package/lib/bundle/stickyFooterAd.js +2 -2
  37. package/lib/bundle/stickyFooterAds2.js +2 -2
  38. package/lib/bundle/stickyHeaderAd.js +2 -2
  39. package/lib/bundle/zeotap.js +2 -2
  40. package/lib/gen/packageJson.js +1 -1
  41. package/lib/types/prebidjs.js +1 -0
  42. package/lib/util/browserStorageKeys.js +1 -0
  43. package/package.json +1 -1
@@ -1,61 +1,53 @@
1
1
  import { mkPrepareRequestAdsStep, HIGH_PRIORITY, mkConfigureStepOncePerRequestAdsCycle } from 'ad-tag/ads/adPipeline';
2
- export class Cleanup {
3
- constructor() {
4
- this.name = 'cleanup';
5
- this.description = 'cleanup out-of-page formats on navigation or ad-reload';
6
- this.moduleType = 'creatives';
7
- this.cleanupConfig = null;
8
- this.cleanUp = (context, configs) => {
9
- configs.forEach(config => {
10
- if ('cssSelectors' in config.deleteMethod) {
11
- config.deleteMethod.cssSelectors.forEach((selector) => {
12
- const elements = context.window__.document.querySelectorAll(selector);
13
- context.logger__.debug('Cleanup Module', `Remove elements with selector ${selector} from dom`, elements);
14
- elements.forEach((element) => {
15
- try {
16
- element.remove();
17
- }
18
- catch (e) {
19
- context.logger__.error('Cleanup Module', `Error removing element with selector ${selector}`, e);
20
- }
21
- });
22
- });
23
- }
24
- else {
25
- config.deleteMethod.jsAsString.forEach(jsLineAsString => {
2
+ export const createCleanup = () => {
3
+ const name = 'cleanup';
4
+ let cleanupConfig = null;
5
+ const config__ = () => cleanupConfig;
6
+ const configure__ = (modulesConfig) => {
7
+ if (modulesConfig?.cleanup && modulesConfig.cleanup.enabled) {
8
+ cleanupConfig = modulesConfig.cleanup;
9
+ }
10
+ };
11
+ const initSteps__ = () => [];
12
+ const cleanUp = (context, configs) => {
13
+ configs.forEach(config => {
14
+ if ('cssSelectors' in config.deleteMethod) {
15
+ config.deleteMethod.cssSelectors.forEach((selector) => {
16
+ const elements = context.window__.document.querySelectorAll(selector);
17
+ context.logger__.debug('Cleanup Module', `Remove elements with selector ${selector} from dom`, elements);
18
+ elements.forEach((element) => {
26
19
  try {
27
- context.logger__.debug('Cleanup Module', `Try to execute string as JS: '${jsLineAsString}'`);
28
- const jsFunction = new Function(jsLineAsString);
29
- jsFunction();
20
+ element.remove();
30
21
  }
31
22
  catch (e) {
32
- context.logger__.error('Cleanup Module', `Error executing JS string: '${jsLineAsString}'`, e);
23
+ context.logger__.error('Cleanup Module', `Error removing element with selector ${selector}`, e);
33
24
  }
34
25
  });
35
- }
36
- });
37
- };
38
- this.hasBidderWonLastAuction = (context, config) => {
39
- const prebidWinningBids = context.window__.pbjs.getAllWinningBids();
40
- const bidderThatWonLastAuctionOnSlot = prebidWinningBids
41
- .filter(bid => bid.adUnitCode === config.domId)
42
- .at(-1)?.bidder;
43
- return bidderThatWonLastAuctionOnSlot === config.bidder;
44
- };
45
- }
46
- configure__(modulesConfig) {
47
- if (modulesConfig?.cleanup && modulesConfig.cleanup.enabled) {
48
- this.cleanupConfig = modulesConfig.cleanup;
49
- }
50
- }
51
- config__() {
52
- return this.cleanupConfig;
53
- }
54
- initSteps__() {
55
- return [];
56
- }
57
- configureSteps__() {
58
- const config = this.cleanupConfig;
26
+ });
27
+ }
28
+ else {
29
+ config.deleteMethod.jsAsString.forEach(jsLineAsString => {
30
+ try {
31
+ context.logger__.debug('Cleanup Module', `Try to execute string as JS: '${jsLineAsString}'`);
32
+ const jsFunction = new Function(jsLineAsString);
33
+ jsFunction();
34
+ }
35
+ catch (e) {
36
+ context.logger__.error('Cleanup Module', `Error executing JS string: '${jsLineAsString}'`, e);
37
+ }
38
+ });
39
+ }
40
+ });
41
+ };
42
+ const hasBidderWonLastAuction = (context, config) => {
43
+ const prebidWinningBids = context.window__.pbjs.getAllWinningBids();
44
+ const bidderThatWonLastAuctionOnSlot = prebidWinningBids
45
+ .filter(bid => bid.adUnitCode === config.domId)
46
+ .at(-1)?.bidder;
47
+ return bidderThatWonLastAuctionOnSlot === config.bidder;
48
+ };
49
+ const configureSteps__ = () => {
50
+ const config = cleanupConfig;
59
51
  return config
60
52
  ? [
61
53
  mkConfigureStepOncePerRequestAdsCycle('destroy-out-of-page-ad-format', (context) => {
@@ -63,16 +55,16 @@ export class Cleanup {
63
55
  return Promise.resolve();
64
56
  }
65
57
  context.window__.pbjs.que.push(() => {
66
- const configsOfDomIdsThatNeedToBeCleaned = config.configs.filter(config => this.hasBidderWonLastAuction(context, config));
67
- this.cleanUp(context, configsOfDomIdsThatNeedToBeCleaned);
58
+ const configsOfDomIdsThatNeedToBeCleaned = config.configs.filter(config => hasBidderWonLastAuction(context, config));
59
+ cleanUp(context, configsOfDomIdsThatNeedToBeCleaned);
68
60
  });
69
61
  return Promise.resolve();
70
62
  })
71
63
  ]
72
64
  : [];
73
- }
74
- prepareRequestAdsSteps__() {
75
- const config = this.cleanupConfig;
65
+ };
66
+ const prepareRequestAdsSteps__ = () => {
67
+ const config = cleanupConfig;
76
68
  return config
77
69
  ? [
78
70
  mkPrepareRequestAdsStep('cleanup-before-ad-reload', HIGH_PRIORITY, (context, slots) => {
@@ -82,12 +74,23 @@ export class Cleanup {
82
74
  context.window__.pbjs.que.push(() => {
83
75
  const configsOfDomIdsThatNeedToBeCleaned = config.configs
84
76
  .filter(config => slots.map(slot => slot.moliSlot.domId).includes(config.domId))
85
- .filter(config => this.hasBidderWonLastAuction(context, config));
86
- this.cleanUp(context, configsOfDomIdsThatNeedToBeCleaned);
77
+ .filter(config => hasBidderWonLastAuction(context, config));
78
+ cleanUp(context, configsOfDomIdsThatNeedToBeCleaned);
87
79
  });
88
80
  return Promise.resolve();
89
81
  })
90
82
  ]
91
83
  : [];
92
- }
93
- }
84
+ };
85
+ return {
86
+ name,
87
+ description: 'cleanup out-of-page formats on navigation or ad-reload',
88
+ moduleType: 'creatives',
89
+ config__,
90
+ configure__,
91
+ initSteps__,
92
+ configureSteps__,
93
+ prepareRequestAdsSteps__,
94
+ cleanUp
95
+ };
96
+ };
@@ -1,47 +1,47 @@
1
1
  import { AssetLoadMethod } from 'ad-tag/util/assetLoaderService';
2
2
  import { mkInitStep } from 'ad-tag/ads/adPipeline';
3
- export class Confiant {
4
- constructor() {
5
- this.name = 'confiant';
6
- this.description = 'ad fraud detection and protection module';
7
- this.moduleType = 'ad-fraud';
8
- this.gvlid = '56';
9
- this.confiantConfig = null;
10
- }
11
- config__() {
12
- return this.confiantConfig;
13
- }
14
- configure__(moduleConfig) {
3
+ export const createConfiant = () => {
4
+ const name = 'confiant';
5
+ const gvlid = '56';
6
+ let confiantConfig = null;
7
+ const config__ = () => confiantConfig;
8
+ const configure__ = (moduleConfig) => {
15
9
  if (moduleConfig?.confiant && moduleConfig.confiant.enabled) {
16
- this.confiantConfig = moduleConfig.confiant;
10
+ confiantConfig = moduleConfig.confiant;
17
11
  }
18
- }
19
- initSteps__() {
20
- const config = this.confiantConfig;
21
- return config ? [mkInitStep('confiant-init', ctx => this.loadConfiant(ctx, config))] : [];
22
- }
23
- loadConfiant(context, config) {
12
+ };
13
+ const loadConfiant = (context, config) => {
24
14
  if (context.env__ === 'test') {
25
15
  return Promise.resolve();
26
16
  }
27
17
  if (context.tcData__.gdprApplies &&
28
18
  (!context.tcData__.purpose.consents['1'] ||
29
- !(!this.confiantConfig?.checkGVLID || context.tcData__.vendor.consents[this.gvlid]))) {
19
+ !(!confiantConfig?.checkGVLID || context.tcData__.vendor.consents[gvlid]))) {
30
20
  return Promise.resolve();
31
21
  }
32
22
  context.assetLoaderService__
33
23
  .loadScript({
34
- name: this.name,
24
+ name,
35
25
  loadMethod: AssetLoadMethod.TAG,
36
26
  assetUrl: config.assetUrl
37
27
  })
38
28
  .catch(error => context.logger__.error('failed to load confiant', error));
39
29
  return Promise.resolve();
40
- }
41
- configureSteps__() {
42
- return [];
43
- }
44
- prepareRequestAdsSteps__() {
45
- return [];
46
- }
47
- }
30
+ };
31
+ const initSteps__ = () => {
32
+ const config = confiantConfig;
33
+ return config ? [mkInitStep('confiant-init', ctx => loadConfiant(ctx, config))] : [];
34
+ };
35
+ const configureSteps__ = () => [];
36
+ const prepareRequestAdsSteps__ = () => [];
37
+ return {
38
+ name,
39
+ description: 'ad fraud detection and protection module',
40
+ moduleType: 'ad-fraud',
41
+ config__,
42
+ configure__,
43
+ initSteps__,
44
+ configureSteps__,
45
+ prepareRequestAdsSteps__
46
+ };
47
+ };
@@ -2,24 +2,96 @@ import { AssetLoadMethod } from 'ad-tag/util/assetLoaderService';
2
2
  import { trackInApp } from './trackInApp';
3
3
  import { shouldTrackLoginEvent, trackLoginEvent } from './trackLoginEvent';
4
4
  import { mkConfigureStepOncePerRequestAdsCycle, mkInitStep } from 'ad-tag/ads/adPipeline';
5
- export class Emetriq {
6
- constructor() {
7
- this.name = 'emetriq';
8
- this.description = 'Provides Emetriq data collection functionality to Moli.';
9
- this.moduleType = 'dmp';
10
- this.gvlid = '213';
11
- this.emetriqConfig = null;
5
+ export const prebidIdentifiers = (ctx) => {
6
+ const identifier = {};
7
+ const userIds = ctx.window__.pbjs.getUserIds();
8
+ if (userIds.amxId) {
9
+ identifier.id_amxid = userIds.amxId;
12
10
  }
13
- config__() {
14
- return this.emetriqConfig;
11
+ if (userIds.idl_env) {
12
+ identifier.id_liveramp = userIds.idl_env;
15
13
  }
16
- configure__(moduleConfig) {
17
- if (moduleConfig?.emetriq && moduleConfig.emetriq.enabled) {
18
- this.emetriqConfig = moduleConfig.emetriq;
14
+ if (userIds.IDP) {
15
+ identifier.id_zeotap = userIds.IDP;
16
+ }
17
+ if (userIds.pubcid) {
18
+ identifier.id_sharedid = userIds.pubcid;
19
+ }
20
+ if (userIds.id5id) {
21
+ identifier.id_id5 = userIds.id5id.uid;
22
+ }
23
+ return identifier;
24
+ };
25
+ export const syncDelay = (ctx, delay) => {
26
+ if (delay) {
27
+ if (typeof delay === 'number') {
28
+ return new Promise(resolve => ctx.window__.setTimeout(() => resolve({}), delay));
29
+ }
30
+ else {
31
+ if (ctx.window__.pbjs) {
32
+ return new Promise(resolve => {
33
+ ctx.window__.pbjs.que.push(() => {
34
+ const listener = () => {
35
+ resolve(prebidIdentifiers(ctx));
36
+ ctx.window__.pbjs.offEvent('auctionEnd', listener);
37
+ };
38
+ ctx.window__.pbjs.onEvent('auctionEnd', listener);
39
+ });
40
+ });
41
+ }
42
+ else {
43
+ ctx.logger__.error('emetriq', 'No sync delay, because window.pbjs is not defined!');
44
+ return Promise.resolve({});
45
+ }
19
46
  }
20
47
  }
21
- initSteps__() {
22
- const config = this.emetriqConfig;
48
+ return Promise.resolve({});
49
+ };
50
+ export const staticCustomParams = (targeting, mappings) => {
51
+ let additionalCustomParams = {};
52
+ (mappings ?? []).forEach(({ param, key }) => {
53
+ const value = targeting[key];
54
+ if (value) {
55
+ additionalCustomParams[param] = typeof value === 'string' ? value : value.join(',');
56
+ }
57
+ });
58
+ return additionalCustomParams;
59
+ };
60
+ export const Emetriq = { syncDelay, staticCustomParams, prebidIdentifiers };
61
+ export const createEmetriq = () => {
62
+ const name = 'emetriq';
63
+ const gvlid = '213';
64
+ let emetriqConfig = null;
65
+ const config__ = () => emetriqConfig;
66
+ const configure__ = (moduleConfig) => {
67
+ if (moduleConfig?.emetriq && moduleConfig.emetriq.enabled) {
68
+ emetriqConfig = moduleConfig.emetriq;
69
+ }
70
+ };
71
+ const checkIfConsentIsMissing = (ctx) => {
72
+ if (ctx.tcData__.gdprApplies && !ctx.tcData__.vendor.consents[gvlid]) {
73
+ ctx.logger__.warn(name, 'missing consent');
74
+ return true;
75
+ }
76
+ return false;
77
+ };
78
+ const loadEmetriqScript = (context, webConfig, additionalIdentifier, additionalCustomParams) => {
79
+ const window = context.window__;
80
+ window._enqAdpParam = {
81
+ ...webConfig._enqAdpParam,
82
+ ...additionalIdentifier,
83
+ ...additionalCustomParams
84
+ };
85
+ return context.assetLoaderService__
86
+ .loadScript({
87
+ name,
88
+ loadMethod: AssetLoadMethod.TAG,
89
+ assetUrl: `https://ups.xplosion.de/loader/${webConfig._enqAdpParam.sid}/default.js`
90
+ })
91
+ .catch(error => context.logger__.error('failed to load emetriq', error));
92
+ };
93
+ const initSteps__ = () => {
94
+ const config = emetriqConfig;
23
95
  return config
24
96
  ? [
25
97
  mkInitStep('load-emetriq', ctx => {
@@ -27,13 +99,13 @@ export class Emetriq {
27
99
  if (ctx.env__ === 'test') {
28
100
  return Promise.resolve();
29
101
  }
30
- if (this.checkIfConsentIsMissing(ctx)) {
102
+ if (checkIfConsentIsMissing(ctx)) {
31
103
  return Promise.resolve();
32
104
  }
33
105
  Emetriq.syncDelay(ctx, config.syncDelay).then(additionalIdentifier => {
34
106
  switch (config.os) {
35
107
  case 'web':
36
- this.loadEmetriqScript(ctx, config, additionalIdentifier, customParams);
108
+ loadEmetriqScript(ctx, config, additionalIdentifier, customParams);
37
109
  break;
38
110
  }
39
111
  });
@@ -41,9 +113,9 @@ export class Emetriq {
41
113
  })
42
114
  ]
43
115
  : [];
44
- }
45
- configureSteps__() {
46
- const config = this.emetriqConfig;
116
+ };
117
+ const configureSteps__ = () => {
118
+ const config = emetriqConfig;
47
119
  return config
48
120
  ? [
49
121
  mkConfigureStepOncePerRequestAdsCycle('track-emetriq', ctx => {
@@ -51,7 +123,7 @@ export class Emetriq {
51
123
  if (ctx.env__ === 'test') {
52
124
  return Promise.resolve();
53
125
  }
54
- if (this.checkIfConsentIsMissing(ctx)) {
126
+ if (checkIfConsentIsMissing(ctx)) {
55
127
  return Promise.resolve();
56
128
  }
57
129
  if (config.login &&
@@ -70,85 +142,18 @@ export class Emetriq {
70
142
  })
71
143
  ]
72
144
  : [];
73
- }
74
- prepareRequestAdsSteps__() {
75
- return [];
76
- }
77
- checkIfConsentIsMissing(ctx) {
78
- if (ctx.tcData__.gdprApplies && !ctx.tcData__.vendor.consents[this.gvlid]) {
79
- ctx.logger__.warn(this.name, 'missing consent');
80
- return true;
81
- }
82
- return false;
83
- }
84
- loadEmetriqScript(context, webConfig, additionalIdentifier, additionalCustomParams) {
85
- const window = context.window__;
86
- window._enqAdpParam = {
87
- ...webConfig._enqAdpParam,
88
- ...additionalIdentifier,
89
- ...additionalCustomParams
90
- };
91
- return context.assetLoaderService__
92
- .loadScript({
93
- name: this.name,
94
- loadMethod: AssetLoadMethod.TAG,
95
- assetUrl: `https://ups.xplosion.de/loader/${webConfig._enqAdpParam.sid}/default.js`
96
- })
97
- .catch(error => context.logger__.error('failed to load emetriq', error));
98
- }
99
- static syncDelay(ctx, delay) {
100
- if (delay) {
101
- if (typeof delay === 'number') {
102
- return new Promise(resolve => ctx.window__.setTimeout(() => resolve({}), delay));
103
- }
104
- else {
105
- if (ctx.window__.pbjs) {
106
- return new Promise(resolve => {
107
- ctx.window__.pbjs.que.push(() => {
108
- const listener = () => {
109
- resolve(Emetriq.prebidIdentifiers(ctx));
110
- ctx.window__.pbjs.offEvent('auctionEnd', listener);
111
- };
112
- ctx.window__.pbjs.onEvent('auctionEnd', listener);
113
- });
114
- });
115
- }
116
- else {
117
- ctx.logger__.error('emetriq', 'No sync delay, because window.pbjs is not defined!');
118
- return Promise.resolve({});
119
- }
120
- }
121
- }
122
- return Promise.resolve({});
123
- }
124
- static staticCustomParams(targeting, mappings) {
125
- let additionalCustomParams = {};
126
- (mappings ?? []).forEach(({ param, key }) => {
127
- const value = targeting[key];
128
- if (value) {
129
- additionalCustomParams[param] = typeof value === 'string' ? value : value.join(',');
130
- }
131
- });
132
- return additionalCustomParams;
133
- }
134
- static prebidIdentifiers(ctx) {
135
- const identifier = {};
136
- const userIds = ctx.window__.pbjs.getUserIds();
137
- if (userIds.amxId) {
138
- identifier.id_amxid = userIds.amxId;
139
- }
140
- if (userIds.idl_env) {
141
- identifier.id_liveramp = userIds.idl_env;
142
- }
143
- if (userIds.IDP) {
144
- identifier.id_zeotap = userIds.IDP;
145
- }
146
- if (userIds.pubcid) {
147
- identifier.id_sharedid = userIds.pubcid;
148
- }
149
- if (userIds.id5id) {
150
- identifier.id_id5 = userIds.id5id.uid;
151
- }
152
- return identifier;
153
- }
154
- }
145
+ };
146
+ const prepareRequestAdsSteps__ = () => [];
147
+ return {
148
+ name,
149
+ description: 'Provides Emetriq data collection functionality to Moli.',
150
+ moduleType: 'dmp',
151
+ config__,
152
+ configure__,
153
+ initSteps__,
154
+ configureSteps__,
155
+ prepareRequestAdsSteps__,
156
+ checkIfConsentIsMissing,
157
+ loadEmetriqScript
158
+ };
159
+ };