You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xap-commits@incubator.apache.org by jm...@apache.org on 2007/04/13 06:01:09 UTC

svn commit: r528368 - /incubator/xap/trunk/codebase/src/xap/bridges/basic/AbstractWidgetBridge.js

Author: jmargaris
Date: Thu Apr 12 23:01:07 2007
New Revision: 528368

URL: http://svn.apache.org/viewvc?view=rev&rev=528368
Log:
From dgennaco: http://issues.apache.org/jira/browse/XAP-375

Modified:
    incubator/xap/trunk/codebase/src/xap/bridges/basic/AbstractWidgetBridge.js

Modified: incubator/xap/trunk/codebase/src/xap/bridges/basic/AbstractWidgetBridge.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/bridges/basic/AbstractWidgetBridge.js?view=diff&rev=528368&r1=528367&r2=528368
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/bridges/basic/AbstractWidgetBridge.js (original)
+++ incubator/xap/trunk/codebase/src/xap/bridges/basic/AbstractWidgetBridge.js Thu Apr 12 23:01:07 2007
@@ -183,6 +183,19 @@
 	var eqq =  (typ== xap.bridges.basic.AbstractWidgetBridge.FUNCTION) ;
 	return eqq ;
 }
+
+/** 
+ * @private
+ * Start tracking mouseenter/mouseleave state for this component.
+ */
+xap.bridges.basic.AbstractWidgetBridge.prototype._trackMouseOver = function() {
+    if (!this._mouseTracking) {
+        var rootNode = this.getRootDomNode();
+    	dojo.event.connect(rootNode, this._onEnter, this, "onMouseOver");
+    	dojo.event.connect(rootNode, this._onLeave, this, "onMouseOut");
+    	this._mouseTracking = true;
+	}
+}
 	
 /**
  *   Actually now more like <code>processPeer</code>, since it now
@@ -270,17 +283,16 @@
 
 		
 		/* only setup mouse events if they're needed, use the IE specific ones on IE */
-		if ( this._wantsMouseEvents ) {
-			if (dojo.render.html.ie) {
+		if (dojo.render.html.ie) {
 				this._onEnter = "onmouseenter";
 				this._onLeave = "onmouseleave";
-			}
-			else {
+		}
+		else {
 				this._onEnter = "onmouseover";
 				this._onLeave = "onmouseout";
-			}
-			dojo.event.connect(rootNode, this._onEnter, this, "onMouseOver");
-			dojo.event.connect(rootNode, this._onLeave, this, "onMouseOut");
+		}
+		if ( this._wantsMouseEvents ) {
+		    this._trackMouseOver();
 			dojo.event.connect(rootNode,"onmousedown", this, "onMouseDown");
 			dojo.event.connect(rootNode,"onmouseup", this, "onMouseUp");
 		}
@@ -649,7 +661,7 @@
 		"fontStyle","fontWeight", "fontSize", "textAlign",
 		"popup","tooltip", "focused", "disabled","visible",
 		"onActiveGained","onActiveLost","onDoubleClick","onKeyDown",
-		"onKeyUp","onKeyPress","onMouseDown","onMouseUp"];
+		"onKeyUp","onKeyChar","onMouseDown","onMouseUp","onMouseMove","onMouseOver","onMouseOut"];
 };
 
 
@@ -726,21 +738,45 @@
 	dojo.event.connectOnce(this.getRootDomNode(),"onkeyup", this, "onKeyUp");
 };
 
