prebid.js 7.3.0 → 7.6.0

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 (225) hide show
  1. package/.circleci/config.yml +11 -6
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/adagioBidAdapter.js +1 -1
  4. package/dist/adbookpspBidAdapter.js +1 -1
  5. package/dist/adgenerationBidAdapter.js +1 -1
  6. package/dist/adnuntiusBidAdapter.js +1 -1
  7. package/dist/adotBidAdapter.js +1 -1
  8. package/dist/adpod.js +1 -1
  9. package/dist/adrelevantisBidAdapter.js +1 -1
  10. package/dist/adrinoBidAdapter.js +1 -1
  11. package/dist/adtelligentBidAdapter.js +1 -1
  12. package/dist/adxcgBidAdapter.js +1 -1
  13. package/dist/ajaBidAdapter.js +1 -1
  14. package/dist/amxBidAdapter.js +1 -1
  15. package/dist/amxIdSystem.js +1 -1
  16. package/dist/appierAnalyticsAdapter.js +1 -1
  17. package/dist/appnexusBidAdapter.js +1 -1
  18. package/dist/asoBidAdapter.js +1 -1
  19. package/dist/atsAnalyticsAdapter.js +1 -1
  20. package/dist/axonixBidAdapter.js +1 -1
  21. package/dist/bidglassBidAdapter.js +1 -1
  22. package/dist/big-richmediaBidAdapter.js +1 -1
  23. package/dist/bridgewellBidAdapter.js +1 -1
  24. package/dist/brightMountainMediaBidAdapter.js +1 -1
  25. package/dist/byDataAnalyticsAdapter.js +1 -1
  26. package/dist/concertBidAdapter.js +1 -1
  27. package/dist/connectadBidAdapter.js +1 -1
  28. package/dist/consumableBidAdapter.js +1 -1
  29. package/dist/conversantBidAdapter.js +1 -1
  30. package/dist/craftBidAdapter.js +1 -1
  31. package/dist/criteoBidAdapter.js +1 -1
  32. package/dist/debugging-standalone.js +1 -1
  33. package/dist/debugging.js +1 -1
  34. package/dist/dspxBidAdapter.js +1 -1
  35. package/dist/eplanningBidAdapter.js +1 -1
  36. package/dist/finativeBidAdapter.js +1 -1
  37. package/dist/gdprEnforcement.js +1 -1
  38. package/dist/glimpseBidAdapter.js +1 -1
  39. package/dist/gmosspBidAdapter.js +1 -1
  40. package/dist/goldbachBidAdapter.js +1 -1
  41. package/dist/gridBidAdapter.js +1 -1
  42. package/dist/gridNMBidAdapter.js +1 -1
  43. package/dist/gumgumBidAdapter.js +1 -1
  44. package/dist/h12mediaBidAdapter.js +1 -1
  45. package/dist/hadronIdSystem.js +1 -1
  46. package/dist/hadronRtdProvider.js +1 -1
  47. package/dist/id5IdSystem.js +1 -1
  48. package/dist/imRtdProvider.js +1 -1
  49. package/dist/improvedigitalBidAdapter.js +1 -1
  50. package/dist/inmarBidAdapter.js +1 -1
  51. package/dist/insticatorBidAdapter.js +1 -1
  52. package/dist/ixBidAdapter.js +1 -1
  53. package/dist/justpremiumBidAdapter.js +1 -1
  54. package/dist/kargoAnalyticsAdapter.js +1 -1
  55. package/dist/kargoBidAdapter.js +1 -1
  56. package/dist/konduitAnalyticsAdapter.js +1 -1
  57. package/dist/kueezBidAdapter.js +1 -1
  58. package/dist/lassoBidAdapter.js +1 -1
  59. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  60. package/dist/logicadBidAdapter.js +1 -1
  61. package/dist/loglyliftBidAdapter.js +1 -1
  62. package/dist/malltvAnalyticsAdapter.js +1 -1
  63. package/dist/marsmediaBidAdapter.js +1 -1
  64. package/dist/mediafuseBidAdapter.js +1 -1
  65. package/dist/mediasquareBidAdapter.js +1 -1
  66. package/dist/mgidBidAdapter.js +1 -1
  67. package/dist/minutemediaBidAdapter.js +1 -1
  68. package/dist/missenaBidAdapter.js +1 -1
  69. package/dist/newspassidBidAdapter.js +1 -0
  70. package/dist/nextMillenniumBidAdapter.js +1 -1
  71. package/dist/not-for-prod/prebid.js +131 -127
  72. package/dist/oguryBidAdapter.js +1 -1
  73. package/dist/onetagBidAdapter.js +1 -1
  74. package/dist/ooloAnalyticsAdapter.js +1 -1
  75. package/dist/openxOrtbBidAdapter.js +1 -0
  76. package/dist/outbrainBidAdapter.js +1 -1
  77. package/dist/parrableIdSystem.js +1 -1
  78. package/dist/pixfutureBidAdapter.js +1 -1
  79. package/dist/prebid-core.js +2 -2
  80. package/dist/priceFloors.js +1 -1
  81. package/dist/pubCommonId.js +1 -1
  82. package/dist/publinkIdSystem.js +1 -1
  83. package/dist/pubmaticBidAdapter.js +1 -1
  84. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  85. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  86. package/dist/pxyzBidAdapter.js +1 -1
  87. package/dist/quantcastBidAdapter.js +1 -1
  88. package/dist/rasBidAdapter.js +1 -0
  89. package/dist/readpeakBidAdapter.js +1 -1
  90. package/dist/relaidoBidAdapter.js +1 -1
  91. package/dist/rhythmoneBidAdapter.js +1 -1
  92. package/dist/riseBidAdapter.js +1 -1
  93. package/dist/rubiconAnalyticsAdapter.js +1 -1
  94. package/dist/rubiconBidAdapter.js +1 -1
  95. package/dist/seedingAllianceBidAdapter.js +1 -1
  96. package/dist/seedtagBidAdapter.js +1 -1
  97. package/dist/sharedIdSystem.js +1 -1
  98. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  99. package/dist/sharethroughBidAdapter.js +1 -1
  100. package/dist/shinezBidAdapter.js +1 -0
  101. package/dist/sizeMappingV2.js +1 -1
  102. package/dist/smaatoBidAdapter.js +1 -1
  103. package/dist/smartadserverBidAdapter.js +1 -1
  104. package/dist/smartxBidAdapter.js +1 -1
  105. package/dist/smilewantedBidAdapter.js +1 -1
  106. package/dist/sonobiBidAdapter.js +1 -1
  107. package/dist/sovrnAnalyticsAdapter.js +1 -1
  108. package/dist/sovrnBidAdapter.js +1 -1
  109. package/dist/sspBCBidAdapter.js +1 -1
  110. package/dist/sublimeBidAdapter.js +1 -1
  111. package/dist/synacormediaBidAdapter.js +1 -1
  112. package/dist/taboolaBidAdapter.js +1 -1
  113. package/dist/targetVideoBidAdapter.js +1 -1
  114. package/dist/teadsBidAdapter.js +1 -1
  115. package/dist/trionBidAdapter.js +1 -1
  116. package/dist/tripleliftBidAdapter.js +1 -1
  117. package/dist/ttdBidAdapter.js +1 -1
  118. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  119. package/dist/underdogmediaBidAdapter.js +1 -1
  120. package/dist/undertoneBidAdapter.js +1 -1
  121. package/dist/ventesBidAdapter.js +1 -1
  122. package/dist/vidazooBidAdapter.js +1 -1
  123. package/dist/videobyteBidAdapter.js +1 -1
  124. package/dist/visxBidAdapter.js +1 -1
  125. package/dist/vrtcalBidAdapter.js +1 -1
  126. package/dist/vuukleBidAdapter.js +1 -1
  127. package/dist/widespaceBidAdapter.js +1 -1
  128. package/dist/winrBidAdapter.js +1 -1
  129. package/dist/yahoosspBidAdapter.js +1 -1
  130. package/dist/yieldmoBidAdapter.js +1 -1
  131. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  132. package/gulpfile.js +1 -1
  133. package/karma.conf.maker.js +3 -1
  134. package/modules/adgenerationBidAdapter.js +24 -1
  135. package/modules/adnuntiusBidAdapter.js +26 -8
  136. package/modules/adotBidAdapter.js +13 -4
  137. package/modules/adrinoBidAdapter.js +10 -2
  138. package/modules/adrinoBidAdapter.md +6 -0
  139. package/modules/adtelligentBidAdapter.js +2 -1
  140. package/modules/appnexusBidAdapter.js +3 -3
  141. package/modules/atsAnalyticsAdapter.js +4 -5
  142. package/modules/byDataAnalyticsAdapter.js +172 -74
  143. package/modules/byDataAnalyticsAdapter.md +5 -6
  144. package/modules/consumableBidAdapter.js +12 -1
  145. package/modules/criteoBidAdapter.js +7 -1
  146. package/modules/cwireBidAdapter.md +1 -1
  147. package/modules/debugging/bidInterceptor.js +1 -1
  148. package/modules/debugging/index.js +2 -1
  149. package/modules/eplanningBidAdapter.js +82 -97
  150. package/modules/gdprEnforcement.js +8 -14
  151. package/modules/gridNMBidAdapter.js +45 -4
  152. package/modules/hadronAnalyticsAdapter.md +5 -5
  153. package/modules/hadronIdSystem.js +18 -5
  154. package/modules/hadronIdSystem.md +15 -11
  155. package/modules/hadronRtdProvider.js +14 -1
  156. package/modules/hadronRtdProvider.md +17 -13
  157. package/modules/imRtdProvider.js +0 -8
  158. package/modules/insticatorBidAdapter.js +9 -0
  159. package/modules/ixBidAdapter.js +462 -58
  160. package/modules/ixBidAdapter.md +95 -5
  161. package/modules/kargoAnalyticsAdapter.js +88 -6
  162. package/modules/kargoAnalyticsAdapter.md +33 -0
  163. package/modules/kargoBidAdapter.js +1 -2
  164. package/modules/minutemediaBidAdapter.js +1 -0
  165. package/modules/missenaBidAdapter.js +20 -2
  166. package/modules/newspassidBidAdapter.js +649 -0
  167. package/modules/nextMillenniumBidAdapter.js +17 -1
  168. package/modules/oguryBidAdapter.js +2 -0
  169. package/modules/openxBidAdapter.md +3 -1
  170. package/modules/openxOrtbBidAdapter.js +349 -0
  171. package/modules/openxOrtbBidAdapter.md +105 -0
  172. package/modules/priceFloors.js +1 -1
  173. package/modules/pubCommonId.js +1 -2
  174. package/modules/pubxaiAnalyticsAdapter.js +6 -1
  175. package/modules/rasBidAdapter.js +149 -0
  176. package/modules/rasBidAdapter.md +50 -0
  177. package/modules/readpeakBidAdapter.js +15 -6
  178. package/modules/relaidoBidAdapter.js +19 -4
  179. package/modules/seedtagBidAdapter.js +37 -1
  180. package/modules/sharedIdSystem.js +11 -5
  181. package/modules/sharethroughBidAdapter.js +9 -24
  182. package/modules/shinezBidAdapter.js +435 -0
  183. package/modules/shinezBidAdapter.md +76 -0
  184. package/modules/taboolaBidAdapter.js +1 -1
  185. package/modules/taboolaBidAdapter.md +3 -3
  186. package/modules/ventesBidAdapter.js +1 -1
  187. package/modules/ventesBidAdapter.md +1 -1
  188. package/modules/vrtcalBidAdapter.js +35 -0
  189. package/package.json +1 -1
  190. package/plugins/pbjsGlobals.js +2 -1
  191. package/src/storageManager.js +4 -5
  192. package/test/spec/modules/adgenerationBidAdapter_spec.js +52 -4
  193. package/test/spec/modules/adnuntiusBidAdapter_spec.js +126 -14
  194. package/test/spec/modules/adotBidAdapter_spec.js +12 -9
  195. package/test/spec/modules/adrinoBidAdapter_spec.js +22 -0
  196. package/test/spec/modules/appnexusBidAdapter_spec.js +165 -156
  197. package/test/spec/modules/byDataAnalyticsAdapter_spec.js +74 -24
  198. package/test/spec/modules/consumableBidAdapter_spec.js +75 -0
  199. package/test/spec/modules/criteoBidAdapter_spec.js +15 -5
  200. package/test/spec/modules/debugging_mod_spec.js +7 -0
  201. package/test/spec/modules/eplanningBidAdapter_spec.js +58 -18
  202. package/test/spec/modules/gdprEnforcement_spec.js +53 -100
  203. package/test/spec/modules/gridNMBidAdapter_spec.js +32 -0
  204. package/test/spec/modules/hadronIdSystem_spec.js +2 -2
  205. package/test/spec/modules/imRtdProvider_spec.js +0 -1
  206. package/test/spec/modules/insticatorBidAdapter_spec.js +22 -1
  207. package/test/spec/modules/ixBidAdapter_spec.js +470 -10
  208. package/test/spec/modules/kargoAnalyticsAdapter_spec.js +42 -0
  209. package/test/spec/modules/kargoBidAdapter_spec.js +1 -0
  210. package/test/spec/modules/minutemediaBidAdapter_spec.js +3 -0
  211. package/test/spec/modules/missenaBidAdapter_spec.js +36 -14
  212. package/test/spec/modules/newspassidBidAdapter_spec.js +1793 -0
  213. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +20 -0
  214. package/test/spec/modules/openxOrtbBidAdapter_spec.js +1303 -0
  215. package/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +5 -0
  216. package/test/spec/modules/rasBidAdapter_spec.js +190 -0
  217. package/test/spec/modules/readpeakBidAdapter_spec.js +1 -0
  218. package/test/spec/modules/relaidoBidAdapter_spec.js +29 -2
  219. package/test/spec/modules/seedtagBidAdapter_spec.js +29 -0
  220. package/test/spec/modules/sharethroughBidAdapter_spec.js +4 -4
  221. package/test/spec/modules/shinezBidAdapter_spec.js +479 -0
  222. package/test/spec/modules/taboolaBidAdapter_spec.js +1 -1
  223. package/test/spec/modules/ventesBidAdapter_spec.js +2 -2
  224. package/test/spec/modules/vrtcalBidAdapter_spec.js +17 -0
  225. package/webpack.conf.js +1 -1
