New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

glightbox

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

glightbox - npm Package Compare versions

Comparing version 4.0.0-beta.2 to 4.0.0-beta.3

dist/index.umd.js

173

dist/glightbox.d.ts

@@ -1,66 +0,10 @@

declare interface AppearaceOptions {
/**
* Define a custom theme it will
* add a class to the lightbox so you can
* change the appearance with CSS
*
* @default 'clean'
*/
theme?: string;
/**
* Set your own svg icons.
*/
slideEffect?: string | false;
/**
* Set your open effect
*/
openEffect?: string | false;
/**
* More text for descriptions on mobile devices.
*
* @default 'See more'
*/
moreText?: string;
/**
* Number of characters to display on the description before adding
* the moreText link (only for mobiles),
* if 0 it will display the entire description.
*
* @default 60
*/
moreLength?: number;
/**
* Name of the effect on lightbox close. (zoom, fade, none)
*
* @default 'zoom'
*/
closeEffect?: string;
/**
* You can completely change the html of GLightbox.
*/
lightboxHTML?: string;
/**
* You can completely change the html of the individual slide.
*/
slideHTML?: string;
/**
* Set your own svg icons.
*/
svg?: Record<'close' | 'next' | 'prev' | 'loader', string>;
}
export declare interface GalleryItem {
node: HTMLElement;
index: number;
slideConfig: any;
slideIndex: number;
slideNode: HTMLElement;
}
declare class GLightbox {
import type { Plugin } from '@glightbox/plugin-core';
import { EventType } from '@glightbox/utils';
import type { ApiEvent, GLightboxOptions, SlideConfig } from './types';
export default class GLightbox {
options: GLightboxOptions;
apiEvents: Set<any>;
events: Map<string, Function>;
apiEvents: Set<ApiEvent>;
events: Map<string, EventType>;
state: Map<string, number | boolean | HTMLElement>;
plugins: Map<string, any>;
plugins: Map<string, Map<string, Plugin>>;
items: Set<SlideConfig>;

@@ -87,3 +31,2 @@ modal: HTMLElement | null;

private setItemsFromNode;
private setItemsFromSelector;
getSettings(): GLightboxOptions;

@@ -98,5 +41,5 @@ private getElementIndex;

private afterSlideLoaded;
protected on(evt: string, callback: Function, once?: boolean): void;
protected once(evt: string, callback: Function): void;
protected trigger(eventName: string, data?: any): void;
on(evt: string, callback: () => void, once?: boolean): void;
once(evt: string, callback: () => void): void;
protected trigger(eventName: string, data?: unknown): void;
private parseConfigFromNode;

@@ -106,96 +49,12 @@ private getRegisteredSlideType;

processVariables(node: HTMLElement): void;
protected registerPlugin(plugin: any): void;
protected registerPlugin(plugin: Plugin): void;
protected initPlugins(): void;
protected runPluginsMethod(method: string): void;
pluginsRunEach(callback: Function): void;
pluginsRunEach(callback: (plugin: Plugin) => void): void;
protected injectCSS(css: string): void;
injectAssets(urls: string | string[]): Promise<void>;
injectAssets(urls: (string | string[] | {
src: string;
module?: boolean;
})[]): Promise<void>;
private clearAllEvents;
}
export default GLightbox;
declare interface GLightboxOptions {
plugins: any[];
/**
* Name of the selector for example '.glightbox' or 'data-glightbox'
* or '*[data-glightbox]'
*
* @default '*[data-glightbox]'
*/
selector?: string;
/**
* Automatically make all items with the same selector a gallery
* if false each item will be displayed individually
*
* @default true
*/
autoGallery?: boolean;
/**
* Name of the effect on lightbox open. (zoom, fade, none)
*
* @default 'zoom'
*/
appearance?: AppearaceOptions;
/**
* Name of the effect on slide change. (slide, fade, zoom, none)
*
* @default 'slide'
*/
slideEffect?: string;
/**
* Close the lightbox when clicking outside the active slide.
*
* @default true
*/
closeOnOutsideClick?: boolean;
/**
* Start lightbox at defined index.
*
* @default 0
*/
startAt?: number;
/**
* Enable or disable preloading.
* If enabled, adjacent slides to the currently displayed will be preloaded
*
* @default true
*/
preload?: boolean;
/**
* Loop slides on end.
*
* @default false
*/
loop?: boolean;
/**
* List of custom data attributes
* you can define custom data attributes
* so they get parsed and you can use them
* in the slide
*
* @default []
*/
customDataAttributes?: string[];
/**
* Custom prefix for data attributes
* so instead of data-url you can define
* data-prefix-url
*
* @default ''
*/
dataAttributesPrefix?: string;
}
declare interface SlideConfig {
node?: Element | null;
url: string;
thumbnail?: string;
title?: string;
description?: string;
html?: boolean;
zoomable?: boolean;
draggable?: boolean;
[key: string]: any;
}
export { }

@@ -1,1 +0,14 @@

"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./glightbox.cjs.js"),t=require("./ImageSlide.cjs.js");exports.GLightbox=e;exports.ImageSlide=t;
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=(l,...e)=>{if(!e.length)return l;const t=e.shift();return t===void 0?l:(E(l)&&E(t)&&Object.keys(t).forEach(function(i){E(t[i])?(l[i]||(l[i]={}),C(l[i],t[i])):l[i]=t[i]}),C(l,...e))};function p(l,e){l.classList.add(...e.split(" "))}function v(l,e){l.classList.remove(...e.split(" "))}function w(l,e){return l.classList.contains(e)}function S(l,{element:e,callback:t,preventDefault:i=!0,once:s=!1,useCapture:o=!1},r){let d=[];const n=t.toString().trim().replace(/\s/g,""),c=typeof e=="string";if(!c)d=[e];else if(c){const h=document.querySelectorAll(e);h&&(d=[...h])}const a=function(h){typeof t=="function"&&(i&&h.preventDefault(),t.call(r,this,h)),s&&a.destroy()};return a.destroy=function(){d.forEach(h=>{h==null||h.removeEventListener(l,a,o)})},d.forEach(h=>{h&&h.attachedEvent!==n&&(h.addEventListener(l,a,o),h.attachedEvent=n)}),a}function H(l,e){return new Promise(t=>{l.addEventListener("animationend",()=>{t(!0)}),p(l,e)})}function P(l){return new Promise((e,t)=>{l||t("url must be defined");let i="";typeof l!="string"?i=l.src:i=l;let s;if((i.includes(".css")?"css":"js")=="css"){if(s=document.querySelectorAll('link[href="'+i+'"]'),s&&s.length>0){e(!0);return}const r=document.getElementsByTagName("head")[0],d=r.querySelectorAll('link[rel="stylesheet"]'),n=document.createElement("link");n.rel="stylesheet",n.type="text/css",n.href=i,n.media="all",d?r.insertBefore(n,d[0]):r.appendChild(n),e(!0);return}if(s=document.querySelectorAll('script[src="'+i+'"]'),s&&s.length>0){e(!0);return}const o=document.createElement("script");o.type="text/javascript",o.src=i,typeof l!="string"&&l!=null&&l.module&&(o.type="module"),o.onload=()=>{e(!0)},document.body.appendChild(o)})}function $(l){return!!(l&&l.nodeType&&l.nodeType==1)}const j=l=>l!==null&&typeof l=="object",E=l=>j(l)&&!Array.isArray(l),D={root:null,autoGallery:!0,setClickEvent:!0,dataAttributesPrefix:"",items:[],plugins:[],appearance:{slideEffect:"fade",openEffect:"zoom",moreText:"See more",moreLength:60,lightboxHTML:`<div id="gl-body" class="gl-lightbox gl-container" tabindex="0" role="dialog" aria-hidden="false">
<div id="gl-slider" class="gl-slider"></div>
<button class="gl-close gl-btn" aria-label="Close" tabindex="3" aria-hidden="false" data-glightbox-close-svg></button>
<button class="gl-next gl-btn" aria-label="Next" tabindex="1" aria-hidden="false" data-glightbox-next-svg></button>
<button class="gl-prev gl-btn" aria-label="Previous" tabindex="2" aria-hidden="false" data-glightbox-prev-svg></button>
<div class="gl-overlay"></div>
</div>`,slideHTML:"",svg:{close:'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" xml:space="preserve"><g><g><path d="M505.943,6.058c-8.077-8.077-21.172-8.077-29.249,0L6.058,476.693c-8.077,8.077-8.077,21.172,0,29.249C10.096,509.982,15.39,512,20.683,512c5.293,0,10.586-2.019,14.625-6.059L505.943,35.306C514.019,27.23,514.019,14.135,505.943,6.058z"/></g></g><g><g><path d="M505.942,476.694L35.306,6.059c-8.076-8.077-21.172-8.077-29.248,0c-8.077,8.076-8.077,21.171,0,29.248l470.636,470.636c4.038,4.039,9.332,6.058,14.625,6.058c5.293,0,10.587-2.019,14.624-6.057C514.018,497.866,514.018,484.771,505.942,476.694z"/></g></g></svg>',next:'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 477.175 477.175" xml:space="preserve"> <g><path d="M360.731,229.075l-225.1-225.1c-5.3-5.3-13.8-5.3-19.1,0s-5.3,13.8,0,19.1l215.5,215.5l-215.5,215.5c-5.3,5.3-5.3,13.8,0,19.1c2.6,2.6,6.1,4,9.5,4c3.4,0,6.9-1.3,9.5-4l225.1-225.1C365.931,242.875,365.931,234.275,360.731,229.075z"/></g></svg>',prev:'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 477.175 477.175" xml:space="preserve"><g><path d="M145.188,238.575l215.5-215.5c5.3-5.3,5.3-13.8,0-19.1s-13.8-5.3-19.1,0l-225.1,225.1c-5.3,5.3-5.3,13.8,0,19.1l225.1,225c2.6,2.6,6.1,4,9.5,4s6.9-1.3,9.5-4c5.3-5.3,5.3-13.8,0-19.1L145.188,238.575z"/></g></svg>',loader:'<svg aria-hidden="true" class="w-8 h-8 mr-2 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/><path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/></svg>'}},startAt:0,customDataAttributes:[],preload:!0,loop:!0,closeOnOutsideClick:!0};class z{constructor(e={}){var i;this.apiEvents=new Set,this.events=new Map,this.state=new Map,this.plugins=new Map,this.items=new Set,this.modal=null,this.prevButton=null,this.nextButton=null,this.overlay=null,this.slidesContainer=null,this.options=C(D,e);const t=window.matchMedia("(prefers-reduced-motion: reduce)");(!t||t.matches)&&((i=this.options.appearance)!=null&&i.slideEffect)&&(this.options.appearance.slideEffect=!1,this.options.appearance.openEffect=!1),this.init()}init(e=!0){if(e)for(const t of this.options.plugins)this.registerPlugin(t);this.options.setClickEvent&&this.events.set("gallery",S("click",{element:"*[data-glightbox]",callback:t=>{this.open(t)}}))}open(e){var i;if(this.state.get("open"))return;if(!this.plugins.has("slide"))throw new Error("No slide types registered");this.items.size===0&&$(e)&&this.setItemsFromNode(e);let t=this.options.startAt;this.options.autoGallery?typeof e=="number"?t=e:$(e)&&(t=this.getElementIndex(e)):t=0,this.state.set("focused",document.activeElement),this.build(),this.trigger("before_open"),this.initPlugins(),this.showSlide(t,!0),this.trigger("open"),this.state.set("open",!0),(i=this.modal)==null||i.focus(),p(document.body,"gl-open")}prevSlide(){this.goToSlide(this.getActiveSlideIndex()-1)}nextSlide(){this.goToSlide(this.getActiveSlideIndex()+1)}goToSlide(e=0){const t=this.getTotalSlides()-1;!this.options.loop&&(e<0||e>this.getTotalSlides()-1)||(e<0?e=t:e>t&&(e=0),this.showSlide(e))}async showSlide(e=0,t=!1){var c,a,h,f;const i=(c=this.slidesContainer)==null?void 0:c.querySelector(".current");i&&v(i,"current");const s=(a=this.slidesContainer)==null?void 0:a.querySelectorAll(".gl-slide")[e];console.log("GLightbox > showSlide > slideNode",s);const o=s.querySelector(".gl-media");if(!s||!o)return;t||this.trigger("slide_before_change",{current:this.state.get("prevActiveSlideIndex"),next:e}),await this.preloadSlide(e,!t);const r=(h=this.options.appearance)==null?void 0:h.slideEffect,d=(f=this.options.appearance)==null?void 0:f.openEffect,n=r!=="slide"||t?"instant":"smooth";s.scrollIntoView({behavior:n,block:"start",inline:"start"}),v(o,"gl-animation-ended"),t&&d?(p(o,"gl-invisible"),d&&await H(o,`gl-${d}-in`),p(o,"gl-animation-ended"),v(o,`gl-invisible gl-${d}-in`)):v(o,"gl-invisible"),this.setActiveSlideState(s,e),this.trigger("slide_changed",{prev:this.state.get("prevActiveSlideIndex"),current:e}),this.options.preload&&(this.preloadSlide(e+1),this.preloadSlide(e-1))}setActiveSlideState(e,t){this.state.set("prevActiveSlide",this.state.get("activeSlide")??!1),this.state.set("prevActiveSlideIndex",this.getActiveSlideIndex()),this.state.set("activeSlide",e),this.state.set("activeSlideIndex",t),this.updateNavigationButtons()}async preloadSlide(e,t=!0){var n,c;if(e<0||e>this.items.size-1)return!1;const i=(n=this.slidesContainer)==null?void 0:n.querySelectorAll(".gl-slide")[e];if(i&&(w(i,"loaded")||w(i,"preloading")))return!0;const s=this.getSlideData(e),o=s==null?void 0:s.type,r=this.getRegisteredSlideType(o);let d="";if((!o||!r)&&(d=`Unable to handle URL: ${s==null?void 0:s.url}`),d)throw this.setSlideError(i,d),new Error(d);if(s!=null&&s.url&&r&&i&&(r!=null&&r.build)){p(i,"preloading");try{this.trigger("slide_before_load",s),await r.build({index:e,slide:i.querySelector(".gl-media"),config:{...s,isPreload:t}}),(c=i.querySelector(".gl-slide-loader"))==null||c.remove(),this.afterSlideLoaded(i);const a=i.querySelector(".gl-media");return a&&(p(a,`gl-type-${o}`),t&&v(a,"gl-invisible")),i}catch(a){this.afterSlideLoaded(i),this.setSlideError(i,a)}}return!1}build(){var d,n,c,a,h,f,x,b,A,k,L,I,M,T,q,B;if(this.state.get("build"))return;this.trigger("before_build");const e=document.body.querySelectorAll(":scope > *");e&&[...e].forEach(u=>{u.parentNode==document.body&&u.nodeName.charAt(0)!=="#"&&u.hasAttribute&&!u.hasAttribute("aria-hidden")&&(u.ariaHidden="true",u.dataset.glHidden="true")});const t=((d=this.options)==null?void 0:d.root)??document.body,i=((c=(n=this.options)==null?void 0:n.appearance)==null?void 0:c.lightboxHTML)??"";if(t.insertAdjacentHTML("beforeend",i),this.modal=document.getElementById("gl-body"),!this.modal)throw new Error("modal body not found");const s=this.modal.querySelector(".gl-close");if(this.prevButton=this.modal.querySelector(".gl-prev"),this.nextButton=this.modal.querySelector(".gl-next"),this.overlay=this.modal.querySelector(".gl-overlay"),this.slidesContainer=document.getElementById("gl-slider"),p(this.modal,"gl-theme-"+(((h=(a=this.options)==null?void 0:a.appearance)==null?void 0:h.theme)??"base")),p(this.modal,"gl-slide-effect-"+(((x=(f=this.options)==null?void 0:f.appearance)==null?void 0:x.slideEffect)||"none")),(A=(b=this.options)==null?void 0:b.appearance)!=null&&A.cssVariables)for(const[u,g]of Object.entries(this.options.appearance.cssVariables))this.modal.style.setProperty(`--gl-${u}`,g);s&&this.events.set("close",S("click",{element:s,callback:()=>this.close()})),this.nextButton&&this.events.set("next",S("click",{element:this.nextButton,callback:()=>this.nextSlide()})),this.prevButton&&this.events.set("prev",S("click",{element:this.prevButton,callback:()=>this.prevSlide()})),this.options.closeOnOutsideClick&&this.events.set("outClose",S("click",{element:this.modal,callback:(u,g)=>{var m;u&&(g!=null&&g.target)&&!((m=g==null?void 0:g.target)!=null&&m.closest(".gl-media"))&&(g.target.closest(".gl-btn")||this.close())}})),this.processVariables(this.modal);const o=new IntersectionObserver(u=>{u.forEach(g=>{var m;if(v(g.target,"visible"),g.isIntersecting&&this.state.get("open")){const y=parseInt(((m=g.target)==null?void 0:m.getAttribute("data-index"))??"0");p(g.target,"visible"),y!==this.state.get("activeSlideIndex")&&this.setActiveSlideState(g.target,y),!w(g.target,"loaded")&&!w(g.target,"preloading")&&(this.preloadSlide(y),this.preloadSlide(y+1),this.preloadSlide(y-1))}})},{root:this.modal,rootMargin:"0px",threshold:.2});let r=0;console.log("this.items",this.items);for(const u of this.items){const g=this.getRegisteredSlideType(u==null?void 0:u.type);if(console.log("GLightbox > build > slideType",g),u!=null&&u.url&&g){let m=(L=(k=this.options)==null?void 0:k.appearance)==null?void 0:L.slideHTML;const y=(T=(M=(I=this.options)==null?void 0:I.appearance)==null?void 0:M.svg)==null?void 0:T.loader;m||(m=`<div class="gl-slide" data-index="${r}" style="--gl-index: ${r}">
<div class="gl-slide-loader" role="status">
${y}
<span class="gl-sr-only">Loading...</span>
</div>
<div class="gl-media gl-invisible">
</div>
</div>`),(q=this.slidesContainer)==null||q.insertAdjacentHTML("beforeend",m);const N=(B=this.slidesContainer)==null?void 0:B.querySelectorAll(".gl-slide")[r];N&&o.observe(N),r++}}this.overlay&&p(this.overlay,"gl-overlay-in"),this.state.set("build",!0),this.trigger("build")}async close(){var s,o,r,d;if(!this.state.get("open")||!this.modal)return;this.runPluginsMethod("destroy"),v(document.body,"gl-open gl-crollbar-fixer");const e=document.querySelectorAll('*[data-gl-hidden="true"]');if(e&&e.forEach(n=>{n.ariaHidden="false",delete n.dataset.glHidden}),((s=this.options.appearance)==null?void 0:s.slideEffect)==="none")(o=this.modal.parentNode)==null||o.removeChild(this.modal);else{const c=this.state.get("activeSlide").querySelector(".gl-media"),a=(r=this.options.appearance)==null?void 0:r.openEffect;c&&(p(this.modal,"gl-closing"),a&&(v(c,"gl-animation-ended"),await H(c,`gl-${a}-out`))),(d=this.modal.parentNode)==null||d.removeChild(this.modal)}this.state.clear(),this.modal=null,this.prevButton=null,this.nextButton=null,this.clearAllEvents(),this.setItems([]);const t=document.querySelectorAll(".gl-css");t&&t.forEach(n=>{var c;return(c=n==null?void 0:n.parentNode)==null?void 0:c.removeChild(n)}),this.trigger("close");const i=this.state.get("focused");i==null||i.focus()}destroy(){this.close(),this.clearAllEvents(!0)}reload(){this.init(!1)}setItems(e){var i,s;if(!e||(this.items=new Set,!e.length))return;const t=this.plugins.get("slide");if(!t)throw new Error("No slide types registered");for(const o of e){if(o!=null&&o.type){if(!t.has(o.type))throw new Error(`Unknown slide type: ${o.type}`);continue}let r=!1;for(const[d,n]of t){if(n.name==="iframe"){r=n;continue}let c=!1;if(n!=null&&n.match&&n.match(o.url.toLowerCase())&&(o.type=d,c=!0),n!=null&&n.options&&typeof((i=n.options)==null?void 0:i.matchFn)=="function"&&(s=n.options)!=null&&s.matchFn(o.url.toLowerCase())&&(o.type=d,c=!0),c)break}o!=null&&o.type||r&&(o.type=r.name),this.getItems().add(o)}}setItemsFromNode(e){if(!this.options.autoGallery){this.setItems([this.parseConfigFromNode(e)]);return}let t="*[data-glightbox]";const i=e.getAttribute("data-glightbox");i&&(t=`*[data-glightbox="${i}"]`);const s=document.querySelectorAll(t);if(!s)return;const o=[];[...s].forEach(r=>{const d=this.parseConfigFromNode(r);o.push(d)}),this.setItems(o)}getSettings(){return this.options}getElementIndex(e){let t=0,i=0;for(const s of this.items){if((s==null?void 0:s.node)===e){t=i;break}i++}return t}getActiveSlide(){if(this.state.has("activeSlide"))return this.state.get("activeSlide")}getActiveSlideIndex(){return this.state.has("activeSlideIndex")?this.state.get("activeSlideIndex"):0}getTotalSlides(){return this.items.size}getItems(){return this.items}updateNavigationButtons(){if(this.items.size===1){this.modal&&p(this.modal,"gl-single-slide");return}if(!this.nextButton||!this.prevButton)return;const e=this.options.loop,t=this.getActiveSlideIndex(),i=this.getTotalSlides()-1;this.prevButton.disabled=!1,this.nextButton.disabled=!1,t===0&&!e?this.prevButton.disabled=!0:t===i&&!e&&(this.nextButton.disabled=!0)}setSlideError(e,t){var s;(s=e.querySelector(".gl-slide-loader"))==null||s.remove();const i=e.querySelector(".gl-media");i&&(p(i,"gl-load-error"),v(i,"gl-invisible"),i.innerHTML=`<div class="gl-error">${t}</div>`)}afterSlideLoaded(e){p(e,"loaded"),v(e,"preloading")}on(e,t,i=!1){if(!e||typeof t!="function")throw new TypeError("Event name and callback must be defined");this.apiEvents.add({evt:e,once:i,callback:t})}once(e,t){this.on(e,t,!0)}trigger(e,t=null){for(const i of this.apiEvents){const{evt:s,once:o,callback:r}=i;s===e&&(r(t),o&&this.apiEvents.delete(i))}}parseConfigFromNode(e){var r,d,n,c;const t={node:null,url:"",title:"",description:"",width:"",height:"",content:"",type:""};let i="";const s={url:"",type:""},o=e.nodeName.toLowerCase();o==="a"&&(i=e.getAttribute("href")||""),o==="img"&&(i=e.getAttribute("src")||""),o==="figure"&&(i=((r=e.querySelector("img"))==null?void 0:r.getAttribute("src"))||""),s.node=e,s.url=i;for(const a in t){let h="data";(d=this.options)!=null&&d.dataAttributesPrefix&&(h+=`-${(n=this.options)==null?void 0:n.dataAttributesPrefix}`);let f=e.getAttribute(`${h}-${a}`);f&&((f==="true"||f==="false")&&(f=f==="true"),s[a]=f)}if(!s.title){const a=e==null?void 0:e.getAttribute("title");a&&(s.title=a)}if(s!=null&&s.description&&s.description.startsWith(".")){const a=(c=document.querySelector(s.description))==null?void 0:c.innerHTML;a&&(s.description=a)}if(!s.description){const a=e.querySelector(".gl-inline-desc");a&&(s.description=a.innerHTML)}return s}getRegisteredSlideType(e){if(this.plugins.has("slide")){const t=this.plugins.get("slide");if(t&&t.has(e))return t.get(e)}return!1}getSlideData(e){return[...this.items][e]}processVariables(e){var i,s,o,r,d,n,c,a,h;const t={"current-slide":"","total-slides":"","close-svg":((o=(s=(i=this.options)==null?void 0:i.appearance)==null?void 0:s.svg)==null?void 0:o.close)??"","next-svg":((n=(d=(r=this.options)==null?void 0:r.appearance)==null?void 0:d.svg)==null?void 0:n.next)??"","prev-svg":((h=(a=(c=this.options)==null?void 0:c.appearance)==null?void 0:a.svg)==null?void 0:h.prev)??""};for(const[f,x]of Object.entries(t)){const b=e.querySelector(`*[data-glightbox-${f}]`);b&&(b.innerHTML=x)}}registerPlugin(e){this.plugins.has(e.type)||this.plugins.set(e.type,new Map);const t=this.plugins.get(e.type);e.instance=this,t==null||t.set(e.name,e)}initPlugins(){this.pluginsRunEach(e=>{if(typeof e.init=="function"&&e.init(),typeof e.cssStyle=="function"){const t=e==null?void 0:e.cssStyle();this.injectCSS(t)}})}runPluginsMethod(e){this.pluginsRunEach(t=>{if(typeof t[e]=="function"){const i=t[e];typeof i=="function"&&(i==null||i.apply(t))}})}pluginsRunEach(e){for(const[t,i]of this.plugins)for(const[s,o]of i)e(o)}injectCSS(e){if(!e)return;const t=document.createElement("style");t.type="text/css",t.className="gl-css",t.innerText=e,document.head.appendChild(t)}async injectAssets(e){typeof e=="string"&&(e=[e]),e.map(async t=>{let i=t;i=t,await P(i)})}clearAllEvents(e=!1){for(const[t,i]of this.events)!e&&t==="gallery"||(i==null||i.destroy(),this.events.delete(t));e&&this.events.clear(),this.apiEvents.clear()}}exports.GLightbox=z;

