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 2017/12/07 19:43:08 UTC

[1/2] wicket git commit: easier rendering of components, closes #249

Repository: wicket
Updated Branches:
  refs/heads/master 693dad38a -> e7597f03f


easier rendering of components, closes #249

setup ThreadLocal independently from filter or tester


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/a148e088
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/a148e088
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/a148e088

Branch: refs/heads/master
Commit: a148e088f13a4ec1cebfc938e24d6215e19576c8
Parents: 693dad3
Author: Sven Meier <sv...@apache.org>
Authored: Thu Dec 7 09:24:12 2017 +0100
Committer: Sven Meier <sv...@apache.org>
Committed: Thu Dec 7 20:40:36 2017 +0100

----------------------------------------------------------------------
 .../core/util/string/ComponentRenderer.java     | 346 ++++++++++++++++++-
 .../ComponentRendererInstanceTest.java          |  51 +++
 2 files changed, 379 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/a148e088/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 0cf63bf..d583057 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
@@ -16,18 +16,34 @@
  */
 package org.apache.wicket.core.util.string;
 
+import java.io.Serializable;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Supplier;
+
 import org.apache.wicket.Application;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.Page;
+import org.apache.wicket.RuntimeConfigurationType;
+import org.apache.wicket.Session;
 import org.apache.wicket.ThreadContext;
 import org.apache.wicket.core.request.handler.PageProvider;
 import org.apache.wicket.markup.IMarkupCacheKeyProvider;
 import org.apache.wicket.markup.IMarkupResourceStreamProvider;
 import org.apache.wicket.markup.MarkupNotFoundException;
 import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.mock.MockApplication;
+import org.apache.wicket.mock.MockWebRequest;
 import org.apache.wicket.protocol.http.BufferedWebResponse;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.protocol.http.mock.MockServletContext;
+import org.apache.wicket.request.Request;
 import org.apache.wicket.request.Response;
+import org.apache.wicket.request.Url;
 import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.serialize.ISerializer;
+import org.apache.wicket.session.ISessionStore;
 import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.StringResourceStream;
 import org.slf4j.Logger;
