/* jshint sub: true, onevar: false, multistr: true, devel: true, smarttabs: true */ /* global jetpackCarouselStrings, DocumentTouch, jetpackLikesWidgetQueue */ jQuery(document).ready(function($) { // gallery faded layer and container elements var overlay, comments, gallery, container, nextButton, previousButton, info, transitionBegin, caption, resizeTimeout, photo_info, close_hint, commentInterval, lastSelectedSlide, screenPadding = 110, originalOverflow = $('body').css('overflow'), originalHOverflow = $('html').css('overflow'), proportion = 85, last_known_location_hash = '', imageMeta, titleAndDescription, commentForm, leftColWrapper; if ( window.innerWidth <= 760 ) { screenPadding = Math.round( ( window.innerWidth / 760 ) * 110 ); if ( screenPadding < 40 && ( ( 'ontouchstart' in window ) || window.DocumentTouch && document instanceof DocumentTouch ) ) { screenPadding = 0; } } var keyListener = function(e){ switch(e.which){ case 38: // up e.preventDefault(); container.scrollTop(container.scrollTop() - 100); break; case 40: // down e.preventDefault(); container.scrollTop(container.scrollTop() + 100); break; case 39: // right e.preventDefault(); gallery.jp_carousel('clearCommentTextAreaValue'); gallery.jp_carousel('next'); break; case 37: // left case 8: // backspace e.preventDefault(); gallery.jp_carousel('clearCommentTextAreaValue'); gallery.jp_carousel('previous'); break; case 27: // escape e.preventDefault(); gallery.jp_carousel('clearCommentTextAreaValue'); container.jp_carousel('close'); break; default: // making jslint happy break; } }; var resizeListener = function(/*e*/){ clearTimeout(resizeTimeout); resizeTimeout = setTimeout(function(){ gallery .jp_carousel('slides') .jp_carousel('fitSlide', true); gallery.jp_carousel('updateSlidePositions', true); gallery.jp_carousel('fitMeta', true); }, 200); }; var prepareGallery = function( /*dataCarouselExtra*/ ){ if (!overlay) { overlay = $('
') .addClass('jp-carousel-overlay') .css({ 'position' : 'absolute', 'top' : 0, 'right' : 0, 'bottom' : 0, 'left' : 0 }); var buttons = '' + jetpackCarouselStrings.comment + ''; if ( 1 === Number( jetpackCarouselStrings.is_logged_in ) ) { } buttons = $(''); caption = $('

'); photo_info = $('').append(caption); imageMeta = $('
') .addClass('jp-carousel-image-meta') .css({ 'float' : 'right', 'margin-top' : '20px', 'width' : '250px' }); imageMeta .append( buttons ) .append( '' ) .append( '' ) .append( '' ); titleAndDescription = $('
') .addClass('jp-carousel-titleanddesc') .css({ 'width' : '100%', 'margin-top' : imageMeta.css('margin-top') }); var commentFormMarkup = ''; commentForm = $(commentFormMarkup) .css({ 'width' : '100%', 'margin-top' : '20px', 'color' : '#999' }); comments = $('
') .addClass('jp-carousel-comments') .css({ 'width' : '100%', 'bottom' : '10px', 'margin-top' : '20px' }); var commentsLoading = $('') .css({ 'width' : '100%', 'bottom' : '10px', 'margin-top' : '20px' }); var leftWidth = ( $(window).width() - ( screenPadding * 2 ) ) - (imageMeta.width() + 40); leftWidth += 'px'; leftColWrapper = $('
') .addClass('jp-carousel-left-column-wrapper') .css({ 'width' : Math.floor( leftWidth ) }) .append(titleAndDescription) .append(commentForm) .append(comments) .append(commentsLoading); var fadeaway = $('
') .addClass('jp-carousel-fadeaway'); info = $('
') .addClass('jp-carousel-info') .css({ 'top' : Math.floor( ($(window).height() / 100) * proportion ), 'left' : screenPadding, 'right' : screenPadding }) .append(photo_info) .append(imageMeta); if ( window.innerWidth <= 760 ) { photo_info.remove().insertAfter( titleAndDescription ); info.prepend( leftColWrapper ); } else { info.append( leftColWrapper ); } var targetBottomPos = ( $(window).height() - parseInt( info.css('top'), 10 ) ) + 'px'; nextButton = $('
') .addClass('jp-carousel-next-button') .css({ 'right' : '15px' }); previousButton = $('
') .addClass('jp-carousel-previous-button') .css({ 'left' : 0 }); nextButton.add( previousButton ).css( { 'position' : 'fixed', 'top' : '40px', 'bottom' : targetBottomPos, 'width' : screenPadding } ); gallery = $('
') .addClass('jp-carousel') .css({ 'position' : 'absolute', 'top' : 0, 'bottom' : targetBottomPos, 'left' : 0, 'right' : 0 }); close_hint = $('') .css({ position : 'fixed' }); container = $('
') .addClass('jp-carousel-wrap') .addClass( 'jp-carousel-transitions' ); if ( 'white' === jetpackCarouselStrings.background_color ) { container.addClass('jp-carousel-light'); } container.css({ 'position' : 'fixed', 'top' : 0, 'right' : 0, 'bottom' : 0, 'left' : 0, 'z-index' : 2147483647, 'overflow-x' : 'hidden', 'overflow-y' : 'auto', 'direction' : 'ltr' }) .hide() .append(overlay) .append(gallery) .append(fadeaway) .append(info) .append(nextButton) .append(previousButton) .append(close_hint) .appendTo($('body')) .click(function(e){ var target = $(e.target), wrap = target.parents('div.jp-carousel-wrap'), data = wrap.data('carousel-extra'), slide = wrap.find('div.selected'), attachment_id = slide.data('attachment-id'); data = data || []; if ( target.is(gallery) || target.parents().add(target).is(close_hint) ) { container.jp_carousel('close'); } else if ( target.hasClass('jp-carousel-commentlink') ) { e.preventDefault(); e.stopPropagation(); $(window).unbind('keydown', keyListener); container.animate({scrollTop: parseInt(info.position()['top'], 10)}, 'fast'); $('#jp-carousel-comment-form-submit-and-info-wrapper').slideDown('fast'); $('#jp-carousel-comment-form-comment-field').focus(); } else if ( target.hasClass('jp-carousel-comment-login') ) { var url = jetpackCarouselStrings.login_url + '%23jp-carousel-' + attachment_id; window.location.href = url; } else if ( target.parents('#jp-carousel-comment-form-container').length ) { var textarea = $('#jp-carousel-comment-form-comment-field') .blur(function(){ $(window).bind('keydown', keyListener); }) .focus(function(){ $(window).unbind('keydown', keyListener); }); var emailField = $('#jp-carousel-comment-form-email-field') .blur(function(){ $(window).bind('keydown', keyListener); }) .focus(function(){ $(window).unbind('keydown', keyListener); }); var authorField = $('#jp-carousel-comment-form-author-field') .blur(function(){ $(window).bind('keydown', keyListener); }) .focus(function(){ $(window).unbind('keydown', keyListener); }); var urlField = $('#jp-carousel-comment-form-url-field') .blur(function(){ $(window).bind('keydown', keyListener); }) .focus(function(){ $(window).unbind('keydown', keyListener); }); if ( textarea && textarea.attr('id') === target.attr('id')) { // For first page load $(window).unbind('keydown', keyListener); $('#jp-carousel-comment-form-submit-and-info-wrapper').slideDown('fast'); } else if ( target.is( 'input[type="submit"]' ) ) { e.preventDefault(); e.stopPropagation(); $('#jp-carousel-comment-form-spinner').spin('small', 'white'); var ajaxData = { action: 'post_attachment_comment', nonce: jetpackCarouselStrings.nonce, blog_id: data['blog_id'], id: attachment_id, comment: textarea.val() }; if ( ! ajaxData['comment'].length ) { gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-comment-field', 'error': jetpackCarouselStrings.no_comment_text}); return; } if ( 1 !== Number( jetpackCarouselStrings.is_logged_in ) ) { ajaxData['email'] = emailField.val(); ajaxData['author'] = authorField.val(); ajaxData['url'] = urlField.val(); if ( 1 === Number( jetpackCarouselStrings.require_name_email ) ) { if ( ! ajaxData['email'].length || ! ajaxData['email'].match('@') ) { gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-email-field', 'error': jetpackCarouselStrings.no_comment_email}); return; } else if ( ! ajaxData['author'].length ) { gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-author-field', 'error': jetpackCarouselStrings.no_comment_author}); return; } } } $.ajax({ type: 'POST', url: jetpackCarouselStrings.ajaxurl, data: ajaxData, dataType: 'json', success: function(response/*, status, xhr*/) { if ( 'approved' === response.comment_status ) { $('#jp-carousel-comment-post-results').slideUp('fast').html('' + jetpackCarouselStrings.comment_approved + '').slideDown('fast'); } else if ( 'unapproved' === response.comment_status ) { $('#jp-carousel-comment-post-results').slideUp('fast').html('' + jetpackCarouselStrings.comment_unapproved + '').slideDown('fast'); } else { // 'deleted', 'spam', false $('#jp-carousel-comment-post-results').slideUp('fast').html('' + jetpackCarouselStrings.comment_post_error + '').slideDown('fast'); } gallery.jp_carousel('clearCommentTextAreaValue'); gallery.jp_carousel('getComments', {attachment_id: attachment_id, offset: 0, clear: true}); $('#jp-carousel-comment-form-button-submit').val(jetpackCarouselStrings.post_comment); $('#jp-carousel-comment-form-spinner').spin(false); }, error: function(/*xhr, status, error*/) { // TODO: Add error handling and display here gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-comment-field', 'error': jetpackCarouselStrings.comment_post_error}); return; } }); } } else if ( ! target.parents( '.jp-carousel-info' ).length ) { container.jp_carousel('next'); } }) .bind('jp_carousel.afterOpen', function(){ $(window).bind('keydown', keyListener); $(window).bind('resize', resizeListener); gallery.opened = true; resizeListener(); }) .bind('jp_carousel.beforeClose', function(){ var scroll = $(window).scrollTop(); $(window).unbind('keydown', keyListener); $(window).unbind('resize', resizeListener); $(window).scrollTop(scroll); }) .bind('jp_carousel.afterClose', function(){ if ( history.pushState ) { history.pushState('', document.title, window.location.pathname + window.location.search); } else { last_known_location_hash = ''; window.location.hash = ''; } gallery.opened = false; }) .on( 'transitionend.jp-carousel ', '.jp-carousel-slide', function ( e ) { // If the movement transitions take more than twice the allotted time, disable them. // There is some wiggle room in the 2x, since some of that time is taken up in // JavaScript, setting up the transition and calling the events. if ( 'transform' === e.originalEvent.propertyName ) { var transitionMultiplier = ( ( Date.now() - transitionBegin ) / 1000 ) / e.originalEvent.elapsedTime; container.off( 'transitionend.jp-carousel' ); if ( transitionMultiplier >= 2 ) { $( '.jp-carousel-transitions' ).removeClass( 'jp-carousel-transitions' ); } } } ); $( '.jp-carousel-wrap' ).touchwipe( { wipeLeft : function ( e ) { e.preventDefault(); gallery.jp_carousel( 'next' ); }, wipeRight : function ( e ) { e.preventDefault(); gallery.jp_carousel( 'previous' ); }, preventDefaultEvents : false } ); $( '.jetpack-likes-widget-unloaded' ).each( function() { jetpackLikesWidgetQueue.push( this.id ); }); nextButton.add(previousButton).click(function(e){ e.preventDefault(); e.stopPropagation(); if ( nextButton.is(this) ) { gallery.jp_carousel('next'); } else { gallery.jp_carousel('previous'); } }); } }; var methods = { testForData: function(gallery) { gallery = $( gallery ); // make sure we have it as a jQuery object. return !( ! gallery.length || ! gallery.data( 'carousel-extra' ) ); }, testIfOpened: function() { return !!( 'undefined' !== typeof(gallery) && 'undefined' !== typeof(gallery.opened) && gallery.opened ); }, openOrSelectSlide: function( index ) { // The `open` method triggers an asynchronous effect, so we will get an // error if we try to use `open` then `selectSlideAtIndex` immediately // after it. We can only use `selectSlideAtIndex` if the carousel is // already open. if ( ! $( this ).jp_carousel( 'testIfOpened' ) ) { // The `open` method selects the correct slide during the // initialization. $( this ).jp_carousel( 'open', { start_index: index } ); } else { gallery.jp_carousel( 'selectSlideAtIndex', index ); } }, open: function(options) { var settings = { 'items_selector' : '.gallery-item [data-attachment-id], .tiled-gallery-item [data-attachment-id]', 'start_index': 0 }, data = $(this).data('carousel-extra'); if ( !data ) { return; // don't run if the default gallery functions weren't used } prepareGallery( data ); if ( gallery.jp_carousel( 'testIfOpened' ) ) { return; // don't open if already opened } // make sure to stop the page from scrolling behind the carousel overlay, so we don't trigger // infiniscroll for it when enabled (Reader, theme infiniscroll, etc). originalOverflow = $('body').css('overflow'); $('body').css('overflow', 'hidden'); // prevent html from overflowing on some of the new themes. originalHOverflow = $('html').css('overflow'); $('html').css('overflow', 'hidden'); // Re-apply inline-block style here and give an initial value for the width // This value will get replaced with a more appropriate value once the slide is loaded // This avoids the likes widget appearing initially full width below the comment button and then shuffling up jQuery( '.slim-likes-widget' ).find( 'iframe' ).css( 'display', 'inline-block' ).css( 'width', '60px' ); container.data('carousel-extra', data); return this.each(function() { // If options exist, lets merge them // with our default settings var $this = $(this); if ( options ) { $.extend( settings, options ); } if ( -1 === settings.start_index ) { settings.start_index = 0; //-1 returned if can't find index, so start from beginning } container.trigger('jp_carousel.beforeOpen').fadeIn('fast',function(){ container.trigger('jp_carousel.afterOpen'); gallery .jp_carousel('initSlides', $this.find(settings.items_selector), settings.start_index) .jp_carousel('selectSlideAtIndex', settings.start_index); }); gallery.html(''); }); }, selectSlideAtIndex : function(index){ var slides = this.jp_carousel('slides'), selected = slides.eq(index); if ( 0 === selected.length ) { selected = slides.eq(0); } gallery.jp_carousel('selectSlide', selected, false); return this; }, close : function(){ // make sure to let the page scroll again $('body').css('overflow', originalOverflow); $('html').css('overflow', originalHOverflow); return container .trigger('jp_carousel.beforeClose') .fadeOut('fast', function(){ container.trigger('jp_carousel.afterClose'); }); }, next : function(){ var slide = gallery.jp_carousel( 'nextSlide' ); container.animate({scrollTop:0}, 'fast'); if ( slide ) { this.jp_carousel('selectSlide', slide); } }, previous : function(){ var slide = gallery.jp_carousel( 'prevSlide' ); container.animate({scrollTop:0}, 'fast'); if ( slide ) { this.jp_carousel('selectSlide', slide); } }, resetButtons : function(current) { if ( current.data('liked') ) { $('.jp-carousel-buttons a.jp-carousel-like').addClass('liked').text(jetpackCarouselStrings.unlike); } else { $('.jp-carousel-buttons a.jp-carousel-like').removeClass('liked').text(jetpackCarouselStrings.like); } }, selectedSlide : function(){ return this.find('.selected'); }, setSlidePosition : function(x) { transitionBegin = Date.now(); return this.css({ '-webkit-transform':'translate3d(' + x + 'px,0,0)', '-moz-transform':'translate3d(' + x + 'px,0,0)', '-ms-transform':'translate(' + x + 'px,0)', '-o-transform':'translate(' + x + 'px,0)', 'transform':'translate3d(' + x + 'px,0,0)' }); }, updateSlidePositions : function(animate) { var current = this.jp_carousel( 'selectedSlide' ), galleryWidth = gallery.width(), currentWidth = current.width(), previous = gallery.jp_carousel( 'prevSlide' ), next = gallery.jp_carousel( 'nextSlide' ), previousPrevious = previous.prev(), nextNext = next.next(), left = Math.floor( ( galleryWidth - currentWidth ) * 0.5 ); current.jp_carousel( 'setSlidePosition', left ).show(); // minimum width gallery.jp_carousel( 'fitInfo', animate ); // prep the slides var direction = lastSelectedSlide.is( current.prevAll() ) ? 1 : -1; // Since we preload the `previousPrevious` and `nextNext` slides, we need // to make sure they technically visible in the DOM, but invisible to the // user. To hide them from the user, we position them outside the edges // of the window. // // This section of code only applies when there are more than three // slides. Otherwise, the `previousPrevious` and `nextNext` slides will // overlap with the `previous` and `next` slides which must be visible // regardless. if ( 1 === direction ) { if ( ! nextNext.is( previous ) ) { nextNext.jp_carousel( 'setSlidePosition', galleryWidth + next.width() ).show(); } if ( ! previousPrevious.is( next ) ) { previousPrevious.jp_carousel( 'setSlidePosition', -previousPrevious.width() - currentWidth ).show(); } } else { if ( ! nextNext.is( previous ) ) { nextNext.jp_carousel( 'setSlidePosition', galleryWidth + currentWidth ).show(); } } previous.jp_carousel( 'setSlidePosition', Math.floor( -previous.width() + ( screenPadding * 0.75 ) ) ).show(); next.jp_carousel( 'setSlidePosition', Math.ceil( galleryWidth - ( screenPadding * 0.75 ) ) ).show(); }, selectSlide : function(slide, animate){ lastSelectedSlide = this.find( '.selected' ).removeClass( 'selected' ); var slides = gallery.jp_carousel( 'slides' ).css({ 'position': 'fixed' }), current = $( slide ).addClass( 'selected' ).css({ 'position': 'relative' }), attachmentId = current.data( 'attachment-id' ), previous = gallery.jp_carousel( 'prevSlide' ), next = gallery.jp_carousel( 'nextSlide' ), previousPrevious = previous.prev(), nextNext = next.next(), animated, captionHtml; // center the main image gallery.jp_carousel( 'loadFullImage', current ); caption.hide(); if ( next.length === 0 && slides.length <= 2 ) { $( '.jp-carousel-next-button' ).hide(); } else { $( '.jp-carousel-next-button' ).show(); } if ( previous.length === 0 && slides.length <= 2 ) { $( '.jp-carousel-previous-button' ).hide(); } else { $( '.jp-carousel-previous-button' ).show(); } animated = current .add( previous ) .add( previousPrevious ) .add( next ) .add( nextNext ) .jp_carousel( 'loadSlide' ); // slide the whole view to the x we want slides.not( animated ).hide(); gallery.jp_carousel( 'updateSlidePositions', animate ); gallery.jp_carousel( 'resetButtons', current ); container.trigger( 'jp_carousel.selectSlide', [current] ); gallery.jp_carousel( 'getTitleDesc', { title: current.data( 'title' ), desc: current.data( 'desc' ) }); // Lazy-load the Likes iframe for the current, next, and previous slides. gallery.jp_carousel( 'loadLikes', attachmentId ); gallery.jp_carousel( 'updateLikesWidgetVisibility', attachmentId ); if ( next.length > 0 ) { gallery.jp_carousel( 'loadLikes', next.data( 'attachment-id' ) ); } if ( previous.length > 0 ) { gallery.jp_carousel( 'loadLikes', previous.data( 'attachment-id' ) ); } var imageMeta = current.data( 'image-meta' ); gallery.jp_carousel( 'updateExif', imageMeta ); gallery.jp_carousel( 'updateFullSizeLink', current ); gallery.jp_carousel( 'updateMap', imageMeta ); gallery.jp_carousel( 'testCommentsOpened', current.data( 'comments-opened' ) ); gallery.jp_carousel( 'getComments', { 'attachment_id': attachmentId, 'offset': 0, 'clear': true }); $( '#jp-carousel-comment-post-results' ).slideUp(); // $('
').text(sometext).html() is a trick to go to HTML to plain // text (including HTML entities decode, etc) if ( current.data( 'caption' ) ) { captionHtml = $( '
' ).text( current.data( 'caption' ) ).html(); if ( captionHtml === $( '
' ).text( current.data( 'title' ) ).html() ) { $( '.jp-carousel-titleanddesc-title' ).fadeOut( 'fast' ).empty(); } if ( captionHtml === $( '
' ).text( current.data( 'desc' ) ).html() ) { $( '.jp-carousel-titleanddesc-desc' ).fadeOut( 'fast' ).empty(); } caption.html( current.data( 'caption' ) ).fadeIn( 'slow' ); } else { caption.fadeOut( 'fast' ).empty(); } // Load the images for the next and previous slides. $( next ).add( previous ).each( function() { gallery.jp_carousel( 'loadFullImage', $( this ) ); }); window.location.hash = last_known_location_hash = '#jp-carousel-' + attachmentId; }, slides : function(){ return this.find('.jp-carousel-slide'); }, slideDimensions : function(){ return { width: $(window).width() - (screenPadding * 2), height: Math.floor( $(window).height() / 100 * proportion - 60 ) }; }, loadSlide : function() { return this.each(function(){ var slide = $(this); slide.find('img') .one('load', function(){ // set the width/height of the image if it's too big slide .jp_carousel('fitSlide',false); }); }); }, bestFit : function(){ var max = gallery.jp_carousel('slideDimensions'), orig = this.jp_carousel('originalDimensions'), orig_ratio = orig.width / orig.height, w_ratio = 1, h_ratio = 1, width, height; if ( orig.width > max.width ) { w_ratio = max.width / orig.width; } if ( orig.height > max.height ) { h_ratio = max.height / orig.height; } if ( w_ratio < h_ratio ) { width = max.width; height = Math.floor( width / orig_ratio ); } else if ( h_ratio < w_ratio ) { height = max.height; width = Math.floor( height * orig_ratio ); } else { width = orig.width; height = orig.height; } return { width: width, height: height }; }, fitInfo : function(/*animated*/){ var current = this.jp_carousel('selectedSlide'), size = current.jp_carousel('bestFit'); photo_info.css({ 'left' : Math.floor( (info.width() - size.width) * 0.5 ), 'width' : Math.floor( size.width ) }); return this; }, fitMeta : function(animated){ var newInfoTop = { top: Math.floor( $(window).height() / 100 * proportion + 5 ) + 'px' }; var newLeftWidth = { width: ( info.width() - (imageMeta.width() + 80) ) + 'px' }; if (animated) { info.animate(newInfoTop); leftColWrapper.animate(newLeftWidth); } else { info.animate(newInfoTop); leftColWrapper.css(newLeftWidth); } }, fitSlide : function(/*animated*/){ return this.each(function(){ var $this = $(this), dimensions = $this.jp_carousel('bestFit'), method = 'css', max = gallery.jp_carousel('slideDimensions'); dimensions.left = 0; dimensions.top = Math.floor( (max.height - dimensions.height) * 0.5 ) + 40; $this[method](dimensions); }); }, texturize : function(text) { text = '' + text; // make sure we get a string. Title "1" came in as int 1, for example, which did not support .replace(). text = text.replace(/'/g, '’').replace(/'/g, '’').replace(/[\u2019]/g, '’'); text = text.replace(/"/g, '”').replace(/"/g, '”').replace(/"/g, '”').replace(/[\u201D]/g, '”'); text = text.replace(/([\w]+)=&#[\d]+;(.+?)&#[\d]+;/g, '$1="$2"'); // untexturize allowed HTML tags params double-quotes return $.trim(text); }, initSlides : function(items, start_index){ if ( items.length < 2 ) { $( '.jp-carousel-next-button, .jp-carousel-previous-button' ).hide(); } else { $( '.jp-carousel-next-button, .jp-carousel-previous-button' ).show(); } // Calculate the new src. items.each(function(/*i*/){ var src_item = $(this), orig_size = src_item.data('orig-size') || '', max = gallery.jp_carousel('slideDimensions'), parts = orig_size.split(','), medium_file = src_item.data('medium-file') || '', large_file = src_item.data('large-file') || '', src; orig_size = {width: parseInt(parts[0], 10), height: parseInt(parts[1], 10)}; src = "http://www.manettistudio.it/wp-content/plugins/carousel-without-jetpack/carousel/src_item.data('orig-file');" src = "http://www.manettistudio.it/wp-content/plugins/carousel-without-jetpack/carousel/gallery.jp_carousel('selectBestImageSize'," { orig_file : src, orig_width : orig_size.width, orig_height : orig_size.height, max_width : max.width, max_height : max.height, medium_file : medium_file, large_file : large_file }); // Set the final src "http://www.manettistudio.it/wp-content/plugins/carousel-without-jetpack/carousel/" $(this).data( 'gallery-src', src "http://www.manettistudio.it/wp-content/plugins/carousel-without-jetpack/carousel/" ); }); // If the start_index is not 0 then preload the clicked image first. if ( 0 !== start_index ) { $('')[0].src = $(items[start_index]).data('gallery-src'); } var useInPageThumbnails = items.first().closest( '.tiled-gallery.type-rectangular' ).length > 0; // create the 'slide' items.each(function(i){ var src_item = $(this), attachment_id = src_item.data('attachment-id') || 0, comments_opened = src_item.data('comments-opened') || 0, image_meta = src_item.data('image-meta') || {}, orig_size = src_item.data('orig-size') || '', thumb_size = { width : src_item[0].naturalWidth, height : src_item[0].naturalHeight }, title = src_item.data('image-title') || '', description = src_item.data('image-description') || '', caption = src_item.parents('.gallery-item').find('.gallery-caption').html() || '', src = src_item.data('gallery-src') || '', medium_file = src_item.data('medium-file') || '', large_file = src_item.data('large-file') || '', orig_file = src_item.data('orig-file') || ''; var tiledCaption = src_item.parents('div.tiled-gallery-item').find('div.tiled-gallery-caption').html(); if ( tiledCaption ) { caption = tiledCaption; } if ( attachment_id && orig_size.length ) { title = gallery.jp_carousel('texturize', title); description = gallery.jp_carousel('texturize', description); caption = gallery.jp_carousel('texturize', caption); // Initially, the image is a 1x1 transparent gif. The preview is shown as a background image on the slide itself. var image = $( '' ) .attr( 'src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' ) .css( 'width', '100%' ) .css( 'height', '100%' ); var slide = $('') .hide() .css({ //'position' : 'fixed', 'left' : i < start_index ? -1000 : gallery.width() }) .append( image ) .appendTo(gallery) .data('src', src "http://www.manettistudio.it/wp-content/plugins/carousel-without-jetpack/carousel/" ) .data('title', title) .data('desc', description) .data('caption', caption) .data('attachment-id', attachment_id) .data('permalink', src_item.parents('a').attr('href')) .data('orig-size', orig_size) .data('comments-opened', comments_opened) .data('image-meta', image_meta) .data('medium-file', medium_file) .data('large-file', large_file) .data('orig-file', orig_file) .data('thumb-size', thumb_size) ; if ( useInPageThumbnails ) { // Use the image already loaded in the gallery as a preview. slide .data( 'preview-image', src_item.attr( 'src' ) ) .css( { 'background-image' : 'url("' + src_item.attr( 'src' ) + '")', 'background-size' : '100% 100%', 'background-position' : 'center center' } ); } slide.jp_carousel( 'fitSlide', false ); } }); return this; }, selectBestImageSize: function(args) { if ( 'object' !== typeof args ) { args = {}; } if ( 'undefined' === typeof args.orig_file ) { return ''; } if ( 'undefined' === typeof args.orig_width || 'undefined' === typeof args.max_width ) { return args.orig_file; } if ( 'undefined' === typeof args.medium_file || 'undefined' === typeof args.large_file ) { return args.orig_file; } var medium_size = args.medium_file.replace(/-([\d]+x[\d]+)\..+$/, '$1'), medium_size_parts = (medium_size !== args.medium_file) ? medium_size.split('x') : [args.orig_width, 0], medium_width = parseInt( medium_size_parts[0], 10 ), medium_height = parseInt( medium_size_parts[1], 10 ), large_size = args.large_file.replace(/-([\d]+x[\d]+)\..+$/, '$1'), large_size_parts = (large_size !== args.large_file) ? large_size.split('x') : [args.orig_width, 0], large_width = parseInt( large_size_parts[0], 10 ), large_height = parseInt( large_size_parts[1], 10 ); // Give devices with a higher devicePixelRatio higher-res images (Retina display = 2, Android phones = 1.5, etc) if ( 'undefined' !== typeof window.devicePixelRatio && window.devicePixelRatio > 1 ) { args.max_width = args.max_width * window.devicePixelRatio; args.max_height = args.max_height * window.devicePixelRatio; } if ( large_width >= args.max_width || large_height >= args.max_height ) { return args.large_file; } if ( medium_width >= args.max_width || medium_height >= args.max_height ) { return args.medium_file; } return args.orig_file; }, originalDimensions: function() { var splitted = $(this).data('orig-size').split(','); return {width: parseInt(splitted[0], 10), height: parseInt(splitted[1], 10)}; }, format: function( args ) { if ( 'object' !== typeof args ) { args = {}; } if ( ! args.text || 'undefined' === typeof args.text ) { return; } if ( ! args.replacements || 'undefined' === typeof args.replacements ) { return args.text; } return args.text.replace(/{(\d+)}/g, function( match, number ) { return typeof args.replacements[number] !== 'undefined' ? args.replacements[number] : match; }); }, shutterSpeed: function(d) { if (d >= 1) { return Math.round(d*10)/10 + 's'; // round to one decimal if value > 1s by multiplying it by 10, rounding, then dividing by 10 again } var df = 1, top = 1, bot = 1; var tol = 1e-8; // iterate while value not reached and difference (positive or negative, hence the Math.abs) between value // and approximated value greater than given tolerance while (df !== d && Math.abs(df-d) > tol) { if (df < d) { top += 1; } else { bot += 1; top = parseInt(d * bot, 10); } df = top / bot; } if (top > 1) { bot = Math.round(bot / top); top = 1; } if (bot <= 1) { return '1s'; } return top + '/' + bot + 's'; }, parseTitleDesc: function( value ) { if ( !value.match(' ') && value.match('_') ) { return ''; } // Prefix list originally based on http://commons.wikimedia.org/wiki/MediaWiki:Filename-prefix-blacklist $([ 'CIMG', // Casio 'DSC_', // Nikon 'DSCF', // Fuji 'DSCN', // Nikon 'DUW', // some mobile phones 'GEDC', // GE 'IMG', // generic 'JD', // Jenoptik 'MGP', // Pentax 'PICT', // misc. 'Imagen', // misc. 'Foto', // misc. 'DSC', // misc. 'Scan', // Scanners 'SANY', // Sanyo 'SAM', // Samsung 'Screen Shot [0-9]+' // Mac screenshots ]) .each(function(key, val){ var regex = new RegExp('^' + val); if ( regex.test(value) ) { value = ''; return; } }); return value; }, getTitleDesc: function( data "http://www.manettistudio.it/wp-content/plugins/carousel-without-jetpack/carousel/" ) { var title ='', desc = '', markup = '', target; target = $( 'div.jp-carousel-titleanddesc', 'div.jp-carousel-wrap' ); target.hide(); title = gallery.jp_carousel('parseTitleDesc', data.title) || ''; desc = gallery.jp_carousel('parseTitleDesc', data.desc) || ''; if ( title.length || desc.length ) { // $('
').text(sometext).html() is a trick to go to HTML to plain text (including HTML entities decode, etc) if ( $('
').text(title).html() === $('
').text(desc).html() ) { title = ''; } markup = ( title.length ) ? '' : ''; markup += ( desc.length ) ? '' : ''; target.html( markup ).fadeIn('slow'); } $( 'div#jp-carousel-comment-form-container' ).css('margin-top', '20px'); $( 'div#jp-carousel-comments-loading' ).css('margin-top', '20px'); }, updateLikesWidgetVisibility: function ( attachmentId ) { // Only do this if likes is enabled if ( 'undefined' === typeof jetpackLikesWidgetQueue ) { return; } // Hide all likes widgets except for the one for the attachmentId passed in $( '.jp-carousel-buttons .jetpack-likes-widget-wrapper' ).css( 'display', 'none' ).each( function () { var widgetWrapper = $( this ); if ( widgetWrapper.attr( 'data-attachment-id' ) == attachmentId ) { // jshint ignore:line widgetWrapper.css( 'display', 'inline-block' ); return false; } }); }, loadLikes : function ( attachmentId ) { var dataCarouselExtra = $( '.jp-carousel-wrap' ).data( 'carousel-extra' ); var blogId = dataCarouselExtra.likes_blog_id; if ( $( '#like-post-wrapper-' + blogId + '-' + attachmentId ).length === 0 ) { // Add the iframe the first time the slide is shown. var protocol = 'http'; var originDomain = 'http://wordpress.com'; if ( dataCarouselExtra.permalink.length ) { protocol = dataCarouselExtra.permalink.split( ':' )[0]; if ( ( protocol !== 'http' ) && ( protocol !== 'https' ) ) { protocol = 'http'; } var parts = dataCarouselExtra.permalink.split( '/' ); if ( parts.length >= 2 ) { originDomain = protocol + '://' + parts[2]; } } var dataSource = protocol + '://widgets.wp.com/likes/#blog_id=' + encodeURIComponent( blogId ) + '&post_id=' + encodeURIComponent( attachmentId ) + '&slim=1&origin=' + encodeURIComponent( originDomain ); if ( 'en' !== jetpackCarouselStrings.lang ) { dataSource += '&lang=' + encodeURIComponent( jetpackCarouselStrings.lang ); } var likesWidget = $( '' ) .attr( 'name', 'like-post-frame-' + blogId + '-' + attachmentId ) .attr( 'src', dataSource ) .css( 'display', 'inline-block' ); var likesWidgetWrapper = $( '
' ) .addClass( 'jetpack-likes-widget-wrapper jetpack-likes-widget-unloaded slim-likes-widget' ) .attr( 'id', 'like-post-wrapper-' + blogId + '-' + attachmentId ) .attr( 'data-src', dataSource ) .attr( 'data-name', 'like-post-frame-' + blogId + '-' + attachmentId ) .attr( 'data-attachment-id', attachmentId ) .css( 'display', 'none' ) .css( 'vertical-align', 'middle' ) .append( likesWidget ) .append( '
' ); $( '.jp-carousel-buttons' ).append( likesWidgetWrapper ); } }, // updateExif updates the contents of the exif UL (.jp-carousel-image-exif) updateExif: function( meta ) { if ( !meta || 1 !== Number( jetpackCarouselStrings.display_exif ) ) { return false; } var $ul = $( '' ); $.each( meta, function( key, val ) { if ( 0 === parseFloat(val) || !val.length || -1 === $.inArray( key, [ 'camera', 'aperture', 'shutter_speed', 'focal_length' ] ) ) { return; } switch( key ) { case 'focal_length': val = val + 'mm'; break; case 'shutter_speed': val = gallery.jp_carousel('shutterSpeed', val); break; case 'aperture': val = 'f/' + val; break; } $ul.append( '
  • ' + jetpackCarouselStrings[key] + '
    ' + val + '
  • ' ); }); // Update (replace) the content of the ul $( 'div.jp-carousel-image-meta ul.jp-carousel-image-exif' ).replaceWith( $ul ); }, // updateFullSizeLink updates the contents of the jp-carousel-image-download link updateFullSizeLink: function(current) { if(!current || !current.data) { return false; } var original = current.data('orig-file').replace(/\?.+$/, ''), origSize = current.data('orig-size').split(','), permalink = $( ''+gallery.jp_carousel('format', {'text': jetpackCarouselStrings.download_original, 'replacements': origSize})+'' ) .addClass( 'jp-carousel-image-download' ) .attr( 'href', original ) .attr( 'target', '_blank' ); // Update (replace) the content of the anchor $( 'div.jp-carousel-image-meta a.jp-carousel-image-download' ).replaceWith( permalink ); }, updateMap: function( meta ) { if ( !meta.latitude || !meta.longitude || 1 !== Number( jetpackCarouselStrings.display_geo ) ) { return; } var latitude = meta.latitude, longitude = meta.longitude, $metabox = $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' ), $mapbox = $( '
    ' ), style = '&scale=2&style=feature:all|element:all|invert_lightness:true|hue:0x0077FF|saturation:-50|lightness:-5|gamma:0.91'; $mapbox .addClass( 'jp-carousel-image-map' ) .html( '\ \
    \ \ ' ) .prependTo( $metabox ); }, testCommentsOpened: function( opened ) { if ( 1 === parseInt( opened, 10 ) ) { $('.jp-carousel-buttons').fadeIn('fast'); commentForm.fadeIn('fast'); } else { $('.jp-carousel-buttons').fadeOut('fast'); commentForm.fadeOut('fast'); } }, getComments: function( args ) { clearInterval( commentInterval ); if ( 'object' !== typeof args ) { return; } if ( 'undefined' === typeof args.attachment_id || ! args.attachment_id ) { return; } if ( ! args.offset || 'undefined' === typeof args.offset || args.offset < 1 ) { args.offset = 0; } var comments = $('.jp-carousel-comments'), commentsLoading = $('#jp-carousel-comments-loading').show(); if ( args.clear ) { comments.hide().empty(); } $.ajax({ type: 'GET', url: jetpackCarouselStrings.ajaxurl, dataType: 'json', data: { action: 'get_attachment_comments', nonce: jetpackCarouselStrings.nonce, id: args.attachment_id, offset: args.offset }, success: function(data/*, status, xhr*/) { if ( args.clear ) { comments.fadeOut('fast').empty(); } $( data "http://www.manettistudio.it/wp-content/plugins/carousel-without-jetpack/carousel/" ).each(function(){ var comment = $('
    ') .addClass('jp-carousel-comment') .attr('id', 'jp-carousel-comment-' + this['id']) .html( '
    ' + this['gravatar_markup'] + '
    ' + '
    ' + this['author_markup'] + '
    ' + '
    ' + this['date_gmt'] + '
    ' + '
    ' + this['content'] + '
    ' ); comments.append(comment); // Set the interval to check for a new page of comments. clearInterval( commentInterval ); commentInterval = setInterval( function() { if ( ( $('.jp-carousel-overlay').height() - 150 ) < $('.jp-carousel-wrap').scrollTop() + $(window).height() ) { gallery.jp_carousel('getComments',{ attachment_id: args.attachment_id, offset: args.offset + 10, clear: false }); clearInterval( commentInterval ); } }, 300 ); }); // Verify (late) that the user didn't repeatldy click the arrows really fast, in which case the requested // attachment id might no longer match the current attachment id by the time we get the data "http://www.manettistudio.it/wp-content/plugins/carousel-without-jetpack/carousel/" back or a now // registered infiniscroll event kicks in, so we don't ever display comments for the wrong image by mistake. var current = $('.jp-carousel div.selected'); if ( current && current.data && current.data('attachment-id') != args.attachment_id ) { // jshint ignore:line comments.fadeOut('fast'); comments.empty(); return; } // Increase the height of the background, semi-transparent overlay to match the new length of the comments list. $('.jp-carousel-overlay').height( $(window).height() + titleAndDescription.height() + commentForm.height() + ( (comments.height() > 0) ? comments.height() : imageMeta.height() ) + 200 ); comments.show(); commentsLoading.hide(); }, error: function(xhr, status, error) { // TODO: proper error handling console.log( 'Comment get fail...', xhr, status, error ); comments.fadeIn('fast'); commentsLoading.fadeOut('fast'); } }); }, postCommentError: function(args) { if ( 'object' !== typeof args ) { args = {}; } if ( ! args.field || 'undefined' === typeof args.field || ! args.error || 'undefined' === typeof args.error ) { return; } $('#jp-carousel-comment-post-results').slideUp('fast').html('').slideDown('fast'); $('#jp-carousel-comment-form-spinner').spin(false); }, setCommentIframeSrc: function(attachment_id) { var iframe = $('#jp-carousel-comment-iframe'); // Set the proper irame src for the current attachment id if (iframe && iframe.length) { iframe.attr('src', iframe.attr('src').replace(/(postid=)\d+/, '$1'+attachment_id) ); iframe.attr('src', iframe.attr('src').replace(/(%23.+)?$/, '%23jp-carousel-'+attachment_id) ); } }, clearCommentTextAreaValue: function() { var commentTextArea = $('#jp-carousel-comment-form-comment-field'); if ( commentTextArea ) { commentTextArea.val(''); } }, nextSlide : function () { var slides = this.jp_carousel( 'slides' ); var selected = this.jp_carousel( 'selectedSlide' ); if ( selected.length === 0 || ( slides.length > 2 && selected.is( slides.last() ) ) ) { return slides.first(); } return selected.next(); }, prevSlide : function () { var slides = this.jp_carousel( 'slides' ); var selected = this.jp_carousel( 'selectedSlide' ); if ( selected.length === 0 || ( slides.length > 2 && selected.is( slides.first() ) ) ) { return slides.last(); } return selected.prev(); }, loadFullImage : function ( slide ) { var image = slide.find( 'img:first' ); if ( ! image.data( 'loaded' ) ) { // If the width of the slide is smaller than the width of the "thumbnail" we're already using, // don't load the full image. image.on( 'load.jetpack', function () { image.off( 'load.jetpack' ); $( this ).closest( '.jp-carousel-slide' ).css( 'background-image', '' ); } ); if ( ! slide.data( 'preview-image' ) || ( slide.data( 'thumb-size' ) && slide.width() > slide.data( 'thumb-size' ).width ) ) { image.attr( 'src', image.closest( '.jp-carousel-slide' ).data( 'src' ) ); } else { image.attr( 'src', slide.data( 'preview-image' ) ); } image.data( 'loaded', 1 ); } } }; $.fn.jp_carousel = function(method){ // ask for the HTML of the gallery // Method calling logic if ( methods[method] ) { return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'object' || ! method ) { return methods.open.apply( this, arguments ); } else { $.error( 'Method ' + method + ' does not exist on jQuery.jp_carousel' ); } }; // register the event listener for starting the gallery $( document.body ).on( 'click', 'div.gallery,div.tiled-gallery', function(e) { if ( ! $(this).jp_carousel( 'testForData', e.currentTarget ) ) { return; } if ( $(e.target).parent().hasClass('gallery-caption') ) { return; } e.preventDefault(); $(this).jp_carousel('open', {start_index: $(this).find('.gallery-item, .tiled-gallery-item').index($(e.target).parents('.gallery-item, .tiled-gallery-item'))}); }); // Makes carousel work on page load and when back button leads to same URL with carousel hash (ie: no actual document.ready trigger) $( window ).on( 'hashchange', function () { var hashRegExp = /jp-carousel-(\d+)/, matches, attachmentId, galleries, selectedThumbnail; if ( ! window.location.hash || ! hashRegExp.test( window.location.hash ) ) { return; } if ( window.location.hash === last_known_location_hash ) { return; } last_known_location_hash = window.location.hash; matches = window.location.hash.match( hashRegExp ); attachmentId = parseInt( matches[1], 10 ); galleries = $( 'div.gallery, div.tiled-gallery' ); // Find the first thumbnail that matches the attachment ID in the location // hash, then open the gallery that contains it. galleries.each( function( _, galleryEl ) { $( galleryEl ).find('img').each( function( imageIndex, imageEl ) { if ( $( imageEl ).data( 'attachment-id' ) === parseInt( attachmentId, 10 ) ) { selectedThumbnail = { index: imageIndex, gallery: galleryEl }; return false; } }); if ( selectedThumbnail ) { $( selectedThumbnail.gallery ) .jp_carousel( 'openOrSelectSlide', selectedThumbnail.index ); } }); }); if ( window.location.hash ) { $( window ).trigger( 'hashchange' ); } }); /** * jQuery Plugin to obtain touch gestures from iPhone, iPod Touch and iPad, should also work with Android mobile phones (not tested yet!) * Common usage: wipe images (left and right to show the previous or next image) * * @author Andreas Waltl, netCU Internetagentur (http://www.netcu.de) * Version 1.1.1, modified to pass the touchmove event to the callbacks. */ (function($) { $.fn.touchwipe = function(settings) { var config = { min_move_x: 20, min_move_y: 20, wipeLeft: function(/*e*/) { }, wipeRight: function(/*e*/) { }, wipeUp: function(/*e*/) { }, wipeDown: function(/*e*/) { }, preventDefaultEvents: true }; if (settings) { $.extend(config, settings); } this.each(function() { var startX; var startY; var isMoving = false; function cancelTouch() { this.removeEventListener('touchmove', onTouchMove); startX = null; isMoving = false; } function onTouchMove(e) { if(config.preventDefaultEvents) { e.preventDefault(); } if(isMoving) { var x = e.touches[0].pageX; var y = e.touches[0].pageY; var dx = startX - x; var dy = startY - y; if(Math.abs(dx) >= config.min_move_x) { cancelTouch(); if(dx > 0) { config.wipeLeft(e); } else { config.wipeRight(e); } } else if(Math.abs(dy) >= config.min_move_y) { cancelTouch(); if(dy > 0) { config.wipeDown(e); } else { config.wipeUp(e); } } } } function onTouchStart(e) { if (e.touches.length === 1) { startX = e.touches[0].pageX; startY = e.touches[0].pageY; isMoving = true; this.addEventListener('touchmove', onTouchMove, false); } } if ('ontouchstart' in document.documentElement) { this.addEventListener('touchstart', onTouchStart, false); } }); return this; }; })(jQuery);