-xap.bridges.basic.AbstractWidgetBridge.prototype.setOnKeyPressAttribute = function(value) {
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnKeyCharAttribute = function(value) {
 	// connect event, discard value
-	dojo.event.connectOnce(this.getRootDomNode(),"onkeypress", this, "onKeyPress");
+	dojo.event.connectOnce(this.getRootDomNode(),"onkeypress", this, "onKeyChar");
 };
 
 xap.bridges.basic.AbstractWidgetBridge.prototype.setOnMouseDownAttribute = function(value) {
 	// connect event, discard value
-	dojo.event.connectOnce(this.getRootDomNode(),"onmousedown", this, "onMouseDown");
+	if (!this._wantsMouseEvents) {
+    	// Even if we don't want mouse events, if an onMouseDown is registered we should 
+	    // connect the event to fire the user code
+	    dojo.event.connectOnce(this.getRootDomNode(),"onmousedown", this, "onMouseDown");
+	}
 };
 
 xap.bridges.basic.AbstractWidgetBridge.prototype.setOnMouseUpAttribute = function(value) {
 	// connect event, discard value
-	dojo.event.connectOnce(this.getRootDomNode(),"onmouseup", this, "onMouseUp");
+	if (!this._wantsMouseEvents) {
+    	// Even if we don't want mouse events, if an onMouseUp is registered we should 
+	    // connect the event to fire the user code
+    	dojo.event.connectOnce(this.getRootDomNode(),"onmouseup", this, "onMouseUp");
+    }
 };
 
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnMouseMoveAttribute = function(value) {
+	// connect event, discard value
+	dojo.event.connectOnce(this.getRootDomNode(),"onmousemove", this, "onMouseMove");
+};
+
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnMouseOverAttribute = function(value) {
+   	// Even if we don't want mouse events, if an onMouseOver is registered we should 
+	// connect mouse tracking events (for mouse enter and leave)
+    this._trackMouseOver();
+};
+
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnMouseOutAttribute = function(value) {
+   	// Even if we don't want mouse events, if an onMouseOut is registered we should 
+	// connect mouse tracking events (for mouse enter and leave)
+    this._trackMouseOver();
+};
 
 /** XML attribute set methods for onXXX end */
 
@@ -1112,50 +1148,68 @@
 	}
 }
 
