@highfivve/ad-tag 5.5.4

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 (132) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +149 -0
  3. package/lib/ads/a9.js +190 -0
  4. package/lib/ads/adPipeline.js +159 -0
  5. package/lib/ads/adService.js +251 -0
  6. package/lib/ads/adUnitPath.js +37 -0
  7. package/lib/ads/auctions/adRequestThrottling.js +22 -0
  8. package/lib/ads/auctions/biddersDisabling.js +90 -0
  9. package/lib/ads/auctions/frequencyCapping.js +189 -0
  10. package/lib/ads/auctions/interstitialContext.js +92 -0
  11. package/lib/ads/auctions/previousBidCpms.js +33 -0
  12. package/lib/ads/auctions/resume.js +3 -0
  13. package/lib/ads/bridge/bridge.js +62 -0
  14. package/lib/ads/consent.js +63 -0
  15. package/lib/ads/eventService.js +44 -0
  16. package/lib/ads/globalAuctionContext.js +98 -0
  17. package/lib/ads/googleAdManager.js +380 -0
  18. package/lib/ads/keyValues.js +1 -0
  19. package/lib/ads/labelConfigService.js +42 -0
  20. package/lib/ads/modules/ad-reload/adVisibilityService.js +158 -0
  21. package/lib/ads/modules/ad-reload/index.js +163 -0
  22. package/lib/ads/modules/ad-reload/userActivityService.js +70 -0
  23. package/lib/ads/modules/adex/adex-mapping.js +77 -0
  24. package/lib/ads/modules/adex/adexUtiq.js +15 -0
  25. package/lib/ads/modules/adex/index.js +142 -0
  26. package/lib/ads/modules/adex/sendAdvertisingId.js +20 -0
  27. package/lib/ads/modules/blocklist-url/index.js +118 -0
  28. package/lib/ads/modules/cleanup/index.js +93 -0
  29. package/lib/ads/modules/confiant/index.js +47 -0
  30. package/lib/ads/modules/emetriq/index.js +154 -0
  31. package/lib/ads/modules/emetriq/trackInApp.js +34 -0
  32. package/lib/ads/modules/emetriq/trackLoginEvent.js +59 -0
  33. package/lib/ads/modules/generic-skin/index.js +150 -0
  34. package/lib/ads/modules/identitylink/index.js +58 -0
  35. package/lib/ads/modules/interstitial/index.js +38 -0
  36. package/lib/ads/modules/interstitial/interstitialAd.js +111 -0
  37. package/lib/ads/modules/lazy-load/index.js +191 -0
  38. package/lib/ads/modules/lazy-load/selectInfiniteSlot.js +11 -0
  39. package/lib/ads/modules/prebid-first-party-data/index.js +115 -0
  40. package/lib/ads/modules/pubstack/index.js +59 -0
  41. package/lib/ads/modules/sticky-footer-ad/desktopFloorAd.js +63 -0
  42. package/lib/ads/modules/sticky-footer-ad/index.js +43 -0
  43. package/lib/ads/modules/sticky-footer-ad/mobileSticky.js +93 -0
  44. package/lib/ads/modules/sticky-footer-ad-v2/footerStickyAd.js +118 -0
  45. package/lib/ads/modules/sticky-footer-ad-v2/index.js +43 -0
  46. package/lib/ads/modules/sticky-header-ad/fadeOutCallback.js +25 -0
  47. package/lib/ads/modules/sticky-header-ad/index.js +103 -0
  48. package/lib/ads/modules/sticky-header-ad/renderResult.js +24 -0
  49. package/lib/ads/modules/utiq/index.js +79 -0
  50. package/lib/ads/modules/yield-optimization/dynamicFloorPrice.js +86 -0
  51. package/lib/ads/modules/yield-optimization/index.js +57 -0
  52. package/lib/ads/modules/yield-optimization/isYieldOptimizationConfigDynamic.js +6 -0
  53. package/lib/ads/modules/yield-optimization/yieldOptimizationService.js +169 -0
  54. package/lib/ads/modules/zeotap/index.js +111 -0
  55. package/lib/ads/moli.js +645 -0
  56. package/lib/ads/moliGlobal.js +11 -0
  57. package/lib/ads/prebid-outstream.js +13 -0
  58. package/lib/ads/prebid.js +406 -0
  59. package/lib/ads/sizeConfigService.js +49 -0
  60. package/lib/ads/spa.js +32 -0
  61. package/lib/bundle/adReload.js +2 -0
  62. package/lib/bundle/adex.js +2 -0
  63. package/lib/bundle/blocklistUrls.js +2 -0
  64. package/lib/bundle/cleanup.js +2 -0
  65. package/lib/bundle/confiant.js +2 -0
  66. package/lib/bundle/configureFromEndpoint.js +40 -0
  67. package/lib/bundle/emetriq.js +2 -0
  68. package/lib/bundle/identityLink.js +2 -0
  69. package/lib/bundle/init.js +2 -0
  70. package/lib/bundle/interstitialModule.js +2 -0
  71. package/lib/bundle/lazyLoad.js +2 -0
  72. package/lib/bundle/prebidFirstPartyData.js +2 -0
  73. package/lib/bundle/pubstack.js +2 -0
  74. package/lib/bundle/skin.js +2 -0
  75. package/lib/bundle/stickyFooterAd.js +2 -0
  76. package/lib/bundle/stickyFooterAds2.js +2 -0
  77. package/lib/bundle/stickyHeaderAd.js +2 -0
  78. package/lib/bundle/utiq.js +2 -0
  79. package/lib/bundle/yieldOptimization.js +2 -0
  80. package/lib/bundle/zeotap.js +2 -0
  81. package/lib/console/components/adSlotConfig.js +225 -0
  82. package/lib/console/components/consentConfig.js +138 -0
  83. package/lib/console/components/globalConfig.js +634 -0
  84. package/lib/console/components/labelConfigDebug.js +19 -0
  85. package/lib/console/components/sizeConfigDebug.js +34 -0
  86. package/lib/console/components/tag.js +4 -0
  87. package/lib/console/debug.js +38 -0
  88. package/lib/console/util/array.js +1 -0
  89. package/lib/console/util/calculateAdDensity.js +36 -0
  90. package/lib/console/util/debounce.js +12 -0
  91. package/lib/console/util/debugLogger.js +6 -0
  92. package/lib/console/util/extractPositionFromPath.js +8 -0
  93. package/lib/console/util/prebid.js +3 -0
  94. package/lib/console/util/stringUtils.js +23 -0
  95. package/lib/console/util/themingService.js +31 -0
  96. package/lib/console/util/windowResizeService.js +22 -0
  97. package/lib/console/validations/adReloadValidations.js +47 -0
  98. package/lib/console/validations/bucketValidations.js +78 -0
  99. package/lib/console/validations/sizesConfigValidations.js +97 -0
  100. package/lib/gen/packageJson.js +3 -0
  101. package/lib/index.js +3 -0
  102. package/lib/types/apstag.js +1 -0
  103. package/lib/types/dom.js +1 -0
  104. package/lib/types/emetriq.js +1 -0
  105. package/lib/types/googletag.js +1 -0
  106. package/lib/types/identitylink.js +1 -0
  107. package/lib/types/module.js +1 -0
  108. package/lib/types/moliConfig.js +1 -0
  109. package/lib/types/moliRuntime.js +1 -0
  110. package/lib/types/prebidjs.js +45 -0
  111. package/lib/types/supplyChainObject.js +1 -0
  112. package/lib/types/tcfapi.js +48 -0
  113. package/lib/util/addNewInfiniteSlotToConfig.js +11 -0
  114. package/lib/util/arrayUtils.js +9 -0
  115. package/lib/util/assetLoaderService.js +91 -0
  116. package/lib/util/browserStorageKeys.js +7 -0
  117. package/lib/util/debugDelay.js +12 -0
  118. package/lib/util/domready.js +15 -0
  119. package/lib/util/environmentOverride.js +16 -0
  120. package/lib/util/extractAdTagVersion.js +16 -0
  121. package/lib/util/extractTopPrivateDomainFromHostname.js +17 -0
  122. package/lib/util/localStorage.js +26 -0
  123. package/lib/util/logging.js +106 -0
  124. package/lib/util/objectUtils.js +29 -0
  125. package/lib/util/query.js +40 -0
  126. package/lib/util/queryParameters.js +5 -0
  127. package/lib/util/resolveOverrides.js +21 -0
  128. package/lib/util/resolveStoredRequestIdInOrtb2Object.js +12 -0
  129. package/lib/util/sizes.js +3 -0
  130. package/lib/util/test-slots.js +150 -0
  131. package/lib/util/uuid.js +10 -0
  132. package/package.json +127 -0
