@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.
- package/lib/ads/labelConfigService.js +14 -1
- package/lib/ads/modules/ad-reload/index.js +146 -142
- package/lib/ads/modules/adex/index.js +106 -104
- package/lib/ads/modules/cleanup/index.js +64 -61
- package/lib/ads/modules/confiant/index.js +29 -29
- package/lib/ads/modules/emetriq/index.js +107 -102
- package/lib/ads/modules/generic-skin/index.js +128 -127
- package/lib/ads/modules/identitylink/index.js +37 -36
- package/lib/ads/modules/moli-analytics/eventTracker.js +43 -0
- package/lib/ads/modules/moli-analytics/events/gptSlotRenderEnded.js +21 -0
- package/lib/ads/modules/moli-analytics/events/index.js +16 -0
- package/lib/ads/modules/moli-analytics/events/pageView.js +31 -0
- package/lib/ads/modules/moli-analytics/events/prebidAuctionEnd.js +39 -0
- package/lib/ads/modules/moli-analytics/events/prebidBidWon.js +23 -0
- package/lib/ads/modules/moli-analytics/index.js +161 -0
- package/lib/ads/modules/moli-analytics/session.js +60 -0
- package/lib/ads/modules/moli-analytics/types.js +1 -0
- package/lib/ads/modules/prebid-first-party-data/index.js +41 -43
- package/lib/ads/modules/pubstack/abTest.js +11 -0
- package/lib/ads/modules/pubstack/index.js +30 -28
- package/lib/ads/modules/sticky-footer-ad/index.js +25 -25
- package/lib/ads/modules/sticky-footer-ad-v2/index.js +25 -25
- package/lib/ads/modules/sticky-header-ad/index.js +44 -42
- package/lib/ads/modules/zeotap/index.js +93 -93
- package/lib/ads/moli.js +35 -22
- package/lib/bundle/adReload.js +2 -2
- package/lib/bundle/adex.js +2 -2
- package/lib/bundle/cleanup.js +2 -2
- package/lib/bundle/confiant.js +2 -2
- package/lib/bundle/emetriq.js +2 -2
- package/lib/bundle/identityLink.js +2 -2
- package/lib/bundle/moliAnalytics.js +2 -0
- package/lib/bundle/prebidFirstPartyData.js +2 -2
- package/lib/bundle/pubstack.js +2 -2
- package/lib/bundle/skin.js +2 -2
- package/lib/bundle/stickyFooterAd.js +2 -2
- package/lib/bundle/stickyFooterAds2.js +2 -2
- package/lib/bundle/stickyHeaderAd.js +2 -2
- package/lib/bundle/zeotap.js +2 -2
- package/lib/gen/packageJson.js +1 -1
- package/lib/types/prebidjs.js +1 -0
- package/lib/util/browserStorageKeys.js +1 -0
- 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
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
40
|
+
site.sectioncat = extractKeyValueArray(gptTargeting.sectionCat, keyValues);
|
|
55
41
|
}
|
|
56
42
|
if (gptTargeting.pageCat) {
|
|
57
|
-
site.pagecat =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
10
|
+
pubstackConfig = moduleConfig.pubstack;
|
|
16
11
|
}
|
|
17
|
-
}
|
|
18
|
-
initSteps__() {
|
|
19
|
-
const config =
|
|
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
|
|
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 =
|
|
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
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
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
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
10
|
+
stickyFooterAdConfig = moduleConfig.stickyFooterAd;
|
|
17
11
|
}
|
|
18
|
-
}
|
|
19
|
-
prepareRequestAdsSteps__() {
|
|
20
|
-
const config =
|
|
12
|
+
};
|
|
13
|
+
const prepareRequestAdsSteps__ = () => {
|
|
14
|
+
const config = stickyFooterAdConfig;
|
|
21
15
|
return config
|
|
22
16
|
? [
|
|
23
|
-
mkPrepareRequestAdsStep(
|
|
17
|
+
mkPrepareRequestAdsStep(name, LOW_PRIORITY, (ctx, slots) => {
|
|
24
18
|
if (config.mobileStickyDomId &&
|
|
25
|
-
slots.some(slot => slot.moliSlot.domId ===
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
9
|
+
stickyFooterAdConfig = moduleConfig.stickyFooterAdV2;
|
|
16
10
|
}
|
|
17
|
-
}
|
|
18
|
-
prepareRequestAdsSteps__() {
|
|
19
|
-
const config =
|
|
11
|
+
};
|
|
12
|
+
const prepareRequestAdsSteps__ = () => {
|
|
13
|
+
const config = stickyFooterAdConfig;
|
|
20
14
|
return config
|
|
21
15
|
? [
|
|
22
|
-
mkPrepareRequestAdsStep(
|
|
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(
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
+
};
|