Author: hlship
Date: Sun Oct 10 17:27:43 2010
New Revision: 1006321

URL: http://svn.apache.org/viewvc?rev=1006321&view=rev
Log:
TAP5-1300: Make use of a special CSS class name of forms to prevent submission 
(when using Ajax updates)
Also, some simplifications to how JavaScript initializations occur in an Ajax 
update

Modified:
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinker.java
    
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.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/PartialMarkupDocumentLinkerTest.java
    
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.java

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinker.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinker.java?rev=1006321&r1=1006320&r2=1006321&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinker.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinker.java
 Sun Oct 10 17:27:43 2010
@@ -28,8 +28,6 @@ public class PartialMarkupDocumentLinker
 
     private final JSONArray stylesheets = new JSONArray();
 
-    private final Map<InitializationPriority, StringBuilder> priorityToScript 
= CollectionFactory.newMap();
-
     private final Map<InitializationPriority, JSONObject> priorityToInits = 
CollectionFactory.newMap();
 
     public void addScriptLink(String scriptURL)
@@ -50,16 +48,8 @@ public class PartialMarkupDocumentLinker
 
     public void addScript(InitializationPriority priority, String script)
     {
-        StringBuilder builder = priorityToScript.get(priority);
-
-        if (builder == null)
-        {
-            builder = new StringBuilder();
-            priorityToScript.put(priority, builder);
-        }
-
-        builder.append(script);
-        builder.append("\n");
+        throw new UnsupportedOperationException(
+                "DocumentLinker.addScript() is not implemented for partial 
page renders.");
     }
 
     public void setInitialization(InitializationPriority priority, JSONObject 
initialization)
@@ -81,25 +71,16 @@ public class PartialMarkupDocumentLinker
         if (stylesheets.length() > 0)
             reply.put("stylesheets", stylesheets);
 
-        StringBuilder master = new StringBuilder();
         JSONArray inits = new JSONArray();
 
         for (InitializationPriority p : InitializationPriority.values())
         {
-            StringBuilder builder = priorityToScript.get(p);
-
-            if (builder != null)
-                master.append(builder);
-
             JSONObject init = priorityToInits.get(p);
 
             if (init != null)
                 inits.put(init);
         }
 
-        if (master.length() > 0)
-            reply.put("script", master.toString());
-
         if (inits.length() > 0)
             reply.put("inits", inits);
     }

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java?rev=1006321&r1=1006320&r2=1006321&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImpl.java
 Sun Oct 10 17:27:43 2010
@@ -61,6 +61,8 @@ public class JavaScriptSupportImpl imple
 
     private final JavaScriptStackPathConstructor stackPathConstructor;
 
+    private final boolean partialMode;
+
     private FieldFocusPriority focusPriority;
 
     private String focusFieldId;
@@ -71,6 +73,24 @@ public class JavaScriptSupportImpl imple
         this(linker, javascriptStackSource, stackPathConstructor, new 
IdAllocator(), false);
     }
 