@@ -1,208 +0,2 @@

import type { BuildParams } from 'glightbox-plugin';
import { GLightboxPlugin } from 'glightbox-plugin';
declare interface AppearaceOptions {
/**
* Define a custom theme it will
* add a class to the lightbox so you can
* change the appearance with CSS
*
* @default 'clean'
*/
theme?: string;
/**
* Set your own svg icons.
*/
slideEffect?: string | false;
/**
* Set your open effect
*/
openEffect?: string | false;
/**
* More text for descriptions on mobile devices.
*
* @default 'See more'
*/
moreText?: string;
/**
* Number of characters to display on the description before adding
* the moreText link (only for mobiles),
* if 0 it will display the entire description.
*
* @default 60
*/
moreLength?: number;
/**
* Name of the effect on lightbox close. (zoom, fade, none)
*
* @default 'zoom'
*/
closeEffect?: string;
/**
* You can completely change the html of GLightbox.
*/
lightboxHTML?: string;
/**
* You can completely change the html of the individual slide.
*/
slideHTML?: string;
/**
* Set your own svg icons.
*/
svg?: Record<'close' | 'next' | 'prev' | 'loader', string>;
}
export declare class GLightbox {
options: GLightboxOptions;
apiEvents: Set<any>;
events: Map<string, Function>;
state: Map<string, number | boolean | HTMLElement>;
plugins: Map<string, any>;
items: Set<SlideConfig>;
modal: HTMLElement | null;
prevButton: HTMLButtonElement | null;
nextButton: HTMLButtonElement | null;
overlay: HTMLButtonElement | null;
slidesContainer: HTMLElement | null;
constructor(options?: Partial<GLightboxOptions>);
private init;
open(startAt: number | HTMLElement | undefined): void;
prevSlide(): void;
nextSlide(): void;
goToSlide(index?: number): void;
private showSlide;
private setActiveSlideState;
private preloadSlide;
private build;
close(): Promise<void>;
destroy(): void;
reload(): void;
setItems(items: SlideConfig[]): void;
private setItemsFromNode;
private setItemsFromSelector;
getSettings(): GLightboxOptions;
private getElementIndex;
getActiveSlide(): HTMLElement | undefined;
getActiveSlideIndex(): number;
getTotalSlides(): number;
getItems(): Set<SlideConfig>;
updateNavigationButtons(): void;
private setSlideError;
private afterSlideLoaded;
protected on(evt: string, callback: Function, once?: boolean): void;
protected once(evt: string, callback: Function): void;
protected trigger(eventName: string, data?: any): void;
private parseConfigFromNode;
private getRegisteredSlideType;
private getSlideData;
processVariables(node: HTMLElement): void;
protected registerPlugin(plugin: any): void;
protected initPlugins(): void;
protected runPluginsMethod(method: string): void;
pluginsRunEach(callback: Function): void;
protected injectCSS(css: string): void;
injectAssets(urls: string | string[]): Promise<void>;
private clearAllEvents;
}
declare interface GLightboxOptions {
plugins: any[];
/**
* Name of the selector for example '.glightbox' or 'data-glightbox'
* or '*[data-glightbox]'
*
* @default '*[data-glightbox]'
*/
selector?: string;
/**
* Automatically make all items with the same selector a gallery
* if false each item will be displayed individually
*
* @default true
*/
autoGallery?: boolean;
/**
* Name of the effect on lightbox open. (zoom, fade, none)
*
* @default 'zoom'
*/
appearance?: AppearaceOptions;
/**
* Name of the effect on slide change. (slide, fade, zoom, none)
*
* @default 'slide'
*/
slideEffect?: string;
/**
* Close the lightbox when clicking outside the active slide.
*
* @default true
*/
closeOnOutsideClick?: boolean;
/**
* Start lightbox at defined index.
*
* @default 0
*/
startAt?: number;
/**
* Enable or disable preloading.
* If enabled, adjacent slides to the currently displayed will be preloaded
*
* @default true
*/
preload?: boolean;
/**
* Loop slides on end.
*
* @default false
*/
loop?: boolean;
/**
* List of custom data attributes
* you can define custom data attributes
* so they get parsed and you can use them
* in the slide
*
* @default []
*/
customDataAttributes?: string[];
/**
* Custom prefix for data attributes
* so instead of data-url you can define
* data-prefix-url
*
* @default ''
*/
dataAttributesPrefix?: string;
}
declare interface ImageOptions {
maxWidth?: string;
matchFn?: Function;
}
export declare class ImageSlide extends GLightboxPlugin {
name: string;
type: string;
options: ImageOptions;
defaults: ImageOptions;
constructor(options?: Partial<ImageOptions>);
match(url: string): boolean;
build({ index, slide, config }: BuildParams): Promise<boolean>;
cssStyle(): string;
}
declare interface SlideConfig {
node?: Element | null;
url: string;
thumbnail?: string;
title?: string;
description?: string;
html?: boolean;
zoomable?: boolean;
draggable?: boolean;
[key: string]: any;
}
export { }
export { default as GLightbox } from './glightbox';
export * from './types';