@@ -1,7 +1,7 @@
1
1
  # Overview
2
2
 
3
3
  layout: Analytics Adapter
4
- title: Ascendeum Pvt Ltd. (https://ascendeum.com/)
4
+ title: byData. (https://bydata.com/)
5
5
  description: Bydata Analytics Adapter
6
6
  modulecode: byDataAnalyticsAdapter
7
7
  gdpr_supported: false (EU GDPR support)
@@ -13,11 +13,12 @@ enable_download: false (in case you don't want users of the website to dow
13
13
 
14
14
  Module Name: Bydata Analytics Adapter
15
15
  Module Type: Analytics Adapter
16
- Maintainer: Ascendeum
16
+ Maintainer: byData
17
17
 
18
18
  # Description
19
19
 
20
- Analytics adapter for https://ascendeum.com/. Contact engineering@ascendeum.com for information.
20
+ Analytics adapter for https://bydata.com/. Contact admin@byData.com for information.
21
+
21
22
 
22
23
  # Test Parameters
23
24
 
@@ -25,10 +26,8 @@ Analytics adapter for https://ascendeum.com/. Contact engineering@ascendeum.com
25
26
  {
26
27
  provider: 'bydata',
27
28
  options : {
28
- clientId: "ASCENDEUM_PROVIDED_CLIENT_ID",
29
+ clientId: "please contact byData team to get a clientId",
29
30
  logFrequency : 100, // Sample Rate Default - 1%
30
31
  }
31
32
  }
32
33
  ```
33
-
34
-
@@ -1,4 +1,4 @@
1
- import { logWarn, createTrackPixelHtml } from '../src/utils.js';
1
+ import { logWarn, createTrackPixelHtml, deepAccess, isArray, deepSetValue } from '../src/utils.js';
2
2
  import { registerBidder } from '../src/adapters/bidderFactory.js';
3
3
 
4
4
  const BIDDER_CODE = 'consumable';
@@ -78,6 +78,8 @@ export const spec = {
78
78
  }
79
79
  });
80
80
 
81
+ handleEids(data, validBidRequests);
82
+
81
83
  ret.data = JSON.stringify(data);
82
84
  ret.bidRequest = validBidRequests;
83
85
  ret.bidderRequest = bidderRequest;
@@ -234,4 +236,13 @@ function retrieveAd(decision, unitId, unitName) {
234
236
  return ad;
235
237
  }
236
238
 
239
+ function handleEids(data, validBidRequests) {
240
+ let bidUserIdAsEids = deepAccess(validBidRequests, '0.userIdAsEids');
241
+ if (isArray(bidUserIdAsEids) && bidUserIdAsEids.length > 0) {
242
+ deepSetValue(data, 'user.eids', bidUserIdAsEids);
243
+ } else {
244
+ deepSetValue(data, 'user.eids', undefined);
245
+ }
246
+ }
247
+
237
248
  registerBidder(spec);
@@ -13,7 +13,7 @@ const BIDDER_CODE = 'criteo';
13
13
  const CDB_ENDPOINT = 'https://bidder.criteo.com/cdb';
14
14
  const PROFILE_ID_INLINE = 207;
15
15
  export const PROFILE_ID_PUBLISHERTAG = 185;
16
- const storage = getStorageManager({ gvlid: GVLID, bidderCode: BIDDER_CODE });
16
+ export const storage = getStorageManager({ gvlid: GVLID, bidderCode: BIDDER_CODE });
17
17
  const LOG_PREFIX = 'Criteo: ';
18
18
 
19
19
  /*
@@ -255,6 +255,12 @@ function buildCdbUrl(context) {
255
255
  url += '&wv=' + encodeURIComponent('$prebid.version$');
256
256
  url += '&cb=' + String(Math.floor(Math.random() * 99999999999));
257
257
 
258
+ if (storage.localStorageIsEnabled()) {
259
+ url += '&lsavail=1';
260
+ } else {
261
+ url += '&lsavail=0';
262
+ }
263
+
258
264
  if (context.amp) {
259
265
  url += '&im=1';
260
266
  }
@@ -38,7 +38,7 @@ var adUnits = [
38
38
  params: {
39
39
  pageId: 1422, // required - number
40
40
  placementId: 2211521, // required - number
41
- cwcreative: 42, // optional - id of creative to force
41
+ cwcreative: '42', // optional - id of creative to force
42
42
  refgroups: 'test-user', // optional - name of group or coma separated list of groups to force
43
43
  cwapikey: 'api_key_xyz', // optional - api key for integration testing
44
44
  }
@@ -122,7 +122,7 @@ Object.assign(BidInterceptor.prototype, {
122
122
  replFn = () => ({});
123
123
  } else {
124
124
  replFn = ({args, ref = replDef}) => {
125
- const result = {};
125
+ const result = Array.isArray(ref) ? [] : {};
126
126
  Object.entries(ref).forEach(([key, val]) => {
127
127
  if (typeof val === 'function') {
128
128
  result[key] = val(...args);
@@ -3,5 +3,6 @@ import {hook} from '../../src/hook.js';
3
3
  import {install} from './debugging.js';
4
4
  import {prefixLog} from '../../src/utils.js';
5
5
  import {createBid} from '../../src/bidfactory.js';
6
+ import {DEBUG_KEY} from '../../src/debugging.js';
6
7
 
7
- install({config, hook, createBid, logger: prefixLog('DEBUG:')});
8
+ install({DEBUG_KEY, config, hook, createBid, logger: prefixLog('DEBUG:')});
@@ -1,4 +1,4 @@
1
- import {getWindowSelf, isEmpty, parseSizesInput} from '../src/utils.js';
1
+ import {getWindowSelf, isEmpty, parseSizesInput, isGptPubadsDefined, isSlotMatchingAdUnitCode} from '../src/utils.js';
2
2
  import {getGlobal} from '../src/prebidGlobal.js';
3
3
  import {registerBidder} from '../src/adapters/bidderFactory.js';
4
4
  import {getStorageManager} from '../src/storageManager.js';
@@ -291,13 +291,25 @@ function getCharset() {
291
291
 
292
292
  function waitForElementsPresent(elements) {
293
293
  const observer = new MutationObserver(function (mutationList, observer) {
294
+ let index;
295
+ let adView;
294
296
  if (mutationList && Array.isArray(mutationList)) {
295
297
  mutationList.forEach(mr => {
296
298
  if (mr && mr.addedNodes && Array.isArray(mr.addedNodes)) {
297
299
  mr.addedNodes.forEach(ad => {
298
- let index = elements.indexOf(ad.id);
300
+ index = elements.indexOf(ad.id);
301
+ adView = ad;
302
+ if (index < 0) {
303
+ elements.forEach(code => {
304
+ let div = _getAdSlotHTMLElement(code);
305
+ if (div && div.contains(ad) && div.getBoundingClientRect().width > 0) {
306
+ index = elements.indexOf(div.id);
307
+ adView = div;
308
+ }
309
+ });
310
+ }
299
311
  if (index >= 0) {
300
- registerViewability(ad);
312
+ registerViewability(adView, elements[index]);
301
313
  elements.splice(index, 1);
302
314
  if (!elements.length) {
303
315
  observer.disconnect();
@@ -318,19 +330,41 @@ function waitForElementsPresent(elements) {
318
330
  });
319
331
  }
320
332
 
321
- function registerViewability(div) {
333
+ function registerViewability(div, name) {
322
334
  visibilityHandler({
323
- name: div.id,
335
+ name: name,
324
336
  div: div
325
337
  });
326
338
  }
327
339
 
340
+ function _mapAdUnitPathToElementId(adUnitCode) {
341
+ if (isGptPubadsDefined()) {
342
+ // eslint-disable-next-line no-undef
343
+ const adSlots = googletag.pubads().getSlots();
344
+ const isMatchingAdSlot = isSlotMatchingAdUnitCode(adUnitCode);
345
+
346
+ for (let i = 0; i < adSlots.length; i++) {
347
+ if (isMatchingAdSlot(adSlots[i])) {
348
+ const id = adSlots[i].getSlotElementId();
349
+ return id;
350
+ }
351
+ }
352
+ }
353
+
354
+ return null;
355
+ }
356
+
357
+ function _getAdSlotHTMLElement(adUnitCode) {
358
+ return document.getElementById(adUnitCode) ||
359
+ document.getElementById(_mapAdUnitPathToElementId(adUnitCode));
360
+ }
361
+
328
362
  function registerViewabilityAllBids(bids) {
329
363
  let elementsNotPresent = [];
330
364
  bids.forEach(bid => {
331
- let div = document.getElementById(bid.adUnitCode);
365
+ let div = _getAdSlotHTMLElement(bid.adUnitCode);
332
366
  if (div) {
333
- registerViewability(div);
367
+ registerViewability(div, bid.adUnitCode);
334
368
  } else {
335
369
  elementsNotPresent.push(bid.adUnitCode);
336
370
  }
@@ -345,114 +379,65 @@ function getViewabilityTracker() {
345
379
  let VIEWABILITY_TIME = 1000;
346
380
  let VIEWABILITY_MIN_RATIO = 0.5;
347
381
  let publicApi;
348
- let context;
349
-
350
- function segmentIsOutsideTheVisibleRange(visibleRangeEnd, p1, p2) {
351
- return p1 > visibleRangeEnd || p2 < 0;
352
- }
353
-
354
- function segmentBeginsBeforeTheVisibleRange(p1) {
355
- return p1 < 0;
356
- }
357
-
358
- function segmentEndsAfterTheVisibleRange(visibleRangeEnd, p2) {
359
- return p2 < visibleRangeEnd;
360
- }
361
-
362
- function axialVisibilityRatio(visibleRangeEnd, p1, p2) {
363
- let visibilityRatio = 0;
364
- if (!segmentIsOutsideTheVisibleRange(visibleRangeEnd, p1, p2)) {
365
- if (segmentBeginsBeforeTheVisibleRange(p1)) {
366
- visibilityRatio = p2 / (p2 - p1);
382
+ let observer;
383
+ let visibilityAds = {};
384
+
385
+ function intersectionCallback(entries) {
386
+ entries.forEach(function(entry) {
387
+ var adBox = entry.target;
388
+ if (entry.isIntersecting) {
389
+ if (entry.intersectionRatio >= VIEWABILITY_MIN_RATIO && entry.boundingClientRect && entry.boundingClientRect.height > 0 && entry.boundingClientRect.width > 0) {
390
+ visibilityAds[adBox.id] = true;
391
+ }
367
392
  } else {
368
- visibilityRatio = segmentEndsAfterTheVisibleRange(visibleRangeEnd, p2) ? 1 : (visibleRangeEnd - p1) / (p2 - p1);
393
+ visibilityAds[adBox.id] = false;
369
394
  }
370
- }
371
- return visibilityRatio;
372
- }
373
-
374
- function isNotHiddenByNonFriendlyIframe() {
375
- try { return (window === window.top) || window.frameElement; } catch (e) {}
376
- }
377
-
378
- function defineContext(e) {
379
- try {
380
- context = e && window.document.body.contains(e) ? window : (window.top.document.body.contains(e) ? top : undefined);
381
- } catch (err) {}
382
- return context;
383
- }
384
-
385
- function getContext(e) {
386
- return context;
387
- }
388
-
389
- function verticalVisibilityRatio(position) {
390
- return axialVisibilityRatio(getContext().innerHeight, position.top, position.bottom);
391
- }
392
-
393
- function horizontalVisibilityRatio(position) {
394
- return axialVisibilityRatio(getContext().innerWidth, position.left, position.right);
395
- }
396
-
397
- function itIsNotHiddenByBannerAreaPosition(e) {
398
- let position = e.getBoundingClientRect();
399
- return (verticalVisibilityRatio(position) * horizontalVisibilityRatio(position)) > VIEWABILITY_MIN_RATIO;
400
- }
401
-
402
- function itIsNotHiddenByDisplayStyleCascade(e) {
403
- return e.offsetHeight > 0 && e.offsetWidth > 0;
404
- }
405
-
406
- function itIsNotHiddenByOpacityStyleCascade(e) {
407
- let s = e.style;
408
- let p = e.parentNode;
409
- return !(s && parseFloat(s.opacity) === 0) && (!p || itIsNotHiddenByOpacityStyleCascade(p));
410
- }
411
-
412
- function itIsNotHiddenByVisibilityStyleCascade(e) {
413
- return getContext().getComputedStyle(e).visibility !== 'hidden';
414
- }
415
-
416
- function itIsNotHiddenByTabFocus() {
417
- try { return getContext().top.document.hasFocus(); } catch (e) {}
418
- }
419
-
420
- function isDefined(e) {
421
- return (e !== null) && (typeof e !== 'undefined');
395
+ });
422
396
  }
423
397
 
424
- function itIsNotHiddenByOrphanBranch() {
425
- return isDefined(getContext());
398
+ function observedElementIsVisible(element) {
399
+ return visibilityAds[element.id] && document.visibilityState && document.visibilityState === 'visible';
426
400
  }
427
401
 
428
- function isContextInAnIframe() {
429
- return isDefined(getContext().frameElement);
402
+ function defineObserver() {
403
+ if (!observer) {
404
+ var observerConfig = {
405
+ root: null,
406
+ rootMargin: '0px',
407
+ threshold: [VIEWABILITY_MIN_RATIO]
408
+ };
409
+ observer = new IntersectionObserver(intersectionCallback.bind(this), observerConfig);
410
+ }
430
411
  }
431
-
432
412
  function processIntervalVisibilityStatus(elapsedVisibleIntervals, element, callback) {
433
- let visibleIntervals = isVisible(element) ? (elapsedVisibleIntervals + 1) : 0;
413
+ let visibleIntervals = observedElementIsVisible(element) ? (elapsedVisibleIntervals + 1) : 0;
434
414
  if (visibleIntervals === TIME_PARTITIONS) {
415
+ stopObserveViewability(element)
435
416
  callback();
436
417
  } else {
437
418
  setTimeout(processIntervalVisibilityStatus.bind(this, visibleIntervals, element, callback), VIEWABILITY_TIME / TIME_PARTITIONS);
438
419
  }
439
420
  }
440
421
 
441
- function isVisible(element) {
442
- defineContext(element);
443
- return isNotHiddenByNonFriendlyIframe() &&
444
- itIsNotHiddenByOrphanBranch() &&
445
- itIsNotHiddenByTabFocus() &&
446
- itIsNotHiddenByDisplayStyleCascade(element) &&
447
- itIsNotHiddenByVisibilityStyleCascade(element) &&
448
- itIsNotHiddenByOpacityStyleCascade(element) &&
449
- itIsNotHiddenByBannerAreaPosition(element) &&
450
- (!isContextInAnIframe() || isVisible(getContext().frameElement));
422
+ function stopObserveViewability(element) {
423
+ delete visibilityAds[element.id];
424
+ observer.unobserve(element);
425
+ }
426
+
427
+ function observeAds(element) {
428
+ observer.observe(element);
429
+ }
430
+
431
+ function initAndVerifyVisibility(element, callback) {
432
+ if (element) {
433
+ defineObserver();
434
+ observeAds(element);
435
+ processIntervalVisibilityStatus(0, element, callback);
436
+ }
451
437
  }
452
438
 
453
439
  publicApi = {
454
- isVisible: isVisible,
455
- onView: processIntervalVisibilityStatus.bind(this, 0)
440
+ onView: initAndVerifyVisibility.bind(this)
456
441
  };
457
442
 
458
443
  return publicApi;
@@ -18,8 +18,6 @@ const TCF2 = {
18
18
  'purpose7': { id: 7, name: 'measurement' }
19
19
  }
20
20
 
21
- const VENDORLESS_MODULE_TYPES = ['fpid-module'];
22
-
23
21
  /*
24
22
  These rules would be used if `consentManagement.gdpr.rules` is undefined by the publisher.
25
23
  */
@@ -125,10 +123,9 @@ function getGvlidForAnalyticsAdapter(code) {
125
123
  * @param {Object} consentData - gdpr consent data
126
124
  * @param {string=} currentModule - Bidder code of the current module
127
125
  * @param {number=} gvlId - GVL ID for the module
128
- * @param {string=} moduleType module type
129
126
  * @returns {boolean}
130
127
  */
131
- export function validateRules(rule, consentData, currentModule, gvlId, moduleType) {
128
+ export function validateRules(rule, consentData, currentModule, gvlId) {
132
129
  const purposeId = TCF2[Object.keys(TCF2).filter(purposeName => TCF2[purposeName].name === rule.purpose)[0]].id;
133
130
 
134
131
  // return 'true' if vendor present in 'vendorExceptions'
@@ -141,14 +138,12 @@ export function validateRules(rule, consentData, currentModule, gvlId, moduleTyp
141
138
  const vendorConsent = deepAccess(consentData, `vendorData.vendor.consents.${gvlId}`);
142
139
  const liTransparency = deepAccess(consentData, `vendorData.purpose.legitimateInterests.${purposeId}`);
143
140
 
144
- const vendorlessModule = includes(VENDORLESS_MODULE_TYPES, moduleType);
145
-
146
141
  /*
147
142
  Since vendor exceptions have already been handled, the purpose as a whole is allowed if it's not being enforced
148
143
  or the user has consented. Similar with vendors.
149
144
  */
150
145
  const purposeAllowed = rule.enforcePurpose === false || purposeConsent === true;
151
- const vendorAllowed = rule.enforceVendor === false || vendorConsent === true || vendorlessModule === true;
146
+ const vendorAllowed = rule.enforceVendor === false || vendorConsent === true;
152
147
 
153
148
  /*
154
149
  Few if any vendors should be declaring Legitimate Interest for Device Access (Purpose 1), but some are claiming
@@ -167,16 +162,15 @@ export function validateRules(rule, consentData, currentModule, gvlId, moduleTyp
167
162
  * @param {Function} fn reference to original function (used by hook logic)
168
163
  * @param {Number=} gvlid gvlid of the module
169
164
  * @param {string=} moduleName name of the module
170
- * @param {string=} moduleType module type
171
165
  */
172
- export function deviceAccessHook(fn, gvlid, moduleName, moduleType, result) {
166
+ export function deviceAccessHook(fn, gvlid, moduleName, result) {
173
167
  result = Object.assign({}, {
174
168
  hasEnforcementHook: true
175
169
  });
176
170
  if (!hasDeviceAccess()) {
177
171
  logWarn('Device access is disabled by Publisher');
178
172
  result.valid = false;
179
- fn.call(this, gvlid, moduleName, moduleType, result);
173
+ fn.call(this, gvlid, moduleName, result);
180
174
  } else {
181
175
  const consentData = gdprDataHandler.getConsentData();
182
176
  if (consentData && consentData.gdprApplies) {
@@ -188,19 +182,19 @@ export function deviceAccessHook(fn, gvlid, moduleName, moduleType, result) {
188
182
  gvlid = getGvlid(moduleName) || gvlid;
189
183
  }
190
184
  const curModule = moduleName || curBidder;
191
- let isAllowed = validateRules(purpose1Rule, consentData, curModule, gvlid, moduleType);
185
+ let isAllowed = validateRules(purpose1Rule, consentData, curModule, gvlid);
192
186
  if (isAllowed) {
193
187
  result.valid = true;
194
- fn.call(this, gvlid, moduleName, moduleType, result);
188
+ fn.call(this, gvlid, moduleName, result);
195
189
  } else {
196
190
  curModule && logWarn(`TCF2 denied device access for ${curModule}`);
197
191
  result.valid = false;
198
192
  storageBlocked.push(curModule);
199
- fn.call(this, gvlid, moduleName, moduleType, result);
193
+ fn.call(this, gvlid, moduleName, result);
200
194
  }
201
195
  } else {
202
196
  result.valid = true;
203
- fn.call(this, gvlid, moduleName, moduleType, result);
197
+ fn.call(this, gvlid, moduleName, result);
204
198
  }
205
199
  }
206
200
  }
@@ -1,4 +1,13 @@
1
- import { isStr, deepAccess, isArray, isNumber, logError, logWarn, parseGPTSingleSizeArrayToRtbSize } from '../src/utils.js';
1
+ import {
2
+ isStr,
3
+ deepAccess,
4
+ isArray,
5
+ isNumber,
6
+ logError,
7
+ logWarn,
8
+ parseGPTSingleSizeArrayToRtbSize,
9
+ mergeDeep
10
+ } from '../src/utils.js';
2
11
  import { registerBidder } from '../src/adapters/bidderFactory.js';
3
12
  import { Renderer } from '../src/Renderer.js';
4
13
  import { VIDEO } from '../src/mediaTypes.js';
@@ -153,9 +162,7 @@ export const spec = {
153
162
  user = {
154
163
  data: [{
155
164
  name: 'iow_labs_pub_data',
156
- segment: jwpseg.map((seg) => {
157
- return {name: 'jwpseg', value: seg};
158
- })
165
+ segment: segmentProcessing(jwpseg, 'jwpseg'),
159
166
  }]
160
167
  };
161
168
  }
@@ -174,9 +181,27 @@ export const spec = {
174
181
  user.ext = userExt;
175
182
  }
176
183
 
184
+ const ortb2UserData = deepAccess(bidderRequest, 'ortb2.user.data');
185
+ if (ortb2UserData && ortb2UserData.length) {
186
+ if (!user) {
187
+ user = { data: [] };
188
+ }
189
+ user = mergeDeep(user, {
190
+ data: [...ortb2UserData]
191
+ });
192
+ }
193
+
177
194
  if (user) {
178
195
  request.user = user;
179
196
  }
197
+ const site = deepAccess(bidderRequest, 'ortb2.site');
198
+ if (site) {
199
+ const data = deepAccess(site, 'content.data');
200
+ if (data && data.length) {
201
+ const siteContent = request.site.content || {};
202
+ request.site.content = mergeDeep(siteContent, { data });
203
+ }
204
+ }
180
205
 
181
206
  if (gdprConsent && gdprConsent.gdprApplies) {
182
207
  request.regs = {
@@ -408,4 +433,20 @@ export function getSyncUrl() {
408
433
  return SYNC_URL;
409
434
  }
410
435
 
436
+ function segmentProcessing(segment, forceSegName) {
437
+ return segment
438
+ .map((seg) => {
439
+ const value = seg && (seg.value || seg.id || seg);
440
+ if (typeof value === 'string' || typeof value === 'number') {
441
+ return {
442
+ value: value.toString(),
443
+ ...(forceSegName && { name: forceSegName }),
444
+ ...(seg.name && { name: seg.name }),
445
+ };
446
+ }
447
+ return null;
448
+ })
449
+ .filter((seg) => !!seg);
450
+ }
451
+
411
452
  registerBidder(spec);
@@ -33,7 +33,7 @@ The following configuration parameters are available:
33
33
 
34
34
  ```javascript
35
35
  pbjs.enableAnalytics({
36
- provider: 'hadron',
36
+ provider: 'hadronAnalytics',
37
37
  options: {
38
38
  partnerId: 1234, // change to the Partner ID you got from Audigent
39
39
  eventsToTrack: ['auctionEnd','bidWon']
@@ -41,8 +41,8 @@ pbjs.enableAnalytics({
41
41
  });
42
42
  ```
43
43
 
44
- | Parameter | Scope | Type | Description | Example |
45
- | --- | --- | --- |---------------------------------------------------------| --- |
46
- | provider | Required | String | The name of this module: `hadronAnalytics` | `hadronAnalytics` |
47
- | options.partnerId | Required | Number | This is the Audigent Partner ID obtained from Audigent. | `1234` |
44
+ | Parameter | Scope | Type | Description | Example |
45
+ |-----------------------|----------|------------------|---------------------------------------------------------|---------------------------|
46
+ | provider | Required | String | The name of this module: `hadronAnalytics` | `hadronAnalytics` |
47
+ | options.partnerId | Required | Number | This is the Audigent Partner ID obtained from Audigent. | `1234` |
48
48
  | options.eventsToTrack | Optional | Array of strings | Overrides the set of tracked events | `['auctionEnd','bidWon']` |
@@ -12,6 +12,7 @@ import { isFn, isStr, isPlainObject, logError } from '../src/utils.js';
12
12
 
13
13
  const MODULE_NAME = 'hadronId';
14
14
  const AU_GVLID = 561;
15
+ const DEFAULT_HADRON_URL_ENDPOINT = 'https://id.hadron.ad.gt/api/v1/pbhid';
15
16
 
16
17
  export const storage = getStorageManager({gvlid: AU_GVLID, moduleName: 'hadron'});
17
18
 
@@ -29,6 +30,15 @@ function paramOrDefault(param, defaultVal, arg) {
29
30
  return defaultVal;
30
31
  }
31
32
 
33
+ /**
34
+ * @param {string} url
35
+ * @param {string} params
36
+ * @returns {string}
37
+ */
38
+ const urlAddParams = (url, params) => {
39
+ return url + (url.indexOf('?') > -1 ? '&' : '?') + params
40
+ }
41
+
32
42
  /** @type {Submodule} */
33
43
  export const hadronIdSubmodule = {
34
44
  /**
@@ -39,8 +49,8 @@ export const hadronIdSubmodule = {
39
49
  /**
40
50
  * decode the stored id value for passing to bid requests
41
51
  * @function
42
- * @param {{value:string}} value
43
- * @returns {{hadronId:Object}}
52
+ * @param {string} value
53
+ * @returns {Object}
44
54
  */
45
55
  decode(value) {
46
56
  let hadronId = storage.getDataFromLocalStorage('auHadronId');
@@ -59,9 +69,12 @@ export const hadronIdSubmodule = {
59
69
  if (!isPlainObject(config.params)) {
60
70
  config.params = {};
61
71
  }
62
- const url = paramOrDefault(config.params.url,
63
- `https://id.hadron.ad.gt/api/v1/pbhid`,
64
- config.params.urlArg);
72
+ const partnerId = config.params.partnerId | 0;
73
+
74
+ const url = urlAddParams(
75
+ paramOrDefault(config.params.url, DEFAULT_HADRON_URL_ENDPOINT, config.params.urlArg),
76
+ `partner_id=${partnerId}&_it=prebid`
77
+ );
65
78
 
66
79
  const resp = function (callback) {
67
80
  let hadronId = storage.getDataFromLocalStorage('auHadronId');
@@ -11,6 +11,9 @@ pbjs.setConfig({
11
11
  usersync: {
12
12
  userIds: [{
13
13
  name: 'hadronId',
14
+ params: {
15
+ partnerId: 1234 // change it to the Partner ID you'll get from Audigent
16
+ },
14
17
  storage: {
15
18
  name: 'hadronId',
16
19
  type: 'html5'
@@ -22,14 +25,15 @@ pbjs.setConfig({
22
25
  ## Parameter Descriptions for the `usersync` Configuration Section
23
26
  The below parameters apply only to the HadronID User ID Module integration.
24
27
 
25
- | Param under usersync.userIds[] | Scope | Type | Description | Example |
26
- | --- | --- | --- | --- | --- |
27
- | name | Required | String | ID value for the HadronID module - `"hadronId"` | `"hadronId"` |
28
- | storage | Required | Object | The publisher must specify the local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. | |
29
- | storage.type | Required | String | This is where the results of the user ID will be stored. The recommended method is `localStorage` by specifying `html5`. | `"html5"` |
30
- | storage.name | Required | String | The name of the cookie or html5 local storage where the user ID will be stored. | `"hadronid"` |
31
- | storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `365` |
32
- | value | Optional | Object | Used only if the page has a separate mechanism for storing the Hadron ID. The value is an object containing the values to be sent to the adapters. In this scenario, no URL is called and nothing is added to local storage | `{"hadronId": "eb33b0cb-8d35-4722-b9c0-1a31d4064888"}` |
33
- | params | Optional | Object | Used to store params for the id system |
34
- | params.url | Optional | String | Set an alternate GET url for HadronId with this parameter |
35
- | params.urlArg | Optional | Object | Optional url parameter for params.url |
28
+ | Param under usersync.userIds[] | Scope | Type | Description | Example |
29
+ |--------------------------------|----------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------|
30
+ | name | Required | String | ID value for the HadronID module - `"hadronId"` | `"hadronId"` |
31
+ | storage | Required | Object | The publisher must specify the local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. | |
32
+ | storage.type | Required | String | This is where the results of the user ID will be stored. The recommended method is `localStorage` by specifying `html5`. | `"html5"` |
33
+ | storage.name | Required | String | The name of the cookie or html5 local storage where the user ID will be stored. | `"hadronid"` |
34
+ | storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `365` |
35
+ | value | Optional | Object | Used only if the page has a separate mechanism for storing the Hadron ID. The value is an object containing the values to be sent to the adapters. In this scenario, no URL is called and nothing is added to local storage | `{"hadronId": "eb33b0cb-8d35-4722-b9c0-1a31d4064888"}` |
36
+ | params | Optional | Object | Used to store params for the id system |
37
+ | params.partnerId | Required | Number | This is the Audigent Partner ID obtained from Audigent. | `1234` |
38
+ | params.url | Optional | String | Set an alternate GET url for HadronId with this parameter |
39
+ | params.urlArg | Optional | Object | Optional url parameter for params.url |
@@ -23,6 +23,15 @@ export const HALOID_LOCAL_NAME = 'auHadronId';
23
23
  export const RTD_LOCAL_NAME = 'auHadronRtd';
24
24
  export const storage = getStorageManager({gvlid: AU_GVLID, moduleName: SUBMODULE_NAME});
25
25
 
26
+ /**
27
+ * @param {string} url
28
+ * @param {string} params
29
+ * @returns {string}
30
+ */
31
+ const urlAddParams = (url, params) => {
32
+ return url + (url.indexOf('?') > -1 ? '&' : '?') + params
33
+ }
34
+
26
35
  /**
27
36
  * Deep set an object unless value present.
28
37
  * @param {Object} obj
@@ -165,8 +174,12 @@ export function getRealTimeData(bidConfig, onDone, rtdConfig, userConsent) {
165
174
  userIds.hadronId = hadronId;
166
175
  getRealTimeDataAsync(bidConfig, onDone, rtdConfig, userConsent, userIds);
167
176
  }
177
+ const partnerId = rtdConfig.params.partnerId | 0;
168
178
  const hadronIdUrl = rtdConfig.params && rtdConfig.params.hadronIdUrl;
169
- const scriptUrl = paramOrDefault(hadronIdUrl, HADRON_ID_DEFAULT_URL, userIds);
179
+ const scriptUrl = urlAddParams(
180
+ paramOrDefault(hadronIdUrl, HADRON_ID_DEFAULT_URL, userIds),
181
+ `partner_id=${partnerId}&_it=prebid`
182
+ );
170
183
  loadExternalScript(scriptUrl, 'hadron', () => {
171
184
  logInfo(LOG_PREFIX, 'hadronIdTag loaded', scriptUrl);
172
185
  })