jQuery.fn.boxy=function(options){
options=options||{};
return this.each(function(){
var node=this.nodeName.toLowerCase(),self=this;
if(node=='a'){
jQuery(this).click(function(){
var active=Boxy.linkedTo(this),
href=this.getAttribute('href'),
localOptions=jQuery.extend({actuator:this,title:this.title},options);
if(active){
active.show();}else if(href.indexOf('#')>=0){
var content=jQuery(href.substr(href.indexOf('#'))),
newContent=content.clone(true);
content.remove();
localOptions.unloadOnHide=false;
new Boxy(newContent,localOptions);}else{
if(!localOptions.cache)localOptions.unloadOnHide=true;
Boxy.load(this.href,localOptions);}
return false;});}else if(node=='form'){
jQuery(this).bind('submit.boxy',function(){
Boxy.confirm(options.message||'Please confirm:',function(){
jQuery(self).unbind('submit.boxy').submit();});
return false;});}});};
function Boxy(element,options){
this.boxy=jQuery(Boxy.WRAPPER);
jQuery.data(this.boxy[0],'boxy',this);
this.visible=false;
this.options=jQuery.extend({},Boxy.DEFAULTS,options||{});
if(this.options.modal){
this.options=jQuery.extend(this.options,{center:true,draggable:false});}
if(this.options.actuator){
jQuery.data(this.options.actuator,'active.boxy',this);}
this.setContent(element||"<div></div>");
this._setupTitleBar();
this.boxy.css('display','none').appendTo(document.body);
this.toTop();
if(this.options.fixed){
if(jQuery.browser.msie&&jQuery.browser.version<7){
this.options.fixed=false;}else{
this.boxy.addClass('fixed');}}
if(this.options.center&&Boxy._u(this.options.x,this.options.y)){
this.center();}else{
this.moveTo(
Boxy._u(this.options.x)?this.options.x:Boxy.DEFAULT_X,
Boxy._u(this.options.y)?this.options.y:Boxy.DEFAULT_Y);}
if(this.options.show)this.show();};
Boxy.EF=function(){};
jQuery.extend(Boxy,{
WRAPPER:"<table cellspacing='0' cellpadding='0' border='0' class='boxy-wrapper'>"+
"<tr><td class='top-left'></td><td class='top'></td><td class='top-right'></td></tr>"+
"<tr><td class='left'></td><td class='boxy-inner'></td><td class='right'></td></tr>"+
"<tr><td class='bottom-left'></td><td class='bottom'></td><td class='bottom-right'></td></tr>"+
"</table>",
DEFAULTS:{
title:null,
closeable:true,
draggable:true,
clone:false,
actuator:null,
center:true,
show:true,
modal:false,
fixed:true,
closeText:'[关闭]',
unloadOnHide:false,
clickToFront:false,
behaviours:Boxy.EF,
afterDrop:Boxy.EF,
afterShow:Boxy.EF,
beforeHide:Boxy.EF,
afterHide:Boxy.EF,
beforeUnload:Boxy.EF},
DEFAULT_X:50,
DEFAULT_Y:50,
zIndex:1337,
dragConfigured:false,
resizeConfigured:false,
dragging:null,
iframeBoxy:null,
inlineBoxy:null,
load:function(url,options){
options=options||{};
var ajax={
url:url,type:'GET',dataType:'html',cache:false,success:function(html){
html=jQuery(html);
if(options.filter)html=jQuery(options.filter,html);
new Boxy(html,options);}};
jQuery.each(['type','cache'],function(){
if(this in options){
ajax[this]=options[this];
delete options[this];}});
jQuery.ajax(ajax);},
iframeLoad:function(url,options){
options=options||{};
Boxy.iframeBoxy=new Boxy('<iframe id="boxyIframe" frameborder="0" src="'+url+'" ></iframe>',options);},
inlineLoad:function(blockId,options){
options=options||{};
if(!options.beforeHide){
options.beforeHide=function(){$("body").append($(blockId).hide())}}
Boxy.inlineBoxy=new Boxy("",options);
Boxy.inlineBoxy.getContent().append($(blockId).show());
Boxy.inlineBoxy.center();},
closeAll:function(){
var l=$(".boxy-content").length;
for(var i=0;i<l;i++){
Boxy.get(".boxy-content").hide();
Boxy.get(".boxy-content").unload();}},
get:function(ele){
var p=jQuery(ele).parents('.boxy-wrapper');
return p.length?jQuery.data(p[0],'boxy'):null;},
linkedTo:function(ele){
return jQuery.data(ele,'active.boxy');},
alert:function(message,callback,options){
return Boxy.ask(message,['确定'],callback,options);},
confirm:function(message,after,options){
return Boxy.ask(message,['确定','取消'],function(response){
if(response=='确定')after();},options);},
ask:function(question,answers,callback,options){
options=jQuery.extend({modal:true,closeable:false},
options||{},{show:true,unloadOnHide:true});
var body=jQuery('<div></div>').append(jQuery('<div class="question"></div>').html(question));
var map={},answerStrings=[];
if(answers instanceof Array){
for(var i=0;i<answers.length;i++){
map[answers[i]]=answers[i];
answerStrings.push(answers[i]);}}else{
for(var k in answers){
map[answers[k]]=k;
answerStrings.push(answers[k]);}}
var buttons=jQuery('<form class="answers"></form>');
buttons.html(jQuery.map(answerStrings,function(v){
return "<input type='button' value='"+v+"' class='btn' />";}).join(' '));
jQuery('input[type=button]',buttons).click(function(){
var clicked=this;
Boxy.get(this).hide(function(){
if(callback)callback(map[clicked.value]);});});
body.append(buttons);
new Boxy(body,options);},
isModalVisible:function(){
return jQuery('.boxy-modal-blackout').length>0;},
_u:function(){
for(var i=0;i<arguments.length;i++)
if(typeof arguments[i]!='undefined')return false;
return true;},
_handleResize:function(evt){
var d=jQuery(document);
jQuery('.boxy-modal-blackout').css('display','none').css({
width:d.width(),height:d.height()}).css('display','block');},
_handleDrag:function(evt){
var d;
if(d=Boxy.dragging){
d[0].boxy.css({left:evt.pageX-d[1],top:evt.pageY-d[2]});}},
_nextZ:function(){
return Boxy.zIndex++;},
_viewport:function(){
var d=document.documentElement,b=document.body,w=window;
return jQuery.extend(
jQuery.browser.msie?{left:b.scrollLeft||d.scrollLeft,top:b.scrollTop||d.scrollTop}:{left:w.pageXOffset,top:w.pageYOffset},!Boxy._u(w.innerWidth)?{width:w.innerWidth,height:w.innerHeight}:(!Boxy._u(d)&&!Boxy._u(d.clientWidth)&&d.clientWidth!=0?{width:d.clientWidth,height:d.clientHeight}:{width:b.clientWidth,height:b.clientHeight}));}});
Boxy.prototype={
estimateSize:function(){
this.boxy.css({visibility:'hidden',display:'block'});
var dims=this.getSize();
this.boxy.css('display','none').css('visibility','visible');
return dims;},
getSize:function(){
return[this.boxy.width(),this.boxy.height()];},
getContentSize:function(){
var c=this.getContent();
return[c.width(),c.height()];},
getPosition:function(){
var b=this.boxy[0];
return[b.offsetLeft,b.offsetTop];},
getCenter:function(){
var p=this.getPosition();
var s=this.getSize();
return[Math.floor(p[0]+s[0]/2),Math.floor(p[1]+s[1]/2)];},
getInner:function(){
return jQuery('.boxy-inner',this.boxy);},
getContent:function(){
return jQuery('.boxy-content',this.boxy);},
setContent:function(newContent){
newContent=jQuery(newContent).css({display:'block'}).addClass('boxy-content');
if(this.options.clone)newContent=newContent.clone(true);
this.getContent().remove();
this.getInner().append(newContent);
this._setupDefaultBehaviours(newContent);
this.options.behaviours.call(this,newContent);
return this;},
moveTo:function(x,y){
this.moveToX(x).moveToY(y);
return this;},
moveToX:function(x){
if(typeof x=='number')this.boxy.css({left:x});
else this.centerX();
return this;},
moveToY:function(y){
if(typeof y=='number')this.boxy.css({top:y});
else this.centerY();
return this;},
centerAt:function(x,y){
var s=this[this.visible?'getSize':'estimateSize']();
if(typeof x=='number')this.moveToX(x-s[0]/2);
if(typeof y=='number')this.moveToY(y-s[1]/2);
return this;},
centerAtX:function(x){
return this.centerAt(x,null);},
centerAtY:function(y){
return this.centerAt(null,y);},
center:function(axis){
var v=Boxy._viewport();
var o=this.options.fixed?[0,0]:[v.left,v.top];
if(!axis||axis=='x')this.centerAt(o[0]+v.width/2,null);
if(!axis||axis=='y')this.centerAt(null,o[1]+v.height/2);
return this;},
centerX:function(){
return this.center('x');},
centerY:function(){
return this.center('y');},
resize:function(width,height,after){
if(!this.visible)return;
var bounds=this._getBoundsForResize(width,height);
this.boxy.css({left:bounds[0],top:bounds[1]});
this.getContent().css({width:bounds[2],height:bounds[3]});
if(after)after(this);
return this;},
tween:function(width,height,after){
if(!this.visible)return;
var bounds=this._getBoundsForResize(width,height);
var self=this;
this.boxy.stop().animate({left:bounds[0],top:bounds[1]});
this.getContent().stop().animate({width:bounds[2],height:bounds[3]},function(){
if(after)after(self);});
return this;},
isVisible:function(){
return this.visible;},
show:function(){
if(this.visible)return;
if(this.options.modal){
var self=this;
if(!Boxy.resizeConfigured){
Boxy.resizeConfigured=true;
jQuery(window).resize(function(){Boxy._handleResize();});}
this.modalBlackout=jQuery('<div class="boxy-modal-blackout"></div>')
.css({zIndex:Boxy._nextZ(),
opacity:0.7,
width:jQuery(document).width(),
height:jQuery(document).height()})
.appendTo(document.body);
this.toTop();
if(this.options.closeable){
jQuery(document.body).bind('keypress.boxy',function(evt){
var key=evt.which||evt.keyCode;
if(key==27){
self.hide();
jQuery(document.body).unbind('keypress.boxy');}});}}
this.boxy.stop().css({opacity:1}).show();
this.visible=true;
this._fire('afterShow');
return this;},
hide:function(after){
if(!this.visible)return;
var self=this;
self._fire('beforeHide');
if(this.options.modal){
jQuery(document.body).unbind('keypress.boxy');
this.modalBlackout.animate({opacity:0},function(){
jQuery(this).remove();});}
this.boxy.stop().animate({opacity:0},300,function(){
self.boxy.css({display:'none'});
self.visible=false;
self._fire('afterHide');
if(after)after(self);
if(self.options.unloadOnHide)self.unload();});
return this;},
toggle:function(){
this[this.visible?'hide':'show']();
return this;},
hideAndUnload:function(after){
this.options.unloadOnHide=true;
this.hide(after);
return this;},
unload:function(){
this._fire('beforeUnload');
this.boxy.remove();
if(this.options.actuator){
jQuery.data(this.options.actuator,'active.boxy',false);}},
toTop:function(){
this.boxy.css({zIndex:Boxy._nextZ()});
return this;},
getTitle:function(){
return jQuery('> .title-bar h2',this.getInner()).html();},
setTitle:function(t){
jQuery('> .title-bar h2',this.getInner()).html(t);
return this;},
_getBoundsForResize:function(width,height){
var csize=this.getContentSize();
var delta=[width-csize[0],height-csize[1]];
var p=this.getPosition();
return[Math.max(p[0]-delta[0]/2,0),
Math.max(p[1]-delta[1]/2,0),width,height];},
_setupTitleBar:function(){
if(this.options.title){
var self=this;
var tb=jQuery("<div class='title-bar'></div>").html("<h2>"+this.options.title+"</h2>");
if(this.options.closeable){
tb.append(jQuery("<a href='#' class='close'></a>").html(this.options.closeText));}
if(this.options.draggable){
tb[0].onselectstart=function(){return false;}
tb[0].unselectable='on';
tb[0].style.MozUserSelect='none';
if(!Boxy.dragConfigured){
jQuery(document).mousemove(Boxy._handleDrag);
Boxy.dragConfigured=true;}
tb.mousedown(function(evt){
self.toTop();
Boxy.dragging=[self,evt.pageX-self.boxy[0].offsetLeft,evt.pageY-self.boxy[0].offsetTop];
jQuery(this).addClass('dragging');}).mouseup(function(){
jQuery(this).removeClass('dragging');
Boxy.dragging=null;
self._fire('afterDrop');});}
this.getInner().prepend(tb);
this._setupDefaultBehaviours(tb);}},
_setupDefaultBehaviours:function(root){
var self=this;
if(this.options.clickToFront){
root.click(function(){self.toTop();});}
jQuery('.close',root).click(function(){
self.hide();
return false;}).mousedown(function(evt){evt.stopPropagation();});},
_fire:function(event){
this.options[event].call(this);}};

