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/17 15:29:53 UTC
[wicket] 01/01: WICKET-6902 allow prepend and append
This is an automated email from the ASF dual-hosted git repository.
svenmeier pushed a commit to branch WICKET-6902-js-after-components
in repository https://gitbox.apache.org/repos/asf/wicket.git
commit 1f2064274c8c5385e66a71ff3445bdf84871561a
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()
---
pom.xml | 5 +++
.../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 | 44 ++++++++++++++-------
5 files changed, 90 insertions(+), 38 deletions(-)
diff --git a/pom.xml b/pom.xml
index eb5088a..241d0a5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1153,6 +1153,11 @@
<className>org/apache/wicket/pageStore/IPageStore</className>
<method>void end(org.apache.wicket.pageStore.IPageContext)</method>
</difference>
+ <difference>
+ <differenceType>7012</differenceType>
+ <className>org/apache/wicket/ajax/AjaxRequestTarget$IListener</className>
+ <method>void onAfterRespond(java.util.Map, org.apache.wicket.ajax.AjaxRequestTarget)</method>
+ </difference>
</ignored>
</configuration>
<executions>
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 1712dc8..f95c959 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..7a83db4 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;
@@ -265,15 +269,18 @@ class AjaxRequestHandlerTest extends WicketTestCase
@Test
void globalAjaxRequestTargetListeners()
{
- final ValidatingAjaxRequestTargetListener listener = new ValidatingAjaxRequestTargetListener();
-
+ ValidatingListener listener = new ValidatingListener();
+
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 +403,32 @@ class AjaxRequestHandlerTest extends WicketTestCase
}
}
- private static class ValidatingAjaxRequestTargetListener implements AjaxRequestTarget.IListener
+ private static class ValidatingListener 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();
+ } catch (IllegalStateException javascriptFrozen) {
+ }
+ }
}
}