prebid-universal-creative 1.12.0 → 1.14.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.
@@ -3,8 +3,12 @@
3
3
  * values in native creative templates.
4
4
  */
5
5
 
6
+ import { addNativeClickTrackers, fireNativeImpressionTrackers } from './nativeORTBTrackerManager';
6
7
  import { sendRequest, loadScript } from './utils';
8
+ import {prebidMessenger} from './messaging.js';
9
+ import { newEnvironment } from './environment.js';
7
10
 
11
+ const envionment = newEnvironment(window);
8
12
  /*
9
13
  * Native asset->key mapping from Prebid.js/src/constants.json
10
14
  * https://github.com/prebid/Prebid.js/blob/8635c91942de9df4ec236672c39b19448545a812/src/constants.json#L67
@@ -56,17 +60,26 @@ const assetTypeMapping = {
56
60
  const DEFAULT_CACHE_HOST = 'prebid.adnxs.com';
57
61
  const DEFAULT_CACHE_PATH = '/pbc/v1/cache';
58
62
 
59
- export function newNativeAssetManager(win) {
63
+ export function newNativeAssetManager(win, pubUrl) {
64
+ const sendMessage = prebidMessenger(pubUrl, win);
60
65
  let callback;
61
66
  let errorCountEscapeHatch = 0;
67
+ let cancelMessageListener;
68
+
69
+ function stopListening() {
70
+ if (cancelMessageListener != null) {
71
+ cancelMessageListener();
72
+ cancelMessageListener = null;
73
+ }
74
+ }
62
75
 
63
76
  function getCacheEndpoint(cacheHost, cachePath) {
64
77
  let host = (typeof cacheHost === 'undefined' || cacheHost === "") ? DEFAULT_CACHE_HOST : cacheHost;
65
78
  let path = (typeof cachePath === 'undefined' || cachePath === "") ? DEFAULT_CACHE_PATH : cachePath;
66
-
79
+
67
80
  return `https://${host}${path}`;
68
81
  }
69
-
82
+
70
83
  function parseResponse(response) {
71
84
  let bidObject;
72
85
  try {
@@ -76,7 +89,7 @@ export function newNativeAssetManager(win) {
76
89
  }
77
90
  return bidObject;
78
91
  }
79
-
92
+
80
93
  function transformToPrebidKeys(adMarkup) {
81
94
  let assets = [];
82
95
  let clicktrackers;
@@ -105,7 +118,7 @@ export function newNativeAssetManager(win) {
105
118
  'key' : 'title',
106
119
  'value' : asset.title.text
107
120
  })
108
- }
121
+ }
109
122
  })
110
123
 
111
124
  if (adMarkup.link) {
@@ -121,7 +134,8 @@ export function newNativeAssetManager(win) {
121
134
  return {
122
135
  assets,
123
136
  clicktrackers,
124
- 'imptrackers' : adMarkup.imptrackers
137
+ 'imptrackers' : adMarkup.imptrackers,
138
+ 'eventtrackers': adMarkup.eventtrackers
125
139
  }
126
140
  }
127
141
 
@@ -137,8 +151,9 @@ export function newNativeAssetManager(win) {
137
151
  win.document.body.innerHTML = newHtml;
138
152
 
139
153
  callback && callback({
140
- clickTrackers: data.clicktrackers,
141
- impTrackers: data.imptrackers
154
+ clickTrackers: data.clicktrackers,
155
+ impTrackers: data.imptrackers,
156
+ eventtrackers: data.eventtrackers
142
157
  });
143
158
  } else {
144
159
  // TODO Shall we just write the markup in the page
@@ -151,13 +166,17 @@ export function newNativeAssetManager(win) {
151
166
  }
152
167
 
153
168
  function loadMobileAssets(tagData, cb) {
154
- const placeholders = scanForPlaceholders();
169
+ const placeholders = scanDOMForPlaceHolders();
155
170
  if (placeholders.length > 0) {
156
171
  callback = cb;
157
172
  requestAssetsFromCache(tagData);
158
173
  }
159
174
  }
160
175
 
176
+ function hasPbNativeData() {
177
+ return typeof win.pbNativeData !== 'undefined'
178
+ }
179
+
161
180
  /*
162
181
  * Entry point to search for placeholderes and set up postmessage roundtrip
163
182
  * to retrieve native assets. Looks for placeholders for the given adId and
@@ -166,43 +185,47 @@ export function newNativeAssetManager(win) {
166
185
  * to retrieve native assets that have a value on the corresponding bid
167
186
  */
