You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by jk...@apache.org on 2006/12/14 00:54:02 UTC

svn commit: r486894 - in /tapestry/tapestry4/trunk: tapestry-annotations/src/java/org/apache/tapestry/annotations/ tapestry-annotations/src/test/org/apache/tapestry/annotations/ tapestry-framework/src/java/org/apache/tapestry/internal/event/ tapestry-f...

Author: jkuhnert
Date: Wed Dec 13 15:54:01 2006
New Revision: 486894

URL: http://svn.apache.org/viewvc?view=rev&rev=486894
Log:
Resolves TAPESTRY-1176. Makes forms not get focus by default during EventListener based form updates.

Also cleaned up some old classes/unit tests that hadn't been finished as the result of the last event connection 
related refactoring.

Added:
    tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/ComponentEventPropertyTest.java
    tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/impl/
    tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/impl/ComponentEventInvokerTest.java
      - copied, changed from r486848, tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java
Removed:
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java
    tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java
Modified:
    tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/EventListener.java
    tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/EventListenerAnnotationWorker.java
    tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotatedPage.java
    tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/TestEventListenerAnnotationWorker.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/ComponentEventProperty.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/EventBoundListener.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/IComponentEventInvoker.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/impl/ComponentEventInvoker.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/ComponentSpecification.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/IEventListener.java
    tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/ComponentEventConnectionWorkerTest.java

Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/EventListener.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/EventListener.java?view=diff&rev=486894&r1=486893&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/EventListener.java (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/EventListener.java Wed Dec 13 15:54:01 2006
@@ -66,7 +66,15 @@
      * @return Whether or not to validate the form.
      */
     boolean validateForm() default false;
-
+    
+    /**
+     * Controls whether or not any forms being submitted as part of this event will request focus 
+     * as per normal form semantics. The default is false.
+     * 
+     * @return True if the form should get focus, false otherwise. The default is false.
+     */
+    boolean focus() default false;
+    
     /**
      * If used in conjunction with {@link #submitForm()}, will either submit the form normally or
      * asynchronously. Default is asyncrhonous.

Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/EventListenerAnnotationWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/EventListenerAnnotationWorker.java?view=diff&rev=486894&r1=486893&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/EventListenerAnnotationWorker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/EventListenerAnnotationWorker.java Wed Dec 13 15:54:01 2006
@@ -53,6 +53,7 @@
         String formId = listener.submitForm();
         boolean validateForm = listener.validateForm();
         boolean async = listener.async();
+        boolean focus = listener.focus();
         
         if (targets.length < 1 && elements.length < 1)
             throw new ApplicationRuntimeException(AnnotationMessages.targetsNotFound(method));
@@ -60,7 +61,7 @@
         for (int i=0; i < targets.length; i++) {
             
             spec.addEventListener(targets[i], listener.events(), 
-                    method.getName(), formId, validateForm, async);
+                    method.getName(), formId, validateForm, async, focus);
             
             _invoker.addEventListener(targets[i], spec);
             
@@ -71,7 +72,7 @@
         for (int i=0; i < elements.length; i++) {
             
             spec.addElementEventListener(elements[i], listener.events(), 
-                    method.getName(), formId, validateForm, async);
+                    method.getName(), formId, validateForm, async, focus);
             
             if (formId != null)
                 _invoker.addFormEventListener(formId, spec);

Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotatedPage.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotatedPage.java?view=diff&rev=486894&r1=486893&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotatedPage.java (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotatedPage.java Wed Dec 13 15:54:01 2006
@@ -154,7 +154,7 @@
     @Component(type = "Form", id = "testForm")
     public abstract IForm getForm();
     
-    @EventListener(events = { "onClick" }, targets = { "email" }, submitForm = "testForm")
+    @EventListener(events = { "onClick" }, targets = { "email" }, submitForm = "testForm", focus=true)
     public void formListener() { }
     
     @EventListener(events = { "onClick" }, targets = { "email" }, submitForm = "notExisting")

Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/TestEventListenerAnnotationWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/TestEventListenerAnnotationWorker.java?view=diff&rev=486894&r1=486893&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/TestEventListenerAnnotationWorker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/TestEventListenerAnnotationWorker.java Wed Dec 13 15:54:01 2006
@@ -36,7 +36,7 @@
 public class TestEventListenerAnnotationWorker extends BaseAnnotationTestCase
 {
 
-    public void testEventConnection()
+    public void test_Event_Connection()
     {
         EnhancementOperation op = newOp();
         IComponentSpecification spec = new ComponentSpecification();
@@ -72,9 +72,11 @@
         listeners = property.getEventListeners("onClick");
         assertNotNull(listeners);
         assertEquals(1, listeners.size());
+        
+        assert ((EventBoundListener)listeners.get(0)).shouldFocusForm() == false;
     }
     
-    public void testFormEventConnection()
+    public void test_Form_Event_Connection()
     {
         EnhancementOperation op = newOp();
         IComponentSpecification spec = new ComponentSpecification();
@@ -106,9 +108,10 @@
         EventBoundListener formListener = (EventBoundListener)listeners.get(0);
         assertEquals("testForm", formListener.getFormId());
         assertFalse(formListener.isValidateForm());
+        assert formListener.shouldFocusForm();
     }
     
-    public void testTargetsNotFound()
+    public void test_Targets_Not_Found()
     {
         EnhancementOperation op = newOp();
         IComponentSpecification spec = newSpec();
@@ -132,7 +135,7 @@
         verify();
     }
     
-    public void testCanEnhance()
+    public void test_Can_Enhance()
     {
         EventListenerAnnotationWorker worker = new EventListenerAnnotationWorker();
         

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/ComponentEventProperty.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/ComponentEventProperty.java?view=diff&rev=486894&r1=486893&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/ComponentEventProperty.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/ComponentEventProperty.java Wed Dec 13 15:54:01 2006
@@ -54,11 +54,11 @@
      * @param async 
      */
     public void addListener(String[] events, String methodName, 
-            String formId, boolean validateForm, boolean async)
+            String formId, boolean validateForm, boolean async, boolean focus)
     {
         for (int i=0; i < events.length; i++) {
             if (formId != null && formId.length() > 0)
-                addFormEventListener(events[i], methodName, formId, validateForm, async);
+                addFormEventListener(events[i], methodName, formId, validateForm, async, focus);
             else
                 addEventListener(events[i], methodName);
         }
@@ -72,10 +72,10 @@
      * @param validateForm
      */
     public void addFormEventListener(String event, String methodName,
-            String formId, boolean validateForm, boolean async)
+            String formId, boolean validateForm, boolean async, boolean focus)
     {
         EventBoundListener listener = 
-            new EventBoundListener(methodName, formId, validateForm, _componentId, async);
+            new EventBoundListener(methodName, formId, validateForm, _componentId, async, focus);
         
         List listeners = getFormEventListeners(event);
         if (!listeners.contains(listener))

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/EventBoundListener.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/EventBoundListener.java?view=diff&rev=486894&r1=486893&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/EventBoundListener.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/EventBoundListener.java Wed Dec 13 15:54:01 2006
@@ -38,6 +38,8 @@
     
     // If targeting a form, whether or not to submit it asynchronously
     private boolean _async;
+    // Whether or not to focus the form
+    private boolean _focus;
     
     /**
      * Creates a new listener binding. 
@@ -60,13 +62,14 @@
      *          If formId is set, whether or not to validate form when submitting.
      */
     public EventBoundListener(String methodName, String formId, 
-            boolean validateForm, String componentId, boolean async)
+            boolean validateForm, String componentId, boolean async, boolean focus)
     {
         _methodName = methodName;
         _formId = formId;
         _validateForm = validateForm;
         _componentId = componentId;
         _async = async;
+        _focus = focus;
     }
     
     /**
@@ -143,7 +146,12 @@
     {
         _isPage = isPage;
     }
-
+    
+    public boolean shouldFocusForm()
+    {
+        return _focus;
+    }
+    
     /** 
      * {@inheritDoc}
      */

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/IComponentEventInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/IComponentEventInvoker.java?view=diff&rev=486894&r1=486893&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/IComponentEventInvoker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/IComponentEventInvoker.java Wed Dec 13 15:54:01 2006
@@ -62,7 +62,6 @@
      *          The form the event listener is bound to. This is the submitForm parameter
      *          of the EventListener annotation/spec driving an event occurrence to submit a particular form. It doesn't
      *          mean that the actual event target was the form . 
