prebid.js 6.5.0 → 6.9.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 (139) hide show
  1. package/.eslintrc.js +8 -1
  2. package/integrationExamples/gpt/amp/creative.html +11 -33
  3. package/integrationExamples/gpt/weboramaRtdProvider_example.html +154 -115
  4. package/integrationExamples/gpt/x-domain/creative.html +63 -29
  5. package/modules/.submodules.json +2 -1
  6. package/modules/adagioBidAdapter.js +0 -8
  7. package/modules/adagioBidAdapter.md +1 -1
  8. package/modules/adbookpspBidAdapter.js +27 -10
  9. package/modules/adhashBidAdapter.js +3 -3
  10. package/modules/adkernelBidAdapter.js +2 -1
  11. package/modules/admanBidAdapter.js +10 -4
  12. package/modules/adomikAnalyticsAdapter.js +23 -11
  13. package/modules/adqueryIdSystem.js +103 -0
  14. package/modules/adqueryIdSystem.md +35 -0
  15. package/modules/appnexusBidAdapter.js +14 -2
  16. package/modules/asealBidAdapter.js +58 -0
  17. package/modules/asealBidAdapter.md +52 -0
  18. package/modules/bliinkBidAdapter.js +2 -1
  19. package/modules/brandmetricsRtdProvider.js +168 -0
  20. package/modules/brandmetricsRtdProvider.md +40 -0
  21. package/modules/colossussspBidAdapter.js +12 -8
  22. package/modules/colossussspBidAdapter.md +15 -1
  23. package/modules/compassBidAdapter.js +10 -3
  24. package/modules/consumableBidAdapter.md +1 -1
  25. package/modules/conversantBidAdapter.js +7 -0
  26. package/modules/criteoBidAdapter.js +10 -1
  27. package/modules/criteoIdSystem.js +29 -7
  28. package/modules/currency.js +26 -1
  29. package/modules/displayioBidAdapter.js +157 -0
  30. package/modules/displayioBidAdapter.md +148 -0
  31. package/modules/e_volutionBidAdapter.js +158 -0
  32. package/modules/glimpseBidAdapter.js +66 -44
  33. package/modules/gnetBidAdapter.js +3 -3
  34. package/modules/gnetBidAdapter.md +4 -4
  35. package/modules/gumgumBidAdapter.js +56 -42
  36. package/modules/idImportLibrary.js +45 -8
  37. package/modules/idImportLibrary.md +4 -0
  38. package/modules/improvedigitalBidAdapter.js +29 -2
  39. package/modules/interactiveOffersBidAdapter.js +9 -6
  40. package/modules/jwplayerRtdProvider.js +71 -6
  41. package/modules/jwplayerRtdProvider.md +27 -11
  42. package/modules/kargoBidAdapter.js +2 -2
  43. package/modules/lunamediahbBidAdapter.js +32 -4
  44. package/modules/nextMillenniumBidAdapter.js +3 -1
  45. package/modules/oguryBidAdapter.js +14 -14
  46. package/modules/onetagBidAdapter.js +4 -2
  47. package/modules/pilotxBidAdapter.js +147 -0
  48. package/modules/pilotxBidAdapter.md +50 -0
  49. package/modules/priceFloors.js +2 -1
  50. package/modules/proxistoreBidAdapter.js +0 -2
  51. package/modules/pubmaticAnalyticsAdapter.js +16 -0
  52. package/modules/richaudienceBidAdapter.js +10 -4
  53. package/modules/riseBidAdapter.js +18 -7
  54. package/modules/rtbhouseBidAdapter.js +14 -4
  55. package/modules/rtdModule/index.js +14 -15
  56. package/modules/rubiconAnalyticsAdapter.js +8 -2
  57. package/modules/seedingAllianceBidAdapter.js +3 -3
  58. package/modules/sharethroughBidAdapter.js +12 -17
  59. package/modules/showheroes-bsBidAdapter.js +13 -2
  60. package/modules/sortableAnalyticsAdapter.js +5 -4
  61. package/modules/sovrnBidAdapter.js +93 -18
  62. package/modules/sovrnBidAdapter.md +80 -2
  63. package/modules/synacormediaBidAdapter.js +31 -10
  64. package/modules/tappxBidAdapter.js +8 -5
  65. package/modules/teadsBidAdapter.js +1 -2
  66. package/modules/undertoneBidAdapter.js +17 -1
  67. package/modules/userId/eids.js +7 -1
  68. package/modules/userId/userId.md +8 -0
  69. package/modules/viewability.js +177 -0
  70. package/modules/viewability.md +87 -0
  71. package/modules/weboramaRtdProvider.js +264 -34
  72. package/modules/weboramaRtdProvider.md +110 -40
  73. package/modules/welectBidAdapter.js +106 -0
  74. package/modules/yahoosspBidAdapter.js +2 -0
  75. package/package.json +2 -1
  76. package/src/adRendering.js +38 -0
  77. package/src/adloader.js +2 -1
  78. package/src/auction.js +103 -73
  79. package/src/bidderSettings.js +69 -0
  80. package/src/hook.js +5 -1
  81. package/src/prebid.js +19 -21
  82. package/src/secureCreatives.js +131 -47
  83. package/src/targeting.js +3 -2
  84. package/src/utils.js +13 -10
  85. package/test/helpers/syncPromise.js +71 -0
  86. package/test/spec/auctionmanager_spec.js +179 -15
  87. package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
  88. package/test/spec/modules/adbookpspBidAdapter_spec.js +17 -3
  89. package/test/spec/modules/adhashBidAdapter_spec.js +2 -2
  90. package/test/spec/modules/admanBidAdapter_spec.js +2 -2
  91. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
  92. package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
  93. package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
  94. package/test/spec/modules/asealBidAdapter_spec.js +144 -0
  95. package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
  96. package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
  97. package/test/spec/modules/colossussspBidAdapter_spec.js +5 -2
  98. package/test/spec/modules/compassBidAdapter_spec.js +1 -0
  99. package/test/spec/modules/conversantBidAdapter_spec.js +54 -2
  100. package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
  101. package/test/spec/modules/criteoIdSystem_spec.js +6 -3
  102. package/test/spec/modules/currency_spec.js +21 -6
  103. package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
  104. package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
  105. package/test/spec/modules/eids_spec.js +15 -0
  106. package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
  107. package/test/spec/modules/gnetBidAdapter_spec.js +6 -6
  108. package/test/spec/modules/gumgumBidAdapter_spec.js +46 -0
  109. package/test/spec/modules/idImportLibrary_spec.js +197 -10
  110. package/test/spec/modules/improvedigitalBidAdapter_spec.js +61 -0
  111. package/test/spec/modules/jwplayerRtdProvider_spec.js +195 -2
  112. package/test/spec/modules/kargoBidAdapter_spec.js +1 -1
  113. package/test/spec/modules/loglyliftBidAdapter_spec.js +1 -1
  114. package/test/spec/modules/lunamediahbBidAdapter_spec.js +27 -1
  115. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +1 -1
  116. package/test/spec/modules/oguryBidAdapter_spec.js +69 -3
  117. package/test/spec/modules/pilotxBidAdapter_spec.js +244 -0
  118. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
  119. package/test/spec/modules/realTimeDataModule_spec.js +67 -5
  120. package/test/spec/modules/richaudienceBidAdapter_spec.js +40 -0
  121. package/test/spec/modules/riseBidAdapter_spec.js +31 -5
  122. package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
  123. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +61 -1
  124. package/test/spec/modules/sharethroughBidAdapter_spec.js +91 -6
  125. package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
  126. package/test/spec/modules/sortableAnalyticsAdapter_spec.js +2 -3
  127. package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
  128. package/test/spec/modules/synacormediaBidAdapter_spec.js +70 -0
  129. package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
  130. package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
  131. package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
  132. package/test/spec/modules/userId_spec.js +68 -19
  133. package/test/spec/modules/viewability_spec.js +280 -0
  134. package/test/spec/modules/weboramaRtdProvider_spec.js +536 -20
  135. package/test/spec/modules/welectBidAdapter_spec.js +211 -0
  136. package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
  137. package/test/spec/unit/core/bidderSettings_spec.js +123 -0
  138. package/test/spec/unit/pbjs_api_spec.js +21 -8
  139. package/test/spec/unit/secureCreatives_spec.js +143 -24
