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/11/24 02:16:12 UTC

svn commit: r478737 - in /tapestry/tapestry4/trunk: src/site/xdoc/components/general/ tapestry-examples/TimeTracker/src/context/ tapestry-examples/TimeTracker/src/context/WEB-INF/ tapestry-examples/TimeTracker/src/context/css/ tapestry-examples/TimeTra...

Author: jkuhnert
Date: Thu Nov 23 17:16:10 2006
New Revision: 478737

URL: http://svn.apache.org/viewvc?view=rev&rev=478737
Log:
Applied For patch from Ryan Holmes to make ForBean render out template tags in a similar way to @If and others.

Enhanced javascript output to remove overly verbose whitespace/newlines.

Fixed For bean to properly update output parameters for clientid on each render.

Fixed ComponentEventInvoker to properly handle ids that may be client ids of a component invoked. 

Added:
    tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/LocaleList.html   (with props)
    tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/LocaleList.java
Modified:
    tapestry/tapestry4/trunk/src/site/xdoc/components/general/for.xml
    tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/Border.html
    tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/Border.properties
    tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/timetracker.application
    tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/css/timetracker.css
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/AbstractComponent.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/For.jwc
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/ForBean.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/engine/DirectServiceParameter.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/EventTarget.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLinkWorker.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DefaultResponseBuilder.java
    tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/util/PageRenderSupportImpl.java
    tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestFor.xml
    tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestImplicitComponents.xml
    tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestProtectedLink.xml
    tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context34/Home.html
    tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/app/ProtectedLink.page
    tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/app/ProtectedLinkResult.page
    tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/DefaultResponseBuilderTest.java
    tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/util/TestPageRenderSupport.java

Modified: tapestry/tapestry4/trunk/src/site/xdoc/components/general/for.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/src/site/xdoc/components/general/for.xml?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/src/site/xdoc/components/general/for.xml (original)
+++ tapestry/tapestry4/trunk/src/site/xdoc/components/general/for.xml Thu Nov 23 17:16:10 2006
@@ -93,6 +93,31 @@
                     </tr>
 
                     <tr>
+                        <td>renderTag</td>
+                        <td>boolean</td>
+                        <td>no</td>
+                        <td>true</td>
+
+                        <td>
+                            Specifies whether or not to render the html tag name used to reference this
+                            component. This logic also deprecates the <code>element</code> parameter in 
+                            that tag names are already captured from the html template read in, so you
+                            only need to tell the component to render or not render whatever tag you used.
+                            
+                            <span class="info">
+                                <strong>Info:</strong>
+                                <p>
+                                    You can also control the default value of this property via the global
+                                    configuration property <code>org.apache.tapestry.renderTags</code> which 
+                                    is covered in more depth in the 
+                                    <a href="../../usersguide/configuration.html#Configuration%20Properties">configuration section</a>
+                                     of the <a href="../../usersguide/index.html">Users Guide</a>.
+                                </p>
+                            </span>
+                        </td>
+                    </tr>
+                    
+                    <tr>
                         <td>element</td>
                         <td>String</td>
                         <td>no</td>

