PageSourceSearch

https://zuomod.com/wp-content/mu-plugins/widgets/modifiers/compone…/product_image_component.js?ver=0173434c

js zuomod.com collected 2026-09-25 18:43:41 UTC 6,509 bytes, 192 lines download raw bytes

1(function(){
2  function getWizshopImagePreview() {
3    try {
4      var settings = JSON.parse(localStorage.getItem('wizshop_settings') || '{}');
5      return settings.image_preview || false;
6    } catch (e) {
7      return false;
8    }
9  }
10  
11  function initComponent(root){
12    if(!root) return;
13    
14    var wizshopImagePreview = getWizshopImagePreview();
15    var enableLightbox = root.getAttribute('data-enable-lightbox') === 'true';
16    var shouldUseLightbox = wizshopImagePreview && enableLightbox;
17    
18    if(shouldUseLightbox) {
19      initLightbox(root);
20    } else {
21      initMagnifier(root);
22      initThumbnailClickHandlers(root);
23    }
24  }
25  
26  function initLightbox(root) {
27    try {
28      if(typeof GLightbox !== 'undefined'){
29        GLightbox({
30          selector: '#' + root.id + ' .glightbox',
31          touchNavigation: true,
32          loop: true,
33          autoplayVideos: false,
34          zoomable: true,
35          moreText: '',
36          closeOnOutsideClick: true,
37          openEffect: 'fade',
38          closeEffect: 'fade'
39        });
40      }
41    } catch(e) { /* no-op */ }
42  }
43  
44  function initMagnifier(root) {
45    var $container = root.querySelector('.product-image-magnifier-container');
46    if(!$container) return;
47    
48    var $img = $container.querySelector('.product-image-magnifier-img');
49    var $magnifier = $container.querySelector('.product-image-magnifier');
50    if(!$img || !$magnifier) return;
51    
52    var isSmallScreen = window.innerWidth <= window.WizBreakpoints.mobile;
53    if(isSmallScreen) {
54      $container.classList.add('no-preview');
55      return;
56    }
57    
58    $container.classList.remove('glightbox');
59    
60    var magnifierSize = 400;
61    var zoomLevel = 4;
62    
63    function getImageSrc() {
64      return $img.src || $img.getAttribute('src') || $container.getAttribute('data-image-src') || '';
65    }
66    
67    $container.addEventListener('mouseenter', function(e) {
68      var containerRect = this.getBoundingClientRect();
69      var imgWidth = containerRect.width;
70      var imgHeight = containerRect.height;
71      var imgSrc = getImageSrc();
72      
73      $magnifier.style.backgroundImage = 'url("' + imgSrc + '")';
74      $magnifier.style.backgroundSize = (imgWidth * zoomLevel) + 'px ' + (imgHeight * zoomLevel) + 'px';
75      $magnifier.style.display = 'block';
76      $magnifier.classList.add('active');
77    });
78    
79    $container.addEventListener('mousemove', function(e) {
80      var containerRect = this.getBoundingClientRect();
81      var x = e.pageX - containerRect.left - window.pageXOffset;
82      var y = e.pageY - containerRect.top - window.pageYOffset;
83      
84      var magnifierX = x - (magnifierSize / 2);
85      var magnifierY = y - (magnifierSize / 2);
86      var bgX = (-x * zoomLevel) + (magnifierSize / 2);
87      var bgY = (-y * zoomLevel) + (magnifierSize / 2);
88      
89      $magnifier.style.left = magnifierX + 'px';
90      $magnifier.style.top = magnifierY + 'px';
91      $magnifier.style.backgroundPosition = bgX + 'px ' + bgY + 'px';
92    });
93    
94    $container.addEventListener('mouseleave', function() {
95      $magnifier.classList.remove('active');
96      $magnifier.style.display = 'none';
97    });
98    
99    $container.addEventListener('click', function(e) {
100      if(!getWizshopImagePreview()) {
101        e.preventDefault();
102        return false;
103      }
104    });
105  }
106  
107  function initThumbnailClickHandlers(root) {
108    var mainImage = root.querySelector('.wiz-prodimgcmp-image');
109    var thumbs = root.querySelectorAll('.wiz-prodimgcmp-thumb');
110    var currentIndex = 0;
111    
112    if(!mainImage || thumbs.length === 0) return;
113    
114    thumbs.forEach(function(thumb, index) {
115      thumb.addEventListener('click', function() {
116        var originalUrl = this.getAttribute('data-image-url');
117        var pdpUrl = this.getAttribute('data-image-pdp');
118        var newImageUrl = pdpUrl || originalUrl;
119        var clickedIndex = parseInt(this.getAttribute('data-image-index'), 10);
120
121        if(newImageUrl && newImageUrl !== mainImage.src) {
122          var direction = clickedIndex > currentIndex ? 'left' : 'right';
123          replaceImageWithSlide(mainImage, newImageUrl, direction);
124          currentIndex = clickedIndex;
125          
126          thumbs.forEach(function(t) { t.classList.remove('active'); });
127          this.classList.add('active');
128          
129          var container = root.querySelector('.product-image-magnifier-container');
130          if(container) {
131            container.setAttribute('data-image-src', newImageUrl);
132            var magnifier = container.querySelector('.product-image-magnifier');
133            if(magnifier && magnifier.classList.contains('active')) {
134              var containerRect = container.getBoundingClientRect();
135              var imgWidth = containerRect.width;
136              var imgHeight = containerRect.height;
137              var zoomLevel = 4;
138              magnifier.style.backgroundImage = 'url("' + newImageUrl + '")';
139              magnifier.style.backgroundSize = (imgWidth * zoomLevel) + 'px ' + (imgHeight * zoomLevel) + 'px';
140            }
141          }
142        }
143      });
144    });
145    
146    if(thumbs.length > 0) {
147      thumbs[0].classList.add('active');
148    }
149  }
150  
151  function replaceImageWithSlide(imageElement, newSrc, direction) {
152    var fallbackImageUrl = window.wizProductImageComponentConfig?.fallbackSrc || 'https://frontend-bucket.vercel.app/images/store_front_img_not_found.svg';
153    imageElement.src = newSrc;
154    imageElement.style.cssText = 'object-fit: contain; width: 100%; height: 100%;';
155    imageElement.onerror = function() {
156      this.onerror = null;
157      this.src = fallbackImageUrl;
158    };
159  }
160  
161  function boot(){
162    document.querySelectorAll('.wiz-prodimgcmp').forEach(initComponent);
163  }
164  
165  if(document.readyState==='loading'){
166    document.addEventListener('DOMContentLoaded',boot);
167  } else {
168    boot();
169  }
170  
171  if(typeof MutationObserver !== 'undefined') {
172    var observer = new MutationObserver(function(mutations) {
173      mutations.forEach(function(mutation) {
174        mutation.addedNodes.forEach(function(node) {
175          if(node.nodeType === 1) {
176            if(node.classList && node.classList.contains('wiz-prodimgcmp')) {
177              initComponent(node);
178            } else if(node.querySelectorAll) {
179              node.querySelectorAll('.wiz-prodimgcmp').forEach(initComponent);
180            }
181          }
182        });
183      });
184    });
185    
186    observer.observe(document.body, {
187      childList: true,
188      subtree: true
189    });
190  }
191})();
192

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.