From a227f4765f109327eadfee925cfc33e7b3b626ea Mon Sep 17 00:00:00 2001 From: Ahmed Saed Date: Wed, 19 Aug 2020 16:47:23 +0200 Subject: [PATCH] v2.3.4 pre-production checklist (PR #118) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * change version number and update readme.txt * Update readme.txt based on remy's update * update plugin version on comments header * Update readme.txt wordpress version * change lazyload front js version to be 16 * add lazyload scripts version 16.1 * Update changelog with all changes in the common library Co-authored-by: Rémy Perona --- assets/js/16.1/lazyload.js | 733 ++++++++++++++++++++++++++ assets/js/16.1/lazyload.min.js | 1 + readme.txt | 14 +- rocket-lazy-load.php | 4 +- src/Subscriber/LazyloadSubscriber.php | 2 +- 5 files changed, 749 insertions(+), 5 deletions(-) create mode 100644 assets/js/16.1/lazyload.js create mode 100644 assets/js/16.1/lazyload.min.js diff --git a/assets/js/16.1/lazyload.js b/assets/js/16.1/lazyload.js new file mode 100644 index 0000000..e0d495a --- /dev/null +++ b/assets/js/16.1/lazyload.js @@ -0,0 +1,733 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = global || self, global.LazyLoad = factory()); +}(this, (function () { 'use strict'; + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends.apply(this, arguments); + } + + var runningOnBrowser = typeof window !== "undefined"; + var isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent); + var supportsIntersectionObserver = runningOnBrowser && "IntersectionObserver" in window; + var supportsClassList = runningOnBrowser && "classList" in document.createElement("p"); + var isHiDpi = runningOnBrowser && window.devicePixelRatio > 1; + + var defaultSettings = { + elements_selector: "IMG", + container: isBot || runningOnBrowser ? document : null, + threshold: 300, + thresholds: null, + data_src: "src", + data_srcset: "srcset", + data_sizes: "sizes", + data_bg: "bg", + data_bg_hidpi: "bg-hidpi", + data_bg_multi: "bg-multi", + data_bg_multi_hidpi: "bg-multi-hidpi", + data_poster: "poster", + class_applied: "applied", + class_loading: "loading", + class_loaded: "loaded", + class_error: "error", + unobserve_completed: true, + unobserve_entered: false, + cancel_on_exit: false, + callback_enter: null, + callback_exit: null, + callback_applied: null, + callback_loading: null, + callback_loaded: null, + callback_error: null, + callback_finish: null, + callback_cancel: null, + use_native: false + }; + var getExtendedSettings = function getExtendedSettings(customSettings) { + return _extends({}, defaultSettings, customSettings); + }; + + /* Creates instance and notifies it through the window element */ + var createInstance = function createInstance(classObj, options) { + var event; + var eventString = "LazyLoad::Initialized"; + var instance = new classObj(options); + + try { + // Works in modern browsers + event = new CustomEvent(eventString, { + detail: { + instance: instance + } + }); + } catch (err) { + // Works in Internet Explorer (all versions) + event = document.createEvent("CustomEvent"); + event.initCustomEvent(eventString, false, false, { + instance: instance + }); + } + + window.dispatchEvent(event); + }; + /* Auto initialization of one or more instances of lazyload, depending on the + options passed in (plain object or an array) */ + + + var autoInitialize = function autoInitialize(classObj, options) { + if (!options) { + return; + } + + if (!options.length) { + // Plain object + createInstance(classObj, options); + } else { + // Array of objects + for (var i = 0, optionsItem; optionsItem = options[i]; i += 1) { + createInstance(classObj, optionsItem); + } + } + }; + + var statusLoading = "loading"; + var statusLoaded = "loaded"; + var statusApplied = "applied"; + var statusError = "error"; + var statusNative = "native"; + + var dataPrefix = "data-"; + var statusDataName = "ll-status"; + var getData = function getData(element, attribute) { + return element.getAttribute(dataPrefix + attribute); + }; + var setData = function setData(element, attribute, value) { + var attrName = dataPrefix + attribute; + + if (value === null) { + element.removeAttribute(attrName); + return; + } + + element.setAttribute(attrName, value); + }; + var getStatus = function getStatus(element) { + return getData(element, statusDataName); + }; + var setStatus = function setStatus(element, status) { + return setData(element, statusDataName, status); + }; + var resetStatus = function resetStatus(element) { + return setStatus(element, null); + }; + var hasEmptyStatus = function hasEmptyStatus(element) { + return getStatus(element) === null; + }; + var hasStatusLoading = function hasStatusLoading(element) { + return getStatus(element) === statusLoading; + }; + var hasStatusError = function hasStatusError(element) { + return getStatus(element) === statusError; + }; + var hasStatusNative = function hasStatusNative(element) { + return getStatus(element) === statusNative; + }; + var hadStartedLoading = function hadStartedLoading(element) { + return !hasEmptyStatus(element); + }; + + var safeCallback = function safeCallback(callback, arg1, arg2, arg3) { + if (!callback) { + return; + } + + if (arg3 !== undefined) { + callback(arg1, arg2, arg3); + return; + } + + if (arg2 !== undefined) { + callback(arg1, arg2); + return; + } + + callback(arg1); + }; + + var addClass = function addClass(element, className) { + if (supportsClassList) { + element.classList.add(className); + return; + } + + element.className += (element.className ? " " : "") + className; + }; + var removeClass = function removeClass(element, className) { + if (supportsClassList) { + element.classList.remove(className); + return; + } + + element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), " ").replace(/^\s+/, "").replace(/\s+$/, ""); + }; + + var addTempImage = function addTempImage(element) { + element.llTempImage = document.createElement("IMG"); + }; + var deleteTempImage = function deleteTempImage(element) { + delete element.llTempImage; + }; + var getTempImage = function getTempImage(element) { + return element.llTempImage; + }; + + var unobserve = function unobserve(element, instance) { + if (!instance) return; + var observer = instance._observer; + if (!observer) return; + observer.unobserve(element); + }; + var resetObserver = function resetObserver(observer) { + observer.disconnect(); + }; + var unobserveIfRequired = function unobserveIfRequired(element, settings, instance) { + if (settings.unobserve_entered) unobserve(element, instance); + }; + + var updateLoadingCount = function updateLoadingCount(instance, delta) { + if (!instance) return; + instance.loadingCount += delta; + }; + var decreaseToLoadCount = function decreaseToLoadCount(instance) { + if (!instance) return; + instance.toLoadCount -= 1; + }; + var setToLoadCount = function setToLoadCount(instance, value) { + if (!instance) return; + instance.toLoadCount = value; + }; + var isSomethingLoading = function isSomethingLoading(instance) { + return instance.loadingCount > 0; + }; + var haveElementsToLoad = function haveElementsToLoad(instance) { + return instance.toLoadCount > 0; + }; + + var getSourceTags = function getSourceTags(parentTag) { + var sourceTags = []; + + for (var i = 0, childTag; childTag = parentTag.children[i]; i += 1) { + if (childTag.tagName === "SOURCE") { + sourceTags.push(childTag); + } + } + + return sourceTags; + }; + var setAttributeIfValue = function setAttributeIfValue(element, attrName, value) { + if (!value) { + return; + } + + element.setAttribute(attrName, value); + }; + var resetAttribute = function resetAttribute(element, attrName) { + element.removeAttribute(attrName); + }; + var hasOriginalAttributes = function hasOriginalAttributes(element) { + return !!element.llOriginalAttrs; + }; + var saveOriginalImageAttributes = function saveOriginalImageAttributes(element) { + if (hasOriginalAttributes(element)) { + return; + } + + var originalAttributes = {}; + originalAttributes["src"] = element.getAttribute("src"); + originalAttributes["srcset"] = element.getAttribute("srcset"); + originalAttributes["sizes"] = element.getAttribute("sizes"); + element.llOriginalAttrs = originalAttributes; + }; + var restoreOriginalImageAttributes = function restoreOriginalImageAttributes(element) { + if (!hasOriginalAttributes(element)) { + return; + } + + var originalAttributes = element.llOriginalAttrs; + setAttributeIfValue(element, "src", originalAttributes["src"]); + setAttributeIfValue(element, "srcset", originalAttributes["srcset"]); + setAttributeIfValue(element, "sizes", originalAttributes["sizes"]); + }; + var setImageAttributes = function setImageAttributes(element, settings) { + setAttributeIfValue(element, "sizes", getData(element, settings.data_sizes)); + setAttributeIfValue(element, "srcset", getData(element, settings.data_srcset)); + setAttributeIfValue(element, "src", getData(element, settings.data_src)); + }; + var resetImageAttributes = function resetImageAttributes(element) { + resetAttribute(element, "src"); + resetAttribute(element, "srcset"); + resetAttribute(element, "sizes"); + }; + var forEachPictureSource = function forEachPictureSource(element, fn) { + var parent = element.parentNode; + + if (!parent || parent.tagName !== "PICTURE") { + return; + } + + var sourceTags = getSourceTags(parent); + sourceTags.forEach(fn); + }; + var forEachVideoSource = function forEachVideoSource(element, fn) { + var sourceTags = getSourceTags(element); + sourceTags.forEach(fn); + }; + var restoreOriginalAttributesImg = function restoreOriginalAttributesImg(element) { + forEachPictureSource(element, function (sourceTag) { + restoreOriginalImageAttributes(sourceTag); + }); + restoreOriginalImageAttributes(element); + }; + var setSourcesImg = function setSourcesImg(element, settings) { + forEachPictureSource(element, function (sourceTag) { + saveOriginalImageAttributes(sourceTag); + setImageAttributes(sourceTag, settings); + }); + saveOriginalImageAttributes(element); + setImageAttributes(element, settings); + }; + var resetSourcesImg = function resetSourcesImg(element) { + forEachPictureSource(element, function (sourceTag) { + resetImageAttributes(sourceTag); + }); + resetImageAttributes(element); + }; + var setSourcesIframe = function setSourcesIframe(element, settings) { + setAttributeIfValue(element, "src", getData(element, settings.data_src)); + }; + var setSourcesVideo = function setSourcesVideo(element, settings) { + forEachVideoSource(element, function (sourceTag) { + setAttributeIfValue(sourceTag, "src", getData(sourceTag, settings.data_src)); + }); + setAttributeIfValue(element, "poster", getData(element, settings.data_poster)); + setAttributeIfValue(element, "src", getData(element, settings.data_src)); + element.load(); + }; + var setSourcesFunctions = { + IMG: setSourcesImg, + IFRAME: setSourcesIframe, + VIDEO: setSourcesVideo + }; + var setBackground = function setBackground(element, settings, instance) { + var bg1xValue = getData(element, settings.data_bg); + var bgHiDpiValue = getData(element, settings.data_bg_hidpi); + var bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; + if (!bgDataValue) return; + element.style.backgroundImage = "url(\"".concat(bgDataValue, "\")"); + getTempImage(element).setAttribute("src", bgDataValue); + manageLoading(element, settings, instance); + }; // NOTE: THE TEMP IMAGE TRICK CANNOT BE DONE WITH data-multi-bg + // BECAUSE INSIDE ITS VALUES MUST BE WRAPPED WITH URL() AND ONE OF THEM + // COULD BE A GRADIENT BACKGROUND IMAGE + + var setMultiBackground = function setMultiBackground(element, settings, instance) { + var bg1xValue = getData(element, settings.data_bg_multi); + var bgHiDpiValue = getData(element, settings.data_bg_multi_hidpi); + var bgDataValue = isHiDpi && bgHiDpiValue ? bgHiDpiValue : bg1xValue; + + if (!bgDataValue) { + return; + } + + element.style.backgroundImage = bgDataValue; + manageApplied(element, settings, instance); + }; + var setSources = function setSources(element, settings) { + var setSourcesFunction = setSourcesFunctions[element.tagName]; + + if (!setSourcesFunction) { + return; + } + + setSourcesFunction(element, settings); + }; + var manageApplied = function manageApplied(element, settings, instance) { + addClass(element, settings.class_applied); + setStatus(element, statusApplied); + removeDataMultiBackground(element, settings); + + if (settings.unobserve_completed) { + // Unobserve now because we can't do it on load + unobserve(element, settings); + } + + safeCallback(settings.callback_applied, element, instance); + }; + var manageLoading = function manageLoading(element, settings, instance) { + updateLoadingCount(instance, +1); + addClass(element, settings.class_loading); + setStatus(element, statusLoading); + safeCallback(settings.callback_loading, element, instance); + }; // REMOVE DATA ATTRIBUTES -------------- + + var removeDataImg = function removeDataImg(element, settings) { + setData(element, settings.data_src, null); + setData(element, settings.data_srcset, null); + setData(element, settings.data_sizes, null); + forEachPictureSource(element, function (sourceTag) { + setData(sourceTag, settings.data_srcset, null); + setData(sourceTag, settings.data_sizes, null); + }); + }; + var removeDataIframe = function removeDataIframe(element, settings) { + setData(element, settings.data_src, null); + }; + var removeDataVideo = function removeDataVideo(element, settings) { + setData(element, settings.data_src, null); + setData(element, settings.data_poster, null); + forEachVideoSource(element, function (sourceTag) { + setData(sourceTag, settings.data_src, null); + }); + }; + var removeDataFunctions = { + IMG: removeDataImg, + IFRAME: removeDataIframe, + VIDEO: removeDataVideo + }; + var removeDataBackground = function removeDataBackground(element, settings) { + setData(element, settings.data_bg, null); + setData(element, settings.data_bg_hidpi, null); + }; + var removeDataMultiBackground = function removeDataMultiBackground(element, settings) { + setData(element, settings.data_bg_multi, null); + setData(element, settings.data_bg_multi_hidpi, null); + }; + var removeDataAttributes = function removeDataAttributes(element, settings) { + var removeDataFunction = removeDataFunctions[element.tagName]; + + if (removeDataFunction) { + removeDataFunction(element, settings); + return; + } + + removeDataBackground(element, settings); + }; + + var elementsWithLoadEvent = ["IMG", "IFRAME", "VIDEO"]; + var hasLoadEvent = function hasLoadEvent(element) { + return elementsWithLoadEvent.indexOf(element.tagName) > -1; + }; + var checkFinish = function checkFinish(settings, instance) { + if (instance && !isSomethingLoading(instance) && !haveElementsToLoad(instance)) { + safeCallback(settings.callback_finish, instance); + } + }; + var addEventListener = function addEventListener(element, eventName, handler) { + element.addEventListener(eventName, handler); + element.llEvLisnrs[eventName] = handler; + }; + var removeEventListener = function removeEventListener(element, eventName, handler) { + element.removeEventListener(eventName, handler); + }; + var hasEventListeners = function hasEventListeners(element) { + return !!element.llEvLisnrs; + }; + var addEventListeners = function addEventListeners(element, loadHandler, errorHandler) { + if (!hasEventListeners(element)) element.llEvLisnrs = {}; + var loadEventName = element.tagName === "VIDEO" ? "loadeddata" : "load"; + addEventListener(element, loadEventName, loadHandler); + addEventListener(element, "error", errorHandler); + }; + var removeEventListeners = function removeEventListeners(element) { + if (!hasEventListeners(element)) { + return; + } + + var eventListeners = element.llEvLisnrs; + + for (var eventName in eventListeners) { + var handler = eventListeners[eventName]; + removeEventListener(element, eventName, handler); + } + + delete element.llEvLisnrs; + }; + var doneHandler = function doneHandler(element, settings, instance) { + deleteTempImage(element); + updateLoadingCount(instance, -1); + decreaseToLoadCount(instance); + removeClass(element, settings.class_loading); + + if (settings.unobserve_completed) { + unobserve(element, instance); + } + }; + var loadHandler = function loadHandler(event, element, settings, instance) { + var goingNative = hasStatusNative(element); + doneHandler(element, settings, instance); + addClass(element, settings.class_loaded); + setStatus(element, statusLoaded); + removeDataAttributes(element, settings); + safeCallback(settings.callback_loaded, element, instance); + if (!goingNative) checkFinish(settings, instance); + }; + var errorHandler = function errorHandler(event, element, settings, instance) { + var goingNative = hasStatusNative(element); + doneHandler(element, settings, instance); + addClass(element, settings.class_error); + setStatus(element, statusError); + safeCallback(settings.callback_error, element, instance); + if (!goingNative) checkFinish(settings, instance); + }; + var addOneShotEventListeners = function addOneShotEventListeners(element, settings, instance) { + var elementToListenTo = getTempImage(element) || element; + + if (hasEventListeners(elementToListenTo)) { + // This happens when loading is retried twice + return; + } + + var _loadHandler = function _loadHandler(event) { + loadHandler(event, element, settings, instance); + removeEventListeners(elementToListenTo); + }; + + var _errorHandler = function _errorHandler(event) { + errorHandler(event, element, settings, instance); + removeEventListeners(elementToListenTo); + }; + + addEventListeners(elementToListenTo, _loadHandler, _errorHandler); + }; + + var loadBackground = function loadBackground(element, settings, instance) { + addTempImage(element); + addOneShotEventListeners(element, settings, instance); + setBackground(element, settings, instance); + setMultiBackground(element, settings, instance); + }; + + var loadRegular = function loadRegular(element, settings, instance) { + addOneShotEventListeners(element, settings, instance); + setSources(element, settings); + manageLoading(element, settings, instance); + }; + + var load = function load(element, settings, instance) { + if (hasLoadEvent(element)) { + loadRegular(element, settings, instance); + } else { + loadBackground(element, settings, instance); + } + }; + var loadNative = function loadNative(element, settings, instance) { + addOneShotEventListeners(element, settings, instance); + setSources(element, settings); + removeDataAttributes(element, settings); + setStatus(element, statusNative); + }; + + var cancelLoadingIfRequired = function cancelLoadingIfRequired(element, entry, settings, instance) { + if (!settings.cancel_on_exit) return; + if (!hasStatusLoading(element)) return; + if (element.tagName !== "IMG") return; //Works only on images + + removeEventListeners(element); + resetSourcesImg(element); + restoreOriginalAttributesImg(element); + removeClass(element, settings.class_loading); + updateLoadingCount(instance, -1); + resetStatus(element); + safeCallback(settings.callback_cancel, element, entry, instance); + }; + + var onEnter = function onEnter(element, entry, settings, instance) { + safeCallback(settings.callback_enter, element, entry, instance); + unobserveIfRequired(element, settings, instance); + if (hadStartedLoading(element)) return; //Prevent loading it again + + load(element, settings, instance); + }; + var onExit = function onExit(element, entry, settings, instance) { + if (hasEmptyStatus(element)) return; //Ignore the first pass, at landing + + cancelLoadingIfRequired(element, entry, settings, instance); + safeCallback(settings.callback_exit, element, entry, instance); + }; + + var tagsWithNativeLazy = ["IMG", "IFRAME"]; + var shouldUseNative = function shouldUseNative(settings) { + return settings.use_native && "loading" in HTMLImageElement.prototype; + }; + var loadAllNative = function loadAllNative(elements, settings, instance) { + elements.forEach(function (element) { + if (tagsWithNativeLazy.indexOf(element.tagName) === -1) { + return; + } + + element.setAttribute("loading", "lazy"); //TODO: Move inside the loadNative method + + loadNative(element, settings, instance); + }); + setToLoadCount(instance, 0); + }; + + var isIntersecting = function isIntersecting(entry) { + return entry.isIntersecting || entry.intersectionRatio > 0; + }; + + var getObserverSettings = function getObserverSettings(settings) { + return { + root: settings.container === document ? null : settings.container, + rootMargin: settings.thresholds || settings.threshold + "px" + }; + }; + + var intersectionHandler = function intersectionHandler(entries, settings, instance) { + entries.forEach(function (entry) { + return isIntersecting(entry) ? onEnter(entry.target, entry, settings, instance) : onExit(entry.target, entry, settings, instance); + }); + }; + + var observeElements = function observeElements(observer, elements) { + elements.forEach(function (element) { + observer.observe(element); + }); + }; + var updateObserver = function updateObserver(observer, elementsToObserve) { + resetObserver(observer); + observeElements(observer, elementsToObserve); + }; + var setObserver = function setObserver(settings, instance) { + if (!supportsIntersectionObserver || shouldUseNative(settings)) { + return; + } + + instance._observer = new IntersectionObserver(function (entries) { + intersectionHandler(entries, settings, instance); + }, getObserverSettings(settings)); + }; + + var toArray = function toArray(nodeSet) { + return Array.prototype.slice.call(nodeSet); + }; + var queryElements = function queryElements(settings) { + return settings.container.querySelectorAll(settings.elements_selector); + }; + var excludeManagedElements = function excludeManagedElements(elements) { + return toArray(elements).filter(hasEmptyStatus); + }; + var hasError = function hasError(element) { + return hasStatusError(element); + }; + var filterErrorElements = function filterErrorElements(elements) { + return toArray(elements).filter(hasError); + }; + var getElementsToLoad = function getElementsToLoad(elements, settings) { + return excludeManagedElements(elements || queryElements(settings)); + }; + + var retryLazyLoad = function retryLazyLoad(settings, instance) { + var errorElements = filterErrorElements(queryElements(settings)); + errorElements.forEach(function (element) { + removeClass(element, settings.class_error); + resetStatus(element); + }); + instance.update(); + }; + var setOnlineCheck = function setOnlineCheck(settings, instance) { + if (!runningOnBrowser) { + return; + } + + window.addEventListener("online", function () { + retryLazyLoad(settings, instance); + }); + }; + + var LazyLoad = function LazyLoad(customSettings, elements) { + var settings = getExtendedSettings(customSettings); + this._settings = settings; + this.loadingCount = 0; + setObserver(settings, this); + setOnlineCheck(settings, this); + this.update(elements); + }; + + LazyLoad.prototype = { + update: function update(givenNodeset) { + var settings = this._settings; + var elementsToLoad = getElementsToLoad(givenNodeset, settings); + setToLoadCount(this, elementsToLoad.length); + + if (isBot || !supportsIntersectionObserver) { + this.loadAll(elementsToLoad); + return; + } + + if (shouldUseNative(settings)) { + loadAllNative(elementsToLoad, settings, this); + return; + } + + updateObserver(this._observer, elementsToLoad); + }, + destroy: function destroy() { + // Observer + if (this._observer) { + this._observer.disconnect(); + } // Clean custom attributes on elements + + + queryElements(this._settings).forEach(function (element) { + delete element.llOriginalAttrs; + }); // Delete all internal props + + delete this._observer; + delete this._settings; + delete this.loadingCount; + delete this.toLoadCount; + }, + loadAll: function loadAll(elements) { + var _this = this; + + var settings = this._settings; + var elementsToLoad = getElementsToLoad(elements, settings); + elementsToLoad.forEach(function (element) { + load(element, settings, _this); + }); + } + }; + + LazyLoad.load = function (element, customSettings) { + var settings = getExtendedSettings(customSettings); + load(element, settings); + }; + + LazyLoad.resetStatus = function (element) { + resetStatus(element); + }; // Automatic instances creation if required (useful for async script loading) + + + if (runningOnBrowser) { + autoInitialize(LazyLoad, window.lazyLoadOptions); + } + + return LazyLoad; + +}))); diff --git a/assets/js/16.1/lazyload.min.js b/assets/js/16.1/lazyload.min.js new file mode 100644 index 0000000..d4eee20 --- /dev/null +++ b/assets/js/16.1/lazyload.min.js @@ -0,0 +1 @@ +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).LazyLoad=n()}(this,(function(){"use strict";function t(){return(t=Object.assign||function(t){for(var n=1;n1,r={elements_selector:"IMG",container:e||n?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",data_bg_hidpi:"bg-hidpi",data_bg_multi:"bg-multi",data_bg_multi_hidpi:"bg-multi-hidpi",data_poster:"poster",class_applied:"applied",class_loading:"loading",class_loaded:"loaded",class_error:"error",unobserve_completed:!0,unobserve_entered:!1,cancel_on_exit:!1,callback_enter:null,callback_exit:null,callback_applied:null,callback_loading:null,callback_loaded:null,callback_error:null,callback_finish:null,callback_cancel:null,use_native:!1},c=function(n){return t({},r,n)},l=function(t,n){var e,i=new t(n);try{e=new CustomEvent("LazyLoad::Initialized",{detail:{instance:i}})}catch(t){(e=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:i})}window.dispatchEvent(e)},s=function(t,n){return t.getAttribute("data-"+n)},u=function(t,n,e){var i="data-"+n;null!==e?t.setAttribute(i,e):t.removeAttribute(i)},d=function(t){return s(t,"ll-status")},f=function(t,n){return u(t,"ll-status",n)},_=function(t){return f(t,null)},g=function(t){return null===d(t)},v=function(t){return"native"===d(t)},b=function(t,n,e,i){t&&(void 0===i?void 0===e?t(n):t(n,e):t(n,e,i))},p=function(t,n){a?t.classList.add(n):t.className+=(t.className?" ":"")+n},h=function(t,n){a?t.classList.remove(n):t.className=t.className.replace(new RegExp("(^|\\s+)"+n+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")},m=function(t){return t.llTempImage},E=function(t,n){if(n){var e=n._observer;e&&e.unobserve(t)}},I=function(t,n){t&&(t.loadingCount+=n)},A=function(t,n){t&&(t.toLoadCount=n)},L=function(t){for(var n,e=[],i=0;n=t.children[i];i+=1)"SOURCE"===n.tagName&&e.push(n);return e},y=function(t,n,e){e&&t.setAttribute(n,e)},w=function(t,n){t.removeAttribute(n)},k=function(t){return!!t.llOriginalAttrs},z=function(t){if(!k(t)){var n={};n.src=t.getAttribute("src"),n.srcset=t.getAttribute("srcset"),n.sizes=t.getAttribute("sizes"),t.llOriginalAttrs=n}},O=function(t){if(k(t)){var n=t.llOriginalAttrs;y(t,"src",n.src),y(t,"srcset",n.srcset),y(t,"sizes",n.sizes)}},C=function(t,n){y(t,"sizes",s(t,n.data_sizes)),y(t,"srcset",s(t,n.data_srcset)),y(t,"src",s(t,n.data_src))},M=function(t){w(t,"src"),w(t,"srcset"),w(t,"sizes")},N=function(t,n){var e=t.parentNode;e&&"PICTURE"===e.tagName&&L(e).forEach(n)},x=function(t,n){L(t).forEach(n)},R={IMG:function(t,n){N(t,(function(t){z(t),C(t,n)})),z(t),C(t,n)},IFRAME:function(t,n){y(t,"src",s(t,n.data_src))},VIDEO:function(t,n){x(t,(function(t){y(t,"src",s(t,n.data_src))})),y(t,"poster",s(t,n.data_poster)),y(t,"src",s(t,n.data_src)),t.load()}},G=function(t,n){var e=R[t.tagName];e&&e(t,n)},T=function(t,n,e){I(e,1),p(t,n.class_loading),f(t,"loading"),b(n.callback_loading,t,e)},D={IMG:function(t,n){u(t,n.data_src,null),u(t,n.data_srcset,null),u(t,n.data_sizes,null),N(t,(function(t){u(t,n.data_srcset,null),u(t,n.data_sizes,null)}))},IFRAME:function(t,n){u(t,n.data_src,null)},VIDEO:function(t,n){u(t,n.data_src,null),u(t,n.data_poster,null),x(t,(function(t){u(t,n.data_src,null)}))}},F=function(t,n){u(t,n.data_bg_multi,null),u(t,n.data_bg_multi_hidpi,null)},V=function(t,n){var e=D[t.tagName];e?e(t,n):function(t,n){u(t,n.data_bg,null),u(t,n.data_bg_hidpi,null)}(t,n)},j=["IMG","IFRAME","VIDEO"],P=function(t,n){!n||function(t){return t.loadingCount>0}(n)||function(t){return t.toLoadCount>0}(n)||b(t.callback_finish,n)},S=function(t,n,e){t.addEventListener(n,e),t.llEvLisnrs[n]=e},U=function(t,n,e){t.removeEventListener(n,e)},$=function(t){return!!t.llEvLisnrs},q=function(t){if($(t)){var n=t.llEvLisnrs;for(var e in n){var i=n[e];U(t,e,i)}delete t.llEvLisnrs}},H=function(t,n,e){!function(t){delete t.llTempImage}(t),I(e,-1),function(t){t&&(t.toLoadCount-=1)}(e),h(t,n.class_loading),n.unobserve_completed&&E(t,e)},B=function(t,n,e){var i=m(t)||t;$(i)||function(t,n,e){$(t)||(t.llEvLisnrs={});var i="VIDEO"===t.tagName?"loadeddata":"load";S(t,i,n),S(t,"error",e)}(i,(function(a){!function(t,n,e,i){var a=v(n);H(n,e,i),p(n,e.class_loaded),f(n,"loaded"),V(n,e),b(e.callback_loaded,n,i),a||P(e,i)}(0,t,n,e),q(i)}),(function(a){!function(t,n,e,i){var a=v(n);H(n,e,i),p(n,e.class_error),f(n,"error"),b(e.callback_error,n,i),a||P(e,i)}(0,t,n,e),q(i)}))},J=function(t,n,e){!function(t){t.llTempImage=document.createElement("IMG")}(t),B(t,n,e),function(t,n,e){var i=s(t,n.data_bg),a=s(t,n.data_bg_hidpi),r=o&&a?a:i;r&&(t.style.backgroundImage='url("'.concat(r,'")'),m(t).setAttribute("src",r),T(t,n,e))}(t,n,e),function(t,n,e){var i=s(t,n.data_bg_multi),a=s(t,n.data_bg_multi_hidpi),r=o&&a?a:i;r&&(t.style.backgroundImage=r,function(t,n,e){p(t,n.class_applied),f(t,"applied"),F(t,n),n.unobserve_completed&&E(t,n),b(n.callback_applied,t,e)}(t,n,e))}(t,n,e)},K=function(t,n,e){!function(t){return j.indexOf(t.tagName)>-1}(t)?J(t,n,e):function(t,n,e){B(t,n,e),G(t,n),T(t,n,e)}(t,n,e)},Q=["IMG","IFRAME"],W=function(t){return t.use_native&&"loading"in HTMLImageElement.prototype},X=function(t,n,e){t.forEach((function(t){return function(t){return t.isIntersecting||t.intersectionRatio>0}(t)?function(t,n,e,i){b(e.callback_enter,t,n,i),function(t,n,e){n.unobserve_entered&&E(t,e)}(t,e,i),function(t){return!g(t)}(t)||K(t,e,i)}(t.target,t,n,e):function(t,n,e,i){g(t)||(function(t,n,e,i){e.cancel_on_exit&&function(t){return"loading"===d(t)}(t)&&"IMG"===t.tagName&&(q(t),function(t){N(t,(function(t){M(t)})),M(t)}(t),function(t){N(t,(function(t){O(t)})),O(t)}(t),h(t,e.class_loading),I(i,-1),_(t),b(e.callback_cancel,t,n,i))}(t,n,e,i),b(e.callback_exit,t,n,i))}(t.target,t,n,e)}))},Y=function(t){return Array.prototype.slice.call(t)},Z=function(t){return t.container.querySelectorAll(t.elements_selector)},tt=function(t){return function(t){return"error"===d(t)}(t)},nt=function(t,n){return function(t){return Y(t).filter(g)}(t||Z(n))},et=function(t,e){var a=c(t);this._settings=a,this.loadingCount=0,function(t,n){i&&!W(t)&&(n._observer=new IntersectionObserver((function(e){X(e,t,n)}),function(t){return{root:t.container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}}(t)))}(a,this),function(t,e){n&&window.addEventListener("online",(function(){!function(t,n){var e;(e=Z(t),Y(e).filter(tt)).forEach((function(n){h(n,t.class_error),_(n)})),n.update()}(t,e)}))}(a,this),this.update(e)};return et.prototype={update:function(t){var n,a,o=this._settings,r=nt(t,o);A(this,r.length),!e&&i?W(o)?function(t,n,e){t.forEach((function(t){-1!==Q.indexOf(t.tagName)&&(t.setAttribute("loading","lazy"),function(t,n,e){B(t,n,e),G(t,n),V(t,n),f(t,"native")}(t,n,e))})),A(e,0)}(r,o,this):(a=r,function(t){t.disconnect()}(n=this._observer),function(t,n){n.forEach((function(n){t.observe(n)}))}(n,a)):this.loadAll(r)},destroy:function(){this._observer&&this._observer.disconnect(),Z(this._settings).forEach((function(t){delete t.llOriginalAttrs})),delete this._observer,delete this._settings,delete this.loadingCount,delete this.toLoadCount},loadAll:function(t){var n=this,e=this._settings;nt(t,e).forEach((function(t){K(t,e,n)}))}},et.load=function(t,n){var e=c(n);K(t,e)},et.resetStatus=function(t){_(t)},n&&function(t,n){if(n)if(n.length)for(var e,i=0;e=n[i];i+=1)l(t,e);else l(t,n)}(et,window.lazyLoadOptions),et})); diff --git a/readme.txt b/readme.txt index c36b5bc..8863780 100644 --- a/readme.txt +++ b/readme.txt @@ -2,9 +2,9 @@ Contributors: wp_rocket, wp_media Tags: lazyload, lazy load, images, iframes, thumbnail, thumbnails, smiley, smilies, avatar, gravatar, youtube Requires at least: 4.7 -Tested up to: 5.3 +Tested up to: 5.5 Requires PHP: 5.6 -Stable tag: 2.3.3 +Stable tag: 2.3.4 Lazy Load your images and iframes, replace Youtube videos by a preview thumbnail. @@ -92,6 +92,16 @@ You can also apply it manually. The element you want to apply lazyload on must h The element must have the class `rocket-lazyload`, and a `data-bg` attribute, which value is the CSS url for the image. == Changelog == += 2.3.4 = +Enhancement: Allow `` tags to lazyload background images +Enhancement: Add