-     * 
      * @param listener 
      *          The listener that has form bound event listeners.
      */

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/impl/ComponentEventInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/impl/ComponentEventInvoker.java?view=diff&rev=486894&r1=486893&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/impl/ComponentEventInvoker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/impl/ComponentEventInvoker.java Wed Dec 13 15:54:01 2006
@@ -27,6 +27,7 @@
 import org.apache.tapestry.IRequestCycle;
 import org.apache.tapestry.event.BrowserEvent;
 import org.apache.tapestry.form.FormSupport;
+import org.apache.tapestry.form.FormSupportImpl;
 import org.apache.tapestry.internal.event.ComponentEventProperty;
 import org.apache.tapestry.internal.event.EventBoundListener;
 import org.apache.tapestry.internal.event.IComponentEventInvoker;
@@ -80,6 +81,8 @@
         if (comps == null)
             return;
         
+        boolean disableFocus = true;
+        
         for (int i=0; i < comps.size(); i++) {
             
             IComponentSpecification spec = (IComponentSpecification)comps.get(i);
@@ -101,6 +104,10 @@
                 if (!targetId.startsWith(listeners[e].getComponentId()))
                     continue;
                 
+                // handle disabling focus 
+                if (listeners[e].shouldFocusForm())
+                    disableFocus = false;
+                
                 // defer execution until after form is done rewinding
                 
                 form.addDeferredRunnable(
@@ -108,6 +115,13 @@
                                 target,
                                 cycle));
             }
