prebid-universal-creative 1.15.0 → 1.17.0

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