source: extensions/iPiwigo/www/extensions/jquery.galleriffic.js @ 9188

Last change on this file since 9188 was 9188, checked in by Polly, 13 years ago

Adding the Phonegap www folder needed to compile.

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