You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2021/09/21 14:02:26 UTC

[wicket] branch master updated: WICKET-6921 Avoid updating hidden forms (#478)

This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/wicket.git


The following commit(s) were added to refs/heads/master by this push:
     new 9bfb779  WICKET-6921 Avoid updating hidden forms (#478)
9bfb779 is described below

commit 9bfb7794d18ff441590ff86ae0e0dc35d9f2048f
Author: Mathieu Mitchell <ma...@gmail.com>
AuthorDate: Tue Sep 21 10:02:21 2021 -0400

    WICKET-6921 Avoid updating hidden forms (#478)
    
    Currently, MultipartFormComponentListener ensures form enctype is
    correct on the client-side when visibility for multipart-enabling
    components is toggled. It does so by visiting all form components,
    detecting multipart-enabling components and emitting javascript code
    to refresh the encoding type on the client-side.
    
    There are a few issues solved by this commit:
    
    - The identified form component could be part of a hidden hierarchy.
      This prevents finding it in the DOM, and using it's form attribute
      to set the form enctype.
    
    - There could be more than one form with multipart-enabling components
      which would require an enctype refresh on the client-side.
    
    This commit modifies MultipartFormComponentListener to find all forms,
    ensure they are visible in the hierarchy, then visiting all form
    components to find multipart-enabling. A single statement is emitted
    per form.
---
 .../http/MultipartFormComponentListener.java         | 20 +++++++++++---------
 .../http/MultipartFormComponentListenerPage.html     |  5 +++--
 .../http/MultipartFormComponentListenerPage.java     |  9 +++++++++
 .../http/MultipartFormComponentListenerTest.java     | 12 ++++++++++--
 4 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/protocol/http/MultipartFormComponentListener.java b/wicket-core/src/main/java/org/apache/wicket/protocol/http/MultipartFormComponentListener.java
index f5572ed..37f01d6 100644
--- a/wicket-core/src/main/java/org/apache/wicket/protocol/http/MultipartFormComponentListener.java
+++ b/wicket-core/src/main/java/org/apache/wicket/protocol/http/MultipartFormComponentListener.java
@@ -37,15 +37,17 @@ public class MultipartFormComponentListener implements AjaxRequestTarget.IListen
 	@Override
 	public void onBeforeRespond(final Map<String, Component> map, final AjaxRequestTarget target)
 	{
-		target.getPage().visitChildren(FormComponent.class, (IVisitor<FormComponent<?>, Void>) (formComponent, visit) -> {
-			if (formComponent.isMultiPart())
-			{
-				Form<?> form = formComponent.getForm();
-				boolean multiPart = form.isMultiPart();
-				String enctype = multiPart ? Form.ENCTYPE_MULTIPART_FORM_DATA : ENCTYPE_URL_ENCODED;
-				target.appendJavaScript(String.format("Wicket.$('%s').form.enctype='%s'",
-						formComponent.getMarkupId(), enctype));
-				visit.stop();
+		target.getPage().visitChildren(Form.class, (IVisitor<Form<?>, Void>) (form, formVisitor) -> {
+			if (form.isVisibleInHierarchy()) {
+				form.visitFormComponents((formComponent, visit) -> {
+					if (formComponent.isMultiPart()) {
+						String enctype = form.isMultiPart() ? Form.ENCTYPE_MULTIPART_FORM_DATA : ENCTYPE_URL_ENCODED;
+						target.appendJavaScript(String.format("Wicket.$('%s').enctype='%s'", form.getMarkupId(), enctype));
+						visit.stop();
+					}
+				});
+			} else {
+				formVisitor.dontGoDeeper();
 			}
 		});
 	}
diff --git a/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerPage.html b/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerPage.html
index eb741e8..c713696 100644
--- a/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerPage.html
+++ b/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerPage.html
@@ -8,10 +8,11 @@
 	<form wicket:id="form">
 		<input type="text" wicket:id="textField" /><br/>
 		<select  wicket:id="dropDown"></select><br/>
-		<input wicket:id="fileUpload" type="file" /><br/> 
+		<input wicket:id="fileUpload" type="file" /><br/>
 		<input type="submit" value="save" wicket:id="submitButton" /><br/><br/><br/>
 	</form>
 	content of textfield or error: <div wicket:id="label"></div>
-	
+
+	<a wicket:id="toggleVisibility">Toggle form visibility</a>
 </body>
 </html>
diff --git a/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerPage.java b/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerPage.java
index d0b7842..0473f6a 100644
--- a/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerPage.java
+++ b/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerPage.java
@@ -20,6 +20,8 @@ import java.util.ArrayList;
 
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.Button;
@@ -76,5 +78,12 @@ public class MultipartFormComponentListenerPage extends WebPage {
 			}
 		});
 
+		add(new AjaxLink<>("toggleVisibility") {
+			@Override
+			public void onClick(AjaxRequestTarget target) {
+				form.setVisible(!form.isVisible());
+				target.add(form);
+			}
+		});
 	}
 }
diff --git a/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerTest.java b/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerTest.java
index b5cbf26..4c87ddb 100644
--- a/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/protocol/http/MultipartFormComponentListenerTest.java
@@ -17,6 +17,7 @@
 package org.apache.wicket.protocol.http;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.apache.wicket.markup.html.form.Form;
@@ -26,6 +27,7 @@ import org.junit.jupiter.api.Test;
 
 /**
  * https://issues.apache.org/jira/browse/WICKET-6914
+ * https://issues.apache.org/jira/browse/WICKET-6921
  */
 class MultipartFormComponentListenerTest extends WicketTestCase
 {
@@ -36,16 +38,22 @@ class MultipartFormComponentListenerTest extends WicketTestCase
         tester.assertRenderedPage(MultipartFormComponentListenerPage.class);
 
         TagTester formTagTester = tester.getTagByWicketId("form");
+        String formMarkupId = formTagTester.getAttribute("id");
+
         assertEquals(Form.ENCTYPE_MULTIPART_FORM_DATA, formTagTester.getAttribute("enctype"));
 
         tester.getRequest().setAttribute("form:dropDown", 1);
         tester.executeAjaxEvent("form:dropDown", "change");
         String ajaxResponse = tester.getLastResponseAsString();
-        assertTrue(ajaxResponse.contains(".form.enctype='" + MultipartFormComponentListener.ENCTYPE_URL_ENCODED + "'})();"));
+        assertTrue(ajaxResponse.contains("Wicket.$('"+formMarkupId+"').enctype='" + MultipartFormComponentListener.ENCTYPE_URL_ENCODED + "'})();"));
 
         tester.getRequest().setAttribute("form:dropDown", 2);
         tester.executeAjaxEvent("form:dropDown", "change");
         ajaxResponse = tester.getLastResponseAsString();
-        assertTrue(ajaxResponse.contains(".form.enctype='" + Form.ENCTYPE_MULTIPART_FORM_DATA + "'})();"));
+        assertTrue(ajaxResponse.contains("Wicket.$('"+formMarkupId+"').enctype='" + Form.ENCTYPE_MULTIPART_FORM_DATA + "'})();"));
+
+        tester.clickLink("toggleVisibility");
+        ajaxResponse = tester.getLastResponseAsString();
+        assertFalse(ajaxResponse.contains("Wicket.$('"+formMarkupId+"').enctype="), "enctype should not be pushed on hidden elements");
     }
 }