+        }
+        
+        // Form uses cycle attributes to test whether or not to focus .
+        // The attribute existing at all is enough to bypass focusing.
+        if (disableFocus){
+            
+            cycle.setAttribute(FormSupportImpl.FIELD_FOCUS_ATTRIBUTE, Boolean.TRUE);
         }
     }
     

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/ComponentSpecification.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/ComponentSpecification.java?view=diff&rev=486894&r1=486893&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/ComponentSpecification.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/ComponentSpecification.java Wed Dec 13 15:54:01 2006
@@ -709,22 +709,22 @@
      * {@inheritDoc}
      */
     public void addEventListener(String componentId, String[] events, 
-            String methodName, String formId, boolean validateForm, boolean async)
+            String methodName, String formId, boolean validateForm, boolean async, boolean focus)
     {
         ComponentEventProperty property = getComponentEvents(componentId);
         
-        property.addListener(events, methodName, formId, validateForm, async);
+        property.addListener(events, methodName, formId, validateForm, async, focus);
     }
     
     /**
      * {@inheritDoc}
      */
     public void addElementEventListener(String elementId, String[] events, 
-            String methodName, String formId, boolean validateForm, boolean async)
+            String methodName, String formId, boolean validateForm, boolean async, boolean focus)
     {
         ComponentEventProperty property = getElementEvents(elementId);
         
-        property.addListener(events, methodName, formId, validateForm, async);
+        property.addListener(events, methodName, formId, validateForm, async, focus);
     }
     
     /**

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/IEventListener.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/IEventListener.java?view=diff&rev=486894&r1=486893&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/IEventListener.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/spec/IEventListener.java Wed Dec 13 15:54:01 2006
@@ -40,9 +40,11 @@
      *          one of the supplied events occurs.
      * @param async 
      *          If submitting a form, whether or not to do it asynchronously.
+     * @param focus
+     *          If submitting a form, controls whether or not to focus it after an update.
      */
     void addEventListener(String componentId, String[] events, 
-            String methodName, String formId, boolean validateForm, boolean async);
+            String methodName, String formId, boolean validateForm, boolean async, boolean focus);
     
     /**
      * Adds a deferred event listener binding for the specified html element.
@@ -52,9 +54,11 @@
      * @param methodName
      * @param async 
      *          If submitting a form, whether or not to do it asynchronously.
+     * @param focus
+     *          If submitting a form, controls whether or not to focus it after an update.
      */
     void addElementEventListener(String elementId, String[] events, 
-            String methodName, String formId, boolean validateForm, boolean async);
+            String methodName, String formId, boolean validateForm, boolean async, boolean focus);
     
     /**
      * Checks if any element events are bound to this component.

Added: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/ComponentEventPropertyTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/ComponentEventPropertyTest.java?view=auto&rev=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/ComponentEventPropertyTest.java (added)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/ComponentEventPropertyTest.java Wed Dec 13 15:54:01 2006
@@ -0,0 +1,101 @@
+// Copyright Jun 3, 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package org.apache.tapestry.internal.event;
+
+import java.util.List;
+
+import org.apache.tapestry.event.BrowserEvent;
+import org.testng.annotations.Test;
+
+import com.javaforge.tapestry.testng.TestBase;
+
+
+/**
+ * Tests for {@link ComponentEventProperty} and {@link EventBoundListener}.
+ * 
+ * @author jkuhnert
+ */
+@Test
+public class ComponentEventPropertyTest extends TestBase
+{
+
+    public void testAddEventListener()
+    {
+        String[] events = {"onClick", "onFoo"};
+        ComponentEventProperty prop = new ComponentEventProperty("compid");
+        
+        prop.addListener(events, "doFoo", null, false, false, false);
+        
+        assertEquals("compid", prop.getComponentId());
+        assertEquals(2, prop.getEvents().size());
+        assertEquals(0, prop.getFormEvents().size());
+        
+        assertNotNull(prop.getEventListeners("onClick"));
+        
+        List listeners = prop.getEventListeners("onClick");
+        assertEquals(1, listeners.size());
+        
+        EventBoundListener listener = (EventBoundListener)listeners.get(0);
+        assertEquals("compid", listener.getComponentId());
+        assertNull(listener.getFormId());
+        assertEquals("doFoo", listener.getMethodName());
+    }
+    
+    public void testAddFormEventListener()
+    {
+        String[] events = {"onFoo"};
+        ComponentEventProperty prop = new ComponentEventProperty("compid");
+        
+        prop.addListener(events, "doFoo", "formid", false, true, false);
+        
+        assertEquals("compid", prop.getComponentId());
+        assertEquals(0, prop.getEvents().size());
+        assertEquals(1, prop.getFormEvents().size());
+        
+        assertNotNull(prop.getFormEventListeners("onFoo"));
+        
+        List listeners = prop.getFormEventListeners("onFoo");
+        assertEquals(1, listeners.size());
+        
+        EventBoundListener listener = (EventBoundListener)listeners.get(0);
+        assertEquals("compid", listener.getComponentId());
+        assertEquals("formid", listener.getFormId());
+        assertFalse(listener.isValidateForm());
+        assertTrue(listener.isAsync());
+        
+        assertEquals(1, prop.getFormEvents().size());
+        
+        assertEquals("doFoo", listener.getMethodName());
+    }
+    
+    public void testGetFormEvents()
+    {
+        String[] events = {"onFoo"};
+        ComponentEventProperty prop = new ComponentEventProperty("compid");
+        BrowserEvent event = new BrowserEvent("onFoo", null);
+        
+        prop.addListener(events, "doFoo", "formid", false, false, true);
+        
+        List listeners = prop.getFormEventListeners("formid", event, null);
+        assertEquals(1, listeners.size());
+        
+        EventBoundListener listener = (EventBoundListener)listeners.get(0);
+        assertEquals("compid", listener.getComponentId());
+        assertEquals("formid", listener.getFormId());
+        assertFalse(listener.isValidateForm());
+        
+        assertEquals("doFoo", listener.getMethodName());
+        assertTrue(listener.shouldFocusForm());
+    }
+}

