You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jc...@apache.org on 2009/03/17 10:55:14 UTC

svn commit: r755172 - /wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js

Author: jcompagner
Date: Tue Mar 17 09:55:13 2009
New Revision: 755172

URL: http://svn.apache.org/viewvc?rev=755172&view=rev
Log:
reset focus fixes, try not to call focus on components that are not replaced

Modified:
    wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js

Modified: wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js
URL: http://svn.apache.org/viewvc/wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js?rev=755172&r1=755171&r2=755172&view=diff
==============================================================================
--- wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js (original)
+++ wicket/branches/wicket-1.3.x/jdk-1.4/wicket/src/main/java/org/apache/wicket/ajax/wicket-ajax.js Tue Mar 17 09:55:13 2009
@@ -1088,7 +1088,7 @@
 			// iinitialize the array for steps (closures that execute each action)
 		    var steps = new Array();
 
-		   // start it a bit later so that the browser does handle the next event 
+		   	// start it a bit later so that the browser does handle the next event 
 		   // before the component is or can be replaced. We could do (if (!posponed))
 		   // because if there is already something in the queue then we could execute that immedietly 
 			steps.push(function(notify) {
@@ -1107,11 +1107,16 @@
 			
 			// go through the ajax response and for every action (component, js evaluation, header contribution)
 			// ad the proper closure to steps
+			var stepIndexOfLastReplacedComponent = -1;
 		    for (var i = 0; i < root.childNodes.length; ++i) {
 		    	var node = root.childNodes[i];				
 
 		        if (node.tagName == "component") {
-		           this.processComponent(steps, node);
+					if (stepIndexOfLastReplacedComponent == -1) {
+						this.processFocusedComponentMark(steps);
+					}
+					stepIndexOfLastReplacedComponent = steps.length;
+					this.processComponent(steps, node);
 		        } else if (node.tagName == "evaluate") {
 		           this.processEvaluation(steps, node);
 		        } else if (node.tagName == "header-contribution") {
@@ -1119,6 +1124,9 @@
 		        }
 		        
 		    }
+			if (stepIndexOfLastReplacedComponent != -1) {
+				this.processFocusedComponentReplaceCheck(steps, stepIndexOfLastReplacedComponent);
+			}
 
 			// add the last step, which should trigger the success call the done method on request
 			this.success(steps);
@@ -1234,6 +1242,27 @@
 	processHeaderContribution: function(steps, node) {
 		var c = new Wicket.Head.Contributor();
 		c.processContribution(steps, node);
+	},
+
+	// mark the focused component so that we know if it has been replaced by response
+	processFocusedComponentMark: function(steps) {
+		steps.push(function(notify) {
+			Wicket.Focus.markFocusedComponent();
+
+			// continue to next step
+			notify();
+		});
+	},
+
+	// detect if the focused component was replaced
+	processFocusedComponentReplaceCheck: function(steps, lastReplaceComponentStep) {
+		// add this step imediately after all components have been replaced
+		steps.splice(lastReplaceComponentStep + 1, 0, function(notify) {
+			Wicket.Focus.checkFocusedComponentReplaced();
+
+			// continue to next step
+			notify();
+		});
 	}
 };
 
@@ -1991,6 +2020,8 @@
 
 Wicket.Focus = {
 	lastFocusId : "",
+	refocusLastFocusedComponentAfterResponse : false,
+	focusSetFromServer : false,
 
 	setFocus: function(event)
 	{ 
@@ -2000,6 +2031,7 @@
 	    // Use "srcElement" instead.
 	    var target = event.target ? event.target : event.srcElement;
 	    if (target) {
+			Wicket.Focus.refocusLastFocusedComponentAfterResponse = false;
 			Wicket.Focus.lastFocusId=target.id;
 			Wicket.Log.info("focus set on " + Wicket.Focus.lastFocusId);
 		}
@@ -2013,17 +2045,16 @@
 	    // Use "srcElement" instead.
 	    var target = event.target ? event.target : event.srcElement;
 	    if (target && Wicket.Focus.lastFocusId==target.id) {
-			Wicket.Focus.lastFocusId=null;
-			Wicket.Log.info("focus removed from " + target.id);
+			if (Wicket.Focus.refocusLastFocusedComponentAfterResponse) {
+				// replaced components seem to blur when replaced only on Safari - so do not modify lastFocusId so it gets refocused
+				Wicket.Log.info("focus removed from " + target.id + " but ignored because of component replacement");
+			} else {
+				Wicket.Focus.lastFocusId=null;
+				Wicket.Log.info("focus removed from " + target.id);
+			}
 		}
 	},
 	
-	setFocusOnId: function(id)
-	{
-		Wicket.Focus.lastFocusId=id;
-		Wicket.Log.info("focus set on " + Wicket.Focus.lastFocusId + " from serverside");
-	},
-	
 	getFocusedElement: function()
 	{
 		if (typeof(Wicket.Focus.lastFocusId) != "undefined" && Wicket.Focus.lastFocusId != "" && Wicket.Focus.lastFocusId != null)
@@ -2034,17 +2065,72 @@
 		return;
 	},
 
+	setFocusOnId: function(id)
+	{
+		if (typeof(id) != "undefined" && id != "" && id != null) {
+			Wicket.Focus.refocusLastFocusedComponentAfterResponse = true;
+			Wicket.Focus.focusSetFromServer = true;
+			Wicket.Focus.lastFocusId=id;
+			Wicket.Log.info("focus set on " + Wicket.Focus.lastFocusId + " from serverside");
+		} else {
+			Wicket.Focus.refocusLastFocusedComponentAfterResponse = false;
+			Wicket.Log.info("refocus focused component after request stopped from serverside");
+		}
+	},
+	
+	// mark the focused component so that we know if it has been replaced or not by response
+	markFocusedComponent: function()
+	{
+		var focusedElement = Wicket.Focus.getFocusedElement();
+		if (typeof(focusedElement) != "undefined" && focusedElement != null) {
+			focusedElement.wasFocusedBeforeComponentReplacements = true; // create a property of the focused element that would not remain there if component is replaced
+			Wicket.Focus.refocusLastFocusedComponentAfterResponse = true;
+			Wicket.Focus.focusSetFromServer = false;
+		} else {
+			Wicket.Focus.refocusLastFocusedComponentAfterResponse = false;
+		}
+	},
+
+	// detect if the focused component was replaced
+	checkFocusedComponentReplaced: function()
+	{
+		var focusedElement = Wicket.Focus.getFocusedElement();
+		if (Wicket.Focus.refocusLastFocusedComponentAfterResponse == true)
+		{
+			if (typeof(focusedElement) != "undefined" && focusedElement != null) {
+				if (typeof(focusedElement.wasFocusedBeforeComponentReplacements) != "undefined")
+				{
+					// focus component was not replaced - no need to refocus it
+					Wicket.Focus.refocusLastFocusedComponentAfterResponse = false;
+				}
+			} else {
+				// focused component dissapeared completely - no use to try to refocus it
+				Wicket.Focus.refocusLastFocusedComponentAfterResponse = false;
+				Wicket.Focus.lastFocusId = "";
+			}
+		}
+	},
 	
 	requestFocus: function()
 	{
-		if (typeof(Wicket.Focus.lastFocusId) != "undefined" && Wicket.Focus.lastFocusId != "" && Wicket.Focus.lastFocusId != null)
+		// if the focused component is replaced by the ajax response, a re-focus might be needed (if focus was not changed from server)
+		// but if not, and the focus component should remain the same, do not re-focus - fixes problem on IE6 for combos that have the popup open (refocusing closes popup)
+		if (Wicket.Focus.refocusLastFocusedComponentAfterResponse && typeof(Wicket.Focus.lastFocusId) != "undefined" && Wicket.Focus.lastFocusId != "" && Wicket.Focus.lastFocusId != null)
 		{ 
 			var toFocus = Wicket.$(Wicket.Focus.lastFocusId);
 			
 			if (toFocus != null && typeof(toFocus) != "undefined") {
 				Wicket.Log.info("Calling focus on " + Wicket.Focus.lastFocusId);
 				try {
-					toFocus.focus();
+					if (Wicket.Focus.focusSetFromServer) {
+						toFocus.focus();
+					} else {
+						// avoid loops like - onfocus triggering an event the modifies the tag => refocus => the event is triggered again
+						var temp = toFocus.onfocus;
+						toFocus.onfocus = null;
+						toFocus.focus();
+						setTimeout(function() { toFocus.onfocus = temp; }, 0);	// IE needs setTimeout (it seems not to call onfocus sync. when focus() is called
+					}
 				} catch (ignore) {
 				}
 			}
@@ -2054,10 +2140,15 @@
 				Wicket.Log.info("Couldn't set focus on " + Wicket.Focus.lastFocusId + " not on the page anymore");
 			}
 		}
-		else
+		else if (Wicket.Focus.refocusLastFocusedComponentAfterResponse)
 		{
 			Wicket.Log.info("last focus id was not set");
 		}
+		else
+		{
+			Wicket.Log.info("refocus last focused component not needed/allowed");
+		}
+		Wicket.Focus.refocusLastFocusedComponentAfterResponse = false;
 	},
 	
 	setFocusOnElements: function (elements)