From 113c3507fc877a218b79b259bff9b5feb62bf79d Mon Sep 17 00:00:00 2001 From: Tony Air Date: Thu, 18 Jun 2020 06:18:13 +0700 Subject: [PATCH] IMPR: Plugin Refactoring --- src/js/_events.js | 38 +++ src/js/meta-lightbox.js | 487 ++++++++++++------------------ src/scss/meta-lightbox-theme.scss | 1 + src/scss/meta-lightbox.scss | 1 + 4 files changed, 236 insertions(+), 291 deletions(-) create mode 100755 src/js/_events.js diff --git a/src/js/_events.js b/src/js/_events.js new file mode 100755 index 0000000..fa82736 --- /dev/null +++ b/src/js/_events.js @@ -0,0 +1,38 @@ +/** + * Add your global events here + */ + +module.exports = { + AJAX: 'ajax-load', + TABHIDDEN: 'tab-hidden', + TABFOCUSED: 'tab-focused', + OFFLINE: 'offline', + ONLINE: 'online', + LOADED: 'load', + SWIPELEFT: 'swipeleft panleft', + SWIPERIGHT: 'swiperight panright', + ALLERTAPPEARED: 'alert-appeared', + ALERTREMOVED: 'alert-removed', + LODEDANDREADY: 'load-ready', + LAZYIMAGEREADY: 'image-lazy-bg-loaded', + LAZYIMAGESREADY: 'images-lazy-loaded', + MAPLOADED: 'map-loaded', + MAPAPILOADED: 'map-api-loaded', + MAPMARKERCLICK: 'map-marker-click', + MAPPOPUPCLOSE: 'map-popup-close', + SCROLL: 'scroll', + RESIZE: 'resize', + CAROUSEL_READY: 'bs.carousel.ready', + SET_TARGET_UPDATE: 'set-target-update', + RESTORE_FIELD: 'restore-field', + FORM_INIT_BASICS: 'form-basics', + FORM_INIT_STEPPED: 'form-init-stepped', + FORM_INIT_VALIDATE: 'form-init-validate', + FORM_INIT_VALIDATE_FIELD: 'form-init-validate-field', + FORM_INIT_STORAGE: 'form-init-storage', + FORM_VALIDATION_FAILED: 'form-validation-failed', + FORM_STEPPED_NEW_STEP: 'form-new-step', + FORM_STEPPED_FIRST_STEP: 'form-first-step', + FORM_STEPPED_LAST_STEP: 'form-last-step', + FORM_FIELDS: 'input,textarea,select', +}; diff --git a/src/js/meta-lightbox.js b/src/js/meta-lightbox.js index 36c26fa..60188f9 100755 --- a/src/js/meta-lightbox.js +++ b/src/js/meta-lightbox.js @@ -1,123 +1,74 @@ /* - * MetaLightbox v0.61 + * MetaLightbox * https://tony.twma.pro * */ +// optional: //=require ../../bower_components/jquery-zoom/jquery.zoom.js -(function($, window, document) { - var pluginName = 'metaLightbox', - defaults = { - effect: 'fade', - theme: 'default', - keyboardNav: true, - clickOverlayToClose: true, - onInit: function() {}, - beforeShowLightbox: function() {}, - afterShowLightbox: function(lightbox) {}, - beforeHideLightbox: function() {}, - afterHideLightbox: function() {}, - onPrev: function(element) {}, - onNext: function(element) {}, - errorMessage: - 'The requested content cannot be loaded. Please try again later.', - }; +"use strict"; - function MetaLightbox(element, options) { - /*this.el = element; - this.$el = $(this.el);*/ +import $ from 'jquery'; - this.options = $.extend({}, defaults, options); +import Events from './_events'; - this._defaults = defaults; - this._name = pluginName; +const MetaLightboxUI = (($) => { + const W = window; + const D = document; + const $Body = $('body'); - this.init(); - } + const NAME = 'MetaLightboxUI'; - MetaLightbox.prototype = { - init: function() { - var $this = this, - $html = $('html'); + class MetaLightboxUI { + static init() { + console.log(`Initializing: ${NAME}`); - this.ajaxLoaded = false; + const ui = this; + ui.isMSIE = /*@cc_on!@*/ 0; + ui.isHidpi = ui.isHidpi(); - // make object globally accessible - document.MetaLightbox = this; - // Need this so we don't use CSS transitions in mobile - if (!$html.hasClass('meta-lightbox-notouch')) - $html.addClass('meta-lightbox-notouch'); - if ('ontouchstart' in document) - $html.removeClass('meta-lightbox-notouch'); - - // Setup the click - $(document).on( - 'click', - '[data-toggle="lightbox"],[data-lightbox-gallery]', - function(e) { - e.preventDefault(); + $(`.js${NAME},[data-toggle="lightbox"],[data-lightbox-gallery]`).on('click', (e) => { + e.preventDefault(); e.stopPropagation(); + const $link = $(e.currentTarget); - $this.showLightbox(this); - return false; - }, - ); + ui.show($link); + }); + } - // keyboardNav - if (this.options.keyboardNav) { - $('body') - .off('keyup') - .on('keyup', (e) => { - var code = e.keyCode ? e.keyCode : e.which; - // Escape - if (code === 27) { - $this.destructLightbox(); - } - // Left - if (code === 37) { - $('.meta-lightbox-prev').trigger('click'); - } - // Right - if (code === 39) { - $('.meta-lightbox-next').trigger('click'); - } - }); - } + static isHidpi() { + console.log(`${NAME}: isHidpi`); + const mediaQuery = + '(-webkit-min-device-pixel-ratio: 1.5),\ + (min--moz-device-pixel-ratio: 1.5),\ + (-o-min-device-pixel-ratio: 3/2),\ + (min-resolution: 1.5dppx)'; + if (W.devicePixelRatio > 1) return true; + return W.matchMedia && W.matchMedia(mediaQuery).matches; + } - this.options.onInit.call(this); - }, + static show($link) { + console.log(`${NAME}: show`); + const ui = this; - showLightbox: function(element) { - this.el = element; - this.$el = $(this.el); + const $lightbox = this.constructLightbox(); + if (!$lightbox) return; - var $this = this, - lightbox, - content, - currentLink, - galleryItems; + const $content = ui.$content; + if (!$content) return; - this.options.beforeShowLightbox.call(this); - - lightbox = this.constructLightbox(); - if (!lightbox) return; - content = lightbox.find('.meta-lightbox-content'); - if (!content) return; - currentLink = this.$el; - $('body').addClass(`meta-lightbox-body-effect-${this.options.effect}`); + $('body').addClass(`meta-lightbox-body-effect-fade`); // Add content - this.processContent(content, currentLink); + ui.process($content, $link); // Nav - if (this.$el.data('lightbox-gallery')) { - galleryItems = $( - `[data-lightbox-gallery="${this.$el.data('lightbox-gallery')}"]`, - ); + if ($link.data('lightbox-gallery')) { + const $galleryItems = $(`[data-lightbox-gallery="${$link.data('lightbox-gallery')}"]`); - if (galleryItems.length === 1) { + if ($galleryItems.length === 1) { $('.meta-lightbox-nav').hide(); } else { $('.meta-lightbox-nav').show(); @@ -126,66 +77,110 @@ // Prev $('.meta-lightbox-prev') .off('click') - .on('click', function(e) { + .on('click', (e) => { e.preventDefault(); - var index = galleryItems.index(currentLink); - currentLink = galleryItems.eq(index - 1); - if (!$(currentLink).length) currentLink = galleryItems.last(); - $this.processContent(content, currentLink); - $this.options.onPrev.call(this, [currentLink]); + const index = $galleryItems.index(currentLink); + let $currentLink = $galleryItems.eq(index - 1); + if (!$currentLink.length) $currentLink = $galleryItems.last(); + $this.process($content, $currentLink); }); // Next $('.meta-lightbox-next') .off('click') - .on('click', function(e) { + .on('click', (e) => { e.preventDefault(); - var index = galleryItems.index(currentLink); - currentLink = galleryItems.eq(index + 1); - if (!$(currentLink).length) currentLink = galleryItems.first(); - $this.processContent(content, currentLink); - $this.options.onNext.call(this, [currentLink]); + const index = $galleryItems.index(currentLink); + $currentLink = $galleryItems.eq(index + 1); + if (!$currentLink.length) $currentLink = $galleryItems.first(); + $this.process($content, $currentLink); }); } - setTimeout(function() { - lightbox.addClass('meta-lightbox-open'); - $this.options.afterShowLightbox.call(this, [lightbox]); + setTimeout(() => { + ui.$overlay.addClass('meta-lightbox-open'); }, 1); // For CSS transitions - }, + } - processContent: function(content, link) { - var $this = this, - img, - video, - src, - classTerm, - iframe, - wrap; + static constructLightbox() { + console.log(`${NAME}: constructLightbox`); + const ui = this; - href = link.attr('href'); - if (!href) { - href = link.data('href'); + const overlay = $('
', { + class: 'meta-lightbox-overlay meta-lightbox-theme-default meta-lightbox-effect-fade', + }); + const wrap = $('
', { + class: 'meta-lightbox-wrap', + }); + const content = $('
', { + class: 'meta-lightbox-content', + }); + const nav = $( + ' Previous Next', + ); + const close = $( + 'Close', + ); + const title = $('
', { + class: 'meta-lightbox-title-wrap', + }); + + if (ui.$overlay) return ui.$overlay; + + if (ui.isMSIE) overlay.addClass('meta-lightbox-ie'); + + wrap.append(content); + wrap.append(title); + overlay.append(wrap); + overlay.append(nav); + overlay.append(close); + $('body').append(overlay); + + overlay.on('click', (e) => { + e.preventDefault(); + ui.hide(); + }); + + close.on('click', (e) => { + e.preventDefault(); + ui.hide(); + }); + + ui.$overlay = overlay; + ui.$content = content; + ui.$title = title; + + return ui.$overlay; + } + + static setTitle(str) { + const ui = this; + + ui.$title.html(str); + } + + static process($content, $link) { + console.log(`${NAME}: process`); + const ui = this; + + const href = $link.attr('href').length ? $link.attr('href') : $link.data('href'); + if (!href.length) { + console.log($link); + console.error(NAME + ': href(attr/data) is missing'); } - content.html('').addClass('meta-lightbox-loading'); - - // Is HiDPI? - if (this.isHidpi() && link.data('lightbox-hidpi')) { - href = link.data('lightbox-hidpi'); - } + const $pageSpinner = $('#PageLoading'); + const loadingContent = $pageSpinner.length ? $pageSpinner.html() : ''; + ui.$content.html(loadingContent).addClass('meta-lightbox-loading'); // Image - if (href.match(/\.(jpeg|jpg|gif|png)$/i) != null) { - /*if ($(window).width() < 768) { - window.open(href, '_blank'); - }*/ - img = $('', { + if (href.match(/\.(jpeg|jpg|gif|png|svg)$/i)) { + const img = $('', { src: href, }); + img.on('load', () => { - var wrap = $('
'), - $content = $('.meta-lightbox-content'), + const wrap = $('
'), imgwrapper = $(''); imgwrapper.append(img); @@ -196,6 +191,7 @@ 'line-height': `${$content.height()}px`, height: `${$content.height()}px`, // For Firefox }); + $(window).resize(() => { wrap.css({ 'line-height': `${$content.height()}px`, @@ -207,29 +203,22 @@ imgwrapper.zoom(); } - content.html(wrap).removeClass('meta-lightbox-loading'); - $this.contentLoaded(); + ui.$content.html(wrap); + ui.contentLoaded(); }); - /*.each(function () { - if (this.complete) $(this).load(); - });*/ img.on('error', () => { - var wrap = $( - `

