You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2006/05/22 19:55:42 UTC

svn commit: r408716 - in /tapestry/tapestry4/trunk: examples/TimeTracker/src/context/ examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/ framework/src/descriptor/META-INF/ framework/src/java/org/apache/tapestry/html/ framework/src/java...

Author: jkuhnert
Date: Mon May 22 10:55:41 2006
New Revision: 408716

URL: http://svn.apache.org/viewvc?rev=408716&view=rev
Log:
More event connection work / tests. 

Added:
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/ElementEvent.script
Modified:
    tapestry/tapestry4/trunk/examples/TimeTracker/src/context/Home.html
    tapestry/tapestry4/trunk/examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java
    tapestry/tapestry4/trunk/framework/src/descriptor/META-INF/tapestry.render.xml
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/Body.java
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/Body.jwc
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/ComponentRenderWorker.java
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java
    tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java

Modified: tapestry/tapestry4/trunk/examples/TimeTracker/src/context/Home.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/examples/TimeTracker/src/context/Home.html?rev=408716&r1=408715&r2=408716&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/examples/TimeTracker/src/context/Home.html (original)
+++ tapestry/tapestry4/trunk/examples/TimeTracker/src/context/Home.html Mon May 22 10:55:41 2006
@@ -1,8 +1,9 @@
 <span jwcid="@Border">
 
-<p/>This is the Tapestry TimeTracker application. It is a demonstration of some of the new
+<p>This is the Tapestry TimeTracker application. It is a demonstration of some of the new
 core features available in tapestry, as well as how a sample application might be built
 using them.
+</p>
 
 <form jwcid="@Form" listener="listener:addTask" >
     <fieldset>
@@ -14,8 +15,8 @@
     </div>
     
     <div class="fm-hopt">
-      <label for="fm-firstname">Start</label>
-      <input jwcid="startPicker" style="width:auto" size="10" name="fm-firstname" id="fm-firstname" type="text" />
+      <label for="startPicker">Start</label>
+      <input jwcid="startPicker" style="width:auto" size="10"  />
     </div>
     <div class="fm-hopt">
       <label for="fm-middlename">End</label>

Modified: tapestry/tapestry4/trunk/examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java?rev=408716&r1=408715&r2=408716&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java (original)
+++ tapestry/tapestry4/trunk/examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java Mon May 22 10:55:41 2006
@@ -75,8 +75,8 @@
      * Invoked when an item is selected from the project
      * selection list.
      */
-    @EventListener(events = {"selectOption"}, 
-            targets = { "projectChoose" })
+    @EventListener(events = {"selectOption", "onChange"}, 
+            targets = { "projectChoose" }, elements = { "startPicker" })
     public void projectSelected()
     {
         

Modified: tapestry/tapestry4/trunk/framework/src/descriptor/META-INF/tapestry.render.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/descriptor/META-INF/tapestry.render.xml?rev=408716&r1=408715&r2=408716&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/descriptor/META-INF/tapestry.render.xml (original)
+++ tapestry/tapestry4/trunk/framework/src/descriptor/META-INF/tapestry.render.xml Mon May 22 10:55:41 2006
@@ -48,6 +48,7 @@
         <set-service property="eventEngine" service-id="tapestry.event.DirectEvent"/>
         <set property="componentScript" value="/org/apache/tapestry/ComponentEvent.script" />
         <set property="widgetScript" value="/org/apache/tapestry/dojo/html/WidgetEvent.script" />
+        <set property="elementScript" value="/org/apache/tapestry/html/ElementEvent.script" />
         <set-service property="scriptSource" service-id="tapestry.script.ScriptSource"/>
       </construct>
     </invoke-factory>

Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/Body.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/Body.java?rev=408716&r1=408715&r2=408716&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/Body.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/Body.java Mon May 22 10:55:41 2006
@@ -22,6 +22,7 @@
 import org.apache.tapestry.PageRenderSupport;
 import org.apache.tapestry.TapestryUtils;
 import org.apache.tapestry.asset.AssetFactory;
+import org.apache.tapestry.services.ComponentRenderWorker;
 import org.apache.tapestry.util.PageRenderSupportImpl;
 import org.apache.tapestry.web.WebResponse;
 
@@ -157,7 +158,9 @@
         IMarkupWriter nested = writer.getNestedWriter();
 
         renderBody(nested, cycle);
-
+        
+        getEventWorker().renderBody(cycle, this);
+        
         // Start the body tag.
         writer.println();
         writer.begin(getElement());
@@ -214,6 +217,13 @@
 
     public abstract WebResponse getResponse();
 
+    /**
+     * Injected.
+     * @return
+     * @since 4.1
+     */
+    public abstract ComponentRenderWorker getEventWorker();
+    
     /** @since 3.0 */
 
     public String getUniqueString(String baseValue)

Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/Body.jwc
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/Body.jwc?rev=408716&r1=408715&r2=408716&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/Body.jwc (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/Body.jwc Mon May 22 10:55:41 2006
@@ -34,4 +34,5 @@
  
   <inject property="assetFactory" object="infrastructure:assetFactory"/>
   <inject property="response" object="infrastructure:response"/>
+  <inject property="eventWorker" object="service:tapestry.render.ComponentEventConnectionWorker" />
 </component-specification>

Added: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/ElementEvent.script
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/ElementEvent.script?rev=408716&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/ElementEvent.script (added)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/html/ElementEvent.script Mon May 22 10:55:41 2006
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!DOCTYPE script PUBLIC
+  "-//Apache Software Foundation//Tapestry Script Specification 3.0//EN"
+  "http://jakarta.apache.org/tapestry/dtd/Script_3_0.dtd">
+<script>
+<include-script resource-path="/org/apache/tapestry/dojo/Widget.js"/>
+
+<input-symbol key="target" required="yes" />
+<input-symbol key="url" required="yes" />
+<input-symbol key="events" required="yes" />
+    <body>
+        <unique>
+            dojo.require("dojo.io");
+            dojo.require("dojo.json");
+            dojo.require("dojo.event");
+        </unique>
+    </body>
+    <initialization>
+        <foreach expression="events" key="event">
+        dojo.event.connect(dojo.byId("${target}"), "${event}", function(e) {
+            dojo.debug("Event fired");
+        });
+        </foreach>
+    </initialization>
+</script>
\ No newline at end of file

Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/ComponentRenderWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/ComponentRenderWorker.java?rev=408716&r1=408715&r2=408716&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/ComponentRenderWorker.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/ComponentRenderWorker.java Mon May 22 10:55:41 2006
@@ -15,6 +15,7 @@
 
 import org.apache.tapestry.IComponent;
 import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.html.Body;
 
 
 /**
@@ -37,4 +38,16 @@
      *          The component that has just been rendered.
      */
     void renderComponent(IRequestCycle cycle, IComponent component);
+    
+    /**
+     * Special render for handling html element targets. This is invoked
+     * just after the body component renders its body, but before the script
+     * data is written out. 
+     * 
+     * @param cycle
+     *          The associated request cycle.
+     * @param component
+     *          The {@link Body} component, which holds the needed {@link PageRenderSupport} object.
+     */
+    void renderBody(IRequestCycle cycle, Body component);
 }

Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java?rev=408716&r1=408715&r2=408716&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java Mon May 22 10:55:41 2006
@@ -14,6 +14,7 @@
 package org.apache.tapestry.services.impl;
 
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 
 import org.apache.hivemind.ClassResolver;
@@ -28,6 +29,7 @@
 import org.apache.tapestry.engine.DirectEventServiceParameter;
 import org.apache.tapestry.engine.IEngineService;
 import org.apache.tapestry.engine.IScriptSource;
+import org.apache.tapestry.html.Body;
 import org.apache.tapestry.internal.event.ComponentEventProperty;
 import org.apache.tapestry.services.ComponentRenderWorker;
 
@@ -50,6 +52,8 @@
     
     private String _widgetScript;
     
+    private String _elementScript;
+    
     private ClassResolver _resolver;
     
     /** 
@@ -77,6 +81,41 @@
         _scriptSource.getScript(resource).execute(cycle, prs, parms);
     }
     
+    /**
+     * {@inheritDoc}
+     */
+    public void renderBody(IRequestCycle cycle, Body component)
+    {
+        if (!_invoker.hasElementEvents())
+            return;
+        
+        Map parms = new HashMap();
+        DirectEventServiceParameter dsp =
+            new DirectEventServiceParameter(component, new Object[] {}, new String[] {}, false);
+        String url = _eventEngine.getLink(false, dsp).getURL();
+        
+        PageRenderSupport prs = TapestryUtils.getPageRenderSupport(cycle, component);
+        Resource resource = new ClasspathResource(_resolver, _elementScript);
+        
+        Map elements = _invoker.getElementEvents();
+        Iterator keys = elements.keySet().iterator();
+        
+        // build our list of targets / events
+        while (keys.hasNext()) {
+            String target = (String)keys.next();
+            
+            ComponentEventProperty prop = (ComponentEventProperty)elements.get(target);
+            
+            parms.put("target", target);
+            parms.put("url", url);
+            parms.put("events", prop.getEvents());
+            
+            _scriptSource.getScript(resource).execute(cycle, prs, parms);
+            
+            parms.clear();
+        }
+    }
+    
     Resource getScript(IComponent component)
     {
         if (IWidget.class.isInstance(component))
@@ -123,6 +162,16 @@
     public void setWidgetScript(String script)
     {
         _widgetScript = script;
+    }
+    
+    /**
+     * The javascript that connects html elements to direct
+     * listener methods.
+     * @param script
+     */
+    public void setElementScript(String script)
+    {
+        _elementScript = script;
     }
     
     /**

Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java?rev=408716&r1=408715&r2=408716&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java Mon May 22 10:55:41 2006
@@ -62,7 +62,7 @@
         
         if (hasEvents(id)) {
             
-            ComponentEventProperty prop = getComponentEvents(component.getId());
+            ComponentEventProperty prop = getComponentEvents(id);
             invokeListeners(prop, component, cycle, event);
         }
         
@@ -71,7 +71,7 @@
         
         if (hasElementEvents(targetId)) {
             
-            ComponentEventProperty prop = getElementEvents(component.getId());
+            ComponentEventProperty prop = getElementEvents(id);
             invokeListeners(prop, component, cycle, event);
         }
     }
@@ -190,6 +190,15 @@
         }
         
         return prop;
+    }
+    
+    /**
+     * Returns the {@link Map} being managed for element events.
+     * @return
+     */
+    public Map getElementEvents()
+    {
+        return _elements;
     }
     
     public void resetEventDidOccur()

Modified: tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java?rev=408716&r1=408715&r2=408716&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java (original)
+++ tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/services/impl/ComponentEventInvokerTest.java Mon May 22 10:55:41 2006
@@ -13,7 +13,19 @@
 // limitations under the License.
 package org.apache.tapestry.services.impl;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.tapestry.BaseComponentTestCase;
+import org.apache.tapestry.IActionListener;
+import org.apache.tapestry.IComponent;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.event.BrowserEvent;
+import org.apache.tapestry.event.EventTarget;
+import org.apache.tapestry.internal.event.ComponentEventProperty;
+import org.apache.tapestry.listener.ListenerInvoker;
+import org.apache.tapestry.listener.ListenerMap;
 
 
 /**
@@ -24,5 +36,94 @@
 public class ComponentEventInvokerTest extends BaseComponentTestCase
 {
     
+    public void testEventProperties()
+    {
+        ComponentEventInvoker invoker = new ComponentEventInvoker();
+        
+        invoker.addEventListener("comp1", new String[] {"onClick"}, "testFoo");
+        assertTrue(invoker.hasEvents("comp1"));
+        
+        ComponentEventProperty prop = invoker.getComponentEvents("comp1");
+        assertNotNull(prop);
+        assertEquals(prop.getEventListeners("onClick").size(), 1);
+        
+        // ensure valid props always returned
+        prop = invoker.getComponentEvents("comp2");
+        assertNotNull(prop);
+        assertEquals(prop.getEvents().size(), 0);
+        
+        List listeners = prop.getEventListeners("nonExistant");
+        assertNotNull(listeners);
+        assertEquals(listeners.size(), 0);
+    }
+    
+    public void testInvokeComponentListener()
+    {
+        IRequestCycle cycle = newCycle();
+        IComponent comp = newComponent();
+        ListenerInvoker listenerInvoker = (ListenerInvoker)newMock(ListenerInvoker.class);
+        ListenerMap listenerMap = (ListenerMap)newMock(ListenerMap.class);
+        IActionListener listener = (IActionListener)newMock(IActionListener.class);
+        
+        Map tprops = new HashMap();
+        tprops.put("id", "testId");
+        BrowserEvent event = new BrowserEvent("onSelect", new EventTarget(tprops));
+        
+        ComponentEventInvoker invoker = new ComponentEventInvoker();
+        invoker.setListenerInvoker(listenerInvoker);
+        
+        invoker.addEventListener("testId", new String[] { "onSelect" }, "fooListener");
+        
+        comp.getId();
+        setReturnValue(comp, "testId");
+        comp.getContainer();
+        setReturnValue(comp, comp);
+        comp.getListeners();
+        setReturnValue(comp, listenerMap);
+        
+        listenerMap.getListener("fooListener");
+        setReturnValue(listenerMap, listener);
+        listenerInvoker.invokeListener(listener, comp, cycle);
+        
+        replayControls();
+        
+        invoker.invokeListeners(comp, cycle, event);
+        
+        verifyControls();
+    }
     
+    public void testInvokeElementListener()
+    {
+        IRequestCycle cycle = newCycle();
+        IComponent comp = newComponent();
+        ListenerInvoker listenerInvoker = (ListenerInvoker)newMock(ListenerInvoker.class);
+        ListenerMap listenerMap = (ListenerMap)newMock(ListenerMap.class);
+        IActionListener listener = (IActionListener)newMock(IActionListener.class);
+        
+        Map tprops = new HashMap();
+        tprops.put("id", "testId");
+        BrowserEvent event = new BrowserEvent("onSelect", new EventTarget(tprops));
+        
+        ComponentEventInvoker invoker = new ComponentEventInvoker();
+        invoker.setListenerInvoker(listenerInvoker);
+        
+        invoker.addElementEventListener("testId", new String[] { "onSelect" }, "fooListener");
+        
+        comp.getId();
+        setReturnValue(comp, "testId");
+        comp.getContainer();
+        setReturnValue(comp, comp);
+        comp.getListeners();
+        setReturnValue(comp, listenerMap);
+        
+        listenerMap.getListener("fooListener");
+        setReturnValue(listenerMap, listener);
+        listenerInvoker.invokeListener(listener, comp, cycle);
+        
+        replayControls();
+        
+        invoker.invokeListeners(comp, cycle, event);
+        
+        verifyControls();
+    }
 }