mirror of
https://github.com/splitbrain/dokuwiki-plugin-gallery.git
synced 2025-07-31 02:53:31 +00:00

Uses code by "jpbarto" darcs-hash:20080401214422-7ad00-0c8f59d8ab704868515c8354ea20cfbeb3628919.gz
562 lines
19 KiB
JavaScript
562 lines
19 KiB
JavaScript
/**
|
|
* 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 <takuya.otani@gmail.com>
|
|
* @link http://serennz.cool.ne.jp/sb/sp/lightbox/
|
|
* @author Lokesh Dhakar <lokesh@huddletogether.com>
|
|
* @link http://www.huddletogether.com/projects/lightbox/
|
|
* @author Andreas Gohr <andi@splitbrain.org>
|
|
*/
|
|
|
|
/* Original copyright notices follow:
|
|
|
|
lightbox_plus.js
|
|
== written by Takuya Otani <takuya.otani@gmail.com> ===
|
|
== 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/
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
* This variable will enable the lightbox mode for every normal image
|
|
* embedded through the normal wiki image syntax and using the ?direct
|
|
* parameter.
|
|
*
|
|
* If you don't like that behavior, set this variable to 0.
|
|
*/
|
|
var lightboxForEveryImg = 1;
|
|
|
|
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<links.length;i++) {
|
|
var anchor = links[i];
|
|
var num = self._imgs.length;
|
|
|
|
//check if this is a direct link to an image
|
|
if ( (anchor.getAttribute("href") && anchor.getAttribute("rel") == "lightbox") ||
|
|
(lightboxForEveryImg && anchor.getAttribute("class") &&
|
|
anchor.getAttribute("class").match("media") &&
|
|
anchor.firstChild.nodeName.toLowerCase().match("img") &&
|
|
anchor.getAttribute("href") &&
|
|
anchor.getAttribute("href").match("lib/exe/fetch.php|_media/")) ){
|
|
// okay add lightbox
|
|
}else{
|
|
continue;
|
|
}
|
|
|
|
|
|
// initialize item
|
|
self._imgs[num] = {src:anchor.getAttribute("href"),w:-1,h:-1,title:'',caption:'',cls:anchor.className};
|
|
if (anchor.getAttribute("title"))
|
|
self._imgs[num].title = anchor.getAttribute("title");
|
|
else if (anchor.firstChild && anchor.firstChild.getAttribute && anchor.firstChild.getAttribute("title"))
|
|
self._imgs[num].title = anchor.firstChild.getAttribute("title");
|
|
if (anchor.firstChild && anchor.firstChild.getAttribute &&
|
|
anchor.firstChild.getAttribute("title") && anchor.firstChild.getAttribute("title") == 'caption') {
|
|
self._imgs[num].caption = anchor.firstChild.innerHTML;
|
|
}
|
|
anchor.onclick = self._genOpener(num); // set closure to onclick event
|
|
}
|
|
var body = d.getElementsByTagName("body")[0];
|
|
self._wrap = self._createWrapOn(body,option.loadingimg);
|
|
self._box = self._createBoxOn(body,option);
|
|
return self;
|
|
},
|
|
_genOpener : function(num)
|
|
{
|
|
var self = this;
|
|
return function() {
|
|
self._show(num);
|
|
if(window.event) window.event.returnValue = false;
|
|
return false;
|
|
}
|
|
},
|
|
_createWrapOn : function(obj,imagePath)
|
|
{
|
|
var self = this;
|
|
if (!obj) return null;
|
|
// create wrapper object, translucent background
|
|
var wrap = document.createElement('div');
|
|
wrap.id = 'gallery__overlay';
|
|
with (wrap.style) {
|
|
display = 'none';
|
|
position = 'fixed';
|
|
top = '0px';
|
|
left = '0px';
|
|
zIndex = '50';
|
|
width = '100%';
|
|
height = '100%';
|
|
}
|
|
if (self._ua.isWinIE) wrap.style.position = 'absolute';
|
|
addEvent(wrap,"click",function() { self._close(); });
|
|
obj.appendChild(wrap);
|
|
// create loading image, animated image
|
|
var imag = new Image;
|
|
imag.onload = function() {
|
|
var spin = document.createElement('img');
|
|
spin.id = 'gallery__loadingImage';
|
|
spin.src = imag.src;
|
|
spin.style.position = 'relative';
|
|
self._set_cursor(spin);
|
|
addEvent(spin,'click',function() { self._close(); });
|
|
wrap.appendChild(spin);
|
|
imag.onload = function(){};
|
|
};
|
|
if (imagePath != '') imag.src = imagePath;
|
|
return wrap;
|
|
},
|
|
_createBoxOn : function(obj,option)
|
|
{
|
|
var self = this;
|
|
if (!obj) return null;
|
|
// create lightbox object, frame rectangle
|
|
var box = document.createElement('div');
|
|
box.id = 'gallery__lightbox';
|
|
with (box.style) {
|
|
display = 'none';
|
|
position = 'absolute';
|
|
zIndex = '60';
|
|
}
|
|
obj.appendChild(box);
|
|
// create image object to display a target image
|
|
var img = document.createElement('img');
|
|
img.id = 'gallery__lightboxImage';
|
|
self._set_cursor(img);
|
|
addEvent(img,'click',function(){ self._close(); });
|
|
addEvent(img,'mouseover',function(){ self._show_action(); });
|
|
addEvent(img,'mouseout',function(){ self._hide_action(); });
|
|
box.appendChild(img);
|
|
var zoom = document.createElement('img');
|
|
zoom.id = 'gallery__actionImage';
|
|
with (zoom.style) {
|
|
display = 'none';
|
|
position = 'absolute';
|
|
top = '15px';
|
|
left = '15px';
|
|
zIndex = '70';
|
|
}
|
|
self._set_cursor(zoom);
|
|
zoom.src = self._expand;
|
|
addEvent(zoom,'mouseover',function(){ self._show_action(); });
|
|
addEvent(zoom,'click', function() { self._zoom(); });
|
|
box.appendChild(zoom);
|
|
addEvent(window,'resize',function(){ self._set_size(true); });
|
|
// close button
|
|
if (option.closeimg) {
|
|
var btn = document.createElement('img');
|
|
btn.id = 'gallery__closeButton';
|
|
with (btn.style) {
|
|
display = 'inline';
|
|
position = 'absolute';
|
|
right = '10px';
|
|
top = '10px';
|
|
zIndex = '80';
|
|
}
|
|
btn.src = option.closeimg;
|
|
self._set_cursor(btn);
|
|
addEvent(btn,'click',function(){ self._close(); });
|
|
box.appendChild(btn);
|
|
}
|
|
// next button
|
|
if (option.nextimg) {
|
|
var btn = document.createElement('img');
|
|
btn.id = 'gallery__nextButton';
|
|
with (btn.style) {
|
|
display = 'inline';
|
|
position = 'absolute';
|
|
right = '10px';
|
|
bottom = '10px';
|
|
zIndex = '80';
|
|
}
|
|
btn.src = option.nextimg;
|
|
self._set_cursor(btn);
|
|
addEvent(btn,'click',function(){ self._move(+1) });
|
|
box.appendChild(btn);
|
|
}
|
|
// prev button
|
|
if (option.previmg) {
|
|
var btn = document.createElement('img');
|
|
btn.id = 'gallery__prevButton';
|
|
with (btn.style) {
|
|
display = 'inline';
|
|
position = 'absolute';
|
|
left = '10px';
|
|
bottom = '10px';
|
|
zIndex = '80';
|
|
}
|
|
btn.src = option.previmg;
|
|
self._set_cursor(btn);
|
|
addEvent(btn,'click',function(){ self._move(-1) });
|
|
box.appendChild(btn);
|
|
}
|
|
// caption text
|
|
var caption = document.createElement('span');
|
|
caption.id = 'gallery__lightboxCaption';
|
|
with (caption.style) {
|
|
display = 'none';
|
|
position = 'absolute';
|
|
zIndex = '80';
|
|
}
|
|
box.appendChild(caption);
|
|
return box;
|
|
},
|
|
_set_photo_size : function()
|
|
{
|
|
var self = this;
|
|
if (self._open == -1) return;
|
|
var imag = self._box.firstChild;
|
|
var targ = { w:self._page.win.w - 30, h:self._page.win.h - 40 };
|
|
var orig = { w:self._imgs[self._open].w, h:self._imgs[self._open].h };
|
|
|
|
// shrink image with the same aspect
|
|
var ratio = 1.0;
|
|
if ((orig.w >= 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 - 33) / 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 = '';
|
|
paddingBottom = '3px';
|
|
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 = '<b>'+self._imgs[self._open].title + '</b><br />' +
|
|
self._imgs[self._open].caption;
|
|
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();
|
|
});
|