prebid-universal-creative 1.16.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.
Files changed (51) hide show
  1. package/.circleci/config.yml +44 -30
  2. package/.github/workflows/codeql.yml +98 -0
  3. package/README.md +2 -2
  4. package/dist/amp.js +3 -3
  5. package/dist/banner.js +3 -3
  6. package/dist/caf7688498213fb0c19f.max.js +1046 -0
  7. package/dist/creative.js +3 -3
  8. package/dist/load-cookie-with-consent.html +1 -1
  9. package/dist/load-cookie.html +1 -1
  10. package/dist/mobile.js +3 -3
  11. package/dist/native-render.js +3 -3
  12. package/dist/native-trk.js +3 -3
  13. package/dist/native.js +3 -3
  14. package/dist/uid.js +2 -2
  15. package/dist/video.js +3 -3
  16. package/gulpfile.js +12 -24
  17. package/integ-test/fixtures/test.js +79 -0
  18. package/integ-test/pages/amp.html +80 -0
  19. package/integ-test/pages/banner.html +96 -0
  20. package/integ-test/pages/native_legacy.html +107 -0
  21. package/integ-test/spec/amp_spec.js +111 -0
  22. package/integ-test/spec/banner_spec.js +85 -0
  23. package/integ-test/spec/native_legacy_spec.js +213 -0
  24. package/package.json +7 -13
  25. package/playwright.config.js +108 -0
  26. package/src/adHtmlRender.js +11 -0
  27. package/src/cookieSync.js +3 -0
  28. package/src/cookieSyncWithConsent.js +3 -0
  29. package/src/domHelper.js +25 -15
  30. package/src/dynamicRenderer.js +56 -0
  31. package/src/messaging.js +23 -2
  32. package/src/mobileAndAmpRender.js +17 -20
  33. package/src/nativeAssetManager.js +98 -79
  34. package/src/nativeORTBTrackerManager.js +1 -1
  35. package/src/nativeRenderManager.js +7 -12
  36. package/src/nativeTrackerManager.js +2 -2
  37. package/src/renderingManager.js +13 -19
  38. package/test/helpers/mocks.js +1 -0
  39. package/test/spec/dynamicRenderer_spec.js +167 -0
  40. package/test/spec/messaging_spec.js +98 -3
  41. package/test/spec/mobileAndAmpRender_spec.js +47 -65
  42. package/test/spec/nativeAssetManager_spec.js +73 -23
  43. package/test/spec/renderingManager_spec.js +20 -6
  44. package/webpack.conf.js +0 -1
  45. package/.nvmrc +0 -1
  46. package/dist/creative.max.js +0 -3102
  47. package/src/postscribeRender.js +0 -10
  48. package/test/e2e/specs/hello_world_banner_non_sf.spec.js +0 -14
  49. package/test/e2e/specs/outstream_non_sf.spec.js +0 -14
  50. package/test/e2e/specs/outstream_sf.spec.js +0 -14
  51. package/wdio.conf.js +0 -50
