--- /dev/null
+/*
+ Lightbox JS: Fullsize Image Overlays
+ by Lokesh Dhakar - http://www.huddletogether.com
+
+ For more information on this script, visit:
+ http://huddletogether.com/projects/lightbox/
+
+ 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)
+
+ Table of Contents
+ -----------------
+ Configuration
+
+ Functions
+ - getPageScroll()
+ - getPageSize()
+ - pause()
+ - getKey()
+ - listenKey()
+ - showLightbox()
+ - hideLightbox()
+ - initLightbox()
+ - addLoadEvent()
+
+ Function Calls
+ - addLoadEvent(initLightbox)
+
+*/
+
+
+
+//
+// Configuration
+//
+
+// If you would like to use a custom loading image or close button reference them in the next two lines.
+var loadingImage = 'loading.gif';
+var closeButton = 'close.gif';
+
+
+
+
+
+//
+// getPageScroll()
+// Returns array with x,y page scroll values.
+// Core code from - quirksmode.org
+//
+function getPageScroll(){
+
+ var yScroll;
+
+ if (self.pageYOffset) {
+ yScroll = self.pageYOffset;
+ } else if (document.documentElement && document.documentElement.scrollTop){ // Explorer 6 Strict
+ yScroll = document.documentElement.scrollTop;
+ } else if (document.body) {// all other Explorers
+ yScroll = document.body.scrollTop;
+ }
+
+ arrayPageScroll = new Array('',yScroll)
+ return arrayPageScroll;
+}
+
+
+
+//
+// getPageSize()
+// Returns array with page width, height and window width, height
+// Core code from - quirksmode.org
+// Edit for Firefox by pHaez
+//
+function getPageSize(){
+
+ var xScroll, yScroll;
+
+ if (window.innerHeight && window.scrollMaxY) {
+ xScroll = document.body.scrollWidth;
+ yScroll = window.innerHeight + window.scrollMaxY;
+ } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
+ xScroll = document.body.scrollWidth;
+ yScroll = document.body.scrollHeight;
+ } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
+ xScroll = document.body.offsetWidth;
+ yScroll = document.body.offsetHeight;
+ }
+
+ var windowWidth, windowHeight;
+ if (self.innerHeight) { // all except Explorer
+ windowWidth = self.innerWidth;
+ windowHeight = self.innerHeight;
+ } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
+ windowWidth = document.documentElement.clientWidth;
+ windowHeight = document.documentElement.clientHeight;
+ } else if (document.body) { // other Explorers
+ windowWidth = document.body.clientWidth;
+ windowHeight = document.body.clientHeight;
+ }
+
+ // for small pages with total height less then height of the viewport
+ if(yScroll < windowHeight){
+ pageHeight = windowHeight;
+ } else {
+ pageHeight = yScroll;
+ }
+
+ // for small pages with total width less then width of the viewport
+ if(xScroll < windowWidth){
+ pageWidth = windowWidth;
+ } else {
+ pageWidth = xScroll;
+ }
+
+
+ arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
+ return arrayPageSize;
+}
+
+
+//
+// pause(numberMillis)
+// Pauses code execution for specified time. Uses busy code, not good.
+// Code from http://www.faqts.com/knowledge_base/view.phtml/aid/1602
+//
+function pause(numberMillis) {
+ var now = new Date();
+ var exitTime = now.getTime() + numberMillis;
+ while (true) {
+ now = new Date();
+ if (now.getTime() > exitTime)
+ return;
+ }
+}
+
+//
+// getKey(key)
+// Gets keycode. If 'x' is pressed then it hides the lightbox.
+//
+
+function getKey(e){
+ if (e == null) { // ie
+ keycode = event.keyCode;
+ } else { // mozilla
+ keycode = e.which;
+ }
+ key = String.fromCharCode(keycode).toLowerCase();
+
+ if(key == 'x'){ hideLightbox(); }
+}
+
+
+//
+// listenKey()
+//
+function listenKey () { document.onkeypress = getKey; }
+
+
+//
+// showLightbox()
+// Preloads images. Pleaces new image in lightbox then centers and displays.
+//
+function showLightbox(objLink)
+{
+ // prep objects
+ var objOverlay = document.getElementById('overlay');
+ var objLightbox = document.getElementById('lightbox');
+ var objCaption = document.getElementById('lightboxCaption');
+ var objImage = document.getElementById('lightboxImage');
+ var objLoadingImage = document.getElementById('loadingImage');
+ var objLightboxDetails = document.getElementById('lightboxDetails');
+
+
+ var arrayPageSize = getPageSize();
+ var arrayPageScroll = getPageScroll();
+
+ // center loadingImage if it exists
+ if (objLoadingImage) {
+ objLoadingImage.style.top = (arrayPageScroll[1] + ((arrayPageSize[3] - 35 - objLoadingImage.height) / 2) + 'px');
+ objLoadingImage.style.left = (((arrayPageSize[0] - 20 - objLoadingImage.width) / 2) + 'px');
+ objLoadingImage.style.display = 'block';
+ }
+
+ // set height of Overlay to take up whole page and show
+ objOverlay.style.height = (arrayPageSize[1] + 'px');
+ objOverlay.style.display = 'block';
+
+ // preload image
+ imgPreload = new Image();
+
+ imgPreload.onload=function(){
+ objImage.src = objLink.href;
+
+ // center lightbox and make sure that the top and left values are not negative
+ // and the image placed outside the viewport
+ var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - imgPreload.height) / 2);
+ var lightboxLeft = ((arrayPageSize[0] - 20 - imgPreload.width) / 2);
+
+ objLightbox.style.top = (lightboxTop < 0) ? "0px" : lightboxTop + "px";
+ objLightbox.style.left = (lightboxLeft < 0) ? "0px" : lightboxLeft + "px";
+
+
+ objLightboxDetails.style.width = imgPreload.width + 'px';
+
+ if(objLink.getAttribute('title')){
+ objCaption.style.display = 'block';
+ //objCaption.style.width = imgPreload.width + 'px';
+ objCaption.innerHTML = objLink.getAttribute('title');
+ } else {
+ objCaption.style.display = 'none';
+ }
+
+ // A small pause between the image loading and displaying is required with IE,
+ // this prevents the previous image displaying for a short burst causing flicker.
+ if (navigator.appVersion.indexOf("MSIE")!=-1){
+ pause(250);
+ }
+
+ if (objLoadingImage) { objLoadingImage.style.display = 'none'; }
+
+ // Hide select boxes as they will 'peek' through the image in IE
+ selects = document.getElementsByTagName("select");
+ for (i = 0; i != selects.length; i++) {
+ selects[i].style.visibility = "hidden";
+ }
+
+
+ objLightbox.style.display = 'block';
+
+ // After image is loaded, update the overlay height as the new image might have
+ // increased the overall page height.
+ arrayPageSize = getPageSize();
+ objOverlay.style.height = (arrayPageSize[1] + 'px');
+
+ // Check for 'x' keypress
+ listenKey();
+
+ return false;
+ }
+
+ imgPreload.src = objLink.href;
+
+}
+
+
+
+
+
+//
+// hideLightbox()
+//
+function hideLightbox()
+{
+ // get objects
+ objOverlay = document.getElementById('overlay');
+ objLightbox = document.getElementById('lightbox');
+
+ // hide lightbox and overlay
+ objOverlay.style.display = 'none';
+ objLightbox.style.display = 'none';
+
+ // make select boxes visible
+ selects = document.getElementsByTagName("select");
+ for (i = 0; i != selects.length; i++) {
+ selects[i].style.visibility = "visible";
+ }
+
+ // disable keypress listener
+ document.onkeypress = '';
+}
+
+
+
+
+//
+// initLightbox()
+// Function runs on window load, going through link tags looking for rel="lightbox".
+// These links receive onclick events that enable the lightbox display for their targets.
+// The function also inserts html markup at the top of the page which will be used as a
+// container for the overlay pattern and the inline image.
+//
+function initLightbox()
+{
+
+ if (!document.getElementsByTagName){ return; }
+ var anchors = document.getElementsByTagName("a");
+
+ // loop through all anchor tags
+ for (var i=0; i<anchors.length; i++){
+ var anchor = anchors[i];
+
+ if (anchor.getAttribute("href") && (anchor.getAttribute("rel") == "lightbox")){
+ anchor.onclick = function () {showLightbox(this); return false;}
+ }
+ }
+
+ // the rest of this code inserts html at the top of the page that looks like this:
+ //
+ // <div id="overlay">
+ // <a href="#" onclick="hideLightbox(); return false;"><img id="loadingImage" /></a>
+ // </div>
+ // <div id="lightbox">
+ // <a href="#" onclick="hideLightbox(); return false;" title="Click anywhere to close image">
+ // <img id="closeButton" />
+ // <img id="lightboxImage" />
+ // </a>
+ // <div id="lightboxDetails">
+ // <div id="lightboxCaption"></div>
+ // <div id="keyboardMsg"></div>
+ // </div>
+ // </div>
+
+ var objBody = document.getElementsByTagName("body").item(0);
+
+ // create overlay div and hardcode some functional styles (aesthetic styles are in CSS file)
+ var objOverlay = document.createElement("div");
+ objOverlay.setAttribute('id','overlay');
+ objOverlay.onclick = function () {hideLightbox(); return false;}
+ objOverlay.style.display = 'none';
+ objOverlay.style.position = 'absolute';
+ objOverlay.style.top = '0';
+ objOverlay.style.left = '0';
+ objOverlay.style.zIndex = '90';
+ objOverlay.style.width = '100%';
+ objBody.insertBefore(objOverlay, objBody.firstChild);
+
+ var arrayPageSize = getPageSize();
+ var arrayPageScroll = getPageScroll();
+
+ // preload and create loader image
+ var imgPreloader = new Image();
+
+ // if loader image found, create link to hide lightbox and create loadingimage
+ imgPreloader.onload=function(){
+
+ var objLoadingImageLink = document.createElement("a");
+ objLoadingImageLink.setAttribute('href','#');
+ objLoadingImageLink.onclick = function () {hideLightbox(); return false;}
+ objOverlay.appendChild(objLoadingImageLink);
+
+ var objLoadingImage = document.createElement("img");
+ objLoadingImage.src = incPrefix + loadingImage;
+ objLoadingImage.setAttribute('id','loadingImage');
+ objLoadingImage.style.position = 'absolute';
+ objLoadingImage.style.zIndex = '150';
+ objLoadingImageLink.appendChild(objLoadingImage);
+
+ imgPreloader.onload=function(){}; // clear onLoad, as IE will flip out w/animated gifs
+
+ return false;
+ }
+
+ imgPreloader.src = incPrefix + loadingImage;
+
+ // create lightbox div, same note about styles as above
+ var objLightbox = document.createElement("div");
+ objLightbox.setAttribute('id','lightbox');
+ objLightbox.style.display = 'none';
+ objLightbox.style.position = 'absolute';
+ objLightbox.style.zIndex = '100';
+ objBody.insertBefore(objLightbox, objOverlay.nextSibling);
+
+ // create link
+ var objLink = document.createElement("a");
+ objLink.setAttribute('href','#');
+ objLink.setAttribute('title','Click to close');
+ objLink.onclick = function () {hideLightbox(); return false;}
+ objLightbox.appendChild(objLink);
+
+ // preload and create close button image
+ var imgPreloadCloseButton = new Image();
+
+ // if close button image found,
+ imgPreloadCloseButton.onload=function(){
+
+ var objCloseButton = document.createElement("img");
+ objCloseButton.src = incPrefix + closeButton;
+ objCloseButton.setAttribute('id','closeButton');
+ objCloseButton.style.position = 'absolute';
+ objCloseButton.style.zIndex = '200';
+ objLink.appendChild(objCloseButton);
+
+ return false;
+ }
+
+ imgPreloadCloseButton.src = incPrefix + closeButton;
+
+ // create image
+ var objImage = document.createElement("img");
+ objImage.setAttribute('id','lightboxImage');
+ objLink.appendChild(objImage);
+
+ // create details div, a container for the caption and keyboard message
+ var objLightboxDetails = document.createElement("div");
+ objLightboxDetails.setAttribute('id','lightboxDetails');
+ objLightbox.appendChild(objLightboxDetails);
+
+ // create caption
+ var objCaption = document.createElement("div");
+ objCaption.setAttribute('id','lightboxCaption');
+ objCaption.style.display = 'none';
+ objLightboxDetails.appendChild(objCaption);
+
+ // create keyboard message
+ var objKeyboardMsg = document.createElement("div");
+ objKeyboardMsg.setAttribute('id','keyboardMsg');
+ objKeyboardMsg.innerHTML = 'press <kbd>x</kbd> to close';
+ objLightboxDetails.appendChild(objKeyboardMsg);
+
+
+}
+
+
+
+
+//
+// addLoadEvent()
+// Adds event to window.onload without overwriting currently assigned onload functions.
+// Function found at Simon Willison's weblog - http://simon.incutio.com/
+//
+function addLoadEvent(func)
+{
+ var oldonload = window.onload;
+ if (typeof window.onload != 'function'){
+ window.onload = func;
+ } else {
+ window.onload = function(){
+ oldonload();
+ func();
+ }
+ }
+
+}
+
+
+
+addLoadEvent(initLightbox); // run initLightbox onLoad
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use Carp;
+use POSIX qw/getcwd/;
+use CGI qw/:html *table *center *div/;
+use Image::Info qw/image_info dim/;
+use Image::Magick;
+
+my $ask=1;
+my $startdir=getcwd;
+
+######################################################################
+
+&processdir($startdir);
+
+sub processdir {
+ my ($start,$dir)=@_;
+ my $dn=$start;
+ $dn .= "/".$dir if ($dir);
+ unless ( -d $dn ) {
+ warn "not a directory: $dn";
+ return;
+ }
+ my $D;
+ unless (opendir($D,$dn)) {
+ warn "cannot opendir $dn: $!";
+ return;
+ }
+
+# recurse into subdirectories BEFORE opening index file
+
+ &iteratedir($D,$start,$dir,sub {
+ my ($start,$dir,$base)=@_;
+ my $ndir = $dir;
+ $ndir .= "/" if ($ndir);
+ $ndir .= $base;
+ return unless ( -d $start."/".$ndir );
+ &processdir($start,$ndir);
+ });
+
+# fill in title
+
+ my $title=&gettitle($dn,$dir);
+
+# get include prefix
+
+ my $inc=&getinclude($dn);
+
+# generate directory index unless suppressed
+
+ if ( -e $dn."/.noindex" ) {
+ open(STDOUT,">/dev/null");
+ } else {
+ open(STDOUT,">".$dn."/index.html");
+ }
+
+# write HTML header
+
+ print start_html(-title => $title,
+ -style=>{-src=>[$inc."gallery.css",
+ $inc."lightbox.css"]},
+ -script=>[{-code=>"var incPrefix='$inc';"},
+ {-src=>$inc."gallery.js"},
+ {-src=>$inc."lightbox.js"}]),"\n";
+ print a({-href=>"../"},"UP");
+ print start_center,"\n";
+ print h1($title),"\n";
+
+# create list of sub-albums
+
+ my $hassubdirs=0;
+ &iteratedir($D,$start,$dir,sub {
+ my ($start,$dir,$base)=@_;
+ my $en=sprintf("%s/%s/%s",$start,$dir,$base);
+ return unless ( -d $en );
+ unless ($hassubdirs) {
+ print hr,h2("Albums"),start_table,"\n";
+ $hassubdirs=1;
+ }
+ &subalbum($base,&gettitle($en,$dir."/".$base));
+ });
+ print end_table,hr,"\n" if ($hassubdirs);
+
+# create picture gallery
+
+ my $haspics=0;
+ &iteratedir($D,$start,$dir,sub {
+ my ($start,$dir,$base)=@_;
+ my $en=sprintf("%s/%s/%s",$start,$dir,$base);
+ return unless ( -f $en );
+ $haspics=1 if (&processfile($start,$dir,$base,$en));
+ });
+
+# write HTML footer
+
+ print br({-clear=>"all"}),"\n";
+ print hr,"\n" if ($haspics);
+ print end_center,"\n";
+ print end_html,"\n";
+
+ close(STDOUT);
+ closedir($D);
+}
+
+#############################################################
+# helper functions
+#############################################################
+
+sub iteratedir {
+ my ($D,$start,$dir,$prog)=@_;
+ my @list=();
+ while (my $de=readdir($D)) {
+ next if ($de =~ /^\./);
+ push(@list,$de);
+ }
+ foreach my $de(sort @list) {
+ &$prog($start,$dir,$de);
+ }
+ rewinddir($D);
+}
+
+sub getinclude {
+ my ($dn)=@_;
+
+ my $depth=20;
+ my $str="";
+ #print STDERR "start include ",$dn."/".$str.".include","\n";
+ while ( ! -d $dn."/".$str.".include" ) {
+ #print STDERR "not include ",$dn."/".$str.".include","\n";
+ $str.="../";
+ last unless ($depth--);
+ }
+ #print STDERR "end include ",$dn."/".$str.".include","\n";
+ if ( -d $dn."/".$str.".include" ) {
+ #print STDERR "return include ".$str.".include/".$fn,"\n";
+ return $str.".include/";
+ } else {
+ return ""; # won't work anyway but return something
+ }
+}
+
+sub gettitle {
+ my ($dir,$dflt)=@_;
+
+ my $F;
+ my $str;
+ if (open($F,"<".$dir."/.title")) {
+ $str=<$F>;
+ chop $str;
+ close($F);
+ } else {
+ print STDERR "enter title for $dir\n";
+ $str=<>;
+ if ($str =~ /^\s*$/) {
+ $str=$dflt;
+ }
+ if (open($F,">".$dir."/.title")) {
+ print $F $str,"\n";
+ close($F);
+ } else {
+ print STDERR "cant open .title in $dir for writing: $!";
+ }
+ }
+ return $str;
+}
+
+sub subalbum {
+ my ($base,$title)=@_;
+
+ print Tr({-bgcolor=>"#c0c0c0"},
+ td(a({-href=>$base."/"},$base)),
+ td(a({-href=>$base."/"},$title))),"\n";
+}
+
+sub processfile {
+ my ($start,$dir,$base,$fn)=@_;
+
+ my $info = image_info($fn);
+ if (my $error = $info->{error}) {
+ if (($error !~ "Unrecognized file format") &&
+ ($error !~ "Can't read head")) {
+ print STDERR "File \"$fn\": $error\n";
+ }
+ return 0;
+ }
+ my ($w,$h) = dim($info);
+ my $title=$info->{'Comment'};
+ $title=$base unless ($title);
+ my $thumb=&scale($start,$dir,$base,$fn,160,$info);
+ my $medium=&scale($start,$dir,$base,$fn,640,$info);
+ print &infobox($info,$base,$fn),"\n";
+ print table({-class=>'slide'},Tr(td(
+ a({-href=>".info/$base.html",
+ -onClick=>"return showIbox('$base');"},$title),
+ br,
+ a({-href=>$medium,-rel=>"lightbox",-title=>$title},
+ img({-src=>$thumb})),
+ br,
+ a({-href=>$base},"($w x $h)"),
+ br))),"\n";
+ #for my $k(keys %$info) {
+ # print "\t$k:\t$info->{$k}<br>\n";
+ #}
+ return 1;
+}
+
+sub infobox {
+ my ($info,$base,$fn)=@_;
+
+ my @infokeys=(
+ 'DateTime',
+ 'ExposureTime',
+ 'FNumber',
+ 'Flash',
+ 'ISOSpeedRatings',
+ 'MeteringMode',
+ 'ExposureProgram',
+ 'FocalLength',
+ 'FileSource',
+ 'Make',
+ 'Model',
+ 'Software',
+ );
+
+ my $msg=start_div({-class=>'ibox',-id=>$base,-OnClick=>"HideIbox('$base');"});
+ $msg.=span({-style=>'float: left;'},"Info for $base").
+ span({-style=>'float: right;'},
+ a({-href=>"#",-OnClick=>"HideIbox('$base');"},"Close"));
+ $msg.=br({-clear=>'all'});
+ $msg.=start_table;
+ foreach my $k(@infokeys) {
+ $msg.=Tr(td($k.":"),td($info->{$k}));
+ }
+ $msg.=end_table;
+ $msg.=end_div;
+ return $msg;
+}
+
+sub scale {
+ my ($start,$dir,$base,$fn,$tsize,$info)=@_;
+ my ($w,$h) = dim($info);
+ my $max=($w>$h)?$w:$h;
+ my $factor=$tsize/$max;
+
+ return $base if ($factor >= 1);
+
+ my $tdir=sprintf "%s/%s/.%s",$start,$dir,$tsize;
+ mkdir($tdir,0755) unless ( -d $tdir );
+ my $tbase=sprintf ".%s/%s",$tsize,$base;
+ my $tfn=sprintf "%s/%s",$tdir,$base;
+ my @sstat=stat($fn);
+ my @tstat=stat($tfn);
+ return $tbase if (@tstat && ($sstat[9] < $tstat[9])); # [9] -> mtime
+
+ print STDERR "scale by $factor from $fn to $tfn\n";
+ &doscaling($fn,$tfn,$factor,$w,$h);
+ return $tbase;
+}
+
+sub doscaling {
+ my ($src,$dest,$factor,$w,$h)=@_;
+
+ my $im=new Image::Magick;
+ my $err;
+ #print STDERR "doscale $src -> $dest by $factor\n";
+ $err=$im->Read($src);
+ unless ($err) {
+ $im->Scale(width=>$w*$factor,height=>$h*$factor);
+ $err=$im->Write($dest);
+ warn "ImageMagic: write \"$dest\": $err" if ($err);
+ } else {
+ warn "ImageMagic: read \"$src\": $err";
+ system("djpeg \"$src\" | pnmscale \"$factor\" | cjpeg >\"$dest\"");
+ }
+ undef $im;
+}