@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
@@ -0,0 +1,161 @@
1
+ import { mkInitStep } from 'ad-tag/ads/adPipeline';
2
+ import { uuidV4 } from 'ad-tag/util/uuid';
3
+ import { createSession } from 'ad-tag/ads/modules/moli-analytics/session';
4
+ import { createEventTracker } from 'ad-tag/ads/modules/moli-analytics/eventTracker';
5
+ import { eventMapper } from 'ad-tag/ads/modules/moli-analytics/events';
6
+ import { extractPubstackAbTestCohort } from '../pubstack/abTest';
7
+ const SESSION_TTL_MIN = 30;
8
+ export const DEFAULT_CONFIG = {
9
+ batchSize: 4,
10
+ batchDelay: 1000
11
+ };
12
+ export const MoliAnalytics = () => {
13
+ let config;
14
+ let eventContext;
15
+ let eventTracker;
16
+ let adUnitsMap = new Map();
17
+ const generatePageViewId = (adPipelineContext) => `pv-${uuidV4(adPipelineContext.window__)}`;
18
+ const handleAuctionEnd = (event, adPipelineContext) => {
19
+ const auctionEnd = eventMapper.prebid.auctionEnd(event, eventContext, adPipelineContext);
20
+ for (const adUnit of auctionEnd.data.adUnits) {
21
+ adUnitsMap.set(adUnit.code, {
22
+ auctionId: auctionEnd.data.auctionId,
23
+ adUnitName: adUnit.adUnitName,
24
+ gpid: adUnit.gpid
25
+ });
26
+ }
27
+ eventTracker.track(auctionEnd);
28
+ };
29
+ const handleBidWon = (event, adPipelineContext) => {
30
+ const adUnitData = adUnitsMap.get(event.adUnitCode);
31
+ eventTracker.track(eventMapper.prebid.bidWon(event, {
32
+ ...eventContext,
33
+ gpid: adUnitData?.gpid || ''
34
+ }, adPipelineContext));
35
+ };
36
+ const handleSlotRenderEnded = (event, adPipelineContext) => {
37
+ const adUnitCode = event.slot.getSlotElementId();
38
+ const adUnitData = adUnitsMap.get(adUnitCode);
39
+ eventTracker.track(eventMapper.gpt.slotRenderEnded(event, {
40
+ ...eventContext,
41
+ auctionId: adUnitData?.auctionId || '',
42
+ adUnitName: adUnitData?.adUnitName || adUnitCode,
43
+ gpid: adUnitData?.gpid || ''
44
+ }, adPipelineContext));
45
+ };
46
+ const handlePageView = (adPipelineContext) => {
47
+ eventContext.pageViewId = generatePageViewId(adPipelineContext);
48
+ eventTracker.track(eventMapper.page.view(eventContext, adPipelineContext));
49
+ };
50
+ const configValid = (config, logger) => {
51
+ if (!config) {
52
+ logger.error('moli-analytics: not configured');
53
+ return false;
54
+ }
55
+ if (!config.publisher) {
56
+ logger.error('moli-analytics: publisher is required');
57
+ return false;
58
+ }
59
+ if (!config.url) {
60
+ logger.error('moli-analytics: url is required');
61
+ return false;
62
+ }
63
+ if (!config.batchSize || config.batchSize < 1) {
64
+ logger.error('moli-analytics: batchSize must be greater than 0');
65
+ return false;
66
+ }
67
+ if (!config.batchDelay || config.batchDelay < 1) {
68
+ logger.error('moli-analytics: batchDelay must be greater than 0');
69
+ return false;
70
+ }
71
+ return true;
72
+ };
73
+ const initMoliAnalytics = async (adPipelineContext) => {
74
+ if (!configValid(config, adPipelineContext.logger__)) {
75
+ return Promise.reject('failed to initialize moli analytics: invalid configuration');
76
+ }
77
+ eventContext = {
78
+ publisher: config.publisher,
79
+ session: createSession(adPipelineContext.window__, SESSION_TTL_MIN),
80
+ pageViewId: generatePageViewId(adPipelineContext),
81
+ analyticsLabels: null
82
+ };
83
+ eventTracker = createEventTracker(config.url, config.batchSize, config.batchDelay, adPipelineContext.logger__);
84
+ if (adPipelineContext.config__.configVersion?.identifier ||
85
+ adPipelineContext.config__.configVersion?.versionVariant) {
86
+ eventContext.analyticsLabels = {
87
+ ab_test: adPipelineContext.config__.configVersion?.identifier || null,
88
+ variant: adPipelineContext.config__.configVersion?.versionVariant || null
89
+ };
90
+ }
91
+ if (adPipelineContext.config__.spa?.enabled) {
92
+ adPipelineContext.window__.moli.addEventListener('afterRequestAds', event => {
93
+ if (event.state === 'spa-finished' || event.state === 'finished') {
94
+ handlePageView(adPipelineContext);
95
+ }
96
+ });
97
+ }
98
+ const setupPrebid = async () => {
99
+ if (typeof adPipelineContext.window__.pbjs.getUserIdsAsync === 'function') {
100
+ await adPipelineContext.window__.pbjs.getUserIdsAsync();
101
+ }
102
+ handlePageView(adPipelineContext);
103
+ adPipelineContext.window__.pbjs.onEvent('auctionEnd', (event) => handleAuctionEnd(event, adPipelineContext));
104
+ adPipelineContext.window__.pbjs.onEvent('bidWon', (event) => handleBidWon(event, adPipelineContext));
105
+ };
106
+ if (typeof adPipelineContext.window__.pbjs.onEvent === 'function') {
107
+ await setupPrebid();
108
+ }
109
+ else {
110
+ adPipelineContext.window__.pbjs.que.push(setupPrebid);
111
+ }
112
+ const setupGPT = () => {
113
+ adPipelineContext.window__.googletag
114
+ .pubads()
115
+ .addEventListener('slotRenderEnded', (event) => handleSlotRenderEnded(event, adPipelineContext));
116
+ };
117
+ if (typeof adPipelineContext.window__.googletag.pubads === 'function') {
118
+ setupGPT();
119
+ }
120
+ else {
121
+ adPipelineContext.window__.googletag.cmd.push(setupGPT);
122
+ }
123
+ return Promise.resolve();
124
+ };
125
+ const setAnalyticsLabels = (ctx) => {
126
+ const pubstackAbTestCohort = extractPubstackAbTestCohort(ctx);
127
+ const moliConfigVariant = ctx.config__.configVersion?.versionVariant;
128
+ ctx.window__.pbjs.que.push(() => ctx.window__.pbjs.mergeConfig({
129
+ analyticsLabels: {
130
+ pubstackAbCohort: pubstackAbTestCohort,
131
+ configVariant: moliConfigVariant
132
+ }
133
+ }));
134
+ return Promise.resolve();
135
+ };
136
+ return {
137
+ name: 'moli-analytics',
138
+ description: 'ad events tracking and analytics module',
139
+ moduleType: 'reporting',
140
+ config__() {
141
+ return config;
142
+ },
143
+ configure__(moduleConfig) {
144
+ if (moduleConfig?.moliAnalytics?.enabled) {
145
+ config = { ...DEFAULT_CONFIG, ...moduleConfig.moliAnalytics };
146
+ }
147
+ },
148
+ configureSteps__() {
149
+ return [];
150
+ },
151
+ initSteps__() {
152
+ return [
153
+ mkInitStep('moli-analytics-init', (context) => initMoliAnalytics(context)),
154
+ mkInitStep('set-analytics-labels', (context) => setAnalyticsLabels(context))
155
+ ];
156
+ },
157
+ prepareRequestAdsSteps__() {
158
+ return [];
159
+ }
160
+ };
161
+ };
@@ -0,0 +1,60 @@
1
+ import { UserActivityService } from 'ad-tag/ads/modules/ad-reload/userActivityService';
2
+ import { BrowserStorageKeys } from 'ad-tag/util/browserStorageKeys';
3
+ import { uuidV4 } from 'ad-tag/util/uuid';
4
+ export const createSession = (window, ttl) => {
5
+ const userActivityService = new UserActivityService(window, {
6
+ level: 'strict'
7
+ });
8
+ const ttlMs = ttl * 60000;
9
+ const loadJSON = (k, d = null) => {
10
+ try {
11
+ return JSON.parse(window.localStorage.getItem(k) || '') ?? d;
12
+ }
13
+ catch {
14
+ return d;
15
+ }
16
+ };
17
+ const saveJSON = (k, v) => window.localStorage.setItem(k, JSON.stringify(v));
18
+ const getSession = () => {
19
+ const now = Date.now();
20
+ let session = loadJSON(BrowserStorageKeys.molyAnalyticsSession);
21
+ if (!session || !session.id || !session.createdAt || !session.lastActivityAt) {
22
+ session = createSession();
23
+ }
24
+ else {
25
+ const idleMs = now - session.lastActivityAt;
26
+ const isIdle = idleMs > ttlMs;
27
+ if (isIdle) {
28
+ session = createSession();
29
+ }
30
+ }
31
+ return session;
32
+ };
33
+ const createSession = () => {
34
+ const now = Date.now();
35
+ const session = {
36
+ id: `sess-${uuidV4(window)}`,
37
+ createdAt: now,
38
+ lastActivityAt: now
39
+ };
40
+ saveJSON(BrowserStorageKeys.molyAnalyticsSession, session);
41
+ return session;
42
+ };
43
+ const touchSession = () => {
44
+ const session = getSession();
45
+ session.lastActivityAt = Date.now();
46
+ saveJSON(BrowserStorageKeys.molyAnalyticsSession, session);
47
+ };
48
+ const getId = () => {
49
+ return getSession().id;
50
+ };
51
+ userActivityService.addUserActivityChangedListener((isActive) => {
52
+ if (isActive) {
53
+ touchSession();
54
+ }
55
+ });
56
+ getSession();
57
+ return {
58
+ getId
59
+ };
60
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -2,35 +2,21 @@ import { mkConfigureStep } from 'ad-tag/ads/adPipeline';
2
2
  import { uniquePrimitiveFilter } from 'ad-tag/util/arrayUtils';
3
3
  import { mergeDeep } from 'ad-tag/util/objectUtils';
4
4
  import { extractTopPrivateDomainFromHostname } from 'ad-tag/util/extractTopPrivateDomainFromHostname';
5
- export class PrebidFirstPartyDataModule {
6
- constructor() {
7
- this.description = 'Module for passing first party data to prebid auctions';
8
- this.moduleType = 'prebid';
9
- this.name = 'prebid-first-party-data';
10
- this.moduleConfig = null;
11
- this._configureSteps = [];
12
- }
13
- config__() {
14
- return this.moduleConfig;
15
- }
16
- configure__(moduleConfig) {
17
- if (moduleConfig?.prebidFirstPartyData?.enabled) {
18
- const config = moduleConfig.prebidFirstPartyData;
19
- this._configureSteps = [
20
- mkConfigureStep('prebid-fpd-module-configure', context => PrebidFirstPartyDataModule.setPrebidFpdConfig(context, config, context.logger__))
21
- ];
5
+ export const createPrebidFirstPartyDataModule = () => {
6
+ const name = 'prebid-first-party-data';
7
+ let moduleConfig = null;
8
+ let configureStepsArr = [];
9
+ const config__ = () => moduleConfig;
10
+ const extractKeyValueArray = (key, keyValues) => {
11
+ const value = keyValues[key];
12
+ if (value) {
13
+ return typeof value === 'string' ? [value] : value;
14
+ }
15
+ else {
16
+ return [];
22
17
  }
23
- }
24
- initSteps__() {
25
- return [];
26
- }
27
- configureSteps__() {
28
- return this._configureSteps;
29
- }
30
- prepareRequestAdsSteps__() {
31
- return [];
32
- }
33
- static setPrebidFpdConfig(context, config, log) {
18
+ };
19
+ const setPrebidFpdConfig = (context, config, log) => {
34
20
  if (context.config__.prebid) {
35
21
  const keyValues = context.config__.targeting?.keyValues || {};
36
22
  const gptTargeting = config.gptTargetingMappings;
@@ -45,16 +31,16 @@ export class PrebidFirstPartyDataModule {
45
31
  ...ortb2FromKeyValues.site
46
32
  };
47
33
  if (gptTargeting.cat) {
48
- const keyValueData = PrebidFirstPartyDataModule.extractKeyValueArray(gptTargeting.cat, keyValues);
34
+ const keyValueData = extractKeyValueArray(gptTargeting.cat, keyValues);
49
35
  site.cat?.push(...keyValueData);
50
36
  site.pagecat?.push(...keyValueData);
51
37
  site.sectioncat?.push(...keyValueData);
52
38
  }
53
39
  if (gptTargeting.sectionCat) {
54
- site.sectioncat = PrebidFirstPartyDataModule.extractKeyValueArray(gptTargeting.sectionCat, keyValues);
40
+ site.sectioncat = extractKeyValueArray(gptTargeting.sectionCat, keyValues);
55
41
  }
56
42
  if (gptTargeting.pageCat) {
57
- site.pagecat = PrebidFirstPartyDataModule.extractKeyValueArray(gptTargeting.pageCat, keyValues);
43
+ site.pagecat = extractKeyValueArray(gptTargeting.pageCat, keyValues);
58
44
  }
59
45
  if (site.cat) {
60
46
  site.cat = site.cat.filter(uniquePrimitiveFilter);
@@ -75,7 +61,7 @@ export class PrebidFirstPartyDataModule {
75
61
  data: site.content?.data?.filter(data => data.name !== provider) ?? []
76
62
  };
77
63
  if (gptTargeting.iabV2 && provider) {
78
- const iabV2Ids = PrebidFirstPartyDataModule.extractKeyValueArray(gptTargeting.iabV2, keyValues);
64
+ const iabV2Ids = extractKeyValueArray(gptTargeting.iabV2, keyValues);
79
65
  const publisherContentData = {
80
66
  name: provider,
81
67
  ext: {
@@ -86,7 +72,7 @@ export class PrebidFirstPartyDataModule {
86
72
  site.content.data?.push(publisherContentData);
87
73
  }
88
74
  if (gptTargeting.iabV3 && provider) {
89
- const iabV3Ids = PrebidFirstPartyDataModule.extractKeyValueArray(gptTargeting.iabV3, keyValues);
75
+ const iabV3Ids = extractKeyValueArray(gptTargeting.iabV3, keyValues);
90
76
  const publisherContentData = {
91
77
  name: provider,
92
78
  ext: {
@@ -102,14 +88,26 @@ export class PrebidFirstPartyDataModule {
102
88
  });
103
89
  }
104
90
  return Promise.resolve();
105
- }
106
- static extractKeyValueArray(key, keyValues) {
107
- const value = keyValues[key];
108
- if (value) {
109
- return typeof value === 'string' ? [value] : value;
110
- }
111
- else {
112
- return [];
91
+ };
92
+ const configure__ = (mConfig) => {
93
+ if (mConfig?.prebidFirstPartyData?.enabled) {
94
+ const config = mConfig.prebidFirstPartyData;
95
+ configureStepsArr = [
96
+ mkConfigureStep('prebid-fpd-module-configure', context => setPrebidFpdConfig(context, config, context.logger__))
97
+ ];
113
98
  }
114
- }
115
- }
99
+ };
100
+ const initSteps__ = () => [];
101
+ const configureSteps__ = () => configureStepsArr;
102
+ const prepareRequestAdsSteps__ = () => [];
103
+ return {
104
+ name,
105
+ description: 'Module for passing first party data to prebid auctions',
106
+ moduleType: 'prebid',
107
+ config__,
108
+ configure__,
109
+ initSteps__,
110
+ configureSteps__,
111
+ prepareRequestAdsSteps__
112
+ };
113
+ };
@@ -0,0 +1,11 @@
1
+ export const extractPubstackAbTestCohort = (ctx) => {
2
+ const pubstackABTestValues = ['0', '1', '2', '3'];
3
+ if (ctx.env__ === 'test') {
4
+ return null;
5
+ }
6
+ const meta = ctx.window__.document.head.querySelector('meta[name="pbstck_context:pbstck_ab_test"]');
7
+ if (meta && meta.content && pubstackABTestValues.includes(meta.content)) {
8
+ return meta.content;
9
+ }
10
+ return null;
11
+ };
@@ -1,22 +1,17 @@
1
1
  import { AssetLoadMethod } from 'ad-tag/util/assetLoaderService';
2
2
  import { mkConfigureStep, mkInitStep } from '../../adPipeline';
3
- export class Pubstack {
4
- constructor() {
5
- this.name = 'pubstack';
6
- this.description = 'prebid analytics integration';
7
- this.moduleType = 'reporting';
8
- this.pubstackConfig = null;
9
- }
10
- config__() {
11
- return this.pubstackConfig;
12
- }
13
- configure__(moduleConfig) {
3
+ import { extractPubstackAbTestCohort } from './abTest';
4
+ export const createPubstack = () => {
5
+ const name = 'pubstack';
6
+ let pubstackConfig = null;
7
+ const config__ = () => pubstackConfig;
8
+ const configure__ = (moduleConfig) => {
14
9
  if (moduleConfig?.pubstack && moduleConfig.pubstack.enabled) {
15
- this.pubstackConfig = moduleConfig.pubstack;
10
+ pubstackConfig = moduleConfig.pubstack;
16
11
  }
17
- }
18
- initSteps__() {
19
- const config = this.pubstackConfig;
12
+ };
13
+ const initSteps__ = () => {
14
+ const config = pubstackConfig;
20
15
  return config
21
16
  ? [
22
17
  mkInitStep('pubstack-init', ctx => {
@@ -25,7 +20,7 @@ export class Pubstack {
25
20
  }
26
21
  ctx.assetLoaderService__
27
22
  .loadScript({
28
- name: 'pubstack',
23
+ name,
29
24
  loadMethod: AssetLoadMethod.TAG,
30
25
  assetUrl: `https://boot.pbstck.com/v1/tag/${config.tagId}`
31
26
  })
@@ -34,26 +29,33 @@ export class Pubstack {
34
29
  })
35
30
  ]
36
31
  : [];
37
- }
38
- configureSteps__() {
39
- const config = this.pubstackConfig;
32
+ };
33
+ const configureSteps__ = () => {
34
+ const config = pubstackConfig;
40
35
  return config
41
36
  ? [
42
37
  mkConfigureStep('pubstack-configure', ctx => {
43
38
  if (ctx.env__ === 'test') {
44
39
  return Promise.resolve();
45
40
  }
46
- const validABTestValues = ['0', '1', '2', '3'];
47
- const meta = ctx.window__.document.head.querySelector('meta[name="pbstck_context:pbstck_ab_test"]');
48
- if (meta && meta.content && validABTestValues.includes(meta.content)) {
49
- ctx.window__.googletag.pubads().setTargeting('pbstck_ab_test', meta.content);
41
+ const pubstackAbTestCohort = extractPubstackAbTestCohort(ctx);
42
+ if (pubstackAbTestCohort) {
43
+ ctx.window__.googletag.pubads().setTargeting('pbstck_ab_test', pubstackAbTestCohort);
50
44
  }
51
45
  return Promise.resolve();
52
46
  })
53
47
  ]
54
48
  : [];
55
- }
56
- prepareRequestAdsSteps__() {
57
- return [];
58
- }
59
- }
49
+ };
50
+ const prepareRequestAdsSteps__ = () => [];
51
+ return {
52
+ name,
53
+ description: 'prebid analytics integration',
54
+ moduleType: 'reporting',
55
+ config__,
56
+ configure__,
57
+ initSteps__,
58
+ configureSteps__,
59
+ prepareRequestAdsSteps__
60
+ };
61
+ };
@@ -1,28 +1,22 @@
1
1
  import { LOW_PRIORITY, mkPrepareRequestAdsStep } from 'ad-tag/ads/adPipeline';
2
2
  import { setupFooterAdListener } from './desktopFloorAd';
3
3
  import { initMobileAdSticky } from './mobileSticky';
4
- export class StickyFooterAd {
5
- constructor() {
6
- this.name = 'sticky-footer-ads';
7
- this.description = 'sticky footer ad creatives';
8
- this.moduleType = 'creatives';
9
- this.stickyFooterAdConfig = null;
10
- }
11
- config__() {
12
- return this.stickyFooterAdConfig;
13
- }
14
- configure__(moduleConfig) {
4
+ export const createStickyFooterAd = () => {
5
+ const name = 'sticky-footer-ads';
6
+ let stickyFooterAdConfig = null;
7
+ const config__ = () => stickyFooterAdConfig;
8
+ const configure__ = (moduleConfig) => {
15
9
  if (moduleConfig?.stickyFooterAd?.enabled) {
16
- this.stickyFooterAdConfig = moduleConfig.stickyFooterAd;
10
+ stickyFooterAdConfig = moduleConfig.stickyFooterAd;
17
11
  }
18
- }
19
- prepareRequestAdsSteps__() {
20
- const config = this.stickyFooterAdConfig;
12
+ };
13
+ const prepareRequestAdsSteps__ = () => {
14
+ const config = stickyFooterAdConfig;
21
15
  return config
22
16
  ? [
23
- mkPrepareRequestAdsStep(this.name, LOW_PRIORITY, (ctx, slots) => {
17
+ mkPrepareRequestAdsStep(name, LOW_PRIORITY, (ctx, slots) => {
24
18
  if (config.mobileStickyDomId &&
25
- slots.some(slot => slot.moliSlot.domId === this.stickyFooterAdConfig?.mobileStickyDomId)) {
19
+ slots.some(slot => slot.moliSlot.domId === config.mobileStickyDomId)) {
26
20
  initMobileAdSticky(ctx.window__, ctx.env__, ctx.logger__, config.mobileStickyDomId, config.disallowedAdvertiserIds, config.initiallyHidden ?? false);
27
21
  }
28
22
  if (config.desktopFloorAdDomId &&
@@ -33,11 +27,17 @@ export class StickyFooterAd {
33
27
  })
34
28
  ]
35
29
  : [];
36
- }
37
- configureSteps__() {
38
- return [];
39
- }
40
- initSteps__() {
41
- return [];
42
- }
43
- }
30
+ };
31
+ const configureSteps__ = () => [];
32
+ const initSteps__ = () => [];
33
+ return {
34
+ name,
35
+ description: 'sticky footer ad creatives',
36
+ moduleType: 'creatives',
37
+ config__,
38
+ configure__,
39
+ prepareRequestAdsSteps__,
40
+ configureSteps__,
41
+ initSteps__
42
+ };
43
+ };
@@ -1,30 +1,24 @@
1
1
  import { LOW_PRIORITY, mkPrepareRequestAdsStep } from 'ad-tag/ads/adPipeline';
2
2
  import { initAdSticky } from './footerStickyAd';
3
- export class StickyFooterAdsV2 {
4
- constructor() {
5
- this.name = 'sticky-footer-ads-v2';
6
- this.description = 'sticky footer ad creatives';
7
- this.moduleType = 'creatives';
8
- this.stickyFooterAdConfig = null;
9
- }
10
- config__() {
11
- return this.stickyFooterAdConfig;
12
- }
13
- configure__(moduleConfig) {
3
+ export const createStickyFooterAdsV2 = () => {
4
+ const name = 'sticky-footer-ads-v2';
5
+ let stickyFooterAdConfig = null;
6
+ const config__ = () => stickyFooterAdConfig;
7
+ const configure__ = (moduleConfig) => {
14
8
  if (moduleConfig?.stickyFooterAdV2 && moduleConfig.stickyFooterAdV2.enabled) {
15
- this.stickyFooterAdConfig = moduleConfig.stickyFooterAdV2;
9
+ stickyFooterAdConfig = moduleConfig.stickyFooterAdV2;
16
10
  }
17
- }
18
- prepareRequestAdsSteps__() {
19
- const config = this.stickyFooterAdConfig;
11
+ };
12
+ const prepareRequestAdsSteps__ = () => {
13
+ const config = stickyFooterAdConfig;
20
14
  return config
21
15
  ? [
22
- mkPrepareRequestAdsStep(this.name, LOW_PRIORITY, (ctx, slots) => {
16
+ mkPrepareRequestAdsStep(name, LOW_PRIORITY, (ctx, slots) => {
23
17
  const desktopSlot = slots.find(slot => slot.moliSlot.domId === config.stickyFooterDomIds.desktop);
24
18
  const mobileSlot = slots.find(slot => slot.moliSlot.domId === config.stickyFooterDomIds.mobile);
25
19
  const footerAdSlot = mobileSlot ? mobileSlot : desktopSlot;
26
20
  if (mobileSlot && desktopSlot) {
27
- ctx.logger__.warn(this.name, 'mobile and desktop sticky footer are called!');
21
+ ctx.logger__.warn(name, 'mobile and desktop sticky footer are called!');
28
22
  }
29
23
  if (footerAdSlot) {
30
24
  initAdSticky(ctx.window__, ctx.env__, ctx.logger__, footerAdSlot.moliSlot.domId, config.disallowedAdvertiserIds, config.closingButtonText);
@@ -33,11 +27,17 @@ export class StickyFooterAdsV2 {
33
27
  })
34
28
  ]
35
29
  : [];
36
- }
37
- configureSteps__() {
38
- return [];
39
- }
40
- initSteps__() {
41
- return [];
42
- }
43
- }
30
+ };
31
+ const configureSteps__ = () => [];
32
+ const initSteps__ = () => [];
33
+ return {
34
+ name,
35
+ description: 'sticky footer ad creatives',
36
+ moduleType: 'creatives',
37
+ config__,
38
+ configure__,
39
+ prepareRequestAdsSteps__,
40
+ configureSteps__,
41
+ initSteps__
42
+ };
43
+ };