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) ;