PageSourceSearch

https://www.productionparadise.com/js/photoswipe.js?v=1790294349

js productionparadise.com collected 2026-09-24 23:59:30 UTC 13,988 bytes, 394 lines download raw bytes

1import PhotoSwipeDynamicCaption from "/js/photoswipe/photoswipe-dynamic-caption-plugin.esm.js";
2import PhotoSwipeLightbox from "/js/photoswipe/photoswipe-lightbox.esm.min.js";
3import PhotoSwipe from "/js/photoswipe/photoswipe.esm.min.js";
4
5function isVideoContent(content) {
6    return content && content.data && content.data.type === "video";
7}
8
9class VideoContentSetup {
10    constructor(lightbox, options) {
11        this.options = options;
12
13        this.initLightboxEvents(lightbox);
14        lightbox.on("init", () => {
15            this.initPswpEvents(lightbox.pswp);
16        });
17    }
18
19    initLightboxEvents(lightbox) {
20        lightbox.on("contentLoad", this.onContentLoad.bind(this));
21        lightbox.on("contentDestroy", this.onContentDestroy.bind(this));
22        lightbox.on("contentActivate", this.onContentActivate.bind(this));
23        lightbox.on("contentDeactivate", this.onContentDeactivate.bind(this));
24        lightbox.on("contentAppend", this.onContentAppend.bind(this));
25        lightbox.on("contentResize", this.onContentResize.bind(this));
26
27        lightbox.addFilter(
28            "isKeepingPlaceholder",
29            this.isKeepingPlaceholder.bind(this)
30        );
31        lightbox.addFilter(
32            "isContentZoomable",
33            this.isContentZoomable.bind(this)
34        );
35        lightbox.addFilter(
36            "useContentPlaceholder",
37            this.useContentPlaceholder.bind(this)
38        );
39
40        lightbox.addFilter("domItemData", (itemData, element, linkEl) => {
41            if (itemData.type === "video" && linkEl) {
42                itemData.isVideoElement = true;
43                if (linkEl.dataset.pswpVideoSources) {
44                    itemData.videoSources = JSON.parse(pswpVideoSources);
45                } else if (linkEl.dataset.pswpVideoSrc) {
46                    itemData.videoSrc = linkEl.dataset.pswpVideoSrc;
47                } else {
48                    itemData.videoSrc = linkEl.href;
49                }
50            }
51            if (linkEl.dataset.pswpExternalHtml) {
52                itemData.externalHtml = linkEl.dataset.pswpExternalHtml;
53                itemData.isVideoElement = false;
54            }
55
56            return itemData;
57        });
58    }
59
60    initPswpEvents(pswp) {
61        // Prevent draggin when pointer is in bottom part of the video
62        // todo: add option for this
63        pswp.on("pointerDown", (e) => {
64            const slide = pswp.currSlide;
65            if (isVideoContent(slide) && this.options.preventDragOffset) {
66                const origEvent = e.originalEvent;
67                if (origEvent.type === "pointerdown") {
68                    const videoHeight = Math.ceil(
69                        slide.height * slide.currZoomLevel
70                    );
71                    const verticalEnding = videoHeight + slide.bounds.center.y;
72                    const pointerYPos = origEvent.pageY - pswp.offset.y;
73                    if (
74                        pointerYPos >
75                            verticalEnding - this.options.preventDragOffset &&
76                        pointerYPos < verticalEnding
77                    ) {
78                        e.preventDefault();
79                    }
80                }
81            }
82        });
83
84        // do not append video on nearby slides
85        pswp.on("appendHeavy", (e) => {
86            if (isVideoContent(e.slide) && !e.slide.isActive) {
87                e.preventDefault();
88            }
89        });
90
91        pswp.on("close", () => {
92            if (isVideoContent(pswp.currSlide.content)) {
93                // Switch from zoom to fade closing transition,
94                // as zoom transition is choppy for videos
95                if (
96                    !pswp.options.showHideAnimationType ||
97                    pswp.options.showHideAnimationType === "zoom"
98                ) {
99                    pswp.options.showHideAnimationType = "fade";
100                }
101
102                // pause video when closing
103                this.pauseVideo(pswp.currSlide.content);
104            }
105        });
106    }
107
108    onContentDestroy({ content }) {
109        if (isVideoContent(content)) {
110            if (content._videoPosterImg) {
111                content._videoPosterImg.onload =
112                    content._videoPosterImg.onerror = null;
113                content._videoPosterImg = null;
114            }
115        }
116    }
117
118    onContentResize(e) {
119        if (isVideoContent(e.content)) {
120            e.preventDefault();
121
122            const width = e.width;
123            const height = e.height;
124            const content = e.content;
125
126            if (content.element) {
127                content.element.style.width = width + "px";
128                content.element.style.height = height + "px";
129            }
130
131            if (content.slide && content.slide.placeholder) {
132                // override placeholder size, so it more accurately matches the video
133                const placeholderElStyle =
134                    content.slide.placeholder.element.style;
135                placeholderElStyle.transform = "none";
136                placeholderElStyle.width = width + "px";
137                placeholderElStyle.height = height + "px";
138            }
139        }
140    }
141
142    isKeepingPlaceholder(isZoomable, content) {
143        if (isVideoContent(content)) {
144            return false;
145        }
146        return isZoomable;
147    }
148
149    isContentZoomable(isZoomable, content) {
150        if (isVideoContent(content)) {
151            return false;
152        }
153        return isZoomable;
154    }
155
156    onContentActivate({ content }) {
157        if (isVideoContent(content) && this.options.autoplay) {
158            this.playVideo(content);
159        }
160    }
161
162    onContentDeactivate({ content }) {
163        if (isVideoContent(content)) {
164            this.pauseVideo(content);
165        }
166    }
167
168    onContentAppend(e) {
169        if (isVideoContent(e.content)) {
170            e.preventDefault();
171            e.content.isAttached = true;
172            e.content.appendImage();
173        }
174    }
175
176    onContentLoad(e) {
177        const content = e.content;
178
179        if (!isVideoContent(e.content)) {
180            return;
181        }
182
183        e.preventDefault();
184
185        if (content.element) {
186            return;
187        }
188
189        content.state = "loading";
190        content.type = "video";
191
192        // show loader until video is loaded
193        content.element = document.createElement("div");
194        content.element.style.width = "100%";
195        content.element.style.height = "100%";
196
197        //append spinner
198        const spinner = document.createElement("div");
199        spinner.classList.add("loader-container-dark");
200        const spinnerElement = document.createElement("div");
201        spinnerElement.classList.add("loader-mansory");
202        spinner.appendChild(spinnerElement);
203        content.element.appendChild(spinner);
204
205        if (content.data.externalHtml) {
206            const externalHtmlContainer = document.createElement("div");
207            externalHtmlContainer.style.width = "100%";
208            externalHtmlContainer.style.height = "100%";
209            externalHtmlContainer.innerHTML = content.data.externalHtml;
210            const iframe = externalHtmlContainer.querySelector("iframe");
211            if (iframe && iframe.src.includes("vimeo")) {
212                if (iframe.src.includes("?")) {
213                    iframe.src += "&";
214                } else {
215                    iframe.src += "?";
216                }
217                iframe.src += "autoplay=1&loop=1&autopause=0&muted=0";
218            } else if (iframe && iframe.src.includes("youtube")) {
219                if (iframe.src.includes("?")) {
220                    iframe.src += "&";
221                } else {
222                    iframe.src += "?";
223                }
224                iframe.src += "autoplay=1";
225            }
226            iframe.style.width = "100%";
227            iframe.style.height = "100%";
228            content.element.appendChild(externalHtmlContainer);
229        } else {
230            content.element.appendChild(document.createElement("video"));
231        }
232
233        const video = content.element.querySelector("video");
234        //check if video is loaded
235        if (content.data.externalHtml) {
236            const iframe = content.element.querySelector("iframe");
237            iframe.onload = () => {
238                setTimeout(() => {
239                    content.element.removeChild(spinner);
240                }, 1000);
241            };
242        } else {
243            video.onloadeddata = () => {
244                content.element.removeChild(spinner);
245            };
246        }
247
248        if (this.options.videoAttributes && video) {
249            for (let key in this.options.videoAttributes) {
250                video.setAttribute(
251                    key,
252                    this.options.videoAttributes[key] || ""
253                );
254            }
255        }
256        content.element.style.position = "absolute";
257        content.element.style.left = 0;
258        content.element.style.top = 0;
259
260        if (content.data.isVideoElement) {
261            if (content.data.videoSources) {
262                content.data.videoSources.forEach((source) => {
263                    let sourceEl = document.createElement("source");
264                    sourceEl.src = source.src;
265                    sourceEl.type = source.type;
266                    video.appendChild(sourceEl);
267                });
268            } else if (content.data.videoSrc) {
269                video.src = content.data.videoSrc;
270            }
271        }
272    }
273
274    playVideo(content) {
275        if (content.element) {
276            if (content.data.isVideoElement) {
277                const video = content.element.querySelector("video");
278                video.play();
279            } else if (content.data.externalHtml) {
280                // For iframes, restore src if it was removed
281                const iframe = content.element.querySelector("iframe");
282                if (iframe && iframe.dataset.originalSrc) {
283                    iframe.src = iframe.dataset.originalSrc;
284                }
285            }
286        }
287    }
288
289    pauseVideo(content) {
290        if (content.element) {
291            if (content.data.isVideoElement) {
292                const video = content.element.querySelector("video");
293                video.pause();
294            } else if (content.data.externalHtml) {
295                // For iframes (YouTube/Vimeo), remove src to stop playback
296                const iframe = content.element.querySelector("iframe");
297                if (iframe) {
298                    iframe.dataset.originalSrc = iframe.src;
299                    iframe.src = "";
300                }
301            }
302        }
303    }
304
305    useContentPlaceholder(usePlaceholder, content) {
306        if (isVideoContent(content)) {
307            return false;
308        }
309        return usePlaceholder;
310    }
311}
312
313const defaultOptions = {
314    videoAttributes: { controls: "", playsinline: "", preload: "auto" },
315    autoplay: true,
316
317    // prevent drag/swipe gesture over the bottom part of video
318    // set to 0 to disable
319    preventDragOffset: 40,
320};
321
322class PhotoSwipeVideoPlugin {
323    constructor(lightbox, options) {
324        new VideoContentSetup(lightbox, {
325            ...defaultOptions,
326            ...options,
327        });
328    }
329}
330
331function loadPhotoSwipe() {
332    const galleries = document.querySelectorAll(".photo-gallery");
333
334    const leftArrowSVGString =
335        '<svg width="41" height="34" viewBox="0 0 41 34" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.46875 16.625L39.4451 16.6231" stroke="#AECCE7" stroke-width="1.94444" stroke-linecap="square" stroke-linejoin="round"/><path d="M15.1658 1.55469L1.55469 17.1121L15.1658 32.6658" stroke="#AECCE7" stroke-width="1.94444" stroke-linejoin="round"/></svg>';
336    const rightArrowSVGString =
337        '<svg width="41" height="34" viewBox="0 0 41 34" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M37.5352 17.5977L1.5588 17.5996" stroke="#AECCE7" stroke-width="1.94444" stroke-linecap="square" stroke-linejoin="round"/><path d="M25.8342 32.668L39.4453 17.1106L25.8342 1.55686" stroke="#AECCE7" stroke-width="1.94444" stroke-linejoin="round"/></svg>';
338
339    const closeIcon =
340        '<svg width="37" height="37" viewBox="0 0 37 37" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M34.9167 2.25L2.25 34.9167" stroke="#AECCE7" stroke-width="2" stroke-linecap="square" stroke-linejoin="round"/><path d="M34.9167 34.9167L2.25 2.25" stroke="#AECCE7" stroke-width="2" stroke-linecap="square" stroke-linejoin="round"/></svg>';
341
342    galleries.forEach((gallery) => {
343        const images = gallery.querySelectorAll("a");
344        images.forEach((image) => {
345            const img = new Image();
346            img.src = image.href;
347            img.onload = function () {
348                image.setAttribute("data-pswp-width", this.width);
349                image.setAttribute("data-pswp-height", this.height);
350            };
351        });
352
353        const smallScreenPadding = {
354            top: 0,
355            bottom: 0,
356            left: 0,
357            right: 0,
358        };
359        const largeScreenPadding = {
360            top: 30,
361            bottom: 30,
362            left: 0,
363            right: 0,
364        };
365
366        const lightbox = new PhotoSwipeLightbox({
367            gallery: gallery,
368            children: ".photo-gallery-item",
369            pswpModule: PhotoSwipe,
370            paddingFn: (viewportSize) => {
371                return viewportSize.x < 700
372                    ? smallScreenPadding
373                    : largeScreenPadding;
374            },
375            preload: [1, 4],
376            showHideAnimationType: "fade",
377            arrowPrevSVG: leftArrowSVGString,
378            arrowNextSVG: rightArrowSVGString,
379            closeSVG: closeIcon,
380            zoom: false,
381            counter: false,
382        });
383        new PhotoSwipeVideoPlugin(lightbox, {});
384        new PhotoSwipeDynamicCaption(lightbox, {
385            type: "below",
386        });
387
388        setTimeout(() => {
389            lightbox.init();
390        }, 500);
391    });
392}
393
394loadPhotoSwipe();

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.