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)


Reply via email to