You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2021/07/20 08:51:16 UTC
[wicket] 01/02: WICKET-6902 allow prepend and append
This is an automated email from the ASF dual-hosted git repository.
svenmeier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/wicket.git
commit fa65fd754ca9345dd966d04204521d7edbe645ec
Author: Sven Meier <sv...@apache.org>
AuthorDate: Sat Jul 17 00:18:02 2021 +0200
WICKET-6902 allow prepend and append
up-to including #onAfterRespond()
---
.../org/apache/wicket/ajax/AjaxRequestHandler.java | 12 +----
.../org/apache/wicket/ajax/AjaxRequestTarget.java | 45 +++++++++++++----
.../org/apache/wicket/page/PartialPageUpdate.java | 22 +++++++-
.../apache/wicket/ajax/AjaxRequestHandlerTest.java | 58 ++++++++++++++++------
4 files changed, 98 insertions(+), 39 deletions(-)
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
index 78699bf..fd54daa 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestHandler.java
@@ -145,19 +145,9 @@ public class AjaxRequestHandler extends AbstractPartialPageRequestHandler implem
final Map<String, Component> components = Collections
.unmodifiableMap(markupIdToComponent);
- // create response that will be used by listeners to append javascript
- final AjaxRequestTarget.IJavaScriptResponse jsresponse = new AjaxRequestTarget.IJavaScriptResponse()
- {
- @Override
- public void addJavaScript(String script)
- {
- writeEvaluations(response, Collections.<CharSequence> singleton(script));
- }
- };
-
for (AjaxRequestTarget.IListener listener : listeners)
{
- listener.onAfterRespond(components, jsresponse);
+ listener.onAfterRespond(components, AjaxRequestHandler.this);
}
}
}
diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java
index 6c874dc..2e1efb6 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/AjaxRequestTarget.java
@@ -38,35 +38,54 @@ public interface AjaxRequestTarget extends IPartialPageRequestHandler, ILoggable
interface IListener
{
/**
- * Triggered before ajax request target begins its response cycle
+ * Triggered before the target begins writing components.
*
* @param map
* modifiable map (markupId -> component) of components already added to the target
* @param target
* the target itself. Could be used to add components or to append/prepend
- * javascript
+ * JavaScript
*
*/
default void onBeforeRespond(Map<String, Component> map, AjaxRequestTarget target)
{}
/**
- * Triggered after ajax request target is done with its response cycle. At this point only
- * additional javascript can be output to the response using the provided
- * {@link AjaxRequestTarget.IJavaScriptResponse} object
+ * Triggered after the target has written components. At this point only
+ * additional JavaScript can be added to the response.
*
- * NOTE: During this stage of processing any calls to target that manipulate the response
- * (adding components, javascript) will have no effect
+ * NOTE: During this stage of processing any calls that manipulate components will result in
+ * an exception.
*
* @param map
* read-only map:markupId->component of components already added to the target
* @param response
- * response object that can be used to output javascript
+ * response object that can be used to output JavaScript
+ *
+ * @deprecated implement {@link #onAfterRespond(Map, AjaxRequestTarget)} instead
*/
+ @Deprecated
default void onAfterRespond(Map<String, Component> map, AjaxRequestTarget.IJavaScriptResponse response)
{}
/**
+ * Triggered after the target has written components. At this point only
+ * additional JavaScript can be added to the response.
+ *
+ * NOTE: During this stage of processing any calls that manipulate components will result in
+ * an exception. After notification of all listeners no JavaScript can be added any longer.
+ *
+ * @param map
+ * read-only map:markupId->component of components already added to the target
+ * @param target
+ * the target itself. Could be used to append/prepend JavaScript
+ */
+ default void onAfterRespond(Map<String, Component> map, AjaxRequestTarget target)
+ {
+ onAfterRespond(map, script -> target.appendJavaScript(script));
+ }
+
+ /**
* Triggered for every Ajax behavior. Can be used to configure common settings.
*
* @param behavior
@@ -80,19 +99,23 @@ public interface AjaxRequestTarget extends IPartialPageRequestHandler, ILoggable
}
/**
- * An ajax javascript response that allows users to add javascript to be executed on the client
+ * An ajax JavaScript response that allows users to add JavaScript to be executed on the client
* side
*
* @author ivaynberg
+ *
+ * @deprecated use {@link AjaxRequestTargetprependJavaScript(CharSequence)} and
+ * {@link AjaxRequestTarget#appendJavaScript(CharSequence)} instead
*/
+ @Deprecated
@FunctionalInterface
interface IJavaScriptResponse
{
/**
- * Adds more javascript to the ajax response that will be executed on the client side
+ * Adds more JavaScript to the ajax response that will be executed on the client side
*
* @param script
- * javascript
+ * JavaScript
*/
void addJavaScript(String script);
}
diff --git a/wicket-core/src/main/java/org/apache/wicket/page/PartialPageUpdate.java b/wicket-core/src/main/java/org/apache/wicket/page/PartialPageUpdate.java
index 2988956..da9e89b 100644
--- a/wicket-core/src/main/java/org/apache/wicket/page/PartialPageUpdate.java
+++ b/wicket-core/src/main/java/org/apache/wicket/page/PartialPageUpdate.java
@@ -104,6 +104,12 @@ public abstract class PartialPageUpdate
protected transient boolean componentsFrozen;
/**
+ * A flag that indicates that javascripts cannot be added anymore.
+ * See https://issues.apache.org/jira/browse/WICKET-6902
+ */
+ protected transient boolean javascriptsFrozen;
+
+ /**
* Buffer of response body.
*/
protected final ResponseBuffer bodyBuffer;
@@ -161,12 +167,14 @@ public abstract class PartialPageUpdate
// process added components
writeComponents(response, encoding);
+ onAfterRespond(response);
+
+ javascriptsFrozen = true;
+
// queue up prepend javascripts. unlike other steps these are executed out of order so that
// components can contribute them from during rendering.
writePriorityEvaluations(response, prependJavaScripts);
- onAfterRespond(response);
-
// execute the dom ready javascripts as first javascripts
// after component replacement
List<CharSequence> evaluationScripts = new ArrayList<>();
@@ -493,6 +501,11 @@ public abstract class PartialPageUpdate
{
Args.notNull(javascript, "javascript");
+ if (javascriptsFrozen)
+ {
+ throw new IllegalStateException("A partial update of the page is being rendered, JavaScript can no longer be added");
+ }
+
appendJavaScripts.add(javascript);
}
@@ -505,6 +518,11 @@ public abstract class PartialPageUpdate
public final void prependJavaScript(CharSequence javascript)
{
Args.notNull(javascript, "javascript");
+
+ if (javascriptsFrozen)
+ {
+ throw new IllegalStateException("A partial update of the page is being rendered, JavaScript can no longer be added");
+ }
prependJavaScripts.add(javascript);
}
diff --git a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxRequestHandlerTest.java b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxRequestHandlerTest.java
index 66cc73d..f2c1236 100644
--- a/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxRequestHandlerTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/ajax/AjaxRequestHandlerTest.java
@@ -21,14 +21,15 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
+
import java.io.IOException;
import java.lang.reflect.Constructor;
-import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.MockPageWithLink;
@@ -38,6 +39,9 @@ import org.apache.wicket.event.IEvent;
import org.apache.wicket.markup.IMarkupResourceStreamProvider;
import org.apache.wicket.markup.html.WebComponent;
import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.request.IRequestHandler;
+import org.apache.wicket.request.cycle.IRequestCycleListener;
+import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.util.encoding.UrlEncoder;
import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.StringResourceStream;
@@ -260,20 +264,24 @@ class AjaxRequestHandlerTest extends WicketTestCase
}
/**
- * @see <a href="https://issues.apache.org/jira/browse/WICKET-3263">WICKET-3263</a>
+ * WICKET-3263<br>
+ * WICKET-6902
*/
@Test
void globalAjaxRequestTargetListeners()
{
- final ValidatingAjaxRequestTargetListener listener = new ValidatingAjaxRequestTargetListener();
-
+ JavaScriptPrependerAppender listener = new JavaScriptPrependerAppender();
+
tester.getApplication().getAjaxRequestTargetListeners().add(listener);
+ tester.getApplication().getRequestCycleListeners().add(listener);
tester.startPage(TestEventPage.class);
tester.clickLink(MockPageWithLinkAndComponent.LINK_ID, true);
- assertTrue(listener.onBeforeRespondExecuted);
- assertTrue(listener.onAfterRespondExecuted);
+ tester.assertContains("BEFORE_RESPOND_PREPEND");
+ tester.assertContains("BEFORE_RESPOND_APPEND");
+ tester.assertContains("AFTER_RESPOND_PREPEND");
+ tester.assertContains("AFTER_RESPOND_APPEND");
}
/**
@@ -396,23 +404,43 @@ class AjaxRequestHandlerTest extends WicketTestCase
}
}
- private static class ValidatingAjaxRequestTargetListener implements AjaxRequestTarget.IListener
+ /**
+ * Listener to AjaxRequestTarget and RequestCycle to test prepending and appending of
+ * JavaScript.
+ */
+ private static class JavaScriptPrependerAppender implements AjaxRequestTarget.IListener, IRequestCycleListener
{
- boolean onBeforeRespondExecuted = false;
- boolean onAfterRespondExecuted = false;
-
@Override
public void onBeforeRespond(Map<String, Component> map, AjaxRequestTarget target)
{
- onBeforeRespondExecuted = true;
-
+ target.prependJavaScript("BEFORE_RESPOND_PREPEND");
+ target.appendJavaScript("BEFORE_RESPOND_APPEND");
}
@Override
- public void onAfterRespond(Map<String, Component> map,
- AjaxRequestTarget.IJavaScriptResponse response)
+ public void onAfterRespond(Map<String, Component> map, AjaxRequestTarget target)
{
- onAfterRespondExecuted = true;
+ target.prependJavaScript("AFTER_RESPOND_PREPEND");
+ target.appendJavaScript("AFTER_RESPOND_APPEND");
+ }
+
+ @Override
+ public void onRequestHandlerExecuted(RequestCycle cycle, IRequestHandler handler) {
+ if (handler instanceof AjaxRequestHandler) {
+ try {
+ ((AjaxRequestHandler) handler).appendJavaScript("FAIL");
+
+ fail("appendJavaScript should not be allowed at this state");
+ } catch (IllegalStateException javascriptFrozen) {
+ }
+
+ try {
+ ((AjaxRequestHandler) handler).prependJavaScript("FAIL");
+
+ fail("prependJavaScript should not be allowed at this state");
+ } catch (IllegalStateException javascriptFrozen) {
+ }
+ }
}
}