@@ -1,6 +0,497 @@

import { default as o } from "./glightbox.es.js";
import { default as f } from "./ImageSlide.es.js";
const C = (l, ...e) => {
if (!e.length)
return l;
const t = e.shift();
return t === void 0 ? l : (E(l) && E(t) && Object.keys(t).forEach(function(i) {
E(t[i]) ? (l[i] || (l[i] = {}), C(l[i], t[i])) : l[i] = t[i];
}), C(l, ...e));
};
function f(l, e) {
l.classList.add(...e.split(" "));
}
function v(l, e) {
l.classList.remove(...e.split(" "));
}
function w(l, e) {
return l.classList.contains(e);
}
function S(l, {
element: e,
callback: t,
preventDefault: i = !0,
once: s = !1,
useCapture: o = !1
}, r) {
let d = [];
const n = t.toString().trim().replace(/\s/g, ""), c = typeof e == "string";
if (!c)
d = [e];
else if (c) {
const h = document.querySelectorAll(e);
h && (d = [...h]);
}
const a = function(h) {
typeof t == "function" && (i && h.preventDefault(), t.call(r, this, h)), s && a.destroy();
};
return a.destroy = function() {
d.forEach((h) => {
h == null || h.removeEventListener(l, a, o);
});
}, d.forEach((h) => {
h && h.attachedEvent !== n && (h.addEventListener(l, a, o), h.attachedEvent = n);
}), a;
}
function H(l, e) {
return new Promise((t) => {
l.addEventListener("animationend", () => {
t(!0);
}), f(l, e);
});
}
function P(l) {
return new Promise((e, t) => {
l || t("url must be defined");
let i = "";
typeof l != "string" ? i = l.src : i = l;
let s;
if ((i.includes(".css") ? "css" : "js") == "css") {
if (s = document.querySelectorAll('link[href="' + i + '"]'), s && s.length > 0) {
e(!0);
return;
}
const r = document.getElementsByTagName("head")[0], d = r.querySelectorAll('link[rel="stylesheet"]'), n = document.createElement("link");
n.rel = "stylesheet", n.type = "text/css", n.href = i, n.media = "all", d ? r.insertBefore(n, d[0]) : r.appendChild(n), e(!0);
return;
}
if (s = document.querySelectorAll('script[src="' + i + '"]'), s && s.length > 0) {
e(!0);
return;
}
const o = document.createElement("script");
o.type = "text/javascript", o.src = i, typeof l != "string" && l != null && l.module && (o.type = "module"), o.onload = () => {
e(!0);
}, document.body.appendChild(o);
});
}
function $(l) {
return !!(l && l.nodeType && l.nodeType == 1);
}
const j = (l) => l !== null && typeof l == "object", E = (l) => j(l) && !Array.isArray(l), D = {
root: null,
autoGallery: !0,
setClickEvent: !0,
dataAttributesPrefix: "",
items: [],
plugins: [],
appearance: {
slideEffect: "fade",
openEffect: "zoom",
moreText: "See more",
moreLength: 60,
lightboxHTML: `<div id="gl-body" class="gl-lightbox gl-container" tabindex="0" role="dialog" aria-hidden="false">
<div id="gl-slider" class="gl-slider"></div>
<button class="gl-close gl-btn" aria-label="Close" tabindex="3" aria-hidden="false" data-glightbox-close-svg></button>
<button class="gl-next gl-btn" aria-label="Next" tabindex="1" aria-hidden="false" data-glightbox-next-svg></button>
<button class="gl-prev gl-btn" aria-label="Previous" tabindex="2" aria-hidden="false" data-glightbox-prev-svg></button>
<div class="gl-overlay"></div>
</div>`,
slideHTML: "",
svg: {
close: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" xml:space="preserve"><g><g><path d="M505.943,6.058c-8.077-8.077-21.172-8.077-29.249,0L6.058,476.693c-8.077,8.077-8.077,21.172,0,29.249C10.096,509.982,15.39,512,20.683,512c5.293,0,10.586-2.019,14.625-6.059L505.943,35.306C514.019,27.23,514.019,14.135,505.943,6.058z"/></g></g><g><g><path d="M505.942,476.694L35.306,6.059c-8.076-8.077-21.172-8.077-29.248,0c-8.077,8.076-8.077,21.171,0,29.248l470.636,470.636c4.038,4.039,9.332,6.058,14.625,6.058c5.293,0,10.587-2.019,14.624-6.057C514.018,497.866,514.018,484.771,505.942,476.694z"/></g></g></svg>',
next: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 477.175 477.175" xml:space="preserve"> <g><path d="M360.731,229.075l-225.1-225.1c-5.3-5.3-13.8-5.3-19.1,0s-5.3,13.8,0,19.1l215.5,215.5l-215.5,215.5c-5.3,5.3-5.3,13.8,0,19.1c2.6,2.6,6.1,4,9.5,4c3.4,0,6.9-1.3,9.5-4l225.1-225.1C365.931,242.875,365.931,234.275,360.731,229.075z"/></g></svg>',
prev: '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 477.175 477.175" xml:space="preserve"><g><path d="M145.188,238.575l215.5-215.5c5.3-5.3,5.3-13.8,0-19.1s-13.8-5.3-19.1,0l-225.1,225.1c-5.3,5.3-5.3,13.8,0,19.1l225.1,225c2.6,2.6,6.1,4,9.5,4s6.9-1.3,9.5-4c5.3-5.3,5.3-13.8,0-19.1L145.188,238.575z"/></g></svg>',
loader: '<svg aria-hidden="true" class="w-8 h-8 mr-2 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/><path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/></svg>'
}
},
startAt: 0,
customDataAttributes: [],
preload: !0,
loop: !0,
closeOnOutsideClick: !0
};
class z {
constructor(e = {}) {
var i;
this.apiEvents = /* @__PURE__ */ new Set(), this.events = /* @__PURE__ */ new Map(), this.state = /* @__PURE__ */ new Map(), this.plugins = /* @__PURE__ */ new Map(), this.items = /* @__PURE__ */ new Set(), this.modal = null, this.prevButton = null, this.nextButton = null, this.overlay = null, this.slidesContainer = null, this.options = C(D, e);
const t = window.matchMedia("(prefers-reduced-motion: reduce)");
(!t || t.matches) && ((i = this.options.appearance) != null && i.slideEffect) && (this.options.appearance.slideEffect = !1, this.options.appearance.openEffect = !1), this.init();
}
init(e = !0) {
if (e)
for (const t of this.options.plugins)
this.registerPlugin(t);
this.options.setClickEvent && this.events.set("gallery", S("click", {
element: "*[data-glightbox]",
callback: (t) => {
this.open(t);
}
}));
}
open(e) {
var i;
if (this.state.get("open"))
return;
if (!this.plugins.has("slide"))
throw new Error("No slide types registered");
this.items.size === 0 && $(e) && this.setItemsFromNode(e);
let t = this.options.startAt;
this.options.autoGallery ? typeof e == "number" ? t = e : $(e) && (t = this.getElementIndex(e)) : t = 0, this.state.set("focused", document.activeElement), this.build(), this.trigger("before_open"), this.initPlugins(), this.showSlide(t, !0), this.trigger("open"), this.state.set("open", !0), (i = this.modal) == null || i.focus(), f(document.body, "gl-open");
}
prevSlide() {
this.goToSlide(this.getActiveSlideIndex() - 1);
}
nextSlide() {
this.goToSlide(this.getActiveSlideIndex() + 1);
}
goToSlide(e = 0) {
const t = this.getTotalSlides() - 1;
!this.options.loop && (e < 0 || e > this.getTotalSlides() - 1) || (e < 0 ? e = t : e > t && (e = 0), this.showSlide(e));
}
async showSlide(e = 0, t = !1) {
var c, a, h, p;
const i = (c = this.slidesContainer) == null ? void 0 : c.querySelector(".current");
i && v(i, "current");
const s = (a = this.slidesContainer) == null ? void 0 : a.querySelectorAll(".gl-slide")[e];
console.log("GLightbox > showSlide > slideNode", s);
const o = s.querySelector(".gl-media");
if (!s || !o)
return;
t || this.trigger("slide_before_change", { current: this.state.get("prevActiveSlideIndex"), next: e }), await this.preloadSlide(e, !t);
const r = (h = this.options.appearance) == null ? void 0 : h.slideEffect, d = (p = this.options.appearance) == null ? void 0 : p.openEffect, n = r !== "slide" || t ? "instant" : "smooth";
s.scrollIntoView({ behavior: n, block: "start", inline: "start" }), v(o, "gl-animation-ended"), t && d ? (f(o, "gl-invisible"), d && await H(o, `gl-${d}-in`), f(o, "gl-animation-ended"), v(o, `gl-invisible gl-${d}-in`)) : v(o, "gl-invisible"), this.setActiveSlideState(s, e), this.trigger("slide_changed", { prev: this.state.get("prevActiveSlideIndex"), current: e }), this.options.preload && (this.preloadSlide(e + 1), this.preloadSlide(e - 1));
}
setActiveSlideState(e, t) {
this.state.set("prevActiveSlide", this.state.get("activeSlide") ?? !1), this.state.set("prevActiveSlideIndex", this.getActiveSlideIndex()), this.state.set("activeSlide", e), this.state.set("activeSlideIndex", t), this.updateNavigationButtons();
}
async preloadSlide(e, t = !0) {
var n, c;
if (e < 0 || e > this.items.size - 1)
return !1;
const i = (n = this.slidesContainer) == null ? void 0 : n.querySelectorAll(".gl-slide")[e];
if (i && (w(i, "loaded") || w(i, "preloading")))
return !0;
const s = this.getSlideData(e), o = s == null ? void 0 : s.type, r = this.getRegisteredSlideType(o);
let d = "";
if ((!o || !r) && (d = `Unable to handle URL: ${s == null ? void 0 : s.url}`), d)
throw this.setSlideError(i, d), new Error(d);
if (s != null && s.url && r && i && (r != null && r.build)) {
f(i, "preloading");
try {
this.trigger("slide_before_load", s), await r.build({
index: e,
slide: i.querySelector(".gl-media"),
config: { ...s, isPreload: t }
}), (c = i.querySelector(".gl-slide-loader")) == null || c.remove(), this.afterSlideLoaded(i);
const a = i.querySelector(".gl-media");
return a && (f(a, `gl-type-${o}`), t && v(a, "gl-invisible")), i;
} catch (a) {
this.afterSlideLoaded(i), this.setSlideError(i, a);
}
}
return !1;
}
build() {
var d, n, c, a, h, p, x, b, A, k, L, I, M, T, q, B;
if (this.state.get("build"))
return;
this.trigger("before_build");
const e = document.body.querySelectorAll(":scope > *");
e && [...e].forEach((u) => {
u.parentNode == document.body && u.nodeName.charAt(0) !== "#" && u.hasAttribute && !u.hasAttribute("aria-hidden") && (u.ariaHidden = "true", u.dataset.glHidden = "true");
});
const t = ((d = this.options) == null ? void 0 : d.root) ?? document.body, i = ((c = (n = this.options) == null ? void 0 : n.appearance) == null ? void 0 : c.lightboxHTML) ?? "";
if (t.insertAdjacentHTML("beforeend", i), this.modal = document.getElementById("gl-body"), !this.modal)
throw new Error("modal body not found");
const s = this.modal.querySelector(".gl-close");
if (this.prevButton = this.modal.querySelector(".gl-prev"), this.nextButton = this.modal.querySelector(".gl-next"), this.overlay = this.modal.querySelector(".gl-overlay"), this.slidesContainer = document.getElementById("gl-slider"), f(this.modal, "gl-theme-" + (((h = (a = this.options) == null ? void 0 : a.appearance) == null ? void 0 : h.theme) ?? "base")), f(this.modal, "gl-slide-effect-" + (((x = (p = this.options) == null ? void 0 : p.appearance) == null ? void 0 : x.slideEffect) || "none")), (A = (b = this.options) == null ? void 0 : b.appearance) != null && A.cssVariables)
for (const [u, g] of Object.entries(this.options.appearance.cssVariables))
this.modal.style.setProperty(`--gl-${u}`, g);
s && this.events.set("close", S("click", {
element: s,
callback: () => this.close()
})), this.nextButton && this.events.set("next", S("click", {
element: this.nextButton,
callback: () => this.nextSlide()
})), this.prevButton && this.events.set("prev", S("click", {
element: this.prevButton,
callback: () => this.prevSlide()
})), this.options.closeOnOutsideClick && this.events.set("outClose", S("click", {
element: this.modal,
callback: (u, g) => {
var m;
u && (g != null && g.target) && !((m = g == null ? void 0 : g.target) != null && m.closest(".gl-media")) && (g.target.closest(".gl-btn") || this.close());
}
})), this.processVariables(this.modal);
const o = new IntersectionObserver((u) => {
u.forEach((g) => {
var m;
if (v(g.target, "visible"), g.isIntersecting && this.state.get("open")) {
const y = parseInt(((m = g.target) == null ? void 0 : m.getAttribute("data-index")) ?? "0");
f(g.target, "visible"), y !== this.state.get("activeSlideIndex") && this.setActiveSlideState(g.target, y), !w(g.target, "loaded") && !w(g.target, "preloading") && (this.preloadSlide(y), this.preloadSlide(y + 1), this.preloadSlide(y - 1));
}
});
}, {
root: this.modal,
rootMargin: "0px",
threshold: 0.2
});
let r = 0;
console.log("this.items", this.items);
for (const u of this.items) {
const g = this.getRegisteredSlideType(u == null ? void 0 : u.type);
if (console.log("GLightbox > build > slideType", g), u != null && u.url && g) {
let m = (L = (k = this.options) == null ? void 0 : k.appearance) == null ? void 0 : L.slideHTML;
const y = (T = (M = (I = this.options) == null ? void 0 : I.appearance) == null ? void 0 : M.svg) == null ? void 0 : T.loader;
m || (m = `<div class="gl-slide" data-index="${r}" style="--gl-index: ${r}">
<div class="gl-slide-loader" role="status">
${y}
<span class="gl-sr-only">Loading...</span>
</div>
<div class="gl-media gl-invisible">
</div>
</div>`), (q = this.slidesContainer) == null || q.insertAdjacentHTML("beforeend", m);
const N = (B = this.slidesContainer) == null ? void 0 : B.querySelectorAll(".gl-slide")[r];
N && o.observe(N), r++;
}
}
this.overlay && f(this.overlay, "gl-overlay-in"), this.state.set("build", !0), this.trigger("build");
}
async close() {
var s, o, r, d;
if (!this.state.get("open") || !this.modal)
return;
this.runPluginsMethod("destroy"), v(document.body, "gl-open gl-crollbar-fixer");
const e = document.querySelectorAll('*[data-gl-hidden="true"]');
if (e && e.forEach((n) => {
n.ariaHidden = "false", delete n.dataset.glHidden;
}), ((s = this.options.appearance) == null ? void 0 : s.slideEffect) === "none")
(o = this.modal.parentNode) == null || o.removeChild(this.modal);
else {
const c = this.state.get("activeSlide").querySelector(".gl-media"), a = (r = this.options.appearance) == null ? void 0 : r.openEffect;
c && (f(this.modal, "gl-closing"), a && (v(c, "gl-animation-ended"), await H(c, `gl-${a}-out`))), (d = this.modal.parentNode) == null || d.removeChild(this.modal);
}
this.state.clear(), this.modal = null, this.prevButton = null, this.nextButton = null, this.clearAllEvents(), this.setItems([]);
const t = document.querySelectorAll(".gl-css");
t && t.forEach((n) => {
var c;
return (c = n == null ? void 0 : n.parentNode) == null ? void 0 : c.removeChild(n);
}), this.trigger("close");
const i = this.state.get("focused");
i == null || i.focus();
}
destroy() {
this.close(), this.clearAllEvents(!0);
}
reload() {
this.init(!1);
}
setItems(e) {
var i, s;
if (!e || (this.items = /* @__PURE__ */ new Set(), !e.length))
return;
const t = this.plugins.get("slide");
if (!t)
throw new Error("No slide types registered");
for (const o of e) {
if (o != null && o.type) {
if (!t.has(o.type))
throw new Error(`Unknown slide type: ${o.type}`);
continue;
}
let r = !1;
for (const [d, n] of t) {
if (n.name === "iframe") {
r = n;
continue;
}
let c = !1;
if (n != null && n.match && n.match(o.url.toLowerCase()) && (o.type = d, c = !0), n != null && n.options && typeof ((i = n.options) == null ? void 0 : i.matchFn) == "function" && (s = n.options) != null && s.matchFn(o.url.toLowerCase()) && (o.type = d, c = !0), c)
break;
}
o != null && o.type || r && (o.type = r.name), this.getItems().add(o);
}
}
setItemsFromNode(e) {
if (!this.options.autoGallery) {
this.setItems([this.parseConfigFromNode(e)]);
return;
}
let t = "*[data-glightbox]";
const i = e.getAttribute("data-glightbox");
i && (t = `*[data-glightbox="${i}"]`);
const s = document.querySelectorAll(t);
if (!s)
return;
const o = [];
[...s].forEach((r) => {
const d = this.parseConfigFromNode(r);
o.push(d);
}), this.setItems(o);
}
getSettings() {
return this.options;
}
getElementIndex(e) {
let t = 0, i = 0;
for (const s of this.items) {
if ((s == null ? void 0 : s.node) === e) {
t = i;
break;
}
i++;
}
return t;
}
getActiveSlide() {
if (this.state.has("activeSlide"))
return this.state.get("activeSlide");
}
getActiveSlideIndex() {
return this.state.has("activeSlideIndex") ? this.state.get("activeSlideIndex") : 0;
}
getTotalSlides() {
return this.items.size;
}
getItems() {
return this.items;
}
updateNavigationButtons() {
if (this.items.size === 1) {
this.modal && f(this.modal, "gl-single-slide");
return;
}
if (!this.nextButton || !this.prevButton)
return;
const e = this.options.loop, t = this.getActiveSlideIndex(), i = this.getTotalSlides() - 1;
this.prevButton.disabled = !1, this.nextButton.disabled = !1, t === 0 && !e ? this.prevButton.disabled = !0 : t === i && !e && (this.nextButton.disabled = !0);
}
setSlideError(e, t) {
var s;
(s = e.querySelector(".gl-slide-loader")) == null || s.remove();
const i = e.querySelector(".gl-media");
i && (f(i, "gl-load-error"), v(i, "gl-invisible"), i.innerHTML = `<div class="gl-error">${t}</div>`);
}
afterSlideLoaded(e) {
f(e, "loaded"), v(e, "preloading");
}
on(e, t, i = !1) {
if (!e || typeof t != "function")
throw new TypeError("Event name and callback must be defined");
this.apiEvents.add({ evt: e, once: i, callback: t });
}
once(e, t) {
this.on(e, t, !0);
}
trigger(e, t = null) {
for (const i of this.apiEvents) {
const { evt: s, once: o, callback: r } = i;
s === e && (r(t), o && this.apiEvents.delete(i));
}
}
parseConfigFromNode(e) {
var r, d, n, c;
const t = {
node: null,
url: "",
title: "",
description: "",
width: "",
height: "",
content: "",
type: ""
};
let i = "";
const s = { url: "", type: "" }, o = e.nodeName.toLowerCase();
o === "a" && (i = e.getAttribute("href") || ""), o === "img" && (i = e.getAttribute("src") || ""), o === "figure" && (i = ((r = e.querySelector("img")) == null ? void 0 : r.getAttribute("src")) || ""), s.node = e, s.url = i;
for (const a in t) {
let h = "data";
(d = this.options) != null && d.dataAttributesPrefix && (h += `-${(n = this.options) == null ? void 0 : n.dataAttributesPrefix}`);
let p = e.getAttribute(`${h}-${a}`);
p && ((p === "true" || p === "false") && (p = p === "true"), s[a] = p);
}
if (!s.title) {
const a = e == null ? void 0 : e.getAttribute("title");
a && (s.title = a);
}
if (s != null && s.description && s.description.startsWith(".")) {
const a = (c = document.querySelector(s.description)) == null ? void 0 : c.innerHTML;
a && (s.description = a);
}
if (!s.description) {
const a = e.querySelector(".gl-inline-desc");
a && (s.description = a.innerHTML);
}
return s;
}
getRegisteredSlideType(e) {
if (this.plugins.has("slide")) {
const t = this.plugins.get("slide");
if (t && t.has(e))
return t.get(e);
}
return !1;
}
getSlideData(e) {
return [...this.items][e];
}
processVariables(e) {
var i, s, o, r, d, n, c, a, h;
const t = {
"current-slide": "",
"total-slides": "",
"close-svg": ((o = (s = (i = this.options) == null ? void 0 : i.appearance) == null ? void 0 : s.svg) == null ? void 0 : o.close) ?? "",
"next-svg": ((n = (d = (r = this.options) == null ? void 0 : r.appearance) == null ? void 0 : d.svg) == null ? void 0 : n.next) ?? "",
"prev-svg": ((h = (a = (c = this.options) == null ? void 0 : c.appearance) == null ? void 0 : a.svg) == null ? void 0 : h.prev) ?? ""
};
for (const [p, x] of Object.entries(t)) {
const b = e.querySelector(`*[data-glightbox-${p}]`);
b && (b.innerHTML = x);
}
}
registerPlugin(e) {
this.plugins.has(e.type) || this.plugins.set(e.type, /* @__PURE__ */ new Map());
const t = this.plugins.get(e.type);
e.instance = this, t == null || t.set(e.name, e);
}
initPlugins() {
this.pluginsRunEach((e) => {
if (typeof e.init == "function" && e.init(), typeof e.cssStyle == "function") {
const t = e == null ? void 0 : e.cssStyle();
this.injectCSS(t);
}
});
}
runPluginsMethod(e) {
this.pluginsRunEach((t) => {
if (typeof t[e] == "function") {
const i = t[e];
typeof i == "function" && (i == null || i.apply(t));
}
});
}
pluginsRunEach(e) {
for (const [t, i] of this.plugins)
for (const [s, o] of i)
e(o);
}
injectCSS(e) {
if (!e)
return;
const t = document.createElement("style");
t.type = "text/css", t.className = "gl-css", t.innerText = e, document.head.appendChild(t);
}
async injectAssets(e) {
typeof e == "string" && (e = [e]), e.map(async (t) => {
let i = t;
i = t, await P(i);
});
}
clearAllEvents(e = !1) {
for (const [t, i] of this.events)
!e && t === "gallery" || (i == null || i.destroy(), this.events.delete(t));
e && this.events.clear(), this.apiEvents.clear();
}
}
export {
o as GLightbox,
f as ImageSlide
z as GLightbox
};
{
"name": "glightbox",
"version": "4.0.0-beta.2",
"description": "Beautiful Javascript lightbox with image, video, iframes and inline content support",
"scripts": {
"dev": "vite",
"watch": "vite build --watch",
"build": "tsc && vite build && node vite.build.umd.js",
"preview": "vite preview"
},
"author": "Biati Digital",
"keywords": [
"lightbox",
"javascript",
"gallery",
"popup"
],
"license": "MIT",
"version": "4.0.0-beta.3",
"description": "Beautiful Pure Javascript Lightbox",
"homepage": "https://biati-digital.github.io/glightbox/",

@@ -24,10 +10,11 @@ "repository": {

},
"bugs": "https://github.com/biati-digital/glightbox/issues",
"type": "module",
"files": [
"dist"
],
"main": "./dist/glightbox.cjs.js",
"module": "./dist/glightbox.es.js",
"types": "./dist/glightbox.d.ts",
"main": "./dist/index.cjs.js",
"import": "./dist/index.es.js",
"scripts": {
"dev": "vite",
"watch": "vite build --watch",
"build": "tsc && vite build",
"preview": "vite preview"
},
"exports": {

@@ -39,32 +26,7 @@ ".": {

},
"./plugins": {
"import": "./dist/plugins.es.js",
"require": "./dist/plugins.cjs.js",
"types": "./dist/plugins.d.ts"
"./src": {
"import": "./src/index.ts",
"require": "./src/index.ts",
"types": "./src/index.ts"
},
"./ImageSlide": {
"import": "./dist/ImageSlide.es.js",
"require": "./dist/ImageSlide.cjs.js",
"types": "./dist/ImageSlide.d.ts"
},
"./IframeSlide": {
"import": "./dist/IframeSlide.es.js",
"require": "./dist/IframeSlide.cjs.js",
"types": "./dist/IframeSlide.d.ts"
},
"./VideoSlide": {
"import": "./dist/VideoSlide.es.js",
"require": "./dist/VideoSlide.cjs.js",
"types": "./dist/VideoSlide.d.ts"
},
"./DragNavigation": {
"import": "./dist/DragNavigation.es.js",
"require": "./dist/DragNavigation.cjs.js",
"types": "./dist/DragNavigation.d.ts"
},
"./KeyboardNavigation": {
"import": "./dist/KeyboardNavigation.es.js",
"require": "./dist/KeyboardNavigation.cjs.js",
"types": "./dist/KeyboardNavigation.d.ts"
},
"./style": {

@@ -75,12 +37,27 @@ "import": "./dist/glightbox.css",

},
"devDependencies": {
"@types/node": "^20.8.0",
"fast-glob": "^3.3.2",
"typescript": "^5.0.2",
"vite": "^5.1.6",
"vite-plugin-dts": "^3.6.0"
"directories": {
"src": "src"
},
"files": [
"dist",
"src"
],
"keywords": [
"lightbox",
"javascript",
"gallery",
"popup"
],
"author": "Biati Digital",
"publishConfig": {
"access": "public"
},
"license": "GPLV3",
"dependencies": {
"glightbox-plugin": "^0.0.1"
"@glightbox/utils": "1.0.0-beta.1",
"@glightbox/plugin-core": "1.0.0-beta.1"
},
"devDependencies": {
"vite-plugin-static-copy": "^1.0.1"
}
}

@@ -1,705 +0,11 @@

# GLightbox
# glightbox
GLightbox is a pure javascript lightbox. It can display images, iframes, inline content and videos with optional autoplay for YouTube, Vimeo and even self hosted videos.
This package is the core of the library.
## Features
## Installation
- **Small** - only 11KB Gzipped
- **Fast and Responsive** - works with any screen size
- **Gallery Support** - Create multiple galleries
- **Response Images Support** - Let the browser use the optimal image for the current screen resolution
- **Video Support** - Youtube, Vimeo and self hosted videos with autoplay
- **Inline content support** - display any inline content
- **Iframe support** - need to embed an iframe? no problem
- **Keyboard Navigation** - esc, arrows keys, tab and enter is all you need
- **Touch Navigation** - mobile touch events
- **Zoomable images** - zoom and drag images on mobile and desktop
- **API** - control the lightbox with the provided methods
- **Themeable** - create your skin or modify the animations with some minor css changes
`npm i glightbox@beta`
## Live Demo
## Options and usage
You can check the live demo [right here](https://biati-digital.github.io/glightbox/)
## Usage
```bash
$ npm install glightbox
# OR
$ yarn add glightbox
# OR
$ bower install glightbox
```
```javascript
// Using ESM specification
import '/path/to/glightbox.js';
// Using a bundler like webpack
import GLightbox from 'glightbox';
```
Or manually download and link `glightbox.min.js` in your HTML:
```html
<link rel="stylesheet" href="dist/css/glightbox.css" />
<script src="dist/js/glightbox.min.js"></script>
<!-- USING A CDN -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/glightbox/dist/css/glightbox.min.css" />
<script src="https://cdn.jsdelivr.net/gh/mcstudios/glightbox/dist/js/glightbox.min.js"></script>
<script type="text/javascript">
const lightbox = GLightbox({ ...options });
</script>
<!-- USING ES MODULES -->
<script type="module">
import 'https://cdn.jsdelivr.net/gh/mcstudios/glightbox/dist/js/glightbox.min.js';
const lightbox = GLightbox({ ...options });
</script>
```
## Examples
```html
<!-- Simple image -->
<a href="large.jpg" class="glightbox">
<img src="small.jpg" alt="image" />
</a>
<!-- Video -->
<a href="https://vimeo.com/115041822" class="glightbox2">
<img src="small.jpg" alt="image" />
</a>
<!-- Gallery -->
<a href="large.jpg" class="glightbox3" data-gallery="gallery1">
<img src="small.jpg" alt="image" />
</a>
<a href="video.mp4" class="glightbox3" data-gallery="gallery1">
<img src="small.jpg" alt="image" />
</a>
<!-- Simple Description -->
<a href="large.jpg" class="glightbox4" data-glightbox="title: My title; description: this is the slide description">
<img src="small.jpg" alt="image" />
</a>
<!-- Advanced Description -->
<a href="large.jpg" class="glightbox5" data-glightbox="title: My title; description: .custom-desc1">
<img src="small.jpg" alt="image" />
</a>
<div class="glightbox-desc custom-desc1">
<p>The content of this div will be used as the slide description</p>
<p>You can add links and any HTML you want</p>
</div>
<!-- URL with no extension -->
<a href="https://picsum.photos/1200/800" data-glightbox="type: image">
<img src="small.jpg" alt="image" />
</a>
<!-- OR using multiple data attributes -->
<a href="https://picsum.photos/1200/800" data-type="image">
<img src="small.jpg" alt="image" />
</a>
<!-- Using responsive images: specify sizes and srcset through data attributes in the
same way you would with the img tag.
See: https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images -->
<a href="deafult.jpg" class="glightbox6" data-title="Responsive example"
data-description="Your browser will choose the optimal image for the resolution"
data-sizes="(max-width: 600px) 480px, 800px"
data-srcset="img480.jpx 480w img800.jpg 800w">
<img src="small.jpg" alt="image" />
</a>
```
## Slide Options
You can specify some options to each individual slide, the available options are:
- title
- alt
- description
- descPosition
- type
- effect
- width
- height
- zoomable
- draggable
```html
<!-- One line config -->
<a href="large.jpg" data-glightbox="title: Your title; description: description here; descPosition: left; type: image; effect: fade; width: 900px; height: auto; zoomable: true; draggable: true;"></a>
<!-- Multiple data attributes / You can use the options as separated data attributes -->
<a
href="large.jpg"
data-title="My title"
data-description="description here"
data-desc-position="right"
data-type="image"
data-effect="fade"
data-width="900px"
data-height="auto"
data-zoomable="true"
data-draggable="true"
></a>
```
## Lightbox Options
Example use of the options.
```javascript
const lightbox = GLightbox({
touchNavigation: true,
loop: true,
autoplayVideos: true
});
// Instead of using a selector, define the gallery elements
const myGallery = GLightbox({
elements: [
{
'href': 'https://picsum.photos/1200/800',
'type': 'image',
'title': 'My Title',
'description': 'Example',
},
{
'href': 'https://picsum.photos/1200/800',
'type': 'image',
'alt': 'image text alternatives'
},
{
'href': 'https://www.youtube.com/watch?v=Ga6RYejo6Hk',
'type': 'video',
'source': 'youtube', //vimeo, youtube or local
'width': 900,
},
{
'content': '<p>This will append some html inside the slide</p>' // read more in the API section
},
{
'content': document.getElementById('inline-example') // this will append a node inside the slide
},
],
autoplayVideos: true,
});
myGallery.open();
// If later you need to modify the elements you can use setElements
myGallery.setElements([...]);
```
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| selector | string | `.glightbox` | Name of the selector for example '.glightbox' or 'data-glightbox' or '\*[data-glightbox]' |
| elements | array | `null` | Instead of passing a selector you can pass all the items that you want in the gallery. |
| skin | string | `clean` | Name of the skin, it will add a class to the lightbox so you can style it with css. |
| openEffect | string | `zoom` | Name of the effect on lightbox open. (zoom, fade, none) |
| closeEffect | string | `zoom` | Name of the effect on lightbox close. (zoom, fade, none) |
| slideEffect | string | `slide` | Name of the effect on slide change. (slide, fade, zoom, none) |
| moreText | string | `See more` | More text for descriptions on mobile devices. |
| moreLength | number | `60` | Number of characters to display on the description before adding the moreText link (only for mobiles), if 0 it will display the entire description. |
| closeButton | boolean | `true` | Show or hide the close button. |
| touchNavigation | boolean | `true` | Enable or disable the touch navigation (swipe). |
| touchFollowAxis | boolean | `true` | Image follow axis when dragging on mobile. |
| keyboardNavigation | boolean | `true` | Enable or disable the keyboard navigation. |
| closeOnOutsideClick | boolean | `true` | Close the lightbox when clicking outside the active slide. |
| startAt | number | `0` | Start lightbox at defined index. |
| width | number | `900px` | Default width for inline elements and iframes, you can define a specific size on each slide. You can use any unit for example 90% or 100vw for full width |
| height | number | `506px` | Default height for inline elements and iframes, you can define a specific size on each slide.You can use any unit for example 90% or 100vh **For inline elements you can set the height to auto**. |
| videosWidth | number | `960px` | Default width for videos. Videos are responsive so height is not required. The width can be in px % or even vw for example, 500px, 90% or 100vw for full width videos |
| descPosition | string | `bottom` | Global position for slides description, you can define a specific position on each slide (bottom, top, left, right). |
| loop | boolean | `false` | Loop slides on end. |
| zoomable | boolean | `true` | Enable or disable zoomable images you can also use data-zoomable="false" on individual nodes. |
| draggable | boolean | `true` | Enable or disable mouse drag to go prev and next slide (only images and inline content), you can also use data-draggable="false" on individual nodes. |
| dragToleranceX | number | `40` | Used with draggable. Number of pixels the user has to drag to go to prev or next slide. |
| dragToleranceY | number | `65` | Used with draggable. Number of pixels the user has to drag up or down to close the lightbox (Set 0 to disable vertical drag). |
| dragAutoSnap | boolean | `false` | If true the slide will automatically change to prev/next or close if dragToleranceX or dragToleranceY is reached, otherwise it will wait till the mouse is released. |
| preload | boolean | `true` | Enable or disable preloading. |
| svg | object | `{}` | Set your own svg icons. |
| cssEfects | object | 'See animations' | Define or adjust lightbox animations. See the Animations section in the README. |
| lightboxHTML | string | 'See themes' | You can completely change the html of GLightbox. See the Themeable section in the README. |
| slideHTML | string | 'See themes' | You can completely change the html of the individual slide. See the Themeable section in the README. |
| autoplayVideos | boolean | `true` | Autoplay videos on open. |
| autofocusVideos | boolean | `false` | If true video will be focused on play to allow keyboard sortcuts for the player, this will deactivate prev and next arrows to change slide so use it only if you know what you are doing. |
| plyr | object | `{}` | [View video player options.](#video-player) |
## Events
You can listen for events using your GLightbox instance (see example under the table). You can use the on() API method or once().
```javascript
const lightbox = GLightbox();
lightbox.on('open', () => {
// Do something
});
lightbox.once('slide_changed', () => {
// Do something just one time
});
```
| Event Type | Description |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| open | Provide a function when the lightbox is opened. |
| close | Provide a function when the lightbox is closed. |
| slide_before_change | Trigger a function before the slide is changed. |
| slide_changed | Trigger a function after the slide is changed. |
| slide_before_load | Trigger a function before a slide is loaded for the first time, the function will only be called once |
| slide_after_load | Trigger a function after a slide is loaded and it's content is set for the first time, the function will only be called once |
| slide_inserted | Trigger a function after a slide is inserted using insertSlide. |
| slide_removed | Trigger a function after a slide is removed` |
```javascript
const lightbox = GLightbox();
lightbox.on('slide_before_change', ({ prev, current }) => {
console.log('Prev slide', prev);
console.log('Current slide', current);
// Prev and current are objects that contain the following data
const { slideIndex, slideNode, slideConfig, player, trigger } = current;
// slideIndex - the slide index
// slideNode - the node you can modify
// slideConfig - will contain the configuration of the slide like title, description, etc.
// player - the slide player if it exists otherwise will return false
// trigger - this will contain the element that triggers this slide, this can be a link, a button, etc in your HTML, it can be null if the elements in the gallery were set dinamically
});
lightbox.on('slide_changed', ({ prev, current }) => {
console.log('Prev slide', prev);
console.log('Current slide', current);
// Prev and current are objects that contain the following data
const { slideIndex, slideNode, slideConfig, player, trigger } = current;
// slideIndex - the slide index
// slideNode - the node you can modify
// slideConfig - will contain the configuration of the slide like title, description, etc.
// player - the slide player if it exists otherwise will return false
// trigger - this will contain the element that triggers this slide, this can be a link, a button, etc in your HTML, it can be null if the elements in the gallery were set dinamically
if (player) {
if (!player.ready) {
// If player is not ready
player.on('ready', (event) => {
// Do something when video is ready
});
}
player.on('play', (event) => {
console.log('Started play');
});
player.on('volumechange', (event) => {
console.log('Volume change');
});
player.on('ended', (event) => {
console.log('Video ended');
});
}
});
// Useful to modify the slide
// before it's content is added
lightbox.on('slide_before_load', (data) => {
// data is an object that contain the following
const { slideIndex, slideNode, slideConfig, player, trigger } = data;
// slideIndex - the slide index
// slideNode - the node you can modify
// slideConfig - will contain the configuration of the slide like title, description, etc.
// player - the slide player if it exists otherwise will return false
// trigger - this will contain the element that triggers this slide, this can be a link, a button, etc in your HTML, it can be null if the elements in the gallery were set dinamically
});
// Useful to execute scripts that depends
// on the slide to be ready with all it's content
// and already has a height
// data will contain all the info about the slide
lightbox.on('slide_after_load', (data) => {
// data is an object that contain the following
const { slideIndex, slideNode, slideConfig, player, trigger } = data;
// slideIndex - the slide index
// slideNode - the node you can modify
// slideConfig - will contain the configuration of the slide like title, description, etc.
// player - the slide player if it exists otherwise will return false
// trigger - this will contain the element that triggers this slide, this can be a link, a button, etc in your HTML, it can be null if the elements in the gallery were set dinamically
});
// Trigger a function when a slide is inserted
lightbox.on('slide_inserted', (data) => {
// data is an object that contain the following
const { slideIndex, slideNode, slideConfig, player, trigger } = data;
// slideIndex - the slide index
// slideNode - the node you can modify
// slideConfig - will contain the configuration of the slide like title, description, etc.
// player - the slide player if it exists otherwise will return false
// trigger - null
});
// Trigger a function when a slide is removed
lightbox.on('slide_removed', (index) => {
// index is the position of the element in the gallery
});
```
## Video player
GLightbox includes "[Plyr](https://plyr.io/)" the best player out there, you can pass any Plyr option to the player, view all available options here [Plyr options](https://github.com/sampotts/plyr). GLightbox will only inject the player library if required and only when the lightbox is opened.
**Internet Explorer 11. If you need support for this browser you need to set the js url to use the polyfilled version. This is not the default because IE11 is ancient and we need to let it die.**
### Autoplay for mobile/tablet
Please note, autoplay is blocked in some browsers, there’s nothing we can do to change that unfortunately, the browser will decide if your video can be autoplayed. Please do not post issues about this, instead inform yourself about this topic:
- [https://webkit.org/blog/6784/new-video-policies-for-ios/](https://webkit.org/blog/6784/new-video-policies-for-ios/)
- [https://developers.google.com/web/updates/2017/09/autoplay-policy-changes](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes)
- [https://hacks.mozilla.org/2019/02/firefox-66-to-block-automatically-playing-audible-video-and-audio/](https://hacks.mozilla.org/2019/02/firefox-66-to-block-automatically-playing-audible-video-and-audio/)
they decide if a video can be autoplayed based in a few rules
```
plyr: {
js: 'https://cdn.plyr.io/3.6.2/plyr.polyfilled.js',
....
```
```javascript
const lightbox = GLightbox({
plyr: {
css: 'https://cdn.plyr.io/3.5.6/plyr.css', // Default not required to include
js: 'https://cdn.plyr.io/3.5.6/plyr.js', // Default not required to include
config: {
ratio: '16:9', // or '4:3'
muted: false,
hideControls: true,
youtube: {
noCookie: true,
rel: 0,
showinfo: 0,
iv_load_policy: 3
},
vimeo: {
byline: false,
portrait: false,
title: false,
speed: true,
transparent: false
}
}
}
});
```
## API
There are methods, setters and getters on a GLightbox object. The easiest way to access the GLightbox object is to set the return value from your call to a variable. For example:
```javascript
const lightbox = GLightbox({ ...options });
```
## Methods
Example method use:
```javascript
lightbox.nextSlide(); // Go to next slide
lightbox.close(); // Close the lightbox
```
| Option | Parameters | Description |
| ---------------------- | ------------------ | -------------------------------------------------------------------------- |
| open | `node` | Open the lightbox, you can optionally pass a node. |
| openAt | `number` | Open at specific index. |
| close | `-` | Close the lightbox. |
| reload | `-` | Reload the lightbox, after inserting content with ajax. |
| destroy | `-` | Destroy and remove all attached events. |
| prevSlide | `-` | Go to the previous slide. |
| nextSlide | `-` | Go to the next slide. |
| goToSlide | `number` | Index of the slide. |
| insertSlide | `object, index` | Insert a slide at the specified index. |
| removeSlide | `index` | Remove slide at the specified index. |
| getActiveSlide | `-` | Get active slide. It will return the active node. |
| getActiveSlideIndex | `-` | Get active slide. It will return the active slide index. |
| slidePlayerPlay | `number` | Play video in the specified slide. |
| slidePlayerPause | `number` | Pause video in the specified slide. |
| getSlidePlayerInstance | `node, index` | Get the player instance of the specified slide. |
| getAllPlayers | `-` | Get all players instance. |
| setElements | `[]` | Update the lightbox gallery elements. |
| on | `string, function` | Set an event listener. See Events section |
| once | `string, function` | Set an event listener that will be triggered only once. See Events section |
```javascript
// Example set custom gallery items
// This overwrites all the items in the gallery
lightbox.setElements([
{
'href': 'https://picsum.photos/1200/800',
'type': 'image' // Type is only required if GLightbox fails to know what kind of content should display
},
{
'href': 'https://www.youtube.com/watch?v=Ga6RYejo6Hk',
'type': 'video', // Type is only required if GLightbox fails to know what kind of content should display
'width': '900px',
},
{
'content': '<p>some html to append in the slide</p>',
'width': '900px',
}
]);
// Insert a single slide at the end of all the items,
lightbox.insertSlide({
href: 'video url...',
width: '90vw'
});
// Insert a single slide at index 2 or pass 0 to add it at the start
lightbox.insertSlide({
href: 'video url...',
width: '90vw'
}, 2);
// You can insert a slide with a defined html
lightbox.insertSlide({
content: '<p>some html to append in the slide</p>',
width: '90vw'
}, 2);
// Or if you prefer you can pass a node
// and it will be inserted in the slide
lightbox.insertSlide({
content: document.getElementById('inline-example'),
width: '90vw'
}, 2);
// Remove the slide at index 2
lightbox.removeSlide(2);
// Open the lightbox
lightbox.open();
// You can also open the lightbox at a specific index
lightbox.openAt(2);
// So imagine that you are making an ajax request that returns some html
// You can create an empty instance and append the content once is returned
const ajaxExample = GLightbox({ selector: null }); // or you can set the selector empty selector: ''
doAjaxCall({...}).then(response => {
ajaxExample.insertSlide({
width: '500px',
content: response.html
});
ajaxExample.open();
})
// Or you could use the set elements method to empty all the slides if any
doAjaxCall({...}).then(response => {
ajaxExample.setElements([
{
content: response.html
}
]);
ajaxExample.open();
})
```
## Animations
Animations are created with CSS, each effect has an in and out value and they are used to attach the correct classes to the node.
For example if you are using
```javascript
const glightbox = GLightbox({
openEffect: 'zoom',
closeEffect: 'fade',
cssEfects: {
// This are some of the animations included, no need to overwrite
fade: { in: 'fadeIn', out: 'fadeOut' },
zoom: { in: 'zoomIn', out: 'zoomOut' }
}
});
```
The open effect will use cssEfects.zoom.in and will add the class gzoomIn, if you take a look at the CSS you'll see:
```javascript
.gzoomIn {
animation: gzoomIn .5s ease;
}
@keyframes gzoomIn {
from {
opacity: 0;
transform: scale3d(.3, .3, .3);
}
to {
opacity: 1;
}
}
```
### Adding a custom animation
You can create any animation you want, you can find some inspiration in the Animate.css library, for example you can add the bounce animation like this:
```javascript
const glightbox = GLightbox({
openEffect: 'bounce', // Define that we want the bounce animation on open
cssEfects: {
// register our new animation
bounce: { in: 'bounceIn', out: 'bounceOut' }
}
});
```
```css
/*A g will be appended to the animation name so bounceIn will become gbounceIn */
.gbounceIn {
animation: bounceIn 1.3s ease;
}
@keyframes bounceIn {
from,
20%,
40%,
60%,
80%,
to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
0% {
opacity: 0;
transform: scale3d(0.3, 0.3, 0.3);
}
20% {
transform: scale3d(1.1, 1.1, 1.1);
}
40% {
transform: scale3d(0.9, 0.9, 0.9);
}
60% {
opacity: 1;
transform: scale3d(1.03, 1.03, 1.03);
}
80% {
transform: scale3d(0.97, 0.97, 0.97);
}
to {
opacity: 1;
transform: scale3d(1, 1, 1);
}
}
```
## Themeable
You can completely customize the structure of GLightbox and use CSS to change any part you want.
```javascript
const customLightboxHTML = `<div id="glightbox-body" class="glightbox-container">
<div class="gloader visible"></div>
<div class="goverlay"></div>
<div class="gcontainer">
<div id="glightbox-slider" class="gslider"></div>
<button class="gnext gbtn" tabindex="0" aria-label="Next" data-customattribute="example">{nextSVG}</button>
<button class="gprev gbtn" tabindex="1" aria-label="Previous">{prevSVG}</button>
<button class="gclose gbtn" tabindex="2" aria-label="Close">{closeSVG}</button>
</div>
</div>`;
let customSlideHTML = `<div class="gslide">
<div class="gslide-inner-content">
<div class="ginner-container">
<div class="gslide-media">
</div>
<div class="gslide-description">
<div class="gdesc-inner">
<h4 class="gslide-title"></h4>
<div class="gslide-desc"></div>
</div>
</div>
</div>
</div>
</div>`;
const glightbox = GLightbox({
lightboxHTML: customLightboxHTML,
slideHTML: customSlideHTML,
skin: 'supercool'
});
```
You can also define a skin name and the lightbox will append the class name "glightbox-supercool" so you can customize it with CSS, this will leave a barebones structure so you can change the buttons appearance, etc.
## Development
```bash
$ npm install
$ npm run watch
```
## Browser Support
GLightbox was tested in the following browsers.
- Safari
- Mobile Safari
- Opera
- Edge
- Firefox
- Internet Explorer 11
It will work in any browser that supports CSS Flexbox
## Contributing
Feel free to report any issues! If you wish to contribute by fixing a bug or implementing a new feature, please first read the [CONTRIBUTING](./CONTRIBUTING.md) guide.
## Donate
If you find this code useful, please consider a donation to keep this project growing, any amount is appreciated.
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://paypal.me/bdigital9816/5usd)
## Support
We only provide support for bugs and feature requests, so please only post issues about this two topics, if you need help implementing GLightbox or you are just starting with HTML/CSS/Javascript please use stackoverlow, you'll be able to find more help there. This will help us to keep the issues related to the library and solve issues faster.
## Changelog
#### Latest version vundefined
See the [CHANGELOG.md](CHANGELOG.md) file for details
## License
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
For options and usage, visit the [documentation website](https://glightbox.biati.digital/)

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc