1/*global wc_single_product_params, PhotoSwipe, PhotoSwipeUI_Default */ 2jQuery( function( $ ) { 3 4 // wc_single_product_params is required to continue. 5 if ( typeof wc_single_product_params === 'undefined' ) { 6 return false; 7 } 8 9 $( 'body' ) 10 // Tabs 11 .on( 'init', '.wc-tabs-wrapper, .woocommerce-tabs', function() { 12 $( this ).find( '.wc-tab, .woocommerce-tabs .panel:not(.panel .panel)' ).hide(); 13 14 var hash = window.location.hash; 15 var url = window.location.href; 16 var $tabs = $( this ).find( '.wc-tabs, ul.tabs' ).first(); 17 18 if ( hash.toLowerCase().indexOf( 'comment-' ) >= 0 || hash === '#reviews' || hash === '#tab-reviews' ) { 19 $tabs.find( 'li.reviews_tab a' ).trigger( 'click' ); 20 } else if ( url.indexOf( 'comment-page-' ) > 0 || url.indexOf( 'cpage=' ) > 0 ) { 21 $tabs.find( 'li.reviews_tab a' ).trigger( 'click' ); 22 } else if ( hash === '#tab-additional_information' ) { 23 $tabs.find( 'li.additional_information_tab a' ).trigger( 'click' ); 24 } else { 25 $tabs.find( 'li:first a' ).trigger( 'click' ); 26 } 27 } ) 28 .on( 'click', '.wc-tabs li a, ul.tabs li a', function( e ) { 29 e.preventDefault(); 30 var $tab = $( this ); 31 var $tabs_wrapper = $tab.closest( '.wc-tabs-wrapper, .woocommerce-tabs' ); 32 var $tabs = $tabs_wrapper.find( '.wc-tabs, ul.tabs' ); 33 34 $tabs.find( 'li' ).attr( 'aria-selected', 'false' ); 35 $tabs.find( 'li' ).removeClass( 'active' ); 36 $tabs_wrapper.find( '.wc-tab, .panel:not(.panel .panel)' ).hide(); 37 38 $tab.closest( 'li' ).attr( 'aria-selected', 'true' ); 39 $tab.closest( 'li' ).addClass( 'active' ); 40 $tabs_wrapper.find( '#' + $tab.attr( 'href' ).split( '#' )[1] ).show(); 41 } ) 42 // Review link 43 .on( 'click', 'a.woocommerce-review-link', function() { 44 $( '.reviews_tab a' ).trigger( 'click' ); 45 return true; 46 } ) 47 // Star ratings for comments 48 .on( 'init', '#rating', function() { 49 $( '#rating' ) 50 .hide() 51 .before( 52 '<p class="stars">\ 53 <span>\ 54 <a class="star-1" href="#">1</a>\ 55 <a class="star-2" href="#">2</a>\ 56 <a class="star-3" href="#">3</a>\ 57 <a class="star-4" href="#">4</a>\ 58 <a class="star-5" href="#">5</a>\ 59 </span>\ 60 </p>' 61 ); 62 } ) 63 .on( 'click', '#respond p.stars a', function() { 64 var $star = $( this ), 65 $rating = $( this ).closest( '#respond' ).find( '#rating' ), 66 $container = $( this ).closest( '.stars' ); 67 68 $rating.val( $star.text() ); 69 $star.siblings( 'a' ).removeClass( 'active' ); 70 $star.addClass( 'active' ); 71 $container.addClass( 'selected' ); 72 73 return false; 74 } ) 75 .on( 'click', '#respond #submit', function() { 76 var $rating = $( this ).closest( '#respond' ).find( '#rating' ), 77 rating = $rating.val(); 78 79 if ( $rating.length > 0 && ! rating && wc_single_product_params.review_rating_required === 'yes' ) { 80 window.alert( wc_single_product_params.i18n_required_rating_text ); 81 82 return false; 83 } 84 } ); 85 86 // Init Tabs and Star Ratings 87 $( '.wc-tabs-wrapper, .woocommerce-tabs, #rating' ).trigger( 'init' ); 88 89 /** 90 * Product gallery class. 91 */ 92 var ProductGallery = function( $target, args ) { 93 this.$target = $target; 94 this.$images = $( '.woocommerce-product-gallery__image', $target ); 95 96 // No images? Abort. 97 if ( 0 === this.$images.length ) { 98 this.$target.css( 'opacity', 1 ); 99 return; 100 } 101 102 // Make this object available. 103 $target.data( 'product_gallery', this ); 104 105 // Pick functionality to initialize... 106 this.flexslider_enabled = 'function' === typeof $.fn.flexslider && wc_single_product_params.flexslider_enabled; 107 this.zoom_enabled = 'function' === typeof $.fn.zoom && wc_single_product_params.zoom_enabled; 108 this.photoswipe_enabled = typeof PhotoSwipe !== 'undefined' && wc_single_product_params.photoswipe_enabled; 109 110 // ...also taking args into account. 111 if ( args ) { 112 this.flexslider_enabled = false === args.flexslider_enabled ? false : this.flexslider_enabled; 113 this.zoom_enabled = false === args.zoom_enabled ? false : this.zoom_enabled; 114 this.photoswipe_enabled = false === args.photoswipe_enabled ? false : this.photoswipe_enabled; 115 } 116 117 // ...and what is in the gallery. 118 if ( 1 === this.$images.length ) { 119 this.flexslider_enabled = false;
120 } 121 122 // Bind functions to this. 123 this.initFlexslider = this.initFlexslider.bind( this ); 124 this.initZoom = this.initZoom.bind( this ); 125 this.initZoomForTarget = this.initZoomForTarget.bind( this ); 126 this.initPhotoswipe = this.initPhotoswipe.bind( this ); 127 this.onResetSlidePosition = this.onResetSlidePosition.bind( this ); 128 this.getGalleryItems = this.getGalleryItems.bind( this ); 129 this.openPhotoswipe = this.openPhotoswipe.bind( this ); 130 131 if ( this.flexslider_enabled ) { 132 this.initFlexslider( args.flexslider ); 133 $target.on( 'woocommerce_gallery_reset_slide_position', this.onResetSlidePosition ); 134 } else { 135 this.$target.css( 'opacity', 1 ); 136 } 137 138 if ( this.zoom_enabled ) { 139 this.initZoom(); 140 $target.on( 'woocommerce_gallery_init_zoom', this.initZoom ); 141 } 142 143 if ( this.photoswipe_enabled ) { 144 this.initPhotoswipe(); 145 } 146 }; 147 148 /** 149 * Initialize flexSlider. 150 */ 151 ProductGallery.prototype.initFlexslider = function( args ) { 152 var $target = this.$target, 153 gallery = this; 154 155 var options = $.extend( { 156 selector: '.woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image', 157 start: function() { 158 $target.css( 'opacity', 1 ); 159 }, 160 after: function( slider ) { 161 gallery.initZoomForTarget( gallery.$images.eq( slider.currentSlide ) ); 162 } 163 }, args ); 164 165 $target.flexslider( options ); 166 167 // Trigger resize after main image loads to ensure correct gallery size. 168 $( '.woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image:eq(0) .wp-post-image' ).one( 'load', function() { 169 var $image = $( this ); 170 171 if ( $image ) { 172 setTimeout( function() { 173 var setHeight = $image.closest( '.woocommerce-product-gallery__image' ).height(); 174 var $viewport = $image.closest( '.flex-viewport' ); 175 176 if ( setHeight && $viewport ) { 177 $viewport.height( setHeight ); 178 } 179 }, 100 ); 180 } 181 } ).each( function() { 182 if ( this.complete ) { 183 $( this ).trigger( 'load' ); 184 } 185 } ); 186 }; 187 188 /** 189 * Init zoom. 190 */ 191 ProductGallery.prototype.initZoom = function() { 192 this.initZoomForTarget( this.$images.first() ); 193 }; 194 195 /** 196 * Init zoom. 197 */ 198 ProductGallery.prototype.initZoomForTarget = function( zoomTarget ) { 199 if ( ! this.zoom_enabled ) { 200 return false; 201 } 202 203 var galleryWidth = this.$target.width(), 204 zoomEnabled = false; 205 206 $( zoomTarget ).each( function( index, target ) { 207 var image = $( target ).find( 'img' ); 208 209 if ( image.data( 'large_image_width' ) > galleryWidth ) { 210 zoomEnabled = true; 211 return false; 212 } 213 } ); 214 215 // But only zoom if the img is larger than its container. 216 if ( zoomEnabled ) { 217 var zoom_options = $.extend( { 218 touch: false, 219 callback: function() { 220 var zoomImg = this; 221 222 setTimeout( function() { 223 zoomImg.removeAttribute( 'role' ); 224 zoomImg.setAttribute( 'alt', '' ); 225 zoomImg.setAttribute( 'aria-hidden', 'true' ); 226 }, 100 ); 227 } 228 }, wc_single_product_params.zoom_options ); 229 230 if ( 'ontouchstart' in document.documentElement ) { 231 zoom_options.on = 'click'; 232 } 233 234 zoomTarget.trigger( 'zoom.destroy' ); 235 zoomTarget.zoom( zoom_options ); 236 237 setTimeout( function() { 238 if ( zoomTarget.find(':hover').length ) { 239 zoomTarget.trigger( 'mouseover' ); 240 } 241 }, 100 ); 242 } 243 }; 244 245 /** 246 * Init PhotoSwipe. 247 */ 248 ProductGallery.prototype.initPhotoswipe = function() { 249 if ( this.zoom_enabled && this.$images.length > 0 ) { 250 this.$target.prepend( '<a href="#" class="woocommerce-product-gallery__trigger">ð</a>' ); 251 this.$target.on( 'click', '.woocommerce-product-gallery__trigger', this.openPhotoswipe ); 252 this.$target.on( 'click', '.woocommerce-product-gallery__image a', function( e ) { 253 e.preventDefault(); 254 }); 255 256 // If flexslider is disabled, gallery images also need to trigger photoswipe on click. 257 if ( ! this.flexslider_enabled ) { 258 this.$target.on( 'click', '.woocommerce-product-gallery__image a', this.openPhotoswipe ); 259 } 260 } else { 261 this.$target.on( 'click', '.woocommerce-product-gallery__image a', this.openPhotoswipe ); 262 } 263 }; 264 265 /** 266 * Reset slide position to 0. 267 */ 268 ProductGallery.prototype.onResetSlidePosition = function() { 269 this.$target.flexslider( 0 ); 270 }; 271 272 /** 273 * Get product gallery image items. 274 */ 275 ProductGallery.prototype.getGalleryItems = function() { 276 var $slides = this.$images, 277 items = []; 278 279 if ( $slides.length > 0 ) { 280 $slides.each( function( i, el ) { 281 var img = $( el ).find( 'img' ); 282 283 if ( img.length ) { 284 var large_image_src = img.attr( 'data-large_image' ), 285 large_image_w = img.attr( 'data-large_image_width' ), 286 large_image_h = img.attr( 'data-large_image_height' ), 287 alt = img.attr( 'alt' ), 288 item = { 289 alt : alt, 290 src : large_image_src, 291 w : large_image_w, 292 h : large_image_h, 293 title: img.attr( 'data-caption' ) ? img.attr( 'data-caption' ) : img.attr( 'title' ) 294 }; 295 items.push( item ); 296 } 297 } ); 298 } 299 300 return items; 301 }; 302 303 /** 304 * Open photoswipe modal. 305 */ 306 ProductGallery.prototype.openPhotoswipe = function( e ) { 307 e.preventDefault(); 308 309 var pswpElement = $( '.pswp' )[0], 310 items = this.getGalleryItems(), 311 eventTarget = $( e.target ), 312 clicked; 313 314 if ( 0 < eventTarget.closest( '.woocommerce-product-gallery__trigger' ).length ) { 315 clicked = this.$target.find( '.flex-active-slide' ); 316 } else { 317 clicked = eventTarget.closest( '.woocommerce-product-gallery__image' ); 318 } 319 320 var options = $.extend( { 321 index: $( clicked ).index(), 322 addCaptionHTMLFn: function( item, captionEl ) { 323 if ( ! item.title ) { 324 captionEl.children[0].textContent = ''; 325 return false;
326 } 327 captionEl.children[0].textContent = item.title; 328 return true; 329 } 330 }, wc_single_product_params.photoswipe_options ); 331 332 // Initializes and opens PhotoSwipe. 333 var photoswipe = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options ); 334 photoswipe.init(); 335 }; 336 337 /** 338 * Function to call wc_product_gallery on jquery selector. 339 */ 340 $.fn.wc_product_gallery = function( args ) { 341 new ProductGallery( this, args || wc_single_product_params ); 342 return this; 343 }; 344 345 /* 346 * Initialize all galleries on page. 347 */ 348 $( '.woocommerce-product-gallery' ).each( function() { 349 350 $( this ).trigger( 'wc-product-gallery-before-init', [ this, wc_single_product_params ] ); 351 352 $( this ).wc_product_gallery( wc_single_product_params ); 353 354 $( this ).trigger( 'wc-product-gallery-after-init', [ this, wc_single_product_params ] ); 355 356 } ); 357} );
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.