vendor: 29,300 bytes, lines 1-778
1/** 2 * 2007-2020 ETS-Soft 3 * 4 * NOTICE OF LICENSE 5 * 6 * This file is not open source! Each license that you purchased is only available for 1 wesite only. 7 * If you want to use this file on more websites (or projects), you need to purchase additional licenses. 8 * You are not allowed to redistribute, resell, lease, license, sub-license or offer our resources to any third party. 9 * 10 * DISCLAIMER 11 * 12 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer 13 * versions in the future. If you wish to customize PrestaShop for your 14 * needs please contact us for extra customization service at an affordable price 15 * 16 * @author ETS-Soft <[email protected]> 17 * @copyright 2007-2020 ETS-Soft 18 * @license Valid for 1 website (or project) for each purchase of license 19 * International Registered Trademark & Property of ETS-Soft 20 */ 21 22;(function(window, undefined) { 23 "use strict"; 24 25 // noinspection JSUnresolvedVariable 26 /** 27 * library instance - here and not in construct to be shorter in minimization 28 * @return void 29 */ 30 var $ = window.jQuery || window.Zepto, 31 32 /** 33 * unique plugin instance id counter 34 * @type {number} 35 */ 36 ets_lazyInstanceId = 0, 37 38 /** 39 * helper to register window load for jQuery 3 40 * @type {boolean} 41 */ 42 windowLoaded = false; 43 44 /** 45 * make ets_lazy available to jquery - and make it a bit more case-insensitive :) 46 * @access public 47 * @type {function} 48 * @param {object} settings 49 * @return {ETSLazyPlugin} 50 */ 51 $.fn.ETSLazy = $.fn.ets_lazy = function(settings) { 52 return new ETSLazyPlugin(this, settings); 53 }; 54 55 /** 56 * helper to add plugins to ets_lazy prototype configuration 57 * @access public 58 * @type {function} 59 * @param {string|Array} names 60 * @param {string|Array|function} [elements] 61 * @param {function} loader 62 * @return void 63 */ 64 $.ETSLazy = $.ets_lazy = function(names, elements, loader) { 65 // make second parameter optional 66 if ($.isFunction(elements)) { 67 loader = elements; 68 elements = []; 69 } 70 71 // exit here if parameter is not a callable function 72 if (!$.isFunction(loader)) { 73 return; 74 } 75 76 // make parameters an array of names to be sure 77 names = $.isArray(names) ? names : [names]; 78 elements = $.isArray(elements) ? elements : [elements]; 79 80 var config = ETSLazyPlugin.prototype.config, 81 forced = config._f || (config._f = {}); 82 83 // add the loader plugin for every name 84 for (var i = 0, l = names.length; i < l; i++) { 85 if (config[names[i]] === undefined || $.isFunction(config[names[i]])) { 86 config[names[i]] = loader; 87 } 88 } 89 90 // add forced elements loader 91 for (var c = 0, a = elements.length; c < a; c++) { 92 forced[elements[c]] = names[0]; 93 } 94 }; 95 96 /** 97 * contains all logic and the whole element handling 98 * is packed in a private function outside class to reduce memory usage, because it will not be created on every plugin instance 99 * @access private 100 * @type {function} 101 * @param {ETSLazyPlugin} instance 102 * @param {object} config 103 * @param {object|Array} items 104 * @param {object} events 105 * @param {string} namespace 106 * @return void 107 */ 108 function _executeETSLazy(instance, config, items, events, namespace) { 109 /** 110 * a helper to trigger the 'onFinishedAll' callback after all other events 111 * @access private 112 * @type {number} 113 */ 114 var _awaitingAfterLoad = 0, 115 116 /** 117 * visible content width 118 * @access private 119 * @type {number} 120 */ 121 _actualWidth = -1, 122 123 /** 124 * visible content height 125 * @access private 126 * @type {number} 127 */ 128 _actualHeight = -1, 129 130 /** 131 * determine possibly detected high pixel density 132 * @access private 133 * @type {boolean} 134 */ 135 _isRetinaDisplay = false, 136 137 /** 138 * dictionary entry for better minimization 139 * @access private 140 * @type {string} 141 */ 142 _afterLoad = 'afterLoad', 143 144 /** 145 * dictionary entry for better minimization 146 * @access private 147 * @type {string} 148 */ 149 _load = 'load', 150 151 /** 152 * dictionary entry for better minimization 153 * @access private 154 * @type {string} 155 */ 156 _error = 'error', 157 158 /** 159 * dictionary entry for better minimization 160 * @access private 161 * @type {string} 162 */ 163 _img = 'img', 164 165 /** 166 * dictionary entry for better minimization 167 * @access private 168 * @type {string} 169 */ 170 _src = 'src', 171 172 /** 173 * dictionary entry for better minimization 174 * @access private 175 * @type {string} 176 */ 177 _srcset = 'srcset', 178 179 /** 180 * dictionary entry for better minimization 181 * @access private 182 * @type {string} 183 */ 184 _sizes = 'sizes', 185 186 /** 187 * dictionary entry for better minimization 188 * @access private 189 * @type {string} 190 */ 191 _backgroundImage = 'background-image'; 192 193 /** 194 * initialize plugin 195 * bind loading to events or set delay time to load all items at once 196 * @access private 197 * @return void 198 */ 199 function _initialize() { 200 // detect actual device pixel ratio 201 // noinspection JSUnresolvedVariable 202 _isRetinaDisplay = window.devicePixelRatio > 1; 203 204 // prepare all initial items 205 items = _prepareItems(items); 206 207 // if delay time is set load all items at once after delay time 208 if (config.delay >= 0) { 209 setTimeout(function() { 210 _ets_lazyLoadItems(true); 211 }, config.delay); 212 } 213 214 // if no delay is set or combine usage is active bind events 215 if (config.delay < 0 || config.combined) { 216 // create unique event function 217 events.e = _throttle(config.throttle, function(event) { 218 // reset detected window size on resize event 219 if (event.type === 'resize') { 220 _actualWidth = _actualHeight = -1; 221 } 222 223 // execute 'ets_lazy magic' 224 _ets_lazyLoadItems(event.all); 225 }); 226 227 // create function to add new items to instance 228 events.a = function(additionalItems) { 229 additionalItems = _prepareItems(additionalItems); 230 items.push.apply(items, additionalItems); 231 }; 232 233 // create function to get all instance items left 234 events.g = function() { 235 // filter loaded items before return in case internal filter was not running until now 236 return (items = $(items).filter(function() { 237 return !$(this).data(config.loadedName); 238 })); 239 }; 240 241 // create function to force loading elements 242 events.f = function(forcedItems) { 243 for (var i = 0; i < forcedItems.length; i++) { 244 // only handle item if available in current instance 245 // use a compare function, because Zepto can't handle object parameter for filter 246 // var item = items.filter(forcedItems[i]); 247 /* jshint loopfunc: true */ 248 var item = items.filter(function() { 249 return this === forcedItems[i]; 250 }); 251 252 if (item.length) { 253 _ets_lazyLoadItems(false, item); 254 } 255 } 256 }; 257 258 // load initial items 259 _ets_lazyLoadItems(); 260 261 // bind ets_lazy load functions to scroll and resize event 262 // noinspection JSUnresolvedVariable 263 $(config.appendScroll).on('scroll.' + namespace + ' resize.' + namespace, events.e); 264 } 265 } 266 267 /** 268 * prepare items before handle them 269 * @access private 270 * @param {Array|object|jQuery} items 271 * @return {Array|object|jQuery} 272 */ 273 function _prepareItems(items) { 274 // fetch used configurations before loops 275 var defaultImage = config.defaultImage, 276 placeholder = config.placeholder, 277 imageBase = config.imageBase, 278 srcsetAttribute = config.srcsetAttribute, 279 loaderAttribute = config.loaderAttribute, 280 forcedTags = config._f || {}; 281 282 // filter items and only add those who not handled yet and got needed attributes available 283 items = $(items).filter(function() { 284 var element = $(this), 285 tag = _getElementTagName(this); 286 287 return !element.data(config.handledName) && 288 (element.attr(config.attribute) || element.attr(srcsetAttribute) || element.attr(loaderAttribute) || forcedTags[tag] !== undefined); 289 }) 290 291 // append plugin instance to all elements 292 .data('plugin_' + config.name, instance); 293 294 for (var i = 0, l = items.length; i < l; i++) { 295 var element = $(items[i]), 296 tag = _getElementTagName(items[i]), 297 elementImageBase = element.attr(config.imageBaseAttribute) || imageBase; 298 299 // generate and update source set if an image base is set 300 if (tag === _img && elementImageBase && element.attr(srcsetAttribute)) { 301 element.attr(srcsetAttribute, _getCorrectedSrcSet(element.attr(srcsetAttribute), elementImageBase)); 302 } 303 304 // add loader to forced element types 305 if (forcedTags[tag] !== undefined && !element.attr(loaderAttribute)) { 306 element.attr(loaderAttribute, forcedTags[tag]); 307 } 308 309 // set default image on every element without source 310 if (tag === _img && defaultImage && !element.attr(_src)) { 311 element.attr(_src, defaultImage); 312 } 313 314 // set placeholder on every element without background image 315 else if (tag !== _img && placeholder && (!element.css(_backgroundImage) || element.css(_backgroundImage) === 'none')) { 316 element.css(_backgroundImage, "url('" + placeholder + "')"); 317 } 318 } 319 320 return items; 321 } 322 323 /** 324 * the 'ets_lazy magic' - check all items 325 * @access private 326 * @param {boolean} [allItems] 327 * @param {object} [forced] 328 * @return void 329 */ 330 function _ets_lazyLoadItems(allItems, forced) { 331 // skip if no items where left 332 if (!items.length) { 333 // destroy instance if option is enabled 334 if (config.autoDestroy) { 335 // noinspection JSUnresolvedFunction 336 instance.destroy(); 337 } 338 339 return; 340 } 341 342 var elements = forced || items, 343 loadTriggered = false, 344 imageBase = config.imageBase || '', 345 srcsetAttribute = config.srcsetAttribute, 346 handledName = config.handledName; 347 348 // loop all available items 349 for (var i = 0; i < elements.length; i++) { 350 // item is at least in loadable area 351 if (allItems || forced || _isInLoadableArea(elements[i])) { 352 var element = $(elements[i]), 353 tag = _getElementTagName(elements[i]), 354 attribute = element.attr(config.attribute), 355 elementImageBase = element.attr(config.imageBaseAttribute) || imageBase, 356 customLoader = element.attr(config.loaderAttribute); 357 358 // is not already handled 359 if (!element.data(handledName) && 360 // and is visible or visibility doesn't matter 361 (!config.visibleOnly || element.is(':visible')) && ( 362 // and image source or source set attribute is available 363 (attribute || element.attr(srcsetAttribute)) && ( 364 // and is image tag where attribute is not equal source or source set 365 (tag === _img && (elementImageBase + attribute !== element.attr(_src) || element.attr(srcsetAttribute) !== element.attr(_srcset))) || 366 // or is non image tag where attribute is not equal background 367 (tag !== _img && elementImageBase + attribute !== element.css(_backgroundImage)) 368 ) || 369 // or custom loader is available 370 customLoader)) 371 { 372 // mark element always as handled as this point to prevent double handling 373 loadTriggered = true; 374 element.data(handledName, true); 375 376 // load item 377 _handleItem(element, tag, elementImageBase, customLoader); 378 } 379 } 380 } 381 382 // when something was loaded remove them from remaining items 383 if (loadTriggered) { 384 items = $(items).filter(function() { 385 return !$(this).data(handledName); 386 }); 387 } 388 } 389 390 /** 391 * load the given element the ets_lazy way 392 * @access private 393 * @param {object} element 394 * @param {string} tag 395 * @param {string} imageBase 396 * @param {function} [customLoader] 397 * @return void 398 */ 399 function _handleItem(element, tag, imageBase, customLoader) { 400 // increment count of items waiting for after load 401 ++_awaitingAfterLoad; 402 403 // extended error callback for correct 'onFinishedAll' handling 404 var errorCallback = function() { 405 _triggerCallback('onError', element); 406 _reduceAwaiting(); 407 408 // prevent further callback calls 409 errorCallback = $.noop; 410 }; 411 412 // trigger function before loading image 413 _triggerCallback('beforeLoad', element); 414 415 // fetch all double used data here for better code minimization 416 var srcAttribute = config.attribute, 417 srcsetAttribute = config.srcsetAttribute, 418 sizesAttribute = config.sizesAttribute, 419 retinaAttribute = config.retinaAttribute, 420 removeAttribute = config.removeAttribute, 421 loadedName = config.loadedName, 422 elementRetina = element.attr(retinaAttribute); 423 424 // handle custom loader 425 if (customLoader) { 426 // on load callback 427 var loadCallback = function() { 428 // remove attribute from element 429 if (removeAttribute) { 430 element.removeAttr(config.loaderAttribute); 431 } 432 433 // mark element as loaded 434 element.data(loadedName, true); 435 436 // call after load event 437 _triggerCallback(_afterLoad, element); 438 439 // remove item from waiting queue and possibly trigger finished event 440 // it's needed to be asynchronous to run after filter was in _ets_lazyLoadItems 441 setTimeout(_reduceAwaiting, 1); 442 443 // prevent further callback calls 444 loadCallback = $.noop; 445 }; 446 447 // bind error event to trigger callback and reduce waiting amount 448 element.off(_error).one(_error, errorCallback) 449 450 // bind after load callback to element 451 .one(_load, loadCallback); 452 453 // trigger custom loader and handle response 454 if (!_triggerCallback(customLoader, element, function(response) { 455 if(response) { 456 element.off(_load); 457 loadCallback(); 458 } 459 else { 460 element.off(_error); 461 errorCallback(); 462 } 463 })) { 464 element.trigger(_error); 465 } 466 } 467 468 // handle images 469 else { 470 // create image object 471 var imageObj = $(new Image()); 472 473 // bind error event to trigger callback and reduce waiting amount 474 imageObj.one(_error, errorCallback) 475 476 // bind after load callback to image 477 .one(_load, function() { 478 // remove element from view 479 element.hide(); 480 481 // set image back to element 482 // do it as single 'attr' calls, to be sure 'src' is set after 'srcset' 483 if (tag === _img) { 484 element.attr(_sizes, imageObj.attr(_sizes)) 485 .attr(_srcset, imageObj.attr(_srcset)) 486 .attr(_src, imageObj.attr(_src)); 487 } 488 else { 489 element.css(_backgroundImage, "url('" + imageObj.attr(_src) + "')"); 490 } 491 492 // bring it back with some effect! 493 element[config.effect](config.effectTime); 494 495 // remove attribute from element 496 if (removeAttribute) { 497 element.removeAttr(srcAttribute + ' ' + srcsetAttribute + ' ' + retinaAttribute + ' ' + config.imageBaseAttribute); 498 499 // only remove 'sizes' attribute, if it was a custom one 500 if (sizesAttribute !== _sizes) { 501 element.removeAttr(sizesAttribute); 502 } 503 } 504 505 // mark element as loaded 506 element.data(loadedName, true); 507 508 // call after load event 509 _triggerCallback(_afterLoad, element); 510 511 // cleanup image object 512 imageObj.remove(); 513 514 // remove item from waiting queue and possibly trigger finished event 515 _reduceAwaiting(); 516 }); 517 518 // set sources 519 // do it as single 'attr' calls, to be sure 'src' is set after 'srcset' 520 var imageSrc = (_isRetinaDisplay && elementRetina ? elementRetina : element.attr(srcAttribute)) || ''; 521 imageObj.attr(_sizes, element.attr(sizesAttribute)) 522 .attr(_srcset, element.attr(srcsetAttribute)) 523 .attr(_src, imageSrc ? imageBase + imageSrc : null); 524 525 // call after load even on cached image 526 imageObj.complete && imageObj.trigger(_load); // jshint ignore : line 527 } 528 } 529 530 /** 531 * check if the given element is inside the current viewport or threshold 532 * @access private 533 * @param {object} element 534 * @return {boolean} 535 */ 536 function _isInLoadableArea(element) { 537 var elementBound = element.getBoundingClientRect(), 538 direction = config.scrollDirection, 539 threshold = config.threshold, 540 vertical = // check if element is in loadable area from top 541 ((_getActualHeight() + threshold) > elementBound.top) && 542 // check if element is even in loadable are from bottom 543 (-threshold < elementBound.bottom), 544 horizontal = // check if element is in loadable area from left 545 ((_getActualWidth() + threshold) > elementBound.left) && 546 // check if element is even in loadable area from right 547 (-threshold < elementBound.right); 548 549 if (direction === 'vertical') { 550 return vertical; 551 } 552 else if (direction === 'horizontal') { 553 return horizontal; 554 } 555 556 return vertical && horizontal; 557 } 558 559 /** 560 * receive the current viewed width of the browser 561 * @access private 562 * @return {number} 563 */ 564 function _getActualWidth() { 565 return _actualWidth >= 0 ? _actualWidth : (_actualWidth = $(window).width()); 566 } 567 568 /** 569 * receive the current viewed height of the browser 570 * @access private 571 * @return {number} 572 */ 573 function _getActualHeight() { 574 return _actualHeight >= 0 ? _actualHeight : (_actualHeight = $(window).height()); 575 } 576 577 /** 578 * get lowercase tag name of an element 579 * @access private 580 * @param {object} element 581 * @returns {string} 582 */ 583 function _getElementTagName(element) { 584 return element.tagName.toLowerCase(); 585 } 586 587 /** 588 * prepend image base to all srcset entries 589 * @access private 590 * @param {string} srcset 591 * @param {string} imageBase 592 * @returns {string} 593 */ 594 function _getCorrectedSrcSet(srcset, imageBase) { 595 if (imageBase) { 596 // trim, remove unnecessary spaces and split entries 597 var entries = srcset.split(','); 598 srcset = ''; 599 600 for (var i = 0, l = entries.length; i < l; i++) { 601 srcset += imageBase + entries[i].trim() + (i !== l - 1 ? ',' : ''); 602 } 603 } 604 605 return srcset; 606 } 607 608 /** 609 * helper function to throttle down event triggering 610 * @access private 611 * @param {number} delay 612 * @param {function} callback 613 * @return {function} 614 */ 615 function _throttle(delay, callback) { 616 var timeout, 617 lastExecute = 0; 618 619 return function(event, ignoreThrottle) { 620 var elapsed = +new Date() - lastExecute; 621 622 function run() { 623 lastExecute = +new Date(); 624 // noinspection JSUnresolvedFunction 625 callback.call(instance, event); 626 } 627 628 timeout && clearTimeout(timeout); // jshint ignore : line 629 630 if (elapsed > delay || !config.enableThrottle || ignoreThrottle) { 631 run(); 632 } 633 else { 634 timeout = setTimeout(run, delay - elapsed); 635 } 636 }; 637 } 638 639 /** 640 * reduce count of awaiting elements to 'afterLoad' event and fire 'onFinishedAll' if reached zero 641 * @access private 642 * @return void 643 */ 644 function _reduceAwaiting() { 645 --_awaitingAfterLoad; 646 647 // if no items were left trigger finished event 648 if (!items.length && !_awaitingAfterLoad) { 649 _triggerCallback('onFinishedAll'); 650 } 651 } 652 653 /** 654 * single implementation to handle callbacks, pass element and set 'this' to current instance 655 * @access private 656 * @param {string|function} callback 657 * @param {object} [element] 658 * @param {*} [args] 659 * @return {boolean} 660 */ 661 function _triggerCallback(callback, element, args) { 662 if ((callback = config[callback])) { 663 // jQuery's internal '$(arguments).slice(1)' are causing problems at least on old iPads 664 // below is shorthand of 'Array.prototype.slice.call(arguments, 1)' 665 callback.apply(instance, [].slice.call(arguments, 1)); 666 return true; 667 } 668 669 return false; 670 } 671 672 // if event driven or window is already loaded don't wait for page loading 673 if (config.bind === 'event' || windowLoaded) { 674 _initialize(); 675 } 676 677 // otherwise load initial items and start ets_lazy after page load 678 else { 679 // noinspection JSUnresolvedVariable 680 $(window).on(_load + '.' + namespace, _initialize); 681 } 682 } 683 684 /** 685 * ets_lazy plugin class constructor 686 * @constructor 687 * @access private 688 * @param {object} elements 689 * @param {object} settings 690 * @return {object|ETSLazyPlugin} 691 */ 692 function ETSLazyPlugin(elements, settings) { 693 /** 694 * this ets_lazy plugin instance 695 * @access private 696 * @type {object|ETSLazyPlugin|ETSLazyPlugin.prototype} 697 */ 698 var _instance = this, 699 700 /** 701 * this ets_lazy plugin instance configuration 702 * @access private 703 * @type {object} 704 */ 705 _config = $.extend({}, _instance.config, settings), 706 707 /** 708 * instance generated event executed on container scroll or resize 709 * packed in an object to be referenceable and short named because properties will not be minified 710 * @access private 711 * @type {object} 712 */ 713 _events = {}, 714 715 /** 716 * unique namespace for instance related events 717 * @access private 718 * @type {string} 719 */ 720 _namespace = _config.name + '-' + (++ets_lazyInstanceId); 721 722 // noinspection JSUndefinedPropertyAssignment 723 /** 724 * wrapper to get or set an entry from plugin instance configuration 725 * much smaller on minify as direct access 726 * @access public 727 * @type {function} 728 * @param {string} entryName 729 * @param {*} [value] 730 * @return {ETSLazyPlugin|*} 731 */ 732 _instance.config = function(entryName, value) { 733 if (value === undefined) { 734 return _config[entryName]; 735 } 736 737 _config[entryName] = value; 738 return _instance; 739 }; 740 741 // noinspection JSUndefinedPropertyAssignment 742 /** 743 * add additional items to current instance 744 * @access public 745 * @param {Array|object|string} items 746 * @return {ETSLazyPlugin} 747 */ 748 _instance.addItems = function(items) { 749 _events.a && _events.a($.type(items) === 'string' ? $(items) : items); // jshint ignore : line 750 return _instance; 751 }; 752 753 // noinspection JSUndefinedPropertyAssignment 754 /** 755 * get all left items of this instance 756 * @access public 757 * @returns {object} 758 */ 759 _instance.getItems = function() { 760 return _events.g ? _events.g() : {}; 761 }; 762 763 // noinspection JSUndefinedPropertyAssignment 764 /** 765 * force ets_lazy to load all items in loadable area right now 766 * by default without throttle 767 * @access public 768 * @type {function} 769 * @param {boolean} [useThrottle] 770 * @return {ETSLazyPlugin} 771 */ 772 _instance.update = function(useThrottle) { 773 _events.e && _events.e({}, !useThrottle); // jshint ignore : line 774 return _instance; 775 }; 776 777 // noinspection JSUndefinedPropertyAssignment 778 /**
779 * force element(s) to load directly, ignoring the viewport 780 * @access public 781 * @param {Array|object|string} items 782 * @return {ETSLazyPlugin} 783 */ 784 _instance.force = function(items) { 785 _events.f && _events.f($.type(items) === 'string' ? $(items) : items); // jshint ignore : line 786 return _instance; 787 }; 788 789 // noinspection JSUndefinedPropertyAssignment 790 /** 791 * force ets_lazy to load all available items right now 792 * this call ignores throttling 793 * @access public 794 * @type {function} 795 * @return {ETSLazyPlugin} 796 */ 797 _instance.loadAll = function() { 798 _events.e && _events.e({all: true}, true); // jshint ignore : line 799 return _instance; 800 }; 801 802 // noinspection JSUndefinedPropertyAssignment 803 /** 804 * destroy this plugin instance 805 * @access public 806 * @type {function} 807 * @return undefined 808 */ 809 _instance.destroy = function() { 810 // unbind instance generated events 811 // noinspection JSUnresolvedFunction, JSUnresolvedVariable 812 $(_config.appendScroll).off('.' + _namespace, _events.e); 813 // noinspection JSUnresolvedVariable 814 $(window).off('.' + _namespace); 815 816 // clear events 817 _events = {}; 818 819 return undefined; 820 }; 821 822 // start using ets_lazy and return all elements to be chainable or instance for further use 823 // noinspection JSUnresolvedVariable 824 _executeETSLazy(_instance, _config, elements, _events, _namespace); 825 return _config.chainable ? elements : _instance; 826 } 827 828 /** 829 * settings and configuration data 830 * @access public 831 * @type {object|*} 832 */ 833 ETSLazyPlugin.prototype.config = { 834 // general 835 name : 'ets_lazy', 836 chainable : true, 837 autoDestroy : true, 838 bind : 'load', 839 threshold : 500, 840 visibleOnly : false, 841 appendScroll : window, 842 scrollDirection : 'both', 843 imageBase : null, 844 defaultImage : 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', 845 placeholder : null, 846 delay : -1, 847 combined : false, 848 849 // attributes 850 attribute : 'data-src', 851 srcsetAttribute : 'data-srcset', 852 sizesAttribute : 'data-sizes', 853 retinaAttribute : 'data-retina', 854 loaderAttribute : 'data-loader', 855 imageBaseAttribute : 'data-imagebase', 856 removeAttribute : true, 857 handledName : 'handled', 858 loadedName : 'loaded', 859 860 // effect 861 effect : 'show', 862 effectTime : 0, 863 864 // throttle 865 enableThrottle : true, 866 throttle : 250, 867 868 // callbacks 869 beforeLoad : undefined, 870 afterLoad : undefined, 871 onError : undefined, 872 onFinishedAll : undefined 873 }; 874 875 // register window load event globally to prevent not loading elements 876 // since jQuery 3.X ready state is fully async and may be executed after 'load' 877 $(window).on('load', function() { 878 windowLoaded = true; 879 }); 880})(window);
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.