Added: tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/LocaleList.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/LocaleList.html?view=auto&rev=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/LocaleList.html (added)
+++ tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/LocaleList.html Thu Nov 23 17:16:10 2006
@@ -0,0 +1,72 @@
+<span jwcid="@Border">
+
+<p>
+Simple For loop listing locales.
+</p>
+
+<style>
+	.localeList {
+		-moz-border-radius: 8px;
+		background: #2A78B0;
+		display:block;
+		float:left;
+		width:20%;
+		margin-top:0.6em;
+		margin-left:0.5em;
+		padding:0.3em;
+	}
+	
+	.localeList a { color: #fff;}
+	
+	.detail {
+		clear:left;
+		display:block;
+		padding: 1em;
+		width: 56%;
+		margin-top:1em;
+		border-left: 1px solid #efefef;
+		border-top: 1px solid #efefef;
+		border-bottom: 1px solid #aaa;
+		border-right: 1px solid #aaa;
+		-moz-border-radius: 0.7em;
+	}
+	
+	.status {
+		display:block;
+		clear:both;
+		width:70%;
+		height: 50px;
+		overflow:auto;
+		font-family:Arial;
+		font-size:8pt;
+		padding: 0.4em;
+		border:1px dotted #D6AE33;
+	}
+	
+</style>
+
+<span jwcid="localeDetail@Any">
+	<p class="detail" jwcid="@If" condition="ognl:selected" >
+		<strong>Country:</strong> 
+		<span jwcid="@Insert" value="ognl:selected.displayCountry" mode="ognl:@org.apache.tapestry.components.InsertMode@BREAK" />
+		&nbsp;
+		<strong>Language:</strong>
+		<span jwcid="@Insert" value="ognl:selected.displayLanguage" mode="ognl:@org.apache.tapestry.components.InsertMode@BREAK" />
+		&nbsp;
+		<strong>Variant:</strong>
+		<span jwcid="@Insert" value="ognl:selected.displayVariant" mode="ognl:@org.apache.tapestry.components.InsertMode@BREAK" />
+	</p>
+</span>
+
+<div jwcid="status@Any" class="status" >
+	<span jwcid="@Insert" value="ognl:status" />
+</div>
+
+<div class="localeList" jwcid="localeLink@For" source="ognl:locales" value="ognl:currLocale">
+	<a jwcid="@DirectLink" listener="listener:selectLocale" parameters="ognl:currLocale""
+		updateComponents="localeDetail"><span jwcid="@Insert" value="ognl:currLocale.toString()" /></a>
+</div>
+
+<br/>
+
+</span>

Propchange: tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/LocaleList.html
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/Border.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/Border.html?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/Border.html (original)
+++ tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/Border.html Thu Nov 23 17:16:10 2006
@@ -15,9 +15,8 @@
 
 <div id="navigation" >
     <ul>
-        <li><a class="here" href="" >home</a></li>
-        <li><a href="others">others</a></li>
-        <li><a href="and more">more things</a></li>
+        <li><a class="here" jwcid="@PageLink" page="Home">home</a></li>
+        <li><a jwcid="@PageLink" page="LocaleList">locale list</a></li>
     </ul>
 </div>
 

Modified: tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/Border.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/Border.properties?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/Border.properties (original)
+++ tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/Border.properties Thu Nov 23 17:16:10 2006
@@ -13,4 +13,4 @@
 # limitations under the License.
 window.title=Tapestry TimeTracker
 
-header.display=Tapestry TimeTracker
\ No newline at end of file
+header.display=Tapestry TimeTracker

Modified: tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/timetracker.application
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/timetracker.application?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/timetracker.application (original)
+++ tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/WEB-INF/timetracker.application Thu Nov 23 17:16:10 2006
@@ -20,7 +20,14 @@
   "http://tapestry.apache.org/dtd/Tapestry_4_0.dtd">
 	
 <application name="Tapestry TimeTracker">
-
+   
+   <meta key="org.apache.tapestry.page-class-packages" 
+        value="org.apache.tapestry.timetracker.page"/>
+        <!-- 
+    <meta key="org.apache.tapestry.component-class-packages" 
+        value="org.apache.tapestry.integration.app1.components"/>
+        -->
+        
   <library id="contrib" specification-path="classpath:/org/apache/tapestry/contrib/Contrib.library"/>
   
 </application>

Modified: tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/css/timetracker.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/css/timetracker.css?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/css/timetracker.css (original)
+++ tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/context/css/timetracker.css Thu Nov 23 17:16:10 2006
@@ -39,7 +39,7 @@
     font-size: 26pt;
     letter-spacing: 0.2em;
     color: #2A78B0;
-    position:fixed;
+    position:absolute;
     display:block;
 }
 

