/** * Script for the Gallery Plugin to add nifty inline image viewing. * * It's based upon lightbox plus by Takuya Otani which is based upon * lightbox by Lokesh Dhakar. * * For the DokuWiki plugin the following modifications were made: * * - addEvent removed (is shipped with DokuWiki) * - IDs were changed to avoid clashs * - previous and next buttons added * - keyboard support added * - neighbor preloading (not sure if it works) * * @license Creative Commons Attribution 2.5 License * @author Takuya Otani * @link http://serennz.cool.ne.jp/sb/sp/lightbox/ * @author Lokesh Dhakar * @link http://www.huddletogether.com/projects/lightbox/ * @author Andreas Gohr */ /* Original copyright notices follow: lightbox_plus.js == written by Takuya Otani === == Copyright (C) 2006 SimpleBoxes/SerendipityNZ Ltd. == Copyright (C) 2006 Takuya Otani/SimpleBoxes - http://serennz.cool.ne.jp/sb/ Copyright (C) 2006 SerendipityNZ - http://serennz.cool.ne.jp/snz/ This script is licensed under the Creative Commons Attribution 2.5 License http://creativecommons.org/licenses/by/2.5/ basically, do anything you want, just leave my name and link. Original script : Lightbox JS : Fullsize Image Overlays Copyright (C) 2005 Lokesh Dhakar - http://www.huddletogether.com For more information on this script, visit: http://huddletogether.com/projects/lightbox/ */ function WindowSize() { // window size object this.w = 0; this.h = 0; return this.update(); } WindowSize.prototype.update = function() { var d = document; this.w = (window.innerWidth) ? window.innerWidth : (d.documentElement && d.documentElement.clientWidth) ? d.documentElement.clientWidth : d.body.clientWidth; this.h = (window.innerHeight) ? window.innerHeight : (d.documentElement && d.documentElement.clientHeight) ? d.documentElement.clientHeight : d.body.clientHeight; return this; }; function PageSize() { // page size object this.win = new WindowSize(); this.w = 0; this.h = 0; return this.update(); } PageSize.prototype.update = function() { var d = document; this.w = (window.innerWidth && window.scrollMaxX) ? window.innerWidth + window.scrollMaxX : (d.body.scrollWidth > d.body.offsetWidth) ? d.body.scrollWidth : d.body.offsetWidt; this.h = (window.innerHeight && window.scrollMaxY) ? window.innerHeight + window.scrollMaxY : (d.body.scrollHeight > d.body.offsetHeight) ? d.body.scrollHeight : d.body.offsetHeight; this.win.update(); if (this.w < this.win.w) this.w = this.win.w; if (this.h < this.win.h) this.h = this.win.h; return this; }; function PagePos() { // page position object this.x = 0; this.y = 0; return this.update(); } PagePos.prototype.update = function() { var d = document; this.x = (window.pageXOffset) ? window.pageXOffset : (d.documentElement && d.documentElement.scrollLeft) ? d.documentElement.scrollLeft : (d.body) ? d.body.scrollLeft : 0; this.y = (window.pageYOffset) ? window.pageYOffset : (d.documentElement && d.documentElement.scrollTop) ? d.documentElement.scrollTop : (d.body) ? d.body.scrollTop : 0; return this; }; function UserAgent() { // user agent information var ua = navigator.userAgent; this.isWinIE = this.isMacIE = false; this.isGecko = ua.match(/Gecko\//); this.isSafari = ua.match(/AppleWebKit/); this.isOpera = window.opera; if (document.all && !this.isGecko && !this.isSafari && !this.isOpera) { this.isWinIE = ua.match(/Win/); this.isMacIE = ua.match(/Mac/); this.isNewIE = (ua.match(/MSIE 5\.5/) || ua.match(/MSIE 6\.0/)); } return this; } // === lightbox === function LightBox(option) { var self = this; self._imgs = new Array(); self._wrap = null; self._box = null; self._open = -1; self._page = new PageSize(); self._pos = new PagePos(); self._ua = new UserAgent(); self._expandable = false; self._expanded = false; self._expand = option.expandimg; self._shrink = option.shrinkimg; return self._init(option); } LightBox.prototype = { _init : function(option) { var self = this; var d = document; if (!d.getElementsByTagName) return; var links = d.getElementsByTagName("a"); for (var i=0;i= targ.w || orig.h >= targ.h) && orig.h && orig.w) ratio = ((targ.w / orig.w) < (targ.h / orig.h)) ? targ.w / orig.w : targ.h / orig.h; imag.width = Math.floor(orig.w * ratio); imag.height = Math.floor(orig.h * ratio); self._expandable = (ratio < 1.0) ? true : false; if (self._ua.isWinIE) self._box.style.display = "block"; self._box.style.top = [self._pos.y + (self._page.win.h - imag.height - 30) / 2,'px'].join(''); self._box.style.left = [((self._page.win.w - imag.width - 30) / 2),'px'].join(''); self._show_caption(true); }, _set_size : function(onResize) { var self = this; if (self._open == -1) return; self._page.update(); self._pos.update(); var spin = self._wrap.firstChild; if (spin) { var top = (self._page.win.h - spin.height) / 2; if (self._wrap.style.position == 'absolute') top += self._pos.y; spin.style.top = [top,'px'].join(''); spin.style.left = [(self._page.win.w - spin.width - 30) / 2,'px'].join(''); } if (self._ua.isWinIE) { self._wrap.style.width = [self._page.win.w,'px'].join(''); self._wrap.style.height = [self._page.h,'px'].join(''); } if (onResize) self._set_photo_size(); }, _show_action : function() { var self = this; if (self._open == -1 || !self._expandable) return; var obj = document.getElementById('gallery__actionImage'); if (!obj) return; obj.src = (self._expanded) ? self._shrink : self._expand; obj.style.display = 'inline'; }, _hide_action : function() { var self = this; var obj = document.getElementById('gallery__actionImage'); if (obj) obj.style.display = 'none'; }, _zoom : function() { var self = this; if (self._expanded) { self._set_photo_size(); self._expanded = false; } else if (self._open > -1) { var imag = self._box.firstChild; self._box.style.top = [self._pos.y,'px'].join(''); self._box.style.left = '0px'; imag.width = self._imgs[self._open].w; imag.height = self._imgs[self._open].h; self._show_caption(false); self._expanded = true; } self._show_action(); }, _show_caption : function(enable) { var self = this; var caption = document.getElementById('gallery__lightboxCaption'); if (!caption) return; if (caption.innerHTML.length == 0 || !enable) { caption.style.display = 'none'; } else { // now display caption var imag = self._box.firstChild; with (caption.style) { top = [imag.height + 10,'px'].join(''); // 10 is top margin of lightbox left = '0px'; width = [imag.width + 20,'px'].join(''); // 20 is total side margin of lightbox height = '1.2em'; display = 'block'; } } }, _move : function(by) { var self = this; var num = self._open + by; // wrap around at start and end if(num < 0) num = self._imgs.length - 1; if(num >= self._imgs.length) num = 0; self._disable_keyboard(); self._hide_action(); self._box.style.display = "none"; self._show(num); }, _show : function(num) { var self = this; var imag = new Image; if (num < 0 || num >= self._imgs.length) return; var loading = document.getElementById('gallery__loadingImage'); var caption = document.getElementById('gallery__lightboxCaption'); self._open = num; // set opened image number self._set_size(false); // calc and set wrapper size self._wrap.style.display = "block"; if (loading) loading.style.display = 'inline'; imag.onload = function() { if (self._imgs[self._open].w == -1) { // store original image width and height self._imgs[self._open].w = imag.width; self._imgs[self._open].h = imag.height; } if (caption) caption.innerHTML = self._imgs[self._open].title; self._set_photo_size(); // calc and set lightbox size self._hide_action(); self._box.style.display = "block"; self._box.firstChild.src = imag.src; self._box.firstChild.setAttribute('title',self._imgs[self._open].title); if (loading) loading.style.display = 'none'; }; self._expandable = false; self._expanded = false; self._enable_keyboard(); imag.src = self._imgs[self._open].src; self._preload_neighbors(num); }, _preload_neighbors: function(num){ var self = this; if((self._imgs.length - 1) > num){ var preloadNextImage = new Image(); preloadNextImage.src = self._imgs[num + 1].src; } if(num > 0){ var preloadPrevImage = new Image(); preloadPrevImage.src = self._imgs[num - 1].src; } }, _set_cursor : function(obj) { var self = this; if (self._ua.isWinIE && !self._ua.isNewIE) return; obj.style.cursor = 'pointer'; }, _close : function() { var self = this; self._open = -1; self._disable_keyboard(); self._hide_action(); self._wrap.style.display = "none"; self._box.style.display = "none"; }, _enable_keyboard: function() { //globally store refernce to current lightbox object: __lightbox = this; addEvent(document,'keydown',this._keyboard_action); }, _disable_keyboard: function() { //remove global pointer: delete __lightbox; removeEvent(document,'keydown',this._keyboard_action); }, _keyboard_action: function(e) { var self = __lightbox; var keycode = 0; if(e.which){ // mozilla keycode = e.which; }else{ // IE keycode = event.keyCode; } var key = String.fromCharCode(keycode).toLowerCase(); if((key == 'x') || (key == 'c') || (keycode == 27)){ // close lightbox self._close(); } else if( (key == 'p') || (keycode == 37) ){ // display previous image self._move(-1); } else if(key == 'n' || (keycode == 39) ){ // display next image self._move(+1); } } }; /** * Add a quicklink to the media popup */ function gallery_plugin(){ var opts = $('media__opts'); if(!opts) return; if(!window.opener) return; var glbl = document.createElement('label'); var glnk = document.createElement('a'); var gbrk = document.createElement('br'); glnk.name = 'gallery_plugin'; glnk.innerHTML = 'Add namespace as gallery'; glnk.style.cursor = 'pointer'; glnk.onclick = function(){ var h1 = $('media__ns'); if(!h1) return; var ns = h1.innerHTML; opener.insertAtCarret('wiki__text','{{gallery>'+ns+'}}'); if(!media.keepopen) window.close(); }; opts.appendChild(glbl); glbl.appendChild(glnk); opts.appendChild(gbrk); } // === main === addInitEvent(function() { var lightbox = new LightBox({ loadingimg:DOKU_BASE+'lib/plugins/gallery/images/loading.gif', expandimg:DOKU_BASE+'lib/plugins/gallery/images/expand.gif', shrinkimg:DOKU_BASE+'lib/plugins/gallery/images/shrink.gif', closeimg:DOKU_BASE+'lib/plugins/gallery/images/close.gif', nextimg:DOKU_BASE+'lib/plugins/gallery/images/next.gif', previmg:DOKU_BASE+'lib/plugins/gallery/images/prev.gif' }); gallery_plugin(); });