1/** 2 * Script for the Gallery Plugin to add nifty inline image viewing. 3 * 4 * It's based upon lightbox plus by Takuya Otani which is based upon 5 * lightbox by Lokesh Dhakar. 6 * 7 * For the DokuWiki plugin the following modifications were made: 8 * 9 * - addEvent removed (is shipped with DokuWiki) 10 * - IDs were changed to avoid clashs 11 * - previous and next buttons added 12 * - keyboard support added 13 * - neighbor preloading (not sure if it works) 14 * 15 * @license Creative Commons Attribution 2.5 License 16 * @author Takuya Otani <takuya.otani@gmail.com> 17 * @link http://serennz.cool.ne.jp/sb/sp/lightbox/ 18 * @author Lokesh Dhakar <lokesh@huddletogether.com> 19 * @link http://www.huddletogether.com/projects/lightbox/ 20 * @author Andreas Gohr <andi@splitbrain.org> 21 */ 22 23/* Original copyright notices follow: 24 25 lightbox_plus.js 26 == written by Takuya Otani <takuya.otani@gmail.com> === 27 == Copyright (C) 2006 SimpleBoxes/SerendipityNZ Ltd. == 28 29 Copyright (C) 2006 Takuya Otani/SimpleBoxes - http://serennz.cool.ne.jp/sb/ 30 Copyright (C) 2006 SerendipityNZ - http://serennz.cool.ne.jp/snz/ 31 32 This script is licensed under the Creative Commons Attribution 2.5 License 33 http://creativecommons.org/licenses/by/2.5/ 34 35 basically, do anything you want, just leave my name and link. 36 37 Original script : Lightbox JS : Fullsize Image Overlays 38 Copyright (C) 2005 Lokesh Dhakar - http://www.huddletogether.com 39 For more information on this script, visit: 40 http://huddletogether.com/projects/lightbox/ 41*/ 42 43function WindowSize() 44{ // window size object 45 this.w = 0; 46 this.h = 0; 47 return this.update(); 48} 49WindowSize.prototype.update = function() 50{ 51 var d = document; 52 this.w = 53 (window.innerWidth) ? window.innerWidth 54 : (d.documentElement && d.documentElement.clientWidth) ? d.documentElement.clientWidth 55 : d.body.clientWidth; 56 this.h = 57 (window.innerHeight) ? window.innerHeight 58 : (d.documentElement && d.documentElement.clientHeight) ? d.documentElement.clientHeight 59 : d.body.clientHeight; 60 return this; 61}; 62function PageSize() 63{ // page size object 64 this.win = new WindowSize(); 65 this.w = 0; 66 this.h = 0; 67 return this.update(); 68} 69PageSize.prototype.update = function() 70{ 71 var d = document; 72 this.w = 73 (window.innerWidth && window.scrollMaxX) ? window.innerWidth + window.scrollMaxX 74 : (d.body.scrollWidth > d.body.offsetWidth) ? d.body.scrollWidth 75 : d.body.offsetWidt; 76 this.h = 77 (window.innerHeight && window.scrollMaxY) ? window.innerHeight + window.scrollMaxY 78 : (d.body.scrollHeight > d.body.offsetHeight) ? d.body.scrollHeight 79 : d.body.offsetHeight; 80 this.win.update(); 81 if (this.w < this.win.w) this.w = this.win.w; 82 if (this.h < this.win.h) this.h = this.win.h; 83 return this; 84}; 85function PagePos() 86{ // page position object 87 this.x = 0; 88 this.y = 0; 89 return this.update(); 90} 91PagePos.prototype.update = function() 92{ 93 var d = document; 94 this.x = 95 (window.pageXOffset) ? window.pageXOffset 96 : (d.documentElement && d.documentElement.scrollLeft) ? d.documentElement.scrollLeft 97 : (d.body) ? d.body.scrollLeft 98 : 0; 99 this.y = 100 (window.pageYOffset) ? window.pageYOffset 101 : (d.documentElement && d.documentElement.scrollTop) ? d.documentElement.scrollTop 102 : (d.body) ? d.body.scrollTop 103 : 0; 104 return this; 105}; 106function UserAgent() 107{ // user agent information 108 var ua = navigator.userAgent; 109 this.isWinIE = this.isMacIE = false; 110 this.isGecko = ua.match(/Gecko\//); 111 this.isSafari = ua.match(/AppleWebKit/); 112 this.isOpera = window.opera; 113 if (document.all && !this.isGecko && !this.isSafari && !this.isOpera) { 114 this.isWinIE = ua.match(/Win/); 115 this.isMacIE = ua.match(/Mac/); 116 this.isNewIE = (ua.match(/MSIE 5\.5/) || ua.match(/MSIE 6\.0/)); 117 } 118 return this; 119} 120// === lightbox === 121function LightBox(option) 122{ 123 var self = this; 124 self._imgs = new Array(); 125 self._wrap = null; 126 self._box = null; 127 self._open = -1; 128 self._page = new PageSize(); 129 self._pos = new PagePos(); 130 self._ua = new UserAgent(); 131 self._expandable = false; 132 self._expanded = false; 133 self._expand = option.expandimg; 134 self._shrink = option.shrinkimg; 135 return self._init(option); 136} 137LightBox.prototype = { 138 _init : function(option) 139 { 140 var self = this; 141 var d = document; 142 if (!d.getElementsByTagName) return; 143 var links = d.getElementsByTagName("a"); 144 for (var i=0;i<links.length;i++) { 145 var anchor = links[i]; 146 var num = self._imgs.length; 147 if (!anchor.getAttribute("href") 148 || anchor.getAttribute("rel") != "lightbox") continue; 149 // initialize item 150 self._imgs[num] = {src:anchor.getAttribute("href"),w:-1,h:-1,title:'',cls:anchor.className}; 151 if (anchor.getAttribute("title")) 152 self._imgs[num].title = anchor.getAttribute("title"); 153 else if (anchor.firstChild && anchor.firstChild.getAttribute && anchor.firstChild.getAttribute("title")) 154 self._imgs[num].title = anchor.firstChild.getAttribute("title"); 155 anchor.onclick = self._genOpener(num); // set closure to onclick event 156 } 157 var body = d.getElementsByTagName("body")[0]; 158 self._wrap = self._createWrapOn(body,option.loadingimg); 159 self._box = self._createBoxOn(body,option); 160 return self; 161 }, 162 _genOpener : function(num) 163 { 164 var self = this; 165 return function() { 166 self._show(num); 167 if(window.event) window.event.returnValue = false; 168 return false; 169 } 170 }, 171 _createWrapOn : function(obj,imagePath) 172 { 173 var self = this; 174 if (!obj) return null; 175 // create wrapper object, translucent background 176 var wrap = document.createElement('div'); 177 wrap.id = 'gallery__overlay'; 178 with (wrap.style) { 179 display = 'none'; 180 position = 'fixed'; 181 top = '0px'; 182 left = '0px'; 183 zIndex = '50'; 184 width = '100%'; 185 height = '100%'; 186 } 187 if (self._ua.isWinIE) wrap.style.position = 'absolute'; 188 addEvent(wrap,"click",function() { self._close(); }); 189 obj.appendChild(wrap); 190 // create loading image, animated image 191 var imag = new Image; 192 imag.onload = function() { 193 var spin = document.createElement('img'); 194 spin.id = 'gallery__loadingImage'; 195 spin.src = imag.src; 196 spin.style.position = 'relative'; 197 self._set_cursor(spin); 198 addEvent(spin,'click',function() { self._close(); }); 199 wrap.appendChild(spin); 200 imag.onload = function(){}; 201 }; 202 if (imagePath != '') imag.src = imagePath; 203 return wrap; 204 }, 205 _createBoxOn : function(obj,option) 206 { 207 var self = this; 208 if (!obj) return null; 209 // create lightbox object, frame rectangle 210 var box = document.createElement('div'); 211 box.id = 'gallery__lightbox'; 212 with (box.style) { 213 display = 'none'; 214 position = 'absolute'; 215 zIndex = '60'; 216 } 217 obj.appendChild(box); 218 // create image object to display a target image 219 var img = document.createElement('img'); 220 img.id = 'gallery__lightboxImage'; 221 self._set_cursor(img); 222 addEvent(img,'click',function(){ self._close(); }); 223 addEvent(img,'mouseover',function(){ self._show_action(); }); 224 addEvent(img,'mouseout',function(){ self._hide_action(); }); 225 box.appendChild(img); 226 var zoom = document.createElement('img'); 227 zoom.id = 'gallery__actionImage'; 228 with (zoom.style) { 229 display = 'none'; 230 position = 'absolute'; 231 top = '15px'; 232 left = '15px'; 233 zIndex = '70'; 234 } 235 self._set_cursor(zoom); 236 zoom.src = self._expand; 237 addEvent(zoom,'mouseover',function(){ self._show_action(); }); 238 addEvent(zoom,'click', function() { self._zoom(); }); 239 box.appendChild(zoom); 240 addEvent(window,'resize',function(){ self._set_size(true); }); 241 // close button 242 if (option.closeimg) { 243 var btn = document.createElement('img'); 244 btn.id = 'gallery__closeButton'; 245 with (btn.style) { 246 display = 'inline'; 247 position = 'absolute'; 248 right = '10px'; 249 top = '10px'; 250 zIndex = '80'; 251 } 252 btn.src = option.closeimg; 253 self._set_cursor(btn); 254 addEvent(btn,'click',function(){ self._close(); }); 255 box.appendChild(btn); 256 } 257 // next button 258 if (option.nextimg) { 259 var btn = document.createElement('img'); 260 btn.id = 'gallery__nextButton'; 261 with (btn.style) { 262 display = 'inline'; 263 position = 'absolute'; 264 right = '10px'; 265 bottom = '10px'; 266 zIndex = '80'; 267 } 268 btn.src = option.nextimg; 269 self._set_cursor(btn); 270 addEvent(btn,'click',function(){ self._move(+1) }); 271 box.appendChild(btn); 272 } 273 // prev button 274 if (option.previmg) { 275 var btn = document.createElement('img'); 276 btn.id = 'gallery__prevButton'; 277 with (btn.style) { 278 display = 'inline'; 279 position = 'absolute'; 280 left = '10px'; 281 bottom = '10px'; 282 zIndex = '80'; 283 } 284 btn.src = option.previmg; 285 self._set_cursor(btn); 286 addEvent(btn,'click',function(){ self._move(-1) }); 287 box.appendChild(btn); 288 } 289 // caption text 290 var caption = document.createElement('span'); 291 caption.id = 'gallery__lightboxCaption'; 292 with (caption.style) { 293 display = 'none'; 294 position = 'absolute'; 295 zIndex = '80'; 296 } 297 box.appendChild(caption); 298 return box; 299 }, 300 _set_photo_size : function() 301 { 302 var self = this; 303 if (self._open == -1) return; 304 var imag = self._box.firstChild; 305 var targ = { w:self._page.win.w - 30, h:self._page.win.h - 30 }; 306 var orig = { w:self._imgs[self._open].w, h:self._imgs[self._open].h }; 307 // shrink image with the same aspect 308 var ratio = 1.0; 309 if ((orig.w >= targ.w || orig.h >= targ.h) && orig.h && orig.w) 310 ratio = ((targ.w / orig.w) < (targ.h / orig.h)) ? targ.w / orig.w : targ.h / orig.h; 311 imag.width = Math.floor(orig.w * ratio); 312 imag.height = Math.floor(orig.h * ratio); 313 self._expandable = (ratio < 1.0) ? true : false; 314 if (self._ua.isWinIE) self._box.style.display = "block"; 315 self._box.style.top = [self._pos.y + (self._page.win.h - imag.height - 30) / 2,'px'].join(''); 316 self._box.style.left = [((self._page.win.w - imag.width - 30) / 2),'px'].join(''); 317 self._show_caption(true); 318 }, 319 _set_size : function(onResize) 320 { 321 var self = this; 322 if (self._open == -1) return; 323 self._page.update(); 324 self._pos.update(); 325 var spin = self._wrap.firstChild; 326 if (spin) { 327 var top = (self._page.win.h - spin.height) / 2; 328 if (self._wrap.style.position == 'absolute') top += self._pos.y; 329 spin.style.top = [top,'px'].join(''); 330 spin.style.left = [(self._page.win.w - spin.width - 30) / 2,'px'].join(''); 331 } 332 if (self._ua.isWinIE) { 333 self._wrap.style.width = [self._page.win.w,'px'].join(''); 334 self._wrap.style.height = [self._page.h,'px'].join(''); 335 } 336 if (onResize) self._set_photo_size(); 337 }, 338 _show_action : function() 339 { 340 var self = this; 341 if (self._open == -1 || !self._expandable) return; 342 var obj = document.getElementById('gallery__actionImage'); 343 if (!obj) return; 344 obj.src = (self._expanded) ? self._shrink : self._expand; 345 obj.style.display = 'inline'; 346 }, 347 _hide_action : function() 348 { 349 var self = this; 350 var obj = document.getElementById('gallery__actionImage'); 351 if (obj) obj.style.display = 'none'; 352 }, 353 _zoom : function() 354 { 355 var self = this; 356 if (self._expanded) { 357 self._set_photo_size(); 358 self._expanded = false; 359 } else if (self._open > -1) { 360 var imag = self._box.firstChild; 361 self._box.style.top = [self._pos.y,'px'].join(''); 362 self._box.style.left = '0px'; 363 imag.width = self._imgs[self._open].w; 364 imag.height = self._imgs[self._open].h; 365 self._show_caption(false); 366 self._expanded = true; 367 } 368 self._show_action(); 369 }, 370 _show_caption : function(enable) 371 { 372 var self = this; 373 var caption = document.getElementById('gallery__lightboxCaption'); 374 if (!caption) return; 375 if (caption.innerHTML.length == 0 || !enable) { 376 caption.style.display = 'none'; 377 } else { // now display caption 378 var imag = self._box.firstChild; 379 with (caption.style) { 380 top = [imag.height + 10,'px'].join(''); // 10 is top margin of lightbox 381 left = '0px'; 382 width = [imag.width + 20,'px'].join(''); // 20 is total side margin of lightbox 383 height = '1.2em'; 384 display = 'block'; 385 } 386 } 387 }, 388 _move : function(by) 389 { 390 var self = this; 391 var num = self._open + by; 392 // wrap around at start and end 393 if(num < 0) num = self._imgs.length - 1; 394 if(num >= self._imgs.length) num = 0; 395 396 self._disable_keyboard(); 397 self._hide_action(); 398 self._box.style.display = "none"; 399 self._show(num); 400 }, 401 _show : function(num) 402 { 403 var self = this; 404 var imag = new Image; 405 if (num < 0 || num >= self._imgs.length) return; 406 var loading = document.getElementById('gallery__loadingImage'); 407 var caption = document.getElementById('gallery__lightboxCaption'); 408 self._open = num; // set opened image number 409 self._set_size(false); // calc and set wrapper size 410 self._wrap.style.display = "block"; 411 if (loading) loading.style.display = 'inline'; 412 imag.onload = function() { 413 if (self._imgs[self._open].w == -1) { 414 // store original image width and height 415 self._imgs[self._open].w = imag.width; 416 self._imgs[self._open].h = imag.height; 417 } 418 if (caption) caption.innerHTML = self._imgs[self._open].title; 419 self._set_photo_size(); // calc and set lightbox size 420 self._hide_action(); 421 self._box.style.display = "block"; 422 self._box.firstChild.src = imag.src; 423 self._box.firstChild.setAttribute('title',self._imgs[self._open].title); 424 if (loading) loading.style.display = 'none'; 425 }; 426 self._expandable = false; 427 self._expanded = false; 428 self._enable_keyboard(); 429 imag.src = self._imgs[self._open].src; 430 self._preload_neighbors(num); 431 }, 432 _preload_neighbors: function(num){ 433 var self = this; 434 435 if((self._imgs.length - 1) > num){ 436 var preloadNextImage = new Image(); 437 preloadNextImage.src = self._imgs[num + 1].src; 438 } 439 if(num > 0){ 440 var preloadPrevImage = new Image(); 441 preloadPrevImage.src = self._imgs[num - 1].src; 442 } 443 }, 444 _set_cursor : function(obj) 445 { 446 var self = this; 447 if (self._ua.isWinIE && !self._ua.isNewIE) return; 448 obj.style.cursor = 'pointer'; 449 }, 450 _close : function() 451 { 452 var self = this; 453 self._open = -1; 454 self._disable_keyboard(); 455 self._hide_action(); 456 self._wrap.style.display = "none"; 457 self._box.style.display = "none"; 458 }, 459 _enable_keyboard: function() 460 { 461 //globally store refernce to current lightbox object: 462 __lightbox = this; 463 addEvent(document,'keydown',this._keyboard_action); 464 }, 465 _disable_keyboard: function() 466 { 467 //remove global pointer: 468 delete __lightbox; 469 removeEvent(document,'keydown',this._keyboard_action); 470 }, 471 _keyboard_action: function(e) { 472 var self = __lightbox; 473 var keycode = 0; 474 475 if(e.which){ // mozilla 476 keycode = e.which; 477 }else{ // IE 478 keycode = event.keyCode; 479 } 480 481 var key = String.fromCharCode(keycode).toLowerCase(); 482 if((key == 'x') || (key == 'c') || (keycode == 27)){ // close lightbox 483 self._close(); 484 } else if( (key == 'p') || (keycode == 37) ){ // display previous image 485 self._move(-1); 486 } else if(key == 'n' || (keycode == 39) ){ // display next image 487 self._move(+1); 488 } 489 } 490}; 491 492/** 493 * Add a quicklink to the media popup 494 */ 495function gallery_plugin(){ 496 var opts = $('media__opts'); 497 if(!opts) return; 498 if(!window.opener) return; 499 500 var glbl = document.createElement('label'); 501 var glnk = document.createElement('a'); 502 var gbrk = document.createElement('br'); 503 glnk.name = 'gallery_plugin'; 504 glnk.innerHTML = 'Add namespace as gallery'; 505 glnk.style.cursor = 'pointer'; 506 507 glnk.onclick = function(){ 508 var h1 = $('media__ns'); 509 if(!h1) return; 510 var ns = h1.innerHTML; 511 opener.insertAtCarret('wiki__text','{{gallery>'+ns+'}}'); 512 if(!media.keepopen) window.close(); 513 }; 514 515 opts.appendChild(glbl); 516 glbl.appendChild(glnk); 517 opts.appendChild(gbrk); 518} 519 520// === main === 521addInitEvent(function() { 522 var lightbox = new LightBox({ 523 loadingimg:DOKU_BASE+'lib/plugins/gallery/images/loading.gif', 524 expandimg:DOKU_BASE+'lib/plugins/gallery/images/expand.gif', 525 shrinkimg:DOKU_BASE+'lib/plugins/gallery/images/shrink.gif', 526 closeimg:DOKU_BASE+'lib/plugins/gallery/images/close.gif', 527 nextimg:DOKU_BASE+'lib/plugins/gallery/images/next.gif', 528 previmg:DOKU_BASE+'lib/plugins/gallery/images/prev.gif' 529 }); 530 gallery_plugin(); 531}); 532