Added: tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/LocaleList.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/LocaleList.java?view=auto&rev=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/LocaleList.java (added)
+++ tapestry/tapestry4/trunk/tapestry-examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/LocaleList.java Thu Nov 23 17:16:10 2006
@@ -0,0 +1,56 @@
+// Copyright 2004, 2005 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.timetracker.page;
+
+import java.util.Locale;
+
+import org.apache.tapestry.annotations.EventListener;
+import org.apache.tapestry.event.BrowserEvent;
+import org.apache.tapestry.html.BasePage;
+import org.apache.tapestry.services.ResponseBuilder;
+
+
+/**
+ * Simple locale listing example.
+ *
+ * @author jkuhnert
+ */
+public abstract class LocaleList extends BasePage
+{
+    
+    public abstract Locale getCurrLocale();
+    
+    public abstract void setSelected(Locale locale);
+    
+    public abstract void setStatus(String status);
+    
+    public abstract ResponseBuilder getBuilder();
+    
+    public Locale[] getLocales()
+    {
+        return Locale.getAvailableLocales();
+    }
+    
+    public void selectLocale(Locale locale)
+    {
+        setSelected(locale);
+    }
+    
+    @EventListener(targets = "localeLink", events = "onmouseover")
+    public void localeHovered(BrowserEvent event)
+    {
+        setStatus(event.toString());
+        getBuilder().updateComponent("status");
+    }
+}

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/AbstractComponent.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/AbstractComponent.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/AbstractComponent.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/AbstractComponent.java Thu Nov 23 17:16:10 2006
@@ -692,8 +692,6 @@
             prepareForRender(cycle);
             
             renderComponent(writer, cycle);
