From: Michael M Slusarz Date: Sun, 18 Jan 2009 23:41:20 +0000 (-0700) Subject: Use document-wide Event handlers. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=0c72f48039b15eb93bc5b67850f6a04ca42d9395;p=horde.git Use document-wide Event handlers. DIMP now uses approx. 10 total ecent handlers as opposed to before, where 1000's of event handlers needed to be created/deleted if a user would scroll through a list of messages. --- diff --git a/imp/js/dragdrop.js b/imp/js/dragdrop.js index eb7ee18a3..796b34871 100644 --- a/imp/js/dragdrop.js +++ b/imp/js/dragdrop.js @@ -1 +1 @@ -var DragDrop={Drags:{drags:$H(),register:function(a){if(!this.drags.size()){if(!this.div){this.div=new Element("DIV",{className:a.options.classname}).hide()}$(document.body).insert(this.div)}this.drags.set(a.element.identify(),a)},unregister:function(a){if(this.drag==a.element){this.drag.deactivate()}this.drags.unset(a.element.identify());if(!this.drags.size()&&this.div){this.div.remove()}},get_drag:function(a){return this.drags.get(Object.isElement(a)?$(a).identify():a)},activate:function(a){if(this.drag){this.deactivate()}this.drag=a;this.mousemoveE=a._mouseMove.bindAsEventListener(a);this.mouseupE=a._mouseUp.bindAsEventListener(a);document.observe("mousemove",this.mousemoveE);document.observe("mouseup",this.mouseupE)},deactivate:function(){if(this.drag){this.drag=null;document.stopObserving("mousemove",this.mousemoveE);document.stopObserving("mouseup",this.mouseupE)}}},Drops:{drops:$H(),register:function(a){this.drops.set(a.element.identify(),a)},unregister:function(a){if(this.drop==a.element){this.drop=null}this.drops.unset(a.element.identify())},get_drop:function(a){return this.drops.get(Object.isElement(a)?$(a).identify():a)}},validDrop:function(a){var b=DragDrop.Drops.drop;return(b&&a&&a!=b.element&&(!b.options.accept.size()||b.options.accept.include(a.tagName)))}},Drag=Class.create({initialize:function(a){this.element=$(a);this.options=Object.extend({caption:"",classname:"drag",constraint:null,ghosting:false,scroll:null,snap:null,threshold:0,onDrag:null,onEnd:null,onStart:null},arguments[1]||{});this.mousedownE=this._mouseDown.bindAsEventListener(this);this.element.observe("mousedown",this.mousedownE);if(this.options.scroll){this.options.scroll=$(this.options.scroll)}DragDrop.Drags.register(this);if(Prototype.Browser.IE){this.element.observe("selectstart",Event.stop)}else{if(Prototype.Browser.Gecko){this.element.setStyle({MozUserSelect:"none"})}}},destroy:function(){this.element.stopObserving("mousedown",this.mousedownE);DragDrop.Drags.unregister(this)},_mouseDown:function(a){$(document.body).setStyle({cursor:"default"});DragDrop.Drags.activate(this);this.move=0;this.wasDragged=false;this.lastcaption=null;if(Object.isFunction(this.options.onStart)){this.options.onStart(this,a)}if(!Prototype.Browser.IE&&!Prototype.Browser.Gecko){a.stop()}},_mouseMove:function(f){var b,c,a,d;if(++this.move<=this.options.threshold){return}this.lastCoord=d=[f.pointerX(),f.pointerY()];if(this.options.ghosting){if(!this.ghost){b=this.element.offsetLeft;c=this.element.offsetTop;this.ghost=$(this.element.cloneNode(true)).writeAttribute("id",null).setOpacity(0.7).clonePosition(this.element,{setLeft:false,setTop:false}).setStyle({left:b+"px",position:"absolute",top:c+"px",zIndex:parseInt(this.element.getStyle("zIndex"))+1});this.element.insert({before:this.ghost});a=this.ghost.viewportOffset();this.ghostOffset=[a[0]-b,a[1]-c]}d[0]-=this.ghostOffset[0];d[1]-=this.ghostOffset[1];switch(this.options.constraint){case"horizontal":d[1]=this.ghost.offsetTop;break;case"vertical":d[0]=this.ghost.offsetLeft;break}if(this.options.snap){d=this.options.snap(d[0],d[1],this.element)}if(this.options.offset){d[0]+=this.options.offset.x;d[1]+=this.options.offset.y}this._setContents(this.ghost,d[0],d[1])}this._onMoveDrag(d,f);if(Object.isFunction(this.options.onDrag)){this.options.onDrag(this,f)}this.wasDragged=true;if(this.options.scroll){this._onMoveScroll()}},_mouseUp:function(a){var b=DragDrop.Drops.drop;this._stopScrolling();if(this.ghost){this.ghost.remove();this.ghost=null}DragDrop.Drags.div.hide();if(DragDrop.validDrop(this.element)&&Object.isFunction(b.options.onDrop)){b.options.onDrop(b.element,this.element,a)}DragDrop.Drags.deactivate();if(Object.isFunction(this.options.onEnd)){this.options.onEnd(this,a)}},_onMoveDrag:function(k,g){var i,j,f,c,h=DragDrop.Drops.drop,a=DragDrop.Drags.div,b=true;if(h&&DragDrop.validDrop(this.element)){c=h.options.caption;if(c){j=Object.isFunction(c)?c(h.element,this.element,g):c;if(j&&h.options.hoverclass){f=h.options.hoverclass}}else{b=false}}if(b){if(!j){i=this.options.caption;j=Object.isFunction(i)?i(this.element):i}if(j!=this.lastcaption){this.lastcaption=j;a.update(j).writeAttribute({className:f||this.options.classname});if(j.empty()){a.hide()}}}if(!this.lastcaption.empty()){this._setContents(a,k[0]+15,k[1]+(this.ghost?(this.ghost.getHeight()+5):5))}},_onMoveScroll:function(){this._stopScrolling();var e,d,b,a=this.options.scroll,c=a.getDimensions();if(a.scrollHeight==c.height){return}e=document.viewport.getScrollOffsets();d=a.viewportOffset(),b=[0,0];d[0]+=a.scrollLeft+e.left;d[2]=d[0]+c.width;if(this.lastCoord[0]>d[2]||this.lastCoord[0]d[3]){b[1]=this.lastCoord[1]-d[3]}if(b[0]||b[1]){this.lastScrolled=new Date();this.scrollInterval=setInterval(this._scroll.bind(this,b[0]*15,b[1]*15),10)}},_stopScrolling:function(){if(this.scrollInterval){clearInterval(this.scrollInterval);this.scrollInterval=null}},_scroll:function(a,e){var c=new Date(),d=c-this.lastScrolled,b=this.options.scroll;this.lastScrolled=c;b.scrollTop+=e*d/1000},_setContents:function(c,a,e){var d=document.viewport.getDimensions(),b=c.getDimensions();if((a+b.width>d.width)||(e+b.height>d.height)){c.hide()}else{c.setStyle({left:a+"px",top:e+"px"}).show()}}}),Drop=Class.create({initialize:function(a){this.element=$(a);this.options=Object.extend({accept:[],caption:"",hoverclass:"",onDrop:null,onOut:null,onOver:null},arguments[1]||{});this.mouseoverE=this._mouseOver.bindAsEventListener(this);this.mouseoutE=this._mouseOut.bindAsEventListener(this);this.element.observe("mouseover",this.mouseoverE);this.element.observe("mouseout",this.mouseoutE);DragDrop.Drops.register(this)},destroy:function(){this.element.stopObserving("mouseover",this.mouseoverE);this.element.stopObserving("mouseout",this.mouseoutE);DragDrop.Drops.unregister(this)},_mouseOver:function(a){if(DragDrop.Drags.drag){DragDrop.Drops.drop=this;if(Object.isFunction(this.options.onOver)){this.options.onOver(this.element,DragDrop.Drags.drag)}}},_mouseOut:function(a){if(Object.isFunction(this.options.onOut)){this.options.onOut(this.element,DragDrop.Drags.drag)}DragDrop.Drops.drop=null}}); \ No newline at end of file +var DragDrop={Drags:{drags:$H(),register:function(a){if(!this.div){this.div=new Element("DIV",{className:a.options.classname}).hide();$(document.body).insert(this.div);document.observe("mousedown",this._mouseHandler.bindAsEventListener(this))}this.drags.set(a.element.identify(),a);a.element.addClassName("DragElt")},unregister:function(a){if(this.drag==a.element){this.drag.deactivate()}this.drags.unset(a.element.identify());a.element.removeClassName("DragElt")},get_drag:function(a){return this.drags.get(Object.isElement(a)?$(a).identify():a)},activate:function(a){if(this.drag){this.deactivate()}this.drag=a;this.mousemoveE=a._mouseMove.bindAsEventListener(a);this.mouseupE=a._mouseUp.bindAsEventListener(a);document.observe("mousemove",this.mousemoveE);document.observe("mouseup",this.mouseupE)},deactivate:function(){if(this.drag){this.drag=null;document.stopObserving("mousemove",this.mousemoveE);document.stopObserving("mouseup",this.mouseupE)}},_mouseHandler:function(b){var a=b.element();if(this.drags.size()){if(!a.hasClassName("DragElt")){a=a.up(".DragElt")}if(a){this.get_drag(a).mouseDown(b)}}}},Drops:{drops:$H(),init:false,register:function(a){if(!this.init){document.observe("mouseover",this._mouseHandler.bindAsEventListener(this,"over"));document.observe("mouseout",this._mouseHandler.bindAsEventListener(this,"out"));this.init=true}this.drops.set(a.element.identify(),a);a.element.addClassName("DropElt")},unregister:function(a){if(this.drop==a.element){this.drop=null}this.drops.unset(a.element.identify());a.element.addClassName("DropElt")},get_drop:function(a){return this.drops.get(Object.isElement(a)?$(a).identify():a)},_mouseHandler:function(c,b){var a=c.element();if(this.drops.size()){if(!a.hasClassName("DropElt")){a=a.up(".DropElt")}if(a){switch(b){case"over":this.get_drop(a).mouseOver(c);break;case"out":this.get_drop(a).mouseOut(c);break}}}}},validDrop:function(a){var b=DragDrop.Drops.drop;return(b&&a&&a!=b.element&&(!b.options.accept.size()||b.options.accept.include(a.tagName)))}},Drag=Class.create({initialize:function(a){this.element=$(a);this.options=Object.extend({caption:"",classname:"drag",constraint:null,ghosting:false,scroll:null,snap:null,threshold:0,onDrag:null,onEnd:null,onStart:null},arguments[1]||{});if(this.options.scroll){this.options.scroll=$(this.options.scroll)}DragDrop.Drags.register(this);if(Prototype.Browser.IE){this.element.observe("selectstart",Event.stop)}else{if(Prototype.Browser.Gecko){this.element.setStyle({MozUserSelect:"none"})}}},destroy:function(){DragDrop.Drags.unregister(this)},mouseDown:function(a){$(document.body).setStyle({cursor:"default"});DragDrop.Drags.activate(this);this.move=0;this.wasDragged=false;this.lastcaption=null;if(Object.isFunction(this.options.onStart)){this.options.onStart(this,a)}if(!Prototype.Browser.IE&&!Prototype.Browser.Gecko){a.stop()}},_mouseMove:function(f){var b,c,a,d;if(++this.move<=this.options.threshold){return}this.lastCoord=d=[f.pointerX(),f.pointerY()];if(this.options.ghosting){if(!this.ghost){b=this.element.offsetLeft;c=this.element.offsetTop;this.ghost=$(this.element.cloneNode(true)).writeAttribute("id",null).setOpacity(0.7).clonePosition(this.element,{setLeft:false,setTop:false}).setStyle({left:b+"px",position:"absolute",top:c+"px",zIndex:parseInt(this.element.getStyle("zIndex"))+1});this.element.insert({before:this.ghost});a=this.ghost.viewportOffset();this.ghostOffset=[a[0]-b,a[1]-c]}d[0]-=this.ghostOffset[0];d[1]-=this.ghostOffset[1];switch(this.options.constraint){case"horizontal":d[1]=this.ghost.offsetTop;break;case"vertical":d[0]=this.ghost.offsetLeft;break}if(this.options.snap){d=this.options.snap(d[0],d[1],this.element)}if(this.options.offset){d[0]+=this.options.offset.x;d[1]+=this.options.offset.y}this._setContents(this.ghost,d[0],d[1])}this._onMoveDrag(d,f);if(Object.isFunction(this.options.onDrag)){this.options.onDrag(this,f)}this.wasDragged=true;if(this.options.scroll){this._onMoveScroll()}},_mouseUp:function(a){var b=DragDrop.Drops.drop;this._stopScrolling();if(this.ghost){this.ghost.remove();this.ghost=null}DragDrop.Drags.div.hide();if(DragDrop.validDrop(this.element)&&Object.isFunction(b.options.onDrop)){b.options.onDrop(b.element,this.element,a)}DragDrop.Drags.deactivate();if(Object.isFunction(this.options.onEnd)){this.options.onEnd(this,a)}},_onMoveDrag:function(k,g){var i,j,f,c,h=DragDrop.Drops.drop,a=DragDrop.Drags.div,b=true;if(h&&DragDrop.validDrop(this.element)){c=h.options.caption;if(c){j=Object.isFunction(c)?c(h.element,this.element,g):c;if(j&&h.options.hoverclass){f=h.options.hoverclass}}else{b=false}}if(b){if(!j){i=this.options.caption;j=Object.isFunction(i)?i(this.element):i}if(j!=this.lastcaption){this.lastcaption=j;a.update(j).writeAttribute({className:f||this.options.classname});if(j.empty()){a.hide()}}}if(!this.lastcaption.empty()){this._setContents(a,k[0]+15,k[1]+(this.ghost?(this.ghost.getHeight()+5):5))}},_onMoveScroll:function(){this._stopScrolling();var e,d,b,a=this.options.scroll,c=a.getDimensions();if(a.scrollHeight==c.height){return}e=document.viewport.getScrollOffsets();d=a.viewportOffset(),b=[0,0];d[0]+=a.scrollLeft+e.left;d[2]=d[0]+c.width;if(this.lastCoord[0]>d[2]||this.lastCoord[0]d[3]){b[1]=this.lastCoord[1]-d[3]}if(b[0]||b[1]){this.lastScrolled=new Date();this.scrollInterval=setInterval(this._scroll.bind(this,b[0]*15,b[1]*15),10)}},_stopScrolling:function(){if(this.scrollInterval){clearInterval(this.scrollInterval);this.scrollInterval=null}},_scroll:function(a,e){var c=new Date(),d=c-this.lastScrolled,b=this.options.scroll;this.lastScrolled=c;b.scrollTop+=e*d/1000},_setContents:function(c,a,e){var d=document.viewport.getDimensions(),b=c.getDimensions();if((a+b.width>d.width)||(e+b.height>d.height)){c.hide()}else{c.setStyle({left:a+"px",top:e+"px"}).show()}}}),Drop=Class.create({initialize:function(a){this.element=$(a);this.options=Object.extend({accept:[],caption:"",hoverclass:"",onDrop:null,onOut:null,onOver:null},arguments[1]||{});DragDrop.Drops.register(this)},destroy:function(){DragDrop.Drops.unregister(this)},mouseOver:function(a){if(DragDrop.Drags.drag){DragDrop.Drops.drop=this;if(Object.isFunction(this.options.onOver)){this.options.onOver(this.element,DragDrop.Drags.drag)}}},mouseOut:function(a){if(DragDrop.Drags.drag){if(Object.isFunction(this.options.onOut)){this.options.onOut(this.element,DragDrop.Drags.drag)}DragDrop.Drops.drop=null}}}); \ No newline at end of file diff --git a/imp/js/src/dragdrop.js b/imp/js/src/dragdrop.js index 2d683e520..fc5bbd802 100644 --- a/imp/js/src/dragdrop.js +++ b/imp/js/src/dragdrop.js @@ -63,7 +63,8 @@ * * Copyright 2008-2009 The Horde Project (http://www.horde.org/) * - * @author Michael Slusarz + * @author Michael Slusarz + * @package IMP */ var DragDrop = { @@ -72,14 +73,14 @@ var DragDrop = { register: function(obj) { - if (!this.drags.size()) { - if (!this.div) { - this.div = new Element('DIV', { className: obj.options.classname }).hide(); - } + if (!this.div) { + this.div = new Element('DIV', { className: obj.options.classname }).hide(); $(document.body).insert(this.div); + document.observe('mousedown', this._mouseHandler.bindAsEventListener(this)); } this.drags.set(obj.element.identify(), obj); + obj.element.addClassName('DragElt'); }, unregister: function(obj) @@ -89,10 +90,7 @@ var DragDrop = { } this.drags.unset(obj.element.identify()); - - if (!this.drags.size() && this.div) { - this.div.remove(); - } + obj.element.removeClassName('DragElt'); }, get_drag: function(el) @@ -119,15 +117,36 @@ var DragDrop = { document.stopObserving('mousemove', this.mousemoveE); document.stopObserving('mouseup', this.mouseupE); } + }, + + _mouseHandler: function(e) + { + var elt = e.element(); + + if (this.drags.size()) { + if (!elt.hasClassName('DragElt')) { + elt = elt.up('.DragElt'); + } + if (elt) { + this.get_drag(elt).mouseDown(e); + } + } } }, Drops: { drops: $H(), + init: false, register: function(obj) { + if (!this.init) { + document.observe('mouseover', this._mouseHandler.bindAsEventListener(this, 'over')); + document.observe('mouseout', this._mouseHandler.bindAsEventListener(this, 'out')); + this.init = true; + } this.drops.set(obj.element.identify(), obj); + obj.element.addClassName('DropElt'); }, unregister: function(obj) @@ -137,11 +156,35 @@ var DragDrop = { } this.drops.unset(obj.element.identify()); + obj.element.addClassName('DropElt'); }, get_drop: function(el) { return this.drops.get(Object.isElement(el) ? $(el).identify() : el); + }, + + _mouseHandler: function(e, type) + { + var elt = e.element(); + + if (this.drops.size()) { + if (!elt.hasClassName('DropElt')) { + elt = elt.up('.DropElt'); + } + + if (elt) { + switch (type) { + case 'over': + this.get_drop(elt).mouseOver(e); + break; + + case 'out': + this.get_drop(elt).mouseOut(e); + break; + } + } + } } }, @@ -172,8 +215,6 @@ Drag = Class.create({ onEnd: null, onStart: null }, arguments[1] || {}); - this.mousedownE = this._mouseDown.bindAsEventListener(this); - this.element.observe('mousedown', this.mousedownE); if (this.options.scroll) { this.options.scroll = $(this.options.scroll); } @@ -193,11 +234,10 @@ Drag = Class.create({ destroy: function() { - this.element.stopObserving('mousedown', this.mousedownE); DragDrop.Drags.unregister(this); }, - _mouseDown: function(e) + mouseDown: function(e) { $(document.body).setStyle({ cursor: 'default' }); DragDrop.Drags.activate(this); @@ -433,21 +473,15 @@ Drop = Class.create({ onOut: null, onOver: null }, arguments[1] || {}); - this.mouseoverE = this._mouseOver.bindAsEventListener(this); - this.mouseoutE = this._mouseOut.bindAsEventListener(this); - this.element.observe('mouseover', this.mouseoverE); - this.element.observe('mouseout', this.mouseoutE); DragDrop.Drops.register(this); }, destroy: function() { - this.element.stopObserving('mouseover', this.mouseoverE); - this.element.stopObserving('mouseout', this.mouseoutE); DragDrop.Drops.unregister(this); }, - _mouseOver: function(e) + mouseOver: function(e) { if (DragDrop.Drags.drag) { DragDrop.Drops.drop = this; @@ -457,11 +491,13 @@ Drop = Class.create({ } }, - _mouseOut: function(e) + mouseOut: function(e) { - if (Object.isFunction(this.options.onOut)) { - this.options.onOut(this.element, DragDrop.Drags.drag); + if (DragDrop.Drags.drag) { + if (Object.isFunction(this.options.onOut)) { + this.options.onOut(this.element, DragDrop.Drags.drag); + } + DragDrop.Drops.drop = null; } - DragDrop.Drops.drop = null; } });