+    /**
+     * @param linker
+     *            responsible for assembling all the information gathered by 
JavaScriptSupport and
+     *            attaching it to the Document (for a full page render) or to 
the JSON response (in a partial render)
+     * @param javascriptStackSource
+     *            source of information about {...@link JavaScriptStack}s, 
used when handling the import
+     *            of libraries and stacks (often, to handle transitive 
dependencies)
+     * @param stackPathConstructor
+     *            encapsulates the knowledge of how to represent a stack 
(which may be converted
+     *            from a series of JavaScript libraries into a single virtual 
JavaScript library)
+     * @param idAllocator
+     *            used when allocating unique ids (it is usually 
pre-initialized in an Ajax request to ensure
+     *            that newly allocated ids do not conflict with previous 
renders and partial updates)
+     * @param partialMode
+     *            if true, then the JSS configures itself for a partial page 
render (part of an Ajax request)
+     *            which automatically assumes the "core" library has been 
added (to the original page render)
+     *            and makes other minor changes to behavior.
+     */
     public JavaScriptSupportImpl(DocumentLinker linker, JavaScriptStackSource 
javascriptStackSource,
             JavaScriptStackPathConstructor stackPathConstructor, IdAllocator 
idAllocator, boolean partialMode)
     {
@@ -78,6 +98,7 @@ public class JavaScriptSupportImpl imple
         this.idAllocator = idAllocator;
         this.javascriptStackSource = javascriptStackSource;
         this.stackPathConstructor = stackPathConstructor;
+        this.partialMode = partialMode;
 
         // In partial mode, assume that the infrastructure stack is already 
present
         // (from the original page render).
@@ -167,13 +188,21 @@ public class JavaScriptSupportImpl imple
 
     public void addScript(InitializationPriority priority, String format, 
Object... arguments)
     {
-        addCoreStackIfNeeded();
         assert priority != null;
         assert InternalUtils.isNonBlank(format);
 
+        addCoreStackIfNeeded();
+
         String newScript = arguments.length == 0 ? format : 
String.format(format, arguments);
 
-        linker.addScript(priority, newScript);
+        if (partialMode)
+        {
+            addInitializerCall(priority, "evalScript", newScript);
+        }
+        else
+        {
+            linker.addScript(priority, newScript);
+        }
     }
 
     public void addScript(String format, Object... arguments)
@@ -266,12 +295,12 @@ public class JavaScriptSupportImpl imple
 
         stylesheetLinks.addAll(stack.getStylesheets());
 
+        addedStacks.put(stackName, true);
+
         String initialization = stack.getInitialization();
 
         if (initialization != null)
-            linker.addScript(InitializationPriority.IMMEDIATE, initialization);
-
-        addedStacks.put(stackName, true);
+            addScript(InitializationPriority.IMMEDIATE, initialization);
     }
 
     public void importStylesheet(Asset stylesheet)

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=1006321&r1=1006320&r2=1006321&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
 Sun Oct 10 17:27:43 2010
@@ -89,6 +89,11 @@ var Tapestry = {
        /** Time, in seconds, that console messages are visible. */
        CONSOLE_DURATION : 10,
 
+       /** CSS Class added to a <form> element that directs Tapestry to 
prevent normal
+        *  (HTTP POST) form submission, in favor of Ajax (XmlHttpRequest) 
submission.
+        */
+       PREVENT_SUBMISSION : "t-prevent-submission",
+       
        /** Initially, false, set to true once the page is fully loaded. */
        pageLoaded : false,
 
@@ -153,7 +158,7 @@ var Tapestry = {
 
        },
 
-       /*
+       /**
         * Adds a callback function that will be invoked when the DOM is loaded
         * (which occurs *before* window.onload, which has to wait for images 
and
         * such to load first. This simply observes the dom:loaded event on the
@@ -297,8 +302,9 @@ var Tapestry = {
         * <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>inits</dt>
+        * <dd>Defines a set of calls to Tapestry.init() to perform 
initialization after the DOM
+        * has been updated.</dd>
         * <dt>stylesheets</dt>
         * <dd>Array of hashes, each hash has key href and optional key 
media</dd>
         * 
@@ -325,34 +331,31 @@ var Tapestry = {
                        /* Let the caller do its thing first (i.e., modify the 
DOM). */
                        callback.call(this);
 
-                       Tapestry.executeReplyScripts(reply.script, reply.inits);
+                       /* And handle the scripts after the DOM is updated. */
+                       Tapestry.executeInits(reply.inits);
                });
        },
 
        /**
-        * Called from Tapestry.loadScriptsInReply to load the script block and 
any
+        * Called from Tapestry.loadScriptsInReply to load  any
         * initializations from the Ajax partial page render response. Calls
-        * Tapestry.onDomLoadedCallback() last.
+        * Tapestry.onDomLoadedCallback() last. This logic must be deferred
+        * until after the DOM is fully updated, as initialization often
+        * refer to DOM elements.
         * 
-        * @param scriptBlock
-        *            block of JavaScript to evaluate (may be null)
         * @param initializations
         *            array of parameters to pass to Tapestry.init(), one 
invocation
         *            per element (may be null)
         */
