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 2010/10/10 19:27:44 UTC
svn commit: r1006321 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/internal/services/
main/java/org/apache/tapestry5/internal/services/ajax/
main/resources/org/apache/tapestry5/
test/java/org/apache/tapestry5/internal...
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();