You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2007/02/26 21:44:14 UTC

svn commit: r511996 - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/internal/services/ main/java/org/apache/tapestry/internal/test/ main/java/org/apache/tapestry/services/ test/app1/WEB-INF/ test/java/org/apache/tapestry...

Author: hlship
Date: Mon Feb 26 12:44:12 2007
New Revision: 511996

URL: http://svn.apache.org/viewvc?view=rev&rev=511996
Log:
TAPESTRY-1302: Extend PageRenderSupport to allow script links and script text to be added to the overall rendered page.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DocumentScriptBuilder.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DocumentScriptBuilderImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/ScriptDemo.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ScriptDemo.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/DocumentScriptBuilderImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/add_script.txt
    tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/add_script_links.txt
    tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/duplicate_script_links_ignored.txt
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/PageRenderSupport.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/dom/DOMTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DocumentScriptBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DocumentScriptBuilder.java?view=auto&rev=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DocumentScriptBuilder.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DocumentScriptBuilder.java Mon Feb 26 12:44:12 2007
@@ -0,0 +1,44 @@
+// Copyright 2007 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.services;
+
+import org.apache.tapestry.dom.Document;
+
+/**
+ * Responsible for building script links and script blocks into a document.
+ */
+public interface DocumentScriptBuilder
+{
+    /** Adds a link to load a script. Scripts will be loaded only once. */
+    void addScriptLink(String scriptURL);
+
+    /**
+     * Adds JavaScript code. The code is collected into a single block that is injected just before
+     * the close body tag of the page.
+     * 
+     * @param script
+     *            statement to add to the block (a newline will be appended as well)
+     */
+    void addScript(String script);
+
+    /**
+     * Updates the supplied Document, locating the html/body element and adding script links (to the
+     * top) and a script block (to the end).
+     * 
+     * @param document
+     *            to be updated
+     */
+    void updateDocument(Document document);
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DocumentScriptBuilderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DocumentScriptBuilderImpl.java?view=auto&rev=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DocumentScriptBuilderImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DocumentScriptBuilderImpl.java Mon Feb 26 12:44:12 2007
@@ -0,0 +1,74 @@
+// Copyright 2007 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.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+
+import java.util.List;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.ioc.internal.util.InternalUtils;
+
+public class DocumentScriptBuilderImpl implements DocumentScriptBuilder
+{
+    private final List<String> _scripts = newList();
+
+    private final StringBuilder _scriptBlock = new StringBuilder();
+
+    public void addScriptLink(String scriptURL)
+    {
+        if (_scripts.contains(scriptURL))
+            return;
+
+        _scripts.add(scriptURL);
+    }
+
+    public void addScript(String script)
+    {
+        if (InternalUtils.isBlank(script))
+            return;
+
+        _scriptBlock.append(script);
+        _scriptBlock.append("\n");
+    }
+
+    public void updateDocument(Document document)
+    {
+        Element body = document.find("html/body");
+
+        if (body == null)
+            return;
+
+        for (int i = 0; i < _scripts.size(); i++)
+        {
+            String scriptURL = _scripts.get(i);
+
+            body.elementAt(i, "script", "src", scriptURL, "type", "text/javascript");
+        }
+
+        if (_scriptBlock.length() > 0)
+        {
+            Element e = body.element("script", "type", "text/javascript", "language", "javascript");
+            e.raw("\n<!--\n");
+
+            e.text(_scriptBlock.toString());
+
+            e.raw("// -->\n");
+        }
+
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java?view=diff&rev=511996&r1=511995&r2=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java Mon Feb 26 12:44:12 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -12,18 +12,39 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.services;
-
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.ioc.internal.util.Defense;
 import org.apache.tapestry.ioc.internal.util.IdAllocator;
-import org.apache.tapestry.services.PageRenderSupport;
-
-public class PageRenderSupportImpl implements PageRenderSupport
-{
-    private final IdAllocator _idAllocator = new IdAllocator();
-
-    public String allocateClientId(String id)
-    {
-        return _idAllocator.allocateId(id);
-    }
-
-}
+import org.apache.tapestry.services.PageRenderSupport;
+
+public class PageRenderSupportImpl implements PageRenderSupport
+{
+    private final IdAllocator _idAllocator = new IdAllocator();
+
+    private final DocumentScriptBuilder _builder;
+
+    public PageRenderSupportImpl(DocumentScriptBuilder builder)
+    {
+        _builder = builder;
+    }
+
+    public String allocateClientId(String id)
+    {
+        return _idAllocator.allocateId(id);
+    }
+
+    public void addScriptLink(Asset scriptAsset)
+    {
+        Defense.notNull(scriptAsset, "scriptAsset");
+
+        _builder.addScriptLink(scriptAsset.toString());
+    }
+
+    public void addScript(String script)
+    {
+        _builder.addScript(script);
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java?view=diff&rev=511996&r1=511995&r2=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java Mon Feb 26 12:44:12 2007
@@ -18,6 +18,12 @@
 import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.isA;
 
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.Reader;
 import java.util.Arrays;
 import java.util.Locale;
 import java.util.ResourceBundle;
@@ -490,5 +496,42 @@
     protected final PageResponseRenderer newPageResponseRenderer()
     {
         return newMock(PageResponseRenderer.class);
+    }
+
+    /**
+     * Reads the content of a file into a string. Each line is trimmed of line separators and
+     * leading/trailing whitespace.
+     * 
+     * @param trim
+     *            trim each line of whitespace
+     */
+    protected final String readFile(String file, boolean trim) throws Exception
+    {
+        InputStream is = getClass().getResourceAsStream(file);
+        is = new BufferedInputStream(is);
+        Reader reader = new BufferedReader(new InputStreamReader(is));
+        LineNumberReader in = new LineNumberReader(reader);
+
+        StringBuilder buffer = new StringBuilder();
+
+        while (true)
+        {
+            String line = in.readLine();
+
+            if (line == null)
+                break;
+
+            if (trim)
+                line = line.trim();
+
+            buffer.append(line);
+
+            if (!trim)
+                buffer.append("\n");
+        }
+
+        in.close();
+
+        return buffer.toString();
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/PageRenderSupport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/PageRenderSupport.java?view=diff&rev=511996&r1=511995&r2=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/PageRenderSupport.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/PageRenderSupport.java Mon Feb 26 12:44:12 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -12,25 +12,46 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.services;
-
+package org.apache.tapestry.services;
+
+import org.apache.tapestry.Asset;
 import org.apache.tapestry.ioc.internal.util.IdAllocator;
-
-/**
- * Provides support to all components that render. This is primarily about generating unique
- * client-side ids (very important for JavaScript generation) as well as accumulating JavaScript to
- * be sent to the client.
- */
-public interface PageRenderSupport
-{
-    /**
-     * Allocates a unique id based on the component's id. In some cases, the return value will not
-     * precisely match the input value (an underscore and a unique index value may be appended).
-     * 
-     * @param id
-     *            the component id from which a unique id will be generated
-     * @return a unqiue id for this rendering of the page
-     * @see IdAllocator
-     */
-    String allocateClientId(String id);
-}
+
+/**
+ * Provides support to all components that render. This is primarily about generating unique
+ * client-side ids (very important for JavaScript generation) as well as accumulating JavaScript to
+ * be sent to the client.
+ */
+public interface PageRenderSupport
+{
+    /**
+     * Allocates a unique id based on the component's id. In some cases, the return value will not
+     * precisely match the input value (an underscore and a unique index value may be appended).
+     * 
+     * @param id
+     *            the component id from which a unique id will be generated
+     * @return a unqiue id for this rendering of the page
+     * @see IdAllocator
+     */
+    String allocateClientId(String id);
+
+    /**
+     * Adds a new script asset to the page. Assets are added uniquely, and appear as &lt;script&gt;
+     * elements just inside the &lt;body&gt; element of the rendered page. Duplicate requests to add
+     * the same script are quietly ignored.
+     * 
+     * @param scriptAsset
+     *            asset to the script to add
+     */
+    void addScriptLink(Asset scriptAsset);
+
+    /**
+     * Adds a script statement to the page's script block (which appears at the end of the page,
+     * just before the &lt/body&gt; tag).
+     * 
+     * @param script
+     *            statement or block of statements to add to the block. Blank or null values will be
+     *            ignored.
+     */
+    void addScript(String script);
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=511996&r1=511995&r2=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Mon Feb 26 12:44:12 2007
@@ -90,6 +90,8 @@
 import org.apache.tapestry.internal.services.CookiesImpl;
 import org.apache.tapestry.internal.services.DefaultInjectionProvider;
 import org.apache.tapestry.internal.services.DefaultValidationDelegateCommand;
+import org.apache.tapestry.internal.services.DocumentScriptBuilder;
+import org.apache.tapestry.internal.services.DocumentScriptBuilderImpl;
 import org.apache.tapestry.internal.services.EnvironmentImpl;
 import org.apache.tapestry.internal.services.EnvironmentalWorker;
 import org.apache.tapestry.internal.services.FieldValidatorDefaultSourceImpl;
@@ -972,12 +974,21 @@
         {
             public void setup(Environment environment)
             {
-                environment.push(PageRenderSupport.class, new PageRenderSupportImpl());
+                DocumentScriptBuilder builder = new DocumentScriptBuilderImpl();
+
+                environment.push(DocumentScriptBuilder.class, builder);
+                environment.push(PageRenderSupport.class, new PageRenderSupportImpl(builder));
             }
 
             public void cleanup(Environment environment)
             {
                 environment.pop(PageRenderSupport.class);
+
+                Document document = environment.peek(Document.class);
+
+                DocumentScriptBuilder builder = environment.pop(DocumentScriptBuilder.class);
+
+                builder.updateDocument(document);
             }
         });
 

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/ScriptDemo.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/ScriptDemo.html?view=auto&rev=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/ScriptDemo.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/ScriptDemo.html Mon Feb 26 12:44:12 2007
@@ -0,0 +1,16 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  
+  <h1>Script Demo</h1>
+
+  <div id="errors" class="t-error" style="display:none;">
+    <ul>
+      <li>There are no actual errors on this page.</li>
+      <li>But eventually, the Errors component will "slide out" errors messages, etc.</li>
+    </ul>
+   </div> 
+   
+  <p>
+    <a href="#" id="show">show errors</a>
+  </p>
+  
+</html>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html?view=diff&rev=511996&r1=511995&r2=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html Mon Feb 26 12:44:12 2007
@@ -116,6 +116,9 @@
                     <li>
                         <a t:type="PageLink" page="pagelinkcontext">PageLink Context Demo</a> --
                         passing explicit context in a page render link </li>
+                  <li>
+                    <a t:type="pagelink" page="scriptdemo">Script Demo</a> -- basic JavaScript integration
+                  </li>
                 </ul>
             </td>
         </tr>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/dom/DOMTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/dom/DOMTest.java?view=diff&rev=511996&r1=511995&r2=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/dom/DOMTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/dom/DOMTest.java Mon Feb 26 12:44:12 2007
@@ -14,50 +14,16 @@
 
 package org.apache.tapestry.dom;
 
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.LineNumberReader;
-import java.io.Reader;
 
-import org.testng.Assert;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
 import org.testng.annotations.Test;
 
 /**
  * Tests for a number of DOM node classes, including {@link org.apache.tapestry.dom.Element} and
  * {@link org.apache.tapestry.dom.Document}.
  */
-public class DOMTest extends Assert
+public class DOMTest extends InternalBaseTestCase
 {
-    /**
-     * Reads the content of a file into a string. Each line is trimmed of line separators and
-     * leading/trailing whitespace.
-     */
-    private String readFile(String file) throws Exception
-    {
-        InputStream is = getClass().getResourceAsStream(file);
-        is = new BufferedInputStream(is);
-        Reader reader = new BufferedReader(new InputStreamReader(is));
-        LineNumberReader in = new LineNumberReader(reader);
-
-        StringBuilder buffer = new StringBuilder();
-
-        while (true)
-        {
-            String line = in.readLine();
-
-            if (line == null)
-                break;
-
-            buffer.append(line.trim());
-        }
-
-        in.close();
-
-        return buffer.toString();
-    }
-
     @Test
     public void document_with_empty_root_element()
     {
@@ -89,7 +55,7 @@
         e.attribute("fred", "flintstone");
         e.attribute("barney", "rubble");
 
-        assertEquals(d.toString(), readFile("document_with_root_element_and_attributes.txt"));
+        assertEquals(d.toString(), readFile("document_with_root_element_and_attributes.txt", true));
     }
 
     @Test
@@ -111,7 +77,7 @@
 
         assertSame(p.getParent(), e);
 
-        assertEquals(d.toString(), readFile("nested_elements.txt"));
+        assertEquals(d.toString(), readFile("nested_elements.txt", true));
     }
 
     @Test

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=511996&r1=511995&r2=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Mon Feb 26 12:44:12 2007
@@ -939,4 +939,19 @@
 
         assertTextSeries("//li[%d]", 1, "fred", "7", "true");
     }
+
+    @Test
+    public void injected_script_links()
+    {
+        _selenium.open(BASE_URL);
+
+        clickAndWait("link=Script Demo");
+
+        assertTextSeries(
+                "//script[%d]/@src",
+                1,
+                "/assets/scriptaculous/prototype.js",
+                "/assets/scriptaculous/scriptaculous.js");
+
+    }
 }

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ScriptDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ScriptDemo.java?view=auto&rev=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ScriptDemo.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/ScriptDemo.java Mon Feb 26 12:44:12 2007
@@ -0,0 +1,40 @@
+// Copyright 2007 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.integration.app1.pages;
+
+import org.apache.tapestry.Asset;
+import org.apache.tapestry.annotations.Environmental;
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.services.PageRenderSupport;
+
+public class ScriptDemo
+{
+    @Environmental
+    private PageRenderSupport _support;
+
+    @Inject("${tapestry.scriptaculous}/prototype.js")
+    private Asset _prototype;
+
+    @Inject("${tapestry.scriptaculous}/scriptaculous.js")
+    private Asset _script;
+
+    void afterRender()
+    {
+        _support.addScriptLink(_prototype);
+        _support.addScriptLink(_script);
+
+        _support.addScript("$('show').onclick = function() { new Effect.Appear($('errors')); }");
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/DocumentScriptBuilderImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/DocumentScriptBuilderImplTest.java?view=auto&rev=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/DocumentScriptBuilderImplTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/DocumentScriptBuilderImplTest.java Mon Feb 26 12:44:12 2007
@@ -0,0 +1,98 @@
+// Copyright 2007 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.services;
+
+import org.apache.tapestry.dom.Document;
+import org.apache.tapestry.dom.XMLMarkupModel;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.testng.annotations.Test;
+
+public class DocumentScriptBuilderImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void do_nothing_if_no_body()
+    {
+        Document document = new Document();
+
+        document.newRootElement("not-html").text("not an HTML document");
+
+        DocumentScriptBuilder builder = new DocumentScriptBuilderImpl();
+
+        builder.addScript("foo.js");
+        builder.addScript("doSomething();");
+
+        builder.updateDocument(document);
+
+        assertEquals(document.toString(), "<not-html>not an HTML document</not-html>");
+    }
+
+    @Test
+    public void add_script_links() throws Exception
+    {
+        Document document = new Document(new XMLMarkupModel());
+
+        document.newRootElement("html").element("body").element("p").text(
+                "Ready to be updated with scripts.");
+
+        DocumentScriptBuilder builder = new DocumentScriptBuilderImpl();
+
+        builder.addScriptLink("foo.js");
+        builder.addScriptLink("bar/baz.js");
+
+        builder.updateDocument(document);
+
+        assertEquals(document.toString(), readFile("add_script_links.txt", true));
+    }
+
+    @Test
+    public void duplicate_script_links_ignored() throws Exception
+    {
+        Document document = new Document();
+
+        document.newRootElement("html").element("body").element("p").text(
+                "Ready to be updated with scripts.");
+
+        DocumentScriptBuilder builder = new DocumentScriptBuilderImpl();
+
+        for (int i = 0; i < 3; i++)
+        {
+            builder.addScriptLink("foo.js");
+            builder.addScriptLink("bar/baz.js");
+            builder.addScriptLink("biff.js");
+        }
+
+        builder.updateDocument(document);
+
+        assertEquals(document.toString(), readFile("duplicate_script_links_ignored.txt", true));
+    }
+
+    @Test
+    public void add_script() throws Exception
+    {
+        Document document = new Document();
+
+        document.newRootElement("html").element("body").element("p").text(
+                "Ready to be updated with scripts.");
+
+        DocumentScriptBuilder builder = new DocumentScriptBuilderImpl();
+
+        builder.addScript("doSomething();");
+        builder.addScript("doSomethingElse();");
+
+        builder.updateDocument(document);
+
+        assertEquals(document.toString(), readFile("add_script.txt", false).trim());
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/add_script.txt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/add_script.txt?view=auto&rev=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/add_script.txt (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/add_script.txt Mon Feb 26 12:44:12 2007
@@ -0,0 +1,6 @@
+<html><body><p>Ready to be updated with scripts.</p><script language="javascript" type="text/javascript">
+<!--
+doSomething();
+doSomethingElse();
+// -->
+</script></body></html>
\ No newline at end of file

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/add_script_links.txt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/add_script_links.txt?view=auto&rev=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/add_script_links.txt (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/add_script_links.txt Mon Feb 26 12:44:12 2007
@@ -0,0 +1 @@
+<html><body><script src="foo.js" type="text/javascript"/><script src="bar/baz.js" type="text/javascript"/><p>Ready to be updated with scripts.</p></body></html>
\ No newline at end of file

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/duplicate_script_links_ignored.txt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/duplicate_script_links_ignored.txt?view=auto&rev=511996
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/duplicate_script_links_ignored.txt (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/internal/services/duplicate_script_links_ignored.txt Mon Feb 26 12:44:12 2007
@@ -0,0 +1 @@
+<html><body><script src="foo.js" type="text/javascript"></script><script src="bar/baz.js" type="text/javascript"></script><script src="biff.js" type="text/javascript"></script><p>Ready to be updated with scripts.</p></body></html>
\ No newline at end of file