@@ -12,6 +12,20 @@ const FRAME_USER_SYNC = 'https://cdn.undertone.com/js/usersync.html';
12
12
  const PIXEL_USER_SYNC_1 = 'https://usr.undertone.com/userPixel/syncOne?id=1&of=2';
13
13
  const PIXEL_USER_SYNC_2 = 'https://usr.undertone.com/userPixel/syncOne?id=2&of=2';
14
14
 
15
+ function getBidFloor(bidRequest, mediaType) {
16
+ if (typeof bidRequest.getFloor !== 'function') {
17
+ return 0;
18
+ }
19
+
20
+ const floor = bidRequest.getFloor({
21
+ currency: 'USD',
22
+ mediaType: mediaType,
23
+ size: '*'
24
+ });
25
+
26
+ return (floor && floor.currency === 'USD' && floor.floor) || 0;
27
+ }
28
+
15
29
  function getCanonicalUrl() {
16
30
  try {
17
31
  let doc = window.top.document;
@@ -134,6 +148,9 @@ export const spec = {
134
148
  params: bidReq.params
135
149
  };
136
150
  const videoMediaType = deepAccess(bidReq, 'mediaTypes.video');
151
+ const mediaType = videoMediaType ? VIDEO : BANNER;
152
+ bid.mediaType = mediaType;
153
+ bid.bidfloor = getBidFloor(bidReq, mediaType);
137
154
  if (videoMediaType) {
138
155
  bid.video = {
139
156
  playerSize: deepAccess(bidReq, 'mediaTypes.video.playerSize') || null,
@@ -142,7 +159,6 @@ export const spec = {
142
159
  maxDuration: deepAccess(bidReq, 'params.video.maxDuration') || null,
143
160
  skippable: deepAccess(bidReq, 'params.video.skippable') || null
144
161
  };
145
- bid.mediaType = 'video';
146
162
  }
147
163
  payload['x-ut-hb-params'].push(bid);
148
164
  });
@@ -257,7 +257,13 @@ const USER_IDS_CONFIG = {
257
257
  'connectId': {
258
258
  source: 'yahoo.com',
259
259
  atype: 3
260
- }
260
+ },
261
+
262
+ // Adquery ID
263
+ 'qid': {
264
+ source: 'adquery.io',
265
+ atype: 1
266
+ },
261
267
  };