@@ -35,20 +51,303 @@ import org.slf4j.LoggerFactory;
 
 /**
  * A helper class for rendering components and pages.
- *
- * <p><strong>Note</strong>: {@link #renderComponent(Component)} does <strong>not</strong>
- * support rendering {@link org.apache.wicket.markup.html.panel.Fragment} instances!</p>
+ * <p>
+ * With the static methods of this class components and pages can be rendered on a thread already
+ * processing an {@link Application}.
+ * <p>
+ * If you want to render independently from any web request processing (e.g. generating an email
+ * body on a worker thread), you can create an instance of this class.<br/>
+ * You may use an existing application, create a fresh one or just use the automatically created
+ * mocked application with sensible defaults.
+ * <p>
+ * Note: For performance reasons instances can and should be reused, be sure to call {@link #destroy()} when
+ * they are no longer needed.
  */
 public class ComponentRenderer
 {
 	private static final Logger LOGGER = LoggerFactory.getLogger(ComponentRenderer.class);
 
+	private Application application;
+
+	/**
+	 * A renderer using a default mocked application, which
+	 * <ul>
+	 * <li>never shares anything in a session</li>
+	 * <li>never serializes anything</li>
+	 * </ul>
+	 */
+	public ComponentRenderer()
+	{
+		this(new MockApplication()
+		{
+			@Override
+			public RuntimeConfigurationType getConfigurationType()
+			{
+				return RuntimeConfigurationType.DEPLOYMENT;
+			}
+
+			@Override
+			protected void init()
+			{
+				super.init();
+
+				setSessionStoreProvider(() -> new NeverSessionStore());
+				getFrameworkSettings().setSerializer(new NeverSerializer());
+			}
+		});
+	}
+
 	/**
-	 * Collects the html generated by the rendering of a page.
+	 * A renderer using the given application.
+	 * <p>
+	 * If the application was not yet initialized - e.g. it is not reused from an already running
+	 * web container - it will be initialized.
+	 * 
+	 * @param application the application to render components in
+	 * 
+	 * @see Application#initApplication()
+	 */
+	public ComponentRenderer(Application application)
+	{
+		this.application = application;
+
+		if (application.getName() == null)
+		{
+			// not yet initialized
+			inThreadContext(this::initApplication);
+		}
+	}
+
+	private void initApplication()
+	{
+		if (application instanceof WebApplication) {
+			WebApplication webApplication = (WebApplication)application;
+			
+			// WebApplication requires a servlet context
+			webApplication.setServletContext(new MockServletContext(application, null));
+		}
+		
+		application.setName("ComponentRenderer[" + System.identityHashCode(ComponentRenderer.this) + "]");
+		application.initApplication();
+	}
+
+	/**
+	 * Destroy this renderer.
+	 */
+	public void destroy()
+	{
+		inThreadContext(() -> {
+			application.internalDestroy();
+			application = null;
+		});
+	}
+
+	/**
+	 * 
+	 * Collects the Html generated by rendering a component.
+	 * 
+	 * @param component
+	 *            supplier of the component
+	 * @return html rendered by the panel
+	 */
+	public CharSequence renderComponent(final Supplier<Component> component)
+	{
+		return renderPage(() -> new RenderPage(component.get()));
+	}
+
+	/**
+	 * Collects the html generated by rendering a page.
+	 *
+	 * @param page
+	 *            supplier of the page
+	 * @return the html rendered by the panel
+	 */
+	public CharSequence renderPage(final Supplier<? extends Page> page)
+	{
+		return inThreadContext(() -> {
+			Request request = newRequest();
+
+			BufferedWebResponse response = new BufferedWebResponse(null);
+
+			RequestCycle cycle = application.createRequestCycle(request, response);
+
+			ThreadContext.setRequestCycle(cycle);
+
+			page.get().renderPage();
+
+			return response.getText();
+		});
+	}
+
+	/**
+	 * Run the given runnable inside a bound {@link ThreadContext}.
+	 * 
+	 * @param runnable
+	 *            runnable
+	 */
+	private void inThreadContext(Runnable runnable)
+	{
+		inThreadContext(() -> {
+			runnable.run();
+			return null;
+		});
+	}
+
+	/**
+	 * Get the result from the given supplier inside a bound {@link ThreadContext}.
+	 * 
+	 * @param supplier
+	 *            supplier
+	 * @return result of {@link Supplier#get()}
+	 */
+	private <T> T inThreadContext(Supplier<T> supplier)
+	{
+		ThreadContext oldContext = ThreadContext.detach();
+
+		try
+		{
+			ThreadContext.setApplication(application);
+
+			return supplier.get();
+		}
+		finally
+		{
+
+			ThreadContext.restore(oldContext);
+		}
+	}
+
+	/**
+	 * Create a new request, by default a {@link MockWebRequest}.
+	 */
+	protected Request newRequest()
+	{
+		return new MockWebRequest(Url.parse("/"));
+	}
+
+	/**
+	 * Never serialize.
+	 */
+	private static final class NeverSerializer implements ISerializer
+	{
+		@Override
+		public byte[] serialize(Object object)
+		{
+			return null;
+		}
+
+		@Override
+		public Object deserialize(byte[] data)
+		{
+			return null;
+		}
+	}
+
+	/**
+	 * Never share anything.
+	 */
+	private static class NeverSessionStore implements ISessionStore
+	{
+
+		@Override
+		public Serializable getAttribute(Request request, String name)
+		{
+			return null;
+		}
+
+		@Override
+		public List<String> getAttributeNames(Request request)
+		{
+			return null;
+		}
+
+		@Override
+		public void setAttribute(Request request, String name, Serializable value)
+		{
+		}
+
+		@Override
+		public void removeAttribute(Request request, String name)
+		{
+		}
+
+		@Override
+		public void invalidate(Request request)
+		{
+		}
+
+		@Override
+		public String getSessionId(Request request, boolean create)
+		{
+			return null;
+		}
+
+		@Override
+		public Session lookup(Request request)
+		{
+			return null;
+		}
+
+		@Override
+		public void bind(Request request, Session newSession)
+		{
+		}
+
+		@Override
+		public void flushSession(Request request, Session session)
+		{
+		}
+
+		@Override
+		public void destroy()
+		{
+		}
+
+		@Override
+		public void registerUnboundListener(UnboundListener listener)
+		{
+		}
+
+		@Override
+		public void unregisterUnboundListener(UnboundListener listener)
+		{
+		}
+
+		@Override
+		public Set<UnboundListener> getUnboundListener()
+		{
+			return null;
+		}
+
+		@Override
+		public void registerBindListener(BindListener listener)
+		{
+		}
+
+		@Override
+		public void unregisterBindListener(BindListener listener)
+		{
+		}
+
+
+		@Override
+
+		public Set<BindListener> getBindListeners()
+		{
+			return null;
+		}
+	}
+
+	/**
+	 * Collects the Html generated by the rendering a page.
+	 * <p>
+	 * Important note: Must be called on a thread bound to an application's {@link ThreadContext}!
 	 *
 	 * @param pageProvider
 	 *            the provider of the page class/instance and its parameters
 	 * @return the html rendered by a page
+	 * 
+	 * @see ThreadContext
 	 */
 	public static CharSequence renderPage(final PageProvider pageProvider)
 	{
@@ -58,7 +357,8 @@ public class ComponentRenderer
 
 		BufferedWebResponse tempResponse = new BufferedWebResponse(null);
 
-		RequestCycle tempRequestCycle = application.createRequestCycle(originalRequestCycle.getRequest(), tempResponse);
+		RequestCycle tempRequestCycle = application
+			.createRequestCycle(originalRequestCycle.getRequest(), tempResponse);
 
 		try
 		{
@@ -74,17 +374,23 @@ public class ComponentRenderer
 	}
 
 	/**
-	 * Collects the html generated by the rendering of a component.
-	 *
+	 * Collects the Html generated by rendering a component.
 	 * <p>
-	 * NOTE: this method is meant to render fresh component instances that are disposed after the
-	 * html has been generate. To avoid unwanted side effects do not use it with components that 
-	 * are from an existing hierarchy.
-	 * </p>
+	 * Important notes:
+	 * <ul>
+	 * <li>this method is meant to render fresh component instances that are disposed after the html
+	 * has been generate. To avoid unwanted side effects do not use it with components that are from
+	 * an existing hierarchy.</li>
+	 * <li>does <strong>not</strong> support rendering
+	 * {@link org.apache.wicket.markup.html.panel.Fragment} instances</li>
+	 * <li>must be called on a thread bound to an application's {@link ThreadContext}!</li>
+	 * </ul>
 	 *
 	 * @param component
 	 *            the component to render.
 	 * @return the html rendered by the component
+	 * 
+	 * @see ThreadContext
 	 */
 	public static CharSequence renderComponent(final Component component)
 	{
@@ -97,10 +403,9 @@ public class ComponentRenderer
 
 		if (oldParent != null && LOGGER.isWarnEnabled())
 		{
-			LOGGER.warn("Component '{}' with a parent '{}' is passed for standalone rendering. " +
-					"It is recommended to render only orphan components because they are not cleaned up/detached" +
-					" after the rendering.",
-					component, oldParent);
+			LOGGER.warn("Component '{}' with a parent '{}' is passed for standalone rendering. "
+				+ "It is recommended to render only orphan components because they are not cleaned up/detached"
+				+ " after the rendering.", component, oldParent);
 		}
 
 		try
@@ -129,7 +434,10 @@ public class ComponentRenderer
 	/**
 	 * A page used as a parent for the component based rendering.
 	 */
-	private static class RenderPage extends WebPage implements IMarkupResourceStreamProvider, IMarkupCacheKeyProvider
+	private static class RenderPage extends WebPage
+		implements
+			IMarkupResourceStreamProvider,
+			IMarkupCacheKeyProvider
 	{
 		/**
 		 * Markup to use when the component to render is not already added to a MarkupContainer
@@ -150,7 +458,8 @@ public class ComponentRenderer
 			try
 			{
 				componentMarkup = component.getMarkup().toString(true);
-			} catch (MarkupNotFoundException mnfx)
+			}
+			catch (MarkupNotFoundException mnfx)
 			{
 				componentMarkup = String.format(DEFAULT_MARKUP, component.getId());
 			}
@@ -159,7 +468,8 @@ public class ComponentRenderer
 		}
 
 		@Override
-		public IResourceStream getMarkupResourceStream(MarkupContainer container, Class<?> containerClass)
+		public IResourceStream getMarkupResourceStream(MarkupContainer container,
+			Class<?> containerClass)
 		{
 			return new StringResourceStream(markup);
 		}

http://git-wip-us.apache.org/repos/asf/wicket/blob/a148e088/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java b/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java
new file mode 100644
index 0000000..fe5aafb
--- /dev/null
+++ b/wicket-core/src/test/java/org/apache/wicket/core/util/string/componentrenderer/ComponentRendererInstanceTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.core.util.string.componentrenderer;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.wicket.core.util.string.ComponentRenderer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for {@link ComponentRenderer}
+ */
+public class ComponentRendererInstanceTest
+{
+	private ComponentRenderer renderer;
+
+	@Before
+	public void setup() {
+		renderer = new ComponentRenderer();
+	}
+	
+	@After
+	public void destroy() {
+		renderer.destroy();
+	}
+	
+	@Test
+	public void render()
+	{
+		CharSequence html = renderer.renderComponent(() -> new Label("id", "Hello renderer"));
+		
+		assertEquals("Hello renderer", html.toString());
+	}
+}
\ No newline at end of file


[2/2] wicket git commit: dont search for ajax indicator twice

Posted by sv...@apache.org.
dont search for ajax indicator twice

ajaAttributes already contains the id; removed superfluous arguments from JavaScript


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/e7597f03
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/e7597f03
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/e7597f03

Branch: refs/heads/master
Commit: e7597f03f2c605badfa114011935cb79a51f2717
Parents: a148e08
Author: Sven Meier <sv...@apache.org>
Authored: Thu Dec 7 18:17:29 2017 +0100
Committer: Sven Meier <sv...@apache.org>
Committed: Thu Dec 7 20:41:57 2017 +0100

----------------------------------------------------------------------
 .../AbstractAutoCompleteBehavior.java           | 15 +---------
 .../html/autocomplete/wicket-autocomplete.js    | 30 ++++++++++----------
 2 files changed, 16 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/e7597f03/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteBehavior.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteBehavior.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteBehavior.java
index 7164ee4..6e9db0f 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteBehavior.java
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/AbstractAutoCompleteBehavior.java
@@ -36,7 +36,6 @@ import org.apache.wicket.request.Response;
 import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
 import org.apache.wicket.request.resource.ResourceReference;
-import org.apache.wicket.util.string.Strings;
 
 /**
  * @since 1.2
@@ -156,20 +155,8 @@ public abstract class AbstractAutoCompleteBehavior extends AbstractDefaultAjaxBe
 	private void renderAutocompleteHead(final IHeaderResponse response)
 	{
 		response.render(JavaScriptHeaderItem.forReference(AUTOCOMPLETE_JS));
-		final String id = getComponent().getMarkupId();
 
-		String indicatorId = findIndicatorId();
-		if (Strings.isEmpty(indicatorId))
-		{
-			indicatorId = "null";
-		}
-		else
-		{
-			indicatorId = "'" + indicatorId + "'";
-		}
-
-		String initJS = String.format("new Wicket.AutoComplete('%s', %s, %s, %s);", id,
-			renderAjaxAttributes(getComponent(), getAttributes()), constructSettingsJS(), indicatorId);
+		String initJS = String.format("new Wicket.AutoComplete(%s, %s);", renderAjaxAttributes(getComponent()), constructSettingsJS());
 
 		final OnDomReadyHeaderItem onDomReady = OnDomReadyHeaderItem.forScript(initJS);
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/e7597f03/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/wicket-autocomplete.js
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/wicket-autocomplete.js b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/wicket-autocomplete.js
index 5fa8d2e..26f4b8d 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/wicket-autocomplete.js
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/markup/html/autocomplete/wicket-autocomplete.js
@@ -35,7 +35,7 @@
 		enterHidesWithNoSelection : false
 	};
 
-	Wicket.AutoComplete=function(elementId, ajaxAttributes, cfg, indicatorId){
+	Wicket.AutoComplete=function(ajaxAttributes, cfg){
 		var KEY_TAB=9;
 		var KEY_ENTER=13;
 		var KEY_ESC=27;
@@ -85,7 +85,7 @@
 				choiceDiv.parentNode.parentNode.removeChild(choiceDiv.parentNode);
 			}
 
-			var obj = Wicket.$(elementId);
+			var obj = Wicket.$(ajaxAttributes.c);
 			initialElement = obj;
 
 			Wicket.Event.add(obj, 'blur', function (jqEvent) {
@@ -120,7 +120,7 @@
 							setSelected(selected-1);
 						}
 
-						var searchTerm = Wicket.$(elementId).value;
+						var searchTerm = Wicket.$(ajaxAttributes.c).value;
 						if(selected === -1 && searchTerm) {
 							// select the last element
 							setSelected(elementCount-1);
@@ -292,7 +292,7 @@
 		}
 
 		function getMenuId() {
-			return elementId+"-autocomplete";
+			return ajaxAttributes.c+"-autocomplete";
 		}
 
 		function getAutocompleteMenu() {
@@ -345,7 +345,7 @@
 		}
 
 		function actualUpdateChoices() {
-			prepareAndExecuteAjaxUpdate(doUpdateChoices, Wicket.$(elementId).value);
+			prepareAndExecuteAjaxUpdate(doUpdateChoices, Wicket.$(ajaxAttributes.c).value);
 		}
 		
 		function prepareAndExecuteAjaxUpdate(successHandler, currentInput){
@@ -357,7 +357,7 @@
 
 			attrs.pre = attrs.pre || [];
 			attrs.pre.push(function (attributes) {
-				var input = Wicket.$(elementId);
+				var input = Wicket.$(ajaxAttributes.c);
 				if (!input) {
 					// WICKET-6366 input might no longer be on page
 					return false;
@@ -385,17 +385,17 @@
 		}
 
 		function showIndicator() {
-			Wicket.DOM.show(indicatorId);
+			Wicket.DOM.show(ajaxAttributes.i);
 		}
 
 		function hideIndicator() {
-			Wicket.DOM.hide(indicatorId);
+			Wicket.DOM.hide(ajaxAttributes.i);
 		}
 
 		function showAutoComplete() {
-			var input = Wicket.$(elementId);
+			var input = Wicket.$(ajaxAttributes.c);
 			var container = getAutocompleteContainer();
-			var index=getOffsetParentZIndex(elementId);
+			var index=getOffsetParentZIndex(ajaxAttributes.c);
 			container.show();
 			if (!isNaN(Number(index))) {
 				container.style.zIndex=(Number(index)+1);
@@ -449,7 +449,7 @@
 			}
 			
 			if (triggerChangeOnHide) {
-				var input = Wicket.$(elementId);
+				var input = Wicket.$(ajaxAttributes.c);
 				jQuery(input).triggerHandler('change');
 				triggerChangeOnHide = false;
 			}
@@ -587,7 +587,7 @@
 			getAutocompleteMenu().showingAutocomplete = false;
 
 			// check if the input hasn't been cleared in the meanwhile or has been replaced by ajax
-			var input=Wicket.$(elementId);
+			var input=Wicket.$(ajaxAttributes.c);
 			if ((input !== initialElement) || (document.activeElement !== input) || !cfg.showListOnEmptyInput && (input.value === null || input.value === "")) {
 				hideAutoComplete();
 				hideIndicator();
@@ -615,7 +615,7 @@
 					var value = getSelectedValue();
 					value = handleSelection(value);
 					
-					var input = Wicket.$(elementId);
+					var input = Wicket.$(ajaxAttributes.c);
 					if (value) {
 						input.value = value;
 						triggerChangeOnHide = true;
@@ -686,7 +686,7 @@
 
 		function scheduleEmptyCheck() {
 			window.setTimeout(function() {
-				var input=Wicket.$(elementId);
+				var input=Wicket.$(ajaxAttributes.c);
 				
 				// WICKET-6366 input might no longer be on page
 				if (input) {
@@ -782,7 +782,7 @@
 				sizeAffected = true;
 			}
 			if (sizeAffected) {
-				calculateAndSetPopupBounds(Wicket.$(elementId), menu.parentNode);
+				calculateAndSetPopupBounds(Wicket.$(ajaxAttributes.c), menu.parentNode);
 			} // update stuff related to bounds if needed
 		}