Merge pull request #13592 from woocommerce/13572-prototype-pattern

Reusable galleries
This commit is contained in:
Mike Jolley 2017-03-14 18:26:22 +00:00 committed by GitHub
commit 448954b9ad
6 changed files with 219 additions and 190 deletions

View File

@ -21,10 +21,10 @@
this.$attributeFields.unbind( 'change ' );
// Methods.
this.getChosenAttributes = this.getChosenAttributes.bind( this );
this.getChosenAttributes = this.getChosenAttributes.bind( this );
this.findMatchingVariations = this.findMatchingVariations.bind( this );
this.isMatch = this.isMatch.bind( this );
this.toggleResetLink = this.toggleResetLink.bind( this );
this.isMatch = this.isMatch.bind( this );
this.toggleResetLink = this.toggleResetLink.bind( this );
// Events.
$form.on( 'click', '.reset_variations', { variationForm: this }, this.onReset );
@ -527,7 +527,9 @@
* Reset the slide position if the variation has a different image than the current one
*/
$.fn.wc_maybe_trigger_slide_position_reset = function( variation ) {
var $form = $( this ),
var $form = $( this ),
$product = $form.closest( '.product' ),
$product_gallery = $product.find( '.images' ),
reset_slide_position = false,
new_image_id = ( variation && variation.image_id ) ? variation.image_id : '';
@ -538,7 +540,7 @@
$form.attr( 'current-image', new_image_id );
if ( reset_slide_position ) {
$( 'body' ).trigger( 'woocommerce_gallery_reset_slide_position' );
$product_gallery.trigger( 'woocommerce_gallery_reset_slide_position' );
}
};
@ -548,9 +550,9 @@
$.fn.wc_variations_image_update = function( variation ) {
var $form = this,
$product = $form.closest( '.product' ),
$product_gallery = $product.find( '.images' ),
$gallery_img = $product.find( '.flex-control-nav li:eq(0) img' ),
$gallery_wrapper = $product.find( '.woocommerce-product-gallery__wrapper ' ),
$product_img_wrap = $gallery_wrapper.find( '.woocommerce-product-gallery__image, .woocommerce-product-gallery__image--placeholder' ).eq( 0 ),
$product_img_wrap = $product_gallery.find( '.woocommerce-product-gallery__image, .woocommerce-product-gallery__image--placeholder' ).eq( 0 ),
$product_img = $product_img_wrap.find( '.wp-post-image' );
if ( variation && variation.image && variation.image.src && variation.image.src.length > 1 ) {
@ -561,9 +563,9 @@
$product_img.wc_set_variation_attr( 'sizes', variation.image.sizes );
$product_img.wc_set_variation_attr( 'title', variation.image.title );
$product_img.wc_set_variation_attr( 'alt', variation.image.alt );
$product_img.wc_set_variation_attr( 'data-large-image', variation.image.full_src );
$product_img.wc_set_variation_attr( 'data-large-image-width', variation.image.full_src_w );
$product_img.wc_set_variation_attr( 'data-large-image-height', variation.image.full_src_h );
$product_img.wc_set_variation_attr( 'data-large_image', variation.image.full_src );
$product_img.wc_set_variation_attr( 'data-large_image_width', variation.image.full_src_w );
$product_img.wc_set_variation_attr( 'data-large_image_height', variation.image.full_src_h );
$product_img_wrap.wc_set_variation_attr( 'data-thumb', variation.image.src );
$gallery_img.wc_set_variation_attr( 'src', variation.image.src );
} else {
@ -574,16 +576,15 @@
$product_img.wc_reset_variation_attr( 'sizes' );
$product_img.wc_reset_variation_attr( 'title' );
$product_img.wc_reset_variation_attr( 'alt' );
$product_img.wc_reset_variation_attr( 'data-large-image' );
$product_img.wc_reset_variation_attr( 'data-large-image-width' );
$product_img.wc_reset_variation_attr( 'data-large-image-height' );
$product_img.wc_reset_variation_attr( 'data-large_image' );
$product_img.wc_reset_variation_attr( 'data-large_image_width' );
$product_img.wc_reset_variation_attr( 'data-large_image_height' );
$product_img_wrap.wc_reset_variation_attr( 'data-thumb' );
$product_img.wc_reset_variation_attr( 'large-image' );
$gallery_img.wc_reset_variation_attr( 'src' );
}
window.setTimeout( function() {
$( 'body' ).trigger( 'woocommerce_init_gallery' );
$product_gallery.trigger( 'woocommerce_gallery_init_zoom' );
$form.wc_maybe_trigger_slide_position_reset( variation );
$( window ).trigger( 'resize' );
}, 10 );

View File

@ -1,13 +1,13 @@
/*global wc_single_product_params, PhotoSwipe, PhotoSwipeUI_Default */
jQuery( function( $ ) {
// wc_single_product_params is required to continue, ensure the object exists
// wc_single_product_params is required to continue.
if ( typeof wc_single_product_params === 'undefined' ) {
return false;
}
// Tabs
$( 'body' )
// Tabs
.on( 'init', '.wc-tabs-wrapper, .woocommerce-tabs', function() {
$( '.wc-tab, .woocommerce-tabs .panel:not(.panel .panel)' ).hide();
@ -22,7 +22,7 @@ jQuery( function( $ ) {
} else {
$tabs.find( 'li:first a' ).click();
}
})
} )
.on( 'click', '.wc-tabs li a, ul.tabs li a', function( e ) {
e.preventDefault();
var $tab = $( this );
@ -34,16 +34,16 @@ jQuery( function( $ ) {
$tab.closest( 'li' ).addClass( 'active' );
$tabs_wrapper.find( $tab.attr( 'href' ) ).show();
})
} )
// Review link
.on( 'click', 'a.woocommerce-review-link', function() {
$( '.reviews_tab a' ).click();
return true;
})
} )
// Star ratings for comments
.on( 'init', '#rating', function() {
$( '#rating' ).hide().before( '<p class="stars"><span><a class="star-1" href="#">1</a><a class="star-2" href="#">2</a><a class="star-3" href="#">3</a><a class="star-4" href="#">4</a><a class="star-5" href="#">5</a></span></p>' );
})
} )
.on( 'click', '#respond p.stars a', function() {
var $star = $( this ),
$rating = $( this ).closest( '#respond' ).find( '#rating' ),
@ -55,7 +55,7 @@ jQuery( function( $ ) {
$container.addClass( 'selected' );
return false;
})
} )
.on( 'click', '#respond #submit', function() {
var $rating = $( this ).closest( '#respond' ).find( '#rating' ),
rating = $rating.val();
@ -65,173 +65,206 @@ jQuery( function( $ ) {
return false;
}
})
.on( 'woocommerce_init_gallery', function() {
if ( $.isFunction( $.fn.zoom ) && wc_single_product_params.zoom_enabled ) {
wc_product_gallery.init_zoom();
}
});
} );
//Init Tabs and Star Ratings
// Init Tabs and Star Ratings
$( '.wc-tabs-wrapper, .woocommerce-tabs, #rating' ).trigger( 'init' );
/**
* Product gallery class.
*/
var wc_product_gallery = {
var ProductGallery = function( $target, args ) {
this.$target = $target;
this.$images = $( '.woocommerce-product-gallery__image', $target );
/**
* Initialize gallery actions and events.
*/
init: function() {
if ( $.isFunction( $.fn.flexslider ) && wc_single_product_params.flexslider_enabled ) {
this.init_flexslider();
}
if ( $.isFunction( $.fn.zoom ) && wc_single_product_params.zoom_enabled ) {
this.init_zoom();
}
if ( typeof PhotoSwipe !== 'undefined' && wc_single_product_params.photoswipe_enabled ) {
this.init_photoswipe();
}
},
// Make this object available.
$target.data( 'product_gallery', this );
/**
* Initialize flexSlider.
*/
init_flexslider: function() {
$( '.woocommerce-product-gallery' ).flexslider({
selector: '.woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image',
animation: wc_single_product_params.flexslider.animation,
smoothHeight: wc_single_product_params.flexslider.smoothHeight,
directionNav: wc_single_product_params.flexslider.directionNav,
controlNav: wc_single_product_params.flexslider.controlNav,
slideshow: wc_single_product_params.flexslider.slideshow,
animationSpeed: wc_single_product_params.flexslider.animationSpeed,
animationLoop: wc_single_product_params.flexslider.animationLoop, // Breaks photoswipe pagination if true.
start: function() {
var $images = $( '.woocommerce-product-gallery__image' );
var largest_height = 0;
// Pick functionality to initialize...
this.flexslider_enabled = $.isFunction( $.fn.flexslider ) && wc_single_product_params.flexslider_enabled;
this.zoom_enabled = $.isFunction( $.fn.zoom ) && wc_single_product_params.zoom_enabled;
this.photoswipe_enabled = typeof PhotoSwipe !== 'undefined' && wc_single_product_params.photoswipe_enabled;
$images.each( function() {
var height = $( this ).height();
// ...also taking args into account.
if ( args ) {
this.flexslider_enabled = false === args.photoswipe_enabled ? false : this.flexslider_enabled;
this.zoom_enabled = false === args.zoom_enabled ? false : this.zoom_enabled;
this.photoswipe_enabled = false === args.photoswipe_enabled ? false : this.photoswipe_enabled;
}
if ( height > largest_height ) {
largest_height = height;
}
});
// Bind functions to this.
this.initFlexslider = this.initFlexslider.bind( this );
this.initZoom = this.initZoom.bind( this );
this.initPhotoswipe = this.initPhotoswipe.bind( this );
this.onResetSlidePosition = this.onResetSlidePosition.bind( this );
this.getGalleryItems = this.getGalleryItems.bind( this );
this.openPhotoswipe = this.openPhotoswipe.bind( this );
$images.each( function() {
$( this ).css( 'min-height', largest_height );
});
}
});
if ( this.flexslider_enabled ) {
this.initFlexslider();
$target.on( 'woocommerce_gallery_reset_slide_position', this.onResetSlidePosition );
}
$( 'body' ).on( 'woocommerce_gallery_reset_slide_position', function(){
$( '.woocommerce-product-gallery' ).flexslider( 0 );
} );
},
if ( this.zoom_enabled ) {
this.initZoom();
$target.on( 'woocommerce_gallery_init_zoom', this.initZoom );
}
/**
* Init zoom.
*/
init_zoom: function() {
var zoom_target = $( '.woocommerce-product-gallery__image' ),
enable_zoom = false;
if ( ! wc_single_product_params.flexslider_enabled ) {
zoom_target = zoom_target.first();
}
$( zoom_target ).each( function( index, target ) {
var image = $( target ).find( 'img' );
if ( image.attr( 'width' ) > $( '.woocommerce-product-gallery' ).width() ) {
enable_zoom = true;
return false;
}
} );
// But only zoom if the img is larger than its container.
if ( enable_zoom ) {
zoom_target.trigger( 'zoom.destroy' );
zoom_target.zoom({
touch: false
});
}
},
/**
* Get product gallery image items.
*/
get_gallery_items: function() {
var $slides = $( '.woocommerce-product-gallery__wrapper' ).children(),
items = [],
index = $slides.filter( '.' + 'flex-active-slide' ).index();
if ( $slides.length > 0 ) {
$slides.each( function( i, el ) {
var img = $( el ).find( 'img' ),
large_image_src = img.attr( 'data-large-image' ),
large_image_w = img.attr( 'data-large-image-width' ),
large_image_h = img.attr( 'data-large-image-height' ),
item = {
src: large_image_src,
w: large_image_w,
h: large_image_h,
title: img.attr( 'title' )
};
items.push( item );
});
}
return {
index: index,
items: items
};
},
/**
* Init PhotoSwipe.
*/
init_photoswipe: function() {
if ( wc_single_product_params.zoom_enabled ) {
$( '.woocommerce-product-gallery--with-images' ).prepend( '<a href="#" class="woocommerce-product-gallery__trigger">🔍</a>' );
$( document ).on( 'click', '.woocommerce-product-gallery__trigger', this.trigger_photoswipe );
}
$( document ).on( 'click', '.woocommerce-product-gallery__image a', this.trigger_photoswipe );
},
/**
* Initialise photoswipe.
*/
trigger_photoswipe: function( e ) {
e.preventDefault();
var pswpElement = $( '.pswp' )[0],
items = wc_product_gallery.get_gallery_items(),
target = $( e.target ),
clicked;
if ( ! target.is( '.woocommerce-product-gallery__trigger' ) ) {
clicked = e.target.closest( 'figure' );
} else {
clicked = target.parents( '.woocommerce-product-gallery' ).find( '.flex-active-slide' );
}
var options = {
index: $( clicked ).index(),
shareEl: false,
closeOnScroll: false,
history: false,
hideAnimationDuration: 0,
showAnimationDuration: 0
};
// Initializes and opens PhotoSwipe.
var gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items.items, options );
gallery.init();
if ( this.photoswipe_enabled ) {
this.initPhotoswipe();
}
};
wc_product_gallery.init();
});
/**
* Initialize flexSlider.
*/
ProductGallery.prototype.initFlexslider = function() {
var images = this.$images;
this.$target.flexslider( {
selector: '.woocommerce-product-gallery__wrapper > .woocommerce-product-gallery__image',
animation: wc_single_product_params.flexslider.animation,
smoothHeight: wc_single_product_params.flexslider.smoothHeight,
directionNav: wc_single_product_params.flexslider.directionNav,
controlNav: wc_single_product_params.flexslider.controlNav,
slideshow: wc_single_product_params.flexslider.slideshow,
animationSpeed: wc_single_product_params.flexslider.animationSpeed,
animationLoop: wc_single_product_params.flexslider.animationLoop, // Breaks photoswipe pagination if true.
start: function() {
var largest_height = 0;
images.each( function() {
var height = $( this ).height();
if ( height > largest_height ) {
largest_height = height;
}
} );
images.each( function() {
$( this ).css( 'min-height', largest_height );
} );
}
} );
};
/**
* Init zoom.
*/
ProductGallery.prototype.initZoom = function() {
var zoomTarget = this.$images,
galleryWidth = this.$target.width(),
zoomEnabled = false;
if ( ! this.flexslider_enabled ) {
zoomTarget = zoomTarget.first();
}
$( zoomTarget ).each( function( index, target ) {
var image = $( target ).find( 'img' );
if ( image.attr( 'width' ) > galleryWidth ) {
zoomEnabled = true;
return false;
}
} );
// But only zoom if the img is larger than its container.
if ( zoomEnabled ) {
zoomTarget.trigger( 'zoom.destroy' );
zoomTarget.zoom( {
touch: false
} );
}
};
/**
* Init PhotoSwipe.
*/
ProductGallery.prototype.initPhotoswipe = function() {
if ( this.zoom_enabled && this.$images.length > 0 ) {
this.$target.prepend( '<a href="#" class="woocommerce-product-gallery__trigger">🔍</a>' );
this.$target.on( 'click', '.woocommerce-product-gallery__trigger', this.openPhotoswipe );
}
this.$target.on( 'click', '.woocommerce-product-gallery__image a', this.openPhotoswipe );
};
/**
* Reset slide position to 0.
*/
ProductGallery.prototype.onResetSlidePosition = function() {
this.$target.flexslider( 0 );
};
/**
* Get product gallery image items.
*/
ProductGallery.prototype.getGalleryItems = function() {
var $slides = this.$images,
items = [];
if ( $slides.length > 0 ) {
$slides.each( function( i, el ) {
var img = $( el ).find( 'img' ),
large_image_src = img.attr( 'data-large_image' ),
large_image_w = img.attr( 'data-large_image_width' ),
large_image_h = img.attr( 'data-large_image_height' ),
item = {
src: large_image_src,
w: large_image_w,
h: large_image_h,
title: img.attr( 'title' )
};
items.push( item );
} );
}
return items;
};
/**
* Open photoswipe modal.
*/
ProductGallery.prototype.openPhotoswipe = function( e ) {
e.preventDefault();
var pswpElement = $( '.pswp' )[0],
items = this.getGalleryItems(),
eventTarget = $( e.target ),
clicked;
if ( ! eventTarget.is( '.woocommerce-product-gallery__trigger' ) ) {
clicked = eventTarget.closest( '.woocommerce-product-gallery__image' );
} else {
clicked = this.$target.find( '.flex-active-slide' );
}
var options = {
index: $( clicked ).index(),
shareEl: false,
closeOnScroll: false,
history: false,
hideAnimationDuration: 0,
showAnimationDuration: 0
};
// Initializes and opens PhotoSwipe.
var photoswipe = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options );
photoswipe.init();
};
/**
* Function to call wc_product_gallery on jquery selector.
*/
$.fn.wc_product_gallery = function( args ) {
new ProductGallery( this, args );
return this;
};
/*
* Initialize all galleries on page.
*/
$( '.woocommerce-product-gallery' ).each( function() {
$( this ).wc_product_gallery();
} );
} );