-xap.bridges.basic.AbstractWidgetBridge.prototype.onMouseOver= function(e){
-	
-	/* add the style - disconnect the mouse move event and set us into MouseOver style */
-	if (!this._disabled && !this._isMouseOver){
-		this.addStyleState("MouseOver");
-		this._isMouseOver = true;
-		dojo.event.disconnect(this.getRootDomNode(), this._onEnter, this, "onMouseOver");
+xap.bridges.basic.AbstractWidgetBridge.prototype.onMouseMove = function(e){
+	if (!this._disabled){
+		this.fireMouseEvent("onMouseMove",e);
+		// prevent event from bubbling up to parent.
 		this.stopEvent(e);
 	}
 }
 
-xap.bridges.basic.AbstractWidgetBridge.prototype.onMouseOut= function(e){
+xap.bridges.basic.AbstractWidgetBridge.prototype.onMouseOver= function(e){
 	
-	//if we did not get the mouseout on us we could have gotten
-	//it moving from one descendent to another, so check for that.
-	//In that case we are still in the mouseOver style as the mouse just
-	//moved internally. This is only an issue in IE
-	/*
-	OBSOLETE - We're now using OnmouseEnter and onmouseleave on IE
-	if (e.srcElement && e.srcElement != this.getRootDomNode())
-		if (e.toElement){
-			var element = e.toElement;
-			while(element && (element!=this.getRootDomNode()) ){
-				element = element.parentNode;
-			}
-			
-			//broke because the mouse out was us, so don't bother removing
-			//the style
-			if (element){
-				return;
-			}
-		}
-	//TODO fire event?
-	*/	
+   	if (!this._disabled && !this._isMouseOver){
+   		// style state should not be added if !this._wantsMouseEvents
+   		if (this._wantsMouseEvents) {
+   			this.addStyleState("MouseOver");
+   		}
+   		this._isMouseOver = true;
+   		dojo.event.disconnect(this.getRootDomNode(), this._onEnter, this, "onMouseOver");
+   		this.fireMouseEvent("onMouseOver", e);
+   		this.stopEvent(e);
+   	}
+}
 
+xap.bridges.basic.AbstractWidgetBridge.prototype.onMouseOut= function(e){
+	
 	/* only if we are in MouseOver state - remove the style and reconnect the mouse move */
-	if (!this._disabled && this._isMouseOver){
-		this._isMouseOver = false;
-		this.removeStyleState("MouseOver");
-		dojo.event.connect(this.getRootDomNode(), this._onEnter, this, "onMouseOver");
-		this.stopEvent(e);
-	}
+   	if (!this._disabled && this._isMouseOver){
+   	
+   	    // Since there is not equivalent of "onmouseenter" and "onmouseleave" outside of
+   	    // IE at this time, we must determine whether or not we are truly being moused out
+   	    // of, that is, the mouse is moving somewhere "out" of us and also not "into" one of
+   	    // our children or descendants
+	    if (e.relatedTarget) {
+	        // In window, it actually can be "exiting" and "entering" the window at the 
+	        // same time when it goes from one inner div area to another!
+	        if (e.relatedTarget === e.currentTarget) {
+	            return;
+	        }
+	        
+	    	var targetAncestor = e.relatedTarget.parentNode;
+	    	while (targetAncestor != null) { // TODO can this be optimized somehow?
+	    		if (targetAncestor === e.currentTarget) {
+	    			return; // ITS MOVING OUT OF US, BUT INTO OUR PROGENY, SO NOT REALLY OUT!
+	    		}
+	    		targetAncestor = targetAncestor.parentNode;
+	    	}
+	    }
+		     
+   		this._isMouseOver = false;
+   		
+   		// style state should not be added if !this._wantsMouseEvents
+   		if (this._wantsMouseEvents) {
+   			this.removeStyleState("MouseOver");
+   		}
+   		// reconnect the onmouseover, since the mouse is now officially out of us.
+   		dojo.event.connect(this.getRootDomNode(), this._onEnter, this, "onMouseOver");
+   		
+   		this.fireMouseEvent("onMouseOut", e);
+   		this.stopEvent(e);
+   	}
 }
 
+
 xap.bridges.basic.AbstractWidgetBridge.prototype.onKeyDown = function(e){
 	if (!this._disabled){
 		this.fireKeyEvent("onKeyDown",e);
@@ -1168,9 +1222,9 @@
 	}
 }
 
-xap.bridges.basic.AbstractWidgetBridge.prototype.onKeyPress = function(e){
+xap.bridges.basic.AbstractWidgetBridge.prototype.onKeyChar = function(e){
 	if (!this._disabled){
-		this.fireKeyEvent("onKeyPress",e);
+		this.fireKeyEvent("onKeyChar",e);
 	}
 }
 
@@ -1179,13 +1233,18 @@
 		window.event.returnValue=false;
 		window.event.cancelBubble=true;
 	}
-	else if (evt.getPreventDefault){
+	else if (evt.preventDefault){
 		evt.preventDefault();
 		evt.stopPropagation();
 	}
 }
 
 xap.bridges.basic.AbstractWidgetBridge.prototype.fireMouseEvent = function( eventName, htmlEvent){
+    // optimization, check whether there is an event handler registered and exit fast first
+    if (!this.getElement().getAttribute(eventName)) {
+        return;
+    } 
+    
 	var clientEvent = new xap.session.ClientEvent(this.getElement(),this.getSession());
 	clientEvent.htmlEvent = htmlEvent;
 	
@@ -1200,6 +1259,11 @@
 }
 
 xap.bridges.basic.AbstractWidgetBridge.prototype.fireKeyEvent = function( eventName, htmlEvent){
+    // optimization, check whether there is an event handler registered and exit fast first
+    if (!this.getElement().getAttribute(eventName)) {
+        return;
+    }
+     
 	var clientEvent = new xap.session.ClientEvent(this.getElement(),this.getSession());
 	clientEvent.htmlEvent = htmlEvent;
 	
@@ -1221,8 +1285,6 @@
 xap.bridges.basic.AbstractWidgetBridge.prototype.onAttributeRemoved = function(event){
 	var node = this.getRootDomNode() ;
 	var attributeName = event.getName() ;
-	
-
 	
 	if (this.attributeRemovers[attributeName]){
 		this.attributeRemovers[attributeName].call(this,event) ;