1/** 2 * 3 * jQuery Galleriffic plugin 4 * 5 * 6 * Copyright (c) 2008 Trent Foley (http://trentacular.com) 7 * Licensed under the MIT License: 8 * http://www.opensource.org/licenses/mit-license.php 9 * 10 * 11 * Much thanks to primary contributer Ponticlaro (http://www.ponticlaro.com) 12 */ 13; 14(function($) { 15 // Globally keep track of all images by their unique hash. Each item is an image data object. 16 var allImages = {}; 17 var imageCounter = 0; 18 //var image_active = 0; 19 20 // Galleriffic static class 21 $.galleriffic = { 22 version: '2.0.1', 23 24 // Strips invalid characters and any leading # characters 25 normalizeHash: function(hash) { 26 return hash.replace(/^.*#/, '').replace(/\?.*$/, ''); 27 }, 28 29 getImage: function(hash) { 30 if (!hash) 31 return undefined; 32 33 hash = $.galleriffic.normalizeHash(hash); 34 return allImages[hash]; 35 }, 36 37 // Global function that looks up an image by its hash and displays the image. 38 // Returns false when an image is not found for the specified hash. 39 // @param {String} hash This is the unique hash value assigned to an image. 40 gotoImage: function(hash) { 41 var imageData = $.galleriffic.getImage(hash); 42 if (!imageData) 43 return false; 44 45 var gallery = imageData.gallery; 46 gallery.gotoImage(imageData); 47 48 return true; 49 }, 50 51 // Removes an image from its respective gallery by its hash. 52 // Returns false when an image is not found for the specified hash or the 53 // specified owner gallery does match the located images gallery. 54 // @param {String} hash This is the unique hash value assigned to an image. 55 // @param {Object} ownerGallery (Optional) When supplied, the located images 56 // gallery is verified to be the same as the specified owning gallery before 57 // performing the remove operation. 58 removeImageByHash: function(hash, ownerGallery) { 59 var imageData = $.galleriffic.getImage(hash); 60 if (!imageData) 61 return false; 62 63 var gallery = imageData.gallery; 64 if (ownerGallery && ownerGallery != gallery) 65 return false; 66 67 return gallery.removeImageByIndex(imageData.index); 68 } 69 }; 70 71 var defaults = { 72 delay: 3000, 73 numThumbs: 20, 74 preloadAhead: 40, // Set to -1 to preload all images 75 enableTopPager: false, 76 enableBottomPager: true, 77 maxPagesToShow: 7, 78 imageContainerSel: '', 79 captionContainerSel: '', 80 controlsContainerSel: '', 81 loadingContainerSel: '', 82 renderSSControls: true, 83 renderNavControls: true, 84 playLinkText: 'Play', 85 pauseLinkText: 'Pause', 86 prevLinkText: 'Previous', 87 nextLinkText: 'Next', 88 nextPageLinkText: 'Next ›', 89 prevPageLinkText: '‹ Prev', 90 enableHistory: false, 91 setThumbnailWidth: true, 92 enableKeyboardNavigation: true, 93 autoStart: false, 94 syncTransitions: false, 95 defaultTransitionDuration: 1000, 96 onSlideChange: undefined, // accepts a delegate like such: function(prevIndex, nextIndex) { ... } 97 onTransitionOut: undefined, // accepts a delegate like such: function(slide, caption, isSync, callback) { ... } 98 onTransitionIn: undefined, // accepts a delegate like such: function(slide, caption, isSync) { ... } 99 onPageTransitionOut: undefined, // accepts a delegate like such: function(callback) { ... } 100 onPageTransitionIn: undefined, // accepts a delegate like such: function() { ... } 101 onImageAdded: undefined, // accepts a delegate like such: function(imageData, $li) { ... } 102 onImageRemoved: undefined // accepts a delegate like such: function(imageData, $li) { ... } 103 }; 104 105 // Primary Galleriffic initialization function that should be called on the thumbnail container. 106 $.fn.galleriffic = function(settings) { 107 // Extend Gallery Object 108 $.extend(this, { 109 // Returns the version of the script 110 version: $.galleriffic.version, 111 112 // Current state of the slideshow
113 isSlideshowRunning: false, 114 slideshowTimeout: undefined, 115 116 // This function is attached to the click event of generated hyperlinks within the gallery 117 clickHandler: function(e, link) { 118 this.pause(); 119 if (!this.enableHistory) { 120 // The href attribute holds the unique hash for an image 121 var hash = $.galleriffic.normalizeHash($(link).attr('href')); 122 $.galleriffic.gotoImage(hash); 123 e.preventDefault(); 124 } 125 }, 126 127 // Appends an image to the end of the set of images. Argument listItem can be either a jQuery DOM element or arbitrary html. 128 // @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery. 129 appendImage: function(listItem) { 130 this.addImage(listItem, false, false); 131 return this; 132 }, 133 134 // Inserts an image into the set of images. Argument listItem can be either a jQuery DOM element or arbitrary html. 135 // @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery. 136 // @param {Integer} position The index within the gallery where the item shouold be added. 137 insertImage: function(listItem, position) { 138 this.addImage(listItem, false, true, position); 139 return this; 140 }, 141 142 // Adds an image to the gallery and optionally inserts/appends it to the DOM (thumbExists) 143 // @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery. 144 // @param {Boolean} thumbExists Specifies whether the thumbnail already exists in the DOM or if it needs to be added. 145 // @param {Boolean} insert Specifies whether the the image is appended to the end or inserted into the gallery. 146 // @param {Integer} position The index within the gallery where the item shouold be added. 147 addImage: function(listItem, thumbExists, insert, position) { 148 var $li = ( typeof listItem === "string" ) ? $(listItem) : listItem; 149 var $aThumb = $li.find('a.thumb'); 150 var slideUrl = $aThumb.attr('href'); 151 var title = $aThumb.attr('title'); 152 var $caption = $li.find('.caption').remove(); 153 var hash = $aThumb.attr('name'); 154 155 // Increment the image counter 156 imageCounter++; 157 158 // Autogenerate a hash value if none is present or if it is a duplicate 159 if (!hash || allImages[''+hash]) { 160 hash = imageCounter; 161 } 162 163 // Set position to end when not specified 164 if (!insert) 165 position = this.data.length; 166 167 var imageData = { 168 title:title, 169 slideUrl:slideUrl, 170 caption:$caption, 171 hash:hash, 172 gallery:this, 173 index:position 174 }; 175 176 // Add the imageData to this gallery's array of images 177 if (insert) { 178 this.data.splice(position, 0, imageData); 179 180 // Reset index value on all imageData objects 181 this.updateIndices(position); 182 } 183 else { 184 this.data.push(imageData); 185 } 186 187 var gallery = this; 188 189 // Add the element to the DOM 190 if (!thumbExists) { 191 // Update thumbs passing in addition post transition out handler 192 this.updateThumbs(function() { 193 var $thumbsUl = gallery.find('ul.thumbs'); 194 if (insert) 195 $thumbsUl.children(':eq('+position+')').before($li); 196 else 197 $thumbsUl.append($li); 198 199 if (gallery.onImageAdded) 200 gallery.onImageAdded(imageData, $li); 201 }); 202 } 203 204 // Register the image globally 205 allImages[''+hash] = imageData; 206 207 // Setup attributes and click handler 208 $aThumb.attr('rel', 'history') 209 .attr('href', '#'+hash) 210 .removeAttr('name') 211 .click(function(e) { 212 //gallery.clickHandler(e, this); 213 var el = $(this); 214 gallery.gotoIndex(position); 215 }); 216 217 return this; 218 }, 219 220 // Removes an image from the gallery based on its index. 221 // Returns false when the index is out of range. 222 removeImageByIndex: function(index) { 223 if (index < 0 || index >= this.data.length) 224 return false;
225 226 var imageData = this.data[index]; 227 if (!imageData) 228 return false; 229 230 this.removeImage(imageData); 231 232 return true; 233 }, 234 235 // Convenience method that simply calls the global removeImageByHash method. 236 removeImageByHash: function(hash) { 237 return $.galleriffic.removeImageByHash(hash, this); 238 }, 239 240 // Removes an image from the gallery. 241 removeImage: function(imageData) { 242 var index = imageData.index; 243 244 // Remove the image from the gallery data array 245 this.data.splice(index, 1); 246 247 // Remove the global registration 248 delete allImages[''+imageData.hash]; 249 250 // Remove the image's list item from the DOM 251 this.updateThumbs(function() { 252 var $li = gallery.find('ul.thumbs') 253 .children(':eq('+index+')') 254 .remove(); 255 256 if (gallery.onImageRemoved) 257 gallery.onImageRemoved(imageData, $li); 258 }); 259 260 // Update each image objects index value 261 this.updateIndices(index); 262 263 return this; 264 }, 265 266 // Updates the index values of the each of the images in the gallery after the specified index 267 updateIndices: function(startIndex) { 268 for (i = startIndex; i < this.data.length; i++) { 269 this.data[i].index = i; 270 } 271 272 return this; 273 }, 274 275 // Scraped the thumbnail container for thumbs and adds each to the gallery 276 initializeThumbs: function() { 277 this.data = []; 278 var gallery = this; 279 280 this.find('ul.thumbs > li').each(function(i) { 281 gallery.addImage($(this), true, false); 282 }); 283 284 return this; 285 }, 286 287 isPreloadComplete: false, 288 289 // Initalizes the image preloader 290 preloadInit: function() { 291 if(global['load_image_to']) 292 this.currentImage = this.data[global['load_image_to']]; 293 294 if (this.preloadAhead == 0 || !this.currentImage.index) return this; 295 296 this.preloadStartIndex = this.currentImage.index; 297 var nextIndex = this.getNextIndex(this.preloadStartIndex); 298 return this.preloadRecursive(this.preloadStartIndex, nextIndex); 299 }, 300 301 // Changes the location in the gallery the preloader should work 302 // @param {Integer} index The index of the image where the preloader should restart at. 303 preloadRelocate: function(index) { 304 // By changing this startIndex, the current preload script will restart 305 this.preloadStartIndex = index; 306 return this; 307 }, 308 309 // Recursive function that performs the image preloading 310 // @param {Integer} startIndex The index of the first image the current preloader started on. 311 // @param {Integer} currentIndex The index of the current image to preload. 312 preloadRecursive: function(startIndex, currentIndex) { 313 // Check if startIndex has been relocated 314 if (startIndex != this.preloadStartIndex) { 315 var nextIndex = this.getNextIndex(this.preloadStartIndex); 316 return this.preloadRecursive(this.preloadStartIndex, nextIndex); 317 } 318 319 var gallery = this; 320 321 // Now check for preloadAhead count 322 var preloadCount = currentIndex - startIndex; 323 if (preloadCount < 0) 324 preloadCount = this.data.length-1-startIndex+currentIndex; 325 if (this.preloadAhead >= 0 && preloadCount > this.preloadAhead) { 326 // Do this in order to keep checking for relocated start index 327 setTimeout(function() { 328 gallery.preloadRecursive(startIndex, currentIndex); 329 }, 500); 330 return this; 331 } 332 333 var imageData = this.data[currentIndex]; 334 if (!imageData) 335 return this; 336 337 // If already loaded, continue 338 if (imageData.image) 339 return this.preloadNext(startIndex, currentIndex); 340 341 // Preload the image 342 var image = new Image(); 343 344 image.onload = function() { 345 imageData.image = this; 346 gallery.preloadNext(startIndex, currentIndex); 347 }; 348 349 image.alt = imageData.title;
350 image.src = imageData.slideUrl; 351 352 return this; 353 }, 354 355 // Called by preloadRecursive in order to preload the next image after the previous has loaded. 356 // @param {Integer} startIndex The index of the first image the current preloader started on. 357 // @param {Integer} currentIndex The index of the current image to preload. 358 preloadNext: function(startIndex, currentIndex) { 359 var nextIndex = this.getNextIndex(currentIndex); 360 if (nextIndex == startIndex) { 361 this.isPreloadComplete = true; 362 } else { 363 // Use setTimeout to free up thread 364 var gallery = this; 365 setTimeout(function() { 366 gallery.preloadRecursive(startIndex, nextIndex); 367 }, 100); 368 } 369 370 return this; 371 }, 372 373 // Safe way to get the next image index relative to the current image. 374 // If the current image is the last, returns 0 375 getNextIndex: function(index) { 376 var nextIndex = index+1; 377 if (nextIndex >= this.data.length) 378 nextIndex = 0; 379 return nextIndex; 380 }, 381 382 // Safe way to get the previous image index relative to the current image. 383 // If the current image is the first, return the index of the last image in the gallery. 384 getPrevIndex: function(index) { 385 var prevIndex = index-1; 386 if (prevIndex < 0) 387 prevIndex = this.data.length-1; 388 return prevIndex; 389 }, 390 391 // Pauses the slideshow 392 pause: function() { 393 this.isSlideshowRunning = false; 394 if (this.slideshowTimeout) { 395 clearTimeout(this.slideshowTimeout); 396 this.slideshowTimeout = undefined; 397 } 398 399 if (this.$controlsContainer) { 400 this.$controlsContainer 401 .find('div.ss-controls a').removeClass().addClass('play') 402 .attr('title', this.playLinkText) 403 .attr('href', '#play') 404 .html(this.playLinkText); 405 } 406 407 return this; 408 }, 409 410 // Plays the slideshow 411 play: function() { 412 this.isSlideshowRunning = true; 413 414 if (this.$controlsContainer) { 415 this.$controlsContainer 416 .find('div.ss-controls a').removeClass().addClass('pause') 417 .attr('title', this.pauseLinkText) 418 .attr('href', '#pause') 419 .html(this.pauseLinkText); 420 } 421 422 if (!this.slideshowTimeout) { 423 var gallery = this; 424 this.slideshowTimeout = setTimeout(function() { 425 gallery.ssAdvance(); 426 }, this.delay); 427 } 428 429 return this; 430 }, 431 432 // Toggles the state of the slideshow (playing/paused) 433 toggleSlideshow: function() { 434 if (this.isSlideshowRunning) 435 this.pause(); 436 else 437 this.play(); 438 439 return this; 440 }, 441 442 // Advances the slideshow to the next image and delegates navigation to the 443 // history plugin when history is enabled 444 // enableHistory is true 445 ssAdvance: function() { 446 if (this.isSlideshowRunning) 447 this.next(true); 448 449 return this; 450 }, 451 452 // Advances the gallery to the next image. 453 // @param {Boolean} dontPause Specifies whether to pause the slideshow. 454 // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled. 455 next: function(dontPause, bypassHistory) { 456 this.gotoIndex(this.getNextIndex(this.currentImage.index), dontPause, bypassHistory); 457 return this; 458 }, 459 460 // Navigates to the previous image in the gallery. 461 // @param {Boolean} dontPause Specifies whether to pause the slideshow. 462 // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled. 463 previous: function(dontPause, bypassHistory) { 464 this.gotoIndex(this.getPrevIndex(this.currentImage.index), dontPause, bypassHistory); 465 return this; 466 }, 467 468 // Navigates to the next page in the gallery. 469 // @param {Boolean} dontPause Specifies whether to pause the slideshow. 470 // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled. 471 nextPage: function(dontPause, bypassHistory) { 472 var page = this.getCurrentPage(); 473 var lastPage = this.getNumPages() - 1; 474 if (page < lastPage) { 475 var startIndex = page * this.numThumbs; 476 var nextPage = startIndex + this.numThumbs; 477 this.gotoIndex(nextPage, dontPause, bypassHistory); 478 } 479 480 return this; 481 }, 482 483 // Navigates to the previous page in the gallery. 484 // @param {Boolean} dontPause Specifies whether to pause the slideshow. 485 // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled. 486 previousPage: function(dontPause, bypassHistory) { 487 var page = this.getCurrentPage(); 488 if (page > 0) { 489 var startIndex = page * this.numThumbs; 490 var prevPage = startIndex - this.numThumbs; 491 this.gotoIndex(prevPage, dontPause, bypassHistory); 492 } 493 494 return this; 495 }, 496 497 // Navigates to the image at the specified index in the gallery 498 // @param {Integer} index The index of the image in the gallery to display. 499 // @param {Boolean} dontPause Specifies whether to pause the slideshow. 500 // @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled. 501 gotoIndex: function(index, dontPause, bypassHistory) { 502 if (!dontPause) 503 this.pause(); 504 505 if (index < 0) index = 0; 506 else if (index >= this.data.length) index = this.data.length-1; 507 508 var imageData = this.data[index]; 509 510 if (!bypassHistory && this.enableHistory) 511 $.historyLoad(String(imageData.hash)); // At the moment, historyLoad only accepts string arguments 512 else 513 this.gotoImage(imageData); 514 515 return this; 516 }, 517 518 // This function is garaunteed to be called anytime a gallery slide changes. 519 // @param {Object} imageData An object holding the image metadata of the image to navigate to. 520 gotoImage: function(imageData) { 521 var index = imageData.index; 522 523 if (this.onSlideChange) 524 this.onSlideChange(this.currentImage.index, index); 525 this.currentImage = imageData; 526 this.preloadRelocate(index); 527 528 this.refresh(); 529 return this; 530 }, 531 532 // Returns the default transition duration value. The value is halved when not 533 // performing a synchronized transition. 534 // @param {Boolean} isSync Specifies whether the transitions are synchronized. 535 getDefaultTransitionDuration: function(isSync) { 536 if (isSync) 537 return this.defaultTransitionDuration; 538 return this.defaultTransitionDuration / 2; 539 }, 540 541 // Rebuilds the slideshow image and controls and performs transitions 542 refresh: function() { 543 var imageData = this.currentImage; 544 if (!imageData) 545 return this; 546 547 var index = imageData.index; 548 549 // Update Controls 550 if (this.$controlsContainer) { 551 this.$controlsContainer
552 .find('div.nav-controls a.prev').attr('href', '#'+this.data[this.getPrevIndex(index)].hash).end() 553 .find('div.nav-controls a.next').attr('href', '#'+this.data[this.getNextIndex(index)].hash); 554 } 555 556 var previousSlide = this.$imageContainer.find('span.current').addClass('previous').removeClass('current'); 557 var previousCaption = 0; 558 559 if (this.$captionContainer) { 560 previousCaption = this.$captionContainer.find('span.current').addClass('previous').removeClass('current'); 561 } 562 563 // Perform transitions simultaneously if syncTransitions is true and the next image is already preloaded 564 var isSync = this.syncTransitions && imageData.image; 565 566 // Flag we are transitioning 567 var isTransitioning = true; 568 var gallery = this; 569 570 var transitionOutCallback = function() { 571 // Flag that the transition has completed 572 isTransitioning = false; 573 574 // Remove the old slide 575 previousSlide.remove(); 576 577 // Remove old caption 578 if (previousCaption) 579 previousCaption.remove(); 580 581 if (!isSync) { 582 if (imageData.image && imageData.hash == gallery.data[gallery.currentImage.index].hash) { 583 gallery.buildImage(imageData, isSync); 584 } else { 585 // Show loading container 586 if (gallery.$loadingContainer) { 587 gallery.$loadingContainer.show(); 588 } 589 } 590 } 591 }; 592 593 if (previousSlide.length == 0) { 594 // For the first slide, the previous slide will be empty, so we will call the callback immediately 595 transitionOutCallback(); 596 } else { 597 if (this.onTransitionOut) { 598 this.onTransitionOut(previousSlide, previousCaption, isSync, transitionOutCallback); 599 } else { 600 previousSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0, transitionOutCallback); 601 if (previousCaption) 602 previousCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0); 603 } 604 } 605 606 // Go ahead and begin transitioning in of next image 607 if (isSync) 608 this.buildImage(imageData, isSync); 609 610 if (!imageData.image) { 611 var image = new Image(); 612
613 // Wire up mainImage onload event 614 image.onload = function() { 615 imageData.image = this; 616 617 // Only build image if the out transition has completed and we are still on the same image hash 618 if (!isTransitioning && imageData.hash == gallery.data[gallery.currentImage.index].hash) { 619 gallery.buildImage(imageData, isSync); 620 } 621 622 if(global['fullscreen_gallery'] == true && (imageData.slideUrl).indexOf('&w') != -1){ 623 center_fullscreen_img(); 624 } 625 var cde = setInterval(function(){ 626 if($j('a.advance-img-link img').height() < 1 && $j('div.title-in-top').height() < 1) 627 return; 628 clearInterval(cde); 629 var slide_height = $j('a.advance-img-link img').height() + $j('div.title-in-top').height() + 15; 630 if(slide_height < 330) 631 slide_height = 330; 632// $j('#images-container .slideshow-container').css('height', slide_height); 633 },200) 634 }; 635 636 // set alt and src 637 image.alt = imageData.title; 638 639 640 //see if in fullscreen mode or not to set image width and height 641 if(global['fullscreen_gallery'] == true && (imageData.slideUrl).indexOf('&w') != -1){ 642 var img_src = (imageData.slideUrl).substr(0,(imageData.slideUrl).indexOf('&w')); 643 image.src = img_src+'&w='+(screen.width)+'&h='+(screen.height)+'&scale=9'; 644 } else { 645 image.src = imageData.slideUrl; 646 } 647 } 648 649 // This causes the preloader (if still running) to relocate out from the currentIndex 650 this.relocatePreload = true; 651 652 return this.syncThumbs(); 653 }, 654 655 // Called by the refresh method after the previous image has been transitioned out or at the same time 656 // as the out transition when performing a synchronous transition. 657 // @param {Object} imageData An object holding the image metadata of the image to build. 658 // @param {Boolean} isSync Specifies whether the transitions are synchronized. 659 buildImage: function(imageData, isSync) { 660 var gallery = this; 661 var nextIndex = this.getNextIndex(imageData.index); 662 663 // Construct new hidden span for the image 664 var title_class = this.title_class; 665 if(!title_class) title_class = 'title-in-top'; 666 var ex_desc = imageData.caption.find('.desc-hidden').html() ? imageData.caption.find('.desc-hidden').html() : ''; 667 var ex_wm_text = ''; 668 if(imageData.caption.find('.watermark-text').html()) 669 ex_wm_text = imageData.caption.find('.watermark-text').html(); 670 if(ex_wm_text != '') 671 ex_wm_text = 'Courtesy of ' + ex_wm_text; 672 var ex_wm_url = ''; 673 if(imageData.caption.find('.watermark-url').html()) 674 ex_wm_url = imageData.caption.find('.watermark-url').html(); 675 var newSlide = this.$imageContainer 676 .html('<span class="image-wrapper current">'+ 677 '<span id="imageGalleryContainer" style="position:relative;">'+ 678 '<a class="advance-img-link" href="javascript:void(0)" title="'+imageData.title+'"> </a>'+ 679 '</span>'+ 680 '<div style="float:right;" class="Link16">'+ 681 '<a style="color:#3B5998; font-size:11px; font-style:italic;" href="'+ex_wm_url+'" target="_blank">'+ex_wm_text+'</a>'+ 682 '</div>'+ 683 '<a id="title_anchor"class="advance-link" rel="history" href="javascript:void(0)" title="'+imageData.title+'"><div class="'+title_class+'" '+(ex_desc.length<100?'align="center"':'')+'>'+ex_desc+'</div> </a>'+ 684 '</span>') 685 .find('span.current').css('opacity', '0'); 686 687 /*var src_img = $(imageData.image).attr("src"), pbg = (src_img.search('&')==-1 ? '?rand=':'&rand=') ; 688 if(src_img.search('rand')==-1){ 689 $(imageData.image).attr("src",src_img+pbg+Math.floor(Math.random()*11)); 690 }*/ 691 692 $(imageData.image).load(function(){ 693 var max_height_width = this.height; 694 if(max_height_width>500) 695// $j('#images-container .slideshow-container').css('height',(max_height_width+60)+'px'); 696 var slide_height = $j('a.advance-img-link img').height() + $j('div.title-in-top').height() + 15; 697 if(slide_height < 330) 698 slide_height = 330; 699// $j('#images-container .slideshow-container').css('height', slide_height); 700 //else 701 //$j('#images-container .slideshow-container').css('height',''); 702 }); 703 $j(imageData.image).css('position','relative'); 704 $j(imageData.image).attr('class','advance-img-data'); 705 706 var img_file = $j(newSlide).find('img').attr('src'); 707 if(!img_file){ 708 newSlide.find('.advance-img-link') 709 .append(imageData.image) 710 .click(function(e){ 711 gallery.gotoIndex(nextIndex); 712 //gallery.clickHandler(e, this); 713 }); 714 newSlide.find('.advance-link') 715 .click(function(e) { 716 gallery.gotoIndex(nextIndex); 717 //gallery.clickHandler(e, this); 718 }); 719 } 720 721 var newCaption = 0; 722 if (this.$captionContainer) { 723 // Construct new hidden caption for the image 724 newCaption = this.$captionContainer 725 .append('<span class="image-caption current"></span>') 726 .find('span.current').css('opacity', '0') 727 .append(imageData.caption); 728 } 729 730 // Hide the loading conatiner 731 if (this.$loadingContainer) { 732 this.$loadingContainer.hide(); 733 } 734 735 // Transition in the new image 736 if (this.onTransitionIn) { 737 this.onTransitionIn(newSlide, newCaption, isSync); 738 } else { 739 newSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0); 740 if (newCaption) 741 newCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0); 742 } 743 744 if (this.isSlideshowRunning) { 745 if (this.slideshowTimeout) 746 clearTimeout(this.slideshowTimeout); 747 748 this.slideshowTimeout = setTimeout(function() { 749 gallery.ssAdvance(); 750 }, this.delay); 751 } 752 753 return this; 754 }, 755 756 // Returns the current page index that should be shown for the currentImage 757 getCurrentPage: function() { 758 return Math.floor(this.currentImage.index / this.numThumbs
758); 759 }, 760 761 // Applies the selected class to the current image's corresponding thumbnail. 762 // Also checks if the current page has changed and updates the displayed page of thumbnails if necessary. 763 syncThumbs: function() { 764 var page = this.getCurrentPage(); 765 if (page != this.displayedPage) 766 this.updateThumbs(); 767 768 // Remove existing selected class and add selected class to new thumb 769 var $thumbs = this.find('ul.thumbs').children(); 770 $thumbs.find('img').filter('.selected').removeClass('selected'); 771 $thumbs.find('img').eq(this.currentImage.index).addClass('selected'); 772 773 return this; 774 }, 775 776 // Performs transitions on the thumbnails container and updates the set of 777 // thumbnails that are to be displayed and the navigation controls. 778 // @param {Delegate} postTransitionOutHandler An optional delegate that is called after 779 // the thumbnails container has transitioned out and before the thumbnails are rebuilt. 780 updateThumbs: function(postTransitionOutHandler) { 781 var gallery = this; 782 var transitionOutCallback = function() { 783 // Call the Post-transition Out Handler 784 if (postTransitionOutHandler) 785 postTransitionOutHandler(); 786 787 gallery.rebuildThumbs(); 788 789 // Transition In the thumbsContainer 790 if (gallery.onPageTransitionIn) 791 gallery.onPageTransitionIn(); 792 else 793 gallery.show(); 794 }; 795 796 // Transition Out the thumbsContainer 797 if (this.onPageTransitionOut) { 798 this.onPageTransitionOut(transitionOutCallback); 799 } else { 800 this.hide(); 801 transitionOutCallback(); 802 } 803 804 return this; 805 }, 806 807 // Updates the set of thumbnails that are to be displayed and the navigation controls. 808 rebuildThumbs: function() { 809 var needsPagination = this.data.length > this.numThumbs; 810 var lastPage = this.getNumPages() - 1; 811 //if(!image_active) image_active = this.numThumbs; 812 813 // Rebuild top pager 814 if (this.enableTopPager) { 815 var $topPager = this.find('div.top'); 816 if ($topPager.length == 0) 817 $topPager = this.prepend('<div class="top pagination"></div>').find('div.top'); 818 else 819 $topPager.empty(); 820 821 if (needsPagination) 822 this.buildPager($topPager); 823 } 824 825 // Rebuild bottom pager 826 if (this.enableBottomPager) { 827 var $bottomPager = this.find('div.bottom'); 828 if ($bottomPager.length == 0) 829 $bottomPager = this.append('<div class="bottom pagination"></div>').find('div.bottom'); 830 else 831 $bottomPager.empty(); 832 833 if (needsPagination) 834 this.buildPager($bottomPager); 835 } 836 837 var page = this.getCurrentPage(); 838 var startIndex = page*this.numThumbs; 839 var stopIndex = startIndex+this.numThumbs-1; 840 if (stopIndex >= this.data.length) 841 stopIndex = this.data.length-1; 842 843 // Show/Hide thumbs 844 var $thumbsUl = this.find('ul.thumbs'); 845 var $thumbsUlLi = this.find('ul.thumbs li'); 846 847 if(this.setThumbnailWidth){ 848 $thumbsUl.css('width',(stopIndex-startIndex+1)*100+'px'); 849 }else{ 850 $thumbsUl.css('height','585px'); 851 } 852 /*$thumbsUl.find('li').each(function(i) { 853 var $li = $(this); 854 $li.hide(); 855 });*/ 856 857 if(page==0) 858 $('#prev_image').css('visibility','hidden'); 859 else 860 $('#prev_image').css('visibility','visible'); 861 862 if(page==lastPage) 863 $('#next_image').css('visibility','hidden'); 864 else 865 $('#next_image').css('visibility','visible'); 866 867 868 $thumbsUl.find('li').each(function(i) { 869 var $li = $(this); 870 if (i >= startIndex && i <= stopIndex) { 871 $li.show(); 872 var img = $li.find('img'); 873 if(img){ 874 if(img.attr('src').indexOf('spacer.gif') != -1){ 875 img.attr('src',img.attr('rel')); 876 img.attr('alt',img.attr('title')); 877 } 878 } 879 } else { 880 $li.hide(); 881 } 882 $li.find('img.selected').css('opacity','1'); 883 }); 884 885 this.displayedPage = page; 886 $j('.navigation-container').css('visibility',''); 887 $j('#page').css('visibility',''); 888 $j('#pageV').css('visibility',''); 889 // Remove the noscript class from the thumbs container ul 890 $thumbsUl.removeClass('noscript'); 891 892 return this; 893 }, 894 895 // Returns the total number of pages required to display all the thumbnails. 896 getNumPages: function() { 897 return Math.ceil(this.data.length/this.numThumbs
897); 898 }, 899 900 // Rebuilds the pager control in the specified matched element. 901 // @param {jQuery} pager A jQuery element set matching the particular pager to be rebuilt. 902 buildPager: function(pager) { 903 var gallery = this; 904 var numPages = this.getNumPages(); 905 var page = this.getCurrentPage(); 906 var startIndex = page * this.numThumbs; 907 var pagesRemaining = this.maxPagesToShow - 1; 908 909 var pageNum = page - Math.floor((this.maxPagesToShow - 1) / 2) + 1; 910 if (pageNum > 0) { 911 var remainingPageCount = numPages - pageNum; 912 if (remainingPageCount < pagesRemaining) { 913 pageNum = pageNum - (pagesRemaining - remainingPageCount); 914 } 915 } 916 917 if (pageNum < 0) { 918 pageNum = 0; 919 } 920 921 // Prev Page Link 922 if (page > 0) { 923 var prevPage = startIndex - this.numThumbs; 924 //pager.append('<a rel="history" href="#'+this.data[prevPage].hash+'" title="'+this.prevPageLinkText+'">'+this.prevPageLinkText+'</a>'); 925 pager.append('<a rel="history" href="javascript:void(0)" title="'+this.prevPageLinkText+'">'+this.prevPageLinkText+'</a>'); 926 } 927 928 // Create First Page link if needed 929 if (pageNum > 0) { 930 this.buildPageLink(pager, 0, numPages); 931 if (pageNum > 1) 932 pager.append('<span class="ellipsis">…</span>'); 933 934 pagesRemaining--; 935 } 936 937 // Page Index Links 938 while (pagesRemaining > 0) { 939 this.buildPageLink(pager, pageNum, numPages); 940 pagesRemaining--; 941 pageNum++; 942 } 943 944 // Create Last Page link if needed 945 if (pageNum < numPages) { 946 var lastPageNum = numPages - 1; 947 if (pageNum < lastPageNum) 948 pager.append('<span class="ellipsis">…</span>'); 949 950 this.buildPageLink(pager, lastPageNum, numPages); 951 } 952 953 // Next Page Link 954 var nextPage = startIndex + this.numThumbs; 955 if (nextPage < this.data.length) { 956 //pager.append('<a rel="history" href="#'+this.data[nextPage].hash+'" title="'+this.nextPageLinkText+'">'+this.nextPageLinkText+'</a>'); 957 pager.append('<a rel="history" href="javascript:void(0)" title="'+this.nextPageLinkText+'">'+this.nextPageLinkText+'</a>'); 958 } 959 960 pager.find('a').click(function(e) { 961 gallery.clickHandler(e, this); 962 }); 963 964 return this; 965 }, 966 967 // Builds a single page link within a pager. This function is called by buildPager 968 // @param {jQuery} pager A jQuery element set matching the particular pager to be rebuilt. 969 // @param {Integer} pageNum The page number of the page link to build. 970 // @param {Integer} numPages The total number of pages required to display all thumbnails. 971 buildPageLink: function(pager, pageNum, numPages) { 972 var pageLabel = pageNum + 1; 973 var currentPage = this.getCurrentPage(); 974 if (pageNum == currentPage) 975 pager.append('<span class="current">'+pageLabel+'</span>'); 976 else if (pageNum < numPages) { 977 var imageIndex = pageNum*this.numThumbs; 978 //pager.append('<a rel="history" href="#'+this.data[imageIndex].hash+'" title="'+pageLabel+'">'+pageLabel+'</a>'); 979 pager.append('<a rel="history" href="javascript:void(0)" title="'+pageLabel+'">'+pageLabel+'</a>'); 980 } 981 982 return this; 983 } 984 }); 985 986 // Now initialize the gallery 987 $.extend(this, defaults, settings); 988 989 // Verify the history plugin is available 990 if (this.enableHistory && !$.historyInit) 991 this.enableHistory = false;
992 993 // Select containers 994 if (this.imageContainerSel) this.$imageContainer = $(this.imageContainerSel); 995 if (this.captionContainerSel) this.$captionContainer = $(this.captionContainerSel); 996 if (this.loadingContainerSel) this.$loadingContainer = $(this.loadingContainerSel); 997 998 // Initialize the thumbails 999 this.initializeThumbs(); 1000 1001 if (this.maxPagesToShow < 3) 1002 this.maxPagesToShow = 3; 1003 1004 this.displayedPage = -1; 1005 this.currentImage = this.data[0]; 1006 var gallery = this; 1007 1008 // Hide the loadingContainer 1009 if (this.$loadingContainer) 1010 this.$loadingContainer.hide(); 1011 1012 // Setup controls 1013 if (this.controlsContainerSel) { 1014 this.$controlsContainer = $(this.controlsContainerSel).empty(); 1015 1016 if (this.renderSSControls) { 1017 if (this.autoStart) { 1018 this.$controlsContainer 1019 .append('<div class="ss-controls"><a href="#pause" class="pause" title="'+this.pauseLinkText+'">'+this.pauseLinkText+'</a></div>'); 1020 } else { 1021 this.$controlsContainer 1022 .append('<div class="ss-controls"><a href="#play" class="play" title="'+this.playLinkText+'">'+this.playLinkText+'</a></div>'); 1023 } 1024 1025 this.$controlsContainer.find('div.ss-controls a') 1026 .click(function(e) { 1027 gallery.toggleSlideshow(); 1028 e.preventDefault(); 1029 return false; 1030 }); 1031 } 1032 1033 if (this.renderNavControls) { 1034 var fs = '' 1035 if(!SD.isSafari && !SD.isIE){ 1036 //fs = '<div class="fullscreen_gallery" title="Fullscreen View"></div>'; 1037 } 1038 this.$controlsContainer 1039 .append('<div class="nav-controls">'+ 1040 fs+ 1041 '<a class="prev" rel="history" title="'+this.prevLinkText+'">'+this.prevLinkText+'</a>'+ 1042 '<a class="next" rel="history" title="'+this.nextLinkText+'">'+this.nextLinkText+'</a>'+ 1043 '</div>') 1044 .find('div.nav-controls') 1045 .mouseenter(function(){ 1046 $('div#controls div.nav-controls a.prev').fadeIn(100); 1047 $('div#controls div.nav-controls a.next').fadeIn(100); 1048 }) 1049 .mouseleave(function(){ 1050 $('div#controls div.nav-controls a.prev').fadeOut(100); 1051 $('div#controls div.nav-controls a.next').fadeOut(100); 1052 }) 1053 .end() 1054 .find('div.nav-controls a') 1055 .click(function(e) { 1056 gallery.clickHandler(e, this); 1057 if(global['fullscreen_gallery'] == true){ 1058 center_fullscreen_img(); 1059 } else { 1060 global['fullscreen_gallery'] = false; 1061 var fs_false = setInterval(function(){ 1062 var src = $j('#images-container .slideshow-container img').attr('src'); 1063 if(typeof(src)=='undefined'){ 1064 return; 1065 } 1066 clearInterval(fs_false); 1067 1068 if(src.indexOf('&w') != -1){ 1069 var esrc = src.substr(0,src.indexOf('&w'))+'&w=625&h=600&scale=9'; 1070 //$j('#images-container .slideshow-container img').attr({'src':esrc}); 1071 } 1072 1073 $j('#loading_img_container').hide; 1074 $j('div.nav-controls div.fullscreen_gallery').attr({ 1075 'style':'' 1076 }); 1077 $j('div.controls a').css('top',''); 1078 $j('span.image-wrapper a.advance-link').css({ 1079 'position':'', 1080 'left':'', 1081 'bottom':'', 1082 'height':'' 1083 });
1084 $j('div.nav-controls').css('height',''); 1085 $j('div.nav-controls a.next').css({ 1086 'width':'', 1087 'background-position':'' 1088 }); 1089 $j('#images-container .slideshow-container img').css({ 1090 'top':'' 1091 }); 1092 var slide_height = $j('a.advance-img-link img').height() + $j('div.title-in-top').height() + 15; 1093 if(slide_height < 330) 1094 slide_height = 330; 1095// $j('#images-container .slideshow-container').css('height', slide_height); 1096 $j('#images-container .slideshow-container').addClass('cd_bg'); 1097 }, 500); 1098 } 1099 }) 1100 .end() 1101 .find('div.nav-controls div.fullscreen_gallery').click(function(){ 1102 if(!SD.isIE && !SD.isSafari){ 1103 if (gallery.$loadingContainer) { 1104 gallery.$loadingContainer.show(); 1105 } 1106 $(this).css({ 1107 'background-image':'url("/img/business_finder/images/close_fs.png")', 1108 'width':'20px', 1109 'height':'20px' 1110 }); 1111 $j('div.nav-controls').css('height',screen.height+'px'); 1112 $j('div.nav-controls a.next').css({ 1113 'width':(screen.width-72)+'px', 1114 'background-position':(screen.width-100)+'px' 1115 }); 1116 //$j('div.controls a').css('top',((screen.height/2)-($j('div.controls a').width()/2))+'px'); 1117 $j('#images-container .slideshow-container').toggleFullScreen(); 1118 $j('#images-container .slideshow-container').removeClass('cd_bg'); 1119// $j('#images-container .slideshow-container').css('height',screen.height+'px'); 1120 center_fullscreen_img(); 1121 var fs_true = setInterval(function(){ 1122 var src = $j('#images-container .slideshow-container img').attr('src'); 1123 if(typeof(src)=='undefined'){ 1124 return; 1125 } 1126 clearInterval(fs_true); 1127 if(src.indexOf('&w') != -1){ 1128 var esrc = src.substr(0,src.indexOf('&w'))+'&w='+(screen.width)+'&h='+(screen.height)+'&scale=9'; 1129 $j('#images-container .slideshow-container img').attr({ 1130 'src':esrc 1131 }); 1132 } else { 1133 gallery.$loadingContainer.hide(); 1134 } 1135 }, 500); 1136 } 1137 }); 1138 1139 } 1140 } 1141 1142 /*var initFirstImage = !this.enableHistory || !location.hash; 1143 if (this.enableHistory && location.hash) { 1144 var hash = $.galleriffic.normalizeHash(location.hash); 1145 var imageData = allImages[hash]; 1146 if (!imageData) 1147 initFirstImage = true; 1148 }*/ 1149 1150 // Setup gallery to show the first image 1151 //if (initFirstImage || true) 1152 //this.gotoIndex(0, true, true); 1153 1154 // Setup Keyboard Navigation 1155 /*if (this.enableKeyboardNavigation) { 1156 $(document).keydown(function(e) { 1157 var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0; 1158 switch(key) { 1159 case 32: // space 1160 gallery.next(); 1161 e.preventDefault(); 1162 break; 1163 case 33: // Page Up 1164 gallery.previousPage(); 1165 e.preventDefault(); 1166 break; 1167 case 34: // Page Down 1168 gallery.nextPage(); 1169 e.preventDefault(); 1170 break; 1171 case 35: // End 1172 gallery.gotoIndex(gallery.data.length-1); 1173 e.preventDefault(); 1174 break; 1175 case 36: // Home 1176 gallery.gotoIndex(0); 1177 e.preventDefault(); 1178 break; 1179 case 37: // left arrow 1180 gallery.previous(); 1181 e.preventDefault(); 1182 break; 1183 case 39: // right arrow 1184 gallery.next(); 1185 e.preventDefault(); 1186 break; 1187 } 1188 }); 1189 }*/ 1190 1191 // Auto start the slideshow 1192 if (this.autoStart) 1193 this.play(); 1194 1195 // Kickoff Image Preloader after 1 second 1196 setTimeout(function() { 1197 gallery.preloadInit(); 1198 }, 1000); 1199 1200 return this; 1201 }; 1202})(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.