@@ -1,3102 +0,0 @@
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 = 3);
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
- * Inserts an image pixel with the specified `url` for cookie sync
85
- * @param {string} url URL string of the image pixel to load
86
- * @param {function} [done] an optional exit callback, used when this usersync pixel is added during an async process
87
- */
88
-
89
- function triggerPixel(url, done) {
90
- var img = new Image();
91
-
92
- if (done && typeof done === 'function') {
93
- img.addEventListener('load', done);
94
- img.addEventListener('error', done);
95
- }
96
-
97
- img.src = url;
98
- }
99
- function createTrackPixelHtml(url) {
100
- if (!url) {
101
- return '';
102
- }
103
-
104
- var escapedUrl = encodeURI(url);
105
- var img = "<div style=\"position:absolute;left:0px;top:0px;visibility:hidden;\"><img src=\"".concat(escapedUrl, "\"></div>");
106
- return img;
107
- }
108
- function writeAdUrl(adUrl, width, height) {
109
- var iframe = __WEBPACK_IMPORTED_MODULE_0__domHelper__["a" /* getEmptyIframe */](height, width);
110
- iframe.src = adUrl;
111
- document.body.appendChild(iframe);
112
- }
113
- function sendRequest(url, callback) {
114
- function reqListener() {
115
- callback(oReq.responseText);
116
- }
117
-
118
- var oReq = new XMLHttpRequest();
119
- oReq.addEventListener('load', reqListener);
120
- oReq.open('GET', url);
121
- oReq.send();
122
- }
123
- function getUUID() {
124
- var d = new Date().getTime();
125
- var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
126
- var r = (d + Math.random() * 16) % 16 | 0;
127
- d = Math.floor(d / 16);
128
- return (c === 'x' ? r : r & 0x3 | 0x8).toString(16);
129
- });
130
- return uuid;
131
- }
132
- ;
133
- function loadScript(currentWindow, tagSrc, successCallback, errorCallback) {
134
- var doc = currentWindow.document;
135
- var scriptTag = doc.createElement('script');
136
- scriptTag.type = 'text/javascript'; // Execute success callback if necessary
137
-
138
- if (successCallback && typeof successCallback === 'function') {
139
- if (scriptTag.readyState) {
140
- scriptTag.onreadystatechange = function () {
141
- if (scriptTag.readyState === 'loaded' || scriptTag.readyState === 'complete') {
142
- scriptTag.onreadystatechange = null;
143
- successCallback();
144
- }
145
- };
146
- } else {
147
- scriptTag.onload = function () {
148
- successCallback();
149
- };
150
- }
151
- } // Execute error callback if necessary
152
-
153
-
154
- if (errorCallback && typeof errorCallback === 'function') {
155
- scriptTag.onerror = function () {
156
- errorCallback();
157
- };
158
- }
159
-
160
- scriptTag.src = tagSrc; //add the new script tag to the page
161
-
162
- var elToAppend = doc.getElementsByTagName('head');
163
- elToAppend = elToAppend.length ? elToAppend : doc.getElementsByTagName('body');
164
-
165
- if (elToAppend.length) {
166
- elToAppend = elToAppend[0];
167
- elToAppend.insertBefore(scriptTag, elToAppend.firstChild);
168
- }
169
-
170
- return scriptTag;
171
- }
172
- ;
173
- /**
174
- * Return comment element
175
- * @param {*} bid
176
- */
177
-
178
- function getCreativeComment(bid) {
179
- return document.createComment("Creative ".concat(bid.crid, " served by Prebid.js Header Bidding"));
180
- }
181
- /**
182
- * Returns comment element markup
183
- * @param {*} bid
184
- */
185
-
186
- function getCreativeCommentMarkup(bid) {
187
- var creativeComment = getCreativeComment(bid);
188
- var wrapper = document.createElement('div');
189
- wrapper.appendChild(creativeComment);
190
- return wrapper.innerHTML;
191
- }
192
- function transformAuctionTargetingData(tagData) {
193
- // this map object translates the Prebid.js auction keys to their equivalent Prebid Universal Creative keys
194
- // when the publisher uses their adserver's generic macro that provides all targeting keys (ie tagData.targetingMap), we need to convert the keys
195
- var auctionKeyMap = {
196
- hb_adid: 'adId',
197
- hb_cache_host: 'cacheHost',
198
- hb_cache_path: 'cachePath',
199
- hb_cache_id: 'uuid',
200
- hb_format: 'mediaType',
201
- hb_env: 'env',
202
- hb_size: 'size',
203
- hb_pb: 'hbPb'
204
- };
205
- /**
206
- * Determine if the supplied property of the tagData object exists and is populated with its own values/properties according to its type
207
- * @param {string} paramName name of the property to check (eg tagData.targetingMap)
208
- * @returns true/false
209
- */
210
-
211
- function isMacroPresent(paramName) {
212
- return !!(tagData[paramName] && (isPlainObject(tagData[paramName]) && Object.keys(tagData[paramName]).length > 0 || isStr(tagData[paramName]) && tagData[paramName] !== ''));
213
- }
214
- /**
215
- * Converts the specifically formatted object of keypairs to a more generalized structure
216
- * It specifically extracts the keyvalue from an array and stores it as a normal string
217
- * @param {object} tarMap object of keys with the keyvalue stored in an array; eg {"hb_adid":["26566ee8c7f251"], ...}
218
- * @returns {object} result is an object map like the following: {"hb_cache_id":"123456", "other_key":"other_value", ...}
219
- */
220
-
221
-
222
- function convertTargetingMapToNormalMap(tarMap) {
223
- var newTarMap = {};
224
- Object.keys(tarMap).forEach(function (key) {
225
- if (Array.isArray(tarMap[key]) && tarMap[key].length > 0) {
226
- newTarMap[key] = tarMap[key][0];
227
- }
228
- });
229
- return newTarMap;
230
- }
231
- /**
232
- * Converts a specifically formatted string of keypairs to a specifically formatted object map
233
- * @param {String} keywordsStr string of keypairs; eg "hb_cache_id:123456,other_key:other_value"
234
- * @returns {object} result is an object map like the following: {"hb_cache_id":"123456", "other_key":"other_value", ...}
235
- */
236
-
237
-
238
- function convertKeyPairStringToMap(keywordsStr) {
239
- var keywordsMap = {};
240
- var keywordsArr = keywordsStr.split(',');
241
-
242
- if (keywordsArr.length > 0) {
243
- keywordsArr.forEach(function (keyPairStr) {
244
- var keyPairArr = keyPairStr.split(':');
245
-
246
- if (keyPairArr.length === 2) {
247
- var k = keyPairArr[0];
248
- var v = keyPairArr[1];
249
- keywordsMap[k] = v;
250
- }
251
- });
252
- }
253
-
254
- return keywordsMap;
255
- }
256
- /**
257
- * Rename key if it's part of the auctionKeyMap object; if not, leave key as is
258
- * Store the resultant keypair in the auctionData object for later use in renderingManager.renderAd()
259
- * @param {object} adServerKeyMap incoming object map of the auction keys from the UC tag; eg {'key1':'value1', 'key2':'value2', ...}
260
- */
261
-
262
-
263
- function renameKnownAuctionKeys(adServerKeyMap) {
264
- Object.keys(adServerKeyMap).forEach(function (key) {
265
- var internalKey = auctionKeyMap[key] || key;
266
- auctionData[internalKey] = adServerKeyMap[key];
267
- });
268
- }
269
-
270
- var auctionData = {};
271
- var formattedKeyMap = {};
272
-
273
- if (isMacroPresent('targetingMap')) {
274
- formattedKeyMap = convertTargetingMapToNormalMap(tagData.targetingMap);
275
- } else if (isMacroPresent('targetingKeywords')) {
276
- formattedKeyMap = convertKeyPairStringToMap(tagData.targetingKeywords);
277
- }
278
-
279
- renameKnownAuctionKeys(formattedKeyMap); // set keys not in defined map macros (eg targetingMap) and/or the keys setup within a non-DFP adserver
280
-
281
- Object.keys(tagData).forEach(function (key) {
282
- if (key !== 'targetingMap' && key !== 'targetingKeywords' && isStr(tagData[key]) && tagData[key] !== '') {
283
- auctionData[key] = tagData[key];
284
- }
285
- });
286
- return auctionData;
287
- }
288
- function parseUrl(url) {
289
- var parsed = document.createElement('a');
290
- parsed.href = decodeURIComponent(url);
291
- return {
292
- href: parsed.href,
293
- protocol: (parsed.protocol || '').replace(/:$/, ''),
294
- hostname: parsed.hostname,
295
- port: +parsed.port,
296
- pathname: parsed.pathname.replace(/^(?!\/)/, '/'),
297
- hash: (parsed.hash || '').replace(/^#/, ''),
298
- host: (parsed.host || window.location.host).replace(/:(443|80)$/, '')
299
- };
300
- }
301
-
302
- function isA(object, _t) {
303
- return Object.prototype.toString.call(object) === '[object ' + _t + ']';
304
- }
305
-
306
- ;
307
-
308
- function isPlainObject(object) {
309
- return isA(object, 'Object');
310
- }
311
-
312
- function isStr(object) {
313
- return isA(object, 'String');
314
- }
315
-
316
- ;
317
-
318
- /***/ }),
319
- /* 1 */
320
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
321
-
322
- "use strict";
323
- /* harmony export (immutable) */ __webpack_exports__["a"] = getEmptyIframe;
324
- /* harmony export (immutable) */ __webpack_exports__["b"] = insertElement;
325
- /**
326
- * domHelper: a collection of helpful dom things
327
- */
328
-
329
- /**
330
- * returns a empty iframe element with specified height/width
331
- * @param {Number} height height iframe set to
332
- * @param {Number} width width iframe set to
333
- * @returns {Element} iframe DOM element
334
- */
335
- function getEmptyIframe(height, width) {
336
- var frame = document.createElement('iframe');
337
- frame.setAttribute('frameborder', 0);
338
- frame.setAttribute('scrolling', 'no');
339
- frame.setAttribute('marginheight', 0);
340
- frame.setAttribute('marginwidth', 0);
341
- frame.setAttribute('TOPMARGIN', 0);
342
- frame.setAttribute('LEFTMARGIN', 0);
343
- frame.setAttribute('allowtransparency', 'true');
344
- frame.setAttribute('width', width);
345
- frame.setAttribute('height', height);
346
- return frame;
347
- }
348
- /**
349
- * Insert element to passed target
350
- * @param {object} elm
351
- * @param {object} doc
352
- * @param {string} target
353
- */
354
-
355
- function insertElement(elm, doc, target) {
356
- doc = doc || document;
357
- var elToAppend;
358
-
359
- if (target) {
360
- elToAppend = doc.getElementsByTagName(target);
361
- } else {
362
- elToAppend = doc.getElementsByTagName('head');
363
- }
364
-
365
- try {
366
- elToAppend = elToAppend.length ? elToAppend : doc.getElementsByTagName('body');
367
-
368
- if (elToAppend.length) {
369
- elToAppend = elToAppend[0];
370
- elToAppend.insertBefore(elm, elToAppend.firstChild);
371
- }
372
- } catch (e) {}
373
- }
374
-
375
- /***/ }),
376
- /* 2 */
377
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
378
-
379
- "use strict";
380
- /* harmony export (immutable) */ __webpack_exports__["b"] = isAmp;
381
- /* harmony export (immutable) */ __webpack_exports__["d"] = isSafeFrame;
382
- /* unused harmony export isCrossDomain */
383
- /* unused harmony export canInspectWindow */
384
- /* harmony export (immutable) */ __webpack_exports__["a"] = canLocatePrebid;
385
- /* harmony export (immutable) */ __webpack_exports__["c"] = isMobileApp;
386
- /***************************************
387
- * Detect Environment Helper Functions
388
- ***************************************/
389
-
390
- /**
391
- * Functions to detect below environments:
392
- * Amp: google Accelerate Mobile Pages ampproject.org
393
- * SafeFrame: SafeFrame
394
- * CrossDomain: An iframe that can't get to the top window
395
- * Mobile App: function to detect mobile app environment
396
- */
397
-
398
- /**
399
- * @param {String} uuid key value from auction, contains the cache id of the winning bid stored in prebid cache
400
- * @returns true if there is an AMP context object
401
- */
402
- function isAmp(uuid, win) {
403
- // TODO Use amp context once it is available in cross domain
404
- // https://github.com/ampproject/amphtml/issues/6829
405
- return typeof uuid === 'string' && uuid !== "" && isCrossDomain(win);
406
- }
407
- /**
408
- * @returns true if the environment is a SafeFrame.
409
- */
410
-
411
- function isSafeFrame(win) {
412
- return !!(win.$sf && win.$sf.ext);
413
- }
414
- /**
415
- * Return true if we are in an iframe and can't access the top window.
416
- * @returns true if the environment is a Cross Domain
417
- */
418
-
419
- function isCrossDomain(win) {
420
- return win.top !== win && !canInspectWindow(win);
421
- }
422
- /**
423
- * Returns true if win's properties can be accessed and win is defined.
424
- * This functioned is used to determine if a window is cross-domained
425
- * from the perspective of the current window.
426
- * @param {!Window} win
427
- * @return {boolean}
428
- */
429
-
430
- function canInspectWindow(win) {
431
- try {
432
- // force an exception in x-domain environments. #1509
433
- win.top.location.toString();
434
- return true;
435
- } catch (e) {
436
- return false;
437
- }
438
- }
439
- /**
440
- * Returns true if we can find the prebid global object (eg pbjs) as we
441
- * climb the accessible windows. Return false if it's not found.
442
- * @returns {boolean}
443
- */
444
-
445
- function canLocatePrebid(win) {
446
- var result = false;
447
- var currentWindow = win;
448
-
449
- while (!result) {
450
- try {
451
- if (currentWindow.pbjs) {
452
- result = true;
453
- break;
454
- }
455
- } catch (e) {}
456
-
457
- if (currentWindow === window.top) break;
458
- currentWindow = currentWindow.parent;
459
- }
460
-
461
- return result;
462
- }
463
- /**
464
- * @param {String} env key value from auction, indicates the environment where tag is served
465
- * @returns true if env exists and is equal to the string 'mobile-app'
466
- */
467
-
468
- function isMobileApp(env) {
469
- return env && env === 'mobile-app';
470
- }
471
-
472
- /***/ }),
473
- /* 3 */
474
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
475
-
476
- "use strict";
477
- Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
478
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(0);
479
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__renderingManager__ = __webpack_require__(4);
480
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__mobileAndAmpRender__ = __webpack_require__(6);
481
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__environment__ = __webpack_require__(2);
482
- /**
483
- * legacy.js
484
- * This is deprecated code, publishers should not use one .js creative to handle all different types of creative.
485
- * To reduce bytes transfered for each ad, publishers should use specific .js based on hb_format targeting key-value.
486
- *
487
- * This file is inserted into the prebid creative as a placeholder for the winning prebid creative. It should support the following formats:
488
- * - Banner
489
- * - AMP
490
- * - Mobile
491
- * - Outstream Video
492
- * - All safeFrame creatives
493
- */
494
-
495
-
496
-
497
-
498
- window.ucTag = window.ucTag || {};
499
-
500
- window.ucTag.renderAd = function (doc, dataObject) {
501
- var targetingData = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["h" /* transformAuctionTargetingData */])(dataObject);
502
-
503
- if (Object(__WEBPACK_IMPORTED_MODULE_3__environment__["c" /* isMobileApp */])(targetingData.env) || Object(__WEBPACK_IMPORTED_MODULE_3__environment__["b" /* isAmp */])(targetingData.uuid, window)) {
504
- Object(__WEBPACK_IMPORTED_MODULE_2__mobileAndAmpRender__["a" /* renderAmpOrMobileAd */])(dataObject);
505
- } else {
506
- Object(__WEBPACK_IMPORTED_MODULE_1__renderingManager__["a" /* renderBannerOrDisplayAd */])(doc, dataObject);
507
- }
508
- };
509
-
510
- /***/ }),
511
- /* 4 */
512
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
513
-
514
- "use strict";
515
- /* harmony export (immutable) */ __webpack_exports__["a"] = renderBannerOrDisplayAd;
516
- /* unused harmony export renderLegacy */
517
- /* unused harmony export renderCrossDomain */
518
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(0);
519
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__environment__ = __webpack_require__(2);
520
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__domHelper__ = __webpack_require__(1);
521
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__messaging_js__ = __webpack_require__(5);
522
-
523
-
524
-
525
-
526
- function renderBannerOrDisplayAd(doc, dataObject) {
527
- var targetingData = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["h" /* transformAuctionTargetingData */])(dataObject);
528
-
529
- if (!Object(__WEBPACK_IMPORTED_MODULE_1__environment__["a" /* canLocatePrebid */])(window)) {
530
- renderCrossDomain(window, targetingData.adId, targetingData.adServerDomain, targetingData.pubUrl);
531
- } else {
532
- renderLegacy(doc, targetingData.adId);
533
- }
534
- }
535
- /**
536
- * Calls prebid.js renderAd function to render ad
537
- * @param {Object} doc Document
538
- * @param {string} adId Id of creative to render
539
- */
540
-
541
- function renderLegacy(doc, adId) {
542
- var found = false;
543
- var w = window;
544
-
545
- for (var i = 0; i < 10; i++) {
546
- w = w.parent;
547
-
548
- if (w.pbjs) {
549
- try {
550
- found = true;
551
- w.pbjs.renderAd(doc, adId);
552
- break;
553
- } catch (e) {
554
- continue;
555
- }
556
- }
557
- }
558
-
559
- if (!found) {
560
- console.error("Unable to locate pbjs.renderAd function!");
561
- }
562
- }
563
- /**
564
- * Render ad in safeframe using postmessage
565
- * @param {string} adId Id of creative to render
566
- * @param {string} pubAdServerDomain publisher adserver domain name
567
- * @param {string} pubUrl Url of publisher page
568
- */
569
-
570
- function renderCrossDomain(win, adId) {
571
- var pubAdServerDomain = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
572
- var pubUrl = arguments.length > 3 ? arguments[3] : undefined;
573
- var windowLocation = win.location;
574
- var adServerDomain = pubAdServerDomain || win.location.hostname;
575
- var fullAdServerDomain = windowLocation.protocol + '//' + adServerDomain;
576
- var sendMessage = Object(__WEBPACK_IMPORTED_MODULE_3__messaging_js__["a" /* prebidMessenger */])(pubUrl, win);
577
-
578
- function renderAd(ev) {
579
- var key = ev.message ? "message" : "data";
580
- var adObject = {};
581
-
582
- try {
583
- adObject = JSON.parse(ev[key]);
584
- } catch (e) {
585
- return;
586
- }
587
-
588
- if (adObject.message && adObject.message === "Prebid Response" && adObject.adId === adId) {
589
- try {
590
- var body = win.document.body;
591
- var ad = adObject.ad;
592
- var url = adObject.adUrl;
593
- var width = adObject.width;
594
- var height = adObject.height;
595
-
596
- if (adObject.mediaType === "video") {
597
- signalRenderResult(false, {
598
- reason: "preventWritingOnMainDocument",
599
- message: "Cannot render video ad ".concat(adId)
600
- });
601
- console.log("Error trying to write ad.");
602
- } else if (ad) {
603
- var iframe = Object(__WEBPACK_IMPORTED_MODULE_2__domHelper__["a" /* getEmptyIframe */])(adObject.height, adObject.width);
604
- body.appendChild(iframe);
605
- iframe.contentDocument.open();
606
- iframe.contentDocument.write(ad);
607
- iframe.contentDocument.close();
608
- signalRenderResult(true);
609
- } else if (url) {
610
- var _iframe = Object(__WEBPACK_IMPORTED_MODULE_2__domHelper__["a" /* getEmptyIframe */])(height, width);
611
-
612
- _iframe.style.display = "inline";
613
- _iframe.style.overflow = "hidden";
614
- _iframe.src = url;
615
- Object(__WEBPACK_IMPORTED_MODULE_2__domHelper__["b" /* insertElement */])(_iframe, document, "body");
616
- signalRenderResult(true);
617
- } else {
618
- signalRenderResult(false, {
619
- reason: "noAd",
620
- message: "No ad for ".concat(adId)
621
- });
622
- console.log("Error trying to write ad. No ad markup or adUrl for ".concat(adId));
623
- }
624
- } catch (e) {
625
- signalRenderResult(false, {
626
- reason: "exception",
627
- message: e.message
628
- });
629
- console.log("Error in rendering ad", e);
630
- }
631
- }
632
-
633
- function signalRenderResult(success) {
634
- var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
635
- reason = _ref.reason,
636
- message = _ref.message;
637
-
638
- var payload = {
639
- message: "Prebid Event",
640
- adId: adId,
641
- event: success ? "adRenderSucceeded" : "adRenderFailed"
642
- };
643
-
644
- if (!success) {
645
- payload.info = {
646
- reason: reason,
647
- message: message
648
- };
649
- }
650
-
651
- sendMessage(payload);
652
- }
653
- }
654
-
655
- function requestAdFromPrebid() {
656
- var message = {
657
- message: 'Prebid Request',
658
- adId: adId,
659
- adServerDomain: fullAdServerDomain
660
- };
661
- sendMessage(message, renderAd);
662
- }
663
-
664
- requestAdFromPrebid();
665
- }
666
-
667
- /***/ }),
668
- /* 5 */
669
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
670
-
671
- "use strict";
672
- /* harmony export (immutable) */ __webpack_exports__["a"] = prebidMessenger;
673
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(0);
674
-
675
- function prebidMessenger(publisherURL) {
676
- var win = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window;
677
-
678
- var prebidDomain = function () {
679
- if (publisherURL == null) {
680
- return null;
681
- }
682
-
683
- var parsedUrl = Object(__WEBPACK_IMPORTED_MODULE_0__utils_js__["f" /* parseUrl */])(publisherURL);
684
- return parsedUrl.protocol + '://' + parsedUrl.host;
685
- }();
686
-
687
- return function sendMessage(message, onResponse) {
688
- if (prebidDomain == null) {
689
- throw new Error('Missing pubUrl');
690
- }
691
-
692
- message = JSON.stringify(message);
693
- var messagePort;
694
-
695
- if (onResponse == null) {
696
- win.parent.postMessage(message, prebidDomain);
697
- } else {
698
- var channel = new MessageChannel();
699
- messagePort = channel.port1;
700
- messagePort.onmessage = onResponse;
701
- win.addEventListener('message', windowListener);
702
- win.parent.postMessage(message, prebidDomain, [channel.port2]);
703
- }
704
-
705
- return function stopListening() {
706
- if (messagePort != null) {
707
- win.removeEventListener('message', windowListener);
708
- messagePort.onmessage = null;
709
- messagePort = null;
710
- }
711
- };
712
-
713
- function windowListener(ev) {
714
- if ((ev.origin || ev.originalEvent && ev.originalEvent.origin) === prebidDomain) {
715
- onResponse(ev);
716
- }
717
- }
718
- };
719
- }
720
-
721
- /***/ }),
722
- /* 6 */
723
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
724
-
725
- "use strict";
726
- /* harmony export (immutable) */ __webpack_exports__["a"] = renderAmpOrMobileAd;
727
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(0);
728
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__environment__ = __webpack_require__(2);
729
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__domHelper__ = __webpack_require__(1);
730
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__postscribeRender__ = __webpack_require__(7);
731
-
732
-
733
-
734
-
735
- var DEFAULT_CACHE_HOST = 'prebid.adnxs.com';
736
- var DEFAULT_CACHE_PATH = '/pbc/v1/cache';
737
- /**
738
- * Render mobile or amp ad
739
- * @param {string} cacheHost Cache host
740
- * @param {string} cachePath Cache path
741
- * @param {string} uuid id to render response from cache endpoint
742
- * @param {string} size size of the creative
743
- * @param {string} hbPb final price of the winning bid
744
- * @param {Bool} isMobileApp flag to detect mobile app
745
- */
746
-
747
- function renderAmpOrMobileAd(dataObject) {
748
- var targetingData = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["h" /* transformAuctionTargetingData */])(dataObject);
749
- var cacheHost = targetingData.cacheHost,
750
- cachePath = targetingData.cachePath,
751
- uuid = targetingData.uuid,
752
- size = targetingData.size,
753
- hbPb = targetingData.hbPb;
754
- uuid = uuid || ''; // For MoPub, creative is stored in localStorage via SDK.
755
-
756
- var search = 'Prebid_';
757
-
758
- if (uuid.substr(0, search.length) === search) {
759
- loadFromLocalCache(uuid); //register creative right away to not miss initial geom-update
760
-
761
- updateIframe(size);
762
- } else {
763
- var adUrl = "".concat(getCacheEndpoint(cacheHost, cachePath), "?uuid=").concat(uuid); //register creative right away to not miss initial geom-update
764
-
765
- updateIframe(size);
766
- Object(__WEBPACK_IMPORTED_MODULE_0__utils__["g" /* sendRequest */])(adUrl, responseCallback(Object(__WEBPACK_IMPORTED_MODULE_1__environment__["c" /* isMobileApp */])(targetingData.env), hbPb));
767
- }
768
- }
769
- /**
770
- * Load response from localStorage. In case of MoPub, sdk caches response
771
- * @param {string} cacheId
772
- */
773
-
774
- function loadFromLocalCache(cacheId) {
775
- var bid = window.localStorage.getItem(cacheId);
776
- var displayFn = responseCallback(true);
777
- displayFn(bid);
778
- }
779
- /**
780
- * update iframe by using size string to resize
781
- * @param {string} size
782
- */
783
-
784
-
785
- function updateIframe(size) {
786
- if (size) {
787
- var sizeArr = size.split('x').map(Number);
788
- resizeIframe(sizeArr[0], sizeArr[1]);
789
- } else {
790
- console.log('Targeting key hb_size not found to resize creative');
791
- }
792
- }
793
- /**
794
- * Resize container iframe
795
- * @param {Number} width width of creative
796
- * @param {Number} height height of creative
797
- */
798
-
799
-
800
- function resizeIframe(width, height) {
801
- if (Object(__WEBPACK_IMPORTED_MODULE_1__environment__["d" /* isSafeFrame */])(window)) {
802
- var resize = function resize(status) {
803
- var newWidth = width - iframeWidth;
804
- var newHeight = height - iframeHeight;
805
- window.$sf.ext.expand({
806
- r: newWidth,
807
- b: newHeight,
808
- push: true
809
- });
810
- };
811
-
812
- var iframeWidth = window.innerWidth;
813
- var iframeHeight = window.innerHeight;
814
-
815
- if (iframeWidth !== width || iframeHeight !== height) {
816
- window.$sf.ext.register(width, height, resize); // we need to resize the DFP container as well
817
-
818
- window.parent.postMessage({
819
- sentinel: 'amp',
820
- type: 'embed-size',
821
- width: width,
822
- height: height
823
- }, '*');
824
- }
825
- }
826
- }
827
- /**
828
- * Returns cache endpoint concatenated with cache path
829
- * @param {string} cacheHost Cache Endpoint host
830
- * @param {string} cachePath Cache Endpoint path
831
- */
832
-
833
-
834
- function getCacheEndpoint(cacheHost, cachePath) {
835
- var host = typeof cacheHost === 'undefined' || cacheHost === "" ? DEFAULT_CACHE_HOST : cacheHost;
836
- var path = typeof cachePath === 'undefined' || cachePath === "" ? DEFAULT_CACHE_PATH : cachePath;
837
- return "https://".concat(host).concat(path);
838
- }
839
- /**
840
- * Cache request Callback to display creative
841
- * @param {Bool} isMobileApp
842
- * @param {string} hbPb final price of the winning bid
843
- * @returns {function} a callback function that parses response
844
- */
845
-
846
-
847
- function responseCallback(isMobileApp, hbPb) {
848
- return function (response) {
849
- var bidObject = parseResponse(response);
850
- var auctionPrice = bidObject.price || hbPb;
851
- var ad = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["c" /* getCreativeCommentMarkup */])(bidObject);
852
- var width = bidObject.width ? bidObject.width : bidObject.w;
853
- var height = bidObject.height ? bidObject.height : bidObject.h; // 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.
854
-
855
- if (bidObject.wurl) {
856
- Object(__WEBPACK_IMPORTED_MODULE_0__utils__["i" /* triggerPixel */])(decodeURIComponent(bidObject.wurl));
857
- }
858
-
859
- if (bidObject.adm) {
860
- if (auctionPrice) {
861
- // replace ${AUCTION_PRICE} macro with the bidObject.price or hb_pb.
862
- bidObject.adm = bidObject.adm.replace('${AUCTION_PRICE}', auctionPrice);
863
- } else {
864
- /*
865
- 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).
866
- */
867
- bidObject.adm = bidObject.adm.replace('${AUCTION_PRICE}', '');
868
- }
869
-
870
- ad += isMobileApp ? constructMarkup(bidObject.adm, width, height) : bidObject.adm;
871
-
872
- if (bidObject.nurl) {
873
- ad += Object(__WEBPACK_IMPORTED_MODULE_0__utils__["a" /* createTrackPixelHtml */])(decodeURIComponent(bidObject.nurl));
874
- }
875
-
876
- if (bidObject.burl) {
877
- var triggerBurl = function triggerBurl() {
878
- Object(__WEBPACK_IMPORTED_MODULE_0__utils__["i" /* triggerPixel */])(bidObject.burl);
879
- };
880
-
881
- if (isMobileApp) {
882
- var mraidScript = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["e" /* loadScript */])(window, 'mraid.js', function () {
883
- // Success loading MRAID
884
- var result = registerMRAIDViewableEvent(triggerBurl);
885
-
886
- if (!result) {
887
- triggerBurl(); // Error registering event
888
- }
889
- }, triggerBurl // Error loading MRAID
890
- );
891
- } else {
892
- triggerBurl(); // Not a mobile app
893
- }
894
- }
895
-
896
- Object(__WEBPACK_IMPORTED_MODULE_3__postscribeRender__["a" /* writeAdHtml */])(ad);
897
- } else if (bidObject.nurl) {
898
- if (isMobileApp) {
899
- var adhtml = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["e" /* loadScript */])(window, bidObject.nurl);
900
- ad += constructMarkup(adhtml.outerHTML, width, height);
901
- Object(__WEBPACK_IMPORTED_MODULE_3__postscribeRender__["a" /* writeAdHtml */])(ad);
902
- } else {
903
- var nurl = bidObject.nurl;
904
- var commentElm = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["b" /* getCreativeComment */])(bidObject);
905
- Object(__WEBPACK_IMPORTED_MODULE_2__domHelper__["b" /* insertElement */])(commentElm, document, 'body');
906
- Object(__WEBPACK_IMPORTED_MODULE_0__utils__["j" /* writeAdUrl */])(nurl, width, height);
907
- }
908
- }
909
- };
910
- }
911
-
912
- ;
913
- /**
914
- * Parse response
915
- * @param {string} response
916
- * @returns {Object} bidObject parsed response
917
- */
918
-
919
- function parseResponse(response) {
920
- var bidObject;
921
-
922
- try {
923
- bidObject = JSON.parse(response);
924
- } catch (error) {
925
- console.log("Error parsing response from cache host: ".concat(error));
926
- }
927
-
928
- return bidObject;
929
- }
930
- /**
931
- * Wrap mobile app creative in div
932
- * @param {string} ad html for creative
933
- * @param {Number} width width of creative
934
- * @param {Number} height height of creative
935
- * @returns {string} creative markup
936
- */
937
-
938
-
939
- function constructMarkup(ad, width, height) {
940
- var id = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["d" /* getUUID */])();
941
- 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>");
942
- }
943
-
944
- function registerMRAIDViewableEvent(callback) {
945
- function exposureChangeListener(exposure) {
946
- if (exposure > 0) {
947
- mraid.removeEventListener('exposureChange', exposureChangeListener);
948
- callback();
949
- }
950
- }
951
-
952
- function viewableChangeListener(viewable) {
953
- if (viewable) {
954
- mraid.removeEventListener('viewableChange', viewableChangeListener);
955
- callback();
956
- }
957
- }
958
-
959
- function registerViewableChecks() {
960
- if (window.MRAID_ENV && parseFloat(window.MRAID_ENV.version) >= 3) {
961
- mraid.addEventListener('exposureChange', exposureChangeListener);
962
- } else if (window.MRAID_ENV && parseFloat(window.MRAID_ENV.version) < 3) {
963
- if (mraid.isViewable()) {
964
- callback();
965
- } else {
966
- mraid.addEventListener('viewableChange', viewableChangeListener);
967
- }
968
- }
969
- }
970
-
971
- function readyListener() {
972
- mraid.removeEventListener('ready', readyListener);
973
- registerViewableChecks();
974
- }
975
-
976
- if (window.mraid && window.MRAID_ENV) {
977
- if (mraid.getState() == 'loading') {
978
- mraid.addEventListener('ready', readyListener);
979
- } else {
980
- registerViewableChecks();
981
- }
982
-
983
- return true;
984
- } else {
985
- return false;
986
- }
987
- }
988
-
989
- /***/ }),
990
- /* 7 */
991
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
992
-
993
- "use strict";
994
- /* harmony export (immutable) */ __webpack_exports__["a"] = writeAdHtml;
995
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_postscribe__ = __webpack_require__(8);
996
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_postscribe___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_postscribe__);
997
-
998
- function writeAdHtml(markup) {
999
- var ps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : __WEBPACK_IMPORTED_MODULE_0_postscribe___default.a;
1000
- // remove <?xml> and <!doctype> tags
1001
- // https://github.com/prebid/prebid-universal-creative/issues/134
1002
- markup = markup.replace(/\<(\?xml|(\!DOCTYPE[^\>\[]+(\[[^\]]+)?))+[^>]+\>/g, '');
1003
- ps(document.body, markup, {
1004
- error: console.error
1005
- });
1006
- }
1007
-
1008
- /***/ }),
1009
- /* 8 */
1010
- /***/ (function(module, exports, __webpack_require__) {
1011
-
1012
- /**
1013
- * @file postscribe
1014
- * @description Asynchronously write javascript, even with document.write.
1015
- * @version v2.0.8
1016
- * @see {@link https://krux.github.io/postscribe}
1017
- * @license MIT
1018
- * @author Derek Brans
1019
- * @copyright 2016 Krux Digital, Inc
1020
- */
1021
- (function webpackUniversalModuleDefinition(root, factory) {
1022
- if(true)
1023
- module.exports = factory();
1024
- else if(typeof define === 'function' && define.amd)
1025
- define([], factory);
1026
- else if(typeof exports === 'object')
1027
- exports["postscribe"] = factory();
1028
- else
1029
- root["postscribe"] = factory();
1030
- })(this, function() {
1031
- return /******/ (function(modules) { // webpackBootstrap
1032
- /******/ // The module cache
1033
- /******/ var installedModules = {};
1034
- /******/
1035
- /******/ // The require function
1036
- /******/ function __webpack_require__(moduleId) {
1037
- /******/
1038
- /******/ // Check if module is in cache
1039
- /******/ if(installedModules[moduleId])
1040
- /******/ return installedModules[moduleId].exports;
1041
- /******/
1042
- /******/ // Create a new module (and put it into the cache)
1043
- /******/ var module = installedModules[moduleId] = {
1044
- /******/ exports: {},
1045
- /******/ id: moduleId,
1046
- /******/ loaded: false
1047
- /******/ };
1048
- /******/
1049
- /******/ // Execute the module function
1050
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
1051
- /******/
1052
- /******/ // Flag the module as loaded
1053
- /******/ module.loaded = true;
1054
- /******/
1055
- /******/ // Return the exports of the module
1056
- /******/ return module.exports;
1057
- /******/ }
1058
- /******/
1059
- /******/
1060
- /******/ // expose the modules object (__webpack_modules__)
1061
- /******/ __webpack_require__.m = modules;
1062
- /******/
1063
- /******/ // expose the module cache
1064
- /******/ __webpack_require__.c = installedModules;
1065
- /******/
1066
- /******/ // __webpack_public_path__
1067
- /******/ __webpack_require__.p = "";
1068
- /******/
1069
- /******/ // Load entry module and return exports
1070
- /******/ return __webpack_require__(0);
1071
- /******/ })
1072
- /************************************************************************/
1073
- /******/ ([
1074
- /* 0 */
1075
- /***/ function(module, exports, __webpack_require__) {
1076
-
1077
- 'use strict';
1078
-
1079
- var _postscribe = __webpack_require__(1);
1080
-
1081
- var _postscribe2 = _interopRequireDefault(_postscribe);
1082
-
1083
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
1084
-
1085
- module.exports = _postscribe2['default'];
1086
-
1087
- /***/ },
1088
- /* 1 */
1089
- /***/ function(module, exports, __webpack_require__) {
1090
-
1091
- 'use strict';
1092
-
1093
- exports.__esModule = true;
1094
-
1095
- var _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; };
1096
-
1097
- exports['default'] = postscribe;
1098
-
1099
- var _writeStream = __webpack_require__(2);
1100
-
1101
- var _writeStream2 = _interopRequireDefault(_writeStream);
1102
-
1103
- var _utils = __webpack_require__(4);
1104
-
1105
- var utils = _interopRequireWildcard(_utils);
1106
-
1107
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
1108
-
1109
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
1110
-
1111
- /**
1112
- * A function that intentionally does nothing.
1113
- */
1114
- function doNothing() {}
1115
-
1116
- /**
1117
- * Available options and defaults.
1118
- *
1119
- * @type {Object}
1120
- */
1121
- var OPTIONS = {
1122
- /**
1123
- * Called when an async script has loaded.
1124
- */
1125
- afterAsync: doNothing,
1126
-
1127
- /**
1128
- * Called immediately before removing from the write queue.
1129
- */
1130
- afterDequeue: doNothing,
1131
-
1132
- /**
1133
- * Called sync after a stream's first thread release.
1134
- */
1135
- afterStreamStart: doNothing,
1136
-
1137
- /**
1138
- * Called after writing buffered document.write calls.
1139
- */
1140
- afterWrite: doNothing,
1141
-
1142
- /**
1143
- * Allows disabling the autoFix feature of prescribe
1144
- */
1145
- autoFix: true,
1146
-
1147
- /**
1148
- * Called immediately before adding to the write queue.
1149
- */
1150
- beforeEnqueue: doNothing,
1151
-
1152
- /**
1153
- * Called before writing a token.
1154
- *
1155
- * @param {Object} tok The token
1156
- */
1157
- beforeWriteToken: function beforeWriteToken(tok) {
1158
- return tok;
1159
- },
1160
-
1161
- /**
1162
- * Called before writing buffered document.write calls.
1163
- *
1164
- * @param {String} str The string
1165
- */
1166
- beforeWrite: function beforeWrite(str) {
1167
- return str;
1168
- },
1169
-
1170
- /**
1171
- * Called when evaluation is finished.
1172
- */
1173
- done: doNothing,
1174
-
1175
- /**
1176
- * Called when a write results in an error.
1177
- *
1178
- * @param {Error} e The error
1179
- */
1180
- error: function error(e) {
1181
- throw new Error(e.msg);
1182
- },
1183
-
1184
-
1185
- /**
1186
- * Whether to let scripts w/ async attribute set fall out of the queue.
1187
- */
1188
- releaseAsync: false
1189
- };
1190
-
1191
- var nextId = 0;
1192
- var queue = [];
1193
- var active = null;
1194
-
1195
- function nextStream() {
1196
- var args = queue.shift();
1197
- if (args) {
1198
- var options = utils.last(args);
1199
-
1200
- options.afterDequeue();
1201
- args.stream = runStream.apply(undefined, args);
1202
- options.afterStreamStart();
1203
- }
1204
- }
1205
-
1206
- function runStream(el, html, options) {
1207
- active = new _writeStream2['default'](el, options);
1208
-
1209
- // Identify this stream.
1210
- active.id = nextId++;
1211
- active.name = options.name || active.id;
1212
- postscribe.streams[active.name] = active;
1213
-
1214
- // Override document.write.
1215
- var doc = el.ownerDocument;
1216
-
1217
- var stash = {
1218
- close: doc.close,
1219
- open: doc.open,
1220
- write: doc.write,
1221
- writeln: doc.writeln
1222
- };
1223
-
1224
- function _write(str) {
1225
- str = options.beforeWrite(str);
1226
- active.write(str);
1227
- options.afterWrite(str);
1228
- }
1229
-
1230
- _extends(doc, {
1231
- close: doNothing,
1232
- open: doNothing,
1233
- write: function write() {
1234
- for (var _len = arguments.length, str = Array(_len), _key = 0; _key < _len; _key++) {
1235
- str[_key] = arguments[_key];
1236
- }
1237
-
1238
- return _write(str.join(''));
1239
- },
1240
- writeln: function writeln() {
1241
- for (var _len2 = arguments.length, str = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
1242
- str[_key2] = arguments[_key2];
1243
- }
1244
-
1245
- return _write(str.join('') + '\n');
1246
- }
1247
- });
1248
-
1249
- // Override window.onerror
1250
- var oldOnError = active.win.onerror || doNothing;
1251
-
1252
- // This works together with the try/catch around WriteStream::insertScript
1253
- // In modern browsers, exceptions in tag scripts go directly to top level
1254
- active.win.onerror = function (msg, url, line) {
1255
- options.error({ msg: msg + ' - ' + url + ': ' + line });
1256
- oldOnError.apply(active.win, [msg, url, line]);
1257
- };
1258
-
1259
- // Write to the stream
1260
- active.write(html, function () {
1261
- // restore document.write
1262
- _extends(doc, stash);
1263
-
1264
- // restore window.onerror
1265
- active.win.onerror = oldOnError;
1266
-
1267
- options.done();
1268
- active = null;
1269
- nextStream();
1270
- });
1271
-
1272
- return active;
1273
- }
1274
-
1275
- function postscribe(el, html, options) {
1276
- if (utils.isFunction(options)) {
1277
- options = { done: options };
1278
- } else if (options === 'clear') {
1279
- queue = [];
1280
- active = null;
1281
- nextId = 0;
1282
- return;
1283
- }
1284
-
1285
- options = utils.defaults(options, OPTIONS);
1286
-
1287
- // id selector
1288
- if (/^#/.test(el)) {
1289
- el = window.document.getElementById(el.substr(1));
1290
- } else {
1291
- el = el.jquery ? el[0] : el;
1292
- }
1293
-
1294
- var args = [el, html, options];
1295
-
1296
- el.postscribe = {
1297
- cancel: function cancel() {
1298
- if (args.stream) {
1299
- args.stream.abort();
1300
- } else {
1301
- args[1] = doNothing;
1302
- }
1303
- }
1304
- };
1305
-
1306
- options.beforeEnqueue(args);
1307
- queue.push(args);
1308
-
1309
- if (!active) {
1310
- nextStream();
1311
- }
1312
-
1313
- return el.postscribe;
1314
- }
1315
-
1316
- _extends(postscribe, {
1317
- // Streams by name.
1318
- streams: {},
1319
- // Queue of streams.
1320
- queue: queue,
1321
- // Expose internal classes.
1322
- WriteStream: _writeStream2['default']
1323
- });
1324
-
1325
- /***/ },
1326
- /* 2 */
1327
- /***/ function(module, exports, __webpack_require__) {
1328
-
1329
- 'use strict';
1330
-
1331
- exports.__esModule = true;
1332
-
1333
- var _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; };
1334
-
1335
- var _prescribe = __webpack_require__(3);
1336
-
1337
- var _prescribe2 = _interopRequireDefault(_prescribe);
1338
-
1339
- var _utils = __webpack_require__(4);
1340
-
1341
- var utils = _interopRequireWildcard(_utils);
1342
-
1343
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
1344
-
1345
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
1346
-
1347
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1348
-
1349
- /**
1350
- * Turn on to debug how each chunk affected the DOM.
1351
- * @type {boolean}
1352
- */
1353
- var DEBUG_CHUNK = false;
1354
-
1355
- /**
1356
- * Prefix for data attributes on DOM elements.
1357
- * @type {string}
1358
- */
1359
- var BASEATTR = 'data-ps-';
1360
-
1361
- /**
1362
- * ID for the style proxy
1363
- * @type {string}
1364
- */
1365
- var PROXY_STYLE = 'ps-style';
1366
-
1367
- /**
1368
- * ID for the script proxy
1369
- * @type {string}
1370
- */
1371
- var PROXY_SCRIPT = 'ps-script';
1372
-
1373
- /**
1374
- * Get data attributes
1375
- *
1376
- * @param {Object} el The DOM element.
1377
- * @param {String} name The attribute name.
1378
- * @returns {String}
1379
- */
1380
- function getData(el, name) {
1381
- var attr = BASEATTR + name;
1382
-
1383
- var val = el.getAttribute(attr);
1384
-
1385
- // IE 8 returns a number if it's a number
1386
- return !utils.existy(val) ? val : String(val);
1387
- }
1388
-
1389
- /**
1390
- * Set data attributes
1391
- *
1392
- * @param {Object} el The DOM element.
1393
- * @param {String} name The attribute name.
1394
- * @param {null|*} value The attribute value.
1395
- */
1396
- function setData(el, name) {
1397
- var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
1398
-
1399
- var attr = BASEATTR + name;
1400
-
1401
- if (utils.existy(value) && value !== '') {
1402
- el.setAttribute(attr, value);
1403
- } else {
1404
- el.removeAttribute(attr);
1405
- }
1406
- }
1407
-
1408
- /**
1409
- * Stream static html to an element, where "static html" denotes "html
1410
- * without scripts".
1411
- *
1412
- * This class maintains a *history of writes devoid of any attributes* or
1413
- * "proxy history".
1414
- *
1415
- * Injecting the proxy history into a temporary div has no side-effects,
1416
- * other than to create proxy elements for previously written elements.
1417
- *
1418
- * Given the `staticHtml` of a new write, a `tempDiv`'s innerHTML is set to
1419
- * `proxy_history + staticHtml`.
1420
- * The *structure* of `tempDiv`'s contents, (i.e., the placement of new nodes
1421
- * beside or inside of proxy elements), reflects the DOM structure that would
1422
- * have resulted if all writes had been squashed into a single write.
1423
- *
1424
- * For each descendent `node` of `tempDiv` whose parentNode is a *proxy*,
1425
- * `node` is appended to the corresponding *real* element within the DOM.
1426
- *
1427
- * Proxy elements are mapped to *actual* elements in the DOM by injecting a
1428
- * `data-id` attribute into each start tag in `staticHtml`.
1429
- *
1430
- */
1431
-
1432
- var WriteStream = function () {
1433
- /**
1434
- * Constructor.
1435
- *
1436
- * @param {Object} root The root element
1437
- * @param {?Object} options The options
1438
- */
1439
- function WriteStream(root) {
1440
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1441
-
1442
- _classCallCheck(this, WriteStream);
1443
-
1444
- this.root = root;
1445
- this.options = options;
1446
- this.doc = root.ownerDocument;
1447
- this.win = this.doc.defaultView || this.doc.parentWindow;
1448
- this.parser = new _prescribe2['default']('', { autoFix: options.autoFix });
1449
-
1450
- // Actual elements by id.
1451
- this.actuals = [root];
1452
-
1453
- // Embodies the "structure" of what's been written so far,
1454
- // devoid of attributes.
1455
- this.proxyHistory = '';
1456
-
1457
- // Create a proxy of the root element.
1458
- this.proxyRoot = this.doc.createElement(root.nodeName);
1459
-
1460
- this.scriptStack = [];
1461
- this.writeQueue = [];
1462
-
1463
- setData(this.proxyRoot, 'proxyof', 0);
1464
- }
1465
-
1466
- /**
1467
- * Writes the given strings.
1468
- *
1469
- * @param {...String} str The strings to write
1470
- */
1471
-
1472
-
1473
- WriteStream.prototype.write = function write() {
1474
- var _writeQueue;
1475
-
1476
- (_writeQueue = this.writeQueue).push.apply(_writeQueue, arguments);
1477
-
1478
- // Process writes
1479
- // When new script gets pushed or pending this will stop
1480
- // because new writeQueue gets pushed
1481
- while (!this.deferredRemote && this.writeQueue.length) {
1482
- var arg = this.writeQueue.shift();
1483
-
1484
- if (utils.isFunction(arg)) {
1485
- this._callFunction(arg);
1486
- } else {
1487
- this._writeImpl(arg);
1488
- }
1489
- }
1490
- };
1491
-
1492
- /**
1493
- * Calls the given function.
1494
- *
1495
- * @param {Function} fn The function to call
1496
- * @private
1497
- */
1498
-
1499
-
1500
- WriteStream.prototype._callFunction = function _callFunction(fn) {
1501
- var tok = { type: 'function', value: fn.name || fn.toString() };
1502
- this._onScriptStart(tok);
1503
- fn.call(this.win, this.doc);
1504
- this._onScriptDone(tok);
1505
- };
1506
-
1507
- /**
1508
- * The write implementation
1509
- *
1510
- * @param {String} html The HTML to write.
1511
- * @private
1512
- */
1513
-
1514
-
1515
- WriteStream.prototype._writeImpl = function _writeImpl(html) {
1516
- this.parser.append(html);
1517
-
1518
- var tok = void 0;
1519
- var script = void 0;
1520
- var style = void 0;
1521
- var tokens = [];
1522
-
1523
- // stop if we see a script token
1524
- while ((tok = this.parser.readToken()) && !(script = utils.isScript(tok)) && !(style = utils.isStyle(tok))) {
1525
- tok = this.options.beforeWriteToken(tok);
1526
-
1527
- if (tok) {
1528
- tokens.push(tok);
1529
- }
1530
- }
1531
-
1532
- if (tokens.length > 0) {
1533
- this._writeStaticTokens(tokens);
1534
- }
1535
-
1536
- if (script) {
1537
- this._handleScriptToken(tok);
1538
- }
1539
-
1540
- if (style) {
1541
- this._handleStyleToken(tok);
1542
- }
1543
- };
1544
-
1545
- /**
1546
- * Write contiguous non-script tokens (a chunk)
1547
- *
1548
- * @param {Array<Object>} tokens The tokens
1549
- * @returns {{tokens, raw, actual, proxy}|null}
1550
- * @private
1551
- */
1552
-
1553
-
1554
- WriteStream.prototype._writeStaticTokens = function _writeStaticTokens(tokens) {
1555
- var chunk = this._buildChunk(tokens);
1556
-
1557
- if (!chunk.actual) {
1558
- // e.g., no tokens, or a noscript that got ignored
1559
- return null;
1560
- }
1561
-
1562
- chunk.html = this.proxyHistory + chunk.actual;
1563
- this.proxyHistory += chunk.proxy;
1564
- this.proxyRoot.innerHTML = chunk.html;
1565
-
1566
- if (DEBUG_CHUNK) {
1567
- chunk.proxyInnerHTML = this.proxyRoot.innerHTML;
1568
- }
1569
-
1570
- this._walkChunk();
1571
-
1572
- if (DEBUG_CHUNK) {
1573
- chunk.actualInnerHTML = this.root.innerHTML;
1574
- }
1575
-
1576
- return chunk;
1577
- };
1578
-
1579
- /**
1580
- * Build a chunk.
1581
- *
1582
- * @param {Array<Object>} tokens The tokens to use.
1583
- * @returns {{tokens: *, raw: string, actual: string, proxy: string}}
1584
- * @private
1585
- */
1586
-
1587
-
1588
- WriteStream.prototype._buildChunk = function _buildChunk(tokens) {
1589
- var nextId = this.actuals.length;
1590
-
1591
- // The raw html of this chunk.
1592
- var raw = [];
1593
-
1594
- // The html to create the nodes in the tokens (with id's injected).
1595
- var actual = [];
1596
-
1597
- // Html that can later be used to proxy the nodes in the tokens.
1598
- var proxy = [];
1599
-
1600
- var len = tokens.length;
1601
- for (var i = 0; i < len; i++) {
1602
- var tok = tokens[i];
1603
- var tokenRaw = tok.toString();
1604
-
1605
- raw.push(tokenRaw);
1606
-
1607
- if (tok.attrs) {
1608
- // tok.attrs <==> startTag or atomicTag or cursor
1609
- // Ignore noscript tags. They are atomic, so we don't have to worry about children.
1610
- if (!/^noscript$/i.test(tok.tagName)) {
1611
- var id = nextId++;
1612
-
1613
- // Actual: inject id attribute: replace '>' at end of start tag with id attribute + '>'
1614
- actual.push(tokenRaw.replace(/(\/?>)/, ' ' + BASEATTR + 'id=' + id + ' $1'));
1615
-
1616
- // Don't proxy scripts: they have no bearing on DOM structure.
1617
- if (tok.attrs.id !== PROXY_SCRIPT && tok.attrs.id !== PROXY_STYLE) {
1618
- // Proxy: strip all attributes and inject proxyof attribute
1619
- proxy.push(
1620
- // ignore atomic tags (e.g., style): they have no "structural" effect
1621
- tok.type === 'atomicTag' ? '' : '<' + tok.tagName + ' ' + BASEATTR + 'proxyof=' + id + (tok.unary ? ' />' : '>'));
1622
- }
1623
- }
1624
- } else {
1625
- // Visit any other type of token
1626
- // Actual: append.
1627
- actual.push(tokenRaw);
1628
-
1629
- // Proxy: append endTags. Ignore everything else.
1630
- proxy.push(tok.type === 'endTag' ? tokenRaw : '');
1631
- }
1632
- }
1633
-
1634
- return {
1635
- tokens: tokens,
1636
- raw: raw.join(''),
1637
- actual: actual.join(''),
1638
- proxy: proxy.join('')
1639
- };
1640
- };
1641
-
1642
- /**
1643
- * Walk the chunks.
1644
- *
1645
- * @private
1646
- */
1647
-
1648
-
1649
- WriteStream.prototype._walkChunk = function _walkChunk() {
1650
- var node = void 0;
1651
- var stack = [this.proxyRoot];
1652
-
1653
- // use shift/unshift so that children are walked in document order
1654
- while (utils.existy(node = stack.shift())) {
1655
- var isElement = node.nodeType === 1;
1656
- var isProxy = isElement && getData(node, 'proxyof');
1657
-
1658
- // Ignore proxies
1659
- if (!isProxy) {
1660
- if (isElement) {
1661
- // New actual element: register it and remove the the id attr.
1662
- this.actuals[getData(node, 'id')] = node;
1663
- setData(node, 'id');
1664
- }
1665
-
1666
- // Is node's parent a proxy?
1667
- var parentIsProxyOf = node.parentNode && getData(node.parentNode, 'proxyof');
1668
- if (parentIsProxyOf) {
1669
- // Move node under actual parent.
1670
- this.actuals[parentIsProxyOf].appendChild(node);
1671
- }
1672
- }
1673
-
1674
- // prepend childNodes to stack
1675
- stack.unshift.apply(stack, utils.toArray(node.childNodes));
1676
- }
1677
- };
1678
-
1679
- /**
1680
- * Handles Script tokens
1681
- *
1682
- * @param {Object} tok The token
1683
- */
1684
-
1685
-
1686
- WriteStream.prototype._handleScriptToken = function _handleScriptToken(tok) {
1687
- var _this = this;
1688
-
1689
- var remainder = this.parser.clear();
1690
-
1691
- if (remainder) {
1692
- // Write remainder immediately behind this script.
1693
- this.writeQueue.unshift(remainder);
1694
- }
1695
-
1696
- tok.src = tok.attrs.src || tok.attrs.SRC;
1697
-
1698
- tok = this.options.beforeWriteToken(tok);
1699
- if (!tok) {
1700
- // User has removed this token
1701
- return;
1702
- }
1703
-
1704
- if (tok.src && this.scriptStack.length) {
1705
- // Defer this script until scriptStack is empty.
1706
- // Assumption 1: This script will not start executing until
1707
- // scriptStack is empty.
1708
- this.deferredRemote = tok;
1709
- } else {
1710
- this._onScriptStart(tok);
1711
- }
1712
-
1713
- // Put the script node in the DOM.
1714
- this._writeScriptToken(tok, function () {
1715
- _this._onScriptDone(tok);
1716
- });
1717
- };
1718
-
1719
- /**
1720
- * Handles style tokens
1721
- *
1722
- * @param {Object} tok The token
1723
- */
1724
-
1725
-
1726
- WriteStream.prototype._handleStyleToken = function _handleStyleToken(tok) {
1727
- var remainder = this.parser.clear();
1728
-
1729
- if (remainder) {
1730
- // Write remainder immediately behind this style.
1731
- this.writeQueue.unshift(remainder);
1732
- }
1733
-
1734
- tok.type = tok.attrs.type || tok.attrs.TYPE || 'text/css';
1735
-
1736
- tok = this.options.beforeWriteToken(tok);
1737
-
1738
- if (tok) {
1739
- // Put the style node in the DOM.
1740
- this._writeStyleToken(tok);
1741
- }
1742
-
1743
- if (remainder) {
1744
- this.write();
1745
- }
1746
- };
1747
-
1748
- /**
1749
- * Build a style and insert it into the DOM.
1750
- *
1751
- * @param {Object} tok The token
1752
- */
1753
-
1754
-
1755
- WriteStream.prototype._writeStyleToken = function _writeStyleToken(tok) {
1756
- var el = this._buildStyle(tok);
1757
-
1758
- this._insertCursor(el, PROXY_STYLE);
1759
-
1760
- // Set content
1761
- if (tok.content) {
1762
- if (el.styleSheet && !el.sheet) {
1763
- el.styleSheet.cssText = tok.content;
1764
- } else {
1765
- el.appendChild(this.doc.createTextNode(tok.content));
1766
- }
1767
- }
1768
- };
1769
-
1770
- /**
1771
- * Build a style element from an atomic style token.
1772
- *
1773
- * @param {Object} tok The token
1774
- * @returns {Element}
1775
- */
1776
-
1777
-
1778
- WriteStream.prototype._buildStyle = function _buildStyle(tok) {
1779
- var el = this.doc.createElement(tok.tagName);
1780
-
1781
- el.setAttribute('type', tok.type);
1782
-
1783
- // Set attributes
1784
- utils.eachKey(tok.attrs, function (name, value) {
1785
- el.setAttribute(name, value);
1786
- });
1787
-
1788
- return el;
1789
- };
1790
-
1791
- /**
1792
- * Append a span to the stream. That span will act as a cursor
1793
- * (i.e. insertion point) for the element.
1794
- *
1795
- * @param {Object} el The element
1796
- * @param {string} which The type of proxy element
1797
- */
1798
-
1799
-
1800
- WriteStream.prototype._insertCursor = function _insertCursor(el, which) {
1801
- this._writeImpl('<span id="' + which + '"/>');
1802
-
1803
- var cursor = this.doc.getElementById(which);
1804
-
1805
- if (cursor) {
1806
- cursor.parentNode.replaceChild(el, cursor);
1807
- }
1808
- };
1809
-
1810
- /**
1811
- * Called when a script is started.
1812
- *
1813
- * @param {Object} tok The token
1814
- * @private
1815
- */
1816
-
1817
-
1818
- WriteStream.prototype._onScriptStart = function _onScriptStart(tok) {
1819
- tok.outerWrites = this.writeQueue;
1820
- this.writeQueue = [];
1821
- this.scriptStack.unshift(tok);
1822
- };
1823
-
1824
- /**
1825
- * Called when a script is done.
1826
- *
1827
- * @param {Object} tok The token
1828
- * @private
1829
- */
1830
-
1831
-
1832
- WriteStream.prototype._onScriptDone = function _onScriptDone(tok) {
1833
- // Pop script and check nesting.
1834
- if (tok !== this.scriptStack[0]) {
1835
- this.options.error({ msg: 'Bad script nesting or script finished twice' });
1836
- return;
1837
- }
1838
-
1839
- this.scriptStack.shift();
1840
-
1841
- // Append outer writes to queue and process them.
1842
- this.write.apply(this, tok.outerWrites);
1843
-
1844
- // Check for pending remote
1845
-
1846
- // Assumption 2: if remote_script1 writes remote_script2 then
1847
- // the we notice remote_script1 finishes before remote_script2 starts.
1848
- // I think this is equivalent to assumption 1
1849
- if (!this.scriptStack.length && this.deferredRemote) {
1850
- this._onScriptStart(this.deferredRemote);
1851
- this.deferredRemote = null;
1852
- }
1853
- };
1854
-
1855
- /**
1856
- * Build a script and insert it into the DOM.
1857
- * Done is called once script has executed.
1858
- *
1859
- * @param {Object} tok The token
1860
- * @param {Function} done The callback when complete
1861
- */
1862
-
1863
-
1864
- WriteStream.prototype._writeScriptToken = function _writeScriptToken(tok, done) {
1865
- var el = this._buildScript(tok);
1866
- var asyncRelease = this._shouldRelease(el);
1867
- var afterAsync = this.options.afterAsync;
1868
-
1869
- if (tok.src) {
1870
- // Fix for attribute "SRC" (capitalized). IE does not recognize it.
1871
- el.src = tok.src;
1872
- this._scriptLoadHandler(el, !asyncRelease ? function () {
1873
- done();
1874
- afterAsync();
1875
- } : afterAsync);
1876
- }
1877
-
1878
- try {
1879
- this._insertCursor(el, PROXY_SCRIPT);
1880
- if (!el.src || asyncRelease) {
1881
- done();
1882
- }
1883
- } catch (e) {
1884
- this.options.error(e);
1885
- done();
1886
- }
1887
- };
1888
-
1889
- /**
1890
- * Build a script element from an atomic script token.
1891
- *
1892
- * @param {Object} tok The token
1893
- * @returns {Element}
1894
- */
1895
-
1896
-
1897
- WriteStream.prototype._buildScript = function _buildScript(tok) {
1898
- var el = this.doc.createElement(tok.tagName);
1899
-
1900
- // Set attributes
1901
- utils.eachKey(tok.attrs, function (name, value) {
1902
- el.setAttribute(name, value);
1903
- });
1904
-
1905
- // Set content
1906
- if (tok.content) {
1907
- el.text = tok.content;
1908
- }
1909
-
1910
- return el;
1911
- };
1912
-
1913
- /**
1914
- * Setup the script load handler on an element.
1915
- *
1916
- * @param {Object} el The element
1917
- * @param {Function} done The callback
1918
- * @private
1919
- */
1920
-
1921
-
1922
- WriteStream.prototype._scriptLoadHandler = function _scriptLoadHandler(el, done) {
1923
- function cleanup() {
1924
- el = el.onload = el.onreadystatechange = el.onerror = null;
1925
- }
1926
-
1927
- var error = this.options.error;
1928
-
1929
- function success() {
1930
- cleanup();
1931
- if (done != null) {
1932
- done();
1933
- }
1934
- done = null;
1935
- }
1936
-
1937
- function failure(err) {
1938
- cleanup();
1939
- error(err);
1940
- if (done != null) {
1941
- done();
1942
- }
1943
- done = null;
1944
- }
1945
-
1946
- function reattachEventListener(el, evt) {
1947
- var handler = el['on' + evt];
1948
- if (handler != null) {
1949
- el['_on' + evt] = handler;
1950
- }
1951
- }
1952
-
1953
- reattachEventListener(el, 'load');
1954
- reattachEventListener(el, 'error');
1955
-
1956
- _extends(el, {
1957
- onload: function onload() {
1958
- if (el._onload) {
1959
- try {
1960
- el._onload.apply(this, Array.prototype.slice.call(arguments, 0));
1961
- } catch (err) {
1962
- failure({ msg: 'onload handler failed ' + err + ' @ ' + el.src });
1963
- }
1964
- }
1965
- success();
1966
- },
1967
- onerror: function onerror() {
1968
- if (el._onerror) {
1969
- try {
1970
- el._onerror.apply(this, Array.prototype.slice.call(arguments, 0));
1971
- } catch (err) {
1972
- failure({ msg: 'onerror handler failed ' + err + ' @ ' + el.src });
1973
- return;
1974
- }
1975
- }
1976
- failure({ msg: 'remote script failed ' + el.src });
1977
- },
1978
- onreadystatechange: function onreadystatechange() {
1979
- if (/^(loaded|complete)$/.test(el.readyState)) {
1980
- success();
1981
- }
1982
- }
1983
- });
1984
- };
1985
-
1986
- /**
1987
- * Determines whether to release.
1988
- *
1989
- * @param {Object} el The element
1990
- * @returns {boolean}
1991
- * @private
1992
- */
1993
-
1994
-
1995
- WriteStream.prototype._shouldRelease = function _shouldRelease(el) {
1996
- var isScript = /^script$/i.test(el.nodeName);
1997
- return !isScript || !!(this.options.releaseAsync && el.src && el.hasAttribute('async'));
1998
- };
1999
-
2000
- return WriteStream;
2001
- }();
2002
-
2003
- exports['default'] = WriteStream;
2004
-
2005
- /***/ },
2006
- /* 3 */
2007
- /***/ function(module, exports, __webpack_require__) {
2008
-
2009
- /**
2010
- * @file prescribe
2011
- * @description Tiny, forgiving HTML parser
2012
- * @version vundefined
2013
- * @see {@link https://github.com/krux/prescribe/}
2014
- * @license MIT
2015
- * @author Derek Brans
2016
- * @copyright 2016 Krux Digital, Inc
2017
- */
2018
- (function webpackUniversalModuleDefinition(root, factory) {
2019
- if(true)
2020
- module.exports = factory();
2021
- else if(typeof define === 'function' && define.amd)
2022
- define([], factory);
2023
- else if(typeof exports === 'object')
2024
- exports["Prescribe"] = factory();
2025
- else
2026
- root["Prescribe"] = factory();
2027
- })(this, function() {
2028
- return /******/ (function(modules) { // webpackBootstrap
2029
- /******/ // The module cache
2030
- /******/ var installedModules = {};
2031
-
2032
- /******/ // The require function
2033
- /******/ function __webpack_require__(moduleId) {
2034
-
2035
- /******/ // Check if module is in cache
2036
- /******/ if(installedModules[moduleId])
2037
- /******/ return installedModules[moduleId].exports;
2038
-
2039
- /******/ // Create a new module (and put it into the cache)
2040
- /******/ var module = installedModules[moduleId] = {
2041
- /******/ exports: {},
2042
- /******/ id: moduleId,
2043
- /******/ loaded: false
2044
- /******/ };
2045
-
2046
- /******/ // Execute the module function
2047
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
2048
-
2049
- /******/ // Flag the module as loaded
2050
- /******/ module.loaded = true;
2051
-
2052
- /******/ // Return the exports of the module
2053
- /******/ return module.exports;
2054
- /******/ }
2055
-
2056
-
2057
- /******/ // expose the modules object (__webpack_modules__)
2058
- /******/ __webpack_require__.m = modules;
2059
-
2060
- /******/ // expose the module cache
2061
- /******/ __webpack_require__.c = installedModules;
2062
-
2063
- /******/ // __webpack_public_path__
2064
- /******/ __webpack_require__.p = "";
2065
-
2066
- /******/ // Load entry module and return exports
2067
- /******/ return __webpack_require__(0);
2068
- /******/ })
2069
- /************************************************************************/
2070
- /******/ ([
2071
- /* 0 */
2072
- /***/ function(module, exports, __webpack_require__) {
2073
-
2074
- 'use strict';
2075
-
2076
- var _HtmlParser = __webpack_require__(1);
2077
-
2078
- var _HtmlParser2 = _interopRequireDefault(_HtmlParser);
2079
-
2080
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2081
-
2082
- module.exports = _HtmlParser2['default'];
2083
-
2084
- /***/ },
2085
- /* 1 */
2086
- /***/ function(module, exports, __webpack_require__) {
2087
-
2088
- 'use strict';
2089
-
2090
- exports.__esModule = true;
2091
-
2092
- var _supports = __webpack_require__(2);
2093
-
2094
- var supports = _interopRequireWildcard(_supports);
2095
-
2096
- var _streamReaders = __webpack_require__(3);
2097
-
2098
- var streamReaders = _interopRequireWildcard(_streamReaders);
2099
-
2100
- var _fixedReadTokenFactory = __webpack_require__(6);
2101
-
2102
- var _fixedReadTokenFactory2 = _interopRequireDefault(_fixedReadTokenFactory);
2103
-
2104
- var _utils = __webpack_require__(5);
2105
-
2106
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2107
-
2108
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
2109
-
2110
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2111
-
2112
- /**
2113
- * Detection regular expressions.
2114
- *
2115
- * Order of detection matters: detection of one can only
2116
- * succeed if detection of previous didn't
2117
-
2118
- * @type {Object}
2119
- */
2120
- var detect = {
2121
- comment: /^<!--/,
2122
- endTag: /^<\//,
2123
- atomicTag: /^<\s*(script|style|noscript|iframe|textarea)[\s\/>]/i,
2124
- startTag: /^</,
2125
- chars: /^[^<]/
2126
- };
2127
-
2128
- /**
2129
- * HtmlParser provides the capability to parse HTML and return tokens
2130
- * representing the tags and content.
2131
- */
2132
-
2133
- var HtmlParser = function () {
2134
- /**
2135
- * Constructor.
2136
- *
2137
- * @param {string} stream The initial parse stream contents.
2138
- * @param {Object} options The options
2139
- * @param {boolean} options.autoFix Set to true to automatically fix errors
2140
- */
2141
- function HtmlParser() {
2142
- var _this = this;
2143
-
2144
- var stream = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
2145
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2146
-
2147
- _classCallCheck(this, HtmlParser);
2148
-
2149
- this.stream = stream;
2150
-
2151
- var fix = false;
2152
- var fixedTokenOptions = {};
2153
-
2154
- for (var key in supports) {
2155
- if (supports.hasOwnProperty(key)) {
2156
- if (options.autoFix) {
2157
- fixedTokenOptions[key + 'Fix'] = true; // !supports[key];
2158
- }
2159
- fix = fix || fixedTokenOptions[key + 'Fix'];
2160
- }
2161
- }
2162
-
2163
- if (fix) {
2164
- this._readToken = (0, _fixedReadTokenFactory2['default'])(this, fixedTokenOptions, function () {
2165
- return _this._readTokenImpl();
2166
- });
2167
- this._peekToken = (0, _fixedReadTokenFactory2['default'])(this, fixedTokenOptions, function () {
2168
- return _this._peekTokenImpl();
2169
- });
2170
- } else {
2171
- this._readToken = this._readTokenImpl;
2172
- this._peekToken = this._peekTokenImpl;
2173
- }
2174
- }
2175
-
2176
- /**
2177
- * Appends the given string to the parse stream.
2178
- *
2179
- * @param {string} str The string to append
2180
- */
2181
-
2182
-
2183
- HtmlParser.prototype.append = function append(str) {
2184
- this.stream += str;
2185
- };
2186
-
2187
- /**
2188
- * Prepends the given string to the parse stream.
2189
- *
2190
- * @param {string} str The string to prepend
2191
- */
2192
-
2193
-
2194
- HtmlParser.prototype.prepend = function prepend(str) {
2195
- this.stream = str + this.stream;
2196
- };
2197
-
2198
- /**
2199
- * The implementation of the token reading.
2200
- *
2201
- * @private
2202
- * @returns {?Token}
2203
- */
2204
-
2205
-
2206
- HtmlParser.prototype._readTokenImpl = function _readTokenImpl() {
2207
- var token = this._peekTokenImpl();
2208
- if (token) {
2209
- this.stream = this.stream.slice(token.length);
2210
- return token;
2211
- }
2212
- };
2213
-
2214
- /**
2215
- * The implementation of token peeking.
2216
- *
2217
- * @returns {?Token}
2218
- */
2219
-
2220
-
2221
- HtmlParser.prototype._peekTokenImpl = function _peekTokenImpl() {
2222
- for (var type in detect) {
2223
- if (detect.hasOwnProperty(type)) {
2224
- if (detect[type].test(this.stream)) {
2225
- var token = streamReaders[type](this.stream);
2226
-
2227
- if (token) {
2228
- if (token.type === 'startTag' && /script|style/i.test(token.tagName)) {
2229
- return null;
2230
- } else {
2231
- token.text = this.stream.substr(0, token.length);
2232
- return token;
2233
- }
2234
- }
2235
- }
2236
- }
2237
- }
2238
- };
2239
-
2240
- /**
2241
- * The public token peeking interface. Delegates to the basic token peeking
2242
- * or a version that performs fixups depending on the `autoFix` setting in
2243
- * options.
2244
- *
2245
- * @returns {object}
2246
- */
2247
-
2248
-
2249
- HtmlParser.prototype.peekToken = function peekToken() {
2250
- return this._peekToken();
2251
- };
2252
-
2253
- /**
2254
- * The public token reading interface. Delegates to the basic token reading
2255
- * or a version that performs fixups depending on the `autoFix` setting in
2256
- * options.
2257
- *
2258
- * @returns {object}
2259
- */
2260
-
2261
-
2262
- HtmlParser.prototype.readToken = function readToken() {
2263
- return this._readToken();
2264
- };
2265
-
2266
- /**
2267
- * Read tokens and hand to the given handlers.
2268
- *
2269
- * @param {Object} handlers The handlers to use for the different tokens.
2270
- */
2271
-
2272
-
2273
- HtmlParser.prototype.readTokens = function readTokens(handlers) {
2274
- var tok = void 0;
2275
- while (tok = this.readToken()) {
2276
- // continue until we get an explicit "false" return
2277
- if (handlers[tok.type] && handlers[tok.type](tok) === false) {
2278
- return;
2279
- }
2280
- }
2281
- };
2282
-
2283
- /**
2284
- * Clears the parse stream.
2285
- *
2286
- * @returns {string} The contents of the parse stream before clearing.
2287
- */
2288
-
2289
-
2290
- HtmlParser.prototype.clear = function clear() {
2291
- var rest = this.stream;
2292
- this.stream = '';
2293
- return rest;
2294
- };
2295
-
2296
- /**
2297
- * Returns the rest of the parse stream.
2298
- *
2299
- * @returns {string} The contents of the parse stream.
2300
- */
2301
-
2302
-
2303
- HtmlParser.prototype.rest = function rest() {
2304
- return this.stream;
2305
- };
2306
-
2307
- return HtmlParser;
2308
- }();
2309
-
2310
- exports['default'] = HtmlParser;
2311
-
2312
-
2313
- HtmlParser.tokenToString = function (tok) {
2314
- return tok.toString();
2315
- };
2316
-
2317
- HtmlParser.escapeAttributes = function (attrs) {
2318
- var escapedAttrs = {};
2319
-
2320
- for (var name in attrs) {
2321
- if (attrs.hasOwnProperty(name)) {
2322
- escapedAttrs[name] = (0, _utils.escapeQuotes)(attrs[name], null);
2323
- }
2324
- }
2325
-
2326
- return escapedAttrs;
2327
- };
2328
-
2329
- HtmlParser.supports = supports;
2330
-
2331
- for (var key in supports) {
2332
- if (supports.hasOwnProperty(key)) {
2333
- HtmlParser.browserHasFlaw = HtmlParser.browserHasFlaw || !supports[key] && key;
2334
- }
2335
- }
2336
-
2337
- /***/ },
2338
- /* 2 */
2339
- /***/ function(module, exports) {
2340
-
2341
- 'use strict';
2342
-
2343
- exports.__esModule = true;
2344
- var tagSoup = false;
2345
- var selfClose = false;
2346
-
2347
- var work = window.document.createElement('div');
2348
-
2349
- try {
2350
- var html = '<P><I></P></I>';
2351
- work.innerHTML = html;
2352
- exports.tagSoup = tagSoup = work.innerHTML !== html;
2353
- } catch (e) {
2354
- exports.tagSoup = tagSoup = false;
2355
- }
2356
-
2357
- try {
2358
- work.innerHTML = '<P><i><P></P></i></P>';
2359
- exports.selfClose = selfClose = work.childNodes.length === 2;
2360
- } catch (e) {
2361
- exports.selfClose = selfClose = false;
2362
- }
2363
-
2364
- work = null;
2365
-
2366
- exports.tagSoup = tagSoup;
2367
- exports.selfClose = selfClose;
2368
-
2369
- /***/ },
2370
- /* 3 */
2371
- /***/ function(module, exports, __webpack_require__) {
2372
-
2373
- 'use strict';
2374
-
2375
- exports.__esModule = true;
2376
-
2377
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
2378
-
2379
- exports.comment = comment;
2380
- exports.chars = chars;
2381
- exports.startTag = startTag;
2382
- exports.atomicTag = atomicTag;
2383
- exports.endTag = endTag;
2384
-
2385
- var _tokens = __webpack_require__(4);
2386
-
2387
- /**
2388
- * Regular Expressions for parsing tags and attributes
2389
- *
2390
- * @type {Object}
2391
- */
2392
- var REGEXES = {
2393
- startTag: /^<([\-A-Za-z0-9_]+)((?:\s+[\w\-]+(?:\s*=?\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,
2394
- endTag: /^<\/([\-A-Za-z0-9_]+)[^>]*>/,
2395
- attr: /(?:([\-A-Za-z0-9_]+)\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))|(?:([\-A-Za-z0-9_]+)(\s|$)+)/g,
2396
- fillAttr: /^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noresize|noshade|nowrap|readonly|selected)$/i
2397
- };
2398
-
2399
- /**
2400
- * Reads a comment token
2401
- *
2402
- * @param {string} stream The input stream
2403
- * @returns {CommentToken}
2404
- */
2405
- function comment(stream) {
2406
- var index = stream.indexOf('-->');
2407
- if (index >= 0) {
2408
- return new _tokens.CommentToken(stream.substr(4, index - 1), index + 3);
2409
- }
2410
- }
2411
-
2412
- /**
2413
- * Reads non-tag characters.
2414
- *
2415
- * @param {string} stream The input stream
2416
- * @returns {CharsToken}
2417
- */
2418
- function chars(stream) {
2419
- var index = stream.indexOf('<');
2420
- return new _tokens.CharsToken(index >= 0 ? index : stream.length);
2421
- }
2422
-
2423
- /**
2424
- * Reads start tag token.
2425
- *
2426
- * @param {string} stream The input stream
2427
- * @returns {StartTagToken}
2428
- */
2429
- function startTag(stream) {
2430
- var endTagIndex = stream.indexOf('>');
2431
- if (endTagIndex !== -1) {
2432
- var match = stream.match(REGEXES.startTag);
2433
- if (match) {
2434
- var _ret = function () {
2435
- var attrs = {};
2436
- var booleanAttrs = {};
2437
- var rest = match[2];
2438
-
2439
- match[2].replace(REGEXES.attr, function (match, name) {
2440
- if (!(arguments[2] || arguments[3] || arguments[4] || arguments[5])) {
2441
- attrs[name] = '';
2442
- } else if (arguments[5]) {
2443
- attrs[arguments[5]] = '';
2444
- booleanAttrs[arguments[5]] = true;
2445
- } else {
2446
- attrs[name] = arguments[2] || arguments[3] || arguments[4] || REGEXES.fillAttr.test(name) && name || '';
2447
- }
2448
-
2449
- rest = rest.replace(match, '');
2450
- });
2451
-
2452
- return {
2453
- v: new _tokens.StartTagToken(match[1], match[0].length, attrs, booleanAttrs, !!match[3], rest.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''))
2454
- };
2455
- }();
2456
-
2457
- if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
2458
- }
2459
- }
2460
- }
2461
-
2462
- /**
2463
- * Reads atomic tag token.
2464
- *
2465
- * @param {string} stream The input stream
2466
- * @returns {AtomicTagToken}
2467
- */
2468
- function atomicTag(stream) {
2469
- var start = startTag(stream);
2470
- if (start) {
2471
- var rest = stream.slice(start.length);
2472
- // for optimization, we check first just for the end tag
2473
- if (rest.match(new RegExp('<\/\\s*' + start.tagName + '\\s*>', 'i'))) {
2474
- // capturing the content is inefficient, so we do it inside the if
2475
- var match = rest.match(new RegExp('([\\s\\S]*?)<\/\\s*' + start.tagName + '\\s*>', 'i'));
2476
- if (match) {
2477
- return new _tokens.AtomicTagToken(start.tagName, match[0].length + start.length, start.attrs, start.booleanAttrs, match[1]);
2478
- }
2479
- }
2480
- }
2481
- }
2482
-
2483
- /**
2484
- * Reads an end tag token.
2485
- *
2486
- * @param {string} stream The input stream
2487
- * @returns {EndTagToken}
2488
- */
2489
- function endTag(stream) {
2490
- var match = stream.match(REGEXES.endTag);
2491
- if (match) {
2492
- return new _tokens.EndTagToken(match[1], match[0].length);
2493
- }
2494
- }
2495
-
2496
- /***/ },
2497
- /* 4 */
2498
- /***/ function(module, exports, __webpack_require__) {
2499
-
2500
- 'use strict';
2501
-
2502
- exports.__esModule = true;
2503
- exports.EndTagToken = exports.AtomicTagToken = exports.StartTagToken = exports.TagToken = exports.CharsToken = exports.CommentToken = exports.Token = undefined;
2504
-
2505
- var _utils = __webpack_require__(5);
2506
-
2507
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2508
-
2509
- /**
2510
- * Token is a base class for all token types parsed. Note we don't actually
2511
- * use intheritance due to IE8's non-existent ES5 support.
2512
- */
2513
- var Token =
2514
- /**
2515
- * Constructor.
2516
- *
2517
- * @param {string} type The type of the Token.
2518
- * @param {Number} length The length of the Token text.
2519
- */
2520
- exports.Token = function Token(type, length) {
2521
- _classCallCheck(this, Token);
2522
-
2523
- this.type = type;
2524
- this.length = length;
2525
- this.text = '';
2526
- };
2527
-
2528
- /**
2529
- * CommentToken represents comment tags.
2530
- */
2531
-
2532
-
2533
- var CommentToken = exports.CommentToken = function () {
2534
- /**
2535
- * Constructor.
2536
- *
2537
- * @param {string} content The content of the comment
2538
- * @param {Number} length The length of the Token text.
2539
- */
2540
- function CommentToken(content, length) {
2541
- _classCallCheck(this, CommentToken);
2542
-
2543
- this.type = 'comment';
2544
- this.length = length || (content ? content.length : 0);
2545
- this.text = '';
2546
- this.content = content;
2547
- }
2548
-
2549
- CommentToken.prototype.toString = function toString() {
2550
- return '<!--' + this.content;
2551
- };
2552
-
2553
- return CommentToken;
2554
- }();
2555
-
2556
- /**
2557
- * CharsToken represents non-tag characters.
2558
- */
2559
-
2560
-
2561
- var CharsToken = exports.CharsToken = function () {
2562
- /**
2563
- * Constructor.
2564
- *
2565
- * @param {Number} length The length of the Token text.
2566
- */
2567
- function CharsToken(length) {
2568
- _classCallCheck(this, CharsToken);
2569
-
2570
- this.type = 'chars';
2571
- this.length = length;
2572
- this.text = '';
2573
- }
2574
-
2575
- CharsToken.prototype.toString = function toString() {
2576
- return this.text;
2577
- };
2578
-
2579
- return CharsToken;
2580
- }();
2581
-
2582
- /**
2583
- * TagToken is a base class for all tag-based Tokens.
2584
- */
2585
-
2586
-
2587
- var TagToken = exports.TagToken = function () {
2588
- /**
2589
- * Constructor.
2590
- *
2591
- * @param {string} type The type of the token.
2592
- * @param {string} tagName The tag name.
2593
- * @param {Number} length The length of the Token text.
2594
- * @param {Object} attrs The dictionary of attributes and values
2595
- * @param {Object} booleanAttrs If an entry has 'true' then the attribute
2596
- * is a boolean attribute
2597
- */
2598
- function TagToken(type, tagName, length, attrs, booleanAttrs) {
2599
- _classCallCheck(this, TagToken);
2600
-
2601
- this.type = type;
2602
- this.length = length;
2603
- this.text = '';
2604
- this.tagName = tagName;
2605
- this.attrs = attrs;
2606
- this.booleanAttrs = booleanAttrs;
2607
- this.unary = false;
2608
- this.html5Unary = false;
2609
- }
2610
-
2611
- /**
2612
- * Formats the given token tag.
2613
- *
2614
- * @param {TagToken} tok The TagToken to format.
2615
- * @param {?string} [content=null] The content of the token.
2616
- * @returns {string} The formatted tag.
2617
- */
2618
-
2619
-
2620
- TagToken.formatTag = function formatTag(tok) {
2621
- var content = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
2622
-
2623
- var str = '<' + tok.tagName;
2624
- for (var key in tok.attrs) {
2625
- if (tok.attrs.hasOwnProperty(key)) {
2626
- str += ' ' + key;
2627
-
2628
- var val = tok.attrs[key];
2629
- if (typeof tok.booleanAttrs === 'undefined' || typeof tok.booleanAttrs[key] === 'undefined') {
2630
- str += '="' + (0, _utils.escapeQuotes)(val) + '"';
2631
- }
2632
- }
2633
- }
2634
-
2635
- if (tok.rest) {
2636
- str += ' ' + tok.rest;
2637
- }
2638
-
2639
- if (tok.unary && !tok.html5Unary) {
2640
- str += '/>';
2641
- } else {
2642
- str += '>';
2643
- }
2644
-
2645
- if (content !== undefined && content !== null) {
2646
- str += content + '</' + tok.tagName + '>';
2647
- }
2648
-
2649
- return str;
2650
- };
2651
-
2652
- return TagToken;
2653
- }();
2654
-
2655
- /**
2656
- * StartTagToken represents a start token.
2657
- */
2658
-
2659
-
2660
- var StartTagToken = exports.StartTagToken = function () {
2661
- /**
2662
- * Constructor.
2663
- *
2664
- * @param {string} tagName The tag name.
2665
- * @param {Number} length The length of the Token text
2666
- * @param {Object} attrs The dictionary of attributes and values
2667
- * @param {Object} booleanAttrs If an entry has 'true' then the attribute
2668
- * is a boolean attribute
2669
- * @param {boolean} unary True if the tag is a unary tag
2670
- * @param {string} rest The rest of the content.
2671
- */
2672
- function StartTagToken(tagName, length, attrs, booleanAttrs, unary, rest) {
2673
- _classCallCheck(this, StartTagToken);
2674
-
2675
- this.type = 'startTag';
2676
- this.length = length;
2677
- this.text = '';
2678
- this.tagName = tagName;
2679
- this.attrs = attrs;
2680
- this.booleanAttrs = booleanAttrs;
2681
- this.html5Unary = false;
2682
- this.unary = unary;
2683
- this.rest = rest;
2684
- }
2685
-
2686
- StartTagToken.prototype.toString = function toString() {
2687
- return TagToken.formatTag(this);
2688
- };
2689
-
2690
- return StartTagToken;
2691
- }();
2692
-
2693
- /**
2694
- * AtomicTagToken represents an atomic tag.
2695
- */
2696
-
2697
-
2698
- var AtomicTagToken = exports.AtomicTagToken = function () {
2699
- /**
2700
- * Constructor.
2701
- *
2702
- * @param {string} tagName The name of the tag.
2703
- * @param {Number} length The length of the tag text.
2704
- * @param {Object} attrs The attributes.
2705
- * @param {Object} booleanAttrs If an entry has 'true' then the attribute
2706
- * is a boolean attribute
2707
- * @param {string} content The content of the tag.
2708
- */
2709
- function AtomicTagToken(tagName, length, attrs, booleanAttrs, content) {
2710
- _classCallCheck(this, AtomicTagToken);
2711
-
2712
- this.type = 'atomicTag';
2713
- this.length = length;
2714
- this.text = '';
2715
- this.tagName = tagName;
2716
- this.attrs = attrs;
2717
- this.booleanAttrs = booleanAttrs;
2718
- this.unary = false;
2719
- this.html5Unary = false;
2720
- this.content = content;
2721
- }
2722
-
2723
- AtomicTagToken.prototype.toString = function toString() {
2724
- return TagToken.formatTag(this, this.content);
2725
- };
2726
-
2727
- return AtomicTagToken;
2728
- }();
2729
-
2730
- /**
2731
- * EndTagToken represents an end tag.
2732
- */
2733
-
2734
-
2735
- var EndTagToken = exports.EndTagToken = function () {
2736
- /**
2737
- * Constructor.
2738
- *
2739
- * @param {string} tagName The name of the tag.
2740
- * @param {Number} length The length of the tag text.
2741
- */
2742
- function EndTagToken(tagName, length) {
2743
- _classCallCheck(this, EndTagToken);
2744
-
2745
- this.type = 'endTag';
2746
- this.length = length;
2747
- this.text = '';
2748
- this.tagName = tagName;
2749
- }
2750
-
2751
- EndTagToken.prototype.toString = function toString() {
2752
- return '</' + this.tagName + '>';
2753
- };
2754
-
2755
- return EndTagToken;
2756
- }();
2757
-
2758
- /***/ },
2759
- /* 5 */
2760
- /***/ function(module, exports) {
2761
-
2762
- 'use strict';
2763
-
2764
- exports.__esModule = true;
2765
- exports.escapeQuotes = escapeQuotes;
2766
-
2767
- /**
2768
- * Escape quotes in the given value.
2769
- *
2770
- * @param {string} value The value to escape.
2771
- * @param {string} [defaultValue=''] The default value to return if value is falsy.
2772
- * @returns {string}
2773
- */
2774
- function escapeQuotes(value) {
2775
- var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
2776
-
2777
- // There's no lookback in JS, so /(^|[^\\])"/ only matches the first of two `"`s.
2778
- // Instead, just match anything before a double-quote and escape if it's not already escaped.
2779
- return !value ? defaultValue : value.replace(/([^"]*)"/g, function (_, prefix) {
2780
- return (/\\/.test(prefix) ? prefix + '"' : prefix + '\\"'
2781
- );
2782
- });
2783
- }
2784
-
2785
- /***/ },
2786
- /* 6 */
2787
- /***/ function(module, exports) {
2788
-
2789
- 'use strict';
2790
-
2791
- exports.__esModule = true;
2792
- exports['default'] = fixedReadTokenFactory;
2793
- /**
2794
- * Empty Elements - HTML 4.01
2795
- *
2796
- * @type {RegExp}
2797
- */
2798
- var EMPTY = /^(AREA|BASE|BASEFONT|BR|COL|FRAME|HR|IMG|INPUT|ISINDEX|LINK|META|PARAM|EMBED)$/i;
2799
-
2800
- /**
2801
- * Elements that you can intentionally leave open (and which close themselves)
2802
- *
2803
- * @type {RegExp}
2804
- */
2805
- var CLOSESELF = /^(COLGROUP|DD|DT|LI|OPTIONS|P|TD|TFOOT|TH|THEAD|TR)$/i;
2806
-
2807
- /**
2808
- * Corrects a token.
2809
- *
2810
- * @param {Token} tok The token to correct
2811
- * @returns {Token} The corrected token
2812
- */
2813
- function correct(tok) {
2814
- if (tok && tok.type === 'startTag') {
2815
- tok.unary = EMPTY.test(tok.tagName) || tok.unary;
2816
- tok.html5Unary = !/\/>$/.test(tok.text);
2817
- }
2818
- return tok;
2819
- }
2820
-
2821
- /**
2822
- * Peeks at the next token in the parser.
2823
- *
2824
- * @param {HtmlParser} parser The parser
2825
- * @param {Function} readTokenImpl The underlying readToken implementation
2826
- * @returns {Token} The next token
2827
- */
2828
- function peekToken(parser, readTokenImpl) {
2829
- var tmp = parser.stream;
2830
- var tok = correct(readTokenImpl());
2831
- parser.stream = tmp;
2832
- return tok;
2833
- }
2834
-
2835
- /**
2836
- * Closes the last token.
2837
- *
2838
- * @param {HtmlParser} parser The parser
2839
- * @param {Array<Token>} stack The stack
2840
- */
2841
- function closeLast(parser, stack) {
2842
- var tok = stack.pop();
2843
-
2844
- // prepend close tag to stream.
2845
- parser.prepend('</' + tok.tagName + '>');
2846
- }
2847
-
2848
- /**
2849
- * Create a new token stack.
2850
- *
2851
- * @returns {Array<Token>}
2852
- */
2853
- function newStack() {
2854
- var stack = [];
2855
-
2856
- stack.last = function () {
2857
- return this[this.length - 1];
2858
- };
2859
-
2860
- stack.lastTagNameEq = function (tagName) {
2861
- var last = this.last();
2862
- return last && last.tagName && last.tagName.toUpperCase() === tagName.toUpperCase();
2863
- };
2864
-
2865
- stack.containsTagName = function (tagName) {
2866
- for (var i = 0, tok; tok = this[i]; i++) {
2867
- if (tok.tagName === tagName) {
2868
- return true;
2869
- }
2870
- }
2871
- return false;
2872
- };
2873
-
2874
- return stack;
2875
- }
2876
-
2877
- /**
2878
- * Return a readToken implementation that fixes input.
2879
- *
2880
- * @param {HtmlParser} parser The parser
2881
- * @param {Object} options Options for fixing
2882
- * @param {boolean} options.tagSoupFix True to fix tag soup scenarios
2883
- * @param {boolean} options.selfCloseFix True to fix self-closing tags
2884
- * @param {Function} readTokenImpl The underlying readToken implementation
2885
- * @returns {Function}
2886
- */
2887
- function fixedReadTokenFactory(parser, options, readTokenImpl) {
2888
- var stack = newStack();
2889
-
2890
- var handlers = {
2891
- startTag: function startTag(tok) {
2892
- var tagName = tok.tagName;
2893
-
2894
- if (tagName.toUpperCase() === 'TR' && stack.lastTagNameEq('TABLE')) {
2895
- parser.prepend('<TBODY>');
2896
- prepareNextToken();
2897
- } else if (options.selfCloseFix && CLOSESELF.test(tagName) && stack.containsTagName(tagName)) {
2898
- if (stack.lastTagNameEq(tagName)) {
2899
- closeLast(parser, stack);
2900
- } else {
2901
- parser.prepend('</' + tok.tagName + '>');
2902
- prepareNextToken();
2903
- }
2904
- } else if (!tok.unary) {
2905
- stack.push(tok);
2906
- }
2907
- },
2908
- endTag: function endTag(tok) {
2909
- var last = stack.last();
2910
- if (last) {
2911
- if (options.tagSoupFix && !stack.lastTagNameEq(tok.tagName)) {
2912
- // cleanup tag soup
2913
- closeLast(parser, stack);
2914
- } else {
2915
- stack.pop();
2916
- }
2917
- } else if (options.tagSoupFix) {
2918
- // cleanup tag soup part 2: skip this token
2919
- readTokenImpl();
2920
- prepareNextToken();
2921
- }
2922
- }
2923
- };
2924
-
2925
- function prepareNextToken() {
2926
- var tok = peekToken(parser, readTokenImpl);
2927
- if (tok && handlers[tok.type]) {
2928
- handlers[tok.type](tok);
2929
- }
2930
- }
2931
-
2932
- return function fixedReadToken() {
2933
- prepareNextToken();
2934
- return correct(readTokenImpl());
2935
- };
2936
- }
2937
-
2938
- /***/ }
2939
- /******/ ])
2940
- });
2941
- ;
2942
-
2943
- /***/ },
2944
- /* 4 */
2945
- /***/ function(module, exports) {
2946
-
2947
- 'use strict';
2948
-
2949
- exports.__esModule = true;
2950
-
2951
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
2952
-
2953
- exports.existy = existy;
2954
- exports.isFunction = isFunction;
2955
- exports.each = each;
2956
- exports.eachKey = eachKey;
2957
- exports.defaults = defaults;
2958
- exports.toArray = toArray;
2959
- exports.last = last;
2960
- exports.isTag = isTag;
2961
- exports.isScript = isScript;
2962
- exports.isStyle = isStyle;
2963
- /**
2964
- * Determine if the thing is not undefined and not null.
2965
- *
2966
- * @param {*} thing The thing to test
2967
- * @returns {boolean} True if the thing is not undefined and not null.
2968
- */
2969
- function existy(thing) {
2970
- return thing !== void 0 && thing !== null;
2971
- }
2972
-
2973
- /**
2974
- * Is this a function?
2975
- *
2976
- * @param {*} x The variable to test
2977
- * @returns {boolean} True if the variable is a function
2978
- */
2979
- function isFunction(x) {
2980
- return 'function' === typeof x;
2981
- }
2982
-
2983
- /**
2984
- * Loop over each item in an array-like value.
2985
- *
2986
- * @param {Array<*>} arr The array to loop over
2987
- * @param {Function} fn The function to call
2988
- * @param {?Object} target The object to bind to the function
2989
- */
2990
- function each(arr, fn, target) {
2991
- var i = void 0;
2992
- var len = arr && arr.length || 0;
2993
- for (i = 0; i < len; i++) {
2994
- fn.call(target, arr[i], i);
2995
- }
2996
- }
2997
-
2998
- /**
2999
- * Loop over each key/value pair in a hash.
3000
- *
3001
- * @param {Object} obj The object
3002
- * @param {Function} fn The function to call
3003
- * @param {?Object} target The object to bind to the function
3004
- */
3005
- function eachKey(obj, fn, target) {
3006
- for (var key in obj) {
3007
- if (obj.hasOwnProperty(key)) {
3008
- fn.call(target, key, obj[key]);
3009
- }
3010
- }
3011
- }
3012
-
3013
- /**
3014
- * Set default options where some option was not specified.
3015
- *
3016
- * @param {Object} options The destination
3017
- * @param {Object} _defaults The defaults
3018
- * @returns {Object}
3019
- */
3020
- function defaults(options, _defaults) {
3021
- options = options || {};
3022
- eachKey(_defaults, function (key, val) {
3023
- if (!existy(options[key])) {
3024
- options[key] = val;
3025
- }
3026
- });
3027
- return options;
3028
- }
3029
-
3030
- /**
3031
- * Convert value (e.g., a NodeList) to an array.
3032
- *
3033
- * @param {*} obj The object
3034
- * @returns {Array<*>}
3035
- */
3036
- function toArray(obj) {
3037
- try {
3038
- return Array.prototype.slice.call(obj);
3039
- } catch (e) {
3040
- var _ret = function () {
3041
- var ret = [];
3042
- each(obj, function (val) {
3043
- ret.push(val);
3044
- });
3045
- return {
3046
- v: ret
3047
- };
3048
- }();
3049
-
3050
- if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
3051
- }
3052
- }
3053
-
3054
- /**
3055
- * Get the last item in an array
3056
- *
3057
- * @param {Array<*>} array The array
3058
- * @returns {*} The last item in the array
3059
- */
3060
- function last(array) {
3061
- return array[array.length - 1];
3062
- }
3063
-
3064
- /**
3065
- * Test if token is a script tag.
3066
- *
3067
- * @param {Object} tok The token
3068
- * @param {String} tag The tag name
3069
- * @returns {boolean} True if the token is a script tag
3070
- */
3071
- function isTag(tok, tag) {
3072
- return !tok || !(tok.type === 'startTag' || tok.type === 'atomicTag') || !('tagName' in tok) ? !1 : !!~tok.tagName.toLowerCase().indexOf(tag);
3073
- }
3074
-
3075
- /**
3076
- * Test if token is a script tag.
3077
- *
3078
- * @param {Object} tok The token
3079
- * @returns {boolean} True if the token is a script tag
3080
- */
3081
- function isScript(tok) {
3082
- return isTag(tok, 'script');
3083
- }
3084
-
3085
- /**
3086
- * Test if token is a style tag.
3087
- *
3088
- * @param {Object} tok The token
3089
- * @returns {boolean} True if the token is a style tag
3090
- */
3091
- function isStyle(tok) {
3092
- return isTag(tok, 'style');
3093
- }
3094
-
3095
- /***/ }
3096
- /******/ ])
3097
- });
3098
- ;
3099
- //# sourceMappingURL=postscribe.js.map
3100
-
3101
- /***/ })
3102
- /******/ ]);