-            
-            getRenderWorker().renderComponent(cycle, this);
         }
         finally
         {
@@ -727,14 +725,14 @@
     protected abstract void renderComponent(IMarkupWriter writer, IRequestCycle cycle);
     
     /**
-     * Invoked by {@link #render(IMarkupWriter, IRequestCycle)}after the component renders. This
-     * implementation does nothing.
+     * Invoked by {@link #render(IMarkupWriter, IRequestCycle)}after the component renders.
      * 
      * @since 2.0.3
      */
 
     protected void cleanupAfterRender(IRequestCycle cycle)
     {
+        getRenderWorker().renderComponent(cycle, this);
     }
 
     public INamespace getNamespace()

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/For.jwc
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/For.jwc?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/For.jwc (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/For.jwc Thu Nov 23 17:16:10 2006
@@ -46,6 +46,8 @@
     </description>
   </parameter>
   
+  <parameter name="renderTag" default-value="ognl:defaultRenderTags" />
+  
   <parameter name="element">
     <description>
     If provided, the component wraps its content with the requested element.
@@ -53,7 +55,6 @@
     </description>
   </parameter>
   
-    
   <parameter name="keyExpression">
     <description>
     Only active in a form. An OGNL expression that returns the primary key of the iterated value. 
@@ -120,6 +121,7 @@
     </description>
   </parameter>
   
+  <inject property="defaultRenderTags" object="app-property:org.apache.tapestry.renderTags" />
   <inject property="dataSqueezer" object="service:tapestry.data.DataSqueezer"/>
   <inject property="valueConverter" object="service:tapestry.coerce.ValueConverter"/>
   <inject property="expressionEvaluator" object="service:tapestry.ognl.ExpressionEvaluator"/>

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/ForBean.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/ForBean.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/ForBean.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/components/ForBean.java Thu Nov 23 17:16:10 2006
@@ -21,6 +21,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.hivemind.HiveMind;
 import org.apache.tapestry.IBinding;
 import org.apache.tapestry.IForm;
 import org.apache.tapestry.IMarkupWriter;
@@ -30,6 +31,7 @@
 import org.apache.tapestry.coerce.ValueConverter;
 import org.apache.tapestry.engine.NullWriter;
 import org.apache.tapestry.form.AbstractFormComponent;
+import org.apache.tapestry.services.ComponentRenderWorker;
 import org.apache.tapestry.services.DataSqueezer;
 import org.apache.tapestry.services.ExpressionEvaluator;
 
@@ -70,6 +72,8 @@
     private boolean _rendering;
     
     // parameters
+    public abstract boolean getRenderTag();
+    
     public abstract String getElement();
 
     public abstract String getKeyExpression();
@@ -88,7 +92,9 @@
     public abstract ValueConverter getValueConverter();
 
     public abstract ExpressionEvaluator getExpressionEvaluator();
-
+    
+    public abstract ComponentRenderWorker getRenderWorker();
+    
     /**
      * Gets the source binding and iterates through its values. For each, it updates the value
      * binding and render's its wrapped elements.
@@ -100,6 +106,7 @@
         
         // If the cycle is rewinding, but not this particular form,
         // then do nothing (don't even render the body).
+        
         boolean cycleRewinding = cycle.isRewinding();
         if (cycleRewinding && form != null && !form.isRewinding())
             return;
@@ -107,18 +114,22 @@
         setForm(form);
         
         // Get the data to be iterated upon. Store in form if needed.
+        
         Iterator dataSource = getData(cycle, form);
 
         // Do not iterate if dataSource is null.
         // The dataSource was either not convertable to Iterator, or was empty.
+        
         if (dataSource == null)
             return;
         
         if (!cycleRewinding && form != null && !NullWriter.class.isInstance(writer))
             form.setFormFieldUpdating(true);
         
-        String element = getElement();
-
+        String element = HiveMind.isNonBlank(getElement()) ? getElement() : getTemplateTagName();
+        
+        boolean render = !cycleRewinding && (getRenderTag() || HiveMind.isNonBlank(getElement()));
+        
         // Perform the iterations
         try
         {
@@ -129,23 +140,38 @@
             {
                 // Get current value
                 _value = dataSource.next();
-
+                
                 // Update output component parameters
                 updateOutputParameters();
-
+                
                 // Render component
-                if (element != null)
-                {
+                
+                if (render) {
+                    
                     writer.begin(element);
+                    
                     renderInformalParameters(writer, cycle);
+                    renderIdAttribute(writer, cycle);
                 }
-
+                
                 renderBody(writer, cycle);
-
-                if (element != null)
-                    writer.end();
+                
+                if (render) {
+                    
+                    writer.end(element);
+                }
                 
                 _index++;
+                
+                // TODO: Fragile / messy
+                // Cause unique client id to be generated as well as event connection
+                // works or other after render workers. (basically reproduce what happens
+                // inside of AbstractComponent.render() . Perhaps this means it's time for
+                // refactoring of this logic, like deferring rendering to an actual component
+                // that can have its proper render() method invoked multiple times.
+                
+                getRenderWorker().renderComponent(cycle, this);
+                generateClientId();
             }
         }
         finally
@@ -154,7 +180,23 @@
             _value = null;
         }
     }
-
+    
+    /**
+     * Overriden so that RenderWorker doesn't get run as we've been invoking
+     * it manually already.
+     */
+    protected void cleanupAfterRender(IRequestCycle cycle)
+    {
+    }
+    
+    protected void generateClientId()
+    {
+        String id = getSpecifiedId();
+        
+        if (id != null && getPage() != null && getPage().getRequestCycle() != null)
+             setClientId(getPage().getRequestCycle().getUniqueId(TapestryUtils.convertTapestryIdToNMToken(id)));
+    }
+    
     /**
      * Returns the most recent value extracted from the source parameter.
      *

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/engine/DirectServiceParameter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/engine/DirectServiceParameter.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/engine/DirectServiceParameter.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/engine/DirectServiceParameter.java Thu Nov 23 17:16:10 2006
@@ -56,13 +56,13 @@
         _serviceParameters = serviceParameters;
         
         if (invoker == null) {
-        
+            
             Collection comps = direct.getUpdateComponents();
             if (comps == null)
                 _updateParts = new String[0];
             else
                 _updateParts = (String[])comps.toArray(new String[comps.size()]);
-
+            
             _json = direct.isJson();
             _async = direct.isAsync();
         } else {
@@ -76,6 +76,12 @@
             _json = invoker.isJson();
             _async = invoker.isAsync();
         }
+        
+        // if they gave only an updateComponents param make it async by default
+        
+        if (!_json && !_async && _updateParts.length > 0)
+            _async = true;
+        
     }
     
     public IDirect getDirect()

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java Thu Nov 23 17:16:10 2006
@@ -16,6 +16,8 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
 import org.apache.hivemind.util.Defense;
 import org.apache.tapestry.IRequestCycle;
 
@@ -182,5 +184,20 @@
         Defense.notNull(cycle, "cycle");
         
         return cycle.getParameter(NAME) != null;
+    }
+    
+    public String toString()
+    {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+        .append("name", _name)
+        .append("type", _type)
+        .append("keys", _keys)
+        .append("charCode", _charCode)
+        .append("pageX", _pageX)
+        .append("pageY", _pageY)
+        .append("layerX", _layerX)
+        .append("layerY", _layerY)
+        .append("target", _target)
+        .toString();
     }
 }

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/EventTarget.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/EventTarget.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/EventTarget.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/EventTarget.java Thu Nov 23 17:16:10 2006
@@ -15,6 +15,9 @@
 
 import java.util.Map;
 
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
 
 /**
  * Represents a browser generated event "target". Most browser events will
@@ -46,5 +49,12 @@
     public Object get(String key)
     {
         return _properties.get(key);
+    }
+    
+    public String toString()
+    {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+        .append("properties", _properties)
+        .toString();
     }
 }

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLinkWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLinkWorker.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLinkWorker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/link/DirectLinkWorker.java Thu Nov 23 17:16:10 2006
@@ -77,7 +77,9 @@
         IDirect direct = (IDirect)component;
         
         // check for dynamic parameters
-        if (!direct.isAsync() && !direct.isJson())
+        if (!direct.isAsync() && !direct.isJson() 
+                && (direct.getUpdateComponents() == null 
+                || direct.getUpdateComponents().size() <= 0))
             return;
         
         PageRenderSupport prs = TapestryUtils.getPageRenderSupport(cycle, component);

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java Thu Nov 23 17:16:10 2006
@@ -112,7 +112,7 @@
         parms.put("clientId", clientId);
         parms.put("component", component);
         
-        Object[][] events = getEvents(prop);
+        Object[][] events = getEvents(prop, clientId);
         Object[][] formEvents = filterFormEvents(prop, parms, cycle);
         
         if (events.length < 1 && formEvents.length < 1)
@@ -160,7 +160,7 @@
             
             parms.put("target", target);
             parms.put("url", url);
-            parms.put("events", getEvents(prop));
+            parms.put("events", getEvents(prop, null));
             parms.put("formEvents", filterFormEvents(prop, parms, cycle));
             
             _scriptSource.getScript(resource).execute(component, cycle, prs, parms);
@@ -220,7 +220,7 @@
      * @param prop The component event properties object the events are managed in.
      * @return A two dimensional array containing all events, or empty array if none exist.
      */
-    Object[][] getEvents(ComponentEventProperty prop)
+    Object[][] getEvents(ComponentEventProperty prop, String clientId)
     {
         Set events = prop.getEvents();
         List ret = new ArrayList();
@@ -236,7 +236,7 @@
                 hash += listeners.get(i).hashCode();
             }
             
-            ret.add(new Object[]{ event, ScriptUtils.functionHash(event + hash) });
+            ret.add(new Object[]{ event, ScriptUtils.functionHash(event + hash + clientId) });
         }
         
         return (Object[][])ret.toArray(new Object[ret.size()][2]);

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventInvoker.java Thu Nov 23 17:16:10 2006
@@ -72,6 +72,7 @@
         }
         
         // Javascript event target element id