168
187
  function loadAssets(adId, cb) {
169
- const placeholders = scanForPlaceholders(adId), flag = (typeof win.pbNativeData !== 'undefined');
188
+ const placeholders = scanDOMForPlaceHolders(adId);
170
189
 
171
- if (flag && win.pbNativeData.hasOwnProperty('assetsToReplace')) {
190
+ if (hasPbNativeData() && win.pbNativeData.hasOwnProperty('assetsToReplace')) {
172
191
  win.pbNativeData.assetsToReplace.forEach((asset) => {
173
192
  const key = (asset.match(/hb_native_/i)) ? asset : NATIVE_KEYS[asset];
174
193
  if (key) {placeholders.push(key);}
175
194
  });
176
195
  }
177
196
 
178
- if (flag && win.pbNativeData.hasOwnProperty('requestAllAssets') && win.pbNativeData.requestAllAssets) {
197
+ if (hasPbNativeData() && win.pbNativeData.hasOwnProperty('requestAllAssets') && win.pbNativeData.requestAllAssets) {
179
198
  callback = cb;
180
- requestAllAssets(adId);
199
+ cancelMessageListener = requestAllAssets(adId);
181
200
  } else if (placeholders.length > 0) {
182
201
  callback = cb;
183
- requestAssets(adId, placeholders);
184
- }
202
+ cancelMessageListener = requestAssets(adId, placeholders);
203
+ }
204
+ }
205
+
206
+ function placeholderFor(key, adId) {
207
+ return (adId && !hasPbNativeData()) ? `${key}:${adId}` : ((hasPbNativeData()) ? `##${key}##` : key)
208
+ }
209
+
210
+ function scanForPlaceHolders(adId, ...markupFragments) {
211
+ return Object.values(NATIVE_KEYS)
212
+ .reduce((found, key) => {
213
+ const placeholder = placeholderFor(key, adId);
214
+ for (const mkup of markupFragments.filter(Boolean)) {
215
+ if (mkup.indexOf(placeholder) >= 0) {
216
+ found.push(key);
217
+ break;
218
+ }
219
+ }
220
+ return found;
221
+ }, []);
185
222
  }
186
223
 
187
224
  /*
188
- * Searches the DOM for placeholder values sent in by Prebid Native
225
+ * Searches the DOM for legacy placeholder values sent in by Prebid Native
189
226
  */
190
- function scanForPlaceholders(adId) {
191
- let placeholders = [];
192
- const doc = win.document;
193
- const flag = (typeof win.pbNativeData !== 'undefined');
194
-
195
- Object.keys(NATIVE_KEYS).forEach(key => {
196
- const placeholderKey = NATIVE_KEYS[key];
197
- const placeholder = (adId && !flag) ? `${placeholderKey}:${adId}` : `${placeholderKey}`;
198
- const placeholderIndex = (~doc.body.innerHTML.indexOf(placeholder)) ? doc.body.innerHTML.indexOf(placeholder) : (doc.head.innerHTML && doc.head.innerHTML.indexOf(placeholder));
199
-
200
- if (~placeholderIndex) {
201
- placeholders.push(placeholderKey);
202
- }
203
- });
204
-
205
- return placeholders;
227
+ function scanDOMForPlaceHolders(adId) {
228
+ return scanForPlaceHolders(adId, win.document.body.innerHTML, win.document.head.innerHTML);
206
229
  }
207
230
 
208
231
  /*
@@ -210,8 +233,6 @@ export function newNativeAssetManager(win) {
210
233
  * creative template, and setups up a listener for when Prebid responds.
211
234
  */
212
235
  function requestAssets(adId, assets) {
213
- win.addEventListener('message', replaceAssets, false);
214
-
215
236
  const message = {
216
237
  message: 'Prebid Native',
217
238
  action: 'assetRequest',
@@ -219,8 +240,7 @@ export function newNativeAssetManager(win) {
219
240
  assets,
220
241
  };
221
242
 
222
-
223
- win.parent.postMessage(JSON.stringify(message), '*');
243
+ return sendMessage(message, replaceAssets);
224
244
  }
225
245
 
226
246
  /*
@@ -228,29 +248,26 @@ export function newNativeAssetManager(win) {
228
248
  * creative template, and setups up a listener for when Prebid responds.
229
249
  */
230
250
  function requestAllAssets(adId) {
231
- win.addEventListener('message', replaceAssets, false);
232
-
233
251
  const message = {
234
252
  message: 'Prebid Native',
235
253
  action: 'allAssetRequest',
236
254
  adId,
237
255
  };
238
-
239
- win.parent.postMessage(JSON.stringify(message), '*');
256
+ return sendMessage(message, replaceAssets);
240
257
  }
241
258
 
242
259
  /*
243
260
  * Sends postmessage to Prebid for native resize
244
261
  */
245
- function requestHeightResize(adId, height) {
262
+ function requestHeightResize(adId, height, width) {
246
263
  const message = {
247
264
  message: 'Prebid Native',
248
265
  action: 'resizeNativeHeight',
249
266
  adId,
250
267
  height,
268
+ width
251
269
  };
252
-
253
- win.parent.postMessage(JSON.stringify(message), '*');
270
+ sendMessage(message);
254
271
  }
255
272
 
256
273
  /*
@@ -267,7 +284,7 @@ export function newNativeAssetManager(win) {
267
284
  * if for some reason Prebid never responds with the native assets,
268
285
  * get rid of this listener because other messages won't stop coming
269
286
  */
270
- win.removeEventListener('message', replaceAssets);
287
+ stopListening();
271
288
  }
272
289
  return;
273
290
  }
@@ -275,69 +292,160 @@ export function newNativeAssetManager(win) {
275
292
  if (data.message === 'assetResponse') {
276
293
  const body = win.document.body.innerHTML;
277
294
  const head = win.document.head.innerHTML;
278
- const flag = (typeof win.pbNativeData !== 'undefined');
279
295
 
280
- if (flag && data.adId !== win.pbNativeData.adId) return;
296
+ if (hasPbNativeData() && data.adId !== win.pbNativeData.adId) return;
281
297
 
282
298
  if (head) win.document.head.innerHTML = replace(head, data);
283
299
 
284
- if ((data.hasOwnProperty('rendererUrl') && data.rendererUrl) || (flag && win.pbNativeData.hasOwnProperty('rendererUrl'))) {
300
+ data.assets = data.assets || [];
301
+ let renderPayload = data.assets;
302
+ if (data.ortb) {
303
+ renderPayload.ortb = data.ortb;
304
+ callback = () => {
305
+ fireNativeImpressionTrackers(data.adId, sendMessage);
306
+ addNativeClickTrackers(data.adId, data.ortb, sendMessage);
307
+ }
308
+ }
309
+
310
+ if ((data.hasOwnProperty('rendererUrl') && data.rendererUrl) || (hasPbNativeData() && win.pbNativeData.hasOwnProperty('rendererUrl'))) {
285
311
  if (win.renderAd) {
286
- const newHtml = (win.renderAd && win.renderAd(data.assets)) || '';
312
+ const newHtml = (win.renderAd && win.renderAd(renderPayload)) || '';
287
313
 
288
- win.document.body.innerHTML = body + newHtml;
289
- callback && callback();
290
- win.removeEventListener('message', replaceAssets);
291
- requestHeightResize(data.adId, (document.body.clientHeight || document.body.offsetHeight));
314
+ renderAd(newHtml, data);
292
315
  } else if (document.getElementById('pb-native-renderer')) {
293
316
  document.getElementById('pb-native-renderer').addEventListener('load', function() {
294
- const newHtml = (win.renderAd && win.renderAd(data.assets)) || '';
317
+ const newHtml = (win.renderAd && win.renderAd(renderPayload)) || '';
295
318
 
296
- win.document.body.innerHTML = body + newHtml;
297
- callback && callback();
298
- win.removeEventListener('message', replaceAssets);
299
- requestHeightResize(data.adId, (document.body.clientHeight || document.body.offsetHeight));
319
+ renderAd(newHtml, data);
300
320
  });
301
321
  } else {
302
- loadScript(win, ((flag && win.pbNativeData.hasOwnProperty('rendererUrl') && win.pbNativeData.rendererUrl) || data.rendererUrl), function() {
303
- const newHtml = (win.renderAd && win.renderAd(data.assets)) || '';
322
+ loadScript(win, ((hasPbNativeData() && win.pbNativeData.hasOwnProperty('rendererUrl') && win.pbNativeData.rendererUrl) || data.rendererUrl), function() {
323
+ const newHtml = (win.renderAd && win.renderAd(renderPayload)) || '';
304
324
 
305
- win.document.body.innerHTML = body + newHtml;
306
- callback && callback();
307
- win.removeEventListener('message', replaceAssets);
308
- requestHeightResize(data.adId, (document.body.clientHeight || document.body.offsetHeight));
325
+ renderAd(newHtml, data);
309
326
  })
310
327
  }
311
- } else if ((data.hasOwnProperty('adTemplate') && data.adTemplate)||(flag && win.pbNativeData.hasOwnProperty('adTemplate'))) {
312
- const template = (flag && win.pbNativeData.hasOwnProperty('adTemplate') && win.pbNativeData.adTemplate) || data.adTemplate;
328
+ } else if ((data.hasOwnProperty('adTemplate') && data.adTemplate)||(hasPbNativeData() && win.pbNativeData.hasOwnProperty('adTemplate'))) {
329
+ const template = (hasPbNativeData() && win.pbNativeData.hasOwnProperty('adTemplate') && win.pbNativeData.adTemplate) || data.adTemplate;
313
330
  const newHtml = replace(template, data);
314
- win.document.body.innerHTML = body + newHtml;
315
- callback && callback();
316
- win.removeEventListener('message', replaceAssets);
317
- requestHeightResize(data.adId, (document.body.clientHeight || document.body.offsetHeight));
331
+
332
+ renderAd(newHtml, data);
318
333
  } else {
319
334
  const newHtml = replace(body, data);
320
335
 
321
336
  win.document.body.innerHTML = newHtml;
322
337
  callback && callback();
323
- win.removeEventListener('message', replaceAssets);
338
+ stopListening();
324
339
  }
325
340
  }
326
341
  }
327
342
 
343
+ /** This function returns the element that contains the current iframe. */
344
+ function getCurrentFrameContainer(win) {
345
+ let currentWindow = win;
346
+ let currentParentWindow;
347
+
348
+ while (currentWindow !== win.top) {
349
+ currentParentWindow = currentWindow.parent;
350
+ if (!currentParentWindow.frames || !currentParentWindow.frames.length) return null;
351
+ for (let idx = 0; idx < currentParentWindow.frames.length; idx++)
352
+ if (currentParentWindow.frames[idx] === currentWindow) {
353
+ if (!currentParentWindow.document) return null;
354
+ for (let frameElement of currentParentWindow.document.getElementsByTagName('iframe')) {
355
+ if (!frameElement.contentWindow) return null;
356
+ if (frameElement.contentWindow === currentWindow) {
357
+ return frameElement.parentElement;
358
+ }
359
+ }
360
+ }
361
+ }
362
+ }
363
+
364
+ function renderAd(html, bid) {
365
+ // if the current iframe is not a safeframe, try to set the
366
+ // current iframe width to the width of the container. This
367
+ // is to handle the case where the native ad is rendered inside
368
+ // a GAM display ad.
369
+ if (!envionment.isSafeFrame()) {
370
+ let iframeContainer = getCurrentFrameContainer(win);
371
+ if (iframeContainer && iframeContainer.children && iframeContainer.children[0]) {
372
+ const iframe = iframeContainer.children[0];
373
+ if (iframe.width === '1' && iframe.height === '1') {
374
+ let width = iframeContainer.getBoundingClientRect().width;
375
+ win.document.body.style.width = `${width}px`;
376
+ }
377
+ }
378
+ } else {
379
+ document.body.style.width = Math.ceil(win.$sf.ext.geom().self.b) + 'px';
380
+ }
381
+ win.document.body.innerHTML += html;
382
+ callback && callback();
383
+ win.removeEventListener('message', replaceAssets);
384
+ stopListening();
385
+ requestHeightResize(bid.adId, (document.body.clientHeight || document.body.offsetHeight), document.body.clientWidth);
386
+
387
+ if (typeof window.postRenderAd === 'function') {
388
+ window.postRenderAd(bid);
389
+ }
390
+ }
391
+
392
+ function replaceORTBAssetsAndLinks(html, ortb) {
393
+
394
+ const getAssetValue = (asset) => {
395
+ if (asset.img) {
396
+ return asset.img.url;
397
+ }
398
+ if (asset.data) {
399
+ return asset.data.value;
400
+ }
401
+ if (asset.title) {
402
+ return asset.title.text;
403
+ }
404
+ if (asset.video) {
405
+ return asset.video.vasttag;
406
+ }
407
+ return ''
408
+ }
409
+
410
+ ortb.assets.forEach(asset => {
411
+ html = html.replace(`##hb_native_asset_id_${asset.id}##`, getAssetValue(asset));
412
+ if (asset.link && asset.link.url) {
413
+ html = html.replace(`##hb_native_asset_link_id_${asset.id}##`, asset.link.url);
414
+ }
415
+ });
416
+
417
+ html = html.replaceAll(/##hb_native_asset_id_\d+##/gm, '');
418
+
419
+ if (ortb.privacy) {
420
+ html = html.replace("##hb_native_privacy##", ortb.privacy);
421
+ }
422
+
423
+ if (ortb.link) {
424
+ html = html.replaceAll("##hb_native_linkurl##", ortb.link.url);
425
+ }
426
+
427
+ return html;
428
+ }
429
+
328
430
  /**
329
431
  * Replaces occurrences of native placeholder values with their actual values
330
432
  * in the given document.
433
+ * If there's no actual value, the placeholder gets replaced by an empty string.
331
434
  */
332
- function replace(document, { assets, adId }) {
333
- let html = document;
435
+ function replace(html, { assets, ortb, adId }) {
436
+ if (ortb) {
437
+ html = replaceORTBAssetsAndLinks(html, ortb);
438
+ } else if (!Array.isArray(assets)) {
439
+ return html;
440
+ }
441
+ assets = assets || [];
334
442
 
335
- (assets || []).forEach(asset => {
336
- const flag = (typeof win.pbNativeData !== 'undefined');
337
- const searchString = (adId && !flag) ? `${NATIVE_KEYS[asset.key]}:${adId}` : ((flag) ? '##'+`${NATIVE_KEYS[asset.key]}`+'##' : `${NATIVE_KEYS[asset.key]}`);
443
+ scanForPlaceHolders(adId, html).forEach(placeholder => {
444
+ const searchString = placeholderFor(placeholder, adId);
338
445
  const searchStringRegex = new RegExp(searchString, 'g');
339
- html = html.replace(searchStringRegex, asset.value);
340
- });
446
+ const fittingAsset = assets.find(asset => placeholder === NATIVE_KEYS[asset.key]);
447
+ html = html.replace(searchStringRegex, fittingAsset ? fittingAsset.value : '');
448
+ })
341
449
 
342
450
  return html;
343
451
  }
@@ -0,0 +1,32 @@
1
+ import { loadScript, triggerPixel } from "./utils";
2
+
3
+ const AD_ANCHOR_CLASS_NAME = 'pb-click';
4
+ const ASSET_ID_ELEMENT_ATTRIBUTE = 'hb_native_asset_id';
5
+
6
+ export function fireNativeImpressionTrackers(adId, sendMessage) {
7
+ const message = {
8
+ message: 'Prebid Native',
9
+ action: 'fireNativeImpressionTrackers',
10
+ adId
11
+ };
12
+ sendMessage(message);
13
+ }
14
+
15
+ export function addNativeClickTrackers(adId, ortb, sendMessage) {
16
+ const message = {
17
+ message: 'Prebid Native',
18
+ action: 'click',
19
+ adId
20
+ };
21
+ const adElements = document.getElementsByClassName(AD_ANCHOR_CLASS_NAME) || [];
22
+ // get all assets that have 'link' property, map asset.id -> asset.link
23
+ for (let i = 0; i < adElements.length; i++) {
24
+ adElements[i].addEventListener('click', (event) => {
25
+ let targetElement = event.target;
26
+ // check if clicked element is associated with any native asset (look for 'hb_native_asset_id' attribute)
27
+ let assetId = targetElement && targetElement.getAttribute(ASSET_ID_ELEMENT_ATTRIBUTE);
28
+ message.assetId = assetId;
29
+ sendMessage(message);
30
+ }, true);
31
+ }
32
+ }
@@ -1,14 +1,14 @@
1
1
  /*
2
2
  * Script to handle firing impression and click trackers from native teamplates
3
3
  */
4
- import { parseUrl, triggerPixel, transformAuctionTargetingData } from './utils';
5
- import { newNativeAssetManager } from './nativeAssetManager';
4
+ import {newNativeAssetManager} from './nativeAssetManager';
5
+ import {prebidMessenger} from './messaging.js';
6
6
 
7
7
  const AD_ANCHOR_CLASS_NAME = 'pb-click';
8
8
  const AD_DATA_ADID_ATTRIBUTE = 'pbAdId';
9
9
 
10
10
  export function newNativeRenderManager(win) {
11
- let publisherDomain;
11
+ let sendMessage;
12
12
 
13
13
 
14
14
  function findAdElements(className) {
@@ -30,8 +30,7 @@ export function newNativeRenderManager(win) {
30
30
  if (action === 'click') {
31
31
  message.action = 'click';
32
32
  }
33
-
34
- win.parent.postMessage(JSON.stringify(message), publisherDomain);
33
+ sendMessage(message);
35
34
  }
36
35
  }
37
36
 
@@ -51,12 +50,10 @@ export function newNativeRenderManager(win) {
51
50
  // START OF MAIN CODE
52
51
  let renderNativeAd = function(nativeTag) {
53
52
  window.pbNativeData = nativeTag;
54
- const targetingData = transformAuctionTargetingData(nativeTag);
55
- const nativeAssetManager = newNativeAssetManager(window);
53
+ sendMessage = prebidMessenger(nativeTag.pubUrl, win);
54
+ const nativeAssetManager = newNativeAssetManager(window, nativeTag.pubUrl);
56
55
 
57
56
  if (nativeTag.hasOwnProperty('adId')) {
58
- let parsedUrl = parseUrl(window.pbNativeData.pubUrl);
59
- publisherDomain = parsedUrl.protocol + '://' + parsedUrl.host;
60
57
 
61
58
  if (nativeTag.hasOwnProperty('rendererUrl') && !nativeTag.rendererUrl.match(/##.*##/i)) {
62
59
  const scr = document.createElement('SCRIPT');
@@ -64,9 +61,10 @@ export function newNativeRenderManager(win) {
64
61
  scr.id = 'pb-native-renderer';
65
62
  document.body.appendChild(scr);
66
63
  }
67
- nativeAssetManager.loadAssets(nativeTag.adId,fireNativeCallback);
68
- fireNativeCallback();
69
- fireNativeImpTracker(nativeTag.adId);
64
+ nativeAssetManager.loadAssets(nativeTag.adId, () => {
65
+ fireNativeImpTracker(nativeTag.adId);
66
+ fireNativeCallback();
67
+ });
70
68
  } else {
71
69
  console.warn('Prebid Native Tag object was missing \'adId\'.');
72
70
  }
@@ -3,12 +3,13 @@
3
3
  */
4
4
  import { parseUrl, triggerPixel, transformAuctionTargetingData } from './utils';
5
5
  import { newNativeAssetManager } from './nativeAssetManager';
6
+ import {prebidMessenger} from './messaging.js';
6
7
 
7
8
  const AD_ANCHOR_CLASS_NAME = 'pb-click';
8
9
  const AD_DATA_ADID_ATTRIBUTE = 'pbAdId';
9
10
 
10
11
  export function newNativeTrackerManager(win) {
11
- let publisherDomain;
12
+ let sendMessage;
12
13
 
13
14
  function findAdElements(className) {
14
15
  let adElements = win.document.getElementsByClassName(className);
@@ -63,17 +64,18 @@ export function newNativeTrackerManager(win) {
63
64
  message.action = 'click';
64
65
  }
65
66
 
66
- win.parent.postMessage(JSON.stringify(message), publisherDomain);
67
+ sendMessage(message);
67
68
  }
68
69
  }
69
70
 
70
71
  // START OF MAIN CODE
71
72
  let startTrackers = function (dataObject) {
72
73
  const targetingData = transformAuctionTargetingData(dataObject);
73
- const nativeAssetManager = newNativeAssetManager(window);
74
+ sendMessage = prebidMessenger(targetingData.pubUrl, win);
75
+ const nativeAssetManager = newNativeAssetManager(window, targetingData.pubUrl);
74
76
 
75
77
  if (targetingData && targetingData.env === 'mobile-app') {
76
- let cb = function({clickTrackers, impTrackers} = {}) {
78
+ let cb = function({clickTrackers, impTrackers, eventtrackers} = {}) {
77
79
  function loadMobileClickTrackers(clickTrackers) {
78
80
  (clickTrackers || []).forEach(triggerPixel);
79
81
  }
@@ -81,12 +83,21 @@ export function newNativeTrackerManager(win) {
81
83
  attachClickListeners(false, boundedLoadMobileClickTrackers);
82
84
 
83
85
  (impTrackers || []).forEach(triggerPixel);
86
+
87
+ // fire impression IMG trackers
88
+ eventtrackers
89
+ .filter(tracker => tracker.event === 1 && tracker.method === 1)
90
+ .map(tracker => tracker.url)
91
+ .forEach(triggerPixel);
92
+
93
+ // fire impression JS trackers
94
+ eventtrackers
95
+ .filter(tracker => tracker.event === 1 && tracker.method === 2)
96
+ .map(tracker => tracker.url)
97
+ .forEach(trackerUrl => loadScript(document, trackerUrl));
84
98
  }
85
99
  nativeAssetManager.loadMobileAssets(targetingData, cb);
86
100
  } else {
87
- let parsedUrl = parseUrl(targetingData && targetingData.pubUrl);
88
- publisherDomain = parsedUrl.protocol + '://' + parsedUrl.host;
89
-
90
101
  let adElements = findAdElements(AD_ANCHOR_CLASS_NAME);
91
102
 
92
103
  nativeAssetManager.loadAssets(