${$this.options.errorMessage}

`, + const wrap = $( + `

${$this.options.errorMessage}

`, ); - content.html(wrap).removeClass('meta-lightbox-loading'); - $this.contentLoaded(); + + ui.$content.html(wrap); + ui.contentLoaded(); }); // Set the title - if (link.data('title')) { - $this.setTitle(link.data('title')); - } else if (link.attr('title')) { - $this.setTitle(link.attr('title')); - } else { - $('.meta-lightbox-title-wrap').html(''); - } + const title = $link.data('title') ? $link.data('title') : $link.attr('title'); + ui.setTitle(title); // google analytics if (typeof ga === 'function') { @@ -237,33 +226,30 @@ } } // Video (Youtube/Vimeo) - else if ( - (video = href.match( - /(youtube|youtube-nocookie|youtu|vimeo)\.(com|be)\/(watch\?v=([\w-]+)|([\w-]+))/, - )) - ) { - src = ''; - classTerm = 'meta-lightbox-video'; + else if (href.match(/(youtube|youtube-nocookie|youtu|vimeo)\.(com|be)\/(watch\?v=([\w-]+)|([\w-]+))/)) { + let video = href.match(/(youtube|youtube-nocookie|youtu|vimeo)\.(com|be)\/(watch\?v=([\w-]+)|([\w-]+))/); + let classTerm = 'meta-lightbox-video'; + let src; if (video[1] == 'youtube') { src = `https://www.youtube.com/embed/${video[4]}`; - classTerm = 'meta-lightbox-youtube'; + classTerm = classTerm + ' meta-lightbox-youtube'; } if (video[1] == 'youtu') { src = `https://www.youtube.com/embed/${video[3]}`; - classTerm = 'meta-lightbox-youtube'; + classTerm = classTerm + ' meta-lightbox-youtube'; } if (video[1] == 'youtube-nocookie') { src = `https://www.youtube-nocookie.com/embed/${video[4]}`; - classTerm = 'nivo-lightbox-youtube'; + classTerm = classTerm+' meta-lightbox-youtube'; } if (video[1] == 'vimeo') { src = `https://player.vimeo.com/video/${video[3]}`; - classTerm = 'meta-lightbox-vimeo'; + classTerm = classTerm + ' meta-lightbox-vimeo'; } if (src) { - iframe = $('