prebid-universal-creative 1.15.0 → 1.17.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.
- package/.circleci/config.yml +44 -30
- package/.github/workflows/codeql.yml +98 -0
- package/.github/workflows/issue_tracker.yml +32 -16
- package/README.md +4 -2
- package/dist/amp.js +3 -3
- package/dist/banner.js +3 -3
- package/dist/caf7688498213fb0c19f.max.js +1046 -0
- package/dist/creative.js +3 -3
- package/dist/load-cookie-with-consent.html +1 -1
- package/dist/load-cookie.html +1 -1
- package/dist/mobile.js +3 -3
- package/dist/native-render.js +3 -3
- package/dist/native-trk.js +3 -3
- package/dist/native.js +3 -3
- package/dist/uid.js +2 -2
- package/dist/video.js +3 -3
- package/gulpfile.js +15 -31
- package/integ-test/fixtures/test.js +79 -0
- package/integ-test/pages/amp.html +80 -0
- package/integ-test/pages/banner.html +96 -0
- package/integ-test/pages/native_legacy.html +107 -0
- package/integ-test/spec/amp_spec.js +111 -0
- package/integ-test/spec/banner_spec.js +85 -0
- package/integ-test/spec/native_legacy_spec.js +213 -0
- package/karma.conf.maker.js +4 -6
- package/package.json +10 -16
- package/playwright.config.js +108 -0
- package/src/adHtmlRender.js +11 -0
- package/src/cookieSync.js +3 -0
- package/src/cookieSyncWithConsent.js +3 -0
- package/src/domHelper.js +25 -15
- package/src/dynamicRenderer.js +56 -0
- package/src/messaging.js +23 -2
- package/src/mobileAndAmpRender.js +17 -20
- package/src/nativeAssetManager.js +134 -80
- package/src/nativeORTBTrackerManager.js +3 -3
- package/src/nativeRenderManager.js +44 -72
- package/src/nativeTrackerManager.js +2 -2
- package/src/renderingManager.js +17 -18
- package/src/utils.js +0 -9
- package/test/helpers/mocks.js +1 -0
- package/test/spec/dynamicRenderer_spec.js +167 -0
- package/test/spec/messaging_spec.js +98 -3
- package/test/spec/mobileAndAmpRender_spec.js +53 -63
- package/test/spec/nativeAssetManager_spec.js +290 -93
- package/test/spec/nativeORTBTrackerManager_spec.js +3 -19
- package/test/spec/nativeRenderManager_spec.js +77 -56
- package/test/spec/renderingManager_spec.js +20 -6
- package/webpack.conf.js +0 -1
- package/.nvmrc +0 -1
- package/dist/creative.max.js +0 -3101
- package/src/postscribeRender.js +0 -8
- package/test/e2e/specs/hello_world_banner_non_sf.spec.js +0 -14
- package/test/e2e/specs/outstream_non_sf.spec.js +0 -14
- package/test/e2e/specs/outstream_sf.spec.js +0 -14
- package/wdio.conf.js +0 -50
@@ -0,0 +1,1046 @@
|
|
1
|
+
/******/ (function(modules) { // webpackBootstrap
|
2
|
+
/******/ // The module cache
|
3
|
+
/******/ var installedModules = {};
|
4
|
+
/******/
|
5
|
+
/******/ // The require function
|
6
|
+
/******/ function __webpack_require__(moduleId) {
|
7
|
+
/******/
|
8
|
+
/******/ // Check if module is in cache
|
9
|
+
/******/ if(installedModules[moduleId]) {
|
10
|
+
/******/ return installedModules[moduleId].exports;
|
11
|
+
/******/ }
|
12
|
+
/******/ // Create a new module (and put it into the cache)
|
13
|
+
/******/ var module = installedModules[moduleId] = {
|
14
|
+
/******/ i: moduleId,
|
15
|
+
/******/ l: false,
|
16
|
+
/******/ exports: {}
|
17
|
+
/******/ };
|
18
|
+
/******/
|
19
|
+
/******/ // Execute the module function
|
20
|
+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
21
|
+
/******/
|
22
|
+
/******/ // Flag the module as loaded
|
23
|
+
/******/ module.l = true;
|
24
|
+
/******/
|
25
|
+
/******/ // Return the exports of the module
|
26
|
+
/******/ return module.exports;
|
27
|
+
/******/ }
|
28
|
+
/******/
|
29
|
+
/******/
|
30
|
+
/******/ // expose the modules object (__webpack_modules__)
|
31
|
+
/******/ __webpack_require__.m = modules;
|
32
|
+
/******/
|
33
|
+
/******/ // expose the module cache
|
34
|
+
/******/ __webpack_require__.c = installedModules;
|
35
|
+
/******/
|
36
|
+
/******/ // define getter function for harmony exports
|
37
|
+
/******/ __webpack_require__.d = function(exports, name, getter) {
|
38
|
+
/******/ if(!__webpack_require__.o(exports, name)) {
|
39
|
+
/******/ Object.defineProperty(exports, name, {
|
40
|
+
/******/ configurable: false,
|
41
|
+
/******/ enumerable: true,
|
42
|
+
/******/ get: getter
|
43
|
+
/******/ });
|
44
|
+
/******/ }
|
45
|
+
/******/ };
|
46
|
+
/******/
|
47
|
+
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
48
|
+
/******/ __webpack_require__.n = function(module) {
|
49
|
+
/******/ var getter = module && module.__esModule ?
|
50
|
+
/******/ function getDefault() { return module['default']; } :
|
51
|
+
/******/ function getModuleExports() { return module; };
|
52
|
+
/******/ __webpack_require__.d(getter, 'a', getter);
|
53
|
+
/******/ return getter;
|
54
|
+
/******/ };
|
55
|
+
/******/
|
56
|
+
/******/ // Object.prototype.hasOwnProperty.call
|
57
|
+
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
58
|
+
/******/
|
59
|
+
/******/ // __webpack_public_path__
|
60
|
+
/******/ __webpack_require__.p = "";
|
61
|
+
/******/
|
62
|
+
/******/ // Load entry module and return exports
|
63
|
+
/******/ return __webpack_require__(__webpack_require__.s = 4);
|
64
|
+
/******/ })
|
65
|
+
/************************************************************************/
|
66
|
+
/******/ ([
|
67
|
+
/* 0 */
|
68
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
69
|
+
|
70
|
+
"use strict";
|
71
|
+
/* harmony export (immutable) */ __webpack_exports__["i"] = triggerPixel;
|
72
|
+
/* harmony export (immutable) */ __webpack_exports__["a"] = createTrackPixelHtml;
|
73
|
+
/* harmony export (immutable) */ __webpack_exports__["j"] = writeAdUrl;
|
74
|
+
/* harmony export (immutable) */ __webpack_exports__["g"] = sendRequest;
|
75
|
+
/* harmony export (immutable) */ __webpack_exports__["d"] = getUUID;
|
76
|
+
/* harmony export (immutable) */ __webpack_exports__["e"] = loadScript;
|
77
|
+
/* harmony export (immutable) */ __webpack_exports__["b"] = getCreativeComment;
|
78
|
+
/* harmony export (immutable) */ __webpack_exports__["c"] = getCreativeCommentMarkup;
|
79
|
+
/* harmony export (immutable) */ __webpack_exports__["h"] = transformAuctionTargetingData;
|
80
|
+
/* harmony export (immutable) */ __webpack_exports__["f"] = parseUrl;
|
81
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__domHelper__ = __webpack_require__(1);
|
82
|
+
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Inserts an image pixel with the specified `url` for cookie sync
|
86
|
+
* @param {string} url URL string of the image pixel to load
|
87
|
+
* @param {function} [done] an optional exit callback, used when this usersync pixel is added during an async process
|
88
|
+
*/
|
89
|
+
function triggerPixel(url, done) {
|
90
|
+
var img = new Image();
|
91
|
+
if (done && typeof done === 'function') {
|
92
|
+
img.addEventListener('load', done);
|
93
|
+
img.addEventListener('error', done);
|
94
|
+
}
|
95
|
+
img.src = url;
|
96
|
+
}
|
97
|
+
function createTrackPixelHtml(url) {
|
98
|
+
if (!url) {
|
99
|
+
return '';
|
100
|
+
}
|
101
|
+
var escapedUrl = encodeURI(url);
|
102
|
+
var img = "<div style=\"position:absolute;left:0px;top:0px;visibility:hidden;\"><img src=\"".concat(escapedUrl, "\"></div>");
|
103
|
+
return img;
|
104
|
+
}
|
105
|
+
function writeAdUrl(adUrl, width, height) {
|
106
|
+
var iframe = __WEBPACK_IMPORTED_MODULE_0__domHelper__["a" /* getEmptyIframe */](height, width);
|
107
|
+
iframe.src = adUrl;
|
108
|
+
document.body.appendChild(iframe);
|
109
|
+
}
|
110
|
+
function sendRequest(url, callback) {
|
111
|
+
function reqListener() {
|
112
|
+
callback(oReq.responseText);
|
113
|
+
}
|
114
|
+
var oReq = new XMLHttpRequest();
|
115
|
+
oReq.addEventListener('load', reqListener);
|
116
|
+
oReq.open('GET', url);
|
117
|
+
oReq.send();
|
118
|
+
}
|
119
|
+
function getUUID() {
|
120
|
+
var d = new Date().getTime();
|
121
|
+
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
122
|
+
var r = (d + Math.random() * 16) % 16 | 0;
|
123
|
+
d = Math.floor(d / 16);
|
124
|
+
return (c === 'x' ? r : r & 0x3 | 0x8).toString(16);
|
125
|
+
});
|
126
|
+
return uuid;
|
127
|
+
}
|
128
|
+
;
|
129
|
+
function loadScript(currentWindow, tagSrc, successCallback, errorCallback) {
|
130
|
+
var doc = currentWindow.document;
|
131
|
+
var scriptTag = doc.createElement('script');
|
132
|
+
scriptTag.type = 'text/javascript';
|
133
|
+
|
134
|
+
// Execute success callback if necessary
|
135
|
+
if (successCallback && typeof successCallback === 'function') {
|
136
|
+
if (scriptTag.readyState) {
|
137
|
+
scriptTag.onreadystatechange = function () {
|
138
|
+
if (scriptTag.readyState === 'loaded' || scriptTag.readyState === 'complete') {
|
139
|
+
scriptTag.onreadystatechange = null;
|
140
|
+
successCallback();
|
141
|
+
}
|
142
|
+
};
|
143
|
+
} else {
|
144
|
+
scriptTag.onload = function () {
|
145
|
+
successCallback();
|
146
|
+
};
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
// Execute error callback if necessary
|
151
|
+
if (errorCallback && typeof errorCallback === 'function') {
|
152
|
+
scriptTag.onerror = function () {
|
153
|
+
errorCallback();
|
154
|
+
};
|
155
|
+
}
|
156
|
+
scriptTag.src = tagSrc;
|
157
|
+
|
158
|
+
//add the new script tag to the page
|
159
|
+
var elToAppend = doc.getElementsByTagName('head');
|
160
|
+
elToAppend = elToAppend.length ? elToAppend : doc.getElementsByTagName('body');
|
161
|
+
if (elToAppend.length) {
|
162
|
+
elToAppend = elToAppend[0];
|
163
|
+
elToAppend.insertBefore(scriptTag, elToAppend.firstChild);
|
164
|
+
}
|
165
|
+
return scriptTag;
|
166
|
+
}
|
167
|
+
;
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Return comment element
|
171
|
+
* @param {*} bid
|
172
|
+
*/
|
173
|
+
function getCreativeComment(bid) {
|
174
|
+
return document.createComment("Creative ".concat(bid.crid, " served by Prebid.js Header Bidding"));
|
175
|
+
}
|
176
|
+
|
177
|
+
/**
|
178
|
+
* Returns comment element markup
|
179
|
+
* @param {*} bid
|
180
|
+
*/
|
181
|
+
function getCreativeCommentMarkup(bid) {
|
182
|
+
var creativeComment = getCreativeComment(bid);
|
183
|
+
var wrapper = document.createElement('div');
|
184
|
+
wrapper.appendChild(creativeComment);
|
185
|
+
return wrapper.innerHTML;
|
186
|
+
}
|
187
|
+
function transformAuctionTargetingData(tagData) {
|
188
|
+
// this map object translates the Prebid.js auction keys to their equivalent Prebid Universal Creative keys
|
189
|
+
// when the publisher uses their adserver's generic macro that provides all targeting keys (ie tagData.targetingMap), we need to convert the keys
|
190
|
+
var auctionKeyMap = {
|
191
|
+
hb_adid: 'adId',
|
192
|
+
hb_cache_host: 'cacheHost',
|
193
|
+
hb_cache_path: 'cachePath',
|
194
|
+
hb_cache_id: 'uuid',
|
195
|
+
hb_format: 'mediaType',
|
196
|
+
hb_env: 'env',
|
197
|
+
hb_size: 'size',
|
198
|
+
hb_pb: 'hbPb'
|
199
|
+
};
|
200
|
+
|
201
|
+
/**
|
202
|
+
* Determine if the supplied property of the tagData object exists and is populated with its own values/properties according to its type
|
203
|
+
* @param {string} paramName name of the property to check (eg tagData.targetingMap)
|
204
|
+
* @returns true/false
|
205
|
+
*/
|
206
|
+
function isMacroPresent(paramName) {
|
207
|
+
return !!(tagData[paramName] && (isPlainObject(tagData[paramName]) && Object.keys(tagData[paramName]).length > 0 || isStr(tagData[paramName]) && tagData[paramName] !== ''));
|
208
|
+
}
|
209
|
+
|
210
|
+
/**
|
211
|
+
* Converts the specifically formatted object of keypairs to a more generalized structure
|
212
|
+
* It specifically extracts the keyvalue from an array and stores it as a normal string
|
213
|
+
* @param {object} tarMap object of keys with the keyvalue stored in an array; eg {"hb_adid":["26566ee8c7f251"], ...}
|
214
|
+
* @returns {object} result is an object map like the following: {"hb_cache_id":"123456", "other_key":"other_value", ...}
|
215
|
+
*/
|
216
|
+
function convertTargetingMapToNormalMap(tarMap) {
|
217
|
+
var newTarMap = {};
|
218
|
+
Object.keys(tarMap).forEach(function (key) {
|
219
|
+
if (Array.isArray(tarMap[key]) && tarMap[key].length > 0) {
|
220
|
+
newTarMap[key] = tarMap[key][0];
|
221
|
+
}
|
222
|
+
});
|
223
|
+
return newTarMap;
|
224
|
+
}
|
225
|
+
|
226
|
+
/**
|
227
|
+
* Converts a specifically formatted string of keypairs to a specifically formatted object map
|
228
|
+
* @param {String} keywordsStr string of keypairs; eg "hb_cache_id:123456,other_key:other_value"
|
229
|
+
* @returns {object} result is an object map like the following: {"hb_cache_id":"123456", "other_key":"other_value", ...}
|
230
|
+
*/
|
231
|
+
function convertKeyPairStringToMap(keywordsStr) {
|
232
|
+
var keywordsMap = {};
|
233
|
+
var keywordsArr = keywordsStr.split(',');
|
234
|
+
if (keywordsArr.length > 0) {
|
235
|
+
keywordsArr.forEach(function (keyPairStr) {
|
236
|
+
var keyPairArr = keyPairStr.split(':');
|
237
|
+
if (keyPairArr.length === 2) {
|
238
|
+
var k = keyPairArr[0];
|
239
|
+
var v = keyPairArr[1];
|
240
|
+
keywordsMap[k] = v;
|
241
|
+
}
|
242
|
+
});
|
243
|
+
}
|
244
|
+
return keywordsMap;
|
245
|
+
}
|
246
|
+
|
247
|
+
/**
|
248
|
+
* Rename key if it's part of the auctionKeyMap object; if not, leave key as is
|
249
|
+
* Store the resultant keypair in the auctionData object for later use in renderingManager.renderAd()
|
250
|
+
* @param {object} adServerKeyMap incoming object map of the auction keys from the UC tag; eg {'key1':'value1', 'key2':'value2', ...}
|
251
|
+
*/
|
252
|
+
function renameKnownAuctionKeys(adServerKeyMap) {
|
253
|
+
Object.keys(adServerKeyMap).forEach(function (key) {
|
254
|
+
var internalKey = auctionKeyMap[key] || key;
|
255
|
+
auctionData[internalKey] = adServerKeyMap[key];
|
256
|
+
});
|
257
|
+
}
|
258
|
+
var auctionData = {};
|
259
|
+
var formattedKeyMap = {};
|
260
|
+
if (isMacroPresent('targetingMap')) {
|
261
|
+
formattedKeyMap = convertTargetingMapToNormalMap(tagData.targetingMap);
|
262
|
+
} else if (isMacroPresent('targetingKeywords')) {
|
263
|
+
formattedKeyMap = convertKeyPairStringToMap(tagData.targetingKeywords);
|
264
|
+
}
|
265
|
+
renameKnownAuctionKeys(formattedKeyMap);
|
266
|
+
|
267
|
+
// set keys not in defined map macros (eg targetingMap) and/or the keys setup within a non-DFP adserver
|
268
|
+
Object.keys(tagData).forEach(function (key) {
|
269
|
+
if (key !== 'targetingMap' && key !== 'targetingKeywords' && isStr(tagData[key]) && tagData[key] !== '') {
|
270
|
+
auctionData[key] = tagData[key];
|
271
|
+
}
|
272
|
+
});
|
273
|
+
return auctionData;
|
274
|
+
}
|
275
|
+
function parseUrl(url) {
|
276
|
+
var parsed = document.createElement('a');
|
277
|
+
parsed.href = decodeURIComponent(url);
|
278
|
+
return {
|
279
|
+
href: parsed.href,
|
280
|
+
protocol: (parsed.protocol || '').replace(/:$/, ''),
|
281
|
+
hostname: parsed.hostname,
|
282
|
+
port: +parsed.port,
|
283
|
+
pathname: parsed.pathname.replace(/^(?!\/)/, '/'),
|
284
|
+
hash: (parsed.hash || '').replace(/^#/, ''),
|
285
|
+
host: (parsed.host || window.location.host).replace(/:(443|80)$/, '')
|
286
|
+
};
|
287
|
+
}
|
288
|
+
function isA(object, _t) {
|
289
|
+
return Object.prototype.toString.call(object) === '[object ' + _t + ']';
|
290
|
+
}
|
291
|
+
;
|
292
|
+
function isPlainObject(object) {
|
293
|
+
return isA(object, 'Object');
|
294
|
+
}
|
295
|
+
function isStr(object) {
|
296
|
+
return isA(object, 'String');
|
297
|
+
}
|
298
|
+
;
|
299
|
+
|
300
|
+
/***/ }),
|
301
|
+
/* 1 */
|
302
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
303
|
+
|
304
|
+
"use strict";
|
305
|
+
/* harmony export (immutable) */ __webpack_exports__["c"] = makeIframe;
|
306
|
+
/* harmony export (immutable) */ __webpack_exports__["a"] = getEmptyIframe;
|
307
|
+
/* harmony export (immutable) */ __webpack_exports__["b"] = insertElement;
|
308
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
309
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
310
|
+
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
311
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
312
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
313
|
+
/**
|
314
|
+
* domHelper: a collection of helpful dom things
|
315
|
+
*/
|
316
|
+
|
317
|
+
/**
|
318
|
+
* returns a empty iframe element with specified attributes.
|
319
|
+
*/
|
320
|
+
function makeIframe(doc) {
|
321
|
+
var attrs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
322
|
+
var frame = doc.createElement('iframe');
|
323
|
+
Object.entries(_extends({
|
324
|
+
frameborder: 0,
|
325
|
+
scrolling: 'no',
|
326
|
+
marginheight: 0,
|
327
|
+
marginwidth: 0,
|
328
|
+
TOPMARGIN: 0,
|
329
|
+
LEFTMARGIN: 0,
|
330
|
+
allowtransparency: 'true'
|
331
|
+
}, attrs)).forEach(function (_ref) {
|
332
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
333
|
+
attr = _ref2[0],
|
334
|
+
value = _ref2[1];
|
335
|
+
frame.setAttribute(attr, value);
|
336
|
+
});
|
337
|
+
return frame;
|
338
|
+
}
|
339
|
+
|
340
|
+
/**
|
341
|
+
* returns a empty iframe element with specified height/width
|
342
|
+
* @param {Number} height height iframe set to
|
343
|
+
* @param {Number} width width iframe set to
|
344
|
+
* @returns {Element} iframe DOM element
|
345
|
+
*/
|
346
|
+
function getEmptyIframe(height, width) {
|
347
|
+
return makeIframe(document, {
|
348
|
+
height: height,
|
349
|
+
width: width
|
350
|
+
});
|
351
|
+
}
|
352
|
+
|
353
|
+
/**
|
354
|
+
* Insert element to passed target
|
355
|
+
* @param {object} elm
|
356
|
+
* @param {object} doc
|
357
|
+
* @param {string} target
|
358
|
+
*/
|
359
|
+
function insertElement(elm, doc, target) {
|
360
|
+
doc = doc || document;
|
361
|
+
var elToAppend;
|
362
|
+
if (target) {
|
363
|
+
elToAppend = doc.getElementsByTagName(target);
|
364
|
+
} else {
|
365
|
+
elToAppend = doc.getElementsByTagName('head');
|
366
|
+
}
|
367
|
+
try {
|
368
|
+
elToAppend = elToAppend.length ? elToAppend : doc.getElementsByTagName('body');
|
369
|
+
if (elToAppend.length) {
|
370
|
+
elToAppend = elToAppend[0];
|
371
|
+
elToAppend.insertBefore(elm, elToAppend.firstChild);
|
372
|
+
}
|
373
|
+
} catch (e) {}
|
374
|
+
}
|
375
|
+
|
376
|
+
/***/ }),
|
377
|
+
/* 2 */
|
378
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
379
|
+
|
380
|
+
"use strict";
|
381
|
+
/* harmony export (immutable) */ __webpack_exports__["b"] = isAmp;
|
382
|
+
/* harmony export (immutable) */ __webpack_exports__["d"] = isSafeFrame;
|
383
|
+
/* unused harmony export isCrossDomain */
|
384
|
+
/* unused harmony export canInspectWindow */
|
385
|
+
/* harmony export (immutable) */ __webpack_exports__["a"] = canLocatePrebid;
|
386
|
+
/* harmony export (immutable) */ __webpack_exports__["c"] = isMobileApp;
|
387
|
+
/***************************************
|
388
|
+
* Detect Environment Helper Functions
|
389
|
+
***************************************/
|
390
|
+
|
391
|
+
/**
|
392
|
+
* Functions to detect below environments:
|
393
|
+
* Amp: google Accelerate Mobile Pages ampproject.org
|
394
|
+
* SafeFrame: SafeFrame
|
395
|
+
* CrossDomain: An iframe that can't get to the top window
|
396
|
+
* Mobile App: function to detect mobile app environment
|
397
|
+
*/
|
398
|
+
|
399
|
+
/**
|
400
|
+
* @param {String} uuid key value from auction, contains the cache id of the winning bid stored in prebid cache
|
401
|
+
* @returns true if there is an AMP context object
|
402
|
+
*/
|
403
|
+
function isAmp(uuid, win) {
|
404
|
+
// TODO Use amp context once it is available in cross domain
|
405
|
+
// https://github.com/ampproject/amphtml/issues/6829
|
406
|
+
return typeof uuid === 'string' && uuid !== "" && isCrossDomain(win);
|
407
|
+
}
|
408
|
+
|
409
|
+
/**
|
410
|
+
* @returns true if the environment is a SafeFrame.
|
411
|
+
*/
|
412
|
+
function isSafeFrame(win) {
|
413
|
+
return !!(win.$sf && win.$sf.ext);
|
414
|
+
}
|
415
|
+
|
416
|
+
/**
|
417
|
+
* Return true if we are in an iframe and can't access the top window.
|
418
|
+
* @returns true if the environment is a Cross Domain
|
419
|
+
*/
|
420
|
+
function isCrossDomain(win) {
|
421
|
+
return win.top !== win && !canInspectWindow(win);
|
422
|
+
}
|
423
|
+
|
424
|
+
/**
|
425
|
+
* Returns true if win's properties can be accessed and win is defined.
|
426
|
+
* This functioned is used to determine if a window is cross-domained
|
427
|
+
* from the perspective of the current window.
|
428
|
+
* @param {!Window} win
|
429
|
+
* @return {boolean}
|
430
|
+
*/
|
431
|
+
function canInspectWindow(win) {
|
432
|
+
try {
|
433
|
+
// force an exception in x-domain environments. #1509
|
434
|
+
win.top.location.toString();
|
435
|
+
return true;
|
436
|
+
} catch (e) {
|
437
|
+
return false;
|
438
|
+
}
|
439
|
+
}
|
440
|
+
|
441
|
+
/**
|
442
|
+
* Returns true if we can find the prebid global object (eg pbjs) as we
|
443
|
+
* climb the accessible windows. Return false if it's not found.
|
444
|
+
* @returns {boolean}
|
445
|
+
*/
|
446
|
+
function canLocatePrebid(win) {
|
447
|
+
var result = false;
|
448
|
+
var currentWindow = win;
|
449
|
+
while (!result) {
|
450
|
+
try {
|
451
|
+
if (currentWindow.pbjs) {
|
452
|
+
result = true;
|
453
|
+
break;
|
454
|
+
}
|
455
|
+
} catch (e) {}
|
456
|
+
if (currentWindow === window.top) break;
|
457
|
+
currentWindow = currentWindow.parent;
|
458
|
+
}
|
459
|
+
return result;
|
460
|
+
}
|
461
|
+
|
462
|
+
/**
|
463
|
+
* @param {String} env key value from auction, indicates the environment where tag is served
|
464
|
+
* @returns true if env exists and is equal to the string 'mobile-app'
|
465
|
+
*/
|
466
|
+
function isMobileApp(env) {
|
467
|
+
return env && env === 'mobile-app';
|
468
|
+
}
|
469
|
+
|
470
|
+
/***/ }),
|
471
|
+
/* 3 */
|
472
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
473
|
+
|
474
|
+
"use strict";
|
475
|
+
/* unused harmony export PREBID_EVENT */
|
476
|
+
/* unused harmony export AD_RENDER_SUCCEEDED */
|
477
|
+
/* unused harmony export AD_RENDER_FAILED */
|
478
|
+
/* harmony export (immutable) */ __webpack_exports__["a"] = prebidMessenger;
|
479
|
+
/* harmony export (immutable) */ __webpack_exports__["b"] = renderEventMessage;
|
480
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(0);
|
481
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
482
|
+
|
483
|
+
var PREBID_EVENT = 'Prebid Event';
|
484
|
+
var AD_RENDER_SUCCEEDED = 'adRenderSucceeded';
|
485
|
+
var AD_RENDER_FAILED = 'adRenderFailed';
|
486
|
+
function prebidMessenger(publisherURL) {
|
487
|
+
var win = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window;
|
488
|
+
var prebidDomain = function () {
|
489
|
+
if (publisherURL == null) {
|
490
|
+
return null;
|
491
|
+
}
|
492
|
+
var parsedUrl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_js__["f" /* parseUrl */])(publisherURL);
|
493
|
+
return parsedUrl.protocol + '://' + parsedUrl.host;
|
494
|
+
}();
|
495
|
+
function isPrebidWindow(win) {
|
496
|
+
return win && win.frames && win.frames.__pb_locator__;
|
497
|
+
}
|
498
|
+
var target = win.parent;
|
499
|
+
try {
|
500
|
+
while (target != null && target !== win.top && !isPrebidWindow(target)) {
|
501
|
+
target = target.parent;
|
502
|
+
}
|
503
|
+
if (!isPrebidWindow(target)) target = win.parent;
|
504
|
+
} catch (e) {}
|
505
|
+
return function sendMessage(message, onResponse) {
|
506
|
+
if (prebidDomain == null) {
|
507
|
+
throw new Error('Missing pubUrl');
|
508
|
+
}
|
509
|
+
message = JSON.stringify(message);
|
510
|
+
var messagePort;
|
511
|
+
if (onResponse == null) {
|
512
|
+
target.postMessage(message, prebidDomain);
|
513
|
+
} else {
|
514
|
+
var channel = new MessageChannel();
|
515
|
+
messagePort = channel.port1;
|
516
|
+
messagePort.onmessage = onResponse;
|
517
|
+
win.addEventListener('message', windowListener);
|
518
|
+
target.postMessage(message, prebidDomain, [channel.port2]);
|
519
|
+
}
|
520
|
+
return function stopListening() {
|
521
|
+
if (messagePort != null) {
|
522
|
+
win.removeEventListener('message', windowListener);
|
523
|
+
messagePort.onmessage = null;
|
524
|
+
messagePort = null;
|
525
|
+
}
|
526
|
+
};
|
527
|
+
function windowListener(ev) {
|
528
|
+
if ((ev.origin || ev.originalEvent && ev.originalEvent.origin) === prebidDomain) {
|
529
|
+
onResponse(ev);
|
530
|
+
}
|
531
|
+
}
|
532
|
+
};
|
533
|
+
}
|
534
|
+
function renderEventMessage(adId, errorInfo) {
|
535
|
+
return _extends({
|
536
|
+
adId: adId,
|
537
|
+
message: PREBID_EVENT,
|
538
|
+
event: errorInfo ? AD_RENDER_FAILED : AD_RENDER_SUCCEEDED
|
539
|
+
}, errorInfo ? {
|
540
|
+
info: errorInfo
|
541
|
+
} : null);
|
542
|
+
}
|
543
|
+
|
544
|
+
/***/ }),
|
545
|
+
/* 4 */
|
546
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
547
|
+
|
548
|
+
"use strict";
|
549
|
+
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
550
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(0);
|
551
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__renderingManager__ = __webpack_require__(5);
|
552
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__mobileAndAmpRender__ = __webpack_require__(7);
|
553
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__environment__ = __webpack_require__(2);
|
554
|
+
/**
|
555
|
+
* legacy.js
|
556
|
+
* This is deprecated code, publishers should not use one .js creative to handle all different types of creative.
|
557
|
+
* To reduce bytes transfered for each ad, publishers should use specific .js based on hb_format targeting key-value.
|
558
|
+
*
|
559
|
+
* This file is inserted into the prebid creative as a placeholder for the winning prebid creative. It should support the following formats:
|
560
|
+
* - Banner
|
561
|
+
* - AMP
|
562
|
+
* - Mobile
|
563
|
+
* - Outstream Video
|
564
|
+
* - All safeFrame creatives
|
565
|
+
*/
|
566
|
+
|
567
|
+
|
568
|
+
|
569
|
+
|
570
|
+
|
571
|
+
window.ucTag = window.ucTag || {};
|
572
|
+
window.ucTag.renderAd = function (doc, dataObject) {
|
573
|
+
var targetingData = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["h" /* transformAuctionTargetingData */])(dataObject);
|
574
|
+
if (Object(__WEBPACK_IMPORTED_MODULE_3__environment__["c" /* isMobileApp */])(targetingData.env) || Object(__WEBPACK_IMPORTED_MODULE_3__environment__["b" /* isAmp */])(targetingData.uuid, window)) {
|
575
|
+
Object(__WEBPACK_IMPORTED_MODULE_2__mobileAndAmpRender__["a" /* renderAmpOrMobileAd */])(dataObject);
|
576
|
+
} else {
|
577
|
+
Object(__WEBPACK_IMPORTED_MODULE_1__renderingManager__["a" /* renderBannerOrDisplayAd */])(doc, dataObject);
|
578
|
+
}
|
579
|
+
};
|
580
|
+
|
581
|
+
/***/ }),
|
582
|
+
/* 5 */
|
583
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
584
|
+
|
585
|
+
"use strict";
|
586
|
+
/* harmony export (immutable) */ __webpack_exports__["a"] = renderBannerOrDisplayAd;
|
587
|
+
/* unused harmony export renderLegacy */
|
588
|
+
/* unused harmony export renderCrossDomain */
|
589
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(0);
|
590
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__environment__ = __webpack_require__(2);
|
591
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__domHelper__ = __webpack_require__(1);
|
592
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__messaging_js__ = __webpack_require__(3);
|
593
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__dynamicRenderer_js__ = __webpack_require__(6);
|
594
|
+
|
595
|
+
|
596
|
+
|
597
|
+
|
598
|
+
|
599
|
+
function renderBannerOrDisplayAd(doc, dataObject) {
|
600
|
+
var targetingData = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["h" /* transformAuctionTargetingData */])(dataObject);
|
601
|
+
if (!Object(__WEBPACK_IMPORTED_MODULE_1__environment__["a" /* canLocatePrebid */])(window)) {
|
602
|
+
renderCrossDomain(window, targetingData.adId, targetingData.adServerDomain, targetingData.pubUrl);
|
603
|
+
} else {
|
604
|
+
renderLegacy(doc, targetingData.adId);
|
605
|
+
}
|
606
|
+
}
|
607
|
+
|
608
|
+
/**
|
609
|
+
* Calls prebid.js renderAd function to render ad
|
610
|
+
* @param {Object} doc Document
|
611
|
+
* @param {string} adId Id of creative to render
|
612
|
+
*/
|
613
|
+
function renderLegacy(doc, adId) {
|
614
|
+
var found = false;
|
615
|
+
var w = window;
|
616
|
+
for (var i = 0; i < 10; i++) {
|
617
|
+
w = w.parent;
|
618
|
+
if (w.pbjs) {
|
619
|
+
try {
|
620
|
+
w.pbjs.renderAd(doc, adId);
|
621
|
+
found = true;
|
622
|
+
break;
|
623
|
+
} catch (e) {
|
624
|
+
continue;
|
625
|
+
}
|
626
|
+
}
|
627
|
+
}
|
628
|
+
if (!found) {
|
629
|
+
console.error("Unable to locate pbjs.renderAd function!");
|
630
|
+
}
|
631
|
+
}
|
632
|
+
|
633
|
+
/**
|
634
|
+
* Render ad in safeframe using postmessage
|
635
|
+
* @param {string} adId Id of creative to render
|
636
|
+
* @param {string} pubAdServerDomain publisher adserver domain name
|
637
|
+
* @param {string} pubUrl Url of publisher page
|
638
|
+
*/
|
639
|
+
function renderCrossDomain(win, adId) {
|
640
|
+
var pubAdServerDomain = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
|
641
|
+
var pubUrl = arguments.length > 3 ? arguments[3] : undefined;
|
642
|
+
var windowLocation = win.location;
|
643
|
+
var adServerDomain = pubAdServerDomain || win.location.hostname;
|
644
|
+
var fullAdServerDomain = windowLocation.protocol + '//' + adServerDomain;
|
645
|
+
var sendMessage = Object(__WEBPACK_IMPORTED_MODULE_3__messaging_js__["a" /* prebidMessenger */])(pubUrl, win);
|
646
|
+
var signalRenderResult = function signalRenderResult(errorInfo) {
|
647
|
+
return sendMessage(Object(__WEBPACK_IMPORTED_MODULE_3__messaging_js__["b" /* renderEventMessage */])(adId, errorInfo));
|
648
|
+
};
|
649
|
+
function renderAd(ev) {
|
650
|
+
var key = ev.message ? "message" : "data";
|
651
|
+
var adObject = {};
|
652
|
+
try {
|
653
|
+
adObject = JSON.parse(ev[key]);
|
654
|
+
} catch (e) {
|
655
|
+
return;
|
656
|
+
}
|
657
|
+
if (adObject.message && adObject.message === "Prebid Response" && adObject.adId === adId) {
|
658
|
+
if (Object(__WEBPACK_IMPORTED_MODULE_4__dynamicRenderer_js__["a" /* hasDynamicRenderer */])(adObject)) {
|
659
|
+
Object(__WEBPACK_IMPORTED_MODULE_4__dynamicRenderer_js__["b" /* runDynamicRenderer */])(adId, adObject, sendMessage, win);
|
660
|
+
return;
|
661
|
+
}
|
662
|
+
try {
|
663
|
+
var body = win.document.body;
|
664
|
+
var ad = adObject.ad;
|
665
|
+
var url = adObject.adUrl;
|
666
|
+
var width = adObject.width;
|
667
|
+
var height = adObject.height;
|
668
|
+
if (adObject.mediaType === "video") {
|
669
|
+
signalRenderResult({
|
670
|
+
reason: "preventWritingOnMainDocument",
|
671
|
+
message: "Cannot render video ad ".concat(adId)
|
672
|
+
});
|
673
|
+
console.log("Error trying to write ad.");
|
674
|
+
} else if (ad) {
|
675
|
+
var iframe = Object(__WEBPACK_IMPORTED_MODULE_2__domHelper__["a" /* getEmptyIframe */])(adObject.height, adObject.width);
|
676
|
+
body.appendChild(iframe);
|
677
|
+
iframe.contentDocument.open();
|
678
|
+
iframe.contentDocument.write(ad);
|
679
|
+
iframe.contentDocument.close();
|
680
|
+
signalRenderResult();
|
681
|
+
} else if (url) {
|
682
|
+
var _iframe = Object(__WEBPACK_IMPORTED_MODULE_2__domHelper__["a" /* getEmptyIframe */])(height, width);
|
683
|
+
_iframe.style.display = "inline";
|
684
|
+
_iframe.style.overflow = "hidden";
|
685
|
+
_iframe.src = url;
|
686
|
+
Object(__WEBPACK_IMPORTED_MODULE_2__domHelper__["b" /* insertElement */])(_iframe, document, "body");
|
687
|
+
signalRenderResult();
|
688
|
+
} else {
|
689
|
+
signalRenderResult({
|
690
|
+
reason: "noAd",
|
691
|
+
message: "No ad for ".concat(adId)
|
692
|
+
});
|
693
|
+
console.log("Error trying to write ad. No ad markup or adUrl for ".concat(adId));
|
694
|
+
}
|
695
|
+
} catch (e) {
|
696
|
+
signalRenderResult({
|
697
|
+
reason: "exception",
|
698
|
+
message: e.message
|
699
|
+
});
|
700
|
+
console.log("Error in rendering ad", e);
|
701
|
+
}
|
702
|
+
}
|
703
|
+
}
|
704
|
+
function requestAdFromPrebid() {
|
705
|
+
var message = {
|
706
|
+
message: 'Prebid Request',
|
707
|
+
adId: adId,
|
708
|
+
adServerDomain: fullAdServerDomain
|
709
|
+
};
|
710
|
+
sendMessage(message, renderAd);
|
711
|
+
}
|
712
|
+
requestAdFromPrebid();
|
713
|
+
}
|
714
|
+
|
715
|
+
/***/ }),
|
716
|
+
/* 6 */
|
717
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
718
|
+
|
719
|
+
"use strict";
|
720
|
+
/* unused harmony export MIN_RENDERER_VERSION */
|
721
|
+
/* harmony export (immutable) */ __webpack_exports__["a"] = hasDynamicRenderer;
|
722
|
+
/* harmony export (immutable) */ __webpack_exports__["b"] = runDynamicRenderer;
|
723
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__domHelper_js__ = __webpack_require__(1);
|
724
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__messaging_js__ = __webpack_require__(3);
|
725
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
726
|
+
|
727
|
+
|
728
|
+
var MIN_RENDERER_VERSION = 3;
|
729
|
+
function hasDynamicRenderer(message) {
|
730
|
+
return typeof message.renderer === 'string' && parseInt(message.rendererVersion, 10) >= MIN_RENDERER_VERSION;
|
731
|
+
}
|
732
|
+
function runDynamicRenderer(adId, data, _sendMessage) {
|
733
|
+
var win = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : window;
|
734
|
+
var mkFrame = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : __WEBPACK_IMPORTED_MODULE_0__domHelper_js__["c" /* makeIframe */];
|
735
|
+
var renderer = mkFrame(win.document, {
|
736
|
+
width: 0,
|
737
|
+
height: 0,
|
738
|
+
style: 'display: none',
|
739
|
+
srcdoc: "<script>".concat(data.renderer, "</script>"),
|
740
|
+
name: '__pb_renderer__'
|
741
|
+
});
|
742
|
+
return new Promise(function (resolve, reject) {
|
743
|
+
function onError() {
|
744
|
+
var e = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
745
|
+
_sendMessage(Object(__WEBPACK_IMPORTED_MODULE_1__messaging_js__["b" /* renderEventMessage */])(adId, {
|
746
|
+
reason: e.reason || 'exception',
|
747
|
+
message: e.message
|
748
|
+
}));
|
749
|
+
e.stack && console.error(e);
|
750
|
+
reject(e);
|
751
|
+
}
|
752
|
+
function guard(fn) {
|
753
|
+
return function () {
|
754
|
+
try {
|
755
|
+
return fn.apply(this, arguments);
|
756
|
+
} catch (e) {
|
757
|
+
onError(e);
|
758
|
+
}
|
759
|
+
};
|
760
|
+
}
|
761
|
+
renderer.onload = guard(function () {
|
762
|
+
var W = renderer.contentWindow;
|
763
|
+
// NOTE: on Firefox, `Promise.resolve(P)` or `new Promise((resolve) => resolve(P))`
|
764
|
+
// does not appear to work if P comes from another frame
|
765
|
+
W.Promise.resolve(W.render(data, {
|
766
|
+
mkFrame: mkFrame,
|
767
|
+
sendMessage: function sendMessage(type, payload, onResponse) {
|
768
|
+
return _sendMessage(_extends({
|
769
|
+
adId: adId,
|
770
|
+
message: type
|
771
|
+
}, payload), onResponse ? guard(onResponse) : undefined);
|
772
|
+
}
|
773
|
+
}, win)).then(function () {
|
774
|
+
return _sendMessage(Object(__WEBPACK_IMPORTED_MODULE_1__messaging_js__["b" /* renderEventMessage */])(adId));
|
775
|
+
}, onError).then(resolve);
|
776
|
+
});
|
777
|
+
win.document.body.appendChild(renderer);
|
778
|
+
});
|
779
|
+
}
|
780
|
+
|
781
|
+
/***/ }),
|
782
|
+
/* 7 */
|
783
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
784
|
+
|
785
|
+
"use strict";
|
786
|
+
/* harmony export (immutable) */ __webpack_exports__["a"] = renderAmpOrMobileAd;
|
787
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(0);
|
788
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__environment__ = __webpack_require__(2);
|
789
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__domHelper__ = __webpack_require__(1);
|
790
|
+
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__adHtmlRender__ = __webpack_require__(8);
|
791
|
+
|
792
|
+
|
793
|
+
|
794
|
+
|
795
|
+
var DEFAULT_CACHE_HOST = 'prebid.adnxs.com';
|
796
|
+
var DEFAULT_CACHE_PATH = '/pbc/v1/cache';
|
797
|
+
|
798
|
+
/**
|
799
|
+
* Render mobile or amp ad
|
800
|
+
* @param {string} cacheHost Cache host
|
801
|
+
* @param {string} cachePath Cache path
|
802
|
+
* @param {string} uuid id to render response from cache endpoint
|
803
|
+
* @param {string} size size of the creative
|
804
|
+
* @param {string} hbPb final price of the winning bid
|
805
|
+
* @param {Bool} isMobileApp flag to detect mobile app
|
806
|
+
*/
|
807
|
+
function renderAmpOrMobileAd(dataObject) {
|
808
|
+
var targetingData = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["h" /* transformAuctionTargetingData */])(dataObject);
|
809
|
+
var cacheHost = targetingData.cacheHost,
|
810
|
+
cachePath = targetingData.cachePath,
|
811
|
+
uuid = targetingData.uuid,
|
812
|
+
size = targetingData.size,
|
813
|
+
hbPb = targetingData.hbPb;
|
814
|
+
uuid = uuid || '';
|
815
|
+
// For MoPub, creative is stored in localStorage via SDK.
|
816
|
+
var search = 'Prebid_';
|
817
|
+
if (uuid.substr(0, search.length) === search) {
|
818
|
+
loadFromLocalCache(uuid);
|
819
|
+
//register creative right away to not miss initial geom-update
|
820
|
+
updateIframe(size);
|
821
|
+
} else {
|
822
|
+
var adUrl = "".concat(getCacheEndpoint(cacheHost, cachePath), "?uuid=").concat(uuid);
|
823
|
+
//register creative right away to not miss initial geom-update
|
824
|
+
updateIframe(size);
|
825
|
+
Object(__WEBPACK_IMPORTED_MODULE_0__utils__["g" /* sendRequest */])(adUrl, responseCallback(Object(__WEBPACK_IMPORTED_MODULE_1__environment__["c" /* isMobileApp */])(targetingData.env), hbPb));
|
826
|
+
}
|
827
|
+
}
|
828
|
+
|
829
|
+
/**
|
830
|
+
* Load response from localStorage. In case of MoPub, sdk caches response
|
831
|
+
* @param {string} cacheId
|
832
|
+
*/
|
833
|
+
function loadFromLocalCache(cacheId) {
|
834
|
+
var bid = window.localStorage.getItem(cacheId);
|
835
|
+
var displayFn = responseCallback(true);
|
836
|
+
displayFn(bid);
|
837
|
+
}
|
838
|
+
|
839
|
+
/**
|
840
|
+
* update iframe by using size string to resize
|
841
|
+
* @param {string} size
|
842
|
+
*/
|
843
|
+
function updateIframe(size) {
|
844
|
+
if (size) {
|
845
|
+
var sizeArr = size.split('x').map(Number);
|
846
|
+
resizeIframe(sizeArr[0], sizeArr[1]);
|
847
|
+
} else {
|
848
|
+
console.log('Targeting key hb_size not found to resize creative');
|
849
|
+
}
|
850
|
+
}
|
851
|
+
|
852
|
+
/**
|
853
|
+
* Resize container iframe
|
854
|
+
* @param {Number} width width of creative
|
855
|
+
* @param {Number} height height of creative
|
856
|
+
*/
|
857
|
+
function resizeIframe(width, height) {
|
858
|
+
var iframeWidth = window.innerWidth;
|
859
|
+
var iframeHeight = window.innerHeight;
|
860
|
+
if (iframeWidth !== width || iframeHeight !== height) {
|
861
|
+
if (Object(__WEBPACK_IMPORTED_MODULE_1__environment__["d" /* isSafeFrame */])(window)) {
|
862
|
+
var resize = function resize(status) {
|
863
|
+
var newWidth = width - iframeWidth;
|
864
|
+
var newHeight = height - iframeHeight;
|
865
|
+
window.$sf.ext.expand({
|
866
|
+
r: newWidth,
|
867
|
+
b: newHeight,
|
868
|
+
push: true
|
869
|
+
});
|
870
|
+
};
|
871
|
+
window.$sf.ext.register(width, height, resize);
|
872
|
+
}
|
873
|
+
// AMP resize request in case the parent is AMP
|
874
|
+
window.parent.postMessage({
|
875
|
+
sentinel: 'amp',
|
876
|
+
type: 'embed-size',
|
877
|
+
width: width,
|
878
|
+
height: height
|
879
|
+
}, '*');
|
880
|
+
}
|
881
|
+
}
|
882
|
+
|
883
|
+
/**
|
884
|
+
* Returns cache endpoint concatenated with cache path
|
885
|
+
* @param {string} cacheHost Cache Endpoint host
|
886
|
+
* @param {string} cachePath Cache Endpoint path
|
887
|
+
*/
|
888
|
+
function getCacheEndpoint(cacheHost, cachePath) {
|
889
|
+
var host = typeof cacheHost === 'undefined' || cacheHost === "" ? DEFAULT_CACHE_HOST : cacheHost;
|
890
|
+
var path = typeof cachePath === 'undefined' || cachePath === "" ? DEFAULT_CACHE_PATH : cachePath;
|
891
|
+
return "https://".concat(host).concat(path);
|
892
|
+
}
|
893
|
+
|
894
|
+
/**
|
895
|
+
* Cache request Callback to display creative
|
896
|
+
* @param {Bool} isMobileApp
|
897
|
+
* @param {string} hbPb final price of the winning bid
|
898
|
+
* @returns {function} a callback function that parses response
|
899
|
+
*/
|
900
|
+
function responseCallback(isMobileApp, hbPb) {
|
901
|
+
return function (response) {
|
902
|
+
var bidObject = parseResponse(response);
|
903
|
+
var auctionPrice = bidObject.price || hbPb;
|
904
|
+
var ad = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["c" /* getCreativeCommentMarkup */])(bidObject);
|
905
|
+
var width = bidObject.width ? bidObject.width : bidObject.w;
|
906
|
+
var height = bidObject.height ? bidObject.height : bidObject.h;
|
907
|
+
|
908
|
+
// When Prebid Universal Creative reads from Prebid Cache, we need to have it check for the existence of the wurl parameter. If it exists, hit it.
|
909
|
+
if (bidObject.wurl) {
|
910
|
+
Object(__WEBPACK_IMPORTED_MODULE_0__utils__["i" /* triggerPixel */])(decodeURIComponent(bidObject.wurl));
|
911
|
+
}
|
912
|
+
if (bidObject.adm) {
|
913
|
+
if (auctionPrice) {
|
914
|
+
// replace ${AUCTION_PRICE} macro with the bidObject.price or hb_pb.
|
915
|
+
bidObject.adm = bidObject.adm.replace('${AUCTION_PRICE}', auctionPrice);
|
916
|
+
} else {
|
917
|
+
/*
|
918
|
+
From OpenRTB spec 2.5: If the source value is an optional parameter that was not specified, the macro will simply be removed (i.e., replaced with a zero-length string).
|
919
|
+
*/
|
920
|
+
bidObject.adm = bidObject.adm.replace('${AUCTION_PRICE}', '');
|
921
|
+
}
|
922
|
+
ad += isMobileApp ? constructMarkup(bidObject.adm, width, height) : bidObject.adm;
|
923
|
+
if (bidObject.nurl) {
|
924
|
+
ad += Object(__WEBPACK_IMPORTED_MODULE_0__utils__["a" /* createTrackPixelHtml */])(decodeURIComponent(bidObject.nurl));
|
925
|
+
}
|
926
|
+
if (bidObject.burl) {
|
927
|
+
var triggerBurl = function triggerBurl() {
|
928
|
+
Object(__WEBPACK_IMPORTED_MODULE_0__utils__["i" /* triggerPixel */])(bidObject.burl);
|
929
|
+
};
|
930
|
+
if (isMobileApp) {
|
931
|
+
var mraidScript = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["e" /* loadScript */])(window, 'mraid.js', function () {
|
932
|
+
// Success loading MRAID
|
933
|
+
var result = registerMRAIDViewableEvent(triggerBurl);
|
934
|
+
if (!result) {
|
935
|
+
triggerBurl(); // Error registering event
|
936
|
+
}
|
937
|
+
}, triggerBurl // Error loading MRAID
|
938
|
+
);
|
939
|
+
} else {
|
940
|
+
triggerBurl(); // Not a mobile app
|
941
|
+
}
|
942
|
+
}
|
943
|
+
|
944
|
+
Object(__WEBPACK_IMPORTED_MODULE_3__adHtmlRender__["a" /* writeAdHtml */])(ad);
|
945
|
+
} else if (bidObject.nurl) {
|
946
|
+
if (isMobileApp) {
|
947
|
+
var adhtml = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["e" /* loadScript */])(window, bidObject.nurl);
|
948
|
+
ad += constructMarkup(adhtml.outerHTML, width, height);
|
949
|
+
Object(__WEBPACK_IMPORTED_MODULE_3__adHtmlRender__["a" /* writeAdHtml */])(ad);
|
950
|
+
} else {
|
951
|
+
var nurl = bidObject.nurl;
|
952
|
+
var commentElm = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["b" /* getCreativeComment */])(bidObject);
|
953
|
+
Object(__WEBPACK_IMPORTED_MODULE_2__domHelper__["b" /* insertElement */])(commentElm, document, 'body');
|
954
|
+
Object(__WEBPACK_IMPORTED_MODULE_0__utils__["j" /* writeAdUrl */])(nurl, width, height);
|
955
|
+
}
|
956
|
+
}
|
957
|
+
};
|
958
|
+
}
|
959
|
+
;
|
960
|
+
|
961
|
+
/**
|
962
|
+
* Parse response
|
963
|
+
* @param {string} response
|
964
|
+
* @returns {Object} bidObject parsed response
|
965
|
+
*/
|
966
|
+
function parseResponse(response) {
|
967
|
+
var bidObject;
|
968
|
+
try {
|
969
|
+
bidObject = JSON.parse(response);
|
970
|
+
} catch (error) {
|
971
|
+
console.log("Error parsing response from cache host: ".concat(error));
|
972
|
+
}
|
973
|
+
return bidObject;
|
974
|
+
}
|
975
|
+
|
976
|
+
/**
|
977
|
+
* Wrap mobile app creative in div
|
978
|
+
* @param {string} ad html for creative
|
979
|
+
* @param {Number} width width of creative
|
980
|
+
* @param {Number} height height of creative
|
981
|
+
* @returns {string} creative markup
|
982
|
+
*/
|
983
|
+
function constructMarkup(ad, width, height) {
|
984
|
+
var id = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["d" /* getUUID */])();
|
985
|
+
return "<div id=\"".concat(id, "\" style=\"border-style: none; position: absolute; width:100%; height:100%;\">\n <div id=\"").concat(id, "_inner\" style=\"margin: 0 auto; width:").concat(width, "px; height:").concat(height, "px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);\">").concat(ad, "</div>\n </div>");
|
986
|
+
}
|
987
|
+
function registerMRAIDViewableEvent(callback) {
|
988
|
+
function exposureChangeListener(exposure) {
|
989
|
+
if (exposure > 0) {
|
990
|
+
mraid.removeEventListener('exposureChange', exposureChangeListener);
|
991
|
+
callback();
|
992
|
+
}
|
993
|
+
}
|
994
|
+
function viewableChangeListener(viewable) {
|
995
|
+
if (viewable) {
|
996
|
+
mraid.removeEventListener('viewableChange', viewableChangeListener);
|
997
|
+
callback();
|
998
|
+
}
|
999
|
+
}
|
1000
|
+
function registerViewableChecks() {
|
1001
|
+
if (window.MRAID_ENV && parseFloat(window.MRAID_ENV.version) >= 3) {
|
1002
|
+
mraid.addEventListener('exposureChange', exposureChangeListener);
|
1003
|
+
} else if (window.MRAID_ENV && parseFloat(window.MRAID_ENV.version) < 3) {
|
1004
|
+
if (mraid.isViewable()) {
|
1005
|
+
callback();
|
1006
|
+
} else {
|
1007
|
+
mraid.addEventListener('viewableChange', viewableChangeListener);
|
1008
|
+
}
|
1009
|
+
}
|
1010
|
+
}
|
1011
|
+
function readyListener() {
|
1012
|
+
mraid.removeEventListener('ready', readyListener);
|
1013
|
+
registerViewableChecks();
|
1014
|
+
}
|
1015
|
+
if (window.mraid && window.MRAID_ENV) {
|
1016
|
+
if (mraid.getState() == 'loading') {
|
1017
|
+
mraid.addEventListener('ready', readyListener);
|
1018
|
+
} else {
|
1019
|
+
registerViewableChecks();
|
1020
|
+
}
|
1021
|
+
return true;
|
1022
|
+
} else {
|
1023
|
+
return false;
|
1024
|
+
}
|
1025
|
+
}
|
1026
|
+
|
1027
|
+
/***/ }),
|
1028
|
+
/* 8 */
|
1029
|
+
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1030
|
+
|
1031
|
+
"use strict";
|
1032
|
+
/* harmony export (immutable) */ __webpack_exports__["a"] = writeAdHtml;
|
1033
|
+
function writeAdHtml(markup) {
|
1034
|
+
var insertHTML = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document.body.insertAdjacentHTML.bind(document.body);
|
1035
|
+
// remove <?xml> and <!doctype> tags
|
1036
|
+
// https://github.com/prebid/prebid-universal-creative/issues/134
|
1037
|
+
markup = markup.replace(/\<(\?xml|(\!DOCTYPE[^\>\[]+(\[[^\]]+)?))+[^>]+\>/gi, '');
|
1038
|
+
try {
|
1039
|
+
insertHTML('beforeend', markup);
|
1040
|
+
} catch (error) {
|
1041
|
+
console.error(error);
|
1042
|
+
}
|
1043
|
+
}
|
1044
|
+
|
1045
|
+
/***/ })
|
1046
|
+
/******/ ]);
|