Blame | Last modification | View Log | RSS feed
if(!dojo._hasResource["dojox.image.Lightbox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.dojo._hasResource["dojox.image.Lightbox"] = true;dojo.provide("dojox.image.Lightbox");dojo.experimental("dojox.image.Lightbox");dojo.require("dijit.Dialog");dojo.require("dojox.fx");dojo.declare("dojox.image.Lightbox",dijit._Widget,{// summary:// a dojo-based Lightbox implementation.//// description:// an Elegant, keyboard accessible, markup and store capable Lightbox widget to show images// in a modal dialog-esque format. Can show individual images as Modal dialog, or can group// images with multiple entry points, all using a single "master" Dialog for visualization//// examples://// <a href="image1.jpg" dojoType="dojox.image.Lightbox">show lightbox</a>// <a href="image2.jpg" dojoType="dojox.image.Lightbox" group="one">show group lightbox</a>// <a href="image3.jpg" dojoType="dojox.image.Lightbox" group="one">show group lightbox</a>//// FIXME: not implemented fully yet, though works with basic datastore access. need to manually call// widget._attachedDialog.addImage(item,"fromStore") for each item in a store result set.// <div dojoType="dojox.image.Lightbox" group="fromStore" store="storeName"></div>// group: String// grouping images in a page with similar tags will provide a 'slideshow' like grouping of imagesgroup: "",// title: String// A string of text to be shown in the Lightbox beneath the image (empty if using a store)title: "",// href; String// link to image to use for this Lightbox node (empty if using a store).href: "",// duration: Integer// generic time in MS to adjust the feel of widget. could possibly add various// durations for the various actions (dialog fadein, sizeing, img fadein ...)duration: 500,// _allowPassthru: Boolean// privately set this to disable/enable natural link of anchor tags_allowPassthru: false,_attachedDialog: null, // try to share a single underlay per page?startup: function(){this.inherited("startup", arguments);// setup an attachment to the masterDialog (or create the masterDialog)var tmp = dijit.byId('dojoxLightboxDialog');if(tmp){this._attachedDialog = tmp;}else{// this is the first instance to start, so we make the masterDialogthis._attachedDialog = new dojox.image._LightboxDialog({ id: "dojoxLightboxDialog" });this._attachedDialog.startup();}if(!this.store){// FIXME: full store support lacking, have to manually call this._attachedDialog.addImage(imgage,group) as it standsthis._addSelf();this.connect(this.domNode, "onclick", "_handleClick");}},_addSelf: function(){this._attachedDialog.addImage({href: this.href,title: this.title},this.group||null);},_handleClick: function(/* Event */e){// summary: handle the click on the linkif(!this._allowPassthru){ e.preventDefault(); }else{ return; }this.show();},show: function(){this._attachedDialog.show(this);},disable: function(){// summary, disables event clobbering and dialog, and follows natural linkthis._allowPassthru = true;},enable: function(){// summary: enables the dialog (prevents default link)this._allowPassthru = false;}});dojo.declare("dojox.image._LightboxDialog",dijit.Dialog,{//// Description://// a widget that intercepts anchor links (typically around images)// and displays a modal Dialog. this is the actual Popup, and should// not be created directly.//// there will only be one of these on a page, so all dojox.image.Lightbox's will us it// (the first instance of a Lightbox to be show()'n will create me If i do not exist)//// note: the could be the ImagePane i was talking about?// title: String// the current titletitle: "",// FIXME: implement titleTemplate// inGroup: Array// Array of objects. this is populated by from the JSON object _groups, and// should not be populate manually. it is a placeholder for the currently// showing group of images in this master dialoginGroup: null,// imgUrl: String// the src="" attrib of our imageNode (can be null at statup)imgUrl: "",// an array of objects, each object being a unique 'group'_groups: { XnoGroupX: [] },_imageReady: false,templateString:"<div class=\"dojoxLightbox\" dojoAttachPoint=\"containerNode\">\n\t<div style=\"position:relative\">\n\t\t<div dojoAttachPoint=\"imageContainer\" class=\"dojoxLightboxContainer\">\n\t\t\t<img dojoAttachPoint=\"imgNode\" src=\"${imgUrl}\" class=\"dojoxLightboxImage\" alt=\"${title}\">\n\t\t\t<div class=\"dojoxLightboxFooter\" dojoAttachPoint=\"titleNode\">\n\t\t\t\t<div class=\"dijitInline LightboxClose\" dojoAttachPoint=\"closeNode\"></div>\n\t\t\t\t<div class=\"dijitInline LightboxNext\" dojoAttachPoint=\"nextNode\"></div>\t\n\t\t\t\t<div class=\"dijitInline LightboxPrev\" dojoAttachPoint=\"prevNode\"></div>\n\n\t\t\t\t<div class=\"dojoxLightboxText\"><span dojoAttachPoint=\"textNode\">${title}</span><span dojoAttachPoint=\"groupCount\" class=\"dojoxLightboxGroupText\"></span></div>\n\t\t\t</div>\n\t\t</div>\t\n\t\t\n\t</div>\n</div>\n",startup: function(){// summary: add some extra event handlers, and startup our superclass.this.inherited("startup", arguments);// FIXME: these are supposed to be available in dijit.Dialog already,// but aren't making it over.dojo.connect(document.documentElement,"onkeypress",this,"_handleKey");this.connect(window,"onresize","_position");this.connect(this.nextNode, "onclick", "_nextImage");this.connect(this.prevNode, "onclick", "_prevImage");this.connect(this.closeNode, "onclick", "hide");},show: function(/* Object */groupData){// summary: starts the chain of events to show an image in the dialog, including showing the dialog// if it is not already visibledojo.style(this.imgNode,"opacity","0");dojo.style(this.titleNode,"opacity","0");// we only need to call dijit.Dialog.show() if we're not already open.if(!this.open){ this.inherited("show", arguments); }this._imageReady = false;this.imgNode.src = groupData.href;if((groupData.group && !(groupData == "XnoGroupX")) || this.inGroup){if(!this.inGroup){this.inGroup = this._groups[(groupData.group)];var i = 0;// determine where we were or are in the showdojo.forEach(this.inGroup,function(g){if (g.href == groupData.href){this._positionIndex = i;}i++;},this);}if(!this._positionIndex){ this._positionIndex=0; this.imgNode.src = this.inGroup[this._positionIndex].href; }this.groupCount.innerHTML = " (" +(this._positionIndex+1) +" of "+this.inGroup.length+")";this.prevNode.style.visibility = "visible";this.nextNode.style.visibility = "visible";}else{this.groupCount.innerHTML = "";this.prevNode.style.visibility = "hidden";this.nextNode.style.visibility = "hidden";}this.textNode.innerHTML = groupData.title;if(!this._imageReady || this.imgNode.complete === true){this._imgConnect = dojo.connect(this.imgNode,"onload", this, function(){this._imageReady = true;this.resizeTo({ w: this.imgNode.width, h:this.imgNode.height, duration:this.duration });dojo.disconnect(this._imgConnect);});// onload doesn't fire in IE if you connect before you set the src.// hack to re-set the src after onload connection made:if(dojo.isIE){ this.imgNode.src = this.imgNode.src; }}else{// do it quickly. kind of a hack, but image is ready nowthis.resizeTo({ w: this.imgNode.width, h:this.imgNode.height, duration:1 });}},_nextImage: function(){// summary: load next image in groupif(this._positionIndex+1<this.inGroup.length){this._positionIndex++;}else{this._positionIndex = 0;}this._loadImage();},_prevImage: function(){// summary: load previous image in groupif(this._positionIndex==0){this._positionIndex = this.inGroup.length-1;}else{this._positionIndex--;}this._loadImage();},_loadImage: function(){// summary: do the prep work before we can show another imagevar _loading = dojo.fx.combine([dojo.fadeOut({ node:this.imgNode, duration:(this.duration/2) }),dojo.fadeOut({ node:this.titleNode, duration:(this.duration/2) })]);this.connect(_loading,"onEnd","_prepNodes");_loading.play(10);},_prepNodes: function(){// summary: a localized hook to accompany _loadImagethis._imageReady = false;this.show({href: this.inGroup[this._positionIndex].href,title: this.inGroup[this._positionIndex].title});},resizeTo: function(/* Object */size){// summary: resize our dialog container, and fire _showImagevar _sizeAnim = dojox.fx.sizeTo({node: this.containerNode,duration:size.duration||this.duration,width: size.w,height:size.h+30});this.connect(_sizeAnim,"onEnd","_showImage");_sizeAnim.play(this.duration);},_showImage: function(){// summary: fade in the image, and fire showNavdojo.fadeIn({ node: this.imgNode, duration:this.duration,onEnd: dojo.hitch(this,"_showNav")}).play(75);},_showNav: function(){// summary: fade in the footer, and setup our connections.dojo.fadeIn({ node: this.titleNode, duration:200 }).play(25);},hide: function(){// summary: close the Lightboxdojo.fadeOut({node:this.titleNode, duration:200 }).play(25);this.inherited("hide", arguments);this.inGroup = null;this._positionIndex = null;},addImage: function(/* object */child,/* String? */group){// summary: add an image to this master dialog//// child.href: String - link to image (required)// child.title: String - title to display//// group: String - attach to group of similar tag// or null for individual image instancevar g = group;if(!child.href){ return; }if(g){if(this._groups[(g)]){this._groups[(g)].push(child);}else{this._groups[(g)] = [(child)];}}else{ this._groups["XnoGroupX"].push(child); }},_handleKey: function(/* Event */e){// summary: handle keyboard navigationif(!this.open){ return; }var key = (e.charCode == dojo.keys.SPACE ? dojo.keys.SPACE : e.keyCode);switch(key){case dojo.keys.ESCAPE: this.hide(); break;case dojo.keys.DOWN_ARROW:case dojo.keys.RIGHT_ARROW:case 78: // key "n"this._nextImage(); break;case dojo.keys.UP_ARROW:case dojo.keys.LEFT_ARROW:case 80: // key "p"this._prevImage(); break;}}});}