-       executeReplyScripts : function(scriptBlock, initializations) {
+       executeInits : function(initializations) {
 
-               if (scriptBlock)
-                       eval(scriptBlock);
-
-               if (initializations)
-                       $A(initializations).each(function(spec) {
-                               Tapestry.init(spec);
-                       });
+               $A(initializations).each(function(spec) {
+                       Tapestry.init(spec);
+               });
 
                Tapestry.onDomLoadedCallback();
-
        },
+       
 
        /**
         * Default function for handling a communication error during an Ajax
@@ -917,6 +920,13 @@ Tapestry.Initializer = {
                $(id).activate();
        },
 
+       /**
+        * evalScript is a synonym for the JavaScript eval function. It is used
+        * in Ajax requests to handle any setup code that does not
+        * fit into a standard Tapestry.Initializer call.
+        */
+       evalScript : eval,
+       
        ajaxFormLoop : function(spec) {
                var rowInjector = $(spec.rowInjector);
 
@@ -1012,8 +1022,8 @@ Tapestry.Initializer = {
 
                if (element.tagName == "FORM") {
 
-                       element.getFormEventManager().preventSubmission = true;
-
+                       element.addClassName(Tapestry.PREVENT_SUBMISSION);
+                       
                        /*
                         * After the form is validated and prepared, this code 
will process
                         * the form submission via an Ajax call. The original 
submit event
@@ -1477,7 +1487,7 @@ Tapestry.FormEventManager = Class.create
 
        handleSubmit : function(domevent) {
 
-               /**
+               /*
                 * Necessary because we set the onsubmit property of the form, 
rather
                 * than observing the event. But that's because we want to 
specfically
                 * overwrite any other handlers.
@@ -1527,7 +1537,7 @@ Tapestry.FormEventManager = Class.create
                 * via Ajax.Request.
                 */
 
-               if (this.preventSubmission) {
+               if (this.form.hasClassName(Tapestry.PREVENT_SUBMISSION)) {
                        domevent.stop();
 
                        /*
@@ -2081,9 +2091,9 @@ Tapestry.ScriptManager = {
  * In the spirit of $(), $T() exists to access a hash of extra data about an
  * element. In release 5.1 and prior, a hash attached to the element by 
Tapestry
  * was returned. In 5.2, Prototype's storage object is returned, which is less
- * like to cause memory leaks in IE.
+ * likely to cause memory leaks in IE.
  * 
- * @deprecated With no specific replacement
+ * @deprecated With no specific replacement. To be removed after Tapestry 5.2.
  * @param element
  *            an element instance or element id
  * @return object Prototype storage object for the element

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinkerTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinkerTest.java?rev=1006321&r1=1006320&r2=1006321&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinkerTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PartialMarkupDocumentLinkerTest.java
 Sun Oct 10 17:27:43 2010
@@ -24,36 +24,14 @@ import org.testng.annotations.Test;
 
 public class PartialMarkupDocumentLinkerTest extends Assert
 {
-    @Test
+    @Test(expectedExceptions = UnsupportedOperationException.class)
     public void script()
     {
         PartialMarkupDocumentLinker linker = new PartialMarkupDocumentLinker();
 
         linker.addScript(InitializationPriority.NORMAL, "foo();");
-        linker.addScript(InitializationPriority.NORMAL, "bar();");
-
-        JSONObject reply = new JSONObject();
-
-        linker.commit(reply);
-
-        assertEquals(reply.get("script"), "foo();\nbar();\n");
-    }
-
-    @Test
-    public void script_with_priorty()
-    {
-        PartialMarkupDocumentLinker linker = new PartialMarkupDocumentLinker();
-
-        linker.addScript(InitializationPriority.LATE, "late();");
-        linker.addScript(InitializationPriority.NORMAL, "normal();");
-        linker.addScript(InitializationPriority.IMMEDIATE, "immediate();");
-        linker.addScript(InitializationPriority.EARLY, "early();");
-
-        JSONObject reply = new JSONObject();
-
-        linker.commit(reply);
 
-        assertEquals(reply.get("script"), 
"immediate();\nearly();\nnormal();\nlate();\n");
+        throw new IllegalStateException("Unreachable code.");
     }
 
     @Test

Modified: 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.java?rev=1006321&r1=1006320&r2=1006321&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ajax/JavaScriptSupportImplTest.java
 Sun Oct 10 17:27:43 2010
@@ -65,11 +65,12 @@ public class JavaScriptSupportImplTest e
     }
 
     @Test
-    public void no_stack_or_dom_loading_callback_in_partial_mode()
+    public void partial_mode_add_script()
     {
         DocumentLinker linker = mockDocumentLinker();
 
-        linker.addScript(InitializationPriority.NORMAL, "doSomething();");
+        linker.setInitialization(InitializationPriority.NORMAL, new JSONObject(
+                "{ 'evalScript' : [ 'doSomething();' ] }"));
 
         replay();
 


Reply via email to