Copied: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/impl/ComponentEventInvokerTest.java (from r486848, tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/impl/ComponentEventInvokerTest.java?view=diff&rev=486894&p1=tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java&r1=486848&p2=tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/impl/ComponentEventInvokerTest.java&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/impl/ComponentEventInvokerTest.java Wed Dec 13 15:54:01 2006
@@ -11,9 +11,11 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
-package org.apache.tapestry.services.impl;
+package org.apache.tapestry.internal.event.impl;
 
-import static org.easymock.EasyMock.*;
+import static org.easymock.EasyMock.checkOrder;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
 
 import java.util.HashMap;
 import java.util.List;
@@ -28,9 +30,12 @@
 import org.apache.tapestry.event.BrowserEvent;
 import org.apache.tapestry.event.EventTarget;
 import org.apache.tapestry.form.FormSupport;
+import org.apache.tapestry.form.FormSupportImpl;
 import org.apache.tapestry.internal.event.ComponentEventProperty;
 import org.apache.tapestry.listener.ListenerInvoker;
 import org.apache.tapestry.listener.ListenerMap;
+import org.apache.tapestry.spec.ComponentSpecification;
+import org.apache.tapestry.spec.IComponentSpecification;
 import org.testng.annotations.Test;
 
 
@@ -45,18 +50,18 @@
     
     public void test_Event_Properties()
     {
-        ComponentEventInvoker invoker = new ComponentEventInvoker();
+        IComponentSpecification spec = new ComponentSpecification();
+        spec.addEventListener("comp1", new String[] {"onClick"}, "testFoo", 
+                null, false, false, false);
         
-        invoker.addEventListener("comp1", new String[] {"onClick"}, "testFoo", 
-                null, false, false);
-        assertTrue(invoker.hasEvents("comp1"));
+        assertTrue(spec.hasEvents("comp1"));
         
-        ComponentEventProperty prop = invoker.getComponentEvents("comp1");
+        ComponentEventProperty prop = spec.getComponentEvents("comp1");
         assertNotNull(prop);
         assertEquals(prop.getEventListeners("onClick").size(), 1);
         
         // ensure valid props always returned
-        prop = invoker.getComponentEvents("comp2");
+        prop = spec.getComponentEvents("comp2");
         assertNotNull(prop);
         assertEquals(prop.getEvents().size(), 0);
         
@@ -72,6 +77,8 @@
         checkOrder(comp, false);
         IPage page = newMock(IPage.class);
         
+        IComponentSpecification spec = new ComponentSpecification();
+        
         ListenerInvoker listenerInvoker = newMock(ListenerInvoker.class);
         ListenerMap listenerMap = newMock(ListenerMap.class);
         
@@ -85,34 +92,25 @@
         BrowserEvent event = new BrowserEvent("onSelect", new EventTarget(tprops));
         
         ComponentEventInvoker invoker = new ComponentEventInvoker();
-        invoker.setListenerInvoker(listenerInvoker);
+        invoker.setInvoker(listenerInvoker);
         
-        invoker.addEventListener("testId", new String[] { "onSelect" }, 
-                "fooListener", null, false, false);
+        spec.addEventListener("testId", new String[] { "onSelect" }, 
+                "fooListener", null, false, false, false);
+        invoker.addEventListener("testId", spec);
         
         expect(comp.getId()).andReturn("testId").anyTimes();
         
+        expect(comp.getSpecification()).andReturn(spec).anyTimes();
+        
         expect(comp.getPage()).andReturn(page);
         
         expect(page.getComponents()).andReturn(comps);
         
-        expect(comp.getContainer()).andReturn(page);
-        
-        expect(page.getIdPath()).andReturn(null);
-        
-        expect(page.getPage()).andReturn(page);
-        
-        expect(page.getPageName()).andReturn("Page");
-        
-        expect(page.getListeners()).andReturn(listenerMap);
-        
-        expect(listenerMap.canProvideListener("fooListener")).andReturn(Boolean.TRUE);
-        
-        expect(page.getListeners()).andReturn(listenerMap);
+        expect(comp.getListeners()).andReturn(listenerMap);
         
         expect(listenerMap.getListener("fooListener")).andReturn(listener1);
         
-        listenerInvoker.invokeListener(listener1, page, cycle);
+        listenerInvoker.invokeListener(listener1, comp, cycle);
         
         replay();
         
@@ -128,6 +126,7 @@
         checkOrder(comp, false);
         
         IPage page = newMock(IPage.class);
+        IComponentSpecification spec = new ComponentSpecification();
         
         ListenerInvoker listenerInvoker = newMock(ListenerInvoker.class);
         ListenerMap listenerMap = newMock(ListenerMap.class);
@@ -141,32 +140,25 @@
         BrowserEvent event = new BrowserEvent("onSelect", new EventTarget(tprops));
         
         ComponentEventInvoker invoker = new ComponentEventInvoker();
-        invoker.setListenerInvoker(listenerInvoker);
+        invoker.setInvoker(listenerInvoker);
         
-        invoker.addElementEventListener("testId", new String[] { "onSelect" }, 
-                "fooListener", null, false, false);
+        spec.addElementEventListener("testId", new String[] { "onSelect" }, 
+                "fooListener", null, false, true, true);
+        invoker.addEventListener("testId", spec);
         
         expect(comp.getId()).andReturn("testId").anyTimes();
         
+        expect(comp.getSpecification()).andReturn(spec).anyTimes();
+        
         expect(comp.getPage()).andReturn(page);
         
         expect(page.getComponents()).andReturn(comps);
         
-        expect(comp.getContainer()).andReturn(page);
-        
-        expect(page.getIdPath()).andReturn(null);
-        
-        expect(page.getPage()).andReturn(page);
-        
-        expect(page.getPageName()).andReturn("Page");
-        
-        expect(page.getListeners()).andReturn(listenerMap).anyTimes();
-        
-        expect(listenerMap.canProvideListener("fooListener")).andReturn(Boolean.TRUE);
+        expect(comp.getListeners()).andReturn(listenerMap);
         
         expect(listenerMap.getListener("fooListener")).andReturn(listener);
         
-        listenerInvoker.invokeListener(listener, page, cycle);
+        listenerInvoker.invokeListener(listener, comp, cycle);
         
         replay();
         
@@ -181,6 +173,7 @@
         IForm form = newForm();
         checkOrder(form, false);
         FormSupport formSupport = newMock(FormSupport.class);
+        IComponentSpecification spec = new ComponentSpecification();
         
         ListenerInvoker listenerInvoker = newMock(ListenerInvoker.class);
         ListenerMap listenerMap = newMock(ListenerMap.class);
@@ -196,10 +189,11 @@
         BrowserEvent event = new BrowserEvent("onSelect", new EventTarget(tprops));
         
         ComponentEventInvoker invoker = new ComponentEventInvoker();
-        invoker.setListenerInvoker(listenerInvoker);
+        invoker.setInvoker(listenerInvoker);
         
-        invoker.addEventListener("form1", new String[] { "onSelect" }, "fooListener",
-                "form1", false, false);
+        spec.addEventListener("form1", new String[] { "onSelect" }, "fooListener",
+                "form1", false, false, false);
+        invoker.addFormEventListener("form1", spec);
         
         expect(formSupport.getForm()).andReturn(form);
         
@@ -209,15 +203,62 @@
         
         expect(page.getComponents()).andReturn(comps);
         
-        expect(form.getContainer()).andReturn(page);
+        expect(form.getSpecification()).andReturn(spec);
+        
+        expect(form.getListeners()).andReturn(listenerMap);
+        
+        expect(listenerMap.getListener("fooListener")).andReturn(listener);
+        
+        form.addDeferredRunnable(isA(Runnable.class));
+        
+        cycle.setAttribute(FormSupportImpl.FIELD_FOCUS_ATTRIBUTE, Boolean.TRUE);
+        
+        replay();
+        
+        invoker.invokeFormListeners(formSupport, cycle, event);
+        
+        verify();
+    }
+    
+    public void test_Invoke_Form_Listener_Enabled_Focus()
+    {
+        IRequestCycle cycle = newCycle();
+        IForm form = newForm();
+        checkOrder(form, false);
+        FormSupport formSupport = newMock(FormSupport.class);
+        IComponentSpecification spec = new ComponentSpecification();
+        
+        ListenerInvoker listenerInvoker = newMock(ListenerInvoker.class);
+        ListenerMap listenerMap = newMock(ListenerMap.class);
+        IActionListener listener = newMock(IActionListener.class);
+        IPage page = newMock(IPage.class);
+        checkOrder(page, false);
         
-        expect(page.getIdPath()).andReturn(null);
+        Map comps = new HashMap();
+        comps.put("form1", form);
         
-        expect(page.getPage()).andReturn(page);
+        Map tprops = new HashMap();
+        tprops.put("id", "form1");
+        BrowserEvent event = new BrowserEvent("onSelect", new EventTarget(tprops));
+        
+        ComponentEventInvoker invoker = new ComponentEventInvoker();
+        invoker.setInvoker(listenerInvoker);
+        
+        spec.addEventListener("form1", new String[] { "onSelect" }, "fooListener",
+                "form1", false, false, true);
+        invoker.addFormEventListener("form1", spec);
+        
+        expect(formSupport.getForm()).andReturn(form);
+        
+        expect(form.getId()).andReturn("form1").anyTimes();
+        
+        expect(form.getPage()).andReturn(page);
+        
+        expect(page.getComponents()).andReturn(comps);
         
-        expect(page.getPageName()).andReturn("TestPage");
+        expect(form.getSpecification()).andReturn(spec);
         
-        expect(page.getListeners()).andReturn(listenerMap);
+        expect(form.getListeners()).andReturn(listenerMap);
         
         expect(listenerMap.getListener("fooListener")).andReturn(listener);
         

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/ComponentEventConnectionWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/ComponentEventConnectionWorkerTest.java?view=diff&rev=486894&r1=486893&r2=486894
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/ComponentEventConnectionWorkerTest.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/ComponentEventConnectionWorkerTest.java Wed Dec 13 15:54:01 2006
@@ -106,8 +106,8 @@
         
         // now test render
         invoker.addEventListener("comp1", spec);
-        spec.addEventListener("comp1", new String[] {"onclick"}, "testMethod", null, false, true);
-        spec.addElementEventListener("elementId", new String[] {"onclick"}, "testMethod", null, false, true);
+        spec.addEventListener("comp1", new String[] {"onclick"}, "testMethod", null, false, true, false);
+        spec.addElementEventListener("elementId", new String[] {"onclick"}, "testMethod", null, false, true, false);
         
         /////////////////////////////////
         
@@ -170,7 +170,7 @@
         // test widget render
         
         invoker.addEventListener("wid1", widgetSpec);
-        widgetSpec.addEventListener("wid1", new String[] {"onclick"}, "testMethod", null, false, true);
+        widgetSpec.addEventListener("wid1", new String[] {"onclick"}, "testMethod", null, false, true, false);
         
         checkOrder(cycle, false);
         expect(cycle.isRewinding()).andReturn(false);
@@ -250,7 +250,7 @@
         
         // now test render
         invoker.addEventListener("comp1", spec);
-        spec.addEventListener("comp1", new String[] {"onclick"}, "testMethod", "form1", true, false);
+        spec.addEventListener("comp1", new String[] {"onclick"}, "testMethod", "form1", true, false, false);
         
         expect(cycle.isRewinding()).andReturn(false);
         
@@ -330,7 +330,7 @@
         
         // now test render
         invoker.addEventListener("comp1", spec);
-        spec.addEventListener("comp1", new String[] {"onclick"}, "testMethod", "form1", false, false);
+        spec.addEventListener("comp1", new String[] {"onclick"}, "testMethod", "form1", false, false, false);
         
         expect(cycle.isRewinding()).andReturn(false);
         
@@ -457,7 +457,7 @@
         
         // now test render
         invoker.addEventListener("comp1", spec);
-        spec.addEventListener("comp1", new String[] {"onclick"}, "testMethod", "form1", false, false);
+        spec.addEventListener("comp1", new String[] {"onclick"}, "testMethod", "form1", false, false, false);
         
         expect(cycle.isRewinding()).andReturn(false);