Update element() to reflect new Event handling model
authorMichael M Slusarz <slusarz@curecanti.org>
Sun, 18 Jan 2009 01:25:28 +0000 (18:25 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Sun, 18 Jan 2009 01:25:28 +0000 (18:25 -0700)
Since there is no guarantee which order document-wide events are
processed, it is possible that by the time an event handler deals with
an event, the contextmenu has already been closed. Therefore, we need to
keep information on the last opened menu for element() purposes.

imp/js/ContextSensitive.js
imp/js/src/ContextSensitive.js

index c973386..5735c54 100644 (file)
@@ -1 +1 @@
-var ContextSensitive=Class.create({initialize:function(){this.current=this.target=null;this.elements=$H();document.observe("contextmenu",this.rightClickHandler.bindAsEventListener(this));document.observe("click",this.leftClickHandler.bindAsEventListener(this));document.observe(Prototype.Browser.Gecko?"DOMMouseScroll":"mousescroll",this.close.bind(this))},addElement:function(d,c,a){var b=Boolean(a.left);if(d&&!this.validElement(d,b)){this.elements.set(d+Number(b),new ContextSensitive.Element(d,c,a))}},removeElement:function(a){this.elements.unset(a+"0");this.elements.unset(a+"1")},close:function(a){if(this.current){if(a){this.current.hide()}else{Effect.Fade(this.current,{duration:0.2})}this.current=this.target=null}},element:function(){return this.target},currentmenu:function(){if(this.current&&this.current.visible()){return this.current}},validElement:function(b,a){return this.elements.get(b+Number(Boolean(a)))},disable:function(d,c,a){var b=this.validElement(d,c);if(b){b.disable=a}},leftClickHandler:function(a){if(a.isRightClick()){return}this.rightClickHandler(a,true)},rightClickHandler:function(b,a){if(this.trigger(b.element(),a,b.pointerX(),b.pointerY())){b.stop()}},trigger:function(f,e,h,g){var j,b,d,c,k,i,a;[f].concat(f.ancestors()).find(function(l){j=this.validElement(l.id,e);return j},this);if(!j||j.disable){this.close();return false}b=$(j.ctx);if(!b){this.close();return false}else{if(e&&b==this.current){return false}}this.current=b;this.target=$(j.id);d=j.opts.offset;if(!d&&(Object.isUndefined(h)||Object.isUndefined(g))){d=f.id}d=$(d);if(d){c=d.viewportOffset();a=document.viewport.getScrollOffsets();h=c[0]+a.left;g=c[1]+d.getHeight()+a.top}i=document.viewport.getDimensions();k=b.getDimensions();if((g+k.height)>i.height){g=i.height-k.height-10}if((h+k.width)>i.width){h=i.width-k.width-10}if(j.opts.onShow){j.opts.onShow(j)}Effect.Appear(b.setStyle({left:h+"px",top:g+"px"}),{duration:0.2});return true}});ContextSensitive.Element=Class.create({initialize:function(c,b,a){this.id=c;this.ctx=b;this.opts=a;this.opts.left=Boolean(a.left);this.disable=false}});
\ No newline at end of file
+var ContextSensitive=Class.create({initialize:function(){this.current=this.lasttarget=this.target=null;this.elements=$H();document.observe("contextmenu",this.rightClickHandler.bindAsEventListener(this));document.observe("click",this.leftClickHandler.bindAsEventListener(this));document.observe(Prototype.Browser.Gecko?"DOMMouseScroll":"mousescroll",this.close.bind(this))},addElement:function(d,c,a){var b=Boolean(a.left);if(d&&!this.validElement(d,b)){this.elements.set(d+Number(b),new ContextSensitive.Element(d,c,a))}},removeElement:function(a){this.elements.unset(a+"0");this.elements.unset(a+"1")},close:function(a){if(this.current){if(a){this.current.hide()}else{Effect.Fade(this.current,{duration:0.2})}this.current=this.target=null}},element:function(a){return a?this.target:this.lasttarget},currentmenu:function(){if(this.current&&this.current.visible()){return this.current}},validElement:function(b,a){return this.elements.get(b+Number(Boolean(a)))},disable:function(d,c,a){var b=this.validElement(d,c);if(b){b.disable=a}},leftClickHandler:function(a){if(a.isRightClick()){return}this.rightClickHandler(a,true)},rightClickHandler:function(b,a){if(this.trigger(b.element(),a,b.pointerX(),b.pointerY())){b.stop()}},trigger:function(f,e,h,g){var j,b,d,c,k,i,a;[f].concat(f.ancestors()).find(function(l){j=this.validElement(l.id,e);return j},this);if(!j||j.disable){this.close();return false}b=$(j.ctx);if(!b){this.close();return false}else{if(e&&b==this.current){return false}}this.current=b;this.lasttarget=this.target=$(j.id);d=j.opts.offset;if(!d&&(Object.isUndefined(h)||Object.isUndefined(g))){d=f.id}d=$(d);if(d){c=d.viewportOffset();a=document.viewport.getScrollOffsets();h=c[0]+a.left;g=c[1]+d.getHeight()+a.top}i=document.viewport.getDimensions();k=b.getDimensions();if((g+k.height)>i.height){g=i.height-k.height-10}if((h+k.width)>i.width){h=i.width-k.width-10}if(j.opts.onShow){j.opts.onShow(j)}Effect.Appear(b.setStyle({left:h+"px",top:g+"px"}),{duration:0.2});return true}});ContextSensitive.Element=Class.create({initialize:function(c,b,a){this.id=c;this.ctx=b;this.opts=a;this.opts.left=Boolean(a.left);this.disable=false}});
\ No newline at end of file
index c13abea..290222c 100644 (file)
@@ -32,7 +32,7 @@ var ContextSensitive = Class.create({
 
     initialize: function()
     {
-        this.current = this.target = null;
+        this.current = this.lasttarget = this.target = null;
         this.elements = $H();
 
         document.observe('contextmenu', this.rightClickHandler.bindAsEventListener(this));
@@ -78,9 +78,9 @@ var ContextSensitive = Class.create({
     /**
      * Get the element that triggered the current context menu (if any).
      */
-    element: function()
+    element: function(current)
     {
-        return this.target;
+        return current ? this.target : this.lasttarget;
     },
 
     /**
@@ -170,7 +170,7 @@ var ContextSensitive = Class.create({
         // Register the current element that will be shown and the
         // element that was clicked on.
         this.current = el;
-        this.target = $(ctx.id);
+        this.lasttarget = this.target = $(ctx.id);
 
         // Get the base element positions.
         offset = ctx.opts.offset;