Просмотр файла cms/screen/todo.js

Размер файла: 13.98Kb
  1. /**
  2. * todo
  3. * author: Pavel Khoroshkov aka pgood
  4. * http://pgood.ru
  5. */
  6. function todo(){this.action=[];this.execute=function(){for(var i in this.action){try{todo.action[i]();}catch(er){alert('todo >> "'+er.message+'" in "'+er.fileName+'" on "'+er.lineNumber+'"');}}};var onLoadAction=function(o){return function(){o.execute();}}(this);if(typeof document.attachEvent!='undefined')window.attachEvent('onload',onLoadAction);else window.addEventListener('load',onLoadAction,false);};
  7. todo.prototype.get=function(id){return document.getElementById(id);};
  8. todo.prototype.create=function(tag,attrs,text,style){var e=document.createElement(tag);if(attrs)for(var i in attrs)switch(i){case 'class': e.className=attrs[i];break;case 'id': e.id=attrs[i];break;default: e.setAttribute(i,attrs[i]);break;};if(text)e.appendChild(document.createTextNode(text));if(style)for(var i in style)e.style[i]=style[i];return e;};
  9. todo.prototype.onload=function(func){this.action[this.action.length]=func;};
  10. todo.prototype.loop=function(e,func,i,step){step=step?Math.abs(step):1;for(var i=i?i:0;i<e.length;i+=step)func.call(e[i],i);};
  11. todo.prototype.stopPropagation=function(e){e=e||window.event;if(!e)return;if(e.stop)e.stopPropagation();else e.cancelBubble=true;if(e.preventDefault)e.preventDefault();else e.returnValue=false;};
  12. todo.prototype.setEvent=function(name,e,f){if(!e._actionQueue)e._actionQueue={};if(!e._actionQueue[name]){e._actionQueue[name]=e['on'+name]?[e['on'+name]]:[];e['on'+name]=function(event){var e=event||window.event;for(var i=0;i<this._actionQueue[e.type].length;i++)if(this._actionQueue[e.type][i])this._actionQueue[e.type][i].call(this,event);}};var i=e._actionQueue[name].length;e._actionQueue[name][i]=f;return i;};
  13. todo.prototype.deleteEvent=function(name,e,i){if(e._actionQueue && e._actionQueue[name] && e._actionQueue[name][i]){delete e._actionQueue[name][i];if(!e._actionQueue[name].length){delete e._actionQueue[name];delete e['on'+name];}}};
  14. todo.prototype.clientSize=function(){if(document.compatMode=='CSS1Compat'){return {'w':document.documentElement.clientWidth,'h':document.documentElement.clientHeight};}else{return {'w':document.body.clientWidth,'h':document.body.clientHeight}}};
  15. todo.prototype.bodyScroll=function(){if(window.pageYOffset)return {'top':window.pageYOffset,'left':window.pageXOffset};else if(document.documentElement)return {'top':document.documentElement.scrollTop,'left':document.documentElement.scrollLeft};else return {'top':(document.scrollTop||body.scrollTop),'left':(document.scrollLeft||body.scrollLeft)}};
  16. todo.prototype.motion=function(v,start,finish,step){v=parseInt(v);var last=Math.abs(Math.abs(finish)-Math.abs(v)),step=Math.ceil((step+last)/step),res,ready;if(finish>=start){res=v+step;ready=res>=finish;}else{res=v-step;ready=res<=finish};return {'res':ready?finish:res,'ready':ready};};
  17. todo.prototype.slide=function(e,x,y,breakOff,callback,delay,step){
  18. var stopIt=function(e){if(e && e.timer){window.clearInterval(e.timer);e.timer=null;if(e.callback)e.callback.call(e._);}};
  19. if(e._slide && e._slide.timer){if(breakOff)stopIt(e._slide);else return;};
  20. if(e.style.position=='absolute'){
  21. if(!e.style.left)e.style.left=e.offsetLeft+'px';
  22. if(!e.style.top)e.style.top=e.offsetTop+'px';
  23. }else{if(!e.style.left)e.style.left='0';if(!e.style.top)e.style.top='0';};
  24. e._slide={'_':e,
  25. 'delay':delay?delay:50,
  26. 'step':step?step:4,
  27. 'start':{'x':parseInt(e.style.left),'y':parseInt(e.style.top)},
  28. 'finish':{'x':x,'y':y},
  29. 'callback':callback,
  30. 'run':function(){if(!this.timer)this.timer=window.setInterval(function(o){return function(){o._slide.slide();}}(this._),this.delay);},
  31. 'slide':function(){
  32. var res_x=todo.motion(this._.style.left,this.start.x,this.finish.x,this.step),
  33. res_y=todo.motion(this._.style.top,this.start.y,this.finish.y,this.step);
  34. this._.style.left=res_x.res+'px';
  35. this._.style.top=res_y.res+'px';
  36. if(res_x.ready && res_y.ready)stopIt(this);
  37. }
  38. };
  39. e._slide.run();
  40. };
  41. todo.prototype.resize=function(e,w,h,breakOff,callback,delay,step){
  42. var stopIt=function(e){if(e && e.timer){window.clearInterval(e.timer);e.timer=null;if(e.callback)e.callback.call(e._);}};
  43. if(e._resize!=undefined&&e._resize.timer){if(breakOff)stopIt(e._resize);else return;};
  44. if(w&&!e.style.width)e.style.width=e.offsetWidth+'px';
  45. if(h&&!e.style.height)e.style.height=e.offsetHeight+'px';
  46. e._resize={'_':e,
  47. 'isImg':e.tagName.toLowerCase()=='img',
  48. 'delay':delay?delay:50,
  49. 'step':step?step:4,
  50. 'start':{'w':parseInt(e.style.width),'h':parseInt(e.style.height)},
  51. 'finish':{'w':w,'h':h},
  52. 'callback':callback,
  53. 'run':function(){if(!this.timer)this.timer=window.setInterval(function(o){return function(){o._resize.resize();}}(this._),this.delay);},
  54. 'resize':function(){
  55. var ready=true;
  56. if(this.finish.w){
  57. var res_w=todo.motion(this._.style.width,this.start.w,this.finish.w,this.step);
  58. if(this.isImg)this._.width=res_w.res;
  59. this._.style.width=res_w.res+'px';
  60. if(!res_w.ready)ready=false;
  61. };
  62. if(this.finish.h){
  63. var res_h=todo.motion(this._.style.height,this.start.h,this.finish.h,this.step);
  64. if(this.isImg)this._.height=res_h.res;
  65. this._.style.height=res_h.res+'px';
  66. if(!res_h.ready)ready=false;
  67. };
  68. if(ready)stopIt(this);
  69. }
  70. };
  71. e._resize.run();
  72. };
  73. todo.prototype.opacity=function(e,opacity,delay,breakOff,callback){
  74. var stopIt=function(e){if(e && e.timer){window.clearInterval(e.timer);e.timer=null;if(e.callback)e.callback.call(e._);}};
  75. if(e._opacity && e._opacity.timer){if(breakOff)stopIt(e._opacity);else return;};
  76. e._opacity={'_':e,
  77. 'delay':delay,
  78. 'step':0.07,
  79. 'finish':opacity,
  80. 'callback':callback,
  81. 'run':function(){
  82. if(!this.timer)this.timer=window.setInterval(
  83. function(o,stopIt){return function(){
  84. var v=o.get()+o.step*o.sign;
  85. if((o.sign>0 && v>=o.finish) || (o.sign<0 && v<=o.finish) || v>1 || v<0){o.set(o.finish);stopIt(o);}else o.set(v);
  86. }}(this,stopIt),this.delay);
  87. },
  88. 'set':function(v){
  89. var p=this.prop();
  90. if(p=='filter'){if(v==1)v='';else v='alpha(opacity='+v*100+')';}
  91. this._.style[p]=v;
  92. },
  93. 'get':function(){
  94. var p=this.prop();
  95. if(p=='filter'){
  96. var tmp=this._.style.filter.match(/opacity=([0-9]{1,3})/);
  97. if(tmp&&tmp[1])return parseInt(tmp[1])/100;
  98. return 1;
  99. };
  100. return this._.style[p]==''?1:parseFloat(this._.style[p]);
  101. },
  102. 'prop':function(){
  103. if(typeof document.body.style.opacity=='string')return 'opacity';
  104. else if(typeof document.body.style.MozOpacity=='string')return 'MozOpacity';
  105. else if(typeof document.body.style.KhtmlOpacity=='string')return 'KhtmlOpacity';
  106. else if(document.body.filters&&navigator.appVersion.match(/MSIE ([\d.]+);/)[1]>=5.5)return 'filter';
  107. return 'opacity';
  108. }
  109. };
  110. if(!delay){e._opacity.set(opacity);return;};
  111. e._opacity.sign=e._opacity.get()>opacity?-1:1;
  112. e._opacity.run();
  113. };
  114. todo.prototype.dragZIndex=199;
  115. todo.prototype.drag=function(e){
  116. e._drag={'_':e,'x':null,'y':null,'draged':false,'onClick':e.onclick,
  117. 'startDrag':function(event){
  118. event=event||window.event;
  119. this.x=event.clientX-parseInt(this._.style.left);
  120. this.y=event.clientY-parseInt(this._.style.top);
  121. this.eventIndexMouseMove=todo.setEvent('mousemove',document,function(e){return function(event){return e.drag(event);}}(this));
  122. this.eventIndexMouseUp=todo.setEvent('mouseup',document,function(e){return function(event){return e.stopDrag(event);}}(this));
  123. this.draged=false;
  124. if(this._.style.zIndex<todo.dragZIndex)this._.style.zIndex=++todo.dragZIndex;
  125. todo.stopPropagation(event);
  126. },
  127. 'drag':function(event){
  128. event=event||window.event;
  129. this._.style.left=(event.clientX-this.x)+'px';
  130. this._.style.top=(event.clientY-this.y)+'px';
  131. todo.stopPropagation(event);
  132. this.draged=true;
  133. },
  134. 'stopDrag':function(event){
  135. todo.deleteEvent('mousemove',document,this.eventIndexMouseMove);
  136. todo.deleteEvent('mouseup',document,this.eventIndexMouseUp);
  137. return false;
  138. }
  139. };
  140. e.onclick=function(e){return function(event){if(e.draged){e.draged=false;todo.stopPropagation(event);return false;}else if(e.onClick)e.onClick.call(this,event);}}(e._drag);
  141. e.onmousedown=function(e){this._drag.startDrag(e);};
  142. e.style.position='absolute';
  143. e.style.zIndex=++todo.dragZIndex;
  144. return e;
  145. };
  146. todo.prototype.popupZIndex=99999;
  147. todo.prototype.popup=function(width,height){
  148. width=width?width:300;
  149. height=height?height:300;
  150. var getCenterPos=function(w,h){
  151. var size=todo.clientSize();
  152. return {'left':size.w>w?Math.ceil((size.w-w)/2):17,
  153. 'top':size.h>h?Math.ceil((size.h-h-46)/2):17}
  154. },
  155. pos=getCenterPos(width,height),
  156. e=todo.create('div',{'class':'todo_popup'},null,{'position':'absolute','left':pos.left+'px','top':pos.top+'px','width':width+'px','height':height+'px','zIndex':todo.popupZIndex});
  157. e._popup={'_':e,'isClose':true,
  158. 'close':function(){
  159. todo.opacity(this._,0.5,50,false,function(w){return function(){w._=w._.parentNode.removeChild(w._);}}(this));
  160. this.isClose=true;
  161. },
  162. 'open':function(){
  163. if(!this.isClose)return;
  164. this._.style.zIndex=todo.popupZIndex;
  165. this.isClose=false;
  166. todo.opacity(this._,1);
  167. this._=document.body.appendChild(this._);
  168. if(this.content)this.content=this.content.parentNode.removeChild(this.content);
  169. else this.content=todo.create('div',null,null,{'paddingTop':'23px','paddingBottom':'23px'});
  170. this._.innerHTML='<div class="todo_top"></div><div class="todo_bottom"></div><div class="todo_left"></div><div class="todo_right"></div><div class="todo_corner1"></div><div class="todo_corner2"></div><div class="todo_corner3"></div><div class="todo_corner4"></div>';
  171. this._.appendChild(this.content);
  172. this._.appendChild(todo.create('div',{'class':'todo_button_close'})).onclick=function(){this.parentNode._popup.close();};
  173. },
  174. 'getSize':function(){return {'width':parseInt(this._.style.width),'height':parseInt(this._.style.height)}},
  175. 'getCenterPos':getCenterPos,
  176. 'resize':function(w,h,callback){todo.resize(this._,w,h+46,false,callback);},
  177. 'position':function(left,top){todo.slide(this._,left,top);}
  178. };
  179. e._popup.open();
  180. return e;
  181. };
  182. todo.prototype.gallery=function(name){
  183. var a=document.getElementsByTagName('a'),res,g;
  184. if(!this._galleries)this._galleries={};
  185. for(var i=0;i<a.length;i++){
  186. if(!a[i].rel)continue;
  187. res=a[i].rel.match(new RegExp(name+'\\[([a-zA-Z0-9]+)\\]'));
  188. if(!res)continue;
  189. if(this._galleries[res[1]])g=this._galleries[res[1]];
  190. else{
  191. g={'name':res[1],'a':[],
  192. 'getWin':function(){
  193. if(!this.win){
  194. this.win=todo.drag(todo.popup(200,200));
  195. this.e=this.win._popup.content;
  196. }else if(this.win._popup.isClose)this.win._popup.open();
  197. return this.win;
  198. },
  199. 'setLoader':function(){
  200. var pos=this.getWin()._popup.getSize();
  201. this.e.innerHTML='';
  202. this.loader=this.e.appendChild(todo.create('div',{'class':'todo_gallery_loader'}));
  203. this.loader.style.top=((pos.height-66)/2)+'px';
  204. this.loader.style.left=((pos.width-66)/2)+'px';
  205. },
  206. 'setImage':function(){
  207. var img=this.img,win=this.getWin(),size=todo.clientSize(),w=img.width,h=img.height;
  208. this.collapse=null;
  209. if(size.h<h+100){
  210. w=Math.ceil((size.h-100)*w/h);h=size.h-100;
  211. this.collapse=true;
  212. };
  213. if(size.w<w+100){
  214. this.collapse={'state':0,'size':{'w':w,'h':h}};
  215. h=Math.ceil((size.w-100)*h/w);w=size.w-100;
  216. this.collapse=true;
  217. };
  218. if(this.collapse){
  219. this.collapse={'state':true,'size':{'w':img.width,'h':img.height},'collapse':{'w':w,'h':h}};
  220. img.width=w;img.height=h;
  221. };
  222. var pos=win._popup.getCenterPos(w,h),
  223. scr=todo.bodyScroll();
  224. this.e.innerHTML='';
  225. win._popup.resize(w,h,function(g){return function(){g.img=g.e.appendChild(g.img);}}(this));
  226. win._popup.position(pos.left+scr.left,pos.top+scr.top);
  227. this.setTitle();
  228. this.setNav();
  229. this.setExpand();
  230. },
  231. 'set':function(a){
  232. this.setLoader();
  233. this.img=todo.create('img',{'src':a.href});
  234. for(var i=0;i<this.a.length;i++)if(a==this.a[i]){
  235. this.current=i;
  236. this.img._gallery=this;
  237. this.img._timer=window.setInterval(function(g){return function(){if(g.img.complete || g.img._counter>1000){g.setImage();window.clearInterval(g.img._timer)}else g.img._counter++;}}(this),200);
  238. break;
  239. }
  240. },
  241. 'next':function(){if(this.current<this.a.length-1)this.set(this.a[this.current+1]);},
  242. 'prev':function(){if(this.current>0)this.set(this.a[this.current-1]);},
  243. 'setTitle':function(){if(this.a[this.current].title){this.e.appendChild(todo.create('div',{'class':'todo_gallery_title'},this.a[this.current].title),{});}},
  244. 'setNav':function(){
  245. if(this.a.length==1)return;
  246. var e=this.e.appendChild(todo.create('div',{'class':'todo_gallery_nav'},(this.current+1)+' из '+this.a.length));
  247. if(this.current>0){
  248. var left=e.appendChild(todo.create('div',{'class':'todo_gallery_button_left','title':'Предыдущая'}));
  249. left._gallery=this;
  250. left.onclick=function(){this._gallery.prev();};
  251. };
  252. if(this.current<this.a.length-1){
  253. var right=e.appendChild(todo.create('div',{'class':'todo_gallery_button_right','title':'Следующая'}));
  254. right._gallery=this;
  255. right.onclick=function(){this._gallery.next();};
  256. }
  257. },
  258. 'setExpand':function(){
  259. if(!this.collapse)return;
  260. var e=this.e.appendChild(todo.create('div',{'class':'todo_gallery_button_expand'}));
  261. e._gallery=this;
  262. e.onclick=function(){
  263. var win=this._gallery.getWin(),size,
  264. state=this._gallery.collapse.state=!this._gallery.collapse.state;
  265. this.className='todo_gallery_button_'+(state?'expand':'collapse');
  266. if(state)size=this._gallery.collapse.collapse;
  267. else size=this._gallery.collapse.size;
  268. var pos=win._popup.getCenterPos(size.w,size.h),
  269. scr=todo.bodyScroll();
  270. win._popup.resize(size.w,size.h);
  271. todo.resize(this._gallery.img,size.w,size.h);
  272. win._popup.position(pos.left+scr.left,pos.top+scr.top);
  273. }
  274. },
  275. 'add':function(e){
  276. for(var i=0;i<this.a.length;i++)if(e==this.a[i])return;
  277. e._gallery=this;
  278. e.onclick=function(){this._gallery.set(this);return false;}
  279. this.a[this.a.length]=e;
  280. }
  281. };
  282. this._galleries[g.name]=g;
  283. };
  284. g.add(a[i]);
  285. }
  286. };
  287. todo=new todo;