1 2jQuery(document).ready(function($) { 3 4 // gallery faded layer and container elements 5 var overlay, comments, gallery, container, nextButton, previousButton, info, title, transitionBegin, 6 caption, resizeTimeout, mouseTimeout, photo_info, close_hint, commentInterval, 7 screenPadding = 110, originalOverflow = $('body').css('overflow'), originalHOverflow = $('html').css('overflow'), proportion = 85, 8 last_known_location_hash = ''; 9 10 if ( window.innerWidth <= 760 ) { 11 screenPadding = Math.round( ( window.innerWidth / 760 ) * 110 ); 12 13 if ( screenPadding < 40 && ( ( 'ontouchstart' in window ) || window.DocumentTouch && document instanceof DocumentTouch ) ) 14 screenPadding = 0; 15 } 16 17 var keyListener = function(e){ 18 switch(e.which){ 19 case 38: // up 20 e.preventDefault(); 21 container.scrollTop(container.scrollTop() - 100); 22 break; 23 case 40: // down 24 e.preventDefault(); 25 container.scrollTop(container.scrollTop() + 100); 26 break; 27 case 39: // right 28 e.preventDefault(); 29 gallery.jp_carousel('clearCommentTextAreaValue'); 30 gallery.jp_carousel('next'); 31 break; 32 case 37: // left 33 case 8: // backspace 34 e.preventDefault(); 35 gallery.jp_carousel('clearCommentTextAreaValue'); 36 gallery.jp_carousel('previous'); 37 break; 38 case 27: // escape 39 e.preventDefault(); 40 gallery.jp_carousel('clearCommentTextAreaValue'); 41 container.jp_carousel('close'); 42 break; 43 default: 44 // making jslint happy 45 break; 46 } 47 }; 48 49 var resizeListener = function(e){ 50 clearTimeout(resizeTimeout); 51 resizeTimeout = setTimeout(function(){ 52 gallery 53 .jp_carousel('slides') 54 .jp_carousel('fitSlide', true); 55 gallery 56 .jp_carousel('fitInfo', true) 57 .jp_carousel('fitMeta', true); 58 }, 200); 59 }; 60 61 var prepareGallery = function( dataCarouselExtra ){ 62 if (!overlay) { 63 overlay = $('<div></div>') 64 .addClass('jp-carousel-overlay') 65 .css({ 66 'position' : 'absolute', 67 'top' : 0, 68 'right' : 0, 69 'bottom' : 0, 70 'left' : 0 71 }); 72 73 var buttons = '<a class="jp-carousel-commentlink" href="#">' + jetpackCarouselStrings.comment + '</a>'; 74 if ( 1 == jetpackCarouselStrings.is_logged_in ) { 75 } 76 77 buttons = $('<div class="jp-carousel-buttons">' + buttons + '</div>'); 78 79 caption = $('<h2></h2>'); 80 photo_info = $('<div class="jp-carousel-photo-info"></div>').append(caption); 81 82 imageMeta = $('<div></div>') 83 .addClass('jp-carousel-image-meta') 84 .css({ 85 'float' : 'right', 86 'margin-top' : '20px', 87 'width' : '250px' 88 }); 89 90 imageMeta 91 .append( buttons ) 92 .append( "<ul class='jp-carousel-image-exif' style='display:none;'></ul>" ) 93 .append( "<a class='jp-carousel-image-download' style='display:none;'></a>" ) 94 .append( "<div class='jp-carousel-image-map' style='display:none;'></div>" ); 95 96 titleAndDescription = $('<div></div>') 97 .addClass('jp-carousel-titleanddesc') 98 .css({ 99 'width' : '100%', 100 'margin-top' : imageMeta.css('margin-top') 101 }); 102 103 var commentFormMarkup = '<div id="jp-carousel-comment-form-container">'; 104 105 if ( jetpackCarouselStrings.local_comments_commenting_as && jetpackCarouselStrings.local_comments_commenting_as.length ) { 106 // Jetpack comments not enabled, fallback to local comments 107 108 if ( 1 != jetpackCarouselStrings.is_logged_in && 1 == jetpackCarouselStrings.comment_registration ) { 109 commentFormMarkup += '<div id="jp-carousel-comment-form-commenting-as">' + jetpackCarouselStrings.local_comments_commenting_as + '</div>'; 110 } else { 111 commentFormMarkup += '<form id="jp-carousel-comment-form">'; 112 commentFormMarkup += '<textarea name="comment" class="jp-carousel-comment-form-field jp-carousel-comment-form-textarea" id="jp-carousel-comment-form-comment-field" placeholder="' + jetpackCarouselStrings.write_comment + '"></textarea>'; 113 commentFormMarkup += '<div id="jp-carousel-comment-form-submit-and-info-wrapper">'; 114 commentFormMarkup += '<div id="jp-carousel-comment-form-commenting-as">' + jetpackCarouselStrings.local_comments_commenting_as + '</div>'; 115 commentFormMarkup += '<input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="'+jetpackCarouselStrings.post_comment+'" />'; 116 commentFormMarkup += '<span id="jp-carousel-comment-form-spinner"> </span>'; 117 commentFormMarkup += '<div id="jp-carousel-comment-post-results"></div>'; 118 commentFormMarkup += '</div>'; 119 commentFormMarkup += '</form>'; 120 } 121 } 122 commentFormMarkup += '</div>'; 123 124 commentForm = $(commentFormMarkup) 125 .css({ 126 'width' : '100%', 127 'margin-top' : '20px', 128 'color' : '#999' 129 }); 130 131 comments = $('<div></div>') 132 .addClass('jp-carousel-comments') 133 .css({ 134 'width' : '100%', 135 'bottom' : '10px', 136 'margin-top' : '20px' 137 }); 138 139 commentsLoading = $('<div id="jp-carousel-comments-loading"><span>'+jetpackCarouselStrings.loading_comments+'</span></div>') 140 .css({ 141 'width' : '100%', 142 'bottom' : '10px', 143 'margin-top' : '20px' 144 }); 145
146 leftWidth = ( $(window).width() - ( screenPadding * 2 ) ) - (imageMeta.width() + 40); 147 leftWidth += 'px'; 148 149 leftColWrapper = $('<div></div>') 150 .addClass('jp-carousel-left-column-wrapper') 151 .css({ 152 'width' : Math.floor( leftWidth ) 153 }) 154 .append(titleAndDescription) 155 .append(commentForm) 156 .append(comments) 157 .append(commentsLoading); 158 159 fadeaway = $('<div></div>') 160 .addClass('jp-carousel-fadeaway'); 161 162 info = $('<div></div>') 163 .addClass('jp-carousel-info') 164 .css({ 165 'top' : Math.floor( ($(window).height() / 100) * proportion ), 166 'left' : screenPadding, 167 'right' : screenPadding 168 }) 169 .append(photo_info) 170 .append(imageMeta); 171 172 if ( window.innerWidth <= 760 ) { 173 photo_info.remove().insertAfter( titleAndDescription ); 174 info.prepend( leftColWrapper ); 175 } 176 else { 177 info.append( leftColWrapper ); 178 } 179 180 targetBottomPos = ( $(window).height() - parseInt( info.css('top'), 10 ) ) + 'px'; 181 182 nextButton = $("<div><span></span></div>") 183 .addClass('jp-carousel-next-button') 184 .css({ 185 'right' : '15px', 186 }); 187 188 previousButton = $("<div><span></span></div>") 189 .addClass('jp-carousel-previous-button') 190 .css({ 191 'left' : 0, 192 }); 193 194 nextButton.add( previousButton ).css( { 195 'position' : 'fixed', 196 'top' : '40px', 197 'bottom' : targetBottomPos, 198 'width' : screenPadding 199 } ); 200 201 gallery = $('<div></div>') 202 .addClass('jp-carousel') 203 .css({ 204 'position' : 'absolute', 205 'top' : 0, 206 'bottom' : targetBottomPos, 207 'left' : 0, 208 'right' : 0 209 }); 210 211 close_hint = $('<div class="jp-carousel-close-hint"><span>×</span></div>') 212 .css({ 213 position : 'fixed' 214 }); 215 216 container = $("<div></div>") 217 .addClass('jp-carousel-wrap') 218 .addClass( 'jp-carousel-transitions' ); 219 220 if ( 'white' == jetpackCarouselStrings.background_color ) 221 container.addClass('jp-carousel-light'); 222 223 container.css({ 224 'position' : 'fixed', 225 'top' : 0, 226 'right' : 0, 227 'bottom' : 0, 228 'left' : 0, 229 'z-index' : 2147483647, 230 'overflow-x' : 'hidden', 231 'overflow-y' : 'auto', 232 'direction' : 'ltr' 233 }) 234 .hide() 235 .append(overlay) 236 .append(gallery) 237 .append(fadeaway) 238 .append(info) 239 .append(nextButton) 240 .append(previousButton) 241 .append(close_hint) 242 .appendTo($('body')) 243 .click(function(e){ 244 var target = $(e.target), wrap = target.parents('div.jp-carousel-wrap'), data = wrap.data('carousel-extra'), 245 slide = wrap.find('div.selected'), attachment_id = slide.data('attachment-id'); 246 data = data || []; 247 248 if ( target.is(gallery) || target.parents().add(target).is(close_hint) ) { 249 container.jp_carousel('close'); 250 } else if ( target.hasClass('jp-carousel-commentlink') ) { 251 e.preventDefault(); 252 e.stopPropagation(); 253 $(window).unbind('keydown', keyListener); 254 container.animate({scrollTop: parseInt(info.position()['top'], 10)}, 'fast'); 255 $('#jp-carousel-comment-form-submit-and-info-wrapper').slideDown('fast'); 256 $('#jp-carousel-comment-form-comment-field').focus(); 257 } else if ( target.hasClass('jp-carousel-comment-login') ) { 258 var url = jetpackCarouselStrings.login_url + '%23jp-carousel-' + attachment_id; 259 260 window.location.href = url; 261 } else if ( target.parents('#jp-carousel-comment-form-container').length ) { 262 var textarea = $('#jp-carousel-comment-form-comment-field') 263 .blur(function(){ 264 $(window).bind('keydown', keyListener); 265 }) 266 .focus(function(){ 267 $(window).unbind('keydown', keyListener); 268 }); 269 270 var emailField = $('#jp-carousel-comment-form-email-field') 271 .blur(function(){ 272 $(window).bind('keydown', keyListener); 273 }) 274 .focus(function(){ 275 $(window).unbind('keydown', keyListener); 276 }); 277 278 var authorField = $('#jp-carousel-comment-form-author-field') 279 .blur(function(){ 280 $(window).bind('keydown', keyListener); 281 }) 282 .focus(function(){ 283 $(window).unbind('keydown', keyListener); 284 }); 285 286 var urlField = $('#jp-carousel-comment-form-url-field') 287 .blur(function(){ 288 $(window).bind('keydown', keyListener); 289 }) 290 .focus(function(){ 291 $(window).unbind('keydown', keyListener); 292 }); 293 294 if ( textarea && textarea.attr('id') == target.attr('id')) { 295 // For first page load 296 $(window).unbind('keydown', keyListener); 297 $('#jp-carousel-comment-form-submit-and-info-wrapper').slideDown('fast'); 298 } else if ( target.is( 'input[type="submit"]' ) ) { 299 e.preventDefault(); 300 e.stopPropagation(); 301 302 $('#jp-carousel-comment-form-spinner').spin('small', 'white'); 303 304 var ajaxData = { 305 action: 'post_attachment_comment', 306 nonce: jetpackCarouselStrings.nonce, 307 blog_id: data['blog_id'], 308 id: attachment_id, 309 comment: textarea.val() 310 }; 311 312 if ( ! ajaxData['comment'].length ) { 313 gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-comment-field', 'error': jetpackCarouselStrings.no_comment_text}); 314 return; 315 } 316 317 if ( 1 != jetpackCarouselStrings.is_logged_in ) { 318 ajaxData['email'] = emailField.val(); 319 ajaxData['author'] = authorField.val(); 320 ajaxData['url'] = urlField.val(); 321 322 if ( 1 == jetpackCarouselStrings.require_name_email ) { 323 if ( ! ajaxData['email'].length || ! ajaxData['email'].match('@') ) { 324 gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-email-field', 'error': jetpackCarouselStrings.no_comment_email}); 325 return; 326 } else if ( ! ajaxData['author'].length ) { 327 gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-author-field', 'error': jetpackCarouselStrings.no_comment_author}); 328 return; 329 } 330 } 331 } 332 333 $.ajax({ 334 type: 'POST', 335 url: jetpackCarouselStrings.ajaxurl, 336 data: ajaxData, 337 dataType: 'json', 338 success: function(response, status, xhr) { 339 if ( 'approved' == response.comment_status ) {
340 $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-success">' + jetpackCarouselStrings.comment_approved + '</span>').slideDown('fast'); 341 } else if ( 'unapproved' == response.comment_status ) { 342 $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-success">' + jetpackCarouselStrings.comment_unapproved + '</span>').slideDown('fast'); 343 } else { 344 // 'deleted', 'spam', false 345 $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-error">' + jetpackCarouselStrings.comment_post_error + '</span>').slideDown('fast'); 346 } 347 gallery.jp_carousel('clearCommentTextAreaValue'); 348 gallery.jp_carousel('getComments', {attachment_id: attachment_id, offset: 0, clear: true}); 349 $('#jp-carousel-comment-form-button-submit').val(jetpackCarouselStrings.post_comment); 350 $('#jp-carousel-comment-form-spinner').spin(false); 351 }, 352 error: function(xhr, status, error) { 353 // TODO: Add error handling and display here 354 gallery.jp_carousel('postCommentError', {'field': 'jp-carousel-comment-form-comment-field', 'error': jetpackCarouselStrings.comment_post_error}); 355 return; 356 } 357 }); 358 } 359 } else if ( ! target.parents( '.jp-carousel-info' ).length ) { 360 container.jp_carousel('next'); 361 } 362 }) 363 .bind('jp_carousel.afterOpen', function(){ 364 $(window).bind('keydown', keyListener); 365 $(window).bind('resize', resizeListener); 366 gallery.opened = true; 367 368 resizeListener(); 369 }) 370 .bind('jp_carousel.beforeClose', function(){ 371 var scroll = $(window).scrollTop(); 372 373 $(window).unbind('keydown', keyListener); 374 $(window).unbind('resize', resizeListener); 375 $(window).scrollTop(scroll); 376 }) 377 .bind('jp_carousel.afterClose', function(){ 378 if ( history.pushState ) { 379 history.pushState("", document.title, window.location.pathname + window.location.search); 380 } else { 381 last_known_location_hash = ''; 382 window.location.hash = ''; 383 } 384 gallery.opened = false; 385 }) 386 .on( 'transitionend.jp-carousel ', '.jp-carousel-slide', function ( e ) { 387 // If the movement transitions take more than twice the allotted time, disable them. 388 // There is some wiggle room in the 2x, since some of that time is taken up in 389 // JavaScript, setting up the transition and calling the events. 390 if ( 'transform' == e.originalEvent.propertyName ) { 391 var transitionMultiplier = ( ( Date.now() - transitionBegin ) / 1000 ) / e.originalEvent.elapsedTime; 392 393 container.off( 'transitionend.jp-carousel' ); 394 395 if ( transitionMultiplier >= 2 ) 396 $( '.jp-carousel-transitions' ).removeClass( 'jp-carousel-transitions' ); 397 } 398 } ); 399 400 $( '.jp-carousel-wrap' ).touchwipe( { 401 wipeLeft : function ( e ) { 402 e.preventDefault(); 403 gallery.jp_carousel( 'next' ); 404 }, 405 wipeRight : function ( e ) { 406 e.preventDefault(); 407 gallery.jp_carousel( 'previous' ); 408 }, 409 preventDefaultEvents : false 410 } ); 411 412 $( '.jetpack-likes-widget-unloaded' ).each( function() { 413 jetpackLikesWidgetQueue.push( this.id ); 414 }); 415 416 nextButton.add(previousButton).click(function(e){ 417 e.preventDefault(); 418 e.stopPropagation(); 419 if ( nextButton.is(this) ) { 420 gallery.jp_carousel('next'); 421 } else { 422 gallery.jp_carousel('previous'); 423 } 424 }); 425 } 426 }; 427 428 var methods = { 429 testForData: function(gallery) { 430 gallery = $( gallery ); // make sure we have it as a jQuery object. 431 if ( ! gallery.length || undefined == gallery.data( 'carousel-extra' ) ) { 432 return false; 433 } 434 return true; 435 }, 436 437 testIfOpened: function() { 438 if ( 'undefined' != typeof(gallery) && 'undefined' != typeof(gallery.opened) && true == gallery.opened ) 439 return true; 440 return false; 441 }, 442 443 open: function(options) { 444 var settings = { 445 'items_selector' : ".gallery-item [data-attachment-id], .tiled-gallery-item [data-attachment-id]", 446 'start_index': 0 447 }, 448 data = $(this).data('carousel-extra'); 449 450 if ( !data ) 451 return; // don't run if the default gallery functions weren't used 452 453 prepareGallery( data ); 454 455 if ( gallery.jp_carousel( 'testIfOpened' ) ) 456 return; // don't open if already opened 457 458 // make sure to stop the page from scrolling behind the carousel overlay, so we don't trigger 459 // infiniscroll for it when enabled (Reader, theme infiniscroll, etc). 460 originalOverflow = $('body').css('overflow'); 461 $('body').css('overflow', 'hidden'); 462 // prevent html from overflowing on some of the new themes. 463 originalHOverflow = $('html').css('overflow'); 464 $('html').css('overflow', 'hidden'); 465 466 // Re-apply inline-block style here and give an initial value for the width 467 // This value will get replaced with a more appropriate value once the slide is loaded 468 // This avoids the likes widget appearing initially full width below the comment button and then shuffling up 469 jQuery( '.slim-likes-widget' ).find( 'iframe' ).css( 'display', 'inline-block' ).css( 'width', '60px' ); 470 471 container.data('carousel-extra', data); 472 473 return this.each(function() { 474 // If options exist, lets merge them 475 // with our default settings 476 var $this = $(this); 477 478 if ( options ) 479 $.extend( settings, options ); 480 if ( -1 == settings.start_index ) 481 settings.start_index = 0; //-1 returned if can't find index, so start from beginning 482 483 container.trigger('jp_carousel.beforeOpen').fadeIn('fast',function(){ 484 container.trigger('jp_carousel.afterOpen'); 485 gallery 486 .jp_carousel('initSlides', $this.find(settings.items_selector), settings.start_index) 487 .jp_carousel('start', settings.start_index); 488 }); 489 gallery.html(''); 490 }); 491 }, 492 493 start : function(start_index){ 494 var slides = this.jp_carousel('slides'), selected = slides.eq(start_index); 495 496 if ( 0 === selected.length ) 497 selected = slides.eq(0); 498 499 gallery.jp_carousel('selectSlide', selected, false); 500 return this; 501 }, 502 503 close : function(){ 504 // make sure to let the page scroll again 505 $('body').css('overflow', originalOverflow); 506 $('html').css('overflow', originalHOverflow); 507 return container 508 .trigger('jp_carousel.beforeClose') 509 .fadeOut('fast', function(){ 510 container.trigger('jp_carousel.afterClose'); 511 }); 512 513 }, 514 515 next : function(){ 516 var slide = gallery.jp_carousel( 'nextSlide' ); 517 container.animate({scrollTop:0}, 'fast'); 518 519 if ( slide ) { 520 this.jp_carousel('selectSlide', slide); 521 } 522 }, 523 524 previous : function(){ 525 var slide = gallery.jp_carousel( 'prevSlide' ); 526 container.animate({scrollTop:0}, 'fast'); 527 528 if ( slide ) { 529 this.jp_carousel('selectSlide', slide); 530 } 531 }, 532 533 resetButtons : function(current) { 534 if ( current.data('liked') ) 535 $('.jp-carousel-buttons a.jp-carousel-like').addClass('liked').text(jetpackCarouselStrings.unlike); 536 else 537 $('.jp-carousel-buttons a.jp-carousel-like').removeClass('liked').text(jetpackCarouselStrings.like); 538 }, 539 540 selectedSlide : function(){ 541 return this.find('.selected'); 542 }, 543 544 setSlidePosition : function(x) { 545 transitionBegin = Date.now(); 546 547 return this.css({ 548 '-webkit-transform':'translate3d(' + x + 'px,0,0)', 549 '-moz-transform':'translate3d(' + x + 'px,0,0)', 550 '-ms-transform':'translate(' + x + 'px,0)', 551 '-o-transform':'translate(' + x + 'px,0)', 552 'transform':'translate3d(' + x + 'px,0,0)' 553 }); 554 }, 555 556 selectSlide : function(slide, animate){ 557 var last = this.find('.selected').removeClass('selected'), 558 slides = gallery.jp_carousel('slides').css({'position': 'fixed'}), 559 current = $(slide).addClass('selected').css({'position': 'relative'}), 560 attachmentId = current.data( 'attachment-id' ), 561 previous = gallery.jp_carousel( 'prevSlide' ), 562 next = gallery.jp_carousel( 'nextSlide' ), 563 width = $(window).width(), 564 previous_previous = previous.prev(), 565 next_next = next.next(), 566 galleryWidth = gallery.width(), 567 currentWidth = current.width(), 568 left = Math.floor( ( galleryWidth - currentWidth ) * 0.5 ), 569 info_left, 570 method, 571 animated, 572 info_min; 573 // center the main image 574 575 gallery.jp_carousel( 'loadFullImage', current ); 576 577 caption.hide(); 578 579 if ( next.length == 0 && slides.length <= 2 ) 580 $( '.jp-carousel-next-button' ).hide(); 581 else 582 $( '.jp-carousel-next-button' ).show(); 583 584 if ( previous.length == 0 && slides.length <= 2 ) 585 $( '.jp-carousel-previous-button' ).hide(); 586 else 587 $( '.jp-carousel-previous-button' ).show(); 588 589 method = 'css'; 590 animated = current 591 .add(previous) 592 .add(previous_previous) 593 .add(next) 594 .add(next_next) 595 .jp_carousel('loadSlide'); 596 // slide the whole view to the x we want 597 slides.not(animated).hide(); 598 599 current.jp_carousel('setSlidePosition', left).show(); 600 601 // minimum width 602 gallery.jp_carousel('fitInfo', animate); 603 604 // prep the slides 605 var direction = last.is(current.prevAll()) ? 1 : -1; 606 607 if ( 1 == direction ) { 608 if ( ! next_next.is( previous ) ) 609 next_next.jp_carousel('setSlidePosition', galleryWidth + next.width()).show(); 610 611 if ( ! previous_previous.is( next ) ) 612 previous_previous.jp_carousel('setSlidePosition', -previous_previous.width() - currentWidth ).show(); 613 } 614 else { 615 if ( ! next_next.is( previous ) ) 616 next_next.jp_carousel('setSlidePosition', galleryWidth + currentWidth ).show(); 617 } 618 619 previous.jp_carousel('setSlidePosition', Math.floor( -previous.width() + (screenPadding * 0.75 ) ) ).show(); 620 next.jp_carousel('setSlidePosition', Math.ceil( galleryWidth - (screenPadding * 0.75 ) ) ).show(); 621 622 gallery.jp_carousel('resetButtons', current); 623 container.trigger('jp_carousel.selectSlide', [current]); 624 625 gallery.jp_carousel( 'getTitleDesc', { title: current.data( 'title' ), desc: current.data( 'desc' ) } ); 626 627 // Lazy-load the Likes iframe for the current, next, and previous slides. 628 gallery.jp_carousel( 'loadLikes', attachmentId ); 629 gallery.jp_carousel( 'updateLikesWidgetVisibility', attachmentId ) 630 631 if ( next.length > 0 ) 632 gallery.jp_carousel( 'loadLikes', next.data( 'attachment-id' ) ); 633 634 if ( previous.length > 0 ) 635 gallery.jp_carousel( 'loadLikes', previous.data( 'attachment-id' ) ); 636 637 var imageMeta = current.data( 'image-meta' ); 638 gallery.jp_carousel( 'updateExif', imageMeta ); 639 gallery.jp_carousel( 'updateFullSizeLink', current ); 640 gallery.jp_carousel( 'updateMap', imageMeta ); 641 gallery.jp_carousel( 'testCommentsOpened', current.data( 'comments-opened' ) ); 642 gallery.jp_carousel( 'getComments', { 'attachment_id': attachmentId, 'offset': 0, 'clear': true } );
643 $('#jp-carousel-comment-post-results').slideUp(); 644 645 // $('<div />').text(sometext).html() is a trick to go to HTML to plain text (including HTML entities decode, etc) 646 if ( current.data('caption') ) { 647 if ( $('<div />').text(current.data('caption')).html() == $('<div />').text(current.data('title')).html() ) 648 $('.jp-carousel-titleanddesc-title').fadeOut('fast').empty(); 649 if ( $('<div />').text(current.data('caption')).html() == $('<div />').text(current.data('desc')).html() ) 650 $('.jp-carousel-titleanddesc-desc').fadeOut('fast').empty(); 651 caption.html( current.data('caption') ).fadeIn('slow'); 652 } else { 653 caption.fadeOut('fast').empty(); 654 } 655 656 657 // Load the images for the next and previous slides. 658 $( next ).add( previous ).each( function () { 659 gallery.jp_carousel( 'loadFullImage', $( this ) ); 660 } ); 661 662 window.location.hash = last_known_location_hash = '#jp-carousel-' + attachmentId; 663 }, 664 665 slides : function(){ 666 return this.find('.jp-carousel-slide'); 667 }, 668 669 slideDimensions : function(){ 670 return { 671 width: $(window).width() - (screenPadding * 2), 672 height: Math.floor( $(window).height() / 100 * proportion - 60 ) 673 }; 674 }, 675 676 loadSlide : function() { 677 return this.each(function(){ 678 var slide = $(this); 679 slide.find('img') 680 .one('load', function(){ 681 // set the width/height of the image if it's too big 682 slide 683 .jp_carousel('fitSlide',false); 684 }); 685 }); 686 }, 687 688 bestFit : function(){ 689 var max = gallery.jp_carousel('slideDimensions'), 690 orig = this.jp_carousel('originalDimensions'), 691 orig_ratio = orig.width / orig.height, 692 w_ratio = 1, 693 h_ratio = 1; 694 695 if ( orig.width > max.width ) 696 w_ratio = max.width / orig.width; 697 if ( orig.height > max.height ) 698 h_ratio = max.height / orig.height; 699 700 if ( w_ratio < h_ratio ) { 701 width = max.width; 702 height = Math.floor( width / orig_ratio ); 703 } else if ( h_ratio < w_ratio ) { 704 height = max.height; 705 width = Math.floor( height * orig_ratio ); 706 } else { 707 width = orig.width; 708 height = orig.height; 709 } 710 711 return { 712 width: width, 713 height: height 714 }; 715 }, 716 717 fitInfo : function(animated){ 718 var current = this.jp_carousel('selectedSlide'), 719 size = current.jp_carousel('bestFit'); 720 721 photo_info.css({ 722 'left' : Math.floor( (info.width() - size.width) * 0.5 ), 723 'width' : Math.floor( size.width ) 724 }); 725 726 return this; 727 }, 728 729 fitMeta : function(animated){ 730 var newInfoTop = { top: Math.floor( $(window).height() / 100 * proportion + 5 ) + 'px' }; 731 var newLeftWidth = { width: ( info.width() - (imageMeta.width() + 80) ) + 'px' }; 732 733 if (animated) { 734 info.animate(newInfoTop); 735 leftColWrapper.animate(newLeftWidth); 736 } else { 737 info.animate(newInfoTop); 738 leftColWrapper.css(newLeftWidth); 739 } 740 }, 741 742 fitSlide : function(animated){ 743 return this.each(function(){ 744 var selected = gallery.jp_carousel('selectedSlide'), 745 $this = $(this), 746 dimensions = $this.jp_carousel('bestFit'), 747 method = 'css', 748 max = gallery.jp_carousel('slideDimensions'); 749 750 dimensions.left = 0; 751 dimensions.top = Math.floor( (max.height - dimensions.height) * 0.5 ) + 40; 752 $this[method](dimensions); 753 }); 754 }, 755 756 texturize : function(text) { 757 text = new String(text); // make sure we get a string. Title "1" came in as int 1, for example, which did not support .replace(). 758 text = text.replace(/'/g, '’').replace(/'/g, '’').replace(/[\u2019]/g, '’'); 759 text = text.replace(/"/g, '”').replace(/"/g, '”').replace(/"/g, '”').replace(/[\u201D]/g, '”'); 760 text = text.replace(/([\w]+)=&#[\d]+;(.+?)&#[\d]+;/g, '$1="$2"'); // untexturize allowed HTML tags params double-quotes 761 return $.trim(text); 762 }, 763 764 initSlides : function(items, start_index){ 765 var width = this.jp_carousel('slideDimensions').width, 766 x = 0; 767 768 if ( items.length < 2 ) { 769 $( '.jp-carousel-next-button, .jp-carousel-previous-button' ).hide(); 770 } 771 else { 772 $( '.jp-carousel-next-button, .jp-carousel-previous-button' ).show(); 773 } 774 775 // Calculate the new src. 776 items.each(function(i){ 777 var src_item = $(this), 778 orig_size = src_item.data('orig-size') || '', 779 max = gallery.jp_carousel('slideDimensions'), 780 parts = orig_size.split(','); 781 orig_size = {width: parseInt(parts[0], 10), height: parseInt(parts[1], 10)}, 782 medium_file = src_item.data('medium-file') || '', 783 large_file = src_item.data('large-file') || ''; 784 785 src = src_item.data('orig-file'); 786 787 src = gallery.jp_carousel('selectBestImageSize', { 788 orig_file : src, 789 orig_width : orig_size.width, 790 orig_height : orig_size.height, 791 max_width : max.width, 792 max_height : max.height, 793 medium_file : medium_file, 794 large_file : large_file 795 }); 796 797 // Set the final src 798 $(this).data( 'gallery-src', src ); 799 }); 800 801 // If the start_index is not 0 then preload the clicked image first. 802 if ( 0 !== start_index ) 803 $('<img/>')[0].src = $(items[start_index]).data('gallery-src'); 804 805 var useInPageThumbnails = items.first().closest( '.tiled-gallery.type-rectangular' ).length > 0; 806 807 // create the 'slide' 808 items.each(function(i){ 809 var src_item = $(this), 810 attachment_id = src_item.data('attachment-id') || 0, 811 comments_opened = src_item.data('comments-opened') || 0, 812 image_meta = src_item.data('image-meta') || {}, 813 orig_size = src_item.data('orig-size') || '',
814 thumb_size = { width : src_item[0].naturalWidth, height : src_item[0].naturalHeight }, 815 title = src_item.data('image-title') || '', 816 description = src_item.data('image-description') || '', 817 caption = src_item.parents('dl').find('dd.gallery-caption').html() || '', 818 src = src_item.data('gallery-src') || '', 819 medium_file = src_item.data('medium-file') || '', 820 large_file = src_item.data('large-file') || '', 821 orig_file = src_item.data('orig-file') || ''; 822 823 var tiledCaption = src_item.parents('div.tiled-gallery-item').find('div.tiled-gallery-caption').html(); 824 if ( tiledCaption ) 825 caption = tiledCaption; 826 827 if ( attachment_id && orig_size.length ) { 828 title = gallery.jp_carousel('texturize', title); 829 description = gallery.jp_carousel('texturize', description); 830 caption = gallery.jp_carousel('texturize', caption); 831 832 // Initially, the image is a 1x1 transparent gif. The preview is shown as a background image on the slide itself. 833 var image = $( '<img/>' ) 834 .attr( 'src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' ) 835 .css( 'width', '100%' ) 836 .css( 'height', '100%' ); 837 838 var slide = $('<div class="jp-carousel-slide"></div>') 839 .hide() 840 .css({ 841 //'position' : 'fixed', 842 'left' : i < start_index ? -1000 : gallery.width() 843 }) 844 .append( image ) 845 .appendTo(gallery) 846 .data('src', src ) 847 .data('title', title) 848 .data('desc', description) 849 .data('caption', caption) 850 .data('attachment-id', attachment_id) 851 .data('permalink', src_item.parents('a').attr('href')) 852 .data('orig-size', orig_size) 853 .data('comments-opened', comments_opened) 854 .data('image-meta', image_meta) 855 .data('medium-file', medium_file) 856 .data('large-file', large_file) 857 .data('orig-file', orig_file) 858 .data('thumb-size', thumb_size) 859 ; 860 861 if ( useInPageThumbnails ) { 862 // Use the image already loaded in the gallery as a preview. 863 slide 864 .data( 'preview-image', src_item.attr( 'src' ) ) 865 .css( { 866 'background-image' : 'url("' + src_item.attr( 'src' ) + '")', 867 'background-size' : '100% 100%', 868 'background-position' : 'center center' 869 } ); 870 } 871 872 slide.jp_carousel( 'fitSlide', false ); 873 } 874 }); 875 return this; 876 }, 877 878 selectBestImageSize: function(args) { 879 if ( 'object' != typeof args ) 880 args = {}; 881 882 if ( 'undefined' == typeof args.orig_file ) 883 return ''; 884 885 if ( 'undefined' == typeof args.orig_width || 'undefined' == typeof args.max_width ) 886 return args.orig_file; 887 888 if ( 'undefined' == typeof args.medium_file || 'undefined' == typeof args.large_file ) 889 return args.orig_file; 890 891 var medium_size = args.medium_file.replace(/-([\d]+x[\d]+)\..+$/, '$1'), 892 medium_size_parts = (medium_size != args.medium_file) ? medium_size.split('x') : [args.orig_width, 0], 893 medium_width = parseInt( medium_size_parts[0], 10 ), 894 medium_height = parseInt( medium_size_parts[1], 10 ), 895 large_size = args.large_file.replace(/-([\d]+x[\d]+)\..+$/, '$1'), 896 large_size_parts = (large_size != args.large_file) ? large_size.split('x') : [args.orig_width, 0], 897 large_width = parseInt( large_size_parts[0], 10 ), 898 large_height = parseInt( large_size_parts[1], 10 ); 899 900 // Give devices with a higher devicePixelRatio higher-res images (Retina display = 2, Android phones = 1.5, etc) 901 if ('undefined' != typeof window.devicePixelRatio && window.devicePixelRatio > 1) { 902 args.max_width = args.max_width * window.devicePixelRatio; 903 args.max_height = args.max_height * window.devicePixelRatio; 904 } 905 906 if ( large_width >= args.max_width || large_height >= args.max_height ) 907 return args.large_file; 908 909 if ( medium_width >= args.max_width || medium_height >= args.max_height ) 910 return args.medium_file; 911 912 return args.orig_file; 913 }, 914 915 916 originalDimensions: function() { 917 var splitted = $(this).data('orig-size').split(','); 918 return {width: parseInt(splitted[0], 10), height: parseInt(splitted[1], 10)}; 919 }, 920 921 format: function( args ) { 922 if ( 'object' != typeof args ) 923 args = {}; 924 if ( ! args.text || 'undefined' == typeof args.text ) 925 return; 926 if ( ! args.replacements || 'undefined' == typeof args.replacements ) 927 return args.text; 928 return args.text.replace(/{(\d+)}/g, function(match, number) { 929 return typeof args.replacements[number] != 'undefined' ? args.replacements[number] : match; 930 }); 931 }, 932 933 shutterSpeed: function(d) { 934 if (d >= 1) 935 return Math.round(d) + 's'; 936 var df = 1, top = 1, bot = 1; 937 var limit = 1e3; 938 while (df != d && limit-- > 0) { 939 if (df < d) { 940 top += 1; 941 } 942 else { 943 bot += 1; 944 top = parseInt(d * bot, 10); 945 } 946 df = top / bot; 947 } 948 if (top > 1) { 949 bot = Math.round(bot / top); 950 top = 1; 951 } 952 if (bot <= 1) 953 return '1s'; 954 return top + '/' + bot + 's'; 955 }, 956 957 parseTitleDesc: function( value ) { 958 if ( !value.match(' ') && value.match('_') ) 959 return ''; 960 // Prefix list originally based on http://commons.wikimedia.org/wiki/MediaWiki:Filename-prefix-blacklist 961 var prefixes = $([ 962 'CIMG', // Casio 963 'DSC_', // Nikon 964 'DSCF', // Fuji 965 'DSCN', // Nikon 966 'DUW', // some mobile phones 967 'GEDC', // GE 968 'IMG', // generic 969 'JD', // Jenoptik 970 'MGP', // Pentax 971 'PICT', // misc. 972 'Imagen', // misc. 973 'Foto', // misc. 974 'DSC', // misc. 975 'Scan', // Scanners 976 'SANY', // Sanyo 977 'SAM', // Samsung 978 'Screen Shot [0-9]+' // Mac screenshots 979 ]) 980 .each(function(key, val){ 981 regex = new RegExp('^' + val); 982 if ( regex.test(value) ) { 983 value = ''; 984 return; 985 } 986 }); 987 return value; 988 }, 989 990 getTitleDesc: function( data ) { 991 var title ='', desc = '', markup = '', target, commentWrappere; 992 993 target = $( 'div.jp-carousel-titleanddesc', 'div.jp-carousel-wrap' ); 994 target.hide(); 995 996 title = gallery.jp_carousel('parseTitleDesc', data.title) || ''; 997 desc = gallery.jp_carousel('parseTitleDesc', data.desc) || ''; 998 999 if ( title.length || desc.length ) {
1000 // $('<div />').text(sometext).html() is a trick to go to HTML to plain text (including HTML entities decode, etc) 1001 if ( $('<div />').text(title).html() == $('<div />').text(desc).html() ) 1002 title = ''; 1003 1004 markup = ( title.length ) ? '<div class="jp-carousel-titleanddesc-title">' + title + '</div>' : ''; 1005 markup += ( desc.length ) ? '<div class="jp-carousel-titleanddesc-desc">' + desc + '</div>' : ''; 1006 1007 target.html( markup ).fadeIn('slow'); 1008 } 1009 1010 $( 'div#jp-carousel-comment-form-container' ).css('margin-top', '20px'); 1011 $( 'div#jp-carousel-comments-loading' ).css('margin-top', '20px'); 1012 }, 1013 1014 updateLikesWidgetVisibility: function ( attachmentId ) { 1015 // Only do this if likes is enabled 1016 if ( "undefined" === typeof jetpackLikesWidgetQueue ) 1017 return; 1018 1019 // Hide all likes widgets except for the one for the attachmentId passed in 1020 $( '.jp-carousel-buttons .jetpack-likes-widget-wrapper' ).css( 'display', 'none' ).each( function () { 1021 var widgetWrapper = $( this ); 1022 if ( widgetWrapper.attr( 'data-attachment-id' ) == attachmentId ) { 1023 widgetWrapper.css( 'display', 'inline-block' ); 1024 return false; 1025 } 1026 }); 1027 }, 1028 1029 loadLikes : function ( attachmentId ) { 1030 var dataCarouselExtra = $( '.jp-carousel-wrap' ).data( 'carousel-extra' ); 1031 var blogId = dataCarouselExtra.likes_blog_id; 1032 1033 if ( $( "#like-post-wrapper-" + blogId + "-" + attachmentId ).length == 0 ) { 1034 // Add the iframe the first time the slide is shown. 1035 var protocol = 'http'; 1036 var originDomain = 'http://wordpress.com'; 1037 1038 if ( dataCarouselExtra.permalink.length ) { 1039 var protocol = dataCarouselExtra.permalink.split( ':' )[0]; 1040 1041 if ( ( protocol != 'http' ) && ( protocol != 'https' ) ) 1042 protocol = 'http'; 1043 1044 var parts = dataCarouselExtra.permalink.split( '/' ); 1045 1046 if ( parts.length >= 2 ) 1047 originDomain = protocol + "://" + parts[2]; 1048 } 1049 1050 var dataSource = protocol + "://widgets.wp.com/likes/#blog_id=" + encodeURIComponent( blogId ) 1051 + "&post_id=" + encodeURIComponent( attachmentId ) 1052 + "&slim=1&origin=" + encodeURIComponent( originDomain ); 1053 1054 if ( 'en' !== jetpackCarouselStrings.lang ) 1055 dataSource += "&lang=" + encodeURIComponent( jetpackCarouselStrings.lang ); 1056 1057 var likesWidget = $( "<iframe class='post-likes-widget jetpack-likes-widget jetpack-resizeable'></iframe>" ) 1058 .attr( "name", "like-post-frame-" + blogId + "-" + attachmentId ) 1059 .attr( 'src', dataSource ) 1060 .css( "display", "inline-block" ); 1061 1062 var likesWidgetWrapper = $( "<div/>" ) 1063 .addClass( "jetpack-likes-widget-wrapper jetpack-likes-widget-unloaded slim-likes-widget" ) 1064 .attr( "id", "like-post-wrapper-" + blogId + "-" + attachmentId ) 1065 .attr( "data-src", dataSource ) 1066 .attr( "data-name", "like-post-frame-" + blogId + "-" + attachmentId ) 1067 .attr( "data-attachment-id", attachmentId ) 1068 .css( "display", "none" ) 1069 .css( "vertical-align", "middle" ) 1070 .append( likesWidget ) 1071 .append( "<div class='post-likes-widget-placeholder'></div>" ); 1072 1073 $( '.jp-carousel-buttons' ).append( likesWidgetWrapper ); 1074 } 1075 1076 }, 1077 1078 // updateExif updates the contents of the exif UL (.jp-carousel-image-exif) 1079 updateExif: function( meta ) { 1080 if ( !meta || 1 != jetpackCarouselStrings.display_exif ) 1081 return false; 1082 1083 var $ul = $( "<ul class='jp-carousel-image-exif'></ul>" ); 1084 1085 $.each( meta, function( key, val ) { 1086 if ( 0 === parseFloat(val) || !val.length || -1 === $.inArray( key, [ 'camera', 'aperture', 'shutter_speed', 'focal_length' ] ) ) 1087 return; 1088 1089 switch( key ) { 1090 case 'focal_length': 1091 val = val + 'mm'; 1092 break; 1093 case 'shutter_speed': 1094 val = gallery.jp_carousel('shutterSpeed', val); 1095 break; 1096 case 'aperture': 1097 val = 'f/' + val; 1098 break; 1099 } 1100 1101 $ul.append( '<li><h5>' + jetpackCarouselStrings[key] + '</h5>' + val + '</li>' ); 1102 }); 1103 1104 // Update (replace) the content of the ul 1105 $( 'div.jp-carousel-image-meta ul.jp-carousel-image-exif' ).replaceWith( $ul ); 1106 }, 1107 1108 // updateFullSizeLink updates the contents of the jp-carousel-image-download link 1109 updateFullSizeLink: function(current) { 1110 if(!current || !current.data) 1111 return false;
1112 var original = current.data('orig-file').replace(/\?.+$/, ''), 1113 origSize = current.data('orig-size').split(','), 1114 permalink = $( '<a>'+gallery.jp_carousel('format', {'text': jetpackCarouselStrings.download_original, 'replacements': origSize})+'</a>' ) 1115 .addClass( 'jp-carousel-image-download' ) 1116 .attr( 'href', original ) 1117 .attr( 'target', '_blank' ); 1118 1119 // Update (replace) the content of the anchor 1120 $( 'div.jp-carousel-image-meta a.jp-carousel-image-download' ).replaceWith( permalink ); 1121 }, 1122 1123 updateMap: function( meta ) { 1124 if ( !meta.latitude || !meta.longitude || 1 != jetpackCarouselStrings.display_geo ) 1125 return; 1126 1127 var latitude = meta.latitude, 1128 longitude = meta.longitude, 1129 $metabox = $( 'div.jp-carousel-image-meta', 'div.jp-carousel-wrap' ), 1130 $mapbox = $( '<div></div>' ), 1131 style = '&scale=2&style=feature:all|element:all|invert_lightness:true|hue:0x0077FF|saturation:-50|lightness:-5|gamma:0.91'; 1132 1133 $mapbox 1134 .addClass( 'jp-carousel-image-map' ) 1135 .html( '<img width="154" height="154" src="https://maps.googleapis.com/maps/api/staticmap?\ 1136 center=' + latitude + ',' + longitude + '&\ 1137 zoom=8&\ 1138 size=154x154&\ 1139 sensor=false&\ 1140 markers=size:medium%7Ccolor:blue%7C' + latitude + ',' + longitude + style +'" class="gmap-main" />\ 1141 \ 1142 <div class="gmap-topright"><div class="imgclip"><img width="175" height="154" src="https://maps.googleapis.com/maps/api/staticmap?\ 1143 center=' + latitude + ',' + longitude + '&\ 1144 zoom=3&\ 1145 size=175x154&\ 1146 sensor=false&\ 1147 markers=size:small%7Ccolor:blue%7C' + latitude + ',' + longitude + style + '"c /></div></div>\ 1148 \ 1149 ' ) 1150 .prependTo( $metabox ); 1151 }, 1152 1153 testCommentsOpened: function( opened ) { 1154 if ( 1 == parseInt( opened, 10 ) ) { 1155 $('.jp-carousel-buttons').fadeIn('fast'); 1156 commentForm.fadeIn('fast'); 1157 } else { 1158 $('.jp-carousel-buttons').fadeOut('fast'); 1159 commentForm.fadeOut('fast'); 1160 } 1161 }, 1162 1163 getComments: function( args ) { 1164 clearInterval( commentInterval ); 1165 1166 if ( 'object' != typeof args ) 1167 return; 1168 1169 if ( 'undefined' == typeof args.attachment_id || ! args.attachment_id ) 1170 return; 1171 1172 if ( ! args.offset || 'undefined' == typeof args.offset || args.offset < 1 ) 1173 args.offset = 0; 1174 1175 var comments = $('.jp-carousel-comments'), 1176 commentsLoading = $('#jp-carousel-comments-loading').show(); 1177 1178 if ( args.clear ) 1179 comments.hide().empty(); 1180 1181 $.ajax({ 1182 type: 'GET', 1183 url: jetpackCarouselStrings.ajaxurl, 1184 dataType: 'json', 1185 data: { 1186 action: 'get_attachment_comments', 1187 nonce: jetpackCarouselStrings.nonce, 1188 id: args.attachment_id, 1189 offset: args.offset 1190 }, 1191 success: function(data, status, xhr) { 1192 if ( args.clear ) 1193 comments.fadeOut('fast').empty(); 1194 1195 $( data ).each(function(){ 1196 var comment = $('<div></div>') 1197 .addClass('jp-carousel-comment') 1198 .attr('id', 'jp-carousel-comment-' + this['id']) 1199 .html( 1200 '<div class="comment-gravatar">' 1201 + this['gravatar_markup'] 1202 + '</div>' 1203 + '<div class="comment-author">' 1204 + this['author_markup'] 1205 + '</div>' 1206 + '<div class="comment-date">' 1207 + this['date_gmt'] 1208 + '</div>' 1209 + '<div class="comment-content">' 1210 + this['content'] 1211 + '</div>' 1212 ); 1213 comments.append(comment); 1214 1215 // Set the interval to check for a new page of comments. 1216 clearInterval( commentInterval ); 1217 commentInterval = setInterval( function() { 1218 if ( ( $('.jp-carousel-overlay').height() - 150 ) < $('.jp-carousel-wrap').scrollTop() + $(window).height() ) { 1219 gallery.jp_carousel('getComments',{ attachment_id: args.attachment_id, offset: args.offset + 10, clear: false }); 1220 clearInterval( commentInterval ); 1221 } 1222 }, 300 ); 1223 }); 1224 1225 // Verify (late) that the user didn't repeatldy click the arrows really fast, in which case the requested 1226 // attachment id might no longer match the current attachment id by the time we get the data back or a now 1227 // registered infiniscroll event kicks in, so we don't ever display comments for the wrong image by mistake. 1228 var current = $('.jp-carousel div.selected'); 1229 if ( current && current.data && current.data('attachment-id') != args.attachment_id ) { 1230 comments.fadeOut('fast'); 1231 comments.empty(); 1232 return; 1233 } 1234 1235 // Increase the height of the background, semi-transparent overlay to match the new length of the comments list. 1236 $('.jp-carousel-overlay').height( $(window).height() + titleAndDescription.height() + commentForm.height() + ( (comments.height() > 0) ? comments.height() : imageMeta.height() ) + 200 ); 1237 1238 comments.show(); 1239 commentsLoading.hide(); 1240 }, 1241 error: function(xhr, status, error) { 1242 // TODO: proper error handling 1243 console.log( 'Comment get fail...', xhr, status, error ); 1244 comments.fadeIn('fast'); 1245 commentsLoading.fadeOut('fast'); 1246 } 1247 }); 1248 }, 1249 1250 postCommentError: function(args) { 1251 if ( 'object' != typeof args ) 1252 args = {}; 1253 if ( ! args.field || 'undefined' == typeof args.field || ! args.error || 'undefined' == typeof args.error ) 1254 return;
1255 $('#jp-carousel-comment-post-results').slideUp('fast').html('<span class="jp-carousel-comment-post-error">'+args.error+'</span>').slideDown('fast'); 1256 $('#jp-carousel-comment-form-spinner').spin(false); 1257 }, 1258 1259 setCommentIframeSrc: function(attachment_id) { 1260 var iframe = $('#jp-carousel-comment-iframe'); 1261 // Set the proper irame src for the current attachment id 1262 if (iframe && iframe.length) { 1263 iframe.attr('src', iframe.attr('src').replace(/(postid=)\d+/, '$1'+attachment_id) ); 1264 iframe.attr('src', iframe.attr('src').replace(/(%23.+)?$/, '%23jp-carousel-'+attachment_id) ); 1265 } 1266 }, 1267 1268 clearCommentTextAreaValue: function() { 1269 var commentTextArea = $('#jp-carousel-comment-form-comment-field'); 1270 if ( commentTextArea ) 1271 commentTextArea.val(''); 1272 }, 1273 1274 nextSlide : function () { 1275 var slides = this.jp_carousel( 'slides' ); 1276 var selected = this.jp_carousel( 'selectedSlide' ); 1277 1278 if ( selected.length == 0 || ( slides.length > 2 && selected.is( slides.last() ) ) ) 1279 return slides.first(); 1280 1281 return selected.next(); 1282 }, 1283 1284 prevSlide : function () { 1285 var slides = this.jp_carousel( 'slides' ); 1286 var selected = this.jp_carousel( 'selectedSlide' ); 1287 1288 if ( selected.length == 0 || ( slides.length > 2 && selected.is( slides.first() ) ) ) 1289 return slides.last(); 1290 1291 return selected.prev(); 1292 }, 1293 1294 loadFullImage : function ( slide ) { 1295 var image = slide.find( 'img:first' ); 1296 1297 if ( ! image.data( 'loaded' ) ) { 1298 // If the width of the slide is smaller than the width of the "thumbnail" we're already using, 1299 // don't load the full image. 1300 1301 image.on( 'load.jetpack', function () { 1302 image.off( 'load.jetpack' ); 1303 $( this ).closest( '.jp-carousel-slide' ).css( 'background-image', '' ); 1304 } ); 1305 1306 if ( ! slide.data( 'preview-image' ) || ( slide.data( 'thumb-size' ) && slide.width() > slide.data( 'thumb-size' ).width ) ) 1307 image.attr( 'src', image.closest( '.jp-carousel-slide' ).data( 'src' ) ); 1308 else 1309 image.attr( 'src', slide.data( 'preview-image' ) ); 1310 1311 image.data( 'loaded', 1 ); 1312 } 1313 } 1314 }; 1315 1316 $.fn.jp_carousel = function(method){ 1317 // ask for the HTML of the gallery 1318 // Method calling logic 1319 if ( methods[method] ) { 1320 return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); 1321 } else if ( typeof method === 'object' || ! method ) { 1322 return methods.open.apply( this, arguments ); 1323 } else { 1324 $.error( 'Method ' + method + ' does not exist on jQuery.jp_carousel' ); 1325 } 1326 1327 }; 1328 1329 // register the event listener for starting the gallery 1330 $( document.body ).on( 'click', 'div.gallery,div.tiled-gallery', function(e) { 1331 if ( ! $(this).jp_carousel( 'testForData', e.currentTarget ) ) 1332 return; 1333 if ( $(e.target).parent().hasClass('gallery-caption') ) 1334 return; 1335 e.preventDefault(); 1336 $(this).jp_carousel('open', {start_index: $(this).find('.gallery-item, .tiled-gallery-item').index($(e.target).parents('.gallery-item, .tiled-gallery-item'))}); 1337 }); 1338 1339 // Makes carousel work on page load and when back button leads to same URL with carousel hash (ie: no actual document.ready trigger) 1340 $( window ).on( 'hashchange', function () { 1341 if ( ! window.location.hash || ! window.location.hash.match(/jp-carousel-(\d+)/) ) 1342 return; 1343 1344 if ( window.location.hash == last_known_location_hash ) 1345 return; 1346 1347 last_known_location_hash = window.location.hash; 1348 1349 var gallery = $('div.gallery, div.tiled-gallery'), index = -1, n = window.location.hash.match(/jp-carousel-(\d+)/); 1350 1351 if ( ! $(this).jp_carousel( 'testForData', gallery ) ) 1352 return; 1353 1354 n = parseInt(n[1], 10); 1355 1356 gallery.find('img').each(function(num, el){ 1357 if ( n && $(el).data('attachment-id') == n ) { // n cannot be 0 (zero) 1358 index = num; 1359 return false; 1360 } 1361 }); 1362 1363 if ( index != -1 ) 1364 gallery.jp_carousel('open', {start_index: index}); // open method checks if already opened 1365 }); 1366 1367 if ( window.location.hash ) 1368 $( window ).trigger( 'hashchange' ); 1369}); 1370 1371/** 1372 * jQuery Plugin to obtain touch gestures from iPhone, iPod Touch and iPad, should also work with Android mobile phones (not tested yet!) 1373 * Common usage: wipe images (left and right to show the previous or next image) 1374 * 1375 * @author Andreas Waltl, netCU Internetagentur (http://www.netcu.de) 1376 * Version 1.1.1, modified to pass the touchmove event to the callbacks. 1377 */ 1378(function($) { 1379$.fn.touchwipe = function(settings) { 1380 var config = { 1381 min_move_x: 20, 1382 min_move_y: 20, 1383 wipeLeft: function(e) { }, 1384 wipeRight: function(e) { }, 1385 wipeUp: function(e) { }, 1386 wipeDown: function(e) { }, 1387 preventDefaultEvents: true 1388 }; 1389 1390 if (settings) $.extend(config, settings); 1391 1392 this.each(function() { 1393 var startX; 1394 var startY; 1395 var isMoving = false;
1396 1397 function cancelTouch() { 1398 this.removeEventListener('touchmove', onTouchMove); 1399 startX = null; 1400 isMoving = false; 1401 } 1402 1403 function onTouchMove(e) { 1404 if(config.preventDefaultEvents) { 1405 e.preventDefault(); 1406 } 1407 if(isMoving) { 1408 var x = e.touches[0].pageX; 1409 var y = e.touches[0].pageY; 1410 var dx = startX - x; 1411 var dy = startY - y; 1412 if(Math.abs(dx) >= config.min_move_x) { 1413 cancelTouch(); 1414 if(dx > 0) { 1415 config.wipeLeft(e); 1416 } 1417 else { 1418 config.wipeRight(e); 1419 } 1420 } 1421 else if(Math.abs(dy) >= config.min_move_y) { 1422 cancelTouch(); 1423 if(dy > 0) { 1424 config.wipeDown(e); 1425 } 1426 else { 1427 config.wipeUp(e); 1428 } 1429 } 1430 } 1431 } 1432 1433 function onTouchStart(e) 1434 { 1435 if (e.touches.length == 1) { 1436 startX = e.touches[0].pageX; 1437 startY = e.touches[0].pageY; 1438 isMoving = true; 1439 this.addEventListener('touchmove', onTouchMove, false); 1440 } 1441 } 1442 if ('ontouchstart' in document.documentElement) { 1443 this.addEventListener('touchstart', onTouchStart, false); 1444 } 1445 }); 1446 1447 return this; 1448}; 1449})(jQuery);
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.