File diff suppressed because one or more lines are too long

View File

@ -19,17 +19,12 @@
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! is_product() ) {
return;
}
?>
<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
<!-- Background of PhotoSwipe.
It's a separate element as animating opacity is faster than rgba(). -->
<!-- Background of PhotoSwipe. It's a separate element as animating opacity is faster than rgba(). -->
<div class="pswp__bg"></div>
<!-- Slides wrapper with overflow:hidden. -->

View File

@ -38,10 +38,10 @@ $wrapper_classes = apply_filters( 'woocommerce_single_product_image_gallery_cl
<figure class="woocommerce-product-gallery__wrapper">
<?php
$attributes = array(
'title' => $image_title,
'data-large-image' => $full_size_image[0],
'data-large-image-width' => $full_size_image[1],
'data-large-image-height' => $full_size_image[2],
'title' => $image_title,
'data-large_image' => $full_size_image[0],
'data-large_image_width' => $full_size_image[1],
'data-large_image_height' => $full_size_image[2],
);
if ( has_post_thumbnail() ) {

View File

@ -33,9 +33,9 @@ if ( $attachment_ids && has_post_thumbnail() ) {
$attributes = array(
'title' => $image_title,
'data-large-image' => $full_size_image[0],
'data-large-image-width' => $full_size_image[1],
'data-large-image-height' => $full_size_image[2],
'data-large_image' => $full_size_image[0],
'data-large_image_width' => $full_size_image[1],
'data-large_image_height' => $full_size_image[2],
);
$html = '<div data-thumb="' . esc_url( $thumbnail[0] ) . '" class="woocommerce-product-gallery__image"><a href="' . esc_url( $full_size_image[0] ) . '">';