var Lightbox = (function () {
'use strict';
class Dom {
createElement(tag) {
return document.createElement(tag);
}
appendChild(parent, child) {
if (parent) parent.appendChild(child);
}
appendHtml(parent, html) {
if (parent) parent.insertAdjacentHTML('beforeend', html);
}
addEventListener(parent, type, listener) {
if (parent) parent.addEventListener(type, listener);
}
addClass(element, classname) {
if (!element) return;
if (this.hasClass(element, classname)) return;
if (element.classList.length === 0) element.className = classname;else element.className = element.className + ' ' + classname;
element.className = element.className.replace(/ +/g, ' '); //else element.classList.add(classname); //error if there is -
}
removeClass(element, classname) {
if (!element) return;
if (element.classList.length > 0) {
// element.className = element.className.replace(new RegExp('\\b'+ classname+'\\b', 'g'), '');
// element.className = element.className.replace(/ +/g, ' ');
let i, j, imax, jmax;
let classesToDel = classname.split(' ');
for (i = 0, imax = classesToDel.length; i < imax; ++i) {
if (!classesToDel[i]) continue;
let classtoDel = classesToDel[i]; // https://jsperf.com/removeclass-methods
let sClassName = '';
let currentClasses = element.className.split(' ');
for (j = 0, jmax = currentClasses.length; j < jmax; ++j) {
if (!currentClasses[j]) continue;
if (currentClasses[j] !== classtoDel) sClassName += currentClasses[j] + ' ';
}
element.className = sClassName.trim();
}
if (element.className === '') element.removeAttribute('class');
}
} // https://plainjs.com/javascript/attributes/adding-removing-and-testing-for-classes-9/
// addClass(element, classname) {
// console.log(element.classList)
// if (element.classList) element.classList.add(classname);
// else if (!this.hasClass(element, classname)) element.className += ' ' + classname;
// }
// removeClass(element, classname) {
// if (element.classList) element.classList.remove(classname);
// else element.className = element.className.replace(new RegExp('\\b'+ classname+'\\b', 'g'), '');
// }
hasClass(element, classname) {
if (!element) return false;
try {
let s = element.getAttribute('class');
return new RegExp('\\b' + classname + '\\b').test(s);
} catch (e) {// Do Nothing
// console.log(element);
} //return element.classList ? element.classList.contains(classname) : new RegExp('\\b'+ classname+'\\b').test(element.className);
}
moveAfter(element, targetElement) {
targetElement.parentNode.insertBefore(element, targetElement);
targetElement.parentNode.insertBefore(targetElement, targetElement.previousElementSibling);
} // https://stackoverflow.com/questions/10381296/best-way-to-get-child-nodes
elementChildren(element) {
const childNodes = element.childNodes;
let children = [];
let i = childNodes.length;
while (i--) {
if (childNodes[i].nodeType === 1
/*&& childNodes[i].tagName === 'DIV'*/
) {
children.unshift(childNodes[i]);
}
}
return children;
}
parentsHasClass(element, classname) {
while (element) {
// if(classname==='is-side') console.log(element.nodeName); // NOTE: click on svg can still returns undefined in IE11
if (!element.tagName) return false;
if (element.tagName === 'BODY' || element.tagName === 'HTML') return false; // if(!element.classList) {
// console.log('no classList');
// return false;
// }
if (this.hasClass(element, classname)) {
return true;
} // TODO: if(element.nodeName.toLowerCase() === 'svg') console.log(element);
element = element.parentNode;
}
}
parentsHasId(element, id) {
while (element) {
if (!element.tagName) return false;
if (element.tagName === 'BODY' || element.tagName === 'HTML') return false;
if (element.id === id) {
return true;
}
element = element.parentNode;
}
}
parentsHasTag(element, tagname) {
while (element) {
if (!element.tagName) return false;
if (element.tagName === 'BODY' || element.tagName === 'HTML') return false;
if (element.tagName.toLowerCase() === tagname.toLowerCase()) {
return true;
}
element = element.parentNode;
}
}
parentsHasAttribute(element, attrname) {
while (element) {
if (!element.tagName) return false;
if (element.tagName === 'BODY' || element.tagName === 'HTML') return false;
try {
if (element.hasAttribute(attrname)) {
// error on svg element
return true;
}
} catch (e) {// Do Nothing
// console.log(element);
// return false;
}
element = element.parentNode;
}
}
parentsHasElement(element, tagname) {
while (element) {
if (!element.tagName) return false;
if (element.tagName === 'BODY' || element.tagName === 'HTML') return false;
element = element.parentNode;
if (!element) return false;
if (!element.tagName) return false;
if (element.tagName.toLowerCase() === tagname) {
return true;
}
}
}
removeClasses(elms, classname) {
for (let i = 0; i < elms.length; i++) {
elms[i].classList.remove(classname);
}
}
removeAttributes(elms, attrname) {
for (let i = 0; i < elms.length; i++) {
elms[i].removeAttribute(attrname);
}
}
removeElements(elms) {
Array.prototype.forEach.call(elms, el => {
el.parentNode.removeChild(el);
});
}
getStyle(element, property) {
return window.getComputedStyle ? window.getComputedStyle(element, null).getPropertyValue(property) : element.style[property.replace(/-([a-z])/g, function (g) {
return g[1].toUpperCase();
})];
}
}
const dom = new Dom();
class Lightbox {
constructor() {
let builderStuff = document.querySelector('#_cbhtml'); // All editing controls will be placed within
...
if (!builderStuff) {
builderStuff = dom.createElement('div');
builderStuff.id = '_cbhtml';
builderStuff.className = 'is-ui';
dom.appendChild(document.body, builderStuff);
}
this.builderStuff = builderStuff;
let div = this.builderStuff.querySelector('#_lightbox');
if (!div) {
let html = `
`; // Click overlay will close lightbox
this.builderStuff.insertAdjacentHTML('afterbegin', html); // Click overlay will close lightbox
const lightboxes = this.builderStuff.querySelectorAll('div.is-lightbox');
lightboxes.forEach(lightbox => {
lightbox.addEventListener('click', e => {
if (dom.parentsHasClass(e.target, 'lightbox-content')) return;
dom.removeClass(lightbox, 'active');
const btnClose = lightbox.querySelector('.cmd-lightbox-close');
btnClose.style.opacity = 0;
document.body.style.overflowY = '';
setTimeout(() => {
let iframe = lightbox.querySelector('iframe');
if (iframe) {
iframe.setAttribute('src', 'about:blank');
}
lightbox.style.display = '';
}, 300);
});
}); // this.init();
}
} //constructor
init() {
// Find all elements that have .block-click & .button-click class.
// Then read data attributes:
// - data-modal-theme: dark or light
// - data-modal-color (background color)
// - data-modal-image (image url)
// - data-modal-video (video url)
// - data-modal-externalvideo (ex. youtube url)
const blockClickables = document.querySelectorAll('.block-click,.button-click,.is-lightbox');
blockClickables.forEach(block => {
block.addEventListener('click', e => {
let url;
let extension;
if (block.tagName.toLowerCase() === 'a') {
url = block.getAttribute('href');
extension = url.split('.').pop();
} else if (block.getAttribute('data-modal-url')) {
url = block.getAttribute('data-modal-url');
extension = url.split('.').pop();
} else {
if (block.getAttribute('data-modal-image') || block.getAttribute('data-modal-video') || block.getAttribute('data-modal-externalvideo')) ; else {
// Overlay is clicked
return;
}
}
let theme = block.getAttribute('data-modal-theme');
if (!theme) theme = 'light';
const color = block.getAttribute('data-modal-color');
if (extension === 'jpg' || extension === 'jpeg' || extension === 'png' || extension === 'gif' || extension === 'webm') {
this.openImage(url, theme, color);
} else if (extension === 'mp4') {
this.openVideo(url, 'dark', color);
} else if (url.toLowerCase().indexOf('youtube.com') !== -1 || url.toLowerCase().indexOf('vimeo.com') !== -1) {
this.openExternalVideo(url, 'dark', color);
} else {
// Open link. But check first some attributes.
if (block.getAttribute('data-modal-image')) {
url = block.getAttribute('data-modal-image');
this.openImage(url, theme, color);
} else if (block.getAttribute('data-modal-video')) {
url = block.getAttribute('data-modal-video');
this.openVideo(url, 'dark', color);
} else if (block.getAttribute('data-modal-externalvideo')) {
url = block.getAttribute('data-modal-externalvideo');
this.openExternalVideo(url, 'dark', color);
} else {
// Now open link
window.location.href = url;
}
}
e.preventDefault();
});
});
} //run
openImage(url, theme, color) {
let lightbox = this.builderStuff.querySelector('div.is-lightbox.lightbox-image'); // in case opened in an iframe (ex. preview)
if (window.frameElement && !lightbox) {
lightbox = parent.document.querySelector('.is-lightbox.lightbox-image');
}
const btnClose = lightbox.querySelector('.cmd-lightbox-close');
btnClose.style.opacity = 0;
if (color) lightbox.style.backgroundColor = color;
const div = lightbox.querySelector('.lightbox-content');
div.innerHTML = '';
if (theme === 'light') {
dom.addClass(lightbox, 'light');
dom.removeClass(lightbox, 'dark');
} else {
dom.addClass(lightbox, 'dark');
dom.removeClass(lightbox, 'light');
}
lightbox.style.display = 'flex';
if (!window.frameElement) document.body.style.overflowY = 'hidden';
setTimeout(() => {
dom.addClass(lightbox, 'active');
setTimeout(() => {
btnClose.style.opacity = 1;
}, 450);
}, 10);
}
openVideo(url, theme, color) {
let lightbox = document.querySelector('.is-lightbox.lightbox-video'); // in case opened in an iframe (ex. preview)
if (window.frameElement && !lightbox) {
lightbox = parent.document.querySelector('.is-lightbox.lightbox-video');
}
const btnClose = lightbox.querySelector('.cmd-lightbox-close');
btnClose.style.opacity = 0;
if (color) lightbox.style.backgroundColor = color;
const div = lightbox.querySelector('.lightbox-content');
div.innerHTML = '';
if (theme === 'light') {
dom.addClass(lightbox, 'light');
dom.removeClass(lightbox, 'dark');
} else {
dom.addClass(lightbox, 'dark');
dom.removeClass(lightbox, 'light');
}
lightbox.style.display = 'flex';
if (!window.frameElement) document.body.style.overflowY = 'hidden';
setTimeout(() => {
dom.addClass(lightbox, 'active');
setTimeout(() => {
btnClose.style.opacity = 1;
}, 450);
}, 10);
}
openExternalVideo(url, theme, color) {
let lightbox = document.querySelector('.is-lightbox.lightbox-externalvideo'); // in case opened in an iframe (ex. preview)
if (window.frameElement && !lightbox) {
lightbox = parent.document.querySelector('.is-lightbox.lightbox-externalvideo');
}
const btnClose = lightbox.querySelector('.cmd-lightbox-close');
btnClose.style.opacity = 0;
if (color) lightbox.style.backgroundColor = color;
if (theme === 'light') {
dom.addClass(lightbox, 'light');
dom.removeClass(lightbox, 'dark');
} else {
dom.addClass(lightbox, 'dark');
dom.removeClass(lightbox, 'light');
}
const iframe = lightbox.querySelector('iframe');
url = this.getIframeVideoUrl(url);
if (url !== '') iframe.setAttribute('src', url);
lightbox.style.display = 'flex';
if (!window.frameElement) document.body.style.overflowY = 'hidden';
const div = lightbox.querySelector('.lightbox-content');
div.style.width = div.offsetHeight * 16 / 9 + 'px';
setTimeout(() => {
dom.addClass(lightbox, 'active');
setTimeout(() => {
btnClose.style.opacity = 1;
}, 450);
}, 10);
}
getIframeVideoUrl(src) {
// https://regex101.com/library/OY96XI
// https://stackoverflow.com/questions/3452546/how-do-i-get-the-youtube-video-id-from-a-url
// let youRegex = /^http[s]?:\/\/(((www.youtube.com\/watch\?(feature=player_detailpage&)?)v=)|(youtu.be\/))([^#&?]*)/;
let youRegex = /^.*(?:https?:)?(?:\/\/)?(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\/\S*?[^\w\s-])((?!videoseries)[\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/;
let vimeoRegex = /^.*(vimeo\.com\/)((channels\/[A-z]+\/)|(groups\/[A-z]+\/videos\/)|(video\/))?([0-9]+)\/?/; // let youRegexMatches = youRegex.exec(src);
let youRegexMatches = src.match(youRegex);
let vimeoRegexMatches = vimeoRegex.exec(src); // if (youRegexMatches !== null || vimeoRegexMatches !== null) {
if ((youRegexMatches !== null || vimeoRegexMatches !== null) && src.indexOf('player.vimeo.com') === -1 && src.indexOf('youtube.com/embed/') === -1) {
if (youRegexMatches !== null) {
// && youRegexMatches.length >= 7) {
// let youMatch = youRegexMatches[6];
let youMatch = youRegexMatches[1];
src = 'https://www.youtube.com/embed/' + youMatch + '?rel=0&autoplay=1&color=white';
}
if (vimeoRegexMatches !== null && vimeoRegexMatches.length >= 7) {
let vimeoMatch = vimeoRegexMatches[6];
src = 'https://player.vimeo.com/video/' + vimeoMatch;
}
}
return src;
}
} //Lightbox
window.lightbox = new Lightbox();
return Lightbox;
})();