Author: hlship
Date: Fri Oct 31 16:42:34 2008
New Revision: 709601

URL: http://svn.apache.org/viewvc?rev=709601&view=rev
Log:
TAP5-313: Provide configuration to move links to JavaScript libraries to the 
top of the page

Added:
    
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/add_script_links_at_top.txt
Modified:
    tapestry/tapestry5/trunk/src/site/apt/cookbook/lib.apt
    tapestry/tapestry5/trunk/src/site/apt/guide/conf.apt
    tapestry/tapestry5/trunk/src/site/apt/index.apt
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/DocumentLinkerImplTest.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/add_script_links.txt

Modified: tapestry/tapestry5/trunk/src/site/apt/cookbook/lib.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/cookbook/lib.apt?rev=709601&r1=709600&r2=709601&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/cookbook/lib.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/cookbook/lib.apt Fri Oct 31 16:42:34 
2008
@@ -223,7 +223,9 @@
   the application was deployed as happyapp.war).
 
   Tapestry uses a far-future expiration date for classpath assets; this allows 
browsers to aggresively cache
-  the file, but this causes a problem should a later version of the library 
change the file.
+  the file, but this causes a problem should a later version of the library 
change the file.     This is discussed
+  in detail in
+  {{{http://developer.yahoo.com/performance/rules.html#expires}Yahoo's 
Performance Best Practices}}.
 
   To handle this problem, you should map your library assets to a versioned 
folder. This can be accomplished using
   another contribution from the HappyModule, this time to the 
ClasspathAssetAliasManager service

Modified: tapestry/tapestry5/trunk/src/site/apt/guide/conf.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/guide/conf.apt?rev=709601&r1=709600&r2=709601&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/guide/conf.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/guide/conf.apt Fri Oct 31 16:42:34 
2008
@@ -173,6 +173,12 @@
     If true, then the page may only be accessed via HTTPS.  The 
{{{../apidocs/org/apache/tapestry5/annotations/[EMAIL PROTECTED]
     annotation will set this value to true.
 
+  [tapestry.script-at-top]
+    If true, then links for external JavaScript libraries will be placed at 
the top of the page, just inside the
+    \<body\> element, rather than in the default location (at the bottom). The 
\<script\> block for per-page
+    initialization will be placed at the bottom of the page in either case.  
The default (scripts at the bottom)
+    was chosen in accordance with 
{{{http://developer.yahoo.com/performance/rules.html#js_bottom}Yahoo Peformance 
Best Practices}}. 
+
   [tapestry.scriptaculous]
     The path to the embedded copy of 
{{{http://script.aculo.us/}script.aculo.us}} packaged with Tapestry. This value 
may be overridden
     to use a different version of the script.aculo.us library. Tapestry's 
default version is 1.8.1

Modified: tapestry/tapestry5/trunk/src/site/apt/index.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/index.apt?rev=709601&r1=709600&r2=709601&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/src/site/apt/index.apt (original)
+++ tapestry/tapestry5/trunk/src/site/apt/index.apt Fri Oct 31 16:42:34 2008
@@ -68,6 +68,8 @@
 
 New And Of Note
 
+  * You can now configure Tapestry to move \<script\> links to the top of the 
page.
+
   * Event handler methods for Ajax requests may now return a page name, page 
class or page instance to force
     the browser to redirect to the page.
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java?rev=709601&r1=709600&r2=709601&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
 Fri Oct 31 16:42:34 2008
@@ -91,4 +91,11 @@
      * This is used by the default exception report handler service.
      */
     public static final String EXCEPTION_REPORT_PAGE = 
"tapestry.exception-report-page";
+
+    /**
+     * If true, then links for external JavaScript libraries are placed at the 
top of the document (just inside the
+     * &lt;body&gt; element).  If false, the default, then the libraries are 
placed at the bottom of the document.
+     * Per-page initialization always goes at the bottom.
+     */
+    public static final String SCRIPTS_AT_TOP = "tapestry.script-at-top";
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java?rev=709601&r1=709600&r2=709601&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/DocumentLinkerImpl.java
 Fri Oct 31 16:42:34 2008
@@ -34,9 +34,12 @@
 
     private final boolean developmentMode;
 
-    public DocumentLinkerImpl(boolean productionMode)
+    private final boolean scriptsAtTop;
+
+    public DocumentLinkerImpl(boolean productionMode, boolean scriptsAtTop)
     {
         developmentMode = !productionMode;
+        this.scriptsAtTop = scriptsAtTop;
     }
 
     public void addStylesheetLink(String styleURL, String media)
@@ -97,7 +100,7 @@
 
         // TAPESTRY-2364
 
-        if (!scripts.isEmpty()) addScriptLinksForIncludedScripts(body, 
scripts);
+        addScriptLinksForIncludedScripts(body, scripts);
 
         addDynamicScriptBlock(body);
     }
@@ -130,16 +133,24 @@
     }
 
     /**
-     * Adds a script link for each included script.  This is only invoked if 
there are scripts to include.
+     * Adds a script link for each included script.
      *
      * @param body    element to add the script links to
-     * @param scripts
+     * @param scripts scripts to add
      */
     protected void addScriptLinksForIncludedScripts(Element body, List<String> 
scripts)
     {
-        for (String scriptURL : scripts)
+        int count = scripts.size();
+
+        for (int i = 0; i < count; i++)
         {
-            body.element("script", "src", scriptURL, "type", 
"text/javascript");
+            String scriptURL = scripts.get(i);
+
+            Element element = scriptsAtTop
+                              ? body.elementAt(i, "script")
+                              : body.element("script");
+
+            element.attributes("src", scriptURL, "type", "text/javascript");
         }
     }
 

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=709601&r1=709600&r2=709601&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
 Fri Oct 31 16:42:34 2008
@@ -1469,6 +1469,9 @@
                                          
@Symbol(SymbolConstants.PRODUCTION_MODE)
                                          final boolean productionMode,
 
+                                         
@Symbol(SymbolConstants.SCRIPTS_AT_TOP)
+                                         final boolean scriptsAtTop,
+
                                          
@Path("${tapestry.default-stylesheet}")
                                          final Asset stylesheetAsset,
 
@@ -1485,7 +1488,7 @@
         {
             public void renderMarkup(MarkupWriter writer, MarkupRenderer 
renderer)
             {
-                DocumentLinkerImpl linker = new 
DocumentLinkerImpl(productionMode);
+                DocumentLinkerImpl linker = new 
DocumentLinkerImpl(productionMode, scriptsAtTop);
 
                 RenderSupportImpl support = new RenderSupportImpl(linker, 
symbolSource, assetSource,
 
@@ -1858,6 +1861,8 @@
                           "WEB-INF/${" + 
InternalConstants.TAPESTRY_APP_NAME_SYMBOL + "}.properties");
 
         configuration.add(SymbolConstants.EXCEPTION_REPORT_PAGE, 
"ExceptionReport");
+
+        configuration.add(SymbolConstants.SCRIPTS_AT_TOP, "false");
     }
 
 
@@ -2049,9 +2054,9 @@
     /**
      * Contributes filters: <dl> <dt>Ajax</dt> <dd>Determines if the request 
is Ajax oriented, and redirects to an
      * alternative handler if so</dd> <dt>ImmediateRender</dt> <dd>When [EMAIL 
PROTECTED]
-     * 
org.apache.tapestry5.SymbolConstants#SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS 
immediate action response rendering}
-     * is enabled, generates the markup response (instead of a page redirect 
response, which is the normal behavior)
-     * </dd> <dt>Secure</dt> <dd>Sends a redirect if an non-secure request 
accesses a secure page</dd></dl>
+     * SymbolConstants#SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS immediate action 
response rendering} is enabled, generates
+     * the markup response (instead of a page redirect response, which is the 
normal behavior) </dd> <dt>Secure</dt>
+     * <dd>Sends a redirect if an non-secure request accesses a secure 
page</dd></dl>
      */
     public void 
contributeComponentEventRequestHandler(OrderedConfiguration<ComponentEventRequestFilter>
 configuration,
                                                        final 
RequestSecurityManager requestSecurityManager,

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js?rev=709601&r1=709600&r2=709601&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
 Fri Oct 31 16:42:34 2008
@@ -249,19 +249,45 @@
     /**
      * Passed the JSON content of a Tapestry partial markup response, extracts
      * the script and stylesheet information.  JavaScript libraries and 
stylesheets are loaded,
-     * then any script code is evaluated.  All three keys are optional:
+     * then the callback is invoked.  All three keys are optional:
      * <dl>
+     * <dt>redirectURL</dt> <dd>URL to redirect to (in which case, the 
callback is not invoked)</dd>
      * <dt>scripts</dt><dd>Array of strings (URIs of scripts)</dd>
      * <dt>stylesheets</dt><dd>Array of hashes, each hash has key href and 
optional key media</dd>
-     * <dt>script</dt> <dd>JavaScript to be executed once all scripts are 
loaded</dd></dl>
+     *
+     * @param reply JSON response object from the server
+     * @param callback function invoked after the scripts have all loaded 
(presumably, to update the DOM)
      */
-    processScriptInReply : function(reply)
+    loadScriptsInReply : function(reply, callback)
     {
-        Tapestry.ScriptManager.addScripts(reply.scripts, reply.script);
+        var redirectURL = reply.redirectURL;
+
+        if (redirectURL)
+        {
+            window.location.pathname = redirectURL;
+
+            // Don't bother loading scripts or invoking the callback.
+
+            return;
+        }
 
         Tapestry.ScriptManager.addStylesheets(reply.stylesheets);
 
-        Tapestry.onDomLoadedCallback();
+        Tapestry.ScriptManager.addScripts(reply.scripts,
+                function()
+                {
+                    callback.call(this);
+
+                    // After the callback updates the DOM
+                    // (presumably), continue on with
+                    // evaluating the reply.script
+                    // and other final steps.
+
+                    if (reply.script) eval(reply.script);
+
+                    Tapestry.onDomLoadedCallback();
+
+                });
     },
 
     /**
@@ -270,7 +296,6 @@
     ajaxFailureHandler : function(response)
     {
         var message = response.getHeader("X-Tapestry-ErrorMessage");
-        "A communication error with the server has occurred.";
 
         Tapestry.updateAjaxConsole("t-err", "Communication with the server 
failed: " + message);
 
@@ -1263,26 +1288,17 @@
     },
 
     /**
-     *  Invoked with a reply (i.e., transport.responseJSON), this updates the 
zone's div
+     * Invoked with a reply (i.e., transport.responseJSON), this updates the 
zone's div
      * and processes any JavaScript in the reply.  The response should have a
      * content key, and may have  script, scripts and stylesheets keys.
      * @param reply response in JSON format appropriate to a Tapestry.Zone
      */
     processReply : function(reply)
     {
-        var redirect = reply.redirectURL;
-
-        if (redirect)
-        {
-            window.location.pathname = redirect;
-        }
-        else
+        Tapestry.loadScriptsInReply(reply, function()
         {
-
             this.show(reply.content);
-
-            Tapestry.processScriptInReply(reply);
-        }
+        }.bind(this));
     },
 
     /** Initiates an Ajax request to update this zone by sending a request
@@ -1401,24 +1417,22 @@
                 var param = { };
                 param[this.below ? "after" : "before"] = newElement;
 
-                // Add the new element with the downloaded content.
-
-                this.element.insert(param);
-
-                // Update the empty element with the content from the server
-
-                newElement.update(reply.content);
+                Tapestry.loadScriptsInReply(reply, function()
+                {
+                    // Add the new element with the downloaded content.
 
-                newElement.id = reply.elementId;
+                    this.element.insert(param);
 
-                // Handle any scripting issues.
+                    // Update the empty element with the content from the 
server
 
-                Tapestry.processScriptInReply(reply);
+                    newElement.update(reply.content);
 
-                // Add some animation to reveal it all.
+                    newElement.id = reply.elementId;
 
-                this.showFunc(newElement);
+                    // Add some animation to reveal it all.
 
+                    this.showFunc(newElement);
+                }.bind(this));
             }.bind(this);
 
             Tapestry.ajaxRequest(this.url, successHandler);
@@ -1429,20 +1443,19 @@
 });
 
 /**
- * Coordinates the execution of JavaScript code blocks (via eval) with the 
loading
- * of an array of <script> elements.
+ * Wait for a set of JavaScript libraries to load (in terms of DOM script 
elements), then invokes a callback function.
  */
-Tapestry.DependentExecutor = Class.create({
+Tapestry.ScriptLoadMonitor = Class.create({
 
-    initialize : function(prereqs, dependent)
+    initialize : function(scriptElements, callback)
     {
-        this.dependent = dependent;
+        this.callback = callback;
         this.loaded = 0;
-        this.toload = prereqs.length;
+        this.toload = scriptElements.length;
 
         var executor = this;
 
-        prereqs.each(function (scriptElement)
+        scriptElements.each(function (scriptElement)
         {
             if (Prototype.Browser.IE)
             {
@@ -1464,16 +1477,20 @@
                 scriptElement.onload = 
executor.loadComplete.bindAsEventListener(executor, scriptElement);
             }
         });
+
+        // If no scripts to actually load, call the callback immediately.
+
+        if (this.toload == 0) this.callback.call(this);
     },
 
-    loadComplete : function(element)
+    loadComplete : function()
     {
         this.loaded++;
 
         // Evaluated the dependent script only once all the elements have 
loaded.
 
         if (this.loaded == this.toload)
-            eval(this.dependent);
+            this.callback.call(this);
     }
 });
 
@@ -1523,7 +1540,13 @@
         return false;
     },
 
-    addScripts: function(scripts, dependent)
+    /**
+     * Add scripts, as needed, to the document, then waits for them all to 
load, and finally, calls
+     * the callback function.
+     * @param scripts        Array of scripts to load
+     * @param callback invoked after scripts are loaded                        
        
+     */
+    addScripts: function(scripts, callback)
     {
         var added = new Array();
 
@@ -1552,15 +1575,7 @@
 
         }
 
-        if (!dependent) return;
-
-        if (added.length)
-        {
-            new Tapestry.DependentExecutor(added, dependent);
-            return;
-        }
-
-        eval(dependent);
+        new Tapestry.ScriptLoadMonitor(added, callback);
     },
 
     addStylesheets : function(stylesheets)

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/DocumentLinkerImplTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/DocumentLinkerImplTest.java?rev=709601&r1=709600&r2=709601&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/DocumentLinkerImplTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/DocumentLinkerImplTest.java
 Fri Oct 31 16:42:34 2008
@@ -33,7 +33,7 @@
 
         document.newRootElement("not-html").text("not an HTML document");
 
-        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false);
 
         linker.addScript("foo.js");
         linker.addScript("doSomething();");
@@ -50,10 +50,11 @@
 
         
document.newRootElement("html").element("body").element("p").text("Ready to be 
updated with scripts.");
 
-        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false);
 
         linker.addScriptLink("foo.js");
         linker.addScriptLink("bar/baz.js");
+        linker.addScript("pageInitialization();");
 
         linker.updateDocument(document);
 
@@ -61,13 +62,31 @@
     }
 
     @Test
+    public void add_script_links_at_top() throws Exception
+    {
+        Document document = new Document(new XMLMarkupModel());
+
+        
document.newRootElement("html").element("body").element("p").text("Ready to be 
updated with scripts at top.");
+
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true, true);
+
+        linker.addScriptLink("foo.js");
+        linker.addScriptLink("bar/baz.js");
+        linker.addScript("pageInitialization();");
+
+        linker.updateDocument(document);
+
+        check(document, "add_script_links_at_top.txt");
+    }
+
+    @Test
     public void add_style_links() throws Exception
     {
         Document document = new Document(new XMLMarkupModel());
 
         
document.newRootElement("html").element("body").element("p").text("Ready to be 
updated with styles.");
 
-        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false);
 
         linker.addStylesheetLink("foo.css", null);
         linker.addStylesheetLink("bar/baz.css", "print");
@@ -84,7 +103,7 @@
 
         
document.newRootElement("html").element("body").element("p").text("Ready to be 
updated with styles.");
 
-        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false);
 
         linker.addStylesheetLink("foo.css", null);
         linker.addStylesheetLink("bar/baz.css", "print");
@@ -105,7 +124,7 @@
         document.newRootElement("html").element("head").comment("existing 
head").getParent()
                 .element("body").text("body content");
 
-        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false);
 
         linker.addStylesheetLink("foo.css", null);
 
@@ -121,7 +140,7 @@
 
         
document.newRootElement("html").element("body").element("p").text("Ready to be 
updated with scripts.");
 
-        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false);
 
         for (int i = 0; i < 3; i++)
         {
@@ -142,7 +161,7 @@
 
         
document.newRootElement("html").element("body").element("p").text("Ready to be 
updated with scripts.");
 
-        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false);
 
         linker.addScript("doSomething();");
         linker.addScript("doSomethingElse();");
@@ -159,7 +178,7 @@
 
         
document.newRootElement("html").element("body").element("p").text("Ready to be 
updated with scripts.");
 
-        DocumentLinkerImpl linker = new DocumentLinkerImpl(false);
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(false, false);
 
         linker.addScriptLink("foo.js");
 
@@ -178,7 +197,7 @@
 
         
document.newRootElement("html").element("notbody").element("p").text("Ready to 
be updated with scripts.");
 
-        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false);
 
         linker.addScriptLink("foo.js");
 
@@ -194,13 +213,12 @@
 
         
document.newRootElement("html").element("body").element("p").text("Ready to be 
updated with scripts.");
 
-        DocumentLinkerImpl linker = new DocumentLinkerImpl(true);
+        DocumentLinkerImpl linker = new DocumentLinkerImpl(true, false);
 
         linker.addScript("for (var i = 0; i < 5; i++)  { doIt(i); }");
 
         linker.updateDocument(document);
 
         assertEquals(document.toString(), 
readFile("script_written_raw.txt").trim());
-
     }
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/add_script_links.txt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/add_script_links.txt?rev=709601&r1=709600&r2=709601&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/add_script_links.txt
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/add_script_links.txt
 Fri Oct 31 16:42:34 2008
@@ -1,2 +1,8 @@
 <?xml version="1.0"?>
-<html><body><p>Ready to be updated with scripts.</p><script src="foo.js" 
type="text/javascript"/><script src="bar/baz.js" 
type="text/javascript"/></body></html>
\ No newline at end of file
+<html><body><p>Ready to be updated with scripts.</p><script src="foo.js" 
type="text/javascript"/><script src="bar/baz.js" 
type="text/javascript"/><script type="text/javascript">
+<!--
+Tapestry.onDOMLoaded(function() {
+pageInitialization();
+});
+// -->
+</script></body></html>
\ No newline at end of file

Added: 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/add_script_links_at_top.txt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/add_script_links_at_top.txt?rev=709601&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/add_script_links_at_top.txt
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry5/internal/services/add_script_links_at_top.txt
 Fri Oct 31 16:42:34 2008
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<html><body><script src="foo.js" type="text/javascript"/><script 
src="bar/baz.js" type="text/javascript"/><p>Ready to be updated with scripts at 
top.</p><script type="text/javascript">
+<!--
+Tapestry.onDOMLoaded(function() {
+pageInitialization();
+});
+// -->
+</script></body></html>
\ No newline at end of file


Reply via email to