PageSourceSearch

http://edfirst.org/~media/elements/PhotoGallery/js/lightbox.js

js edfirst.org collected 2026-10-08 16:56:18 UTC 30,935 bytes, 912 lines download raw bytes

1// -----------------------------------------------------------------------------------
2//
3//	Lightbox v2.03.3
4//	by Lokesh Dhakar - http://www.huddletogether.com
5//	5/21/06
6//
7//	For more information on this script, visit:
8//	http://huddletogether.com/projects/lightbox2/
9//
10//	Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
11//	
12//	Credit also due to those who have helped, inspired, and made their code available to the public.
13//	Including: Scott Upton(uptonic.com), Peter-Paul Koch(quirksmode.com), Thomas Fuchs(mir.aculo.us), and others.
14//
15//******************************************************************************************
16//  VERY IMPORTANT NOTE: this version of Lightbox.js has been modified, so as not to conflict with the JQuery library
17//  All instances of '$' have been chnaged to 'PR' (short for Prototype), as JQuery heavily relies on the '$' symbol as well.
18//  Please keep this in mind when making modifications.
19//
20//  Also, this version of Lightbox.js has custom Homestead functionality.
21//  See \\moose\users\Builds\QS38\QS38_Websites10_Photo_Gallery\QS38_Websites10_Photo_Gallery.doc
22//   - Prev/next links are always visible at the top (permaNav)
23//   - Prev/next links and keyboard commands wrap when you reach the end of the list
24//   - Clicking the photo simulates 'next'
25//   - Image count is always displayed
26//   - Display area has a fixed minimum width, even for very narrow images.
27//******************************************************************************************
28//
29// -----------------------------------------------------------------------------------
30/*
31
32	Table of Contents
33	-----------------
34	Configuration
35	Global Variables
36
37	Extending Built-in Objects	
38	- Object.extend(Element)
39	- Array.prototype.removeDuplicates()
40	- Array.prototype.empty()
41
42	Lightbox Class Declaration
43	- initialize()
44	- updateImageList()
45	- start()
46	- changeImage()
47	- resizeImageContainer()
48	- showImage()
49	- updateDetails()
50	- updateNav()
51	- enableKeyboardNav()
52	- disableKeyboardNav()
53	- keyboardAction()
54	- preloadNeighborImages()
55	- end()
56	
57	Miscellaneous Functions
58	- getPageScroll()
59	- getPageSize()
60	- getKey()
61	- listenKey()
62	- showSelectBoxes()
63	- hideSelectBoxes()
64	- showFlash()
65	- hideFlash()
66	- showApplets()
67	- hideApplets()
68	- pause()
69	- initLightbox()
70	
71	Function Calls
72	- addLoadEvent(initLightbox)
73	
74*/
75// -----------------------------------------------------------------------------------
76
77//
78//	Configuration
79//
80//   WARNING: pre-QS37 user pages have a script tag that manually overwrites
81//   fileLoadingImage and fileBottomNavCloseImage with absolute URLs.  This is 
82//   unnecessary, and QS38+ pages use the defaults defined here instead.
83//
84var fileLoadingImage = "/~media/elements/PhotoGallery/images/loading.gif";		
85var fileBottomNavCloseImage = "/~media/elements/PhotoGallery/images/closelabel.gif";
86var fileBottomNavCloseImageOver = "/~media/elements/PhotoGallery/images/closelabel_over.gif";
87
88var overlayOpacity = 0.8;	// controls transparency of shadow overlay
89
90var animate = true;			// toggles resizing animations
91var resizeSpeed = 7;		// controls the speed of the image resizing animations (1=slowest and 10=fastest)
92
93var borderSize = 10;		//if you adjust the padding in the CSS, you will need to update this variable
94
95// -----------------------------------------------------------------------------------
96
97//
98//	Global Variables
99//
100var imageArray = new Array;
101var activeImage;
102
103if(animate == true){
104	overlayDuration = 0.2;	// shadow fade in/out duration
105	if(resizeSpeed > 10){ resizeSpeed = 10;}
106	if(resizeSpeed < 1){ resizeSpeed = 1;}
107	resizeDuration = (11 - resizeSpeed) * 0.15;
108} else { 
109	overlayDuration = 0;
110	resizeDuration = 0;
111}
112
113// -----------------------------------------------------------------------------------
114
115//
116//	Additional methods for Element added by SU, Couloir
117//	- further additions by Lokesh Dhakar (huddletogether.com)
118//
119Object.extend(Element, {
120	getWidth: function(element) {
121	   	element = PR(element);
122	   	return element.offsetWidth; 
123	},
124	setWidth: function(element,w) {
125	   	element = PR(element);
126    	element.style.width = w +"px";
127	},
128	setHeight: function(element,h) {
129   		element = PR(element);
130    	element.style.height = h +"px";
131	},
132	setTop: function(element,t) {
133	   	element = PR(element);
134    	element.style.top = t +"px";
135	},
136	setLeft: function(element,l) {
137	   	element = PR(element);
138    	element.style.left = l +"px";
139	},
140	setSrc: function(element,src) {
141    	element = PR(element);
142    	element.src = src; 
143	},
144	setHref: function(element,href) {
145    	element = PR(element);
146    	element.href = href; 
147	},
148	setInnerHTML: function(element,content) {
149		element = PR(element);
150		element.innerHTML = content;
151	}
152});
153
154// -----------------------------------------------------------------------------------
155
156//
157//	Extending built-in Array object
158//	- array.removeDuplicates()
159//	- array.empty()
160//
161Array.prototype.removeDuplicates = function () {
162    for(i = 0; i < this.length; i++){
163        for(j = this.length-1; j>i; j--){        
164            if(this[i][0] == this[j][0]){
165                this.splice(j,1);
166            }
167        }
168    }
169}
170
171// -----------------------------------------------------------------------------------
172
173Array.prototype.empty = function () {
174	for(i = 0; i <= this.length; i++){
175		this.shift();
176	}
177}
178
179// -----------------------------------------------------------------------------------
180
181//
182//	Lightbox Class Declaration
183//	- initialize()
184//	- start()
185//	- changeImage()
186//	- resizeImageContainer()
187//	- showImage()
188//	- updateDetails()
189//	- updateNav()
190//	- enableKeyboardNav()
191//	- disableKeyboardNav()
192//	- keyboardNavAction()
193//	- preloadNeighborImages()
194//	- end()
195//
196//	Structuring of code inspired by Scott Upton (http://www.uptonic.com/)
197//
198var Lightbox = Class.create();
199
200Lightbox.prototype = {
201	
202	// initialize()
203	// Constructor runs on completion of the DOM loading. Calls updateImageList and then
204	// the function inserts html at the bottom of the page which is used to display the shadow 
205	// overlay and the image container.
206	//
207	initialize: function() {	
208		
209		this.updateImageList();
210
211		// Code inserts html at the bottom of the page that looks similar to this:
212		//
213		//	<div id="overlay"></div>
214		//	<div id="lightbox">
215		//		<div id="outerImageContainer">
216		//			<div style="" id="permaNav">
217		//				<a href="#" id="prevLink"></a>
218		//				<a href="#" id="nextLink"></a>
219		//			</div>
220		//			<div id="imageContainer">
221		//				<img id="lightboxImage">
222		//				<div id="loading">
223		//					<a href="#" id="loadingLink">
224		//						<img src="images/loading.gif">
225		//					</a>
226		//				</div>
227		//			</div>
228		//		</div>
229		//		<div id="imageDataContainer">
230		//			<div id="imageData">
231		//				<div id="imageDetails">
232		//					<span id="caption"></span>
233		//					<span id="numberDisplay"></span>
234		//				</div>
235		//				<div id="bottomNav">
236		//					<a href="#" id="bottomNavClose">
237		//						<img src="images/close.gif">
238		//					</a>
239		//				</div>
240		//			</div>
241		//		</div>
242		//	</div>
243
244
245		var objBody = document.getElementsByTagName("body").item(0);
246		
247		var objOverlay = document.createElement("div");
248		objOverlay.setAttribute('id','overlay');
249		objOverlay.style.display = 'none';
250		objOverlay.onclick = function() { myLightbox.end(); }
251		objBody.appendChild(objOverlay);
252		
253		var objLightbox = document.createElement("div");
254		objLightbox.setAttribute('id','lightbox');
255		objLightbox.style.display = 'none';
256		objLightbox.onclick = function(e) {	// close Lightbox is user clicks shadow overlay
257			if (!e) var e = window.event;
258			var clickObj = Event.element(e).id;
259			if ( clickObj == 'lightbox') {
260				myLightbox.end();
261			}
262		};
263		objBody.appendChild(objLightbox);
264			
265		var objOuterImageContainer = document.createElement("div");
266		objOuterImageContainer.setAttribute('id','outerImageContainer');
267		objLightbox.appendChild(objOuterImageContainer);
268
269		// When Lightbox starts it will resize itself from 250 by 250 to the current image dimension.
270		// If animations are turned off, it will be hidden as to prevent a flicker of a
271		// white 250 by 250 box.
272		if(animate){
273			Element.setWidth('outerImageContainer', 250);
274			Element.setHeight('outerImageContainer', 250);			
275		} else {
276			Element.setWidth('outerImageContainer', 1);
277			Element.setHeight('outerImageContainer', 1);			
278		}
279
280		var objImageContainer = document.createElement("div");
281		objImageContainer.setAttribute('id','imageContainer');
282		objOuterImageContainer.appendChild(objImageContainer);
283
284		var objPermaNav = document.createElement("div");
285		objPermaNav.setAttribute('id','permaNav');
286		objImageContainer.appendChild(objPermaNav);
287
288		var objPrevLink = document.createElement("a");
289		objPrevLink.setAttribute('id','prevLink');
290		objPrevLink.setAttribute('href','#');
291		//objPrevLink.onclick = function() { return false; }
292		objPrevLink.setAttribute('onclick','return false;');
293		objPermaNav.appendChild(objPrevLink);
294		
295		var objNextLink = document.createElement("a");
296		objNextLink.setAttribute('id','nextLink');
297		objNextLink.setAttribute('href','#');
298		//objNextLink.onclick = function() { return false; }
299		objNextLink.setAttribute('onclick','return false;');
300		objPermaNav.appendChild(objNextLink);
301		
302		var objLightboxImage = document.createElement("img");
303		objLightboxImage.setAttribute('id','lightboxImage');
304		objImageContainer.appendChild(objLightboxImage);
305	
306		var objLoading = document.createElement("div");
307		objLoading.setAttribute('id','loading');
308		objImageContainer.appendChild(objLoading);
309	
310		var objLoadingLink = document.createElement("a");
311		objLoadingLink.setAttribute('id','loadingLink');
312		objLoadingLink.setAttribute('href','#');
313		objLoadingLink.onclick = function() { myLightbox.end(); return false; }
314		objLoading.appendChild(objLoadingLink);
315	
316		var objLoadingImage = document.createElement("img");
317		objLoadingImage.setAttribute('src', fileLoadingImage);
318		objLoadingLink.appendChild(objLoadingImage);
319
320		var objImageDataContainer = document.createElement("div");
321		objImageDataContainer.setAttribute('id','imageDataContainer');
322		objLightbox.appendChild(objImageDataContainer);
323
324		var objImageData = document.createElement("div");
325		objImageData.setAttribute('id','imageData');
326		objImageDataContainer.appendChild(objImageData);
327	
328		var objImageDetails = document.createElement("div");
329		objImageDetails.setAttribute('id','imageDetails');
330		objImageData.appendChild(objImageDetails);
331	
332		var objCaption = document.createElement("span");
333		objCaption.setAttribute('id','caption');
334		objImageDetails.appendChild(objCaption);
335	
336		var objNumberDisplay = document.createElement("span");
337		objNumberDisplay.setAttribute('id','numberDisplay');
338		objImageDetails.appendChild(objNumberDisplay);
339		
340		var objBottomNav = document.createElement("div");
341		objBottomNav.setAttribute('id','bottomNav');
342		objImageData.appendChild(objBottomNav);
343	
344		var objBottomNavCloseLink = document.createElement("a");
345		objBottomNavCloseLink.setAttribute('id','bottomNavClose');
346		objBottomNavCloseLink.setAttribute('href','#');
347		objBottomNavCloseLink.onclick = function() { myLightbox.end(); return false; }
348		objBottomNav.appendChild(objBottomNavCloseLink);
349	
350		var objBottomNavCloseImage = document.createElement("img");
351		objBottomNavCloseImage.setAttribute('src', fileBottomNavCloseImage);
352		objBottomNavCloseImage.onmouseover = function() { this.src = fileBottomNavCloseImageOver; }
353		objBottomNavCloseImage.onmouseout = function() { this.src = fileBottomNavCloseImage; }
354		objBottomNavCloseLink.appendChild(objBottomNavCloseImage);
355	},
356
357
358	//
359	// updateImageList(
359)
360	// Loops through anchor tags looking for 'lightbox' references and applies onclick
361	// events to appropriate links. You can rerun after dynamically adding images w/ajax.
362	//
363	updateImageList: function() {	
364		if (!document.getElementsByTagName){ return; }
365		var anchors = document.getElementsByTagName('a');
366		var areas = document.getElementsByTagName('area');
367
368		// loop through all anchor tags
369		for (var i=0; i<anchors.length; i++){
370			var anchor = anchors[i];
371			
372			var relAttribute = String(anchor.getAttribute('rel'));
373			
374			// use the string.match() method to catch 'lightbox' references in the rel attribute
375			if (anchor.getAttribute('href') && (relAttribute.toLowerCase().match('lightbox'))){
376				anchor.onclick = function () {myLightbox.start(this); return false;}
377			}
378		}
379
380		// loop through all area tags
381		// todo: combine anchor & area tag loops
382		for (var i=0; i< areas.length; i++){
383			var area = areas[i];
384			
385			var relAttribute = String(area.getAttribute('rel'));
386			
387			// use the string.match() method to catch 'lightbox' references in the rel attribute
388			if (area.getAttribute('href') && (relAttribute.toLowerCase().match('lightbox'))){
389				area.onclick = function () {myLightbox.start(this); return false;}
390			}
391		}
392	},
393	
394	
395	//
396	//	start()
397	//	Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
398	//
399	start: function(imageLink) {	
400
401		hideSelectBoxes();
402		hideFlash();
403		hideApplets();
404
405		// stretch overlay to fill page and fade in
406		var arrayPageSize = getPageSize();
407		Element.setWidth('overlay', arrayPageSize[0]);
408		Element.setHeight('overlay', arrayPageSize[1]);
409
410		new Effect.Appear('overlay', { duration: overlayDuration, from: 0.0, to: overlayOpacity });
411
412		imageArray = [];
413		imageNum = 0;		
414
415		if (!document.getElementsByTagName){ return; }
416		var anchors = document.getElementsByTagName( imageLink.tagName);
417
418		// if image is NOT part of a set..
419		if((imageLink.getAttribute('rel') == 'lightbox')){
420			// add single image to imageArray
421			// we push attributes into imageArray
422			// 'href' = image's filename
423			// 'id' = Styling information (textfont and color) (note, this is put the id attribute instead of style, because IE6 has problems getting the attribute as a string when it is put into style)
424			// 'name' = unique thumbnail ID, used to identify between images with the same 'href'
425			// 'title' = caption, placed in this attribute for tooltip functionality
426			imageArray.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('id'), imageLink.getAttribute('name'), imageLink.getAttribute('title')));					
427		} else {
428		// if image is part of a set..
429
430			// loop through anchors, find other images in set, and add them to imageArray
431			for (var i=0; i<anchors.length; i++){
432				var anchor = anchors[i];
433				if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))){
434					// See above for information about attributes
435					imageArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('id'), anchor.getAttribute('name'), anchor.getAttribute('title')));
436				}
437			}
438			// We check that the image has the same 'href' and 'name' (unique thumbnail id) to identify the correct place in imageArray to start.
439			// if either 'href' or 'name' don't match, then we don't have the exact image we want called up (both filename and thumbID must match to exit out of the loop)
440			while((imageArray[imageNum][0] != imageLink.getAttribute('href')) || (imageArray[imageNum][2] != imageLink.getAttribute('name'))) { 
441				imageNum++;
442				}
443		}
444
445		// Only show nav links if there are more than one photos in the set.
446		if (imageArray.length > 1) {
447			Element.show('prevLink');
448			Element.show('nextLink');
449		} else {
450			Element.hide('prevLink');
451			Element.hide('nextLink');
452		}
453
454		// calculate top and left offset for the lightbox 
455		var arrayPageScroll = getPageScroll();
456		var lightboxTop = arrayPageScroll[1] + (arrayPageSize[3] / 10);
457		var lightboxLeft = arrayPageScroll[0];
458		Element.setTop('lightbox', lightboxTop);
459		Element.setLeft('lightbox', lightboxLeft);
460		
461		Element.show('lightbox');
462		
463		this.changeImage(imageNum);
464	},
465
466	//
467	//	changeImage()
468	//	Hide most elements and preload image in preparation for resizing image container.
469	//
470	changeImage: function(imageNum) {	
471		
472		activeImage = imageNum;	// update global var
473
474		// hide elements during transition
475		if(animate){ Element.show('loading');}
476		Element.hide('lightboxImage');
477		Element.hide('imageDataContainer');
478		Element.hide('numberDisplay');
479		
480		// Deactivate navigation links until the photo is fully displayed.
481		// Browsing too fast (before the image is ready) leads to a mismatch between the image and the info being displayed.
482		document.getElementById('prevLink').onclick = document.getElementById('nextLink').onclick = document.getElementById('lightboxImage').onclick = function() { return false; }
483		
484		imgPreloader = new Image();
485		
486		// once image is preloaded, resize image container
487		imgPreloader.onload=function(){
488		var imageWidth = imgPreloader.width;
489		var imageHeight = imgPreloader.height;
490			Element.setSrc('lightboxImage', imageArray[activeImage][0]);
491			if (imageWidth > myLightbox.maxWidth) {
492				imageWidth = Number(myLightbox.maxWidth);
493			}
494			if (imageHeight > myLightbox.maxHeight) {
495				imageHeight = Number(myLightbox.maxHeight);
496			}
497			myLightbox.resizeImageContainer(imageWidth, imageHeight);
498			
499			imgPreloader.onload=function(){};	//	clear onLoad, IE behaves irratically with animated gifs otherwise 
500		}
501		imgPreloader.src = imageArray[activeImage][0];
502	},
503
504	//
505	//	resizeImageContainer()
506	//
507	resizeImageContainer: function( imgWidth, imgHeight) {
508		// Scale to fit the browser window so the user can see the entire image without having to scroll.
509		// Also, maintain the aspect ratio to avoid stretching the image out of proportion.
510		var arrayPageSize = getPageSize();
511		var windowWidth = arrayPageSize[2];
512		var windowHeight = arrayPageSize[3];
513		var imgWidthNew = imgWidth;
514		var imgHeightNew = imgHeight;
515		// Browser window width available for the image
516		// This is calculated by substracting the border sizes from the width of the browser window. 
517		var windowWidthAvailable = (windowWidth - (borderSize * 2));
518		// Browser window height available for the image
519		// This is calculated by subtracting the offset from the top of the window, the border sizes, the height of the top nav,
520		// and the height of the bottom nav from the height of the browser window.
521		var windowHeightAvailable = (windowHeight - (windowHeight / 10) - (borderSize * 2) - (imageArray.length > 1 ? 10 : 0) - 33);
522		if (imgWidthNew  > windowWidthAvailable) {
523			imgWidthNew = windowWidthAvailable;
524			imgHeightNew = imgWidthNew * imgHeight / imgWidth;
525		}
526		if (imgHeightNew > windowHeightAvailable) {
527			imgHeightNew = windowHeightAvailable * .80; //WEB007811 Image height has to be 62% of the outer image container so that bottom menu, image comments and image numbers are not hidden behind the image. QS72: 60% is too small, so we land somewhere in the middle.
528			imgWidthNew = imgHeightNew * imgWidth / imgHeight;
529		}
530		
531		// get curren width and height
532		this.widthCurrent = Element.getWidth('outerImageContainer');
533		this.heightCurrent = Element.getHeight('outerImageContainer');
534
535		// get new width and height
536		var widthNew = (imgWidthNew  + (borderSize * 2));
537		var heightNew = (imgHeightNew  + (borderSize * 2)) + (imageArray.length > 1 ? 10 : 0) + 20; // include space for top nav and bottom close buttons
538		
539		// lock minimum width of display box to size of "< prev | next >" links
540		widthNew = Math.max(widthNew, 118 + (borderSize * 2));
541		
542		// scalars based on change from old to new
543		this.xScale = ( widthNew / this.widthCurrent) * 100;
544		this.yScale = ( heightNew / this.heightCurrent) * 100;
545
546		// calculate size difference between new and old image, and resize if necessary
547		wDiff = this.widthCurrent - widthNew;
548		hDiff = this.heightCurrent - heightNew;
549
550		if(!( hDiff == 0)){ new Effect.Scale('outerImageContainer', this.yScale, {scaleX: false, duration: resizeDuration, queue: 'front'}); }
551		if(!( wDiff == 0)){ new Effect.Scale('outerImageContainer', this.xScale, {scaleY: false, delay: resizeDuration, duration: resizeDuration}); }
552
553		// if new and old image are same size and no scaling transition is necessary, 
554		// do a quick pause to prevent image flicker.
555		if((hDiff == 0) && (wDiff == 0)){
556			if (navigator.appVersion.indexOf("MSIE")!=-1){ pause(250); } else { pause(100);} 
557		}
558
559		Element.setWidth('lightboxImage', imgWidthNew);
560		Element.setHeight('lightboxImage', imgHeightNew);
561		Element.setWidth( 'imageDataContainer', widthNew);
562
563		this.showImage();
564	},
565	
566	//
567	//	showImage()
568	//	Display image and begin preloading neighbors.
569	//
570	showImage: function(){
571		Element.hide('loading');
572		new Effect.Appear('lightboxImage', { duration: resizeDuration, queue: 'end', afterFinish: function(){	myLightbox.updateDetails(); } });
573		this.preloadNeighborImages();
574	},
575
576	//
577	//	updateDetails()
578	//	Display caption, image number, and bottom nav.
579	//
580	updateDetails: function() {
581	
582		// if caption is not null
583		if(imageArray[activeImage][1]){
584			Element.show('caption');
585			// add HTML regarding image settings
586			// imageArray[activeImage][1] = 'id' = style settings (textfont and color)
587			// imageArray[activeImage][3] = 'title' = caption
588			Element.setInnerHTML( 'caption', '<div style="' + imageArray[activeImage][1] + '">' + imageArray[activeImage][3]);
589		}
590		
591		// display 'Image x of x' 
592		Element.show('numberDisplay');
593		Element.setInnerHTML( 'numberDisplay', "Image " + eval(activeImage + 1) + " of " + imageArray.length);
594
595		new Effect.Parallel(
596			[ new Effect.SlideDown( 'imageDataContainer', { sync: true, duration: resizeDuration, from: 0.0, to: 1.0 }), 
597			  new Effect.Appear('imageDataContainer', { sync: true, duration: resizeDuration }) ], 
598			{ duration: resizeDuration, afterFinish: function() {
599				// update overlay size and update nav
600				var arrayPageSize = getPageSize();
601				Element.setHeight('overlay', arrayPageSize[1]);
602				myLightbox.updateNav();
603				}
604			} 
605		);
606	},
607
608	//
609	//	updateNav()
610	//	Update target of previous and next navigation buttons.
611	//
612	updateNav: function() {
613		if (imageArray.length > 1) {
614			// wrap to the end if we are on the first image.
615			document.getElementById('prevLink').onclick = function() {
616				myLightbox.changeImage((activeImage > 0 ? activeImage - 1 : imageArray.length - 1)); return false;
617			}
618
619			// wrap to the beginning if we are on the last image.
620			document.getElementById('nextLink').onclick = function() {
621				myLightbox.changeImage((activeImage < (imageArray.length - 1) ? activeImage + 1 : 0)); return false;
622			}
623			
624			// clicking the image is the same as clicking 'next'.
625			document.getElementById('lightboxImage').onclick = document.getElementById('nextLink').onclick;
626			
627			this.enableKeyboardNav();
628		} else {
629			document.getElementById('prevLink').onclick = '';
630			document.getElementById('nextLink').onclick = '';
631			document.getElementById('lightboxImage').onclick = '';
632		}
633	},
634
635	//
636	//	enableKeyboardNav()
637	//
638	enableKeyboardNav: function() {
639		document.onkeydown = this.keyboardAction; 
640	},
641
642	//
643	//	disableKeyboardNav()
644	//
645	disableKeyboardNav: function() {
646		document.onkeydown = '';
647	},
648
649	//
650	//	keyboardAction()
651	//
652	keyboardAction: function(e) {
653		if (e == null) { // ie
654			keycode = event.keyCode;
655			escapeKey = 27;
656		} else { // mozilla
657			keycode = e.keyCode;
658			escapeKey = e.DOM_VK_ESCAPE;
659		}
660
661		key = String.fromCharCode(keycode).toLowerCase();
662		
663		if((key == 'x') || (key == 'o') || (key == 'c') || (keycode == escapeKey)){	// close lightbox
664			myLightbox.end();
665		} else if((key == 'p') || (keycode == 37)){	// display previous image (wrap if at beginning)
666			myLightbox.disableKeyboardNav();
667			myLightbox.changeImage(activeImage > 0 ? activeImage - 1 : imageArray.length - 1);
668		} else if((key == 'n') || (keycode == 39)){	// display next image (wrap if at end)
669			myLightbox.disableKeyboardNav();
670			myLightbox.changeImage(activeImage < (imageArray.length - 1) ? activeImage + 1 : 0);
671		}
672
673	},
674
675	//
676	//	preloadNeighborImages()
677	//	Preload previous and next images.
678	//
679	preloadNeighborImages: function(){
680
681		if((imageArray.length - 1) > activeImage){
682			preloadNextImage = new Image();
683			preloadNextImage.src = imageArray[activeImage + 1][0];
684		}
685		if(activeImage > 0){
686			preloadPrevImage = new Image();
687			preloadPrevImage.src = imageArray[activeImage - 1][0];
688		}
689	
690	},
691
692	//
693	//	end()
694	//
695	end: function() {
696		this.disableKeyboardNav();
697		Element.hide('lightbox');
698		new Effect.Fade('overlay', { duration: overlayDuration});
699		showSelectBoxes();
700		showFlash();
701		showApplets();
702	}
703}
704
705// -----------------------------------------------------------------------------------
706
707//
708// getPageScroll()
709// Returns array with x,y page scroll values.
710// Core code from - quirksmode.com
711//
712function getPageScroll(){
713
714	var xScroll, yScroll;
715
716	if (self.pageYOffset) {
717		yScroll = self.pageYOffset;
718		xScroll = self.pageXOffset;
719	} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
720		yScroll = document.documentElement.scrollTop;
721		xScroll = document.documentElement.scrollLeft;
722	} else if (document.body) {// all other Explorers
723		yScroll = document.body.scrollTop;
724		xScroll = document.body.scrollLeft;	
725	}
726
727	arrayPageScroll = new Array(xScroll,yScroll) 
728	return arrayPageScroll;
729}
730
731// -----------------------------------------------------------------------------------
732
733//
734// getPageSize()
735// Returns array with page width, height and window width, height
736// Core code from - quirksmode.com
737// Edit for Firefox by pHaez
738//
739function getPageSize(){
740	
741	var xScroll, yScroll;
742	
743	if (window.innerHeight && window.scrollMaxY) {	
744		xScroll = window.innerWidth + window.scrollMaxX;
745		yScroll = window.innerHeight + window.scrollMaxY;
746	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
747		xScroll = document.body.scrollWidth;
748		yScroll = document.body.scrollHeight;
749	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
750		xScroll = document.body.offsetWidth;
751		yScroll = document.body.offsetHeight;
752	}
753	
754	var windowWidth, windowHeight;
755	
756//	console.log(self.innerWidth);
757//	console.log(document.documentElement.clientWidth);
758
759	if (self.innerHeight) {	// all except Explorer
760		if(document.documentElement.clientWidth){
761			windowWidth = document.documentElement.clientWidth; 
762		} else {
763			windowWidth = self.innerWidth;
764		}
765		windowHeight = self.innerHeight;
766	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
767		windowWidth = document.documentElement.clientWidth;
768		windowHeight = document.documentElement.clientHeight;
769	} else if (document.body) { // other Explorers
770		windowWidth = document.body.clientWidth;
771		windowHeight = document.body.clientHeight;
772	}	
773	
774	// for small pages with total height less then height of the viewport
775	if(yScroll < windowHeight){
776		pageHeight = windowHeight;
777	} else { 
778		pageHeight = yScroll;
779	}
780
781//	console.log("xScroll " + xScroll)
782//	console.log("windowWidth " + windowWidth)
783
784	// for small pages with total width less then width of the viewport
785	if(xScroll < windowWidth){	
786		pageWidth = xScroll;		
787	} else {
788		pageWidth = windowWidth;
789	}
790//	console.log("pageWidth " + pageWidth)
791
792	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
793	return arrayPageSize;
794}
795
796// -----------------------------------------------------------------------------------
797
798//
799// getKey(key)
800// Gets keycode. If 'x' is pressed then it hides the lightbox.
801//
802function getKey(e){
803	if (e == null) { // ie
804		keycode = event.keyCode;
805	} else { // mozilla
806		keycode = e.which;
807	}
808	key = String.fromCharCode(keycode).toLowerCase();
809	
810	if(key == 'x'){
811	}
812}
813
814// -----------------------------------------------------------------------------------
815
816//
817// listenKey()
818//
819function listenKey () {	document.onkeypress = getKey; }
820	
821// ---------------------------------------------------
822
823function showSelectBoxes(){
824	var selects = document.getElementsByTagName("select");
825	for (i = 0; i != selects.length; i++) {
826		selects[i].style.visibility = "visible";
827	}
828}
829
830// ---------------------------------------------------
831
832function hideSelectBoxes(){
833	var selects = document.getElementsByTagName("select");
834	for (i = 0; i != selects.length; i++) {
835		selects[i].style.visibility = "hidden";
836	}
837}
838
839// ---------------------------------------------------
840
841function showFlash(){
842	var flashObjects = document.getElementsByTagName("object");
843	for (i = 0; i < flashObjects.length; i++) {
844		flashObjects[i].style.visibility = "visible";
845	}
846
847	var flashEmbeds = document.getElementsByTagName("embed");
848	for (i = 0; i < flashEmbeds.length; i++) {
849		flashEmbeds[i].style.visibility = "visible";
850	}
851}
852
853// ---------------------------------------------------
854
855function hideFlash(){
856	var flashObjects = document.getElementsByTagName("object");
857	for (i = 0; i < flashObjects.length; i++) {
858		flashObjects[i].style.visibility = "hidden";
859	}
860
861	var flashEmbeds = document.getElementsByTagName("embed");
862	for (i = 0; i < flashEmbeds.length; i++) {
863		flashEmbeds[i].style.visibility = "hidden";
864	}
865
866}
867
868// ---------------------------------------------------
869
870function showApplets(){
871	var applets = document.getElementsByTagName("applet");
872	for (i = 0; i < applets.length; i++) {
873		applets[i].style.visibility = "visible";
874	}
875}
876
877// ---------------------------------------------------
878
879function hideApplets(){
880	var applets = document.getElementsByTagName("applet");
881	for (i = 0; i < applets.length; i++) {
882		applets[i].style.visibility = "hidden";
883	}
884}
885
886
887// ---------------------------------------------------
888
889//
890// pause(numberMillis)
891// Pauses code execution for specified time. Uses busy code, not good.
892// Help from Ran Bar-On [[email protected]]
893//
894
895function pause(ms){
896	var date = new Date();
897	curDate = null;
898	do{var curDate = new Date();}
899	while( curDate - date < ms);
900}
901/*
902function pause(numberMillis) {
903	var curently = new Date().getTime() + sender;
904	while (new Date().getTime();	
905}
906*/
907// ---------------------------------------------------
908
909
910
911function initLightbox() { myLightbox = new Lightbox(); }
912Event.observe(window, 'load', initLightbox, false);

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.