@@ -0,0 +1,406 @@
1
+ import { LOW_PRIORITY, mkConfigureStep, mkConfigureStepOncePerRequestAdsCycle, mkInitStep, mkPrepareRequestAdsStep, mkRequestBidsStep } from './adPipeline';
2
+ import { SizeConfigService } from './sizeConfigService';
3
+ import { resolveAdUnitPath } from './adUnitPath';
4
+ import { isNotNull, uniquePrimitiveFilter } from '../util/arrayUtils';
5
+ import { resolveStoredRequestIdInOrtb2Object } from '../util/resolveStoredRequestIdInOrtb2Object';
6
+ import { createTestSlots } from '../util/test-slots';
7
+ import { AssetLoadMethod } from '../util/assetLoaderService';
8
+ import { packageJson } from 'ad-tag/gen/packageJson';
9
+ import { prebidOutstreamRenderer } from 'ad-tag/ads/prebid-outstream';
10
+ import { isGamInterstitial } from 'ad-tag/ads/auctions/interstitialContext';
11
+ const prebidTimeout = (context) => {
12
+ return new Promise((_, reject) => {
13
+ context.window__.setTimeout(() => reject('Prebid did not resolve in time. Maybe you forgot to import the prebid distribution in the ad tag'), 5000);
14
+ });
15
+ };
16
+ const prebidReady = (window) => new Promise(resolve => window.pbjs.que.push(resolve));
17
+ const isPrebidSlotDefinition = (slotDefinition) => {
18
+ return !!slotDefinition.moliSlot.prebid;
19
+ };
20
+ const isAdUnitDefined = (adUnit, window) => {
21
+ if (window.pbjs.adUnits) {
22
+ return window.pbjs.adUnits.some(adUnit2 => adUnit.code === adUnit2.code);
23
+ }
24
+ return false;
25
+ };
26
+ const createdAdUnits = (context, prebidConfig, slots) => {
27
+ const prebidAdUnits = slots
28
+ .filter(isPrebidSlotDefinition)
29
+ .map(({ moliSlot, priceRule, filterSupportedSizes }) => {
30
+ const floors = priceRule
31
+ ? {
32
+ floors: {
33
+ currency: prebidConfig.config.currency?.adServerCurrency ?? 'EUR',
34
+ schema: {
35
+ delimiter: '|',
36
+ fields: ['mediaType']
37
+ },
38
+ values: {
39
+ '*': priceRule.floorprice
40
+ }
41
+ }
42
+ }
43
+ : null;
44
+ context.logger__.debug('Prebid', context.requestId__, 'Price Rule', priceRule, moliSlot.domId, floors);
45
+ return extractPrebidAdSlotConfigs(moliSlot.prebid)
46
+ .map(prebidAdSlotConfig => {
47
+ const mediaTypeBanner = prebidAdSlotConfig.adUnit.mediaTypes.banner;
48
+ const mediaTypeVideo = prebidAdSlotConfig.adUnit.mediaTypes.video;
49
+ const mediaTypeNative = prebidAdSlotConfig.adUnit.mediaTypes.native;
50
+ const bannerSizes = mediaTypeBanner
51
+ ? filterSupportedSizes(mediaTypeBanner.sizes).filter(SizeConfigService.isFixedSize)
52
+ : [];
53
+ const videoSizes = mediaTypeVideo
54
+ ? filterVideoPlayerSizes(mediaTypeVideo.playerSize, filterSupportedSizes)
55
+ : [];
56
+ const bids = prebidAdSlotConfig.adUnit.bids
57
+ .filter((bid) => context.labelConfigService__.filterSlot(bid))
58
+ .filter((bid) => !bid.bidder ||
59
+ (bid.bidder &&
60
+ !context.auction__.isBidderDisabled(moliSlot.domId, bid.bidder) &&
61
+ !context.auction__.isBidderFrequencyCappedOnSlot(moliSlot.domId, bid.bidder)))
62
+ .map(bid => {
63
+ const { labelAny: _, labelAll: __, ...bidCopy } = bid;
64
+ return bidCopy;
65
+ });
66
+ const videoDimensionsWH = videoSizes.length > 0 && !mediaTypeVideo?.w && !mediaTypeVideo?.h
67
+ ? {
68
+ w: videoSizes[0][0],
69
+ h: videoSizes[0][1]
70
+ }
71
+ : {};
72
+ const backupVideoRenderer = prebidConfig.backupVideoRenderer;
73
+ const video = mediaTypeVideo
74
+ ? {
75
+ video: {
76
+ ...mediaTypeVideo,
77
+ playerSize: videoSizes.length === 0 ? undefined : videoSizes,
78
+ ...videoDimensionsWH,
79
+ ...(backupVideoRenderer
80
+ ? { renderer: prebidOutstreamRenderer(moliSlot.domId, backupVideoRenderer.url) }
81
+ : {})
82
+ }
83
+ }
84
+ : undefined;
85
+ const banner = mediaTypeBanner && bannerSizes.length > 0
86
+ ? {
87
+ banner: { ...mediaTypeBanner, sizes: bannerSizes }
88
+ }
89
+ : undefined;
90
+ const native = mediaTypeNative
91
+ ? {
92
+ native: { ...mediaTypeNative }
93
+ }
94
+ : undefined;
95
+ const pubstack = {
96
+ ...prebidAdSlotConfig.adUnit.pubstack,
97
+ adUnitPath: resolveAdUnitPath(prebidAdSlotConfig.adUnit.pubstack?.adUnitPath || moliSlot.adUnitPath, context.adUnitPathVariables__)
98
+ };
99
+ const storedRequest = prebidAdSlotConfig.adUnit.ortb2Imp?.ext?.prebid?.storedrequest;
100
+ const storedRequestWithSolvedId = storedRequest && storedRequest.id
101
+ ? {
102
+ ...storedRequest,
103
+ id: resolveAdUnitPath(storedRequest.id, context.adUnitPathVariables__)
104
+ }
105
+ : null;
106
+ return {
107
+ ...prebidAdSlotConfig.adUnit,
108
+ ...(storedRequest &&
109
+ storedRequestWithSolvedId && {
110
+ ortb2Imp: resolveStoredRequestIdInOrtb2Object(prebidAdSlotConfig.adUnit.ortb2Imp, storedRequestWithSolvedId)
111
+ }),
112
+ code: prebidAdSlotConfig.adUnit.code || moliSlot.domId,
113
+ ...(prebidAdSlotConfig.adUnit.pubstack ? { pubstack } : {}),
114
+ mediaTypes: {
115
+ ...video,
116
+ ...banner,
117
+ ...native
118
+ },
119
+ bids: bids,
120
+ ...floors
121
+ };
122
+ })
123
+ .filter(adUnit => adUnit.bids.length > 0 &&
124
+ adUnit.mediaTypes &&
125
+ (adUnit.mediaTypes.banner || adUnit.mediaTypes.video || adUnit.mediaTypes.native) &&
126
+ !isAdUnitDefined(adUnit, context.window__));
127
+ });
128
+ return prebidAdUnits.reduce((acc, adUnits) => [...acc, ...adUnits], []);
129
+ };
130
+ export const prebidInit = (assetService) => mkInitStep('prebid-init', context => {
131
+ context.window__.pbjs = context.window__.pbjs || { que: [] };
132
+ const analyticAdapters = context.config__.prebid?.analyticAdapters;
133
+ if (analyticAdapters && analyticAdapters.length > 0) {
134
+ context.window__.pbjs.que.push(() => {
135
+ context.window__.pbjs.enableAnalytics(analyticAdapters);
136
+ });
137
+ }
138
+ if (context.window__.pbjs.libLoaded) {
139
+ return Promise.resolve();
140
+ }
141
+ else if (context.config__.prebid?.distributionUrl) {
142
+ assetService.loadScript({
143
+ name: 'prebid',
144
+ assetUrl: context.config__.prebid.distributionUrl,
145
+ loadMethod: AssetLoadMethod.TAG
146
+ });
147
+ return Promise.resolve();
148
+ }
149
+ else {
150
+ return Promise.race([prebidReady(context.window__), prebidTimeout(context)]);
151
+ }
152
+ });
153
+ export const prebidRemoveAdUnits = (prebidConfig) => mkConfigureStep('prebid-remove-adunits', (context) => new Promise(resolve => {
154
+ if (prebidConfig.ephemeralAdUnits !== true) {
155
+ context.window__.pbjs = context.window__.pbjs || { que: [] };
156
+ const adUnits = context.window__.pbjs.adUnits;
157
+ if (adUnits) {
158
+ context.window__.pbjs.que.push(() => {
159
+ context.logger__.debug('Prebid', `Destroying prebid adUnits`, adUnits);
160
+ adUnits.forEach(adUnit => context.window__.pbjs.removeAdUnit(adUnit.code));
161
+ });
162
+ }
163
+ }
164
+ resolve();
165
+ }));
166
+ export const prebidClearAuction = () => {
167
+ return mkConfigureStepOncePerRequestAdsCycle('prebid-clear-auction', (context) => new Promise(resolve => {
168
+ context.window__.pbjs = context.window__.pbjs || { que: [] };
169
+ context.window__.pbjs.que.push(() => {
170
+ context.logger__.debug('Prebid', 'Clearing prebid auctions');
171
+ context.window__.pbjs.clearAllAuctions();
172
+ });
173
+ resolve();
174
+ }));
175
+ };
176
+ export const prebidConfigure = (prebidConfig, schainConfig) => {
177
+ let result;
178
+ const mkSupplyChainConfig = (nodes) => ({
179
+ validation: 'relaxed',
180
+ config: {
181
+ ver: '1.0',
182
+ complete: 1,
183
+ nodes
184
+ }
185
+ });
186
+ return mkConfigureStep('prebid-configure', (context, _slots) => {
187
+ if (!result) {
188
+ result = new Promise(resolve => {
189
+ if (prebidConfig.bidderSettings) {
190
+ context.window__.pbjs.bidderSettings = prebidConfig.bidderSettings;
191
+ }
192
+ context.window__.pbjs.que.push(() => {
193
+ const s2sConfig = prebidConfig.config.s2sConfig;
194
+ if (s2sConfig) {
195
+ const s2sConfigs = Array.isArray(prebidConfig.config.s2sConfig)
196
+ ? prebidConfig.config.s2sConfig
197
+ : [prebidConfig.config.s2sConfig];
198
+ s2sConfigs.forEach(s2sConfigEntry => {
199
+ const h5v = s2sConfigEntry.extPrebid?.analytics?.h5v;
200
+ if (h5v) {
201
+ h5v.configLabel = context.window__.moli.configLabel;
202
+ h5v.moliVersion = packageJson.version;
203
+ }
204
+ });
205
+ }
206
+ context.window__.pbjs.setConfig({
207
+ ...prebidConfig.config,
208
+ ...{ schain: mkSupplyChainConfig([schainConfig.supplyChainStartNode]) },
209
+ ...{ floors: prebidConfig.config.floors || {} }
210
+ });
211
+ prebidConfig.bidderConfigs?.forEach(({ options, merge }) => {
212
+ context.window__.pbjs.setBidderConfig(options, merge);
213
+ });
214
+ prebidConfig.schain.nodes.forEach(({ bidder, node, appendNode }) => {
215
+ const nodes = [schainConfig.supplyChainStartNode];
216
+ if (appendNode) {
217
+ nodes.push(node);
218
+ }
219
+ context.window__.pbjs.setBidderConfig({ bidders: [bidder], config: { schain: mkSupplyChainConfig(nodes) } }, true);
220
+ });
221
+ if (context.window__.pbjs.registerSignalSources) {
222
+ context.window__.pbjs.registerSignalSources();
223
+ }
224
+ });
225
+ resolve();
226
+ });
227
+ }
228
+ return result;
229
+ });
230
+ };
231
+ const extractPrebidAdSlotConfigs = (provider) => {
232
+ return Array.isArray(provider) ? provider : [provider];
233
+ };
234
+ export const prebidPrepareRequestAds = (prebidConfig) => mkPrepareRequestAdsStep('prebid-prepare-adunits', LOW_PRIORITY, (context, slots) => new Promise(resolve => {
235
+ if (prebidConfig.ephemeralAdUnits) {
236
+ resolve();
237
+ }
238
+ else {
239
+ context.window__.pbjs.que.push(() => {
240
+ const adUnits = createdAdUnits(context, prebidConfig, slots);
241
+ adUnits.forEach(adUnit => {
242
+ context.logger__.debug('Prebid', context.requestId__, `Prebid add ad unit: [Code] ${adUnit.code}`, adUnit);
243
+ });
244
+ context.window__.pbjs.addAdUnits(adUnits);
245
+ });
246
+ resolve();
247
+ }
248
+ }));
249
+ export const prebidRequestBids = (prebidConfig, adServer) => mkRequestBidsStep('prebid-request-bids', (context, slots) => {
250
+ const failsafeTimeout = Math.max((prebidConfig.config.bidderTimeout ?? 2000) + 3000, prebidConfig.failsafeTimeout ?? 0);
251
+ const failsafe = new Promise(resolve => context.window__.setTimeout(resolve, failsafeTimeout));
252
+ const auction = new Promise(resolve => {
253
+ const slotsToRefresh = slots.filter(slot => !context.auction__.isSlotThrottled(slot.adSlot) &&
254
+ (!isGamInterstitial(slot.adSlot, context.window__) ||
255
+ context.auction__.interstitialChannel() !== 'gam'));
256
+ const requestObject = prebidConfig.ephemeralAdUnits
257
+ ? {
258
+ adUnits: createdAdUnits(context, prebidConfig, slotsToRefresh)
259
+ }
260
+ : {
261
+ adUnitCodes: slotsToRefresh
262
+ .filter(isPrebidSlotDefinition)
263
+ .map(slot => slot.moliSlot.domId)
264
+ };
265
+ const adUnitCodes = requestObject.adUnitCodes ||
266
+ requestObject.adUnits
267
+ ?.map(adUnit => adUnit.code)
268
+ .filter(isNotNull)
269
+ .filter(uniquePrimitiveFilter) ||
270
+ [];
271
+ if (adUnitCodes.length === 0) {
272
+ context.logger__.debug('Prebid', 'skip request bids. All slots were filtered.', slotsToRefresh.map(s => s.moliSlot));
273
+ return resolve();
274
+ }
275
+ let adserverRequestSent = false;
276
+ context.logger__.debug('Prebid', `Prebid request bids: \n\t\t\t${adUnitCodes.join('\n\t\t\t')}`);
277
+ const bidsBackHandler = (bidResponses, timedOut, auctionId) => {
278
+ context.logger__.info('Prebid', auctionId, bidResponses, slots.map(s => s.moliSlot.domId));
279
+ try {
280
+ if (adserverRequestSent) {
281
+ context.logger__.warn('Prebid', `ad server request already sent [${context.requestId__}]. AuctionId ${auctionId}`);
282
+ return;
283
+ }
284
+ if (!bidResponses) {
285
+ context.logger__.warn('Prebid', `Undefined bid response map for ad unit codes: ${adUnitCodes.join(', ')}`);
286
+ return resolve();
287
+ }
288
+ adserverRequestSent = true;
289
+ if (adServer === 'gam') {
290
+ context.runtimeConfig__.adPipelineConfig.prebidBidsBackHandler.forEach(handler => handler(context, bidResponses, slots));
291
+ context.window__.pbjs.setTargetingForGPTAsync(adUnitCodes);
292
+ }
293
+ resolve();
294
+ }
295
+ catch (error) {
296
+ context.logger__.error('Prebid', 'DfpService:: could not resolve bidsBackHandler' + JSON.stringify(error));
297
+ resolve();
298
+ }
299
+ };
300
+ context.window__.pbjs.que.push(() => {
301
+ context.window__.pbjs.requestBids({
302
+ ...requestObject,
303
+ auctionId: context.auctionId__,
304
+ timeout: context.bucket__?.timeout,
305
+ bidsBackHandler: bidsBackHandler
306
+ });
307
+ });
308
+ });
309
+ return Promise.race([failsafe, auction]);
310
+ });
311
+ export const prebidDefineSlots = () => (context, slots) => {
312
+ const slotDefinitions = slots.map(moliSlot => {
313
+ const sizeConfigService = new SizeConfigService(moliSlot.sizeConfig, context.labelConfigService__.getSupportedLabels(), context.window__);
314
+ const filterSupportedSizes = sizeConfigService.filterSupportedSizes;
315
+ if (!(sizeConfigService.filterSlot(moliSlot) &&
316
+ context.labelConfigService__.filterSlot(moliSlot))) {
317
+ return Promise.resolve(null);
318
+ }
319
+ const adSlot = {
320
+ getAdUnitPath: () => moliSlot.adUnitPath
321
+ };
322
+ switch (context.env__) {
323
+ case 'production':
324
+ return Promise.resolve({
325
+ moliSlot,
326
+ adSlot,
327
+ filterSupportedSizes
328
+ });
329
+ case 'test':
330
+ return Promise.resolve({
331
+ moliSlot,
332
+ adSlot,
333
+ filterSupportedSizes
334
+ });
335
+ default:
336
+ return Promise.reject(`invalid environment: ${context.runtimeConfig__.environment}`);
337
+ }
338
+ });
339
+ return Promise.all(slotDefinitions).then(slots => slots.filter(isNotNull));
340
+ };
341
+ export const prebidRenderAds = () => (context, slots) => {
342
+ return new Promise((resolve, reject) => {
343
+ context.logger__.debug('Prebid', 'start rendering');
344
+ try {
345
+ switch (context.env__) {
346
+ case 'test':
347
+ context.logger__.debug('Prebid', 'Rendering test slots');
348
+ createTestSlots(context, slots);
349
+ break;
350
+ case 'production':
351
+ context.window__.pbjs
352
+ .getHighestCpmBids()
353
+ .filter(bid => bid && bid.adId)
354
+ .forEach(winningBid => {
355
+ const adSlotDiv = context.window__.document.getElementById(winningBid.adUnitCode);
356
+ if (adSlotDiv) {
357
+ const innerDiv = document.createElement('div');
358
+ innerDiv.style.setProperty('border', '0pt none');
359
+ const iframe = document.createElement('iframe');
360
+ iframe.scrolling = 'no';
361
+ iframe.frameBorder = '0';
362
+ iframe.marginHeight = '0';
363
+ iframe.marginHeight = '0';
364
+ iframe.name = `prebid_ads_iframe_${winningBid.adUnitCode}`;
365
+ iframe.title = '3rd party ad content';
366
+ iframe.sandbox.add('allow-forms', 'allow-popups', 'allow-popups-to-escape-sandbox', 'allow-same-origin', 'allow-scripts', 'allow-top-navigation-by-user-activation');
367
+ iframe.setAttribute('aria-label', 'Advertisment');
368
+ iframe.style.setProperty('border', '0');
369
+ iframe.style.setProperty('margin', '0');
370
+ iframe.style.setProperty('overflow', 'hidden');
371
+ innerDiv.appendChild(iframe);
372
+ adSlotDiv.appendChild(innerDiv);
373
+ const iframeDoc = iframe.contentWindow?.document;
374
+ if (iframeDoc) {
375
+ context.window__.pbjs.renderAd(iframeDoc, winningBid.adId);
376
+ const normalizeCss = `/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */button,hr,input{overflow:visible}progress,sub,sup{vertical-align:baseline}[type=checkbox],[type=radio],legend{box-sizing:border-box;padding:0}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}details,main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{padding:.35em .75em .625em}legend{color:inherit;display:table;max-width:100%;white-space:normal}textarea{overflow:auto}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none}`;
377
+ const iframeStyle = iframeDoc.createElement('style');
378
+ iframeStyle.appendChild(iframeDoc.createTextNode(normalizeCss));
379
+ iframeDoc.head.appendChild(iframeStyle);
380
+ }
381
+ else {
382
+ context.logger__.error('Prebid', `No access to iframe contentWindow for ad unit${winningBid.adUnitCode}`);
383
+ }
384
+ }
385
+ else {
386
+ context.logger__.error('Prebid', `Could not locate ad slot with id ${winningBid.adUnitCode}`);
387
+ }
388
+ });
389
+ break;
390
+ }
391
+ resolve();
392
+ }
393
+ catch (e) {
394
+ reject(e);
395
+ }
396
+ });
397
+ };
398
+ const filterVideoPlayerSizes = (playerSize, filterSupportedSizes) => {
399
+ const isSinglePlayerSize = (size) => {
400
+ return (!!size && size.length === 2 && typeof size[0] === 'number' && typeof size[1] === 'number');
401
+ };
402
+ if (!playerSize) {
403
+ return [];
404
+ }
405
+ return filterSupportedSizes(isSinglePlayerSize(playerSize) ? [playerSize] : playerSize).filter(SizeConfigService.isFixedSize);
406
+ };
@@ -0,0 +1,49 @@
1
+ import { flatten, uniquePrimitiveFilter } from '../util/arrayUtils';
2
+ import { isSizeEqual } from '../util/sizes';
3
+ export class SizeConfigService {
4
+ static isFixedSize(size) {
5
+ return size !== 'fluid';
6
+ }
7
+ constructor(sizeConfig, supportedLabels, window) {
8
+ this.sizeConfig = sizeConfig;
9
+ this.supportedLabels = supportedLabels;
10
+ this.window = window;
11
+ this.filterSupportedSizes = (givenSizes) => {
12
+ if (!this.isValid) {
13
+ return [];
14
+ }
15
+ return this.supportedSizes.length === 0
16
+ ? givenSizes
17
+ : givenSizes.filter(givenSize => this.supportedSizes.some(configuredSize => {
18
+ if (configuredSize === 'fluid') {
19
+ return givenSize === 'fluid';
20
+ }
21
+ else if (givenSize === 'fluid') {
22
+ return false;
23
+ }
24
+ else {
25
+ return isSizeEqual(givenSize, configuredSize);
26
+ }
27
+ }));
28
+ };
29
+ this.areLabelsMatching = (conf, supportedLabels) => {
30
+ return ((!conf.labelAll ||
31
+ conf.labelAll.every(label => supportedLabels.some(supportedLabel => supportedLabel === label))) &&
32
+ (!conf.labelNone ||
33
+ !conf.labelNone.some(label => supportedLabels.some(supportedLabel => supportedLabel === label))));
34
+ };
35
+ const supportedSizeConfigs = sizeConfig.length !== 0
36
+ ? sizeConfig.filter(conf => window.matchMedia(conf.mediaQuery).matches &&
37
+ this.areLabelsMatching(conf, supportedLabels))
38
+ : [];
39
+ this.isValid =
40
+ sizeConfig.length === 0 || !(sizeConfig.length > 0 && supportedSizeConfigs.length === 0);
41
+ this.supportedSizes = flatten(supportedSizeConfigs.map(conf => conf.sizesSupported))
42
+ .map(size => JSON.stringify(size))
43
+ .filter(uniquePrimitiveFilter)
44
+ .map(sizeAsString => JSON.parse(sizeAsString));
45
+ }
46
+ filterSlot(slot) {
47
+ return (!slot.sizes || slot.sizes.length === 0 || this.filterSupportedSizes(slot.sizes).length > 0);
48
+ }
49
+ }
package/lib/ads/spa.js ADDED
@@ -0,0 +1,32 @@
1
+ export const allowRefreshAdSlot = (validateLocation, stateHref, currentLocation) => {
2
+ switch (validateLocation) {
3
+ case 'none':
4
+ return true;
5
+ case 'href':
6
+ return currentLocation.href === stateHref;
7
+ case 'path':
8
+ try {
9
+ const url = new URL(stateHref);
10
+ return currentLocation.pathname === url.pathname;
11
+ }
12
+ catch (e) {
13
+ return true;
14
+ }
15
+ }
16
+ };
17
+ export const allowRequestAds = (validateLocation, stateHref, currentLocation) => {
18
+ switch (validateLocation) {
19
+ case 'none':
20
+ return true;
21
+ case 'href':
22
+ return currentLocation.href !== stateHref;
23
+ case 'path':
24
+ try {
25
+ const url = new URL(stateHref);
26
+ return currentLocation.pathname !== url.pathname;
27
+ }
28
+ catch (e) {
29
+ return true;
30
+ }
31
+ }
32
+ };
@@ -0,0 +1,2 @@
1
+ import { AdReload } from '../ads/modules/ad-reload';
2
+ window.moli.registerModule(new AdReload());
@@ -0,0 +1,2 @@
1
+ import { AdexModule } from '../ads/modules/adex';
2
+ window.moli.registerModule(new AdexModule());
@@ -0,0 +1,2 @@
1
+ import { createBlocklistedUrls } from '../ads/modules/blocklist-url';
2
+ window.moli.registerModule(createBlocklistedUrls());
@@ -0,0 +1,2 @@
1
+ import { Cleanup } from '../ads/modules/cleanup';
2
+ window.moli.registerModule(new Cleanup());
@@ -0,0 +1,2 @@
1
+ import { Confiant } from '../ads/modules/confiant';
2
+ window.moli.registerModule(new Confiant());
@@ -0,0 +1,40 @@
1
+ import { QueryParameters } from '../util/queryParameters';
2
+ import { resolveOverrides } from '../util/resolveOverrides';
3
+ import { BrowserStorageKeys } from '../util/browserStorageKeys';
4
+ const currentScript = window.document.currentScript ?? document.getElementById('moli-ad-tag');
5
+ const pubCodeOverride = resolveOverrides(window, QueryParameters.moliPubCode, BrowserStorageKeys.moliPubCode)[0]?.value;
6
+ const versionOverride = resolveOverrides(window, QueryParameters.moliVersion, BrowserStorageKeys.moliVersion)[0]?.value;
7
+ if (currentScript) {
8
+ const publisherCode = pubCodeOverride ?? currentScript.getAttribute('data-publisher-code');
9
+ const version = versionOverride ?? currentScript.getAttribute('data-version') ?? 'production';
10
+ const labels = (currentScript.getAttribute('data-labels') ?? '')
11
+ .split(',')
12
+ .map(l => l.trim())
13
+ .filter(l => l.length > 0);
14
+ if (labels.length > 0) {
15
+ window.moli.que.push(moli => {
16
+ moli.beforeRequestAds(() => labels.forEach(label => moli.addLabel(label)));
17
+ });
18
+ }
19
+ window.moli.configLabel = version;
20
+ const endpoint = currentScript.getAttribute('data-endpoint') ?? 'api.h5v.eu/publishers';
21
+ const fallback = currentScript.getAttribute('data-endpoint-fallback') ?? 'cdn.h5v.eu/publishers';
22
+ if (publisherCode) {
23
+ const path = `/${publisherCode}/configs/${version}/config.json`;
24
+ const url = `//${endpoint}${path}`;
25
+ fetch(url, { mode: 'cors' })
26
+ .then(response => response.json())
27
+ .catch(error => {
28
+ console.error(`Failed to load configuration from ${url}. Using fallback`, error);
29
+ return fetch(`//${fallback}${path}`, { mode: 'cors' });
30
+ })
31
+ .then(config => window.moli.configure(config))
32
+ .catch(error => console.error(`Failed to load configuration from ${url}:`, error));
33
+ }
34
+ else {
35
+ console.error('No publisher code provided for ad tag configuration! Add the `data-publisher-code="yourCode"` attribute to the script tag.');
36
+ }
37
+ }
38
+ else {
39
+ console.error('Failed to find the current script tag for the ad tag bundle!');
40
+ }
@@ -0,0 +1,2 @@
1
+ import { Emetriq } from 'ad-tag/ads/modules/emetriq';
2
+ window.moli.registerModule(new Emetriq());
@@ -0,0 +1,2 @@
1
+ import { IdentityLink } from 'ad-tag/ads/modules/identitylink';
2
+ window.moli.registerModule(new IdentityLink());
@@ -0,0 +1,2 @@
1
+ import { initAdTag } from '../ads/moliGlobal';
2
+ initAdTag(window);
@@ -0,0 +1,2 @@
1
+ import { createInterstitialModule } from 'ad-tag/ads/modules/interstitial';
2
+ window.moli.registerModule(createInterstitialModule());
@@ -0,0 +1,2 @@
1
+ import { createLazyLoad } from 'ad-tag/ads/modules/lazy-load';
2
+ window.moli.registerModule(createLazyLoad());
@@ -0,0 +1,2 @@
1
+ import { PrebidFirstPartyDataModule } from 'ad-tag/ads/modules/prebid-first-party-data';
2
+ window.moli.registerModule(new PrebidFirstPartyDataModule());
@@ -0,0 +1,2 @@
1
+ import { Pubstack } from '../ads/modules/pubstack';
2
+ window.moli.registerModule(new Pubstack());
@@ -0,0 +1,2 @@
1
+ import { Skin } from '../ads/modules/generic-skin';
2
+ window.moli.registerModule(new Skin());
@@ -0,0 +1,2 @@
1
+ import { StickyFooterAd } from 'ad-tag/ads/modules/sticky-footer-ad';
2
+ window.moli.registerModule(new StickyFooterAd());
@@ -0,0 +1,2 @@
1
+ import { StickyFooterAdsV2 } from 'ad-tag/ads/modules/sticky-footer-ad-v2';
2
+ window.moli.registerModule(new StickyFooterAdsV2());
@@ -0,0 +1,2 @@
1
+ import { StickyHeaderAd } from 'ad-tag/ads/modules/sticky-header-ad';
2
+ window.moli.registerModule(new StickyHeaderAd());
@@ -0,0 +1,2 @@
1
+ import { createUtiq } from 'ad-tag/ads/modules/utiq';
2
+ window.moli.registerModule(createUtiq());
@@ -0,0 +1,2 @@
1
+ import { YieldOptimization } from 'ad-tag/ads/modules/yield-optimization';
2
+ window.moli.registerModule(YieldOptimization());
@@ -0,0 +1,2 @@
1
+ import { Zeotap } from 'ad-tag/ads/modules/zeotap';
2
+ window.moli.registerModule(new Zeotap());