1(function ($) { 2 $.fn.dsImageView = function (opts) { 3 var options = $.extend({ 4 transition: "fade", // Transition 5 playSpeed: 5000, // Time (ms) for each image when playing through 6 disabledClass: "disabled", // CSS class for disabled previous/next elements 7 image: $("#ds-image"), // [required] image element, will have its src attribute replaced as necessary 8 description: $("#ds-description"), // [required] Description element, its content is replaced by the current image description 9 previous: $("#ds-previous"), // [required] "previous" element 10 imageNumber: $("#ds-image-number"), // [required] Image number element, its content is replaced by the current image number 11 next: $("#ds-next"), // [required] "next" element 12 totalNumber: $("#ds-total-number"), // [required] Total number element, its content is replaced by the total number of images 13 descriptions: null, // [required] Collection of image description elements 14 close: $("#ds-close"), // [optional] "Close" button 15 play: $("#ds-play"), // [optional] "play" element 16 stop: $("#ds-pause"), // [optional] "stop" element 17 overlay: null, // [optional] Overlay element, automatically faded in/out and resized as necessary 18 container: null, // [optional] Container element, resized as necessary 19 activeClass: "active", // [optional] CSS class for "active" links 20 playable: true, // [optional] Playing enabled 21 autoPlay: false, // [optional] Start playing automatically 22 callback: null, // [optional] callback to be notified of image changes - function (activatedImageNumber) {...} 23 containerTop: 20, // [optional] Sets default space for the fullview container from top 24 commentForm: $("#ds-comment-form"), // [optional] Comment form element 25 commentList: "div.GalleryComments" // [optional] Comment list selector 26 }, opts), 27 playable = options.playable && options.play && options.stop, 28 autoPlay = options.autoPlay && playable, 29 subjects = this, 30 disabledClass = options.disabledClass, 31 ie6 = ($.browser.msie && $.browser.version < "7"), 32 currentImage = null, 33 images = [], 34 playId = null, 35 containerWidth = null, 36 containerHeight = null, 37 containerTop = null; 38 var count = 0; 39 40 function show() { 41 var obj = $(this); 42 currentImage = null; 43 44 // Size image view appropriately 45 adjustSize(); 46 47 // Hide objects that MSIE would show above the overlay 48 if (ie6) { 49 $("embed, object, select").css({ visibility: "hidden" }); 50 } 51 52 // Show image view 53 presentContainer(function () { 54 view(obj); 55 initPlaying(); 56 }); 57 58 eventHandlers("bind"); 59 return false; 60 } 61 62 function view(obj) { 63 var index = subjects.index(obj); 64 stopPlaying(); 65 go(index); 66 return false; 67 } 68 69 function go(image) { 70 var from = currentImage, 71 to = image; 72 image = (image + images.length) % images.length; 73 to = image; 74 75 if (image !== currentImage && image >= 0 && image < images.length) { 76 currentImage = image; 77 loadImage(images[currentImage].src, function () { 78 if (currentImage !== null) { 79 transitionImage(from, to); 80 } 81 }); 82 refreshNavigation(); 83 if (options.callback) { 84 options.callback(currentImage); 85 } 86 resetPlayTimeout(); 87 preloadNeighbours(); 88 } 89 } 90 91 function transitionImage(from, to) { 92 var obj = options.image.parent().parent(), 93 fwd = ((from < to) && !(from === 0 && to === images.length - 1)) || (from === images.length - 1 && to === 0), 94 src = images[currentImage].src; 95 obj.transitionTo(src, from === null ? false : options.transition, fwd); 96 } 97 98 function previous() { 99 go(currentImage - 1); 100 return false; 101 } 102 103 function next() { 104 go(currentImage === null ? 0 : currentImage + 1); 105 return false; 106 } 107 108 function initPlaying() { 109 options.totalNumber.html(images.length); 110 if (images.length <= 1) { 111 options.previous.parent().hide(); 112 } 113 else { 114 options.previous.parent().show(); 115 } 116 // Hide elements as necessary 117 if (playable) { 118 options.play.show(); 119 options.stop.show(); 120 121 // Autostart? 122 if (autoPlay) { 123 startPlaying(); 124 } 125 } 126 else { 127 options.play.hide(); 128 options.stop.hide(); 129 } 130 } 131 132 function playClicked() { 133 startPlaying(); 134 next(); 135 } 136 137 function startPlaying() { 138 stopPlaying(); 139 playId = window.setTimeout(next, options.playSpeed); 140 options.play.addClass(options.disabledClass); 141 options.stop.removeClass(options.disabledClass); 142 return false; 143 } 144 145 function stopPlaying() { 146 if (playId) { 147 window.clearTimeout(playId); 148 playId = null; 149 refreshNavigation(); 150 } 151 options.play.removeClass(options.disabledClass); 152 options.stop.addClass(options.disabledClass); 153 return false; 154 } 155 156 function togglePlaying() { 157 if (playId) { 158 stopPlaying(); 159 } 160 else { 161 playClicked(); 162 } 163 } 164 165 function resetPlayTimeout() { 166 if (playId) { 167 window.clearTimeout(playId); 168 playId = window.setTimeout(next, options.playSpeed); 169 } 170 } 171 172 function presentContainer(callback) { 173 // Prepare for animation 174 var children = options.container.find("> *"); 175 options.container.css({ 176 width: 0, 177 height: 0, 178 minWidth: 0, 179 minHeight: 0, 180 display: "block" 181 }); 182 options.image.css("visibility", "hidden"); 183 children.css("opacity", 0); 184
185 //children.fixIEBackground(); 186 187 // Do the animation 188 options.container.animate({ 189 width: containerWidth, 190 height: containerHeight 191 }, function () { 192 options.container.css({ 193 minWidth: containerWidth, 194 minHeight: containerHeight, 195 height: ie6 ? containerHeight : "auto" 196 }); 197 callback(); 198 options.image.css("visibility", "visible"); 199 children.animate({ opacity: 1 }); 200 }); 201 if (options.overlay) { 202 options.overlay.fadeOut(0).css({ opacity: 0.7 }).fadeIn("normal"); 203 } 204 } 205 206 function hideImage() { 207 options.image.stop(true, true).css({ opacity: 0 }); 208 options.description.stop(true, true).css({ opacity: 0 }); 209 } 210 211 function refreshNavigation() { 212 var speed = options.description.html() ? "normal" : 0; 213 options.imageNumber.text(currentImage + 1); 214 options.description.stop(true, true); 215 //options.description.fixIEBackground(); 216 options.description.fadeOut(speed, function () { 217 if (currentImage !== null) { 218 options.description.html(images[currentImage].description()); 219 options.description.find("div").each(function () { 220 var obj = $(this); 221 var id = obj.attr("id"); 222 if (id != undefined && id.length > 0) 223 obj.attr("id", "_" + id); 224 }); 225 options.description.find(options.commentList).show(); 226 if (options.commentForm.length > 0) 227 options.description.append(options.commentForm.clone()); 228 options.description.fadeIn(speed); 229 } 230 }); 231 232 subjects.removeClass(options.activeClass); 233 subjects.eq(currentImage).addClass(options.activeClass); 234 } 235 236 // Preload previous and next images 237 function preloadNeighbours() { 238 var total = images.length, 239 prev = (currentImage + total - 1) % total, 240 next = (currentImage + total + 1) % total; 241 loadImage(images[prev].src); 242 loadImage(images[next].src); 243 } 244 245 function loadImage(url, callback) { 246 var image = new Image(); 247 if (callback) { 248 image.onload = function () { 249 // Reset onload or MSIE will misbehave with animated gifs 250 image.onload = function () { }; 251 callback(); 252 }; 253 } 254 image.src = url; 255 } 256 257 function hide() { 258 // Disable event handlers 259 eventHandlers("unbind"); 260 261 // Stop playing 262 if (playable) { 263 stopPlaying(); 264 } 265 266 // Hide container 267 options.image.parent().parent().css("opacity", ""); 268 $("> *", options.container).animate({ opacity: 0 }); 269 options.container.animate({ 270 width: 0, 271 height: 0, 272 minWidth: 0, 273 minHeight: 0 274 }, "normal", function () { 275 options.description.html(""); 276 options.container.hide().width(containerWidth).height(containerHeight); 277 }); 278 options.overlay.fadeOut("normal", function () { 279 if (ie6) { 280 // Show objects that were hidden for MSIE 281 $("embed, object, select").css({ visibility: "visible" }); 282 } 283 }); 284 currentImage = null; 285 options.image.attr("src", "/resources/functions/images/empty-pixel.gif"); 286 return false; 287 } 288 289 function eventHandlers(action) { 290 // Click handlers 291 if (options.close) { 292 options.close[action]("click", hide); 293 } 294 options.next[action]("click", next); 295 options.previous[action]("click", previous); 296 if (playable) { 297 options.play[action]("click", playClicked); 298 options.stop[action]("click", stopPlaying); 299 } 300
301 // Window event handlers 302 if (options.overlay && options.container) { 303 options.overlay[action]("click", hide); 304 $(window)[action]("resize", adjustSize); 305 $(window)[action]("scroll", onScroll); 306 } 307 options.image.parent()[action]("click", next); 308 $(document)[action]("keydown", onKeyDown); 309 } 310 311 function onKeyDown(event) { 312 if (event.which == 32) { 313 // Space 314 if (playable) { 315 var target = $(event.target); 316 if (target.is("textarea, input")) 317 return; 318 togglePlaying(); 319 } 320 } else if (event.which == 27) { 321 // Escape 322 if (options.container) 323 hide(); 324 } else if (event.which == 37) { 325 // Left 326 previous(); 327 } else if (event.which == 39) { 328 // Right 329 next(); 330 } 331 } 332 333 function onScroll() { 334 var scrollLeft = $(window).scrollLeft(), 335 scrollTop = $(window).scrollTop(), 336 currentTop = options.container.position().top; 337 if (currentTop > scrollTop + containerTop) { 338 options.container.css({ 339 top: scrollTop + containerTop 340 }); 341 } 342 else if (currentTop + options.container.height() < scrollTop + $(window).height() 343 && currentTop < scrollTop + containerTop) { 344 options.container.css({ 345 top: Math.max(containerTop, scrollTop + $(window).height() - options.container.outerHeight()) 346 }); 347 } 348 349 if (ie6) { 350 options.overlay.css({ 351 position: 'absolute', 352 left: scrollLeft, 353 top: scrollTop, 354 width: $(window).width(), 355 height: $(window).height() 356 }); 357 } 358 } 359 360 function adjustSize() { 361 var scrollTop = $(window).scrollTop(), 362 scrollLeft = $(window).scrollLeft(), 363 xOffset = scrollLeft, 364 yOffset = scrollTop, 365 currentTop = Math.max(options.container.position().top, containerTop), 366 containerXOffset = ($(window).width() - options.container.width()) / 2, 367 containerYOffset = containerTop; // ($(window).height() - options.container.height()) / 2; 368 369 // overlay size 370 options.overlay.css({ 371 position: ie6 ? 'absolute' : 'fixed', 372 left: ie6 ? xOffset : 0, 373 top: ie6 ? yOffset : 0, 374 width: $(window).width(), 375 height: $(window).height() 376 }); 377 378 xOffset = scrollLeft + Math.max(0, containerXOffset); 379 yOffset = scrollTop + Math.max(containerTop, Math.max(0, containerYOffset)); 380 381 options.container.css({ 382 position: 'absolute', 383 left: Math.floor(xOffset), 384 top: Math.floor(yOffset) 385 }); 386 } 387 388 // Find all images 389 this.each(function (index) { 390 var obj = $(this); 391 images[index] = { 392 id: obj.attr("id"), 393 src: obj.attr("href"), 394 description: function () { 395 return (options.descriptions ? options.descriptions.eq(index).html() : subjects.eq(index).find("img").attr("alt")); 396 } 397 }; 398 }); 399 400 // Measure container 401 if (options.container) { 402 var css = { 403 visibility: options.container.css("visibility"), 404 display: options.container.css("display") 405 }; 406 407 options.container.css({ 408 visibility: "hidden", 409 display: "block" 410 }); 411 containerWidth = options.container.width(); 412 containerHeight = options.container.height(); 413 containerTop = options.containerTop; 414 options.container.css(css); 415 } 416 417 // Set appropriate click handlers 418 if (options.container) { 419 this.click(show); 420 } 421 else { 422 eventHandlers("bind"); 423 initPlaying(); 424 go(0); 425 this.click(function () { 426 return view($(this)); 427 }); 428 } 429 return this; 430 }; 431})(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.