+        
         String targetId = (String)event.getTarget().get("id");
         
         if (hasElementEvents(targetId)) {
@@ -86,11 +87,16 @@
     {
         List listeners = prop.getEventListeners(event.getName());
         
+        String targetId = (String)event.getTarget().get("id");
+        if (targetId == null)
+            return;
+        
         for (int i=0; i < listeners.size(); i++) {
             EventBoundListener eventListener = (EventBoundListener)listeners.get(i);
             
             // ensure ~only~ the method that targeted this event gets called!
-            if (!eventListener.getComponentId().equals(event.getTarget().get("id")))
+            
+            if (!targetId.startsWith(eventListener.getComponentId()))
                 continue;
             
             IComponent container = component.getContainer();

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DefaultResponseBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DefaultResponseBuilder.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DefaultResponseBuilder.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/DefaultResponseBuilder.java Thu Nov 23 17:16:10 2006
@@ -215,7 +215,7 @@
     {
         writer.begin("script");
         writer.attribute("type", "text/javascript");
-        writer.printRaw("<!--");
+        writer.printRaw("<!--\n");
     }
     
     /** 
@@ -223,7 +223,7 @@
      */
     public void endBodyScript(IMarkupWriter writer, IRequestCycle cycle)
     {
-        writer.printRaw("\n\n// -->");
+        writer.printRaw("\n// -->");
         writer.end();
     }
 
@@ -232,7 +232,6 @@
      */
     public void writeBodyScript(IMarkupWriter writer, String script, IRequestCycle cycle)
     {
-        writer.printRaw("\n\n");
         writer.printRaw(script);
     }
 
@@ -257,7 +256,7 @@
         writer.println();
         writer.printRaw("dojo.addOnLoad(function(e) {\n");
         
-        writer.printRaw("\n\n" + preloadName + " = [];\n");
+        writer.printRaw(preloadName + " = [];\n");
         writer.printRaw("if (document.images)\n");
         writer.printRaw("{\n");
         writer.printRaw(script);

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/util/PageRenderSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/util/PageRenderSupportImpl.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/util/PageRenderSupportImpl.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/util/PageRenderSupportImpl.java Thu Nov 23 17:16:10 2006
@@ -19,6 +19,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.hivemind.Locatable;
 import org.apache.hivemind.Location;
 import org.apache.hivemind.Resource;
@@ -145,12 +146,17 @@
     
     public void addBodyScript(IComponent target, String script)
     {
-        if (!_builder.isBodyScriptAllowed(target)) return;
+        if (!_builder.isBodyScriptAllowed(target)) 
+            return;
+        
+        String val = StringUtils.stripToEmpty(script);
+        if (val.length() <= 0)
+            return;
         
         if (_bodyScript == null)
-            _bodyScript = new StringBuffer(script.length());
+            _bodyScript = new StringBuffer(val.length());
 
-        _bodyScript.append(script);
+        _bodyScript.append(val);
     }
     
     public void addInitializationScript(String script)
@@ -160,13 +166,17 @@
 
     public void addInitializationScript(IComponent target, String script)
     {
-        if (!_builder.isInitializationScriptAllowed(target)) return;
+        if (!_builder.isInitializationScriptAllowed(target)) 
+            return;
+        
+        String val = StringUtils.stripToEmpty(script);
+        if (val.length() <= 0)
+            return;
         
         if (_initializationScript == null)
-            _initializationScript = new StringBuffer(script.length() + 1);
+            _initializationScript = new StringBuffer(val.length() + 1);
         
-        _initializationScript.append(script);
-        _initializationScript.append('\n');
+        _initializationScript.append("\n").append(val);
     }
     
     public void addExternalScript(Resource scriptLocation)
@@ -176,7 +186,8 @@
     
     public void addExternalScript(IComponent target, Resource scriptLocation)
     {
-        if (!_builder.isExternalScriptAllowed(target)) return;
+        if (!_builder.isExternalScriptAllowed(target)) 
+            return;
         
         if (_externalScripts == null)
             _externalScripts = new ArrayList();
@@ -227,7 +238,7 @@
     {
         if (!Tapestry.isEmpty(_externalScripts))
             writeExternalScripts(writer, cycle);
-
+        
         if (!(any(_bodyScript) || any(_imageInitializations)))
             return;
         
@@ -237,7 +248,7 @@
         {
             _builder.writeImageInitializations(writer, _imageInitializations.toString(), _preloadName, cycle);
         }
-
+        
         if (any(_bodyScript))
         {
             _builder.writeBodyScript(writer, _bodyScript.toString(), cycle);

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestFor.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestFor.xml?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestFor.xml (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestFor.xml Thu Nov 23 17:16:10 2006
@@ -53,7 +53,15 @@
 		<assert-output name="Test If 4">
 But show this form text too!
 		</assert-output>
+    
+    <assert-output name="Test tags For">
+&lt;li informal="informal-value" id="tags"&gt;Render tag&lt;/li&gt;
+    </assert-output>
         
+    <assert-no-output name="Test no Tags For">
+&lt;li informal="informal-value"&gt;Do not render tag&lt;/li&gt;
+    </assert-no-output>
+
 	</request>		
 
 	<request>

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestImplicitComponents.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestImplicitComponents.xml?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestImplicitComponents.xml (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestImplicitComponents.xml Thu Nov 23 17:16:10 2006
@@ -44,7 +44,7 @@
 					
  	    <assert-output-matches name="Foreach output" subgroup="1">
 <![CDATA[
-<li>\s*(.*?)\s*</li>
+>\s*(.*?)\s*</li>
 ]]>
 			<match>Alpha</match>
 			<match>Beta</match>

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestProtectedLink.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestProtectedLink.xml?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestProtectedLink.xml (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/scripts/TestProtectedLink.xml Thu Nov 23 17:16:10 2006
@@ -90,7 +90,7 @@
 		
 		<assert-output-matches name="Parameters" subgroup="1">
 <![CDATA[
-<li>(.*?)</li>
+>(.*?)</li>
 ]]>
 			<match>6</match>
 			<match>13</match>
@@ -121,7 +121,7 @@
 		
 		<assert-output-matches name="Parameters" subgroup="1">
 <![CDATA[
-<li>(.*?)</li>
+>(.*?)</li>
 ]]>
 			<match>6</match>
 			<match>13</match>

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context34/Home.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context34/Home.html?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context34/Home.html (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test-data/context34/Home.html Thu Nov 23 17:16:10 2006
@@ -2,7 +2,7 @@
 <body>
 
 <p>
-Check the behavour of If, Else, and For.
+Check the behavior of If, Else, and For.
 </p>
 
 	<span jwcid="@If" condition="ognl: !false">Show text!</span>
@@ -26,6 +26,14 @@
         Rewinded value <span jwcid="@Insert" value="ognl: components.vals.index"/> is <span jwcid="@Insert" value="ognl: components.vals.value"/>
     </span>
     
+    <ul>
+      <li jwcid="tags@For" source="ognl: { '1' }" renderTag="true" informal="informal-value">Render tag</li>
+    </ul>
+
+    <ul>
+      <li jwcid="noTags@For" source="ognl: { '1' }" renderTag="false" informal="informal-value">Do not render tag</li>
+    </ul>
+
     <span jwcid="@Form">
 		<span jwcid="@If" condition="ognl: !false">Show form text!</span>
 		<span jwcid="@Else">Do not show form text</span>

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/app/ProtectedLink.page
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/app/ProtectedLink.page?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/app/ProtectedLink.page (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/app/ProtectedLink.page Thu Nov 23 17:16:10 2006
@@ -16,18 +16,18 @@
 -->
 
 <!DOCTYPE page-specification PUBLIC 
-  "-//Apache Software Foundation//Tapestry Specification 3.0//EN" 
-  "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
+  "-//Apache Software Foundation//Tapestry Specification 4.0//EN" 
+  "http://tapestry.apache.org/dtd/Tapestry_4_0.dtd">
 	
 <page-specification class="org.apache.tapestry.junit.mock.app.ProtectedLink">
 
   <component id="border" type="lib:Border">
-  	<static-binding name="title">ProtectedLink</static-binding>
+  	<binding name="title" value="literal:ProtectedLink"/>
   </component>
   
   <component id="link" type="DirectLink">
-  	<binding name="listener" expression="listeners.linkClicked"/>
-  	<binding name="parameters" expression="{ 6, 13, 1999}"/>
+  	<binding name="listener" value="listeners.linkClicked"/>
+  	<binding name="parameters" value="{ 6, 13, 1999}"/>
   </component>
    
 </page-specification>

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/app/ProtectedLinkResult.page
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/app/ProtectedLinkResult.page?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/app/ProtectedLinkResult.page (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/junit/mock/app/ProtectedLinkResult.page Thu Nov 23 17:16:10 2006
@@ -16,22 +16,21 @@
 -->
 
 <!DOCTYPE page-specification PUBLIC 
-  "-//Apache Software Foundation//Tapestry Specification 3.0//EN" 
-  "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
+  "-//Apache Software Foundation//Tapestry Specification 4.0//EN" 
+  "http://tapestry.apache.org/dtd/Tapestry_4_0.dtd">
 	
 <page-specification class="org.apache.tapestry.junit.mock.app.ProtectedLinkResult">
 
   <component id="border" type="lib:Border">
-  	<static-binding name="title">ProtectedLink: Result</static-binding>
+  	<binding name="title" value="literal:ProtectedLink: Result" />
   </component>
   
   <component id="foreach" type="For">
-  	<binding name="source" expression="parameters"/>
-  	<static-binding name="element">li</static-binding>	
+  	<binding name="source" value="parameters"/>
   </component>
   
   <component id="insertParameter" type="Insert">
-  	<binding name="value" expression="components.foreach.value"/>
+  	<binding name="value" value="components.foreach.value"/>
   </component>
    
 </page-specification>

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/DefaultResponseBuilderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/DefaultResponseBuilderTest.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/DefaultResponseBuilderTest.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/services/impl/DefaultResponseBuilderTest.java Thu Nov 23 17:16:10 2006
@@ -60,8 +60,8 @@
 
     private void assertOutput(String expected)
     {
-        assertEquals(expected, _writer.toString());
-
+        assertEquals(_writer.toString(), expected);
+        
         _writer.reset();
     }
     
@@ -140,12 +140,12 @@
         
         builder.beginBodyScript(mw, cycle);
         
-        assertOutput("<script type=\"text/javascript\"><!--");
+        assertOutput("<script type=\"text/javascript\"><!--"+LINE_SEPARATOR);
         
         builder.writeImageInitializations(mw, imageInit, preload, cycle);
         
         assertOutput(LINE_SEPARATOR
-                + "dojo.addOnLoad(function(e) {\n\n\n"
+                + "dojo.addOnLoad(function(e) {\n"
                 + preload + " = [];\n"
                 + "if (document.images)\n"
                 + "{\n" + imageInit + "}\n"
@@ -153,12 +153,11 @@
         
         builder.writeBodyScript(mw, bscript, cycle);
         
-        assertOutput("\n\n"
-                + bscript);
+        assertOutput(bscript);
         
         builder.endBodyScript(mw, cycle);
         
-        assertOutput("\n\n// --></script>");
+        assertOutput("\n// --></script>");
         
         verify();
     }

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/util/TestPageRenderSupport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/util/TestPageRenderSupport.java?view=diff&rev=478737&r1=478736&r2=478737
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/util/TestPageRenderSupport.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/util/TestPageRenderSupport.java Thu Nov 23 17:16:10 2006
@@ -97,10 +97,11 @@
     private void assertOutput(String expected)
     {
         String actual = _writer.toString();
+        
         // Replace any system line feeds with \n
         actual = actual.replaceAll(SYSTEM_NEWLINE, TEST_NEWLINE);
-
-        assertEquals(expected, actual);
+        
+        assertEquals(actual, expected);
 
         _writer.reset();
     }
@@ -139,15 +140,14 @@
         prs.writeBodyScript(writer, cycle);
 
         assertOutput(new String[]
-        { "<script type=\"text/javascript\"><!--",
-                "dojo.addOnLoad(function(e) {", "","",
+        { "<script type=\"text/javascript\"><!--","",
+                "dojo.addOnLoad(function(e) {",
                 "tapestry._preload = [];", "if (document.images)", "{",
                 "  tapestry._preload[0] = new Image();",
                 "  tapestry._preload[0].src = \"/foo/bar.gif\";",
                 "  tapestry._preload[1] = new Image();",
-                "  tapestry._preload[1].src = \"/zip/zap.png\";", "}", "});", "", 
-                "myBodyScript();",
-                "", "// --></script>" });
+                "  tapestry._preload[1].src = \"/zip/zap.png\";", "}", "});myBodyScript();",
+                "// --></script>" });
 
         verify();
     }
@@ -160,20 +160,20 @@
         IMarkupWriter writer = createWriter();
 
         replay();
-
+        
         PageRenderSupportImpl prs = new PageRenderSupportImpl(factory, "NAMESPACE", l, newBuilder(writer));
-
+        
         assertEquals("NAMESPACE_preload[0].src", prs.getPreloadedImageReference("/foo/bar.gif"));
-
+        
         prs.writeBodyScript(writer, cycle);
-
+        
         assertOutput(new String[]
-        {"<script type=\"text/javascript\"><!--", 
-                "dojo.addOnLoad(function(e) {","","",
+        {"<script type=\"text/javascript\"><!--", "",
+                "dojo.addOnLoad(function(e) {",
                 "NAMESPACE_preload = [];", "if (document.images)", "{",
                 "  NAMESPACE_preload[0] = new Image();",
                 "  NAMESPACE_preload[0].src = \"/foo/bar.gif\";", "}",
-                "});","",
+                "});",
                 "// --></script>" });
 
         verify();
@@ -195,9 +195,9 @@
         prs.writeBodyScript(writer, cycle);
 
         assertOutput(new String[]
-        { "<script type=\"text/javascript\"><!--","", 
+        { "<script type=\"text/javascript\"><!--",
                 "myBodyScript();",
-                "", "// --></script>" });
+                "// --></script>" });
 
         verify();
     }
@@ -253,9 +253,9 @@
         
         assertOutput(new String[]
         { "<script type=\"text/javascript\"><!--",
-                "dojo.addOnLoad(function(e) {",
-                "myInitializationScript1();", "myInitializationScript2();", 
-                "});", "// --></script>" });
+                "dojo.addOnLoad(function(e) {","",
+                "myInitializationScript1();", "myInitializationScript2();});",
+                "// --></script>" });
 
         verify();
     }