262
268
 
263
269
  // this function will create an eid object for the given UserId sub-module
@@ -297,6 +297,14 @@ pbjs.setConfig({
297
297
  type: 'html5',
298
298
  expires: 15
299
299
  }
300
+ }
301
+ {
302
+ name: "qid",
303
+ storage: {
304
+ type: "html5",
305
+ name: "qid",
306
+ expires: 365
307
+ }
300
308
  }],
301
309
  syncDelay: 5000
302
310
  }
@@ -0,0 +1,177 @@
1
+ import { logWarn, logInfo, isStr, isFn, triggerPixel, insertHtmlIntoIframe } from '../src/utils.js';
2
+ import { getGlobal } from '../src/prebidGlobal.js';
3
+ import find from 'core-js-pure/features/array/find.js';
4
+
5
+ export const MODULE_NAME = 'viewability';
6
+
7
+ export function init() {
8
+ (getGlobal()).viewability = {
9
+ startMeasurement: startMeasurement,
10
+ stopMeasurement: stopMeasurement,
11
+ };
12
+
13
+ listenMessagesFromCreative();
14
+ }
15
+
16
+ const observers = {};
17
+
18
+ function isValid(vid, element, tracker, criteria) {
19
+ if (!element) {
20
+ logWarn(`${MODULE_NAME}: no html element provided`);
21
+ return false;
22
+ }
23
+
24
+ let validTracker = tracker &&
25
+ ((tracker.method === 'img' && isStr(tracker.value)) ||
26
+ (tracker.method === 'js' && isStr(tracker.value)) ||
27
+ (tracker.method === 'callback' && isFn(tracker.value)));
28
+
29
+ if (!validTracker) {
30
+ logWarn(`${MODULE_NAME}: invalid tracker`, tracker);
31
+ return false;
32
+ }
33
+
34
+ if (!criteria || !criteria.inViewThreshold || !criteria.timeInView) {
35
+ logWarn(`${MODULE_NAME}: missing criteria`, criteria);
36
+ return false;
37
+ }
38
+
39
+ if (!vid || observers[vid]) {
40
+ logWarn(`${MODULE_NAME}: must provide an unregistered vid`, vid);
41
+ return false;
42
+ }
43
+
44
+ return true;
45
+ }
46
+
47
+ function stopObserving(observer, vid, element) {
48
+ observer.unobserve(element);
49
+ observers[vid].done = true;
50
+ }
51
+
52
+ function fireViewabilityTracker(element, tracker) {
53
+ switch (tracker.method) {
54
+ case 'img':
55
+ triggerPixel(tracker.value, () => {
56
+ logInfo(`${MODULE_NAME}: viewability pixel fired`, tracker.value);
57
+ });
58
+ break;
59
+ case 'js':
60
+ insertHtmlIntoIframe(`<script src="${tracker.value}"></script>`);
61
+ break;
62
+ case 'callback':
63
+ tracker.value(element);
64
+ break;
65
+ }
66
+ }
67
+
68
+ function viewabilityCriteriaMet(observer, vid, element, tracker) {
69
+ stopObserving(observer, vid, element);
70
+ fireViewabilityTracker(element, tracker);
71
+ }
72
+
73
+ /**
74
+ * Start measuring viewability of an element
75
+ * @typedef {{ method: string='img','js','callback', value: string|function }} ViewabilityTracker { method: 'img', value: 'http://my.tracker/123' }
76
+ * @typedef {{ inViewThreshold: number, timeInView: number }} ViewabilityCriteria { inViewThreshold: 0.5, timeInView: 1000 }
77
+ * @param {string} vid unique viewability identifier
78
+ * @param {HTMLElement} element
79
+ * @param {ViewabilityTracker} tracker
80
+ * @param {ViewabilityCriteria} criteria
81
+ */
82
+ export function startMeasurement(vid, element, tracker, criteria) {
83
+ if (!isValid(vid, element, tracker, criteria)) {
84
+ return;
85
+ }
86
+
87
+ const options = {
88
+ root: null,
89
+ rootMargin: '0px',
90
+ threshold: criteria.inViewThreshold,
91
+ };
92
+
93
+ let observer;
94
+ let viewable = false;
95
+ let stateChange = (entries) => {
96
+ viewable = entries[0].isIntersecting;
97
+
98
+ if (viewable) {
99
+ observers[vid].timeoutId = window.setTimeout(() => {
100
+ viewabilityCriteriaMet(observer, vid, element, tracker);
101
+ }, criteria.timeInView);
102
+ } else if (observers[vid].timeoutId) {
103
+ window.clearTimeout(observers[vid].timeoutId);
104
+ }
105
+ };
106
+
107
+ observer = new IntersectionObserver(stateChange, options);
108
+ observers[vid] = {
109
+ observer: observer,
110
+ element: element,
111
+ timeoutId: null,
112
+ done: false,
113
+ };
114
+
115
+ observer.observe(element);
116
+
117
+ logInfo(`${MODULE_NAME}: startMeasurement called with:`, arguments);
118
+ }
119
+
120
+ /**
121
+ * Stop measuring viewability of an element
122
+ * @param {string} vid unique viewability identifier
123
+ */
124
+ export function stopMeasurement(vid) {
125
+ if (!vid || !observers[vid]) {
126
+ logWarn(`${MODULE_NAME}: must provide a registered vid`, vid);
127
+ return;
128
+ }
129
+
130
+ observers[vid].observer.unobserve(observers[vid].element);
131
+ if (observers[vid].timeoutId) {
132
+ window.clearTimeout(observers[vid].timeoutId);
133
+ }
134
+
135
+ // allow the observer under this vid to be created again
136
+ if (!observers[vid].done) {
137
+ delete observers[vid];
138
+ }
139
+ }
140
+
141
+ function listenMessagesFromCreative() {
142
+ window.addEventListener('message', receiveMessage, false);
143
+ }
144
+
145
+ /**
146
+ * Recieve messages from creatives
147
+ * @param {MessageEvent} evt
148
+ */
149
+ export function receiveMessage(evt) {
150
+ var key = evt.message ? 'message' : 'data';
151
+ var data = {};
152
+ try {
153
+ data = JSON.parse(evt[key]);
154
+ } catch (e) {
155
+ return;
156
+ }
157
+
158
+ if (!data || data.message !== 'Prebid Viewability') {
159
+ return;
160
+ }
161
+
162
+ switch (data.action) {
163
+ case 'startMeasurement':
164
+ let element = data.elementId && document.getElementById(data.elementId);
165
+ if (!element) {
166
+ element = find(document.getElementsByTagName('IFRAME'), iframe => (iframe.contentWindow || iframe.contentDocument.defaultView) == evt.source);
167
+ }
168
+
169
+ startMeasurement(data.vid, element, data.tracker, data.criteria);
170
+ break;
171
+ case 'stopMeasurement':
172
+ stopMeasurement(data.vid);
173
+ break;
174
+ }
175
+ }
176
+
177
+ init();
@@ -0,0 +1,87 @@
1
+ # Overview
2
+
3
+ Module Name: Viewability
4
+
5
+ Purpose: Track when a given HTML element becomes viewable
6
+
7
+ Maintainer: atrajkovic@magnite.com
8
+
9
+ # Configuration
10
+
11
+ Module does not need any configuration, as long as you include it in your PBJS bundle.
12
+ Viewability module has only two functions `startMeasurement` and `stopMeasurement` which can be used to enable more complex viewability measurements. Since it allows tracking from within creative (possibly inside a safe frame) this module registers a message listener, for messages with a format that is described bellow.
13
+
14
+ ## `startMeasurement`
15
+
16
+ | startMeasurement Arg Object | Scope | Type | Description | Example |
17
+ | --------------------- | -------- | ------------ | -------------------------------------------------------------------------------- | --------- |
18
+ | vid | Required | String | Unique viewability identifier, used to reference particular observer | `"ae0f9"` |
19
+ | element | Required | HTMLElement | Reference to an HTML element that needs to be tracked | `document.getElementById('test_div')` |
20
+ | tracker | Required | ViewabilityTracker | How viewaility event is communicated back to the parties of interest | `{ method: 'img', value: 'http://my.tracker/123' }` |
21
+ | criteria | Required | ViewabilityCriteria| Defines custom viewability criteria using the threshold and duration provided | `{ inViewThreshold: 0.5, timeInView: 1000 }` |
22
+
23
+ | ViewabilityTracker | Scope | Type | Description | Example |
24
+ | --------------------- | -------- | ------------ | -------------------------------------------------------------------------------- | --------- |
25
+ | method | Required | String | Type of method for Tracker | `'img' OR 'js' OR 'callback'` |
26
+ | value | Required | String | URL string for 'img' and 'js' Trackers, or a function for 'callback' Tracker | `'http://my.tracker/123'` |
27
+
28
+ | ViewabilityCriteria | Scope | Type | Description | Example |
29
+ | --------------------- | -------- | ------------ | -------------------------------------------------------------------------------- | --------- |
30
+ | inViewThreshold | Required | Number | Represents a percentage threshold for the Element to be registered as in view | `0.5` |
31
+ | timeInView | Required | Number | Number of milliseconds that a given element needs to be in view continuously, above the threshold | `1000` |
32
+
33
+ ## Please Note:
34
+ - `vid` allows for multiple trackers, with different criteria to be registered for a given HTML element, independently. It's not autogenerated by `startMeasurement()`, it needs to be provided by the caller so that it doesn't have to be posted back to the source iframe (in case viewability is started from within the creative).
35
+ - In case of 'callback' method, HTML element is being passed back to the callback function.
36
+ - When a tracker needs to be started, without direct access to pbjs, postMessage mechanism can be used to invoke `startMeasurement`, with a following payload: `vid`, `tracker` and `criteria` as described above, but also with `message: 'Prebid Viewability'` and `action: 'startMeasurement'`. Optionally payload can provide `elementId`, if available at that time (for ad servers where name of the iframe is known, or adservers that render outside an iframe). If `elementId` is not provided, viewability module will try to find the iframe that corresponds to the message source.
37
+
38
+
39
+ ## `stopMeasurement`
40
+
41
+ | stopMeasurement Arg Object | Scope | Type | Description | Example |
42
+ | --------------------- | -------- | ------------ | -------------------------------------------------------------------------------- | --------- |
43
+ | vid | Required | String | Unique viewability identifier, referencing an already started viewability tracker. | `"ae0f9"` |
44
+
45
+ ## Please Note:
46
+ - When a tracker needs to be stopped, without direct access to pbjs, postMessage mechanism can be used here as well. To invoke `stopMeasurement`, you provide the payload with `vid`, `message: 'Prebid Viewability'` and `action: 'stopMeasurement`. Check the example bellow.
47
+
48
+ # Examples
49
+
50
+ ## Example of starting a viewability measurement, when you have direct access to pbjs
51
+ ```
52
+ pbjs.viewability.startMeasurement(
53
+ 'ae0f9',
54
+ document.getElementById('test_div'),
55
+ { method: 'img', value: 'http://my.tracker/123' },
56
+ { inViewThreshold: 0.5, timeInView: 1000 }
57
+ );
58
+ ```
59
+
60
+ ## Example of starting a viewability measurement from within a rendered creative
61
+ ```
62
+ let viewabilityRecord = {
63
+ vid: 'ae0f9',
64
+ tracker: { method: 'img', value: 'http://my.tracker/123'},
65
+ criteria: { inViewThreshold: 0.5, timeInView: 1000 },
66
+ message: 'Prebid Viewability',
67
+ action: 'startMeasurement'
68
+ }
69
+
70
+ window.parent.postMessage(JSON.stringify(viewabilityRecord), '*');
71
+ ```
72
+
73
+ ## Example of stopping the viewability measurement, when you have direct access to pbjs
74
+ ```
75
+ pbjs.viewability.stopMeasurement('ae0f9');
76
+ ```
77
+
78
+ ## Example of stopping the viewability measurement from within a rendered creative
79
+ ```
80
+ let viewabilityRecord = {
81
+ vid: 'ae0f9',
82
+ message: 'Prebid Viewability',
83
+ action: 'stopMeasurement'
84
+ }
85
+
86
+ window.parent.postMessage(JSON.stringify(viewabilityRecord), '*');
87
+ ```