@highfivve/ad-tag 5.12.1 → 5.13.1

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.
@@ -6,6 +6,7 @@ import { generateAdUnitPathVariables } from './adUnitPath';
6
6
  import { createAssetLoaderService } from '../util/assetLoaderService';
7
7
  import { uuidV4 } from '../util/uuid';
8
8
  import { getMoliLabelsFromQueryParam, getMoliLabelsFromStorage } from '../util/debugLabels';
9
+ import { adVolumeToLabels } from '../util/adVolume';
9
10
  export const HIGH_PRIORITY = 100;
10
11
  export const LOW_PRIORITY = 10;
11
12
  export const mkInitStep = (name, fn) => {
@@ -86,6 +87,7 @@ export class AdPipeline {
86
87
  return this.tcData.then(consentData => {
87
88
  const extraLabels = [
88
89
  ...(config.targeting?.labels || []),
90
+ ...adVolumeToLabels(runtimeConfig.adVolume ?? config.targeting?.adVolume),
89
91
  ...runtimeConfig.labels,
90
92
  ...getMoliLabelsFromQueryParam(this.window),
91
93
  ...getMoliLabelsFromStorage(this.window)
@@ -5,6 +5,7 @@ import { AssetLoadMethod } from '../util/assetLoaderService';
5
5
  import { tcfapi } from '../types/tcfapi';
6
6
  import { createTestSlots } from '../util/test-slots';
7
7
  import { resolveAdUnitPath } from './adUnitPath';
8
+ import { findGoogletagSlot } from './findGoogletagSlot';
8
9
  import { formatKey, CUSTOM_INTERSTITIAL_FORMAT, CUSTOM_ANCHOR_BOTTOM_FORMAT, CUSTOM_ANCHOR_TOP_FORMAT } from './keyValues';
9
10
  const testAdSlot = (domId, adUnitPath) => ({
10
11
  setCollapseEmptyDiv() {
@@ -124,17 +125,23 @@ export const gptDestroyAdSlots = () => {
124
125
  }
125
126
  return Promise.resolve();
126
127
  case 'requested':
127
- const allGptSlots = context.window__.googletag.pubads().getSlots();
128
128
  const gptSlots = slots
129
- .map(slot => allGptSlots.find(s => s.getSlotElementId() === slot.domId))
129
+ .map(slot => findGoogletagSlot({
130
+ domId: slot.domId,
131
+ adUnitPath: resolveAdUnitPath(slot.adUnitPath, context.adUnitPathVariables__)
132
+ }, context.window__.googletag))
130
133
  .filter(isNotNull);
131
134
  return destroySelectedSlots(gptSlots);
132
135
  case 'excluded':
133
136
  if (isNextRequestAdsCall) {
137
+ const excludedAdUnitPaths = context.config__.slots
138
+ .filter(moliSlot => cleanup.slotIds.includes(moliSlot.domId))
139
+ .map(moliSlot => resolveAdUnitPath(moliSlot.adUnitPath, context.adUnitPathVariables__));
134
140
  const destroyableSlots = context.window__.googletag
135
141
  .pubads()
136
142
  .getSlots()
137
- .filter(slot => !cleanup.slotIds.includes(slot.getSlotElementId()));
143
+ .filter(slot => !cleanup.slotIds.includes(slot.getSlotElementId()) &&
144
+ !excludedAdUnitPaths.includes(slot.getAdUnitPath()));
138
145
  return destroySelectedSlots(destroyableSlots);
139
146
  }
140
147
  return Promise.resolve();
package/lib/ads/moli.js CHANGED
@@ -24,58 +24,13 @@ export const createMoliTag = (window) => {
24
24
  modules: []
25
25
  };
26
26
  function setTargeting(key, value) {
27
- switch (state.state) {
28
- case 'configurable':
29
- case 'configured': {
30
- state.runtimeConfig.keyValues[key] = value;
31
- break;
32
- }
33
- case 'spa-finished':
34
- case 'spa-requestAds': {
35
- state.nextRuntimeConfig.keyValues[key] = value;
36
- break;
37
- }
38
- default: {
39
- getLogger(state.runtimeConfig, window).error('MoliGlobal', `Setting key-value after configuration: ${key} : ${value}`);
40
- break;
41
- }
42
- }
27
+ setConfig({ targeting: { [key]: value } });
43
28
  }
44
29
  function addLabel(label) {
45
- switch (state.state) {
46
- case 'configurable':
47
- case 'configured': {
48
- state.runtimeConfig.labels.push(label);
49
- break;
50
- }
51
- case 'spa-requestAds':
52
- case 'spa-finished': {
53
- state.nextRuntimeConfig.labels.push(label);
54
- break;
55
- }
56
- default: {
57
- getLogger(state.runtimeConfig, window).error('MoliGlobal', `Adding label after configure: ${label}`);
58
- break;
59
- }
60
- }
30
+ setConfig({ labels: [label] });
61
31
  }
62
32
  function setAdUnitPathVariables(variables) {
63
- switch (state.state) {
64
- case 'configurable':
65
- case 'configured': {
66
- state.runtimeConfig.adUnitPathVariables = variables;
67
- break;
68
- }
69
- case 'spa-requestAds':
70
- case 'spa-finished': {
71
- state.nextRuntimeConfig.adUnitPathVariables = variables;
72
- break;
73
- }
74
- default: {
75
- getLogger(state.runtimeConfig, window).error('MoliGlobal', `Setting unit path variables after configuration: ${variables}`);
76
- break;
77
- }
78
- }
33
+ setConfig({ adUnitPathVariables: variables });
79
34
  }
80
35
  function getAdUnitPathVariables() {
81
36
  const domain = extractTopPrivateDomainFromHostname(window.location.hostname) || 'unknown';
@@ -640,37 +595,73 @@ export const createMoliTag = (window) => {
640
595
  function setABtestTargeting() {
641
596
  const abTestValues = getAbTestValues(window, QueryParameters.abTest, BrowserStorageKeys.abTest);
642
597
  const abTestValue = abTestValues.length > 0 ? Number(abTestValues[0].value) : Math.floor(Math.random() * 100) + 1;
643
- setTargeting(QueryParameters.abTest, abTestValue.toString());
598
+ setConfig({ targeting: { [QueryParameters.abTest]: abTestValue.toString() } });
644
599
  }
645
600
  function addDomainLabel(domainFromConfig) {
646
601
  const domain = domainFromConfig || extractTopPrivateDomainFromHostname(window.location.hostname);
647
602
  if (domain) {
648
- addLabel(domain);
603
+ setConfig({ labels: [domain] });
649
604
  }
650
605
  }
651
606
  function addGeoLabels(geoFromConfig) {
652
607
  const { country, continent } = geoFromConfig ?? detectGeoFromBrowser();
653
- if (country) {
654
- addLabel(country);
655
- }
656
- if (continent) {
657
- addLabel(continent);
608
+ const labels = [country, continent].filter((label) => !!label);
609
+ if (labels.length > 0) {
610
+ setConfig({ labels });
658
611
  }
659
612
  }
660
613
  function setAudience(audience) {
614
+ setConfig({ audience: audience });
615
+ }
616
+ function validateConfigOverrides(partial) {
617
+ const validated = {
618
+ labels: partial.labels,
619
+ targeting: partial.targeting,
620
+ audience: partial.audience,
621
+ adUnitPathVariables: partial.adUnitPathVariables
622
+ };
623
+ if (partial.adVolume !== undefined) {
624
+ if (Number.isInteger(partial.adVolume) && partial.adVolume >= 1 && partial.adVolume <= 10) {
625
+ validated.adVolume = partial.adVolume;
626
+ }
627
+ else {
628
+ getLogger(state.runtimeConfig, window).warn('MoliGlobal', `Ignoring invalid adVolume in setConfig(): ${partial.adVolume}. Must be an integer between 1 and 10.`);
629
+ }
630
+ }
631
+ return validated;
632
+ }
633
+ function applyConfigOverrides(target, validated) {
634
+ if (validated.adVolume !== undefined) {
635
+ target.adVolume = validated.adVolume;
636
+ }
637
+ if (validated.labels !== undefined) {
638
+ target.labels.push(...validated.labels);
639
+ }
640
+ if (validated.targeting !== undefined) {
641
+ Object.assign(target.keyValues, validated.targeting);
642
+ }
643
+ if (validated.audience !== undefined) {
644
+ target.audience = validated.audience;
645
+ }
646
+ if (validated.adUnitPathVariables !== undefined) {
647
+ target.adUnitPathVariables = validated.adUnitPathVariables;
648
+ }
649
+ }
650
+ function setConfig(partial) {
651
+ const validated = validateConfigOverrides(partial);
661
652
  switch (state.state) {
662
653
  case 'configurable':
663
654
  case 'configured': {
664
- state.runtimeConfig.audience = audience;
655
+ applyConfigOverrides(state.runtimeConfig, validated);
665
656
  break;
666
657
  }
667
658
  case 'spa-finished':
668
659
  case 'spa-requestAds': {
669
- state.nextRuntimeConfig.audience = audience;
660
+ applyConfigOverrides(state.nextRuntimeConfig, validated);
670
661
  break;
671
662
  }
672
663
  default: {
673
- getLogger(state.runtimeConfig, window).error('MoliGlobal', `Setting audience targeting after configuration: ${JSON.stringify(audience)}`);
664
+ getLogger(state.runtimeConfig, window).error('MoliGlobal', `Setting config after configuration: ${JSON.stringify(partial)}`);
674
665
  break;
675
666
  }
676
667
  }
@@ -727,6 +718,7 @@ export const createMoliTag = (window) => {
727
718
  getState: getState,
728
719
  openConsole: openConsole,
729
720
  setAudience: setAudience,
721
+ setConfig: setConfig,
730
722
  addEventListener: eventService.addEventListener,
731
723
  removeEventListener: eventService.removeEventListener
732
724
  };
@@ -13,9 +13,14 @@ if (currentScript) {
13
13
  .filter(l => l.length > 0);
14
14
  if (labels.length > 0) {
15
15
  window.moli.que.push(moli => {
16
- moli.beforeRequestAds(() => labels.forEach(label => moli.addLabel(label)));
16
+ moli.beforeRequestAds(() => moli.setConfig({ labels }));
17
17
  });
18
18
  }
19
+ const adVolumeAttr = currentScript.getAttribute('data-ad-volume');
20
+ if (adVolumeAttr !== null) {
21
+ const adVolume = parseInt(adVolumeAttr, 10);
22
+ window.moli.que.push(moli => moli.setConfig({ adVolume }));
23
+ }
19
24
  window.moli.configLabel = version;
20
25
  const endpoint = currentScript.getAttribute('data-endpoint') ?? 'api.h5v.eu/publishers';
21
26
  const fallback = currentScript.getAttribute('data-endpoint-fallback') ?? 'cdn.h5v.eu/publishers';
@@ -1,3 +1,3 @@
1
1
  export const packageJson = {
2
- version: '5.12.1'
2
+ version: '5.13.1'
3
3
  };
@@ -0,0 +1,6 @@
1
+ export const adVolumeToLabels = (adVolume) => {
2
+ if (adVolume === undefined) {
3
+ return [];
4
+ }
5
+ return Array.from({ length: adVolume }, (_, index) => `av${index + 1}`);
6
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highfivve/ad-tag",
3
- "version": "5.12.1",
3
+ "version": "5.13.1",
4
4
  "license": "Apache-2.0",
5
5
  "description": "An ad tag implementation called moli",
6
6
  "main": "./lib/index.js",