PageSourceSearch

https://chatsworthcouncil.org/wp-content/plugins/breakdance/subplu…/lightbox.js?bd_ver=2.8.3

js chatsworthcouncil.org collected 2026-10-02 07:51:27 UTC 9,690 bytes, 329 lines download raw bytes

1/* global lightGallery, lgAutoplay, lgFullscreen, lgZoom, lgVideo, lgThumbnail */
2(function () {
3  const { mergeObjects, toArray } = BreakdanceFrontend.utils;
4
5  class BreakdanceLightbox {
6    defaultOptions = {
7      type: "default",
8      items: [],
9      itemSelector: ".ee-gallery-item",
10      autoplay: false,
11      speed: { number: 3000 },
12      autoplay_videos: false,
13      thumbnails: false,
14      animated_thumbnails: false,
15      show_download_button: false,
16      disable_autoplay_on_first_video: false,
17      watchAttrs: false,
18    };
19
20    constructor(element, options) {
21      this.itemize = this.itemize.bind(this);
22      this.filterByGallery = this.filterByGallery.bind(this);
23
24      this.options = mergeObjects(this.defaultOptions, options);
25      this.selector = element;
26      this.element = this.queryElement(element);
27      this.itemSelector = `${this.options.itemSelector}:not(.swiper-slide-duplicate)`;
28
29      this.init();
30    }
31
32    createGallery(options) {
33      const defaultOptions = this.getLibOptions();
34
35      this.lightbox = lightGallery(this.element, {
36        ...defaultOptions,
37        ...options,
38      });
39
40      this.detectDuplicateSwiperSlides();
41      this.addThumbnailsToVideos();
42    }
43
44    queryElement(element) {
45      if (typeof element == "string") {
46        return document.querySelector(element);
47      }
48
49      return element;
50    }
51
52    getNamespace() {
53      if (this.element.dataset.lightboxId) {
54        return this.element.dataset.lightboxId;
55      }
56
57      if (this.selector) {
58        const tokens = this.selector
59          .split("-")
60          .filter((t) => !isNaN(Number(t)))
61          .slice(0, 2); // Post ID and Node ID only.
62
63        return tokens.join('-');
64      }
65
66      return "default";
67    }
68
69    getLibOptions() {
70      const settings = this.options;
71      const namespace = this.getNamespace();
72      const className = `bde-lightbox bde-lightbox-${namespace}`;
73
74      return {
75        plugins: [lgAutoplay, lgFullscreen, lgZoom, lgVideo, lgThumbnail],
76        licenseKey: "9E9C183D-14564BA5-B09B8BE0-F8B54A20",
77        addClass: className,
78        autoplay: settings.autoplay,
79        slideShowAutoplay: settings.autoplay,
80        slideShowInterval: settings.speed.number,
81        autoplayFirstVideo: !settings.disable_autoplay_on_first_video,
82        autoplayVideoOnSlide: settings.autoplay_videos, // TODO: This option is broken in the library
83        thumbnail: settings.thumbnails,
84        animateThumb: settings.animated_thumbnails,
85        zoomFromOrigin: settings.animated_thumbnails,
86        zoom: true,
87        download: settings.show_download_button,
88        mobileSettings: {
89          controls: true,
90          showCloseIcon: true,
91        }
92      };
93    }
94
95    getExtension(url) {
96      return url.split(".").pop();
97    }
98
99    isVideo(url) {
100      const types = ["mp4", "mov", "wmv", "avi", "mpg", "ogg", "3gp", "3g2"];
101      const extension = this.getExtension(url);
102      return types.includes(extension);
103    }
104
105    getVideoObject(url, caption, mime) {
106      if (!this.isVideo(url)) {
107        return {
108          src: url,
109          subHtml: caption,
110        };
111      }
112
113      if (!mime) {
114        const extension = this.getExtension(url);
115        mime = `video/${extension}`;
116      }
117
118      return {
119        video: {
120          source: [
121            {
122              src: url,
123              type: mime,
124            },
125          ],
126          attributes: {
127            preload: false,
128            controls: true,
129          },
130        },
131        subHtml: caption,
132        subHtmlUrl: "",
133      };
134    }
135
136    filterItems(item) {
137      const isImg = item.type === "image" && item.image;
138      const isVideo = item.type === "video" && item.video;
139      return isImg || isVideo;
140    }
141
142    itemize(item) {
143      // HTML5 videos or oEmbeds.
144      if (item.type === "video") {
145        return this.getVideoObject(item.video.url, item.caption);
146      }
147
148      // Handle HTML5 videos in WP Media Input
149      if (item.image && item.image.type === "video") {
150        return this.getVideoObject(
151          item.image.url,
152          item.caption,
153          item.image.mime
154        );
155      }
156
157      return {
158        src: item.image.url,
159        type: item.image.type,
160        thumb: item.image.sizes.thumbnail.url,
161        subHtml: item.caption,
162      };
163    }
164
165    getDynamicItems() {
166      return this.options.items.filter(this.filterItems).map(this.itemize);
167    }
168
169    detectDuplicateSwiperSlides() {
170      // If the slide clicked is a duplicate, we'll open the original slide in the lightbox instead.
171      this.element.addEventListener("click", (event) => {
172        const isDuplicateSlide = event.target.closest(
173          ".swiper-slide-duplicate"
174        );
175
176        if (!isDuplicateSlide) return;
177
178        event.preventDefault();
179        const index = isDuplicateSlide.getAttribute("data-swiper-slide-index");
180        this.lightbox.openGallery(index);
181      });
182    }
183
184    addThumbnailsToVideos() {
185      const videoPlaceholder =
186        "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMAAAACYCAAAAACXarlBAAAACXBIWXMAAC4jAAAuIwF4pT92AAAB6UlEQVR42u3ZWU+DQBSGYf//7zKaAOew2FLQqomaaF1aXFqXaMfi2qJWLwQ58f2uJnM1T84Ms7DijGcFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP4p4DjfrCbPr5zbyy5NAE784EN8r3AuW5WRBcCWF39IFJ471/dVhxYA/peAWGXYfkB/CSCpR9AcIK6nBk0CZoKRbUBcw0puFlDDLGoY8PsruWFAWYNzi4B8TV6z1plaA1w4t999Oxv1di0CrJxGPwPEwYFxQBgNJnMZX1sDxJHoXLx0ag2wGMkAAAAAAMBygM5/+EWftzNRsQKQ9KQYvaYYbJQCDQ+LvtgAhJ2bhc6rKJyNv7wNb4kJQLBX6c1FtCgbA88GYL8K8ORp/GYA1Qp0vZfXlCObgGnn1NkGTJxtwHsA/NEUejAOuN+5MT6FkuTWFqC6kWXr6b3pCuTip081OLYB0Mq7yW2isd+7m7V2AxvHad0ezz1kXWTlGTToFpMDtXKhWXjIUn35OaMScaUEAABAvYDNnwB6LQbseN8DgtS1FzBJfP0momctBri74XC0PGdj12ZA8wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3lEeS3kwDalXS7AAAAAElFTkSuQmCC";
187
188      const lgItems = this.lightbox.galleryItems;
189
190      if (!lgItems) return;
191
192      const items = lgItems.map((item) => {
193        if (item.video) {
194          return {
195            ...item,
196            thumb: item.thumb || videoPlaceholder,
197            src: null, // lightGallery goes crazy if the src key is present for videos.
198          };
199        }
200
201        return item;
202      });
203
204      this.lightbox.refresh(items);
205    }
206
207    update(options) {
208      this.options = mergeObjects(this.defaultOptions, options);
209      this.destroy();
210      this.init();
211    }
212
213    destroy() {
214      if (this.lightbox) {
215        this.lightbox.destroy();
216        this.lightbox = null;
217      }
218    }
219
220    initDynamic() {
221      const items = this.getDynamicItems();
222
223      this.element.addEventListener("click", () => {
224        this.createGallery({
225          dynamic: true,
226          dynamicEl: items,
227        });
228
229        // We wrap the method in a setTimeout, so that clicking the element
230        // won't fire a resize event before the gallery is ready.
231        //
232        // By clicking the element, the property panel opens up thus decreasing
233        // the iframe's width and triggering a resize event.
234        setTimeout(() => this.lightbox.openGallery(), 5);
235      });
236    }
237
238    getItemFromAnchor(el) {
239      const src = el.href;
240      return this.isVideo(src) ? this.getVideoObject(src) : { src };
241    }
242
243    filterByGallery(event) {
244      const { category } = event.detail;
245
246      const selector = category === "all"
247        ? this.itemSelector
248        : toArray(this.itemSelector).filter(
249          item => item.dataset.category === category
250        );
251
252      this.lightbox.settings.selector = selector;
253      this.lightbox.refresh();
254    }
255
256    initFromDOM() {
257      const onClick = (event) => {
258        const isLinkALightbox = event.currentTarget.dataset.type === "lightbox";
259        const disableAutoplay = event.currentTarget.dataset.lightboxAutoplay === "false";
260
261        this.options.disable_autoplay_on_first_video = disableAutoplay;
262
263        if (this.options.watchAttrs && !isLinkALightbox) return;
264
265        const item = this.getItemFromAnchor(this.element);
266
267        if (this.lightbox) {
268          this.lightbox.refresh([item]);
269        } else {
270          this.createGallery({
271            dynamic: true,
272            dynamicEl: [item]
273          });
274        }
275
276        this.lightbox.openGallery();
277      };
278
279      this.element.addEventListener("click", onClick);
280    }
281
282    initDefault() {
283      this.createGallery({
284        selector: this.itemSelector,
285      });
286
287      this.element.addEventListener("breakdance_gallery_filtered", this.filterByGallery);
288    }
289
290    init() {
291      const { type } = this.options;
292
293      if (type === "dynamic") {
294        // Element: Lightbox Gallery
295        // Show multiple images from an array
296        this.initDynamic();
297      } else if (type === "single") {
298        // Element: Button, Text Link, and Image (v1)
299        // Show an image from a href attribute
300        this.initFromDOM();
301      } else {
302        // Element: Gallery
303        // Show multiple images from DOM elements with the same css class
304        this.initDefault();
305      }
306
307      this.element.addEventListener("click", (event) => event.preventDefault());
308      this.element.classList.add("is-lightbox-active");
309    }
310
311    static autoload(parent = null) {
312      const element = parent ?? document;
313      // Autoload lightboxes from macros
314      const selector =
315        ".breakdance-link[data-type='lightbox']:not(.is-lightbox-active), .oxygen-link[data-type='lightbox']:not(.is-lightbox-active)";
316      const links = element.querySelectorAll(selector);
317
318      links.forEach((link) => {
319        new this(link, {
320          type: "single",
321          watchAttrs: true,
322        });
323      });
324    }
325  }
326
327  BreakdanceLightbox.autoload();
328  window.BreakdanceLightbox = BreakdanceLightbox;
329})();

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.