%PDF- %PDF-
Direktori : /home1/lightco1/www/media/sigplus/js/ |
Current File : //home1/lightco1/www/media/sigplus/js/progressive.js |
/**@license sigplus progressive gallery * @author Levente Hunyadi * @version 1.5.0 * @remarks Copyright (C) 2011-2018 Levente Hunyadi * @remarks Licensed under GNU/GPLv3, see http://www.gnu.org/licenses/gpl-3.0.html * @see http://hunyadi.info.hu/projects/sigplus **/ /*{"compilation_level":"ADVANCED_OPTIMIZATIONS"}*/ 'use strict'; /** * Options for the progressive gallery. * Unrecognized options set via the loosely-typed parameter object are silently ignored. * The object has the following properties: * + limit: The number of images to reveal on clicking "Show more...". * + show_more: The localized label of the "Show more..." button/link. * + no_more: The localized label shown when there are no additional items to display. * * @typedef {{ * limit: number, * show_more: string, * no_more: string * }} */ let ProgressiveGalleryOptions; /** @type {!ProgressiveGalleryOptions} */ const progressiveDefaults = { 'limit': 20, 'show_more': 'Show next {$next} of {$left} remaining...', 'no_more': 'No more items to show' }; /** * A gallery that unveils progressively as the user scrolls to the bottom and clicks a "Show more..." link. * @constructor * @param {HTMLElement} gallery * @param {Object=} opts */ function ProgressiveGallery(gallery, opts) { /** * Sets all undefined properties on an object using a reference object. * @param {Object|null|undefined} obj * @param {!Object} ref * @return {!Object} */ function applyDefaults(obj, ref) { /** @type {!Object} */ let extended = obj || {}; for (const prop in /** @type {!Object} */ (JSON.parse(JSON.stringify(ref)))) { // use JSON functions to clone object extended[prop] = /** @type {*} */ (extended[prop]) || /** @type {*} */ (ref[prop]); } return extended; } /** * @param {!Element} elem * @param {!Array<string>} attributes */ function moveAttributesToDataset(elem, attributes) { attributes.forEach(function (name) { if (elem.hasAttribute(name)) { let dataname = 'data-' + name; let value = elem.getAttribute(name); elem.setAttribute(dataname, value); elem.removeAttribute(name); } }); } /** * @param {!Element} elem * @param {!Array<string>} attributes */ function moveAttributesFromDataset(elem, attributes) { attributes.forEach(function (name) { let dataname = 'data-' + name; if (elem.hasAttribute(dataname)) { let value = elem.getAttribute(dataname); elem.setAttribute(name, value); elem.removeAttribute(dataname); } }); } /** * @param {!Array<!HTMLImageElement>} images * @param {function()} callback */ function loadImages(images, callback) { let count = images.length; if (count < 1) { callback(); return; } function imageEventListener() { --count; // check if there are further images waiting to load if (count == 0) { callback(); } } images.forEach(function (image) { image.addEventListener('load', imageEventListener); image.addEventListener('error', imageEventListener); // re-apply previously cleared native image attributes by reading data attributes moveAttributesFromDataset(image, ['src','srcset','sizes']); }); } /** * @param {!HTMLElement} elem * @param {string} text * @param {number} next * @param {number} left */ function updateShowMoreLabel(elem, text, next, left) { elem.text = text.replace('{$next}', '' + Math.min(next, left)).replace('{$left}', '' + left); } /** @type {!ProgressiveGalleryOptions} */ let options = /** @type {!ProgressiveGalleryOptions} */ (applyDefaults(opts, progressiveDefaults)); let limit = options['limit']; let label = options['show_more']; if (gallery) { let items = gallery.querySelectorAll('li'); if (items.length > limit) { gallery.classList.add('sigplus-progressive'); // "Show more..." anchor let anchor = /** @type {HTMLAnchorElement} */ (document.createElement('a')); anchor.href = '#'; anchor.classList.add('sigplus-more'); updateShowMoreLabel(anchor, label, limit, items.length - limit); gallery.appendChild(anchor); // delay fetching image data for hidden elements for (let i = limit; i < items.length; ++i) { items[i].classList.add('sigplus-hidden'); [].forEach.call(/** @type {!IArrayLike<!HTMLImageElement>} */ (items[i].querySelectorAll('img')), function (/** @type {!HTMLImageElement} */ image) { moveAttributesToDataset(image, ['src','srcset','sizes']); }); } // unveil elements upon request anchor.addEventListener('click', function (evt) { evt.preventDefault(); // find elements still hidden let hiddenItems = gallery.querySelectorAll('li.sigplus-hidden'); // find images wrapped in hidden elements let images = []; for (let i = 0; i < limit && i < hiddenItems.length; ++i) { [].forEach.call(/** @type {!IArrayLike<!HTMLImageElement>} */ (hiddenItems[i].querySelectorAll('img')), function (/** @type {!HTMLImageElement} */ image) { images.push(image); }); } loadImages(images, function () { // show some (but not all) hidden elements let i = 0; for (; i < limit && i < hiddenItems.length; ++i) { hiddenItems[i].classList.remove('sigplus-hidden'); } if (i < hiddenItems.length) { updateShowMoreLabel(anchor, label, limit, hiddenItems.length - i); } else { // all images are already visible anchor.classList.add('sigplus-final'); anchor.text = options['no_more']; } }); }); } } } window['ProgressiveGallery'] = ProgressiveGallery;