You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by so...@apache.org on 2018/01/22 03:38:51 UTC
[05/10] wicket git commit: WICKET-6503 beforeRender clean-up
WICKET-6503 beforeRender clean-up
- prepare all components before writing them to Ajax response
- simplified delayed preparation of feedbacks
- clean-up internal component API an flags
this closes #250
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/c27a57b3
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/c27a57b3
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/c27a57b3
Branch: refs/heads/WICKET-6498_deferred_javascript
Commit: c27a57b31a0e519ef15dfe08b425d85f9a24f685
Parents: c787470
Author: Sven Meier <sv...@apache.org>
Authored: Thu Dec 14 07:55:53 2017 +0100
Committer: Sven Meier <sv...@apache.org>
Committed: Wed Jan 17 22:26:11 2018 +0100
----------------------------------------------------------------------
.../main/java/org/apache/wicket/Component.java | 332 ++++++-------------
.../java/org/apache/wicket/MarkupContainer.java | 22 --
.../src/main/java/org/apache/wicket/Page.java | 36 +-
.../ComponentRenderingRequestHandler.java | 9 +-
.../handler/PageAndComponentProvider.java | 2 +-
.../core/util/string/ComponentRenderer.java | 3 +-
.../apache/wicket/feedback/FeedbackDelay.java | 119 +++++++
.../org/apache/wicket/feedback/IFeedback.java | 5 +-
.../apache/wicket/page/PartialPageUpdate.java | 74 ++++-
.../wicket/page/XmlPartialPageUpdate.java | 50 +--
.../wicket/feedback/FeedbackRenderTest.java | 22 +-
.../apache/wicket/feedback/FeedbacksPage.html | 16 +-
.../apache/wicket/feedback/FeedbacksPage.java | 31 +-
.../markup/html/internal/EnclosurePage_1.java | 50 ++-
.../markup/html/internal/EnclosureTest.java | 4 +
15 files changed, 422 insertions(+), 353 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/main/java/org/apache/wicket/Component.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/Component.java b/wicket-core/src/main/java/org/apache/wicket/Component.java
index 7240a13..fc32b09 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Component.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Component.java
@@ -17,11 +17,11 @@
package org.apache.wicket;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
+import java.util.Optional;
import org.apache.wicket.ajax.IAjaxRegionMarkupIdProvider;
import org.apache.wicket.application.IComponentInstantiationListener;
@@ -40,6 +40,7 @@ import org.apache.wicket.event.Broadcast;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.event.IEventSink;
import org.apache.wicket.event.IEventSource;
+import org.apache.wicket.feedback.FeedbackDelay;
import org.apache.wicket.feedback.FeedbackMessage;
import org.apache.wicket.feedback.FeedbackMessages;
import org.apache.wicket.feedback.IFeedback;
@@ -86,7 +87,6 @@ import org.apache.wicket.util.lang.Classes;
import org.apache.wicket.util.string.PrependingStringBuffer;
import org.apache.wicket.util.string.Strings;
import org.apache.wicket.util.value.ValueMap;
-import org.apache.wicket.util.visit.IVisit;
import org.apache.wicket.util.visit.IVisitFilter;
import org.apache.wicket.util.visit.IVisitor;
import org.apache.wicket.util.visit.Visit;
@@ -312,12 +312,6 @@ public abstract class Component
}
};
- /** an unused flag */
- private static final int FLAG_UNUSED0 = 0x20000000;
- private static final int FLAG_UNUSED1 = 0x800000;
- private static final int FLAG_UNUSED2 = 0x1000000;
- private static final int FLAG_UNUSED3 = 0x10000000;
-
/** True when a component is being auto-added */
private static final int FLAG_AUTO = 0x0001;
@@ -389,17 +383,6 @@ public abstract class Component
*/
private static final int FLAG_MODEL_SET = 0x100000;
- /** True when a component is being removed from the hierarchy */
- protected static final int FLAG_REMOVING_FROM_HIERARCHY = 0x200000;
-
- /**
- * Flag that makes we are in before-render callback phase Set after component.onBeforeRender is
- * invoked (right before invoking beforeRender on children)
- */
- protected static final int FLAG_RENDERING = 0x2000000;
- protected static final int FLAG_PREPARED_FOR_RENDER = 0x4000000;
- protected static final int FLAG_AFTER_RENDERING = 0x8000000;
-
/**
* Flag that restricts visibility of a component when set to true. This is usually used when a
* component wants to restrict visibility of another component. Calling
@@ -408,8 +391,6 @@ public abstract class Component
*/
private static final int FLAG_VISIBILITY_ALLOWED = 0x40000000;
- private static final int FLAG_DETACHING = 0x80000000;
-
/**
* The name of attribute that will hold markup id
*/
@@ -447,6 +428,16 @@ public abstract class Component
private static final short RFLAG_INITIALIZE_SUPER_CALL_VERIFIED = 0x40;
protected static final short RFLAG_CONTAINER_DEQUEING = 0x80;
private static final short RFLAG_ON_RE_ADD_SUPER_CALL_VERIFIED = 0x100;
+ /**
+ * Flag that makes we are in before-render callback phase Set after component.onBeforeRender is
+ * invoked (right before invoking beforeRender on children)
+ */
+ private static final short RFLAG_RENDERING = 0x200;
+ private static final short RFLAG_PREPARED_FOR_RENDER = 0x400;
+ private static final short RFLAG_AFTER_RENDERING = 0x800;
+ private static final short RFLAG_DETACHING = 0x1000;
+ /** True when a component is being removed from the hierarchy */
+ private static final short RFLAG_REMOVING_FROM_HIERARCHY = 0x2000;
/**
* Flags that only keep their value during the request. Useful for cache markers, etc. At the
@@ -789,7 +780,7 @@ public abstract class Component
}
/**
- * Called once per request on components before they are about to be rendered. This method
+ * Called on all components before any component is rendered. This method
* should be used to configure such things as visibility and enabled flags.
* <p>
* Overrides must call {@code super.onConfigure()}, usually before any other code
@@ -857,7 +848,7 @@ public abstract class Component
}
/**
- * THIS METHOD IS NOT PART OF THE PUBLIC API, DO NOT CALL IT
+ * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
*
* Used to call {@link #onInitialize()}
*/
@@ -903,22 +894,19 @@ public abstract class Component
}
/**
- * Called on every component after the page is rendered. It will call onAfterRender for it self
- * and its children.
+ * Called on every component after the page is rendered. Calls hook {@link #onAfterRender()}.
*/
- public final void afterRender()
+ final void afterRender()
{
+ setRequestFlag(RFLAG_PREPARED_FOR_RENDER, false);
+
try
{
- setFlag(FLAG_AFTER_RENDERING, true);
-
- // always detach children because components can be attached
- // independently of their parents
- onAfterRenderChildren();
+ setRequestFlag(RFLAG_AFTER_RENDERING, true);
onAfterRender();
getApplication().getComponentOnAfterRenderListeners().onAfterRender(this);
- if (getFlag(FLAG_AFTER_RENDERING))
+ if (getRequestFlag(RFLAG_AFTER_RENDERING))
{
throw new IllegalStateException(Component.class.getName() +
" has not been properly detached. Something in the hierarchy of " +
@@ -929,91 +917,53 @@ public abstract class Component
finally
{
// this flag must always be set to false.
- markRendering(false);
+ setRequestFlag(RFLAG_RENDERING, false);
}
}
- private void internalBeforeRender()
- {
- configure();
-
- if ((determineVisibility()) && !getFlag(FLAG_RENDERING) &&
- !getFlag(FLAG_PREPARED_FOR_RENDER))
- {
- setRequestFlag(RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED, false);
-
- Application application = getApplication();
- application.getComponentPreOnBeforeRenderListeners().onBeforeRender(this);
-
- onBeforeRender();
- application.getComponentPostOnBeforeRenderListeners().onBeforeRender(this);
-
- if (!getRequestFlag(RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED))
- {
- throw new IllegalStateException(Component.class.getName() +
- " has not been properly rendered. Something in the hierarchy of " +
- getClass().getName() +
- " has not called super.onBeforeRender() in the override of onBeforeRender() method");
- }
- }
- }
-
- /**
- * We need to postpone calling beforeRender() on components that implement {@link IFeedback}, to
- * be sure that all other component's beforeRender() has been already called, so that IFeedbacks
- * can collect all feedback messages. This is the key under list of postponed {@link IFeedback}
- * is stored to request cycle metadata. The List is then iterated over in
- * {@link #prepareForRender()} after calling {@link #beforeRender()}, to initialize postponed
- * components.
- */
- private static final MetaDataKey<List<Component>> FEEDBACK_LIST = new MetaDataKey<List<Component>>()
- {
- private static final long serialVersionUID = 1L;
- };
-
/**
- * Called for every component when the page is getting to be rendered. it will call
- * {@link #configure()} and {@link #onBeforeRender()} for this component and all the child
- * components
+ * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
+ *
+ * Called on all components before any component is rendered. Calls hooks
+ * {@link #configure()} and (if visible) {@link #onBeforeRender()}
+ * and delegates to {@link #beforeRender()} of all child components.
*/
public final void beforeRender()
{
if (this instanceof IFeedback)
{
- // this component is a feedback. Feedback must be initialized last, so that
- // they can collect messages from other components
- List<Component> feedbacks = getRequestCycle().getMetaData(FEEDBACK_LIST);
- if (feedbacks == null)
- {
- feedbacks = new ArrayList<>();
- getRequestCycle().setMetaData(FEEDBACK_LIST, feedbacks);
+ Optional<FeedbackDelay> delay = FeedbackDelay.get(getRequestCycle());
+ if (delay.isPresent()) {
+ delay.get().postpone((IFeedback)this);
+ return;
}
+ }
- if (this instanceof MarkupContainer)
- {
- ((MarkupContainer)this).visitChildren(IFeedback.class,
- new IVisitor<Component, Void>()
- {
- @Override
- public void component(Component feedback, IVisit<Void> visit)
- {
- feedback.beforeRender();
-
- // don't need to go deeper,
- // as the feedback will visit its children on its own
- visit.dontGoDeeper();
- }
- });
- }
+ configure();
- if (!feedbacks.contains(this))
- {
- feedbacks.add(this);
- }
- }
- else
+ if ((determineVisibility()) && !getRequestFlag(RFLAG_RENDERING) &&
+ !getRequestFlag(RFLAG_PREPARED_FOR_RENDER))
{
- internalBeforeRender();
+ try {
+ setRequestFlag(RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED, false);
+
+ Application application = getApplication();
+ application.getComponentPreOnBeforeRenderListeners().onBeforeRender(this);
+
+ onBeforeRender();
+ application.getComponentPostOnBeforeRenderListeners().onBeforeRender(this);
+
+ if (!getRequestFlag(RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED))
+ {
+ throw new IllegalStateException(Component.class.getName() +
+ " has not been properly rendered. Something in the hierarchy of " +
+ getClass().getName() +
+ " has not called super.onBeforeRender() in the override of onBeforeRender() method");
+ }
+ } catch (RuntimeException ex) {
+ setRequestFlag(RFLAG_PREPARED_FOR_RENDER, false);
+ throw ex;
+ }
}
}
@@ -1072,9 +1022,6 @@ public abstract class Component
}
/**
- *
- * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
- *
* Called after the {@link #onConfigure()}, but before {@link #onBeforeRender()}
*/
void internalOnAfterConfigure()
@@ -1134,10 +1081,10 @@ public abstract class Component
*/
final void internalOnRemove()
{
- setFlag(FLAG_REMOVING_FROM_HIERARCHY, true);
+ setRequestFlag(RFLAG_REMOVING_FROM_HIERARCHY, true);
onRemove();
setFlag(FLAG_REMOVED, true);
- if (getFlag(FLAG_REMOVING_FROM_HIERARCHY))
+ if (getRequestFlag(RFLAG_REMOVING_FROM_HIERARCHY))
{
throw new IllegalStateException(Component.class.getName() +
" has not been properly removed from hierachy. Something in the hierarchy of " +
@@ -1157,9 +1104,9 @@ public abstract class Component
{
try
{
- setFlag(FLAG_DETACHING, true);
+ setRequestFlag(RFLAG_DETACHING, true);
onDetach();
- if (getFlag(FLAG_DETACHING))
+ if (getRequestFlag(RFLAG_DETACHING))
{
throw new IllegalStateException(Component.class.getName() +
" has not been properly detached. Something in the hierarchy of " +
@@ -1469,7 +1416,7 @@ public abstract class Component
}
/**
- * THIS IS WICKET INTERNAL ONLY. DO NOT USE IT.
+ * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
*
* Get a copy of the markup's attributes which are associated with the component.
* <p>
@@ -2170,23 +2117,6 @@ public abstract class Component
}
/**
- * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
- *
- * Sets the RENDERING flag and removes the PREPARED_FOR_RENDER flag on component and it's
- * children.
- *
- * @param setRenderingFlag
- * if this is false only the PREPARED_FOR_RENDER flag is removed from component, the
- * RENDERING flag is not set.
- *
- * @see #internalPrepareForRender(boolean)
- */
- public final void markRendering(boolean setRenderingFlag)
- {
- internalMarkRendering(setRenderingFlag);
- }
-
- /**
* Called to indicate that the model content for this component has been changed
*/
public final void modelChanged()
@@ -2215,62 +2145,6 @@ public abstract class Component
}
/**
- * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
- * <p>
- * Prepares the component and it's children for rendering. On whole page render this method must
- * be called on the page. On AJAX request, this method must be called on the updated component.
- *
- * @param setRenderingFlag
- * Whether to set the rendering flag. This must be true if the page is about to be
- * rendered. However, there are usecases to call this method without an immediate
- * render (e.g. on stateless listener request target to build the component
- * hierarchy), in that case setRenderingFlag should be false.
- */
- public void internalPrepareForRender(boolean setRenderingFlag)
- {
- beforeRender();
-
- if (setRenderingFlag)
- {
- // only process feedback panel when we are about to be rendered.
- // setRenderingFlag is false in case prepareForRender is called only to build component
- // hierarchy (i.e. in BookmarkableListenerRequestHandler).
- // prepareForRender(true) is always called before the actual rendering is done so
- // that's where feedback panels gather the messages
-
- List<Component> feedbacks = getRequestCycle().getMetaData(FEEDBACK_LIST);
- if (feedbacks != null)
- {
- // iterate over a copy because a IFeedback may add more IFeedback children
-// (WICKET-4687)
- Component[] feedbacksCopy = feedbacks.toArray(new Component[feedbacks.size()]);
- for (Component feedback : feedbacksCopy)
- {
- // render it only if it is still in the page hierarchy (WICKET-4895)
- if (feedback.findPage() != null)
- {
- feedback.internalBeforeRender();
- }
- }
- }
- getRequestCycle().setMetaData(FEEDBACK_LIST, null);
- }
-
- markRendering(setRenderingFlag);
- }
-
- /**
- * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
- *
- * Prepares the component and it's children for rendering. On whole page render this method must
- * be called on the page. On AJAX request, this method must be called on updated component.
- */
- public final void prepareForRender()
- {
- internalPrepareForRender(true);
- }
-
- /**
* Redirects browser to an intermediate page such as a sign-in page. The current request's url
* is saved for future use by method continueToOriginalDestination(); Only use this method when
* you plan to continue to the current url at some later time; otherwise just use
@@ -2303,24 +2177,42 @@ public abstract class Component
parent.remove(this);
}
+ /**
+ * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
+ * <p>
+ * Renders this component as a part of a response - the caller has to
+ * make sure that this component is prepared for render.
+ *
+ * @see #beforeRender()
+ */
+ public final void renderPart() {
+ Page page = getPage();
+
+ page.startComponentRender(this);
+
+ render();
+
+ page.endComponentRender(this);
+ }
/**
- * Render the Component.
+ * Render this component and all its children. Always calls hook {@link #onAfterRender()}
+ * regardless of any exception.
*/
public final void render()
{
- RuntimeException exception = null;
+ if (isAuto())
+ {
+ // auto components are prepared when rendered
+ beforeRender();
+ }
+ // Do the render
+ RuntimeException exception = null;
try
{
- // Invoke prepareForRender only if this is the root component to be rendered
- MarkupContainer parent = getParent();
- if ((parent == null) || (parent.getFlag(FLAG_RENDERING) == false) || isAuto())
- {
- internalPrepareForRender(true);
- }
-
- // Do the render
+ setRequestFlag(RFLAG_RENDERING, true);
+
internalRender();
}
catch (final RuntimeException ex)
@@ -2367,9 +2259,6 @@ public abstract class Component
// MarkupStream is an Iterator for the markup
MarkupStream markupStream = new MarkupStream(markup);
- // Flag: we started the render process
- markRendering(true);
-
MarkupElement elem = markup.get(0);
if (elem instanceof ComponentTag)
{
@@ -2513,13 +2402,13 @@ public abstract class Component
/**
- * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT.
+ * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
* <p>
* Renders the component at the current position in the given markup stream. The method
* onComponentTag() is called to allow the component to mutate the start tag. The method
* onComponentTagBody() is then called to permit the component to render its body.
*/
- public final void internalRenderComponent()
+ protected final void internalRenderComponent()
{
final IMarkupFragment markup = getMarkup();
if (markup == null)
@@ -2698,7 +2587,7 @@ public abstract class Component
}
/**
- * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT.
+ * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
*
* Print to the web response what ever the component wants to contribute to the head section.
* Make sure that all attached behaviors are asked as well.
@@ -3645,7 +3534,7 @@ public abstract class Component
protected void checkHierarchyChange(final Component component)
{
// Throw exception if modification is attempted during rendering
- if (getFlag(FLAG_RENDERING) && !component.isAuto())
+ if (getRequestFlag(RFLAG_RENDERING) && !component.isAuto())
{
throw new WicketRuntimeException(
"Cannot modify component hierarchy after render phase has started (page version cant change then anymore)");
@@ -3876,15 +3765,16 @@ public abstract class Component
}
/**
- * Called just after a component is rendered.
+ * Called immediately after a component and all its children have been rendered,
+ * regardless of any exception.
*/
protected void onAfterRender()
{
- setFlag(FLAG_AFTER_RENDERING, false);
+ setRequestFlag(RFLAG_AFTER_RENDERING, false);
}
/**
- * Called just before a component is rendered only if the component is visible.
+ * Called on all visible components before any component is rendered.
* <p>
* <strong>NOTE</strong>: If you override this, you *must* call super.onBeforeRender() within
* your implementation.
@@ -3900,7 +3790,6 @@ public abstract class Component
*/
protected void onBeforeRender()
{
- setFlag(FLAG_PREPARED_FOR_RENDER, true);
onBeforeRenderChildren();
setRequestFlag(RFLAG_BEFORE_RENDER_SUPER_CALL_VERIFIED, true);
}
@@ -3958,7 +3847,7 @@ public abstract class Component
*/
protected void onDetach()
{
- setFlag(FLAG_DETACHING, false);
+ setRequestFlag(RFLAG_DETACHING, false);
}
/**
@@ -3969,7 +3858,7 @@ public abstract class Component
*/
protected void onRemove()
{
- setFlag(FLAG_REMOVING_FROM_HIERARCHY, false);
+ setRequestFlag(RFLAG_REMOVING_FROM_HIERARCHY, false);
}
/**
@@ -4161,14 +4050,12 @@ public abstract class Component
}
/**
- * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT USE IT!
- *
* @param flag
* The flag to set
* @param set
* True to turn the flag on, false to turn it off
*/
- protected final Component setRequestFlag(final short flag, final boolean set)
+ final Component setRequestFlag(final short flag, final boolean set)
{
if (set)
{
@@ -4245,18 +4132,6 @@ public abstract class Component
}
/**
- * @param setRenderingFlag
- * rendering flag
- */
- void internalMarkRendering(boolean setRenderingFlag)
- {
- // WICKET-5460 no longer prepared for render
- setFlag(FLAG_PREPARED_FOR_RENDER, false);
-
- setFlag(FLAG_RENDERING, setRenderingFlag);
- }
-
- /**
* @return True if this component or any of its parents is in auto-add mode
*/
public final boolean isAuto()
@@ -4278,14 +4153,7 @@ public abstract class Component
*/
boolean isPreparedForRender()
{
- return getFlag(FLAG_PREPARED_FOR_RENDER);
- }
-
- /**
- *
- */
- protected void onAfterRenderChildren()
- {
+ return getRequestFlag(RFLAG_PREPARED_FOR_RENDER);
}
/**
@@ -4474,7 +4342,7 @@ public abstract class Component
*/
public final boolean isRendering()
{
- return getFlag(FLAG_RENDERING);
+ return getRequestFlag(RFLAG_RENDERING);
}
/**
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java b/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
index 36b7684..aad0aac 100644
--- a/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
+++ b/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java
@@ -1694,17 +1694,6 @@ public abstract class MarkupContainer extends Component implements Iterable<Comp
}
}
- @Override
- void internalMarkRendering(boolean setRenderingFlag)
- {
- super.internalMarkRendering(setRenderingFlag);
-
- for (Component child : this)
- {
- child.internalMarkRendering(setRenderingFlag);
- }
- }
-
/**
* @return a copy of the children array.
*/
@@ -1793,17 +1782,6 @@ public abstract class MarkupContainer extends Component implements Iterable<Comp
}
@Override
- protected void onAfterRenderChildren()
- {
- for (Component child : this)
- {
- // set RENDERING_FLAG to false for auto-component's children (like Enclosure)
- child.markRendering(false);
- }
- super.onAfterRenderChildren();
- }
-
- @Override
protected void onDetach()
{
super.onDetach();
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/main/java/org/apache/wicket/Page.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/Page.java b/wicket-core/src/main/java/org/apache/wicket/Page.java
index fb4f04d..9b8dc7f 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Page.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Page.java
@@ -24,6 +24,7 @@ import java.util.Set;
import org.apache.wicket.authorization.UnauthorizedActionException;
import org.apache.wicket.core.util.lang.WicketObjects;
+import org.apache.wicket.feedback.FeedbackDelay;
import org.apache.wicket.markup.MarkupException;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.MarkupType;
@@ -229,14 +230,15 @@ public abstract class Page extends MarkupContainer
}
@Override
- public void internalPrepareForRender(boolean setRenderingFlag)
+ protected void onConfigure()
{
if (!isInitialized())
{
// initialize the page if not yet initialized
internalInitialize();
}
- super.internalPrepareForRender(setRenderingFlag);
+
+ super.onConfigure();
}
/**
@@ -300,14 +302,14 @@ public abstract class Page extends MarkupContainer
}
/**
- * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL.
- *
- * This method is called when a component was rendered standalone. If it is a <code>
+ * This method is called when a component was rendered as a part. If it is a <code>
* MarkupContainer</code> then the rendering for that container is checked.
*
* @param component
+ *
+ * @see Component#renderPart()
*/
- public final void endComponentRender(Component component)
+ final void endComponentRender(Component component)
{
if (component instanceof MarkupContainer)
{
@@ -527,14 +529,13 @@ public abstract class Page extends MarkupContainer
}
/**
- * THIS METHOD IS NOT PART OF THE WICKET PUBLIC API. DO NOT CALL.
- *
- * This method is called when a component will be rendered standalone.
+ * This method is called when a component will be rendered as a part.
*
* @param component
*
+ * @see Component#renderPart()
*/
- public final void startComponentRender(Component component)
+ final void startComponentRender(Component component)
{
renderedComponents = null;
}
@@ -984,9 +985,17 @@ public abstract class Page extends MarkupContainer
try
{
++renderCount;
- render();
- // stateless = null;
+ FeedbackDelay delay = new FeedbackDelay(getRequestCycle());
+ try {
+ beforeRender();
+
+ delay.beforeRender();
+ } finally {
+ delay.release();
+ }
+
+ render();
}
finally
{
@@ -1004,5 +1013,4 @@ public abstract class Page extends MarkupContainer
{
return renderedComponents != null && renderedComponents.contains(component);
}
-
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/main/java/org/apache/wicket/core/request/handler/ComponentRenderingRequestHandler.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/request/handler/ComponentRenderingRequestHandler.java b/wicket-core/src/main/java/org/apache/wicket/core/request/handler/ComponentRenderingRequestHandler.java
index 1636707..e6d5874 100644
--- a/wicket-core/src/main/java/org/apache/wicket/core/request/handler/ComponentRenderingRequestHandler.java
+++ b/wicket-core/src/main/java/org/apache/wicket/core/request/handler/ComponentRenderingRequestHandler.java
@@ -64,13 +64,8 @@ public class ComponentRenderingRequestHandler implements IComponentRequestHandle
response.disableCaching();
}
- Page page = component.getPage();
-
- page.startComponentRender(component);
-
- component.render();
-
- page.endComponentRender(component);
+ component.beforeRender();
+ component.renderPart();
}
@Override
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/main/java/org/apache/wicket/core/request/handler/PageAndComponentProvider.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/request/handler/PageAndComponentProvider.java b/wicket-core/src/main/java/org/apache/wicket/core/request/handler/PageAndComponentProvider.java
index 8bdfa93..de59ecc 100644
--- a/wicket-core/src/main/java/org/apache/wicket/core/request/handler/PageAndComponentProvider.java
+++ b/wicket-core/src/main/java/org/apache/wicket/core/request/handler/PageAndComponentProvider.java
@@ -169,7 +169,7 @@ public class PageAndComponentProvider extends PageProvider implements IPageAndCo
{
Page p = (Page)page;
p.internalInitialize();
- p.internalPrepareForRender(false);
+ p.beforeRender();
component = page.get(componentPath);
}
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java b/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
index d583057..9104eb9 100644
--- a/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
+++ b/wicket-core/src/main/java/org/apache/wicket/core/util/string/ComponentRenderer.java
@@ -416,7 +416,8 @@ public class ComponentRenderer
RenderPage page = new RenderPage(component);
page.internalInitialize();
- component.render();
+ component.beforeRender();
+ component.renderPart();
}
finally
{
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/main/java/org/apache/wicket/feedback/FeedbackDelay.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/feedback/FeedbackDelay.java b/wicket-core/src/main/java/org/apache/wicket/feedback/FeedbackDelay.java
new file mode 100644
index 0000000..4d0ef30
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/feedback/FeedbackDelay.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.feedback;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MetaDataKey;
+import org.apache.wicket.Page;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.request.cycle.RequestCycle;
+
+/**
+ * Postpone calling {@link IFeedback#beforeRender()} after other components.
+ * <p>
+ * This gives other {@link Component#beforeRender()} the possibility to report feedbacks,
+ * which can then be collected by {@link IFeedback}s afterwards.
+ */
+public class FeedbackDelay implements Serializable
+{
+ private static final MetaDataKey<FeedbackDelay> KEY = new MetaDataKey<FeedbackDelay>()
+ {
+ private static final long serialVersionUID = 1L;
+ };
+
+ private List<IFeedback> feedbacks = new ArrayList<>();
+
+ private RequestCycle cycle;
+
+ /**
+ * Delay all feedbacks for the given cycle.
+ * <p>
+ * All postponed feedbacks will be prepared for render with {@link #beforeRender()}.
+ *
+ * @param cycle
+ * request cycle
+ */
+ public FeedbackDelay(RequestCycle cycle) {
+ if (get(cycle).isPresent()) {
+ throw new WicketRuntimeException("feedbacks are already delayed");
+ }
+
+ cycle.setMetaData(KEY, this);
+
+ this.cycle = cycle;
+ }
+
+ /**
+ * Get the current delay.
+ *
+ * @param cycle
+ * @return optional delay
+ */
+ public static Optional<FeedbackDelay> get(RequestCycle cycle) {
+ return Optional.ofNullable(cycle.getMetaData(KEY));
+ }
+
+ /**
+ * Postpone {@link Component#beforeRender()} on the given feedback.
+ *
+ * @param feedback
+ * @return
+ */
+ public FeedbackDelay postpone(IFeedback feedback) {
+ feedbacks.add(feedback);
+
+ return this;
+ }
+
+ /**
+ * Prepares all postponed feedbacks for render.
+ *
+ * @see IFeedback#beforeRender()
+ */
+ public void beforeRender() {
+ cycle.setMetaData(KEY, null);
+ cycle = null;
+
+ for (IFeedback feedback : feedbacks)
+ {
+ if (feedback instanceof Component) {
+ Component component = (Component)feedback;
+
+ // render only if it is still in the page hierarchy (WICKET-4895)
+ if (component.findParent(Page.class) == null)
+ {
+ continue;
+ }
+ }
+
+ feedback.beforeRender();
+ }
+ }
+
+ public void release() {
+ if (cycle != null) {
+ cycle.setMetaData(KEY, null);
+ cycle = null;
+ feedbacks.clear();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/main/java/org/apache/wicket/feedback/IFeedback.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/feedback/IFeedback.java b/wicket-core/src/main/java/org/apache/wicket/feedback/IFeedback.java
index a1bd08c..6e0085e 100644
--- a/wicket-core/src/main/java/org/apache/wicket/feedback/IFeedback.java
+++ b/wicket-core/src/main/java/org/apache/wicket/feedback/IFeedback.java
@@ -20,12 +20,13 @@ package org.apache.wicket.feedback;
* Interface for components that present some kind of feedback to the user, normally based on the
* feedback messages attached to various components on a given page.
*
- * This is basically a marker interface that tells Wicket that this component's onBeforeRender
- * method must be called after all non feedback components have been initialized.
+ * This is tells Wicket that a component's {@link Component#beforeRender()} must be called after all non
+ * feedback components have been initialized.
*
* @author Jonathan Locke
* @author Eelco Hillenius
*/
public interface IFeedback
{
+ void beforeRender();
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/main/java/org/apache/wicket/page/PartialPageUpdate.java
----------------------------------------------------------------------
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 2bef5e2..caec116 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
@@ -28,6 +28,7 @@ import javax.servlet.http.Cookie;
import org.apache.wicket.Component;
import org.apache.wicket.Page;
+import org.apache.wicket.feedback.FeedbackDelay;
import org.apache.wicket.markup.head.HeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.IWrappedHeaderItem;
@@ -238,19 +239,36 @@ public abstract class PartialPageUpdate
{
componentsFrozen = true;
- // process component markup
- for (Map.Entry<String, Component> stringComponentEntry : markupIdToComponent.entrySet())
- {
- final Component component = stringComponentEntry.getValue();
-
- if (!containsAncestorFor(component))
+ List<Component> prepared = new ArrayList<>(markupIdToComponent.size());
+
+ // prepare components
+ FeedbackDelay delay = new FeedbackDelay(RequestCycle.get());
+ try {
+ for (Component component : markupIdToComponent.values())
{
- writeComponent(response, component.getAjaxRegionMarkupId(), component, encoding);
+ if (!containsAncestorFor(component))
+ {
+ prepareComponent(component);
+ prepared.add(component);
+ }
}
+
+ // .. now prepare all postponed feedbacks
+ delay.beforeRender();
+ } finally {
+ delay.release();
+ }
+
+ // write components
+ for (Component component : prepared)
+ {
+ writeComponent(response, component.getAjaxRegionMarkupId(), component, encoding);
}
if (header != null)
{
+ RequestCycle cycle = RequestCycle.get();
+
// some header responses buffer all calls to render*** until close is called.
// when they are closed, they do something (i.e. aggregate all JS resource urls to a
// single url), and then "flush" (by writing to the real response) before closing.
@@ -258,14 +276,14 @@ public abstract class PartialPageUpdate
// tag, which we do here:
headerRendering = true;
// save old response, set new
- Response oldResponse = RequestCycle.get().setResponse(headerBuffer);
+ Response oldResponse = cycle.setResponse(headerBuffer);
headerBuffer.reset();
// now, close the response (which may render things)
header.getHeaderResponse().close();
// revert to old response
- RequestCycle.get().setResponse(oldResponse);
+ cycle.setResponse(oldResponse);
// write the XML tags and we're done
writeHeaderContribution(response);
@@ -274,6 +292,44 @@ public abstract class PartialPageUpdate
}
/**
+ * Prepare a single component
+ *
+ * @param component
+ * the component to prepare
+ */
+ protected void prepareComponent(Component component)
+ {
+ if (component.getRenderBodyOnly() == true)
+ {
+ throw new IllegalStateException(
+ "A partial update is not possible for a component that has renderBodyOnly enabled. Component: " +
+ component.toString());
+ }
+
+ component.setOutputMarkupId(true);
+
+ // Initialize temporary variables
+ final Page page = component.findParent(Page.class);
+ if (page == null)
+ {
+ // dont throw an exception but just ignore this component, somehow
+ // it got removed from the page.
+ LOG.warn("Component '{}' not rendered because it was already removed from page", component);
+ return;
+ }
+
+ try
+ {
+ component.beforeRender();
+ }
+ catch (RuntimeException e)
+ {
+ bodyBuffer.reset();
+ throw e;
+ }
+ }
+
+ /**
* Writes a single component
*
* @param response
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/main/java/org/apache/wicket/page/XmlPartialPageUpdate.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/page/XmlPartialPageUpdate.java b/wicket-core/src/main/java/org/apache/wicket/page/XmlPartialPageUpdate.java
index 28c2ffa..5f78ef3 100644
--- a/wicket-core/src/main/java/org/apache/wicket/page/XmlPartialPageUpdate.java
+++ b/wicket-core/src/main/java/org/apache/wicket/page/XmlPartialPageUpdate.java
@@ -59,29 +59,11 @@ public class XmlPartialPageUpdate extends PartialPageUpdate
response.write("\"?>");
response.write(START_ROOT_ELEMENT);
}
-
+
@Override
protected void writeComponent(Response response, String markupId, Component component, String encoding)
{
- if (component.getRenderBodyOnly() == true)
- {
- throw new IllegalStateException(
- "A partial update is not possible for a component that has renderBodyOnly enabled. Component: " +
- component.toString());
- }
-
- component.setOutputMarkupId(true);
-
- // Initialize temporary variables
final Page page = component.findParent(Page.class);
- if (page == null)
- {
- // dont throw an exception but just ignore this component, somehow
- // it got removed from the page.
- LOG.warn("Component '{}' with markupid: '{}' not rendered because it was already removed from page",
- component, markupId);
- return;
- }
// substitute our encoding response for the old one so we can capture
// component's markup in a manner safe for transport inside CDATA block
@@ -89,42 +71,20 @@ public class XmlPartialPageUpdate extends PartialPageUpdate
try
{
+ // render any associated headers of the component
+ writeHeaderContribution(response, component);
+
bodyBuffer.reset();
- page.startComponentRender(component);
-
- try
- {
- component.prepareForRender();
-
- // render any associated headers of the component
- writeHeaderContribution(response, component);
- }
- catch (RuntimeException e)
- {
- try
- {
- component.afterRender();
- }
- catch (RuntimeException e2)
- {
- // ignore this one could be a result off.
- }
- bodyBuffer.reset();
- throw e;
- }
-
try
{
- component.render();
+ component.renderPart();
}
catch (RuntimeException e)
{
bodyBuffer.reset();
throw e;
}
-
- page.endComponentRender(component);
}
finally
{
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbackRenderTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbackRenderTest.java b/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbackRenderTest.java
index 8f0f7cb..c12fb2a 100644
--- a/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbackRenderTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbackRenderTest.java
@@ -36,7 +36,25 @@ public class FeedbackRenderTest extends WicketTestCase
tester.startPage(page);
- // non-IFeedback first, then IFeedback from nested to top
- assertEquals("|id4|id3|id2|id1", page.onBeforeRenderOrder.toString());
+ // non-IFeedback first, then IFeedback top-down
+ assertEquals("|id4|id1|id2|id3", page.onBeforeRenderOrder.toString());
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testAjax() throws Exception
+ {
+ final FeedbacksPage page = new FeedbacksPage();
+
+ tester.startPage(page);
+
+ page.onBeforeRenderOrder.setLength(0);
+
+ tester.executeAjaxEvent(page.getAjaxLink(), "click");
+
+ // non-IFeedback first, then IFeedback top-down
+ assertEquals("|id4|id1|id2|id3", page.onBeforeRenderOrder.toString());
}
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbacksPage.html
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbacksPage.html b/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbacksPage.html
index 8d9000f..bc6c4f1 100644
--- a/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbacksPage.html
+++ b/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbacksPage.html
@@ -14,14 +14,20 @@
-->
<html>
<body>
-<span wicket:id="id1">
- <span wicket:id="id2">
- <span wicket:id="id3">
+<span wicket:id="feedbacks">
+ <span wicket:id="id1">
+ <span wicket:id="id2">
+ <span wicket:id="id3">
+ </span>
</span>
- </span>
-</span>
+ </span>
+</span>
<span wicket:id="id4">
</span>
+
+<span wicket:id="ajax">
+</span>
+
</body>
</html>
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbacksPage.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbacksPage.java b/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbacksPage.java
index 840495c..50c920f 100644
--- a/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbacksPage.java
+++ b/wicket-core/src/test/java/org/apache/wicket/feedback/FeedbacksPage.java
@@ -16,6 +16,8 @@
*/
package org.apache.wicket.feedback;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
@@ -28,13 +30,18 @@ public class FeedbacksPage extends WebPage
public final StringBuilder onBeforeRenderOrder = new StringBuilder();
+ private AjaxLink<Void> ajaxLink;
+
/**
*/
public FeedbacksPage()
{
-
+ WebMarkupContainer feedbacks = new WebMarkupContainer("feedbacks");
+ feedbacks.setOutputMarkupId(true);
+ add(feedbacks);
+
Impl impl1 = new FeedbackImpl("id1");
- add(impl1);
+ feedbacks.add(impl1);
Impl impl2 = new FeedbackImpl("id2");
impl1.add(impl2);
@@ -43,7 +50,25 @@ public class FeedbacksPage extends WebPage
impl2.add(impl3);
Impl impl4 = new Impl("id4");
+ impl4.setOutputMarkupId(true);
add(impl4);
+
+ ajaxLink = new AjaxLink<Void>("ajax")
+ {
+ @Override
+ public void onClick(AjaxRequestTarget target)
+ {
+ // feedbacks added first, but should be prepared last
+ target.add(feedbacks);
+ target.add(impl4);
+ }
+ };
+ add(ajaxLink);
+ }
+
+ public AjaxLink<Void> getAjaxLink()
+ {
+ return ajaxLink;
}
private class Impl extends WebMarkupContainer
@@ -76,4 +101,4 @@ public class FeedbacksPage extends WebPage
super(id);
}
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/EnclosurePage_1.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/EnclosurePage_1.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/EnclosurePage_1.java
index 650bdbf..22a4a3f 100644
--- a/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/EnclosurePage_1.java
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/EnclosurePage_1.java
@@ -29,23 +29,53 @@ import org.apache.wicket.markup.html.basic.Label;
public class EnclosurePage_1 extends WebPage
{
private static final long serialVersionUID = 1L;
+
+ public int pendingAfterRenderCount = 0;
/**
* Construct.
*/
public EnclosurePage_1()
{
- add(new Label("label1", "Test Label 1"));
- add(new Label("label2", "Test Label 2"));
- add(new Label("label3", "Test Label 3").setVisible(false));
- add(new Label("label4", "Test Label 2"));
- add(new Label("label5", "Test Label 2"));
- add(new Label("label6", "Test Label 2"));
- add(new Label("label7", "Test Label 2"));
+ add(new AfterRenderCountingLabel("label1", "Test Label 1"));
+ add(new AfterRenderCountingLabel("label2", "Test Label 2"));
+ add(new AfterRenderCountingLabel("label3", "Test Label 3").setVisible(false));
+ add(new AfterRenderCountingLabel("label4", "Test Label 2"));
+ add(new AfterRenderCountingLabel("label5", "Test Label 2"));
+ add(new AfterRenderCountingLabel("label6", "Test Label 2"));
+ add(new AfterRenderCountingLabel("label7", "Test Label 2"));
+
WebMarkupContainer container = new WebMarkupContainer("container");
add(container);
- container.add(new Label("label8", "Test Label 2"));
- add(new Label("label9", "Test Label 2"));
- add(new Label("label10", "Test Label 3"));
+
+ container.add(new AfterRenderCountingLabel("label8", "Test Label 2"));
+
+ add(new AfterRenderCountingLabel("label9", "Test Label 2"));
+ add(new AfterRenderCountingLabel("label10", "Test Label 3"));
+ }
+
+ class AfterRenderCountingLabel extends Label {
+
+ public AfterRenderCountingLabel(String id, String model)
+ {
+ super(id, model);
+ }
+
+ @Override
+ protected void onBeforeRender()
+ {
+ super.onBeforeRender();
+
+
+ pendingAfterRenderCount++;
+ }
+
+ @Override
+ protected void onAfterRender()
+ {
+ super.onAfterRender();
+
+ pendingAfterRenderCount--;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/c27a57b3/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/EnclosureTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/EnclosureTest.java b/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/EnclosureTest.java
index a34ea5c..7067c7d 100644
--- a/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/EnclosureTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/markup/html/internal/EnclosureTest.java
@@ -52,6 +52,10 @@ public class EnclosureTest extends WicketTestCase
public void testRenderHomePage() throws Exception
{
executeTest(EnclosurePage_1.class, "EnclosurePageExpectedResult_1.html");
+
+ EnclosurePage_1 page = (EnclosurePage_1)tester.getLastRenderedPage();
+
+ assertEquals(0, page.pendingAfterRenderCount);
}
/**