1/** 2 * @file postscribe 3 * @description Asynchronously write javascript, even with document.write. 4 * @version v2.0.8 5 * @see {@link https://krux.github.io/postscribe} 6 * @license MIT 7 * @author Derek Brans 8 * @copyright 2016 Krux Digital, Inc 9 */ 10(function webpackUniversalModuleDefinition(root, factory) { 11 if(typeof exports === 'object' && typeof module === 'object') 12 module.exports = factory(); 13 else if(typeof define === 'function' && define.amd) 14 define([], factory); 15 else if(typeof exports === 'object') 16 exports["advads_postscribe"] = factory(); 17 root["advads_
vendor: 15,628 bytes, lines 17-608
17postscribe"] = factory(); 18})(this, function() { 19return /******/ (function(modules) { // webpackBootstrap 20/******/ // The module cache 21/******/ var installedModules = {}; 22/******/ 23/******/ // The require function 24/******/ function __webpack_require__(moduleId) { 25/******/ 26/******/ // Check if module is in cache 27/******/ if(installedModules[moduleId]) 28/******/ return installedModules[moduleId].exports; 29/******/ 30/******/ // Create a new module (and put it into the cache) 31/******/ var module = installedModules[moduleId] = { 32/******/ exports: {}, 33/******/ id: moduleId, 34/******/ loaded: false 35/******/ }; 36/******/ 37/******/ // Execute the module function 38/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 39/******/ 40/******/ // Flag the module as loaded 41/******/ module.loaded = true; 42/******/ 43/******/ // Return the exports of the module 44/******/ return module.exports; 45/******/ } 46/******/ 47/******/ 48/******/ // expose the modules object (__webpack_modules__) 49/******/ __webpack_require__.m = modules; 50/******/ 51/******/ // expose the module cache 52/******/ __webpack_require__.c = installedModules; 53/******/ 54/******/ // __webpack_public_path__ 55/******/ __webpack_require__.p = ""; 56/******/ 57/******/ // Load entry module and return exports 58/******/ return __webpack_require__(0); 59/******/ }) 60/************************************************************************/ 61/******/ ([ 62/* 0 */ 63/***/ function(module, exports, __webpack_require__) { 64 65 'use strict'; 66 67 var _postscribe = __webpack_require__(1); 68 69 var _postscribe2 = _interopRequireDefault(_postscribe); 70 71 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 72 73 module.exports = _postscribe2['default']; 74 75/***/ }, 76/* 1 */ 77/***/ function(module, exports, __webpack_require__) { 78 79 'use strict'; 80 81 exports.__esModule = true; 82 83 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; }; 84 85 exports['default'] = postscribe; 86 87 var _writeStream = __webpack_require__(2); 88 89 var _writeStream2 = _interopRequireDefault(_writeStream); 90 91 var _utils = __webpack_require__(4); 92 93 var utils = _interopRequireWildcard(_utils); 94 95 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; } } 96 97 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 98 99 /** 100 * A function that intentionally does nothing. 101 */ 102 function doNothing() {} 103 104 /** 105 * Available options and defaults. 106 * 107 * @type {Object} 108 */ 109 var OPTIONS = { 110 /** 111 * Called when an async script has loaded. 112 */ 113 afterAsync: doNothing, 114 115 /** 116 * Called immediately before removing from the write queue. 117 */ 118 afterDequeue: doNothing, 119 120 /** 121 * Called sync after a stream's first thread release. 122 */ 123 afterStreamStart: doNothing, 124 125 /** 126 * Called after writing buffered document.write calls. 127 */ 128 afterWrite: doNothing, 129 130 /** 131 * Allows disabling the autoFix feature of prescribe 132 */ 133 autoFix: true, 134 135 /** 136 * Called immediately before adding to the write queue. 137 */ 138 beforeEnqueue: doNothing, 139 140 /** 141 * Called before writing a token. 142 * 143 * @param {Object} tok The token 144 */ 145 beforeWriteToken: function beforeWriteToken(tok) { 146 return tok; 147 }, 148 149 /** 150 * Called before writing buffered document.write calls. 151 * 152 * @param {String} str The string 153 */ 154 beforeWrite: function beforeWrite(str) { 155 return str; 156 }, 157 158 /** 159 * Called when evaluation is finished. 160 */ 161 done: doNothing, 162 163 /** 164 * Called when a write results in an error. 165 * 166 * @param {Error} e The error 167 */ 168 error: function error(e) { 169 throw new Error(e.msg); 170 }, 171 172 173 /** 174 * Whether to let scripts w/ async attribute set fall out of the queue. 175 */ 176 releaseAsync: false 177 }; 178 179 var nextId = 0; 180 var queue = []; 181 var active = null; 182 183 function nextStream() { 184 var args = queue.shift(); 185 if (args) { 186 var options = utils.last(args); 187 188 options.afterDequeue(); 189 args.stream = runStream.apply(undefined, args); 190 options.afterStreamStart(); 191 } 192 } 193 194 function runStream(el, html, options) { 195 active = new _writeStream2['default'](el, options); 196 197 // Identify this stream. 198 active.id = nextId++; 199 active.name = options.name || active.id; 200 postscribe.streams[active.name] = active; 201 202 // Override document.write. 203 var doc = el.ownerDocument; 204 205 var stash = { 206 close: doc.close, 207 open: doc.open, 208 write: doc.write, 209 writeln: doc.writeln 210 }; 211 212 function _write(str) { 213 str = options.beforeWrite(str); 214 active.write(str); 215 options.afterWrite(str); 216 } 217 218 _extends(doc, { 219 close: doNothing, 220 open: doNothing, 221 write: function write() { 222 for (var _len = arguments.length, str = Array(_len), _key = 0; _key < _len; _key++) { 223 str[_key] = arguments[_key]; 224 } 225 226 return _write(str.join('')); 227 }, 228 writeln: function writeln() { 229 for (var _len2 = arguments.length, str = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 230 str[_key2] = arguments[_key2]; 231 } 232 233 return _write(str.join('') + '\n'); 234 } 235 }); 236 237 // Override window.onerror 238 var oldOnError = active.win.onerror || doNothing; 239 240 // This works together with the try/catch around WriteStream::insertScript 241 // In modern browsers, exceptions in tag scripts go directly to top level 242 active.win.onerror = function (msg, url, line) { 243 options.error({ msg: msg + ' - ' + url + ': ' + line }); 244 oldOnError.apply(active.win, [msg, url, line]); 245 }; 246 247 // Write to the stream 248 active.write(html, function () { 249 // restore document.write 250 _extends(doc, stash); 251 252 // restore window.onerror 253 active.win.onerror = oldOnError; 254 255 options.done(); 256 active = null; 257 nextStream(); 258 }); 259 260 return active; 261 } 262 263 function postscribe(el, html, options) { 264 if (utils.isFunction(options)) { 265 options = { done: options }; 266 } else if (options === 'clear') { 267 queue = []; 268 active = null; 269 nextId = 0; 270 return; 271 } 272 273 options = utils.defaults(options, OPTIONS); 274 275 // id selector 276 if (/^#/.test(el)) { 277 el = window.document.getElementById(el.substr(1)); 278 } else { 279 el = el.jquery ? el[0] : el; 280 } 281 282 var args = [el, html, options]; 283 284 el.postscribe = { 285 cancel: function cancel() { 286 if (args.stream) { 287 args.stream.abort(); 288 } else { 289 args[1] = doNothing; 290 } 291 } 292 }; 293 294 options.beforeEnqueue(args); 295 queue.push(args); 296 297 if (!active) { 298 nextStream(); 299 } 300 301 return el.postscribe; 302 } 303 304 _extends(postscribe, { 305 // Streams by name. 306 streams: {}, 307 // Queue of streams. 308 queue: queue, 309 // Expose internal classes. 310 WriteStream: _writeStream2['default'] 311 }); 312 313/***/ }, 314/* 2 */ 315/***/ function(module, exports, __webpack_require__) { 316 317 'use strict'; 318 319 exports.__esModule = true; 320 321 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; }; 322 323 var _prescribe = __webpack_require__(3); 324 325 var _prescribe2 = _interopRequireDefault(_prescribe); 326 327 var _utils = __webpack_require__(4); 328 329 var utils = _interopRequireWildcard(_utils); 330 331 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; } } 332 333 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 334 335 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 336 337 /** 338 * Turn on to debug how each chunk affected the DOM. 339 * @type {boolean} 340 */ 341 var DEBUG_CHUNK = false; 342 343 /** 344 * Prefix for data attributes on DOM elements. 345 * @type {string} 346 */ 347 var BASEATTR = 'data-ps-'; 348 349 /** 350 * ID for the style proxy 351 * @type {string} 352 */ 353 var PROXY_STYLE = 'ps-style'; 354 355 /** 356 * ID for the script proxy 357 * @type {string} 358 */ 359 var PROXY_SCRIPT = 'ps-script'; 360 361 /** 362 * Get data attributes 363 * 364 * @param {Object} el The DOM element. 365 * @param {String} name The attribute name. 366 * @returns {String} 367 */ 368 function getData(el, name) { 369 var attr = BASEATTR + name; 370 371 var val = el.getAttribute(attr); 372 373 // IE 8 returns a number if it's a number 374 return !utils.existy(val) ? val : String(val); 375 } 376 377 /** 378 * Set data attributes 379 * 380 * @param {Object} el The DOM element. 381 * @param {String} name The attribute name. 382 * @param {null|*} value The attribute value. 383 */ 384 function setData(el, name) { 385 var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 386 387 var attr = BASEATTR + name; 388 389 if (utils.existy(value) && value !== '') { 390 el.setAttribute(attr, value); 391 } else { 392 el.removeAttribute(attr); 393 } 394 } 395 396 /** 397 * Stream static html to an element, where "static html" denotes "html 398 * without scripts". 399 * 400 * This class maintains a *history of writes devoid of any attributes* or 401 * "proxy history". 402 * 403 * Injecting the proxy history into a temporary div has no side-effects, 404 * other than to create proxy elements for previously written elements. 405 * 406 * Given the `staticHtml` of a new write, a `tempDiv`'s innerHTML is set to 407 * `proxy_history + staticHtml`. 408 * The *structure* of `tempDiv`'s contents, (i.e., the placement of new nodes 409 * beside or inside of proxy elements), reflects the DOM structure that would 410 * have resulted if all writes had been squashed into a single write. 411 * 412 * For each descendent `node` of `tempDiv` whose parentNode is a *proxy*, 413 * `node` is appended to the corresponding *real* element within the DOM. 414 * 415 * Proxy elements are mapped to *actual* elements in the DOM by injecting a 416 * `data-id` attribute into each start tag in `staticHtml`. 417 * 418 */ 419 420 var WriteStream = function () { 421 /** 422 * Constructor. 423 * 424 * @param {Object} root The root element 425 * @param {?Object} options The options 426 */ 427 function WriteStream(root) { 428 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 429 430 _classCallCheck(this, WriteStream); 431 432 this.root = root; 433 this.options = options; 434 this.doc = root.ownerDocument; 435 this.win = this.doc.defaultView || this.doc.parentWindow; 436 this.parser = new _prescribe2['default']('', { autoFix: options.autoFix }); 437 438 // Actual elements by id. 439 this.actuals = [root]; 440 441 // Embodies the "structure" of what's been written so far, 442 // devoid of attributes. 443 this.proxyHistory = ''; 444 445 // Create a proxy of the root element. 446 this.proxyRoot = this.doc.createElement(root.nodeName); 447 448 this.scriptStack = []; 449 this.writeQueue = []; 450 451 setData(this.proxyRoot, 'proxyof', 0); 452 } 453 454 /** 455 * Writes the given strings. 456 * 457 * @param {...String} str The strings to write 458 */ 459 460 461 WriteStream.prototype.write = function write() { 462 var _writeQueue; 463 464 (_writeQueue = this.writeQueue).push.apply(_writeQueue, arguments); 465 466 // Process writes 467 // When new script gets pushed or pending this will stop 468 // because new writeQueue gets pushed 469 while (!this.deferredRemote && this.writeQueue.length) { 470 var arg = this.writeQueue.shift(); 471 472 if (utils.isFunction(arg)) { 473 this._callFunction(arg); 474 } else { 475 this._writeImpl(arg); 476 } 477 } 478 }; 479 480 /** 481 * Calls the given function. 482 * 483 * @param {Function} fn The function to call 484 * @private 485 */ 486 487 488 WriteStream.prototype._callFunction = function _callFunction(fn) { 489 var tok = { type: 'function', value: fn.name || fn.toString() }; 490 this._onScriptStart(tok); 491 fn.call(this.win, this.doc); 492 this._onScriptDone(tok); 493 }; 494 495 /** 496 * The write implementation 497 * 498 * @param {String} html The HTML to write. 499 * @private 500 */ 501 502 503 WriteStream.prototype._writeImpl = function _writeImpl(html) { 504 this.parser.append(html); 505 506 var tok = void 0; 507 var script = void 0; 508 var style = void 0; 509 var tokens = []; 510 511 // stop if we see a script token 512 while ((tok = this.parser.readToken()) && !(script = utils.isScript(tok)) && !(style = utils.isStyle(tok))) { 513 tok = this.options.beforeWriteToken(tok); 514 515 if (tok) { 516 tokens.push(tok); 517 } 518 } 519 520 if (tokens.length > 0) { 521 this._writeStaticTokens(tokens); 522 } 523 524 if (script) { 525 this._handleScriptToken(tok); 526 } 527 528 if (style) { 529 this._handleStyleToken(tok); 530 } 531 }; 532 533 /** 534 * Write contiguous non-script tokens (a chunk) 535 * 536 * @param {Array<Object>} tokens The tokens 537 * @returns {{tokens, raw, actual, proxy}|null} 538 * @private 539 */ 540 541 542 WriteStream.prototype._writeStaticTokens = function _writeStaticTokens(tokens) { 543 var chunk = this._buildChunk(tokens); 544 545 if (!chunk.actual) { 546 // e.g., no tokens, or a noscript that got ignored 547 return null; 548 } 549 550 chunk.html = this.proxyHistory + chunk.actual; 551 this.proxyHistory += chunk.proxy; 552 this.proxyRoot.innerHTML = chunk.html; 553 554 if (DEBUG_CHUNK) { 555 chunk.proxyInnerHTML = this.proxyRoot.innerHTML; 556 } 557 558 this._walkChunk(); 559 560 if (DEBUG_CHUNK) { 561 chunk.actualInnerHTML = this.root.innerHTML; 562 } 563 564 return chunk; 565 }; 566 567 /** 568 * Build a chunk. 569 * 570 * @param {Array<Object>} tokens The tokens to use. 571 * @returns {{tokens: *, raw: string, actual: string, proxy: string}} 572 * @private 573 */ 574 575 576 WriteStream.prototype._buildChunk = function _buildChunk(tokens) { 577 var nextId = this.actuals.length; 578 579 // The raw html of this chunk. 580 var raw = []; 581 582 // The html to create the nodes in the tokens (with id's injected). 583 var actual = []; 584 585 // Html that can later be used to proxy the nodes in the tokens. 586 var proxy = []; 587 588 var len = tokens.length; 589 for (var i = 0; i < len; i++) { 590 var tok = tokens[i]; 591 var tokenRaw = tok.toString(); 592 593 raw.push(tokenRaw); 594 595 if (tok.attrs) { 596 // tok.attrs <==> startTag or atomicTag or cursor 597 // Ignore noscript tags. They are atomic, so we don't have to worry about children. 598 if (!/^noscript$/i.test(tok.tagName)) { 599 var id = nextId++; 600 601 // Actual: inject id attribute: replace '>' at end of start tag with id attribute + '>' 602 actual.push(tokenRaw.replace(/(\/?>)/, ' ' + BASEATTR + 'id=' + id + ' $1')); 603 604 // Don't proxy scripts: they have no bearing on DOM structure. 605 if (tok.attrs.id !== PROXY_SCRIPT && tok.attrs.id !== PROXY_STYLE) { 606 // Proxy: strip all attributes and inject proxyof attribute 607 proxy.push( 608 // ignore atomic tags (e.g., style): they have no "structural" effect
vendor: 38,542 bytes, lines 609-2086
609 tok.type === 'atomicTag' ? '' : '<' + tok.tagName + ' ' + BASEATTR + 'proxyof=' + id + (tok.unary ? ' />' : '>')); 610 } 611 } 612 } else { 613 // Visit any other type of token 614 // Actual: append. 615 actual.push(tokenRaw); 616 617 // Proxy: append endTags. Ignore everything else. 618 proxy.push(tok.type === 'endTag' ? tokenRaw : ''); 619 } 620 } 621 622 return { 623 tokens: tokens, 624 raw: raw.join(''), 625 actual: actual.join(''), 626 proxy: proxy.join('') 627 }; 628 }; 629 630 /** 631 * Walk the chunks. 632 * 633 * @private 634 */ 635 636 637 WriteStream.prototype._walkChunk = function _walkChunk() { 638 var node = void 0; 639 var stack = [this.proxyRoot]; 640 641 // use shift/unshift so that children are walked in document order 642 while (utils.existy(node = stack.shift())) { 643 var isElement = node.nodeType === 1; 644 var isProxy = isElement && getData(node, 'proxyof'); 645 646 // Ignore proxies 647 if (!isProxy) { 648 if (isElement) { 649 // New actual element: register it and remove the the id attr. 650 this.actuals[getData(node, 'id')] = node; 651 setData(node, 'id'); 652 } 653 654 // Is node's parent a proxy? 655 var parentIsProxyOf = node.parentNode && getData(node.parentNode, 'proxyof'); 656 if (parentIsProxyOf) { 657 // Move node under actual parent. 658 this.actuals[parentIsProxyOf].appendChild(node); 659 } 660 } 661 662 // prepend childNodes to stack 663 stack.unshift.apply(stack, utils.toArray(node.childNodes)); 664 } 665 }; 666 667 /** 668 * Handles Script tokens 669 * 670 * @param {Object} tok The token 671 */ 672 673 674 WriteStream.prototype._handleScriptToken = function _handleScriptToken(tok) { 675 var _this = this; 676 677 var remainder = this.parser.clear(); 678 679 if (remainder) { 680 // Write remainder immediately behind this script. 681 this.writeQueue.unshift(remainder); 682 } 683 684 tok.src = tok.attrs.src || tok.attrs.SRC; 685 686 tok = this.options.beforeWriteToken(tok); 687 if (!tok) { 688 // User has removed this token 689 return; 690 } 691 692 if (tok.src && this.scriptStack.length) { 693 // Defer this script until scriptStack is empty. 694 // Assumption 1: This script will not start executing until 695 // scriptStack is empty. 696 this.deferredRemote = tok; 697 } else { 698 this._onScriptStart(tok); 699 } 700 701 // Put the script node in the DOM. 702 this._writeScriptToken(tok, function () { 703 _this._onScriptDone(tok); 704 }); 705 }; 706 707 /** 708 * Handles style tokens 709 * 710 * @param {Object} tok The token 711 */ 712 713 714 WriteStream.prototype._handleStyleToken = function _handleStyleToken(tok) { 715 var remainder = this.parser.clear(); 716 717 if (remainder) { 718 // Write remainder immediately behind this style. 719 this.writeQueue.unshift(remainder); 720 } 721 722 tok.type = tok.attrs.type || tok.attrs.TYPE || 'text/css'; 723 724 tok = this.options.beforeWriteToken(tok); 725 726 if (tok) { 727 // Put the style node in the DOM. 728 this._writeStyleToken(tok); 729 } 730 731 if (remainder) { 732 this.write(); 733 } 734 }; 735 736 /** 737 * Build a style and insert it into the DOM. 738 * 739 * @param {Object} tok The token 740 */ 741 742 743 WriteStream.prototype._writeStyleToken = function _writeStyleToken(tok) { 744 var el = this._buildStyle(tok); 745 746 this._insertCursor(el, PROXY_STYLE); 747 748 // Set content 749 if (tok.content) { 750 if (el.styleSheet && !el.sheet) { 751 el.styleSheet.cssText = tok.content; 752 } else { 753 el.appendChild(this.doc.createTextNode(tok.content)); 754 } 755 } 756 }; 757 758 /** 759 * Build a style element from an atomic style token. 760 * 761 * @param {Object} tok The token 762 * @returns {Element} 763 */ 764 765 766 WriteStream.prototype._buildStyle = function _buildStyle(tok) { 767 var el = this.doc.createElement(tok.tagName); 768 769 el.setAttribute('type', tok.type); 770 771 // Set attributes 772 utils.eachKey(tok.attrs, function (name, value) { 773 el.setAttribute(name, value); 774 }); 775 776 return el; 777 }; 778 779 /** 780 * Append a span to the stream. That span will act as a cursor 781 * (i.e. insertion point) for the element. 782 * 783 * @param {Object} el The element 784 * @param {string} which The type of proxy element 785 */ 786 787 788 WriteStream.prototype._insertCursor = function _insertCursor(el, which) { 789 this._writeImpl('<span id="' + which + '"/>'); 790 791 var cursor = this.doc.getElementById(which); 792 793 if (cursor) { 794 cursor.parentNode.replaceChild(el, cursor); 795 } 796 }; 797 798 /** 799 * Called when a script is started. 800 * 801 * @param {Object} tok The token 802 * @private 803 */ 804 805 806 WriteStream.prototype._onScriptStart = function _onScriptStart(tok) { 807 tok.outerWrites = this.writeQueue; 808 this.writeQueue = []; 809 this.scriptStack.unshift(tok); 810 }; 811 812 /** 813 * Called when a script is done. 814 * 815 * @param {Object} tok The token 816 * @private 817 */ 818 819 820 WriteStream.prototype._onScriptDone = function _onScriptDone(tok) { 821 // Pop script and check nesting. 822 if (tok !== this.scriptStack[0]) { 823 this.options.error({ msg: 'Bad script nesting or script finished twice' }); 824 return; 825 } 826 827 this.scriptStack.shift(); 828 829 // Append outer writes to queue and process them. 830 this.write.apply(this, tok.outerWrites); 831 832 // Check for pending remote 833 834 // Assumption 2: if remote_script1 writes remote_script2 then 835 // the we notice remote_script1 finishes before remote_script2 starts. 836 // I think this is equivalent to assumption 1 837 if (!this.scriptStack.length && this.deferredRemote) { 838 this._onScriptStart(this.deferredRemote); 839 this.deferredRemote = null; 840 } 841 }; 842 843 /** 844 * Build a script and insert it into the DOM. 845 * Done is called once script has executed. 846 * 847 * @param {Object} tok The token 848 * @param {Function} done The callback when complete 849 */ 850 851 852 WriteStream.prototype._writeScriptToken = function _writeScriptToken(tok, done) { 853 var el = this._buildScript(tok); 854 var asyncRelease = this._shouldRelease(el); 855 var afterAsync = this.options.afterAsync; 856 857 if (tok.src) { 858 // Fix for attribute "SRC" (capitalized). IE does not recognize it. 859 el.src = tok.src; 860 this._scriptLoadHandler(el, !asyncRelease ? function () { 861 done(); 862 afterAsync(); 863 } : afterAsync); 864 } 865 866 try { 867 this._insertCursor(el, PROXY_SCRIPT); 868 if (!el.src || asyncRelease) { 869 done(); 870 } 871 } catch (e) { 872 this.options.error(e); 873 done(); 874 } 875 }; 876 877 /** 878 * Build a script element from an atomic script token. 879 * 880 * @param {Object} tok The token 881 * @returns {Element} 882 */ 883 884 885 WriteStream.prototype._buildScript = function _buildScript(tok) { 886 var el = this.doc.createElement(tok.tagName); 887 888 // Set attributes 889 utils.eachKey(tok.attrs, function (name, value) { 890 el.setAttribute(name, value); 891 }); 892 893 // Set content 894 if (tok.content) { 895 el.text = tok.content; 896 } 897 898 return el; 899 }; 900 901 /** 902 * Setup the script load handler on an element. 903 * 904 * @param {Object} el The element 905 * @param {Function} done The callback 906 * @private 907 */ 908 909 910 WriteStream.prototype._scriptLoadHandler = function _scriptLoadHandler(el, done) { 911 function cleanup() { 912 el = el.onload = el.onreadystatechange = el.onerror = null; 913 } 914 915 var error = this.options.error; 916 917 function success() { 918 cleanup(); 919 if (done != null) { 920 done(); 921 } 922 done = null; 923 } 924 925 function failure(err) { 926 cleanup(); 927 error(err); 928 if (done != null) { 929 done(); 930 } 931 done = null; 932 } 933 934 function reattachEventListener(el, evt) { 935 var handler = el['on' + evt]; 936 if (handler != null) { 937 el['_on' + evt] = handler; 938 } 939 } 940 941 reattachEventListener(el, 'load'); 942 reattachEventListener(el, 'error'); 943 944 _extends(el, { 945 onload: function onload() { 946 if (el._onload) { 947 try { 948 el._onload.apply(this, Array.prototype.slice.call(arguments, 0)); 949 } catch (err) { 950 failure({ msg: 'onload handler failed ' + err + ' @ ' + el.src }); 951 } 952 } 953 success(); 954 }, 955 onerror: function onerror() { 956 if (el._onerror) { 957 try { 958 el._onerror.apply(this, Array.prototype.slice.call(arguments, 0)); 959 } catch (err) { 960 failure({ msg: 'onerror handler failed ' + err + ' @ ' + el.src }); 961 return; 962 } 963 } 964 failure({ msg: 'remote script failed ' + el.src }); 965 }, 966 onreadystatechange: function onreadystatechange() { 967 if (/^(loaded|complete)$/.test(el.readyState)) { 968 success(); 969 } 970 } 971 }); 972 }; 973 974 /** 975 * Determines whether to release. 976 * 977 * @param {Object} el The element 978 * @returns {boolean} 979 * @private 980 */ 981 982 983 WriteStream.prototype._shouldRelease = function _shouldRelease(el) { 984 var isScript = /^script$/i.test(el.nodeName); 985 return !isScript || !!(this.options.releaseAsync && el.src && el.hasAttribute('async')); 986 }; 987 988 return WriteStream; 989 }(); 990 991 exports['default'] = WriteStream; 992 993/***/ }, 994/* 3 */ 995/***/ function(module, exports, __webpack_require__) { 996 997 /** 998 * @file prescribe 999 * @description Tiny, forgiving HTML parser 1000 * @version vundefined 1001 * @see {@link https://github.com/krux/prescribe/} 1002 * @license MIT 1003 * @author Derek Brans 1004 * @copyright 2016 Krux Digital, Inc 1005 */ 1006 (function webpackUniversalModuleDefinition(root, factory) { 1007 if(true) 1008 module.exports = factory(); 1009 else if(typeof define === 'function' && define.amd) 1010 define([], factory); 1011 else if(typeof exports === 'object') 1012 exports["Prescribe"] = factory(); 1013 else 1014 root["Prescribe"] = factory(); 1015 })(this, function() { 1016 return /******/ (function(modules) { // webpackBootstrap 1017 /******/ // The module cache 1018 /******/ var installedModules = {}; 1019 1020 /******/ // The require function 1021 /******/ function __webpack_require__(moduleId) { 1022 1023 /******/ // Check if module is in cache 1024 /******/ if(installedModules[moduleId]) 1025 /******/ return installedModules[moduleId].exports; 1026 1027 /******/ // Create a new module (and put it into the cache) 1028 /******/ var module = installedModules[moduleId] = { 1029 /******/ exports: {}, 1030 /******/ id: moduleId, 1031 /******/ loaded: false 1032 /******/ }; 1033 1034 /******/ // Execute the module function 1035 /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 1036 1037 /******/ // Flag the module as loaded 1038 /******/ module.loaded = true; 1039 1040 /******/ // Return the exports of the module 1041 /******/ return module.exports; 1042 /******/ } 1043 1044 1045 /******/ // expose the modules object (__webpack_modules__) 1046 /******/ __webpack_require__.m = modules; 1047 1048 /******/ // expose the module cache 1049 /******/ __webpack_require__.c = installedModules; 1050 1051 /******/ // __webpack_public_path__ 1052 /******/ __webpack_require__.p = ""; 1053 1054 /******/ // Load entry module and return exports 1055 /******/ return __webpack_require__(0); 1056 /******/ }) 1057 /************************************************************************/ 1058 /******/ ([ 1059 /* 0 */ 1060 /***/ function(module, exports, __webpack_require__) { 1061 1062 'use strict'; 1063 1064 var _HtmlParser = __webpack_require__(1); 1065 1066 var _HtmlParser2 = _interopRequireDefault(_HtmlParser); 1067 1068 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 1069 1070 module.exports = _HtmlParser2['default']; 1071 1072 /***/ }, 1073 /* 1 */ 1074 /***/ function(module, exports, __webpack_require__) { 1075 1076 'use strict'; 1077 1078 exports.__esModule = true; 1079 1080 var _supports = __webpack_require__(2); 1081 1082 var supports = _interopRequireWildcard(_supports); 1083 1084 var _streamReaders = __webpack_require__(3); 1085 1086 var streamReaders = _interopRequireWildcard(_streamReaders); 1087 1088 var _fixedReadTokenFactory = __webpack_require__(6); 1089 1090 var _fixedReadTokenFactory2 = _interopRequireDefault(_fixedReadTokenFactory); 1091 1092 var _utils = __webpack_require__(5); 1093 1094 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 1095 1096 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; } } 1097 1098 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 1099 1100 /** 1101 * Detection regular expressions. 1102 * 1103 * Order of detection matters: detection of one can only 1104 * succeed if detection of previous didn't 1105 1106 * @type {Object} 1107 */ 1108 var detect = { 1109 comment: /^<!--/, 1110 endTag: /^<\//, 1111 atomicTag: /^<\s*(script|style|noscript|iframe|textarea)[\s\/>]/i, 1112 startTag: /^</, 1113 chars: /^[^<]/ 1114 }; 1115 1116 /** 1117 * HtmlParser provides the capability to parse HTML and return tokens 1118 * representing the tags and content. 1119 */ 1120 1121 var HtmlParser = function () { 1122 /** 1123 * Constructor. 1124 * 1125 * @param {string} stream The initial parse stream contents. 1126 * @param {Object} options The options 1127 * @param {boolean} options.autoFix Set to true to automatically fix errors 1128 */ 1129 function HtmlParser() { 1130 var _this = this; 1131 1132 var stream = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 1133 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 1134 1135 _classCallCheck(this, HtmlParser); 1136 1137 this.stream = stream; 1138 1139 var fix = false; 1140 var fixedTokenOptions = {}; 1141 1142 for (var key in supports) { 1143 if (supports.hasOwnProperty(key)) { 1144 if (options.autoFix) { 1145 fixedTokenOptions[key + 'Fix'] = true; // !supports[key]; 1146 } 1147 fix = fix || fixedTokenOptions[key + 'Fix']; 1148 } 1149 } 1150 1151 if (fix) { 1152 this._readToken = (0, _fixedReadTokenFactory2['default'])(this, fixedTokenOptions, function () { 1153 return _this._readTokenImpl(); 1154 }); 1155 this._peekToken = (0, _fixedReadTokenFactory2['default'])(this, fixedTokenOptions, function () { 1156 return _this._peekTokenImpl(); 1157 }); 1158 } else { 1159 this._readToken = this._readTokenImpl; 1160 this._peekToken = this._peekTokenImpl; 1161 } 1162 } 1163 1164 /** 1165 * Appends the given string to the parse stream. 1166 * 1167 * @param {string} str The string to append 1168 */ 1169 1170 1171 HtmlParser.prototype.append = function append(str) { 1172 this.stream += str; 1173 }; 1174 1175 /** 1176 * Prepends the given string to the parse stream. 1177 * 1178 * @param {string} str The string to prepend 1179 */ 1180 1181 1182 HtmlParser.prototype.prepend = function prepend(str) { 1183 this.stream = str + this.stream; 1184 }; 1185 1186 /** 1187 * The implementation of the token reading. 1188 * 1189 * @private 1190 * @returns {?Token} 1191 */ 1192 1193 1194 HtmlParser.prototype._readTokenImpl = function _readTokenImpl() { 1195 var token = this._peekTokenImpl(); 1196 if (token) { 1197 this.stream = this.stream.slice(token.length); 1198 return token; 1199 } 1200 }; 1201 1202 /** 1203 * The implementation of token peeking. 1204 * 1205 * @returns {?Token} 1206 */ 1207 1208 1209 HtmlParser.prototype._peekTokenImpl = function _peekTokenImpl() { 1210 for (var type in detect) { 1211 if (detect.hasOwnProperty(type)) { 1212 if (detect[type].test(this.stream)) { 1213 var token = streamReaders[type](this.stream); 1214 1215 if (token) { 1216 if (token.type === 'startTag' && /script|style/i.test(token.tagName)) { 1217 return null; 1218 } else { 1219 token.text = this.stream.substr(0, token.length); 1220 return token; 1221 } 1222 } 1223 } 1224 } 1225 } 1226 }; 1227 1228 /** 1229 * The public token peeking interface. Delegates to the basic token peeking 1230 * or a version that performs fixups depending on the `autoFix` setting in 1231 * options. 1232 * 1233 * @returns {object} 1234 */ 1235 1236 1237 HtmlParser.prototype.peekToken = function peekToken() { 1238 return this._peekToken(); 1239 }; 1240 1241 /** 1242 * The public token reading interface. Delegates to the basic token reading 1243 * or a version that performs fixups depending on the `autoFix` setting in 1244 * options. 1245 * 1246 * @returns {object} 1247 */ 1248 1249 1250 HtmlParser.prototype.readToken = function readToken() { 1251 return this._readToken(); 1252 }; 1253 1254 /** 1255 * Read tokens and hand to the given handlers. 1256 * 1257 * @param {Object} handlers The handlers to use for the different tokens. 1258 */ 1259 1260 1261 HtmlParser.prototype.readTokens = function readTokens(handlers) { 1262 var tok = void 0; 1263 while (tok = this.readToken()) { 1264 // continue until we get an explicit "false" return 1265 if (handlers[tok.type] && handlers[tok.type](tok) === false) { 1266 return; 1267 } 1268 } 1269 }; 1270 1271 /** 1272 * Clears the parse stream. 1273 * 1274 * @returns {string} The contents of the parse stream before clearing. 1275 */ 1276 1277 1278 HtmlParser.prototype.clear = function clear() { 1279 var rest = this.stream; 1280 this.stream = ''; 1281 return rest; 1282 }; 1283 1284 /** 1285 * Returns the rest of the parse stream. 1286 * 1287 * @returns {string} The contents of the parse stream. 1288 */ 1289 1290 1291 HtmlParser.prototype.rest = function rest() { 1292 return this.stream; 1293 }; 1294 1295 return HtmlParser; 1296 }(); 1297 1298 exports['default'] = HtmlParser; 1299 1300 1301 HtmlParser.tokenToString = function (tok) { 1302 return tok.toString(); 1303 }; 1304 1305 HtmlParser.escapeAttributes = function (attrs) { 1306 var escapedAttrs = {}; 1307 1308 for (var name in attrs) { 1309 if (attrs.hasOwnProperty(name)) { 1310 escapedAttrs[name] = (0, _utils.escapeQuotes)(attrs[name], null); 1311 } 1312 } 1313 1314 return escapedAttrs; 1315 }; 1316 1317 HtmlParser.supports = supports; 1318 1319 for (var key in supports) { 1320 if (supports.hasOwnProperty(key)) { 1321 HtmlParser.browserHasFlaw = HtmlParser.browserHasFlaw || !supports[key] && key; 1322 } 1323 } 1324 1325 /***/ }, 1326 /* 2 */ 1327 /***/ function(module, exports) { 1328 1329 'use strict'; 1330 1331 exports.__esModule = true; 1332 var tagSoup = false; 1333 var selfClose = false; 1334 1335 var work = window.document.createElement('div'); 1336 1337 try { 1338 var html = '<P><I></P></I>'; 1339 work.innerHTML = html; 1340 exports.tagSoup = tagSoup = work.innerHTML !== html; 1341 } catch (e) { 1342 exports.tagSoup = tagSoup = false; 1343 } 1344 1345 try { 1346 work.innerHTML = '<P><i><P></P></i></P>'; 1347 exports.selfClose = selfClose = work.childNodes.length === 2; 1348 } catch (e) { 1349 exports.selfClose = selfClose = false; 1350 } 1351 1352 work = null; 1353 1354 exports.tagSoup = tagSoup; 1355 exports.selfClose = selfClose; 1356 1357 /***/ }, 1358 /* 3 */ 1359 /***/ function(module, exports, __webpack_require__) { 1360 1361 'use strict'; 1362 1363 exports.__esModule = true; 1364 1365 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; }; 1366 1367 exports.comment = comment; 1368 exports.chars = chars; 1369 exports.startTag = startTag; 1370 exports.atomicTag = atomicTag; 1371 exports.endTag = endTag; 1372 1373 var _tokens = __webpack_require__(4); 1374 1375 /** 1376 * Regular Expressions for parsing tags and attributes 1377 * 1378 * @type {Object} 1379 */ 1380 var REGEXES = { 1381 startTag: /^<([\-A-Za-z0-9_]+)((?:\s+[\w\-]+(?:\s*=?\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/, 1382 endTag: /^<\/([\-A-Za-z0-9_]+)[^>]*>/, 1383 attr: /(?:([\-A-Za-z0-9_]+)\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))|(?:([\-A-Za-z0-9_]+)(\s|$)+)/g, 1384 fillAttr: /^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noresize|noshade|nowrap|readonly|selected)$/i 1385 }; 1386 1387 /** 1388 * Reads a comment token 1389 * 1390 * @param {string} stream The input stream 1391 * @returns {CommentToken} 1392 */ 1393 function comment(stream) { 1394 var index = stream.indexOf('-->'); 1395 if (index >= 0) { 1396 return new _tokens.CommentToken(stream.substr(4, index - 1), index + 3); 1397 } 1398 } 1399 1400 /** 1401 * Reads non-tag characters. 1402 * 1403 * @param {string} stream The input stream 1404 * @returns {CharsToken} 1405 */ 1406 function chars(stream) { 1407 var index = stream.indexOf('<'); 1408 return new _tokens.CharsToken(index >= 0 ? index : stream.length); 1409 } 1410 1411 /** 1412 * Reads start tag token. 1413 * 1414 * @param {string} stream The input stream 1415 * @returns {StartTagToken} 1416 */ 1417 function startTag(stream) { 1418 var endTagIndex = stream.indexOf('>'); 1419 if (endTagIndex !== -1) { 1420 var match = stream.match(REGEXES.startTag); 1421 if (match) { 1422 var _ret = function () { 1423 var attrs = {}; 1424 var booleanAttrs = {}; 1425 var rest = match[2]; 1426 1427 match[2].replace(REGEXES.attr, function (match, name) { 1428 if (!(arguments[2] || arguments[3] || arguments[4] || arguments[5])) { 1429 attrs[name] = ''; 1430 } else if (arguments[5]) { 1431 attrs[arguments[5]] = ''; 1432 booleanAttrs[arguments[5]] = true; 1433 } else { 1434 attrs[name] = arguments[2] || arguments[3] || arguments[4] || REGEXES.fillAttr.test(name) && name || ''; 1435 } 1436 1437 rest = rest.replace(match, ''); 1438 }); 1439 1440 return { 1441 v: new _tokens.StartTagToken(match[1], match[0].length, attrs, booleanAttrs, !!match[3], rest.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')) 1442 }; 1443 }(); 1444 1445 if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; 1446 } 1447 } 1448 } 1449 1450 /** 1451 * Reads atomic tag token. 1452 * 1453 * @param {string} stream The input stream 1454 * @returns {AtomicTagToken} 1455 */ 1456 function atomicTag(stream) { 1457 var start = startTag(stream); 1458 if (start) { 1459 var rest = stream.slice(start.length); 1460 // for optimization, we check first just for the end tag 1461 if (rest.match(new RegExp('<\/\\s*' + start.tagName + '\\s*>', 'i'))) { 1462 // capturing the content is inefficient, so we do it inside the if 1463 var match = rest.match(new RegExp('([\\s\\S]*?)<\/\\s*' + start.tagName + '\\s*>', 'i')); 1464 if (match) { 1465 return new _tokens.AtomicTagToken(start.tagName, match[0].length + start.length, start.attrs, start.booleanAttrs, match[1]); 1466 } 1467 } 1468 } 1469 } 1470 1471 /** 1472 * Reads an end tag token. 1473 * 1474 * @param {string} stream The input stream 1475 * @returns {EndTagToken} 1476 */ 1477 function endTag(stream) { 1478 var match = stream.match(REGEXES.endTag); 1479 if (match) { 1480 return new _tokens.EndTagToken(match[1], match[0].length); 1481 } 1482 } 1483 1484 /***/ }, 1485 /* 4 */ 1486 /***/ function(module, exports, __webpack_require__) { 1487 1488 'use strict'; 1489 1490 exports.__esModule = true; 1491 exports.EndTagToken = exports.AtomicTagToken = exports.StartTagToken = exports.TagToken = exports.CharsToken = exports.CommentToken = exports.Token = undefined; 1492 1493 var _utils = __webpack_require__(5); 1494 1495 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 1496 1497 /** 1498 * Token is a base class for all token types parsed. Note we don't actually 1499 * use intheritance due to IE8's non-existent ES5 support. 1500 */ 1501 var Token = 1502 /** 1503 * Constructor. 1504 * 1505 * @param {string} type The type of the Token. 1506 * @param {Number} length The length of the Token text. 1507 */ 1508 exports.Token = function Token(type, length) { 1509 _classCallCheck(this, Token); 1510 1511 this.type = type; 1512 this.length = length; 1513 this.text = ''; 1514 }; 1515 1516 /** 1517 * CommentToken represents comment tags. 1518 */ 1519 1520 1521 var CommentToken = exports.CommentToken = function () { 1522 /** 1523 * Constructor. 1524 * 1525 * @param {string} content The content of the comment 1526 * @param {Number} length The length of the Token text. 1527 */ 1528 function CommentToken(content, length) { 1529 _classCallCheck(this, CommentToken); 1530 1531 this.type = 'comment'; 1532 this.length = length || (content ? content.length : 0); 1533 this.text = ''; 1534 this.content = content; 1535 } 1536 1537 CommentToken.prototype.toString = function toString() { 1538 return '<!--' + this.content; 1539 }; 1540 1541 return CommentToken; 1542 }(); 1543 1544 /** 1545 * CharsToken represents non-tag characters. 1546 */ 1547 1548 1549 var CharsToken = exports.CharsToken = function () { 1550 /** 1551 * Constructor. 1552 * 1553 * @param {Number} length The length of the Token text. 1554 */ 1555 function CharsToken(length) { 1556 _classCallCheck(this, CharsToken); 1557 1558 this.type = 'chars'; 1559 this.length = length; 1560 this.text = ''; 1561 } 1562 1563 CharsToken.prototype.toString = function toString() { 1564 return this.text; 1565 }; 1566 1567 return CharsToken; 1568 }(); 1569 1570 /** 1571 * TagToken is a base class for all tag-based Tokens. 1572 */ 1573 1574 1575 var TagToken = exports.TagToken = function () { 1576 /** 1577 * Constructor. 1578 * 1579 * @param {string} type The type of the token. 1580 * @param {string} tagName The tag name. 1581 * @param {Number} length The length of the Token text. 1582 * @param {Object} attrs The dictionary of attributes and values 1583 * @param {Object} booleanAttrs If an entry has 'true' then the attribute 1584 * is a boolean attribute 1585 */ 1586 function TagToken(type, tagName, length, attrs, booleanAttrs) { 1587 _classCallCheck(this, TagToken); 1588 1589 this.type = type; 1590 this.length = length; 1591 this.text = ''; 1592 this.tagName = tagName; 1593 this.attrs = attrs; 1594 this.booleanAttrs = booleanAttrs; 1595 this.unary = false; 1596 this.html5Unary = false; 1597 } 1598 1599 /** 1600 * Formats the given token tag. 1601 * 1602 * @param {TagToken} tok The TagToken to format. 1603 * @param {?string} [content=null] The content of the token. 1604 * @returns {string} The formatted tag. 1605 */ 1606 1607 1608 TagToken.formatTag = function formatTag(tok) { 1609 var content = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 1610 1611 var str = '<' + tok.tagName; 1612 for (var key in tok.attrs) { 1613 if (tok.attrs.hasOwnProperty(key)) { 1614 str += ' ' + key; 1615 1616 var val = tok.attrs[key]; 1617 if (typeof tok.booleanAttrs === 'undefined' || typeof tok.booleanAttrs[key] === 'undefined') { 1618 str += '="' + (0, _utils.escapeQuotes)(val) + '"'; 1619 } 1620 } 1621 } 1622 1623 if (tok.rest) { 1624 str += ' ' + tok.rest; 1625 } 1626 1627 if (tok.unary && !tok.html5Unary) { 1628 str += '/>'; 1629 } else { 1630 str += '>'; 1631 } 1632 1633 if (content !== undefined && content !== null) { 1634 str += content + '</' + tok.tagName + '>'; 1635 } 1636 1637 return str; 1638 }; 1639 1640 return TagToken; 1641 }(); 1642 1643 /** 1644 * StartTagToken represents a start token. 1645 */ 1646 1647 1648 var StartTagToken = exports.StartTagToken = function () { 1649 /** 1650 * Constructor. 1651 * 1652 * @param {string} tagName The tag name. 1653 * @param {Number} length The length of the Token text 1654 * @param {Object} attrs The dictionary of attributes and values 1655 * @param {Object} booleanAttrs If an entry has 'true' then the attribute 1656 * is a boolean attribute 1657 * @param {boolean} unary True if the tag is a unary tag 1658 * @param {string} rest The rest of the content. 1659 */ 1660 function StartTagToken(tagName, length, attrs, booleanAttrs, unary, rest) { 1661 _classCallCheck(this, StartTagToken); 1662 1663 this.type = 'startTag'; 1664 this.length = length; 1665 this.text = ''; 1666 this.tagName = tagName; 1667 this.attrs = attrs; 1668 this.booleanAttrs = booleanAttrs; 1669 this.html5Unary = false; 1670 this.unary = unary; 1671 this.rest = rest; 1672 } 1673 1674 StartTagToken.prototype.toString = function toString() { 1675 return TagToken.formatTag(this); 1676 }; 1677 1678 return StartTagToken; 1679 }(); 1680 1681 /** 1682 * AtomicTagToken represents an atomic tag. 1683 */ 1684 1685 1686 var AtomicTagToken = exports.AtomicTagToken = function () { 1687 /** 1688 * Constructor. 1689 * 1690 * @param {string} tagName The name of the tag. 1691 * @param {Number} length The length of the tag text. 1692 * @param {Object} attrs The attributes. 1693 * @param {Object} booleanAttrs If an entry has 'true' then the attribute 1694 * is a boolean attribute 1695 * @param {string} content The content of the tag. 1696 */ 1697 function AtomicTagToken(tagName, length, attrs, booleanAttrs, content) { 1698 _classCallCheck(this, AtomicTagToken); 1699 1700 this.type = 'atomicTag'; 1701 this.length = length; 1702 this.text = ''; 1703 this.tagName = tagName; 1704 this.attrs = attrs; 1705 this.booleanAttrs = booleanAttrs; 1706 this.unary = false; 1707 this.html5Unary = false; 1708 this.content = content; 1709 } 1710 1711 AtomicTagToken.prototype.toString = function toString() { 1712 return TagToken.formatTag(this, this.content); 1713 }; 1714 1715 return AtomicTagToken; 1716 }(); 1717 1718 /** 1719 * EndTagToken represents an end tag. 1720 */ 1721 1722 1723 var EndTagToken = exports.EndTagToken = function () { 1724 /** 1725 * Constructor. 1726 * 1727 * @param {string} tagName The name of the tag. 1728 * @param {Number} length The length of the tag text. 1729 */ 1730 function EndTagToken(tagName, length) { 1731 _classCallCheck(this, EndTagToken); 1732 1733 this.type = 'endTag'; 1734 this.length = length; 1735 this.text = ''; 1736 this.tagName = tagName; 1737 } 1738 1739 EndTagToken.prototype.toString = function toString() { 1740 return '</' + this.tagName + '>'; 1741 }; 1742 1743 return EndTagToken; 1744 }(); 1745 1746 /***/ }, 1747 /* 5 */ 1748 /***/ function(module, exports) { 1749 1750 'use strict'; 1751 1752 exports.__esModule = true; 1753 exports.escapeQuotes = escapeQuotes; 1754 1755 /** 1756 * Escape quotes in the given value. 1757 * 1758 * @param {string} value The value to escape. 1759 * @param {string} [defaultValue=''] The default value to return if value is falsy. 1760 * @returns {string} 1761 */ 1762 function escapeQuotes(value) { 1763 var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; 1764 1765 // There's no lookback in JS, so /(^|[^\\])"/ only matches the first of two `"`s. 1766 // Instead, just match anything before a double-quote and escape if it's not already escaped. 1767 return !value ? defaultValue : value.replace(/([^"]*)"/g, function (_, prefix) { 1768 return (/\\/.test(prefix) ? prefix + '"' : prefix + '\\"' 1769 ); 1770 }); 1771 } 1772 1773 /***/ }, 1774 /* 6 */ 1775 /***/ function(module, exports) { 1776 1777 'use strict'; 1778 1779 exports.__esModule = true; 1780 exports['default'] = fixedReadTokenFactory; 1781 /** 1782 * Empty Elements - HTML 4.01 1783 * 1784 * @type {RegExp} 1785 */ 1786 var EMPTY = /^(AREA|BASE|BASEFONT|BR|COL|FRAME|HR|IMG|INPUT|ISINDEX|LINK|META|PARAM|EMBED)$/i; 1787 1788 /** 1789 * Elements that you can intentionally leave open (and which close themselves) 1790 * 1791 * @type {RegExp} 1792 */ 1793 var CLOSESELF = /^(COLGROUP|DD|DT|LI|OPTIONS|P|TD|TFOOT|TH|THEAD|TR)$/i; 1794 1795 /** 1796 * Corrects a token. 1797 * 1798 * @param {Token} tok The token to correct 1799 * @returns {Token} The corrected token 1800 */ 1801 function correct(tok) { 1802 if (tok && tok.type === 'startTag') { 1803 tok.unary = EMPTY.test(tok.tagName) || tok.unary; 1804 tok.html5Unary = !/\/>$/.test(tok.text); 1805 } 1806 return tok; 1807 } 1808 1809 /** 1810 * Peeks at the next token in the parser. 1811 * 1812 * @param {HtmlParser} parser The parser 1813 * @param {Function} readTokenImpl The underlying readToken implementation 1814 * @returns {Token} The next token 1815 */ 1816 function peekToken(parser, readTokenImpl) { 1817 var tmp = parser.stream; 1818 var tok = correct(readTokenImpl()); 1819 parser.stream = tmp; 1820 return tok; 1821 } 1822 1823 /** 1824 * Closes the last token. 1825 * 1826 * @param {HtmlParser} parser The parser 1827 * @param {Array<Token>} stack The stack 1828 */ 1829 function closeLast(parser, stack) { 1830 var tok = stack.pop(); 1831 1832 // prepend close tag to stream. 1833 parser.prepend('</' + tok.tagName + '>'); 1834 } 1835 1836 /** 1837 * Create a new token stack. 1838 * 1839 * @returns {Array<Token>} 1840 */ 1841 function newStack() { 1842 var stack = []; 1843 1844 stack.last = function () { 1845 return this[this.length - 1]; 1846 }; 1847 1848 stack.lastTagNameEq = function (tagName) { 1849 var last = this.last(); 1850 return last && last.tagName && last.tagName.toUpperCase() === tagName.toUpperCase(); 1851 }; 1852 1853 stack.containsTagName = function (tagName) { 1854 for (var i = 0, tok; tok = this[i]; i++) { 1855 if (tok.tagName === tagName) { 1856 return true; 1857 } 1858 } 1859 return false; 1860 }; 1861 1862 return stack; 1863 } 1864 1865 /** 1866 * Return a readToken implementation that fixes input. 1867 * 1868 * @param {HtmlParser} parser The parser 1869 * @param {Object} options Options for fixing 1870 * @param {boolean} options.tagSoupFix True to fix tag soup scenarios 1871 * @param {boolean} options.selfCloseFix True to fix self-closing tags 1872 * @param {Function} readTokenImpl The underlying readToken implementation 1873 * @returns {Function} 1874 */ 1875 function fixedReadTokenFactory(parser, options, readTokenImpl) { 1876 var stack = newStack(); 1877 1878 var handlers = { 1879 startTag: function startTag(tok) { 1880 var tagName = tok.tagName; 1881 1882 if (tagName.toUpperCase() === 'TR' && stack.lastTagNameEq('TABLE')) { 1883 parser.prepend('<TBODY>'); 1884 prepareNextToken(); 1885 } else if (options.selfCloseFix && CLOSESELF.test(tagName) && stack.containsTagName(tagName)) { 1886 if (stack.lastTagNameEq(tagName)) { 1887 closeLast(parser, stack); 1888 } else { 1889 parser.prepend('</' + tok.tagName + '>'); 1890 prepareNextToken(); 1891 } 1892 } else if (!tok.unary) { 1893 stack.push(tok); 1894 } 1895 }, 1896 endTag: function endTag(tok) { 1897 var last = stack.last(); 1898 if (last) { 1899 if (options.tagSoupFix && !stack.lastTagNameEq(tok.tagName)) { 1900 // cleanup tag soup 1901 closeLast(parser, stack); 1902 } else { 1903 stack.pop(); 1904 } 1905 } else if (options.tagSoupFix) { 1906 // cleanup tag soup part 2: skip this token 1907 readTokenImpl(); 1908 prepareNextToken(); 1909 } 1910 } 1911 }; 1912 1913 function prepareNextToken() { 1914 var tok = peekToken(parser, readTokenImpl); 1915 if (tok && handlers[tok.type]) { 1916 handlers[tok.type](tok); 1917 } 1918 } 1919 1920 return function fixedReadToken() { 1921 prepareNextToken(); 1922 return correct(readTokenImpl()); 1923 }; 1924 } 1925 1926 /***/ } 1927 /******/ ]) 1928 }); 1929 ; 1930 1931/***/ }, 1932/* 4 */ 1933/***/ function(module, exports) { 1934 1935 'use strict'; 1936 1937 exports.__esModule = true; 1938 1939 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; }; 1940 1941 exports.existy = existy; 1942 exports.isFunction = isFunction; 1943 exports.each = each; 1944 exports.eachKey = eachKey; 1945 exports.defaults = defaults; 1946 exports.toArray = toArray; 1947 exports.last = last; 1948 exports.isTag = isTag; 1949 exports.isScript = isScript; 1950 exports.isStyle = isStyle; 1951 /** 1952 * Determine if the thing is not undefined and not null. 1953 * 1954 * @param {*} thing The thing to test 1955 * @returns {boolean} True if the thing is not undefined and not null. 1956 */ 1957 function existy(thing) { 1958 return thing !== void 0 && thing !== null; 1959 } 1960 1961 /** 1962 * Is this a function? 1963 * 1964 * @param {*} x The variable to test 1965 * @returns {boolean} True if the variable is a function 1966 */ 1967 function isFunction(x) { 1968 return 'function' === typeof x; 1969 } 1970 1971 /** 1972 * Loop over each item in an array-like value. 1973 * 1974 * @param {Array<*>} arr The array to loop over 1975 * @param {Function} fn The function to call 1976 * @param {?Object} target The object to bind to the function 1977 */ 1978 function each(arr, fn, target) { 1979 var i = void 0; 1980 var len = arr && arr.length || 0; 1981 for (i = 0; i < len; i++) { 1982 fn.call(target, arr[i], i); 1983 } 1984 } 1985 1986 /** 1987 * Loop over each key/value pair in a hash. 1988 * 1989 * @param {Object} obj The object 1990 * @param {Function} fn The function to call 1991 * @param {?Object} target The object to bind to the function 1992 */ 1993 function eachKey(obj, fn, target) { 1994 for (var key in obj) { 1995 if (obj.hasOwnProperty(key)) { 1996 fn.call(target, key, obj[key]); 1997 } 1998 } 1999 } 2000 2001 /** 2002 * Set default options where some option was not specified. 2003 * 2004 * @param {Object} options The destination 2005 * @param {Object} _defaults The defaults 2006 * @returns {Object} 2007 */ 2008 function defaults(options, _defaults) { 2009 options = options || {}; 2010 eachKey(_defaults, function (key, val) { 2011 if (!existy(options[key])) { 2012 options[key] = val; 2013 } 2014 }); 2015 return options; 2016 } 2017 2018 /** 2019 * Convert value (e.g., a NodeList) to an array. 2020 * 2021 * @param {*} obj The object 2022 * @returns {Array<*>} 2023 */ 2024 function toArray(obj) { 2025 try { 2026 return Array.prototype.slice.call(obj); 2027 } catch (e) { 2028 var _ret = function () { 2029 var ret = []; 2030 each(obj, function (val) { 2031 ret.push(val); 2032 }); 2033 return { 2034 v: ret 2035 }; 2036 }(); 2037 2038 if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; 2039 } 2040 } 2041 2042 /** 2043 * Get the last item in an array 2044 * 2045 * @param {Array<*>} array The array 2046 * @returns {*} The last item in the array 2047 */ 2048 function last(array) { 2049 return array[array.length - 1]; 2050 } 2051 2052 /** 2053 * Test if token is a script tag. 2054 * 2055 * @param {Object} tok The token 2056 * @param {String} tag The tag name 2057 * @returns {boolean} True if the token is a script tag 2058 */ 2059 function isTag(tok, tag) { 2060 return !tok || !(tok.type === 'startTag' || tok.type === 'atomicTag') || !('tagName' in tok) ? !1 : !!~tok.tagName.toLowerCase().indexOf(tag); 2061 } 2062 2063 /** 2064 * Test if token is a script tag. 2065 * 2066 * @param {Object} tok The token 2067 * @returns {boolean} True if the token is a script tag 2068 */ 2069 function isScript(tok) { 2070 return isTag(tok, 'script'); 2071 } 2072 2073 /** 2074 * Test if token is a style tag. 2075 * 2076 * @param {Object} tok The token 2077 * @returns {boolean} True if the token is a style tag 2078 */ 2079 function isStyle(tok) { 2080 return isTag(tok, 'style'); 2081 } 2082 2083/***/ } 2084/******/ ]) 2085}); 2086;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.