UNPKG

photoswipe

Version:
163 lines (135 loc) 4.64 kB
/** * PhotoSwipe base class that can retrieve data about every slide. * Shared by PhotoSwipe Core and PhotoSwipe Lightbox */ import Eventable from './eventable'; import { getElementsFromOption } from '../util/util.js'; import Content from '../slide/content'; class PhotoSwipeBase extends Eventable { /** * Get total number of slides */ getNumItems() { let numItems; const { dataSource } = this.options; if (!dataSource) { numItems = 0; } else if (dataSource.length) { // may be an array or just object with length property numItems = dataSource.length; } else if (dataSource.gallery) { // query DOM elements if (!dataSource.items) { dataSource.items = this._getGalleryDOMElements(dataSource.gallery); } if (dataSource.items) { numItems = dataSource.items.length; } } // legacy event, before filters were introduced const event = this.dispatch('numItems', { dataSource, numItems }); return this.applyFilters('numItems', event.numItems, dataSource); } createContentFromData(slideData, index) { return new Content(slideData, this, index); } /** * Get item data by index. * * "item data" should contain normalized information that PhotoSwipe needs to generate a slide. * For example, it may contain properties like * `src`, `srcset`, `w`, `h`, which will be used to generate a slide with image. * * @param {Integer} index */ getItemData(index) { const { dataSource } = this.options; let dataSourceItem; if (Array.isArray(dataSource)) { // Datasource is an array of elements dataSourceItem = dataSource[index]; } else if (dataSource && dataSource.gallery) { // dataSource has gallery property, // thus it was created by Lightbox, based on // gallerySelecor and childSelector options // query DOM elements if (!dataSource.items) { dataSource.items = this._getGalleryDOMElements(dataSource.gallery); } dataSourceItem = dataSource.items[index]; } let itemData = dataSourceItem; if (itemData instanceof Element) { itemData = this._domElementToItemData(itemData); } // Dispatching the itemData event, // it's a legacy verion before filters were introduced const event = this.dispatch('itemData', { itemData: itemData || {}, index }); return this.applyFilters('itemData', event.itemData, index); } /** * Get array of gallery DOM elements, * based on childSelector and gallery element. * * @param {Element} galleryElement */ _getGalleryDOMElements(galleryElement) { if (this.options.children || this.options.childSelector) { return getElementsFromOption( this.options.children, this.options.childSelector, galleryElement ) || []; } return [galleryElement]; } /** * Converts DOM element to item data object. * * @param {Element} element DOM element */ // eslint-disable-next-line class-methods-use-this _domElementToItemData(element) { const itemData = { element }; const linkEl = element.tagName === 'A' ? element : element.querySelector('a'); if (linkEl) { // src comes from data-pswp-src attribute, // if it's empty link href is used itemData.src = linkEl.dataset.pswpSrc || linkEl.href; if (linkEl.dataset.pswpSrcset) { itemData.srcset = linkEl.dataset.pswpSrcset; } itemData.width = parseInt(linkEl.dataset.pswpWidth, 10); itemData.height = parseInt(linkEl.dataset.pswpHeight, 10); // support legacy w & h properties itemData.w = itemData.width; itemData.h = itemData.height; if (linkEl.dataset.pswpType) { itemData.type = linkEl.dataset.pswpType; } const thumbnailEl = element.querySelector('img'); if (thumbnailEl) { // msrc is URL to placeholder image that's displayed before large image is loaded // by default it's displayed only for the first slide itemData.msrc = thumbnailEl.currentSrc || thumbnailEl.src; itemData.alt = thumbnailEl.getAttribute('alt'); } if (linkEl.dataset.pswpCropped || linkEl.dataset.cropped) { itemData.thumbCropped = true; } } this.applyFilters('domItemData', itemData, element, linkEl); return itemData; } } export default PhotoSwipeBase;