From 343989f6108bd1b77295175c15669296d64b5b57 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 11 Apr 2020 22:51:11 +0200 Subject: [PATCH 01/18] Add unloading capability to the image loader --- src/components/images/imageFetcher.js | 29 ++- src/components/images/imageLoader.js | 38 ++-- .../lazyloader-intersectionobserver.js | 43 +--- .../lazyloader/lazyloader-scroll.js | 185 ------------------ src/controllers/movies/moviegenres.js | 3 +- src/controllers/shows/tvgenres.js | 3 +- src/scripts/site.js | 7 +- 7 files changed, 49 insertions(+), 259 deletions(-) delete mode 100644 src/components/lazyloader/lazyloader-scroll.js diff --git a/src/components/images/imageFetcher.js b/src/components/images/imageFetcher.js index 1e13cebc77..c7deadc1bd 100644 --- a/src/components/images/imageFetcher.js +++ b/src/components/images/imageFetcher.js @@ -2,28 +2,36 @@ define(['dom'], function (dom) { 'use strict'; function loadImage(elem, url) { - if (!elem) { return Promise.reject('elem cannot be null'); } if (elem.tagName !== "IMG") { - elem.style.backgroundImage = "url('" + url + "')"; return Promise.resolve(); - - //return loadImageIntoImg(document.createElement('img'), url).then(function () { - // elem.style.backgroundImage = "url('" + url + "')"; - // return Promise.resolve(); - //}); - } return loadImageIntoImg(elem, url); } + function unloadImage(elem) { + if (!elem) { + return Promise.reject('elem cannot be null'); + } + + var url; + if (elem.tagName !== "IMG") { + url = elem.style.backgroundImage.slice(4, -1).replace(/"/g, ""); + elem.style.backgroundImage = 'none'; + } else { + url = elem.getAttribute("src"); + elem.setAttribute("src", ""); + } + + return Promise.resolve(url); + } + function loadImageIntoImg(elem, url) { return new Promise(function (resolve, reject) { - dom.addEventListener(elem, 'load', resolve, { once: true }); @@ -32,7 +40,8 @@ define(['dom'], function (dom) { } return { - loadImage: loadImage + loadImage: loadImage, + unloadImage: unloadImage }; }); diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 28b6923c33..8e2bcedf82 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -3,40 +3,36 @@ define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings', var self = {}; - function fillImage(elem, source, enableEffects) { - - if (!elem) { - throw new Error('elem cannot be null'); + function fillImage(entry) { + if (!entry) { + throw new Error('entry cannot be null'); } - if (!source) { - source = elem.getAttribute('data-src'); - } + var source = entry.target.getAttribute('data-src'); - if (!source) { - return; + if (entry.intersectionRatio > 0 && source) { + fillImageElement(entry.target, source); + } else if (!source) { + emptyImageElement(entry.target); } - - fillImageElement(elem, source, enableEffects); } - function fillImageElement(elem, source, enableEffects) { + function fillImageElement(elem, source) { imageFetcher.loadImage(elem, source).then(function () { - - if (enableEffects !== false) { - fadeIn(elem); + if (userSettings.enableFastFadein()) { + elem.classList.add('lazy-image-fadein-fast'); + } else { + elem.classList.add('lazy-image-fadein'); } elem.removeAttribute("data-src"); }); } - function fadeIn(elem) { - if (userSettings.enableFastFadein()) { - elem.classList.add('lazy-image-fadein-fast'); - } else { - elem.classList.add('lazy-image-fadein'); - } + function emptyImageElement(elem) { + imageFetcher.unloadImage(elem).then(function (url) { + elem.setAttribute("data-src", url); + }); } function lazyChildren(elem) { diff --git a/src/components/lazyloader/lazyloader-intersectionobserver.js b/src/components/lazyloader/lazyloader-intersectionobserver.js index 5f83742601..377e3d0cff 100644 --- a/src/components/lazyloader/lazyloader-intersectionobserver.js +++ b/src/components/lazyloader/lazyloader-intersectionobserver.js @@ -11,42 +11,15 @@ define(['require', 'browser'], function (require, browser) { } LazyLoader.prototype.createObserver = function () { + var callback = this.options.callback; - var observerOptions = {}; - var options = this.options; - var loadedCount = 0; - var callback = options.callback; - - observerOptions.rootMargin = "50%"; - - var observerId = 'obs' + new Date().getTime(); - - var self = this; - var observer = new IntersectionObserver(function (entries) { - for (var j = 0, length2 = entries.length; j < length2; j++) { - var entry = entries[j]; - - if (entry.intersectionRatio > 0) { - - // Stop watching and load the image - var target = entry.target; - - observer.unobserve(target); - - if (!target[observerId]) { - target[observerId] = 1; - callback(target); - loadedCount++; - - if (loadedCount >= self.elementCount) { - self.destroyObserver(); - } - } - } - } - }, - observerOptions - ); + var observer = new IntersectionObserver( + (entries, observer) => { + entries.forEach(entry => { + callback(entry); + }, + {rootMargin: "50%"}); + }); this.observer = observer; }; diff --git a/src/components/lazyloader/lazyloader-scroll.js b/src/components/lazyloader/lazyloader-scroll.js deleted file mode 100644 index 4930f6376c..0000000000 --- a/src/components/lazyloader/lazyloader-scroll.js +++ /dev/null @@ -1,185 +0,0 @@ -define(['visibleinviewport', 'dom', 'browser'], function (visibleinviewport, dom, browser) { - 'use strict'; - - var thresholdX; - var thresholdY; - - function resetThresholds() { - - var threshold = 0.3; - - thresholdX = screen.availWidth * threshold; - thresholdY = screen.availHeight * threshold; - } - - function resetThresholdsOnTimer() { - - setTimeout(resetThresholds, 500); - } - - if (browser.iOS) { - dom.addEventListener(window, "orientationchange", resetThresholdsOnTimer, { passive: true }); - dom.addEventListener(window, 'resize', resetThresholdsOnTimer, { passive: true }); - } else { - dom.addEventListener(window, "orientationchange", resetThresholds, { passive: true }); - dom.addEventListener(window, 'resize', resetThresholds, { passive: true }); - } - resetThresholds(); - - function isVisible(elem) { - return visibleinviewport(elem, true, thresholdX, thresholdY); - } - - var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel' : 'mousewheel'); - var self = {}; - - function cancelAll(tokens) { - for (var i = 0, length = tokens.length; i < length; i++) { - - tokens[i] = true; - } - } - - function unveilElementsInternal(instance, callback) { - - var unveiledElements = []; - var cancellationTokens = []; - var loadedCount = 0; - - function unveilInternal(tokenIndex) { - - var anyFound = false; - var out = false; - - var elements = instance.elements; - // TODO: This out construct assumes left to right, top to bottom - - for (var i = 0, length = elements.length; i < length; i++) { - - if (cancellationTokens[tokenIndex]) { - return; - } - if (unveiledElements[i]) { - continue; - } - var elem = elements[i]; - if (!out && isVisible(elem)) { - anyFound = true; - unveiledElements[i] = true; - callback(elem); - loadedCount++; - } else { - - if (anyFound) { - out = true; - } - } - } - - if (loadedCount >= elements.length) { - dom.removeEventListener(document, 'focus', unveil, { - capture: true, - passive: true - }); - dom.removeEventListener(document, 'scroll', unveil, { - capture: true, - passive: true - }); - dom.removeEventListener(document, wheelEvent, unveil, { - capture: true, - passive: true - }); - dom.removeEventListener(window, 'resize', unveil, { - capture: true, - passive: true - }); - } - } - - function unveil() { - - cancelAll(cancellationTokens); - - var index = cancellationTokens.length; - cancellationTokens.length++; - - setTimeout(function () { - unveilInternal(index); - }, 1); - } - - dom.addEventListener(document, 'focus', unveil, { - capture: true, - passive: true - }); - dom.addEventListener(document, 'scroll', unveil, { - capture: true, - passive: true - }); - dom.addEventListener(document, wheelEvent, unveil, { - capture: true, - passive: true - }); - dom.addEventListener(window, 'resize', unveil, { - capture: true, - passive: true - }); - - unveil(); - } - - function LazyLoader(options) { - - this.options = options; - } - - LazyLoader.prototype.createObserver = function () { - - unveilElementsInternal(this, this.options.callback); - this.observer = 1; - }; - - LazyLoader.prototype.addElements = function (elements) { - - this.elements = this.elements || []; - - for (var i = 0, length = elements.length; i < length; i++) { - this.elements.push(elements[i]); - } - - var observer = this.observer; - - if (!observer) { - this.createObserver(); - } - - }; - - LazyLoader.prototype.destroyObserver = function (elements) { - - }; - - LazyLoader.prototype.destroy = function (elements) { - - this.destroyObserver(); - this.options = null; - }; - - function unveilElements(elements, root, callback) { - - if (!elements.length) { - return; - } - var lazyLoader = new LazyLoader({ - callback: callback - }); - lazyLoader.addElements(elements); - } - - LazyLoader.lazyChildren = function (elem, callback) { - - unveilElements(elem.getElementsByClassName('lazy'), elem, callback); - }; - - return LazyLoader; -}); diff --git a/src/controllers/movies/moviegenres.js b/src/controllers/movies/moviegenres.js index bb395f337c..f2c472dace 100644 --- a/src/controllers/movies/moviegenres.js +++ b/src/controllers/movies/moviegenres.js @@ -50,7 +50,8 @@ define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader return enableScrollX() ? "overflowPortrait" : "portrait"; } - function fillItemsContainer(elem) { + function fillItemsContainer(entry) { + var elem = entry.target; var id = elem.getAttribute("data-id"); var viewStyle = self.getCurrentViewStyle(); var limit = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? 5 : 9; diff --git a/src/controllers/shows/tvgenres.js b/src/controllers/shows/tvgenres.js index 9a0823a6b9..aa46fd4361 100644 --- a/src/controllers/shows/tvgenres.js +++ b/src/controllers/shows/tvgenres.js @@ -50,7 +50,8 @@ define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader return enableScrollX() ? "overflowPortrait" : "portrait"; } - function fillItemsContainer(elem) { + function fillItemsContainer(entry) { + var elem = entry.target; var id = elem.getAttribute("data-id"); var viewStyle = self.getCurrentViewStyle(); var limit = "Thumb" == viewStyle || "ThumbCard" == viewStyle ? 5 : 9; diff --git a/src/scripts/site.js b/src/scripts/site.js index 90fa1d849f..8957481242 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -379,12 +379,7 @@ var AppInfo = {}; define("filesystem", [componentsPath + "/filesystem"], returnFirstDependency); - if (window.IntersectionObserver && !browser.edge) { - define("lazyLoader", [componentsPath + "/lazyloader/lazyloader-intersectionobserver"], returnFirstDependency); - } else { - define("lazyLoader", [componentsPath + "/lazyloader/lazyloader-scroll"], returnFirstDependency); - } - + define("lazyLoader", [componentsPath + "/lazyloader/lazyloader-intersectionobserver"], returnFirstDependency); define("shell", [componentsPath + "/shell"], returnFirstDependency); define("apiclient", [bowerPath + "/apiclient/apiclient"], returnFirstDependency); From e97c659dc00df753210de52d97b94824c65bedea Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 12 Apr 2020 00:23:16 +0200 Subject: [PATCH 02/18] Migrate lazyloader-intesctionobserver to ES6 --- package.json | 3 +- src/components/images/imageLoader.js | 1 - src/components/lazyloader/lazyedgehack.css | 5 - .../lazyloader-intersectionobserver.js | 99 +++++++++---------- 4 files changed, 49 insertions(+), 59 deletions(-) delete mode 100644 src/components/lazyloader/lazyedgehack.css diff --git a/package.json b/package.json index 8f42635adc..8de04b3628 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,8 @@ "src/scripts/settings/webSettings.js", "src/scripts/dfnshelper.js", "src/scripts/imagehelper.js", - "src/scripts/inputManager.js" + "src/scripts/inputManager.js", + "src/components/lazyloader/lazyloader-intersectionobserver.js" ], "plugins": [ "@babel/plugin-transform-modules-amd" diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 8e2bcedf82..37b9226f6a 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -36,7 +36,6 @@ define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings', } function lazyChildren(elem) { - lazyLoader.lazyChildren(elem, fillImage); } diff --git a/src/components/lazyloader/lazyedgehack.css b/src/components/lazyloader/lazyedgehack.css deleted file mode 100644 index e358872f16..0000000000 --- a/src/components/lazyloader/lazyedgehack.css +++ /dev/null @@ -1,5 +0,0 @@ -.lazy { - /* In edge, intersection observer will not fire on 0px sized elements */ - min-width: 0.1em; - min-height: 0.1em; -} diff --git a/src/components/lazyloader/lazyloader-intersectionobserver.js b/src/components/lazyloader/lazyloader-intersectionobserver.js index 377e3d0cff..222192f244 100644 --- a/src/components/lazyloader/lazyloader-intersectionobserver.js +++ b/src/components/lazyloader/lazyloader-intersectionobserver.js @@ -1,76 +1,71 @@ -define(['require', 'browser'], function (require, browser) { - 'use strict'; +import require from 'require'; +import browser from 'browser'; +/* eslint-disable indent */ - function LazyLoader(options) { + export class LazyLoader { + constructor(options) { + this.options = options; + this.observer; + } - this.options = options; - } + createObserver() { + const callback = this.options.callback; - if (browser.edge) { - require(['css!./lazyedgehack']); - } + const observer = new IntersectionObserver( + (entries, observer) => { + entries.forEach(entry => { + callback(entry); + }, + {rootMargin: "50%"}); + }); - LazyLoader.prototype.createObserver = function () { - var callback = this.options.callback; + this.observer = observer; + } - var observer = new IntersectionObserver( - (entries, observer) => { - entries.forEach(entry => { - callback(entry); - }, - {rootMargin: "50%"}); + addElements(elements) { + let observer = this.observer; + + if (!observer) { + this.createObserver(); + observer = this.observer; + } + + Array.from(elements).forEach(element => { + observer.observe(element); }); - - this.observer = observer; - }; - - LazyLoader.prototype.addElements = function (elements) { - - var observer = this.observer; - - if (!observer) { - this.createObserver(); - observer = this.observer; } - this.elementCount = (this.elementCount || 0) + elements.length; + destroyObserver(elements) { + const observer = this.observer; - for (var i = 0, length = elements.length; i < length; i++) { - observer.observe(elements[i]); + if (observer) { + observer.disconnect(); + this.observer = null; + } } - }; - LazyLoader.prototype.destroyObserver = function (elements) { - - var observer = this.observer; - - if (observer) { - observer.disconnect(); - this.observer = null; + destroy(elements) { + this.destroyObserver(); + this.options = null; } - }; - - LazyLoader.prototype.destroy = function (elements) { - - this.destroyObserver(); - this.options = null; - }; + } function unveilElements(elements, root, callback) { - if (!elements.length) { return; } - var lazyLoader = new LazyLoader({ + const lazyLoader = new LazyLoader({ callback: callback }); lazyLoader.addElements(elements); } - LazyLoader.lazyChildren = function (elem, callback) { - + export function lazyChildren(elem, callback) { unveilElements(elem.getElementsByClassName('lazy'), elem, callback); - }; + } - return LazyLoader; -}); +/* eslint-enable indent */ +export default { + LazyLoader: LazyLoader, + lazyChildren: lazyChildren +}; From 17784043547d04009ce795ff0f926176def51ab3 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 12 Apr 2020 00:29:33 +0200 Subject: [PATCH 03/18] Fix bug and code smells --- src/components/lazyloader/lazyloader-intersectionobserver.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/lazyloader/lazyloader-intersectionobserver.js b/src/components/lazyloader/lazyloader-intersectionobserver.js index 222192f244..d39bddf6ac 100644 --- a/src/components/lazyloader/lazyloader-intersectionobserver.js +++ b/src/components/lazyloader/lazyloader-intersectionobserver.js @@ -1,11 +1,7 @@ -import require from 'require'; -import browser from 'browser'; /* eslint-disable indent */ - export class LazyLoader { constructor(options) { this.options = options; - this.observer; } createObserver() { From fc6a11bb4bac7ed28ef70a57fc837c85ea60c22a Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 12 Apr 2020 03:49:42 +0200 Subject: [PATCH 04/18] Refactor the lazy loader for images --- src/components/images/imageFetcher.js | 47 --------------------------- src/components/images/imageLoader.js | 36 ++++++++++++++++---- src/components/images/style.css | 39 +++++----------------- src/scripts/site.js | 4 --- 4 files changed, 39 insertions(+), 87 deletions(-) delete mode 100644 src/components/images/imageFetcher.js diff --git a/src/components/images/imageFetcher.js b/src/components/images/imageFetcher.js deleted file mode 100644 index c7deadc1bd..0000000000 --- a/src/components/images/imageFetcher.js +++ /dev/null @@ -1,47 +0,0 @@ -define(['dom'], function (dom) { - 'use strict'; - - function loadImage(elem, url) { - if (!elem) { - return Promise.reject('elem cannot be null'); - } - - if (elem.tagName !== "IMG") { - elem.style.backgroundImage = "url('" + url + "')"; - return Promise.resolve(); - } - return loadImageIntoImg(elem, url); - } - - function unloadImage(elem) { - if (!elem) { - return Promise.reject('elem cannot be null'); - } - - var url; - if (elem.tagName !== "IMG") { - url = elem.style.backgroundImage.slice(4, -1).replace(/"/g, ""); - elem.style.backgroundImage = 'none'; - } else { - url = elem.getAttribute("src"); - elem.setAttribute("src", ""); - } - - return Promise.resolve(url); - } - - function loadImageIntoImg(elem, url) { - return new Promise(function (resolve, reject) { - dom.addEventListener(elem, 'load', resolve, { - once: true - }); - elem.setAttribute("src", url); - }); - } - - return { - loadImage: loadImage, - unloadImage: unloadImage - }; - -}); diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 37b9226f6a..4d6a45d2d4 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -1,4 +1,4 @@ -define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings', 'userSettings', 'require', 'css!./style'], function (lazyLoader, imageFetcher, layoutManager, browser, appSettings, userSettings, require) { +define(['lazyLoader', 'userSettings', 'css!./style'], function (lazyLoader, userSettings) { 'use strict'; var self = {}; @@ -17,8 +17,17 @@ define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings', } } - function fillImageElement(elem, source) { - imageFetcher.loadImage(elem, source).then(function () { + function fillImageElement(elem, url) { + let preloaderImg = new Image(); + preloaderImg.src = url; + + preloaderImg.addEventListener('load', (event) => { + if (elem.tagName !== "IMG") { + elem.style.backgroundImage = "url('" + url + "')"; + } else { + elem.setAttribute("src", url); + } + if (userSettings.enableFastFadein()) { elem.classList.add('lazy-image-fadein-fast'); } else { @@ -26,13 +35,28 @@ define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings', } elem.removeAttribute("data-src"); + preloaderImg = null; }); } function emptyImageElement(elem) { - imageFetcher.unloadImage(elem).then(function (url) { - elem.setAttribute("data-src", url); - }); + var url; + + if (elem.tagName !== "IMG") { + url = elem.style.backgroundImage.slice(4, -1).replace(/"/g, ""); + elem.style.backgroundImage = 'none'; + } else { + url = elem.getAttribute("src"); + elem.setAttribute("src", ""); + } + + elem.setAttribute("data-src", url); + + if (userSettings.enableFastFadein()) { + elem.classList.remove('lazy-image-fadein-fast'); + } else { + elem.classList.remove('lazy-image-fadein'); + } } function lazyChildren(elem) { diff --git a/src/components/images/style.css b/src/components/images/style.css index 2836dd0159..ef60f8b837 100644 --- a/src/components/images/style.css +++ b/src/components/images/style.css @@ -1,26 +1,15 @@ -.lazy-image-fadein { +.cardImageContainer.lazy { opacity: 0; - animation: lazy-image-fadein 330ms ease-in normal both; - -webkit-animation-duration: 0.8s; - -moz-animation-duration: 0.8s; - -o-animation-duration: 0.8s; - animation-duration: 0.8s; - -webkit-animation-name: popInAnimation; - -moz-animation-name: popInAnimation; - -o-animation-name: popInAnimation; - animation-name: popInAnimation; - -webkit-animation-fill-mode: forwards; - -moz-animation-fill-mode: forwards; - -o-animation-fill-mode: forwards; - animation-fill-mode: forwards; - -webkit-animation-timing-function: cubic-bezier(0, 0, 0.5, 1); - -moz-animation-timing-function: cubic-bezier(0, 0, 0.5, 1); - -o-animation-timing-function: cubic-bezier(0, 0, 0.5, 1); - animation-timing-function: cubic-bezier(0, 0, 0.5, 1); } -.lazy-image-fadein-fast { - animation: lazy-image-fadein 160ms ease-in normal both; +.cardImageContainer.lazy.lazy-image-fadein { + opacity: 1; + transition: opacity 1s; +} + +.cardImageContainer.lazy.lazy-image-fadein-fast { + opacity: 1; + transition: opacity 0.5s; } @keyframes lazy-image-fadein { @@ -32,13 +21,3 @@ opacity: 1; } } - -@keyframes popInAnimation { - 0% { - opacity: 0; - } - - 100% { - opacity: 1; - } -} diff --git a/src/scripts/site.js b/src/scripts/site.js index 8957481242..df1c0f33d1 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -392,10 +392,6 @@ var AppInfo = {}; define("registerElement", ["document-register-element"], returnFirstDependency); } - define("imageFetcher", [componentsPath + "/images/imageFetcher"], returnFirstDependency); - - var preferNativeAlerts = browser.tv; - define("alert", [componentsPath + "/alert"], returnFirstDependency); defineResizeObserver(); From 03b614266ea1ea8b1084b35981e745978342a5d8 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 12 Apr 2020 03:54:09 +0200 Subject: [PATCH 05/18] Remove superfluous observer instance in lazyloader --- src/components/lazyloader/lazyloader-intersectionobserver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/lazyloader/lazyloader-intersectionobserver.js b/src/components/lazyloader/lazyloader-intersectionobserver.js index d39bddf6ac..4282587902 100644 --- a/src/components/lazyloader/lazyloader-intersectionobserver.js +++ b/src/components/lazyloader/lazyloader-intersectionobserver.js @@ -8,7 +8,7 @@ const callback = this.options.callback; const observer = new IntersectionObserver( - (entries, observer) => { + (entries) => { entries.forEach(entry => { callback(entry); }, From a802079ba3e10bf312be640430b17bddc802e6ed Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 12 Apr 2020 05:47:19 +0200 Subject: [PATCH 06/18] Add default export to userSettings --- src/scripts/settings/userSettings.js | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/scripts/settings/userSettings.js b/src/scripts/settings/userSettings.js index 6f115eeffa..d757dd8081 100644 --- a/src/scripts/settings/userSettings.js +++ b/src/scripts/settings/userSettings.js @@ -265,3 +265,33 @@ import events from 'events'; } /* eslint-enable indent */ +export default { + setUserInfo: setUserInfo, + getData: getData, + importFrom: importFrom, + set: set, + get: get, + serverConfig: serverConfig, + enableCinemaMode: enableCinemaMode, + enableNextVideoInfoOverlay: enableNextVideoInfoOverlay, + enableThemeSongs: enableThemeSongs, + enableThemeVideos: enableThemeVideos, + enableFastFadein: enableFastFadein, + enableBackdrops: enableBackdrops, + language: language, + dateTimeLocale: dateTimeLocale, + skipBackLength: skipBackLength, + skipForwardLength: skipForwardLength, + dashboardTheme: dashboardTheme, + skin: skin, + theme: theme, + screensaver: screensaver, + libraryPageSize: libraryPageSize, + soundEffects: soundEffects, + loadQuerySettings: loadQuerySettings, + saveQuerySettings: saveQuerySettings, + getSubtitleAppearanceSettings: getSubtitleAppearanceSettings, + setSubtitleAppearanceSettings: setSubtitleAppearanceSettings, + setFilter: setFilter, + getFilter: getFilter +}; From ac9668f9bb188830ca6fac5c411fd7328b3f8c92 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 12 Apr 2020 05:47:41 +0200 Subject: [PATCH 07/18] Migrate imageLoader to ES6 --- package.json | 3 ++- src/components/images/imageLoader.js | 30 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 8de04b3628..e33b447f82 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,8 @@ "src/scripts/dfnshelper.js", "src/scripts/imagehelper.js", "src/scripts/inputManager.js", - "src/components/lazyloader/lazyloader-intersectionobserver.js" + "src/components/lazyloader/lazyloader-intersectionobserver.js", + "src/components/images/imageLoader.js" ], "plugins": [ "@babel/plugin-transform-modules-amd" diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 4d6a45d2d4..fda6e54668 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -1,9 +1,9 @@ -define(['lazyLoader', 'userSettings', 'css!./style'], function (lazyLoader, userSettings) { - 'use strict'; +import lazyLoader from 'lazyLoader'; +import userSettings from 'userSettings'; +import 'css!./style'; +/* eslint-disable indent */ - var self = {}; - - function fillImage(entry) { + export function fillImage(entry) { if (!entry) { throw new Error('entry cannot be null'); } @@ -59,11 +59,11 @@ define(['lazyLoader', 'userSettings', 'css!./style'], function (lazyLoader, user } } - function lazyChildren(elem) { + export function lazyChildren(elem) { lazyLoader.lazyChildren(elem, fillImage); } - function getPrimaryImageAspectRatio(items) { + export function getPrimaryImageAspectRatio(items) { var values = []; @@ -123,7 +123,7 @@ define(['lazyLoader', 'userSettings', 'css!./style'], function (lazyLoader, user return result; } - function fillImages(elems) { + export function fillImages(elems) { for (var i = 0, length = elems.length; i < length; i++) { var elem = elems[0]; @@ -131,10 +131,10 @@ define(['lazyLoader', 'userSettings', 'css!./style'], function (lazyLoader, user } } - self.fillImages = fillImages; - self.lazyImage = fillImage; - self.lazyChildren = lazyChildren; - self.getPrimaryImageAspectRatio = getPrimaryImageAspectRatio; - - return self; -}); +/* eslint-enable indent */ +export default { + fillImages: fillImages, + lazyImage: fillImage, + lazyChildren: lazyChildren, + getPrimaryImageAspectRatio: getPrimaryImageAspectRatio +}; From 6dde11349acfae90a1c1ebffa637ed1227f19f5f Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 12 Apr 2020 14:25:12 +0200 Subject: [PATCH 08/18] Fix image loading on details pages --- src/components/images/imageLoader.js | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index fda6e54668..80bb24bcfe 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -3,12 +3,33 @@ import userSettings from 'userSettings'; import 'css!./style'; /* eslint-disable indent */ + export function lazyImage(elem, source, enableEffects) { + + if (!elem) { + throw new Error('elem cannot be null'); + } + + if (!source) { + source = elem.getAttribute('data-src'); + } + + if (!source) { + return; + } + + fillImageElement(elem, source, enableEffects); + } + export function fillImage(entry) { if (!entry) { throw new Error('entry cannot be null'); } - var source = entry.target.getAttribute('data-src'); + if (entry.target) { + var source = entry.target.getAttribute('data-src'); + } else { + var source = entry; + } if (entry.intersectionRatio > 0 && source) { fillImageElement(entry.target, source); @@ -21,7 +42,7 @@ import 'css!./style'; let preloaderImg = new Image(); preloaderImg.src = url; - preloaderImg.addEventListener('load', (event) => { + preloaderImg.addEventListener('load', () => { if (elem.tagName !== "IMG") { elem.style.backgroundImage = "url('" + url + "')"; } else { @@ -134,7 +155,8 @@ import 'css!./style'; /* eslint-enable indent */ export default { fillImages: fillImages, - lazyImage: fillImage, + fillImage: fillImage, + lazyImage: lazyImage, lazyChildren: lazyChildren, getPrimaryImageAspectRatio: getPrimaryImageAspectRatio }; From 58d9037986cb07df54408b60f9927551fa4eca44 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 12 Apr 2020 14:29:42 +0200 Subject: [PATCH 09/18] Remove useless parameter in lazyImage --- src/components/images/imageLoader.js | 9 ++------- src/controllers/itemdetailpage.js | 10 +++++----- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 80bb24bcfe..2166d6ccff 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -3,21 +3,16 @@ import userSettings from 'userSettings'; import 'css!./style'; /* eslint-disable indent */ - export function lazyImage(elem, source, enableEffects) { - + export function lazyImage(elem, source = elem.getAttribute('data-src')) { if (!elem) { throw new Error('elem cannot be null'); } - if (!source) { - source = elem.getAttribute('data-src'); - } - if (!source) { return; } - fillImageElement(elem, source, enableEffects); + fillImageElement(elem, source); } export function fillImage(entry) { diff --git a/src/controllers/itemdetailpage.js b/src/controllers/itemdetailpage.js index 178419e284..81314ce7c1 100644 --- a/src/controllers/itemdetailpage.js +++ b/src/controllers/itemdetailpage.js @@ -473,7 +473,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti tag: item.ImageTags.Thumb }); page.classList.remove("noBackdrop"); - imageLoader.lazyImage(itemBackdropElement, imgUrl, false); + imageLoader.lazyImage(itemBackdropElement, imgUrl); hasbackdrop = true; } else if (usePrimaryImage && item.ImageTags && item.ImageTags.Primary) { imgUrl = apiClient.getScaledImageUrl(item.Id, { @@ -483,7 +483,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti tag: item.ImageTags.Primary }); page.classList.remove("noBackdrop"); - imageLoader.lazyImage(itemBackdropElement, imgUrl, false); + imageLoader.lazyImage(itemBackdropElement, imgUrl); hasbackdrop = true; } else if (item.BackdropImageTags && item.BackdropImageTags.length) { imgUrl = apiClient.getScaledImageUrl(item.Id, { @@ -493,7 +493,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti tag: item.BackdropImageTags[0] }); page.classList.remove("noBackdrop"); - imageLoader.lazyImage(itemBackdropElement, imgUrl, false); + imageLoader.lazyImage(itemBackdropElement, imgUrl); hasbackdrop = true; } else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) { imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, { @@ -503,7 +503,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti tag: item.ParentBackdropImageTags[0] }); page.classList.remove("noBackdrop"); - imageLoader.lazyImage(itemBackdropElement, imgUrl, false); + imageLoader.lazyImage(itemBackdropElement, imgUrl); hasbackdrop = true; } else if (item.ImageTags && item.ImageTags.Thumb) { imgUrl = apiClient.getScaledImageUrl(item.Id, { @@ -513,7 +513,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti tag: item.ImageTags.Thumb }); page.classList.remove("noBackdrop"); - imageLoader.lazyImage(itemBackdropElement, imgUrl, false); + imageLoader.lazyImage(itemBackdropElement, imgUrl); hasbackdrop = true; } else { itemBackdropElement.style.backgroundImage = ""; From e256e64e68d9348ef7151d9be3a6bea3cc1eff46 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 12 Apr 2020 14:34:51 +0200 Subject: [PATCH 10/18] Handle source properly in fillImage --- src/components/images/imageLoader.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 2166d6ccff..4247f2c0cb 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -20,10 +20,11 @@ import 'css!./style'; throw new Error('entry cannot be null'); } + var source = undefined; if (entry.target) { - var source = entry.target.getAttribute('data-src'); + source = entry.target.getAttribute('data-src'); } else { - var source = entry; + source = entry; } if (entry.intersectionRatio > 0 && source) { @@ -34,6 +35,10 @@ import 'css!./style'; } function fillImageElement(elem, url) { + if (url === undefined) { + throw new Error('url cannot be undefined'); + } + let preloaderImg = new Image(); preloaderImg.src = url; From e0a71938eae6b07f523d0c843efddfba035d1ceb Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Wed, 15 Apr 2020 14:39:44 +0200 Subject: [PATCH 11/18] Adjust animation speed and remove useless arguments --- src/components/images/style.css | 14 ++------------ .../lazyloader/lazyloader-intersectionobserver.js | 4 ++-- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/components/images/style.css b/src/components/images/style.css index ef60f8b837..2b9422d55b 100644 --- a/src/components/images/style.css +++ b/src/components/images/style.css @@ -4,20 +4,10 @@ .cardImageContainer.lazy.lazy-image-fadein { opacity: 1; - transition: opacity 1s; + transition: opacity 0.7s; } .cardImageContainer.lazy.lazy-image-fadein-fast { opacity: 1; - transition: opacity 0.5s; -} - -@keyframes lazy-image-fadein { - from { - opacity: 0; - } - - to { - opacity: 1; - } + transition: opacity 0.2s; } diff --git a/src/components/lazyloader/lazyloader-intersectionobserver.js b/src/components/lazyloader/lazyloader-intersectionobserver.js index 4282587902..68f1b11cbc 100644 --- a/src/components/lazyloader/lazyloader-intersectionobserver.js +++ b/src/components/lazyloader/lazyloader-intersectionobserver.js @@ -31,7 +31,7 @@ }); } - destroyObserver(elements) { + destroyObserver() { const observer = this.observer; if (observer) { @@ -40,7 +40,7 @@ } } - destroy(elements) { + destroy() { this.destroyObserver(); this.options = null; } From 7860deac2382314caf62a0f67b9bf24dcd81dca6 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 25 Apr 2020 20:23:51 +0200 Subject: [PATCH 12/18] Implement suggestions --- package.json | 10 +++++----- src/components/images/imageLoader.js | 11 ++--------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 7d33448d15..7e8969556d 100644 --- a/package.json +++ b/package.json @@ -93,17 +93,17 @@ "src/components/dom.js", "src/components/filedownloader.js", "src/components/filesystem.js", + "src/components/images/imageLoader.js", "src/components/input/keyboardnavigation.js", + "src/components/lazyloader/lazyloader-intersectionobserver.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", - "src/scripts/settings/appSettings.js", - "src/scripts/settings/userSettings.js", - "src/scripts/settings/webSettings.js", "src/scripts/dfnshelper.js", "src/scripts/imagehelper.js", "src/scripts/inputManager.js", - "src/components/lazyloader/lazyloader-intersectionobserver.js", - "src/components/images/imageLoader.js" + "src/scripts/settings/appSettings.js", + "src/scripts/settings/userSettings.js", + "src/scripts/settings/webSettings.js" ], "plugins": [ "@babel/plugin-transform-modules-amd" diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 4247f2c0cb..d610b79938 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -4,10 +4,6 @@ import 'css!./style'; /* eslint-disable indent */ export function lazyImage(elem, source = elem.getAttribute('data-src')) { - if (!elem) { - throw new Error('elem cannot be null'); - } - if (!source) { return; } @@ -73,11 +69,8 @@ import 'css!./style'; elem.setAttribute("data-src", url); - if (userSettings.enableFastFadein()) { - elem.classList.remove('lazy-image-fadein-fast'); - } else { - elem.classList.remove('lazy-image-fadein'); - } + elem.classList.remove('lazy-image-fadein-fast'); + elem.classList.remove('lazy-image-fadein'); } export function lazyChildren(elem) { From b8422a24643c2b460e54d2f38fa02ca68000e939 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 1 May 2020 15:01:56 +0200 Subject: [PATCH 13/18] Fix userSettings import --- src/components/images/imageLoader.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index d610b79938..1254f71167 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -1,5 +1,5 @@ -import lazyLoader from 'lazyLoader'; -import userSettings from 'userSettings'; +import * as lazyLoader from 'lazyLoader'; +import * as userSettings from 'userSettings'; import 'css!./style'; /* eslint-disable indent */ @@ -45,6 +45,7 @@ import 'css!./style'; elem.setAttribute("src", url); } + console.warn(userSettings.enableFastFadein()); if (userSettings.enableFastFadein()) { elem.classList.add('lazy-image-fadein-fast'); } else { From ff7b69e5d64978fa5912e5ca4e472dce1e9b51b9 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 1 May 2020 15:04:09 +0200 Subject: [PATCH 14/18] Remove unused file visibleinviewport.js --- src/libraries/visibleinviewport.js | 41 ------------------------------ src/scripts/site.js | 1 - 2 files changed, 42 deletions(-) delete mode 100644 src/libraries/visibleinviewport.js diff --git a/src/libraries/visibleinviewport.js b/src/libraries/visibleinviewport.js deleted file mode 100644 index a48dbd3a1d..0000000000 --- a/src/libraries/visibleinviewport.js +++ /dev/null @@ -1,41 +0,0 @@ -define(['dom'], function (dom) { - 'use strict'; - - /** - * Copyright 2012, Digital Fusion - * Licensed under the MIT license. - * http://teamdf.com/jquery-plugins/license/ - * - * @author Sam Sehnert - * @desc A small plugin that checks whether elements are within - * the user visible viewport of a web browser. - * only accounts for vertical position, not horizontal. - */ - function visibleInViewport(elem, partial, thresholdX, thresholdY) { - - thresholdX = thresholdX || 0; - thresholdY = thresholdY || 0; - - if (!elem.getBoundingClientRect) { - return true; - } - - var windowSize = dom.getWindowSize(); - - var vpWidth = windowSize.innerWidth; - var vpHeight = windowSize.innerHeight; - - // Use this native browser method, if available. - var rec = elem.getBoundingClientRect(); - var tViz = rec.top >= 0 && rec.top < vpHeight + thresholdY; - var bViz = rec.bottom > 0 && rec.bottom <= vpHeight + thresholdY; - var lViz = rec.left >= 0 && rec.left < vpWidth + thresholdX; - var rViz = rec.right > 0 && rec.right <= vpWidth + thresholdX; - var vVisible = partial ? tViz || bViz : tViz && bViz; - var hVisible = partial ? lViz || rViz : lViz && rViz; - - return vVisible && hVisible; - } - - return visibleInViewport; -}); diff --git a/src/scripts/site.js b/src/scripts/site.js index 5d5062c394..0583c5c676 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -646,7 +646,6 @@ var AppInfo = {}; medialibraryeditor: componentsPath + "/medialibraryeditor/medialibraryeditor", imageoptionseditor: componentsPath + "/imageoptionseditor/imageoptionseditor", apphost: componentsPath + "/apphost", - visibleinviewport: bowerPath + "/visibleinviewport", qualityoptions: componentsPath + "/qualityoptions", focusManager: componentsPath + "/focusManager", itemHelper: componentsPath + "/itemhelper", From 331341884bfc4709ad781e938b45576dcd1b7ec5 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 1 May 2020 15:11:47 +0200 Subject: [PATCH 15/18] Remove console warning --- src/components/images/imageLoader.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 1254f71167..a3114f783c 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -45,7 +45,6 @@ import 'css!./style'; elem.setAttribute("src", url); } - console.warn(userSettings.enableFastFadein()); if (userSettings.enableFastFadein()) { elem.classList.add('lazy-image-fadein-fast'); } else { From a7fe19832934e3a029fe7ce01355a8fba77353b4 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 1 May 2020 17:06:50 +0200 Subject: [PATCH 16/18] Attempt to fix image loading issues --- src/components/images/imageLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index a3114f783c..52c65b85f0 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -23,7 +23,7 @@ import 'css!./style'; source = entry; } - if (entry.intersectionRatio > 0 && source) { + if (entry.intersectionRatio > 0) { fillImageElement(entry.target, source); } else if (!source) { emptyImageElement(entry.target); From 28f575755b18f8db864cdc768a3fe1f5f0b4703d Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 2 May 2020 19:44:27 +0200 Subject: [PATCH 17/18] Add check for source when loading images --- src/components/images/imageLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 52c65b85f0..69ad01b606 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -24,7 +24,7 @@ import 'css!./style'; } if (entry.intersectionRatio > 0) { - fillImageElement(entry.target, source); + if (source) fillImageElement(entry.target, source); } else if (!source) { emptyImageElement(entry.target); } From 1e4dd8ec93a157f5222cb94f202327aa487f3b78 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 7 May 2020 11:02:47 +0200 Subject: [PATCH 18/18] Remove lazyloader-scroll --- .../lazyloader/lazyloader-scroll.js | 185 ------------------ 1 file changed, 185 deletions(-) delete mode 100644 src/components/lazyloader/lazyloader-scroll.js diff --git a/src/components/lazyloader/lazyloader-scroll.js b/src/components/lazyloader/lazyloader-scroll.js deleted file mode 100644 index 2704c0f7be..0000000000 --- a/src/components/lazyloader/lazyloader-scroll.js +++ /dev/null @@ -1,185 +0,0 @@ -define(['visibleinviewport', 'dom', 'browser'], function (visibleinviewport, dom, browser) { - 'use strict'; - - var thresholdX; - var thresholdY; - - function resetThresholds() { - - var threshold = 0.3; - - thresholdX = screen.availWidth * threshold; - thresholdY = screen.availHeight * threshold; - } - - function resetThresholdsOnTimer() { - - setTimeout(resetThresholds, 500); - } - - if (browser.iOS) { - dom.addEventListener(window, 'orientationchange', resetThresholdsOnTimer, { passive: true }); - dom.addEventListener(window, 'resize', resetThresholdsOnTimer, { passive: true }); - } else { - dom.addEventListener(window, 'orientationchange', resetThresholds, { passive: true }); - dom.addEventListener(window, 'resize', resetThresholds, { passive: true }); - } - resetThresholds(); - - function isVisible(elem) { - return visibleinviewport(elem, true, thresholdX, thresholdY); - } - - var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel' : 'mousewheel'); - var self = {}; - - function cancelAll(tokens) { - for (var i = 0, length = tokens.length; i < length; i++) { - - tokens[i] = true; - } - } - - function unveilElementsInternal(instance, callback) { - - var unveiledElements = []; - var cancellationTokens = []; - var loadedCount = 0; - - function unveilInternal(tokenIndex) { - - var anyFound = false; - var out = false; - - var elements = instance.elements; - // TODO: This out construct assumes left to right, top to bottom - - for (var i = 0, length = elements.length; i < length; i++) { - - if (cancellationTokens[tokenIndex]) { - return; - } - if (unveiledElements[i]) { - continue; - } - var elem = elements[i]; - if (!out && isVisible(elem)) { - anyFound = true; - unveiledElements[i] = true; - callback(elem); - loadedCount++; - } else { - - if (anyFound) { - out = true; - } - } - } - - if (loadedCount >= elements.length) { - dom.removeEventListener(document, 'focus', unveil, { - capture: true, - passive: true - }); - dom.removeEventListener(document, 'scroll', unveil, { - capture: true, - passive: true - }); - dom.removeEventListener(document, wheelEvent, unveil, { - capture: true, - passive: true - }); - dom.removeEventListener(window, 'resize', unveil, { - capture: true, - passive: true - }); - } - } - - function unveil() { - - cancelAll(cancellationTokens); - - var index = cancellationTokens.length; - cancellationTokens.length++; - - setTimeout(function () { - unveilInternal(index); - }, 1); - } - - dom.addEventListener(document, 'focus', unveil, { - capture: true, - passive: true - }); - dom.addEventListener(document, 'scroll', unveil, { - capture: true, - passive: true - }); - dom.addEventListener(document, wheelEvent, unveil, { - capture: true, - passive: true - }); - dom.addEventListener(window, 'resize', unveil, { - capture: true, - passive: true - }); - - unveil(); - } - - function LazyLoader(options) { - - this.options = options; - } - - LazyLoader.prototype.createObserver = function () { - - unveilElementsInternal(this, this.options.callback); - this.observer = 1; - }; - - LazyLoader.prototype.addElements = function (elements) { - - this.elements = this.elements || []; - - for (var i = 0, length = elements.length; i < length; i++) { - this.elements.push(elements[i]); - } - - var observer = this.observer; - - if (!observer) { - this.createObserver(); - } - - }; - - LazyLoader.prototype.destroyObserver = function (elements) { - - }; - - LazyLoader.prototype.destroy = function (elements) { - - this.destroyObserver(); - this.options = null; - }; - - function unveilElements(elements, root, callback) { - - if (!elements.length) { - return; - } - var lazyLoader = new LazyLoader({ - callback: callback - }); - lazyLoader.addElements(elements); - } - - LazyLoader.lazyChildren = function (elem, callback) { - - unveilElements(elem.getElementsByClassName('lazy'), elem, callback); - }; - - return LazyLoader; -});