You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jd...@apache.org on 2006/11/04 14:47:08 UTC
svn commit: r471185 [1/2] - in /incubator/wicket/trunk/wicket/src:
main/java/wicket/ main/java/wicket/ajax/ main/java/wicket/markup/
main/java/wicket/markup/html/ main/java/wicket/markup/html/border/
main/java/wicket/markup/html/internal/ main/java/wic...
Author: jdonnerstag
Date: Sat Nov 4 05:47:06 2006
New Revision: 471185
URL: http://svn.apache.org/viewvc?view=rev&rev=471185
Log:
Changed <wicket:head> to make use of MarkupFragments.
Public API is unchanged.
Added:
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/WicketHeadContainer.java
- copied, changed from r464848, incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderPartContainer.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/IMarkupLoadListener.java (with props)
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/WicketHeaderLoader.java (with props)
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_7/
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_7/EmailPage.html (with props)
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_7/EmailPage.java (with props)
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_7/ExpectedResult-1.html (with props)
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_7/ExpectedResult-2.html (with props)
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_7/FormTesterTest.java (with props)
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_7/MyPanel.html (with props)
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_7/MyPanel.java (with props)
Removed:
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderPartContainer.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/resolver/HtmlHeaderResolver.java
Modified:
incubator/wicket/trunk/wicket/src/main/java/wicket/Application.java
incubator/wicket/trunk/wicket/src/main/java/wicket/Component.java
incubator/wicket/trunk/wicket/src/main/java/wicket/MarkupContainer.java
incubator/wicket/trunk/wicket/src/main/java/wicket/Page.java
incubator/wicket/trunk/wicket/src/main/java/wicket/ajax/AjaxRequestTarget.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupCache.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupFragment.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupParser.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebMarkupContainerWithAssociatedMarkup.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebPage.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/border/Border.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderContainer.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderResponse.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HtmlHeaderContainer.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/PortletHeaderContainer.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/Panel.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/DefaultMarkupLoader.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/InheritedMarkupMarkupLoader.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/MarkupFragmentUtils.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/HtmlHeaderSectionHandler.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/TagTypeHandler.java
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/WicketTagIdentifier.java
incubator/wicket/trunk/wicket/src/main/java/wicket/protocol/http/portlet/PortletPage.java
incubator/wicket/trunk/wicket/src/main/java/wicket/response/StringResponse.java
incubator/wicket/trunk/wicket/src/main/java/wicket/settings/IMarkupSettings.java
incubator/wicket/trunk/wicket/src/main/java/wicket/settings/Settings.java
incubator/wicket/trunk/wicket/src/test/java/wicket/ajax/AjaxRequestTargetTest.java
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/MarkupInheritanceExpectedResult_10.html
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/MarkupInheritanceExpectedResult_11.html
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/MarkupInheritanceExpectedResult_12.html
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/html/debug/WicketComponentTreeTestPage_ExpectedResult.html
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/html/header/testing4/Panel1.html
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/html/header/testing4/TestPage_ExpectedResult-1.html
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/parser/filter/HeaderSectionMyLabel.java
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/parser/filter/HeaderSectionMyLabel2.java
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/parser/filter/HeaderSectionPageExpectedResult_14.html
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/parser/filter/HeaderSectionPageExpectedResult_9.html
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/parser/filter/HeaderSectionPageExpectedResult_9a.html
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/parser/filter/HeaderSectionPage_19.java
incubator/wicket/trunk/wicket/src/test/java/wicket/protocol/http/portlet/MockPortletPage.java
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/Application.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/Application.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/Application.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/Application.java Sat Nov 4 05:47:06 2006
@@ -35,9 +35,9 @@
import wicket.application.IComponentInstantiationListener;
import wicket.markup.MarkupCache;
import wicket.markup.html.image.resource.DefaultButtonImageResourceFactory;
+import wicket.markup.parser.onLoadListener.WicketHeaderLoader;
import wicket.markup.resolver.AutoComponentResolver;
import wicket.markup.resolver.FragmentResolver;
-import wicket.markup.resolver.HtmlHeaderResolver;
import wicket.markup.resolver.MarkupInheritanceResolver;
import wicket.markup.resolver.ParentResolver;
import wicket.markup.resolver.WicketLinkResolver;
@@ -719,14 +719,16 @@
{
settingsAccessible = true;
IPageSettings pageSettings = getPageSettings();
+
// Install default component resolvers
pageSettings.addComponentResolver(new ParentResolver());
- pageSettings.addComponentResolver(new AutoComponentResolver());
pageSettings.addComponentResolver(new MarkupInheritanceResolver());
- pageSettings.addComponentResolver(new HtmlHeaderResolver());
pageSettings.addComponentResolver(new WicketLinkResolver());
pageSettings.addComponentResolver(new WicketMessageResolver());
pageSettings.addComponentResolver(new FragmentResolver());
+ pageSettings.addComponentResolver(new AutoComponentResolver());
+
+ getMarkupSettings().addMarkupLoadListener(new WicketHeaderLoader());
// Install button image resource factory
getResourceSettings().addResourceFactory("buttonFactory",
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/Component.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/Component.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/Component.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/Component.java Sat Nov 4 05:47:06 2006
@@ -47,7 +47,7 @@
import wicket.markup.MarkupNotFoundException;
import wicket.markup.MarkupStream;
import wicket.markup.html.IHeaderContributor;
-import wicket.markup.html.internal.HeaderContainer;
+import wicket.markup.html.IHeaderResponse;
import wicket.model.IAssignmentAwareModel;
import wicket.model.IInheritableModel;
import wicket.model.IModel;
@@ -711,8 +711,14 @@
}
/**
- * Gets the markup fragment associated with the component. Except for Pages
- * it is assumed that the first markup element of the fragment is a tag.
+ * Gets the markup fragment associated with the component. Except for Pages,
+ * Panels and Borders, it is assumed that the first markup element of the
+ * fragment is a tag.
+ * <p>
+ * If the markup fragment has been determined previously, the transient cache
+ * of the Component is returned. Else, the parent container will be asked to
+ * provide the markup for its child and the object returned will be cached
+ * for later re-use.
*
* @return markup fragment.
*/
@@ -730,17 +736,17 @@
+ getId());
}
- MarkupFragment markupFragment = parent.getMarkupFragment(getId());
- if (markupFragment == null)
+ this.markupFragment = parent.getMarkupFragment(getId());
+ if (this.markupFragment == null)
{
throw new MarkupNotFoundException("Unable to find markup for Component: " + getId());
}
// Attached behaviors provided by the ComponentTag which
// one of the markup handlers might have added.
- if (markupFragment.size() > 0)
+ if (this.markupFragment.size() > 0)
{
- final ComponentTag tag = markupFragment.getTag();
+ final ComponentTag tag = this.markupFragment.getTag();
// add any behaviors attached to the component tag
if ((tag != null) && tag.hasBehaviors())
@@ -1955,30 +1961,22 @@
* the head section. Make sure that all attached behaviors are asked as
* well.
*
- * @param container
- * The HtmlHeaderContainer
+ * @param response
+ * The response object to write the output to
*/
- public void renderHead(final HeaderContainer container)
+ public void renderHead(final IHeaderResponse response)
{
- if (isHeadRendered() == false)
+ if ((isVisible() == true) && (isHeadRendered() == false))
{
- // first try whether the component can contribute something?
- if (this instanceof IHeaderContributor)
- {
- ((IHeaderContributor)this).renderHead(container.getHeaderResponse());
- }
-
// Ask all behaviors if they have something to contribute to the
// header or body onLoad tag.
if (this.behaviors != null)
{
- final Iterator<IBehavior> iter = this.behaviors.iterator();
- while (iter.hasNext())
+ for (IBehavior behavior : this.behaviors)
{
- IBehavior behavior = iter.next();
if (behavior instanceof IHeaderContributor)
{
- ((IHeaderContributor)behavior).renderHead(container.getHeaderResponse());
+ ((IHeaderContributor)behavior).renderHead(response);
}
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/MarkupContainer.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/MarkupContainer.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/MarkupContainer.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/MarkupContainer.java Sat Nov 4 05:47:06 2006
@@ -29,6 +29,7 @@
import org.apache.commons.logging.LogFactory;
import wicket.annot.AnnotationUtils;
+import wicket.annot.OnAfterRender;
import wicket.feedback.IFeedback;
import wicket.markup.ComponentTag;
import wicket.markup.MarkupElement;
@@ -36,6 +37,8 @@
import wicket.markup.MarkupFragment;
import wicket.markup.MarkupNotFoundException;
import wicket.markup.MarkupStream;
+import wicket.markup.html.IHeaderResponse;
+import wicket.markup.parser.onLoadListener.IMarkupLoadListener;
import wicket.markup.resolver.IComponentResolver;
import wicket.model.IInheritableModel;
import wicket.model.IModel;
@@ -91,7 +94,7 @@
* @see MarkupStream
* @author Jonathan Locke
*/
-public abstract class MarkupContainer<T> extends Component<T>
+public abstract class MarkupContainer<T> extends Component<T> implements Iterable<Component>
{
private static final long serialVersionUID = 1L;
@@ -408,12 +411,8 @@
AnnotationUtils.invokeOnDetachListeners(this);
// Loop through child components
- final Iterator iter = iterator();
- while (iter.hasNext())
+ for (Component child : this)
{
- // Get next child
- final Component child = (Component)iter.next();
-
// Call end request on the child
child.internalDetach();
}
@@ -844,6 +843,18 @@
return this.associatedMarkup;
}
+
+ /**
+ * Make sure changes to the locale and style are handled properly
+ *
+ * @see wicket.Component#onAfterRender()
+ */
+ @OnAfterRender
+ protected void onAfterRender()
+ {
+ this.associatedMarkup = null;
+ super.onAfterRender();
+ }
/**
* Components which whish to analyze the markup and automatically add
@@ -857,6 +868,11 @@
*/
protected void onAssociatedMarkupLoaded(final MarkupFragment markup)
{
+ // Call all register load listeners
+ for (IMarkupLoadListener listener : getApplication().getMarkupSettings().getMarkupLoadListeners())
+ {
+ listener.onAssociatedMarkupLoaded(this, markup);
+ }
}
/**
@@ -1384,5 +1400,22 @@
public boolean isTransparentResolver()
{
return false;
+ }
+
+ /**
+ * @see wicket.Component#renderHead(wicket.markup.html.IHeaderResponse)
+ */
+ @Override
+ public void renderHead(final IHeaderResponse response)
+ {
+ if (isVisible())
+ {
+ super.renderHead(response);
+
+ for (Component child : this)
+ {
+ child.renderHead(response);
+ }
+ }
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/Page.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/Page.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/Page.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/Page.java Sat Nov 4 05:47:06 2006
@@ -365,7 +365,7 @@
throw new MarkupException(
"The component "
+ component
- + " has the same wicket:id as another component already added at the same level");
+ + " has the same wicket:id as another component already rendered at the same level");
}
if (log.isDebugEnabled())
{
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/ajax/AjaxRequestTarget.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/ajax/AjaxRequestTarget.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/ajax/AjaxRequestTarget.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/ajax/AjaxRequestTarget.java Sat Nov 4 05:47:06 2006
@@ -18,13 +18,10 @@
*/
package wicket.ajax;
-import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -32,15 +29,13 @@
import wicket.Application;
import wicket.Component;
import wicket.IRequestTarget;
-import wicket.MarkupContainer;
import wicket.Page;
import wicket.RequestCycle;
import wicket.Response;
-import wicket.markup.html.internal.HeaderContainer;
-import wicket.markup.html.internal.HtmlHeaderContainer;
-import wicket.markup.parser.filter.HtmlHeaderSectionHandler;
+import wicket.markup.html.IHeaderResponse;
+import wicket.markup.html.internal.HeaderResponse;
import wicket.protocol.http.WebResponse;
-import wicket.util.string.AppendingStringBuffer;
+import wicket.response.StringResponse;
import wicket.util.string.Strings;
/**
@@ -56,8 +51,8 @@
* an id attribute in the generated markup that is equal to the value retrieved
* from Component#getMarkupId(). This can be accomplished by either setting the
* id attribute in the html template, or using an attribute modifier that will
- * add the attribute with value Component#getMarkupId() to the tag ( such as
- * MarkupIdSetter )
+ * add the attribute with value Component#getMarkupId() to the tag (such as
+ * MarkupIdSetter)
* <p>
* Any javascript that needs to be evaluater on the client side can be added
* using AjaxRequestTarget#addJavascript(String). For example, this feature can
@@ -70,130 +65,24 @@
*/
public class AjaxRequestTarget implements IRequestTarget
{
- /**
- * Response that uses an encoder to encode its contents
- *
- * @author Igor Vaynberg (ivaynberg)
- */
- private final class EncodingResponse extends WebResponse
- {
- private final AppendingStringBuffer buffer = new AppendingStringBuffer(256);
-
- private boolean escaped = false;
-
- private final Response originalResponse;
-
- /**
- * Construct.
- *
- * @param originalResponse
- */
- public EncodingResponse(Response originalResponse)
- {
- this.originalResponse = originalResponse;
- }
-
- /**
- * @see wicket.Response#encodeURL(CharSequence)
- */
- @Override
- public CharSequence encodeURL(CharSequence url)
- {
- return originalResponse.encodeURL(url);
- }
-
- /**
- * @return contents of the response
- */
- public CharSequence getContents()
- {
- return buffer;
- }
-
- /**
- * NOTE: this method is not supported
- *
- * @see wicket.Response#getOutputStream()
- */
- @Override
- public OutputStream getOutputStream()
- {
- throw new UnsupportedOperationException("Cannot get output stream on StringResponse");
- }
-
- /**
- * @return true if any escaping has been performed, false otherwise
- */
- public boolean isContentsEncoded()
- {
- return escaped;
- }
-
- /**
- * Resets the response to a clean state so it can be reused to save on
- * garbage.
- */
- @Override
- public void reset()
- {
- buffer.clear();
- escaped = false;
-
- }
-
- /**
- * @see wicket.Response#write(CharSequence)
- */
- @Override
- public void write(CharSequence cs)
- {
- String string = cs.toString();
- if (needsEncoding(string))
- {
- string = encode(string);
- escaped = true;
- buffer.append(string);
- }
- else
- {
- buffer.append(cs);
- }
- }
-
- }
-
- private static final Log LOG = LogFactory.getLog(AjaxRequestTarget.class);
+ private static final Log Log = LogFactory.getLog(AjaxRequestTarget.class);
+ /** */
private final List<String> appendJavascripts = new ArrayList<String>();
- /**
- * create a response for component body and javascript that will escape
- * output to make it safe to use inside a CDATA block
- */
- private final EncodingResponse encodingBodyResponse;
-
- /**
- * Response for header contributon that will escape output to make it safe
- * to use inside a CDATA block
- */
- private final EncodingResponse encodingHeaderResponse;
+ /** */
+ private final List<String> prependJavascripts = new ArrayList<String>();
/** the component instances that will be rendered */
private final Map<String, Component> markupIdToComponent = new HashMap<String, Component>();
- private final List<String> prependJavascripts = new ArrayList<String>();
-
/**
* Constructor
*/
public AjaxRequestTarget()
{
- Response response = RequestCycle.get().getResponse();
- encodingBodyResponse = new EncodingResponse(response);
- encodingHeaderResponse = new EncodingResponse(response);
}
-
/**
* Adds a component to the list of components to be rendered
*
@@ -255,7 +144,6 @@
{
}
-
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@@ -272,7 +160,6 @@
return false;
}
-
/**
* @see wicket.IRequestTarget#getLock(RequestCycle)
*/
@@ -315,6 +202,7 @@
*/
public final void respond(final RequestCycle requestCycle)
{
+ final WebResponse response = (WebResponse)requestCycle.getResponse();
try
{
final Application app = Application.get();
@@ -323,7 +211,6 @@
final String encoding = app.getRequestCycleSettings().getResponseRequestEncoding();
// Set content type based on markup type for page
- WebResponse response = (WebResponse)requestCycle.getResponse();
response.setCharacterEncoding(encoding);
response.setContentType("text/xml; charset=" + encoding);
@@ -344,13 +231,12 @@
respondInvocation(response, js);
}
- Iterator<Entry<String, Component>> it = markupIdToComponent.entrySet().iterator();
- while (it.hasNext())
+ for (Map.Entry<String, Component> entry : markupIdToComponent.entrySet())
{
- final Map.Entry<String, Component> entry = it.next();
final Component component = entry.getValue();
final String markupId = entry.getKey();
-
+
+ // render the component
respondComponent(response, markupId, component);
}
@@ -366,9 +252,11 @@
// log the error but output nothing in the response, parse failure
// of response will cause any javascript failureHandler to be
// invoked
- LOG.error("Error while responding to an AJAX request: " + toString(), ex);
- System.out.println(ex.getMessage());
- ex.printStackTrace();
+ Log.error("Error while responding to an AJAX request: " + toString(), ex);
+ }
+ finally
+ {
+ requestCycle.setResponse(response);
}
}
@@ -442,13 +330,7 @@
}
component.setOutputMarkupId(true);
-
- // substitute our encoding response for the real one so we can capture
- // component's markup in a manner safe for transport inside CDATA block
- final Response originalResponse = response;
- encodingBodyResponse.reset();
- RequestCycle.get().setResponse(encodingBodyResponse);
-
+
// Initialize temporary variables
final Page page = component.getPage();
if (page == null)
@@ -461,37 +343,40 @@
page.setVersioned(false);
page.startComponentRender(component);
- component.renderComponent();
+ // render any associated headers of the component
respondHeaderContribution(response, component);
-
- page.endComponentRender(component);
- page.setVersioned(versioned);
+ Response encodingResponse = new StringResponse();
+ try
+ {
+ RequestCycle.get().setResponse(encodingResponse);
+
+ component.renderComponent();
+ }
+ finally
+ {
+ // Restore original response
+ RequestCycle.get().setResponse(response);
+ }
- // Restore original response
- RequestCycle.get().setResponse(originalResponse);
+ page.endComponentRender(component);
+ page.setVersioned(versioned);
response.write("<component id=\"");
response.write(markupId);
response.write("\" ");
- if (encodingBodyResponse.isContentsEncoded())
+ if (needsEncoding(encodingResponse.toString()))
{
response.write(" encoding=\"");
response.write(getEncodingName());
response.write("\" ");
}
response.write("><![CDATA[");
- response.write(encodingBodyResponse.getContents());
+ response.write(encodingResponse.toString());
response.write("]]></component>");
-
- encodingBodyResponse.reset();
-
-
}
- private HeaderContainer header = null;
-
/**
*
* @param response
@@ -499,45 +384,24 @@
*/
private void respondHeaderContribution(final Response response, final Component component)
{
- if (header == null)
+ Response encodingResponse = new StringResponse();
+
+ try
{
- header = new HtmlHeaderContainer(component.getPage(),
- HtmlHeaderSectionHandler.HEADER_ID);
+ final IHeaderResponse headerResponse = new HeaderResponse(encodingResponse);
+ RequestCycle.get().setResponse(headerResponse.getResponse());
+ component.renderHead(headerResponse);
}
-
- Response oldResponse = RequestCycle.get().setResponse(encodingHeaderResponse);
-
- encodingHeaderResponse.reset();
-
- component.renderHead(header);
-
- if (component instanceof MarkupContainer)
+ finally
{
- ((MarkupContainer)component).visitChildren(new Component.IVisitor()
- {
- public Object component(Component component)
- {
- if (component.isVisible())
- {
- component.renderHead(header);
-
- return CONTINUE_TRAVERSAL;
- }
- else
- {
- return CONTINUE_TRAVERSAL_BUT_DONT_GO_DEEPER;
- }
- }
- });
+ RequestCycle.get().setResponse(response);
}
- RequestCycle.get().setResponse(oldResponse);
-
- if (encodingHeaderResponse.getContents().length() != 0)
+ if (encodingResponse.toString().length() != 0)
{
response.write("<header-contribution");
- if (encodingHeaderResponse.isContentsEncoded())
+ if (needsEncoding(encodingResponse.toString()))
{
response.write(" encoding=\"");
response.write(getEncodingName());
@@ -545,14 +409,10 @@
}
// we need to write response as CDATA and parse it on client,
- // because
- // konqueror crashes when there is a <script> element
+ // because konqueror crashes when there is a <script> element
response.write("><![CDATA[<head xmlns:wicket=\"http://wicket.sourceforge.net\">");
-
- response.write(encodingHeaderResponse.getContents());
-
+ response.write(encodingResponse.toString());
response.write("</head>]]>");
-
response.write("</header-contribution>");
}
}
@@ -586,7 +446,5 @@
response.write(javascript);
response.write("]]>");
response.write("</evaluate>");
-
- encodingBodyResponse.reset();
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupCache.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupCache.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupCache.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupCache.java Sat Nov 4 05:47:06 2006
@@ -331,6 +331,7 @@
// add the markup to the cache
if (markupResourceStream.getCacheKey() != null)
{
+ markup.makeImmutable();
markupCache.put(markupResourceStream.getCacheKey(), markup);
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupFragment.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupFragment.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupFragment.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupFragment.java Sat Nov 4 05:47:06 2006
@@ -322,6 +322,12 @@
*/
public final void addMarkupElement(final int pos, final MarkupElement markupElement)
{
+// if ((markupElement instanceof ComponentTag) && (pos > 0) && (pos < size()))
+// {
+// throw new WicketRuntimeException(
+// "ComponentTag's within a MarkupFragment can only be at the first or last position: "
+// + markupElement.toUserDebugString());
+// }
this.markupElements.add(pos, markupElement);
}
@@ -334,6 +340,17 @@
public final MarkupElement removeMarkupElement(final int index)
{
return this.markupElements.remove(index);
+ }
+
+ /**
+ * Remove the element from the list
+ *
+ * @param element
+ * @return true, if removed
+ */
+ public final boolean removeMarkupElement(final MarkupElement element)
+ {
+ return this.markupElements.remove(element);
}
/**
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupParser.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupParser.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupParser.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/MarkupParser.java Sat Nov 4 05:47:06 2006
@@ -75,6 +75,9 @@
/** The root markup fragment of the markup being parsed */
private final MarkupFragment rootFragment;
+ /** The current markup fragment in process */
+ private MarkupFragment currentFragment;
+
/** True if comments are to be removed */
private boolean stripComments;
@@ -165,11 +168,9 @@
}
/**
- * Like internal filters, user provided filters might need access to the
- * markup as well.
+ * Gets the Markup of the resource
*
* @return The markup resource stream
- * @deprecated Since 2.0 please use getMarkupFragment().getMarkup() instead
*/
public final IMarkup getMarkup()
{
@@ -178,13 +179,14 @@
/**
* Like internal filters, user provided filters might need access to the
- * markup as well.
+ * markup as well. But be careful, out of the fragment tree it is always the
+ * one currently in process.
*
* @return The markup resource stream
*/
- public final MarkupFragment getMarkupFragment()
+ public final MarkupFragment getCurrentMarkupFragment()
{
- return this.rootFragment;
+ return this.currentFragment;
}
/**
@@ -196,28 +198,27 @@
// Chain together all the different markup filters and configure them
this.markupFilterChain = xmlParser;
- registerMarkupFilter(new WicketTagIdentifier(markup));
+ registerMarkupFilter(new WicketTagIdentifier(this.markup));
registerMarkupFilter(new TagTypeHandler());
registerMarkupFilter(new HtmlHandler());
registerMarkupFilter(new WicketRemoveTagHandler());
registerMarkupFilter(new WicketLinkTagHandler());
- registerMarkupFilter(new WicketNamespaceHandler(markup));
+ registerMarkupFilter(new WicketNamespaceHandler(this.markup));
// Provided the wicket component requesting the markup is known ...
- final MarkupResourceStream resource = markup.getResource();
+ final MarkupResourceStream resource = this.markup.getResource();
if (resource != null)
{
final ContainerInfo containerInfo = resource.getContainerInfo();
if (containerInfo != null)
{
registerMarkupFilter(new WicketMessageTagHandler());
-
registerMarkupFilter(new BodyOnLoadHandler());
// Pages require additional handlers
if (Page.class.isAssignableFrom(containerInfo.getContainerClass()))
{
- registerMarkupFilter(new HtmlHeaderSectionHandler(this.rootFragment));
+ registerMarkupFilter(new HtmlHeaderSectionHandler(this));
}
registerMarkupFilter(new HeadForceTagIdHandler(containerInfo.getContainerClass()));
@@ -285,12 +286,12 @@
private MarkupFragment parseMarkup()
{
final Stack<MarkupFragment> fragmentStack = new Stack<MarkupFragment>();
- MarkupFragment fragment = this.rootFragment;
-
+ this.currentFragment = this.rootFragment;
+
try
{
// allways remember the latest index (size)
- int size = fragment.size();
+ int size = currentFragment.size();
// Loop through tags
for (ComponentTag tag; null != (tag = (ComponentTag)this.markupFilterChain.nextTag());)
@@ -324,7 +325,7 @@
// Make sure you add it at the correct location.
// IMarkupFilters might have added elements as well.
- fragment.addMarkupElement(size, new RawMarkup(rawMarkup));
+ currentFragment.addMarkupElement(size, new RawMarkup(rawMarkup));
}
if (add)
@@ -335,29 +336,29 @@
{
if (tag.isOpen() || tag.isOpenClose())
{
- fragmentStack.push(fragment);
+ fragmentStack.push(currentFragment);
MarkupFragment newFragment = new MarkupFragment(this.markup);
- fragment.addMarkupElement(newFragment);
- fragment = newFragment;
+ currentFragment.addMarkupElement(newFragment);
+ currentFragment = newFragment;
}
-
- fragment.addMarkupElement(tag);
+
+ currentFragment.addMarkupElement(tag);
if (tag.isClose() || tag.isOpenClose() || tag.hasNoCloseTag())
{
- fragment = fragmentStack.pop();
+ currentFragment = fragmentStack.pop();
}
}
}
else if (tag.isModified())
{
- fragment.addMarkupElement(new RawMarkup(tag.toCharSequence()));
+ currentFragment.addMarkupElement(new RawMarkup(tag.toCharSequence()));
}
this.xmlParser.setPositionMarker();
}
// allways remember the latest index (size)
- size = fragment.size();
+ size = currentFragment.size();
}
}
catch (final ParseException ex)
@@ -366,14 +367,14 @@
final CharSequence text = this.xmlParser.getInputFromPositionMarker(-1);
if (text.length() > 0)
{
- fragment.addMarkupElement(new RawMarkup(text));
+ currentFragment.addMarkupElement(new RawMarkup(text));
}
this.markup.setEncoding(this.xmlParser.getEncoding());
this.markup.setXmlDeclaration(this.xmlParser.getXmlDeclaration());
// Create a MarkupStream and position it at the error location
- MarkupElement element = fragment.get(fragment.size() - 1);
+ MarkupElement element = currentFragment.get(currentFragment.size() - 1);
MarkupStream markupStream = new MarkupStream(this.rootFragment);
while (markupStream.hasMore())
{
@@ -382,7 +383,7 @@
break;
}
}
-
+
throw new MarkupException(markupStream, ex.getMessage(), ex);
}
@@ -402,26 +403,23 @@
rawMarkup = compressWhitespace(rawMarkup);
}
- fragment.addMarkupElement(new RawMarkup(rawMarkup));
+ currentFragment.addMarkupElement(new RawMarkup(rawMarkup));
}
- // Do we have unclosed tags in the markup? Re-balance the markup tree
+ // Do we have unclosed tags in the markup? Re-balance the markup tree
if (fragmentStack.size() > 0)
{
- fragment.handleUnclosedTags();
- fragment = this.rootFragment;
+ currentFragment.handleUnclosedTags();
+ currentFragment = this.rootFragment;
}
-
+
// remove "empty" root fragment
- if ((fragment.size() == 1) && (fragment.get(0) instanceof MarkupFragment))
+ if ((currentFragment.size() == 1) && (currentFragment.get(0) instanceof MarkupFragment))
{
- fragment = (MarkupFragment)fragment.get(0);
+ currentFragment = (MarkupFragment)currentFragment.get(0);
}
- // Make all tags immutable and the list of elements unmodifable
- fragment.makeImmutable();
-
- return fragment;
+ return currentFragment;
}
/**
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebMarkupContainerWithAssociatedMarkup.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebMarkupContainerWithAssociatedMarkup.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebMarkupContainerWithAssociatedMarkup.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebMarkupContainerWithAssociatedMarkup.java Sat Nov 4 05:47:06 2006
@@ -18,20 +18,15 @@
*/
package wicket.markup.html;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import wicket.Component;
import wicket.MarkupContainer;
-import wicket.Response;
-import wicket.WicketRuntimeException;
-import wicket.markup.ComponentTag;
-import wicket.markup.MarkupElement;
-import wicket.markup.MarkupException;
import wicket.markup.MarkupFragment;
import wicket.markup.MarkupStream;
-import wicket.markup.html.internal.HeaderContainer;
-import wicket.markup.html.internal.HeaderPartContainer;
+import wicket.markup.html.internal.WicketHeadContainer;
import wicket.model.IModel;
-import wicket.response.NullResponse;
-import wicket.util.lang.Classes;
/**
* A WebMarkupContainer, such as Panel or Border, with an associated markup
@@ -44,6 +39,8 @@
*/
public class WebMarkupContainerWithAssociatedMarkup<T> extends WebMarkupContainer<T>
{
+ private static final Log log = LogFactory.getLog(WebMarkupContainerWithAssociatedMarkup.class);
+
private static final long serialVersionUID = 1L;
/** True if body onLoad attribute modifiers have been attached */
@@ -52,12 +49,15 @@
/** <wicket:head> is only allowed before <body>, </head>, <wicket:panel> etc. */
private boolean noMoreWicketHeadTagsAllowed = false;
+ /** True, if headers have been added */
+ private transient boolean headersInitialized;
+
/**
* @see Component#Component(MarkupContainer,String)
*/
public WebMarkupContainerWithAssociatedMarkup(MarkupContainer parent, final String id)
{
- super(parent, id);
+ this(parent, id, null);
}
/**
@@ -67,6 +67,8 @@
IModel<T> model)
{
super(parent, id, model);
+
+ getAssociatedMarkup(true);
}
/**
@@ -75,264 +77,38 @@
* @param id
* @return MarkupFragment
*/
+ @Override
public MarkupFragment getMarkupFragment(final String id)
{
- return getMarkupFragment().getChildFragment(id, true);
- }
-
- /**
- * Create a new HeaderPartContainer. Users may wish to do that to
- * implemented more sophisticated header scoping stragegies.
- *
- * @param parent
- * The parent of this component
- *
- * @param id
- * The header component's id
- * @param scope
- * The default scope of the header
- * @return The new HeaderPartContainer
- */
- public HeaderPartContainer newHeaderPartContainer(MarkupContainer parent, final String id,
- final String scope)
- {
- return new HeaderPartContainer(parent, id, this, scope);
- }
-
- /**
- * Called by components like Panel and Border which have associated Markup
- * and which may have a <wicket:head> tag.
- * <p>
- * Whereas 'this' might be a Panel or Border, the HtmlHeaderContainer
- * parameter has been added to the Page as a container for all headers any
- * of its components might wish to contribute.
- * <p>
- * The headers contributed are rendered in the standard way.
- *
- * @param htmlContainer
- * The HtmlHeaderContainer added to the Page
- */
- protected final void renderHeadFromAssociatedMarkupFile(final HeaderContainer htmlContainer)
- {
- // Gracefully getAssociateMarkupStream. Throws no exception in case
- // markup is not found
- final MarkupFragment markupFragment = getAssociatedMarkup(false);
-
- // No associated markup => no header section
- if (markupFragment == null)
- {
- return;
- }
-
- final MarkupStream markupStream = new MarkupStream(markupFragment);
-
- // Position pointer at current (first) header
- this.noMoreWicketHeadTagsAllowed = false;
- while (nextHeaderMarkup(markupStream) != -1)
- {
- Class markupClass = markupStream.getTag().getMarkupClass();
- if (markupClass == null)
- {
- markupClass = markupStream.getContainerClass();
- }
- // Create a HeaderPartContainer and associate the markup
- final HeaderPartContainer headerPart = getHeaderPart(htmlContainer, markupClass,
- markupStream.getCurrentIndex());
- if (headerPart != null)
- {
- // A component's header section must only be added once,
- // no matter how often the same Component has been added
- // to the page or any other container in the hierachy.
- if (htmlContainer.okToRenderComponent(headerPart.getScope(), headerPart.getId()))
- {
- headerPart.autoAdded();
-
- // Check if the Panel/Border requires some <body
- // onload=".."> attribute to be copied to the page's body
- // tag.
- if (checkedBody == false)
- {
- checkedBody = true;
- checkBodyOnLoad();
- }
- }
- else
- {
- // TODO Performance: I haven't found a more efficient
- // solution yet.
- // Already added but all the components in this header part
- // must be touched (that they are rendered)
- Response response = getRequestCycle().getResponse();
- try
- {
- getRequestCycle().setResponse(NullResponse.getInstance());
- headerPart.autoAdded();
- }
- finally
- {
- getRequestCycle().setResponse(response);
- }
- }
- }
-
- // Position the stream after <wicket:head>
- markupStream.skipComponent();
- }
- }
-
- /**
- * Check if the Panel/Border requires some <body onload=".."> attribute to
- * be copied to the page's body tag.
- */
- private void checkBodyOnLoad()
- {
- // Gracefully getAssociateMarkupStream. Throws no exception in case
- // markup is not found
- final MarkupStream associatedMarkupStream = new MarkupStream(getAssociatedMarkup(false));
-
- // No associated markup => no body tag
- if (associatedMarkupStream == null)
- {
- return;
- }
-
- // Remember the current position within markup, where we need to
- // go back to, at the end.
- int index = associatedMarkupStream.getCurrentIndex();
-
- try
+ MarkupFragment fragment = getMarkupFragment().getChildFragment(id, false);
+ if (fragment != null)
{
- associatedMarkupStream.setCurrentIndex(0);
- while (associatedMarkupStream.hasMoreComponentTags())
- {
- final ComponentTag tag = associatedMarkupStream.getTag();
- if (tag.isBodyTag())
- {
- final CharSequence onLoad = tag.getString("onload");
- if (onLoad != null)
- {
- // Attach an AttributeModifier to the body container
- // which appends the new value to the onLoad
- // attribute
- getWebPage().getBodyContainer().addOnLoadModifier(onLoad, this);
- }
-
- // There can only be one body tag
- break;
- }
- }
- }
- finally
- {
- // Make sure we return to the orginal position in the markup
- associatedMarkupStream.setCurrentIndex(index);
+ return fragment;
}
+
+ return getAssociatedMarkup(true).getChildFragment(id, true);
}
/**
- * Gets the header part of the Panel/Border. Returns null if it doesn't have
- * a header tag.
- *
- * @param parent
- * The parent of this component
- *
- * @param index
- * A unique index
- * @param markupClass
- * The java class the wicket:head tag is directly associated with
- * @return the header part for this panel/border or null if it doesn't have
- * a wicket:head tag.
+ * @see wicket.Component#renderHead(wicket.markup.html.IHeaderResponse)
*/
- private final HeaderPartContainer getHeaderPart(MarkupContainer parent,
- final Class markupClass, final int index)
+ @Override
+ public void renderHead(final IHeaderResponse response)
{
- // Gracefully getAssociateMarkupStream. Throws no exception in case
- // markup is not found
- final MarkupStream markupStream = new MarkupStream(getAssociatedMarkup(false));
-
- // Position markup stream at beginning of header tag
- markupStream.setCurrentIndex(index);
-
- // Create a HtmlHeaderContainer for the header tag found
- final ComponentTag tag = markupStream.getTag(false);
- if ((tag != null) && tag.isWicketHeadTag())
+ if (isVisible())
{
- // found <wicket:head>. Create a unique id for the
- // HtmlHeaderContainer to be created
- final String headerId = Component.AUTO_COMPONENT_PREFIX
- + Classes.simpleName(markupClass) + getVariation() + "Header" + index;
-
- // Create the header container and associate the markup with
- // it
- String scope = tag.getAttributes().getString(
- markupStream.getWicketNamespace() + ":scope");
- final HeaderPartContainer headerContainer = newHeaderPartContainer(parent, headerId,
- scope);
- headerContainer.setMyMarkupStream(markupStream);
- headerContainer.setRenderBodyOnly(true);
-
- // The container does have a header component
- return headerContainer;
- }
-
- throw new WicketRuntimeException("Programming error: expected a WicketTag: "
- + markupStream.toString());
- }
-
- /**
- *
- * @param associatedMarkupStream
- * @return xxx
- */
- private final int nextHeaderMarkup(final MarkupStream associatedMarkupStream)
- {
- // No associated markup => no header section
- if (associatedMarkupStream == null)
- {
- return -1;
- }
-
- // Scan the markup for <wicket:head>.
- MarkupElement elem = associatedMarkupStream.get();
- while (elem != null)
- {
- if (elem instanceof ComponentTag)
+ // Load the markup and create the header containers if necessary
+ getAssociatedMarkup(true);
+
+ for (Component child : this)
{
- ComponentTag tag = (ComponentTag)elem;
- if (tag.isOpen() && tag.isWicketHeadTag())
- {
- if (this.noMoreWicketHeadTagsAllowed == true)
- {
- throw new MarkupException(
- "<wicket:head> tags are only allowed before <body>, </head>, <wicket:panel> etc. tag. Component: "
- + this.toString());
- }
- return associatedMarkupStream.getCurrentIndex();
- }
- else if (this.noMoreWicketHeadTagsAllowed == false)
+ if (child instanceof WicketHeadContainer)
{
- // wicket:head must be before border, panel or extend
- if (tag.isOpen()
- && (tag.isPanelTag() || tag.isBorderTag() || tag.isExtendTag()))
- {
- this.noMoreWicketHeadTagsAllowed = true;
- }
- // wicket:head must be before </head>
- else if (tag.isClose() && tag.isHeadTag())
- {
- this.noMoreWicketHeadTagsAllowed = true;
- }
- // wicket:head must be before <body>
- else if (tag.isOpen() && tag.isBodyTag())
- {
- this.noMoreWicketHeadTagsAllowed = true;
- }
+ child.render(new MarkupStream(child.getMarkupFragment()));
}
}
- elem = associatedMarkupStream.next();
+
+ super.renderHead(response);
}
-
- // No (more) wicket:head found
- return -1;
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebPage.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebPage.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebPage.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/WebPage.java Sat Nov 4 05:47:06 2006
@@ -37,11 +37,13 @@
import wicket.markup.ComponentTag;
import wicket.markup.MarkupFragment;
import wicket.markup.MarkupStream;
+import wicket.markup.html.internal.HeaderContainer;
import wicket.markup.html.internal.HtmlBodyContainer;
import wicket.markup.html.internal.HtmlHeaderContainer;
import wicket.markup.html.link.BookmarkablePageLink;
import wicket.markup.parser.filter.BodyOnLoadHandler;
import wicket.markup.parser.filter.HtmlHeaderSectionHandler;
+import wicket.markup.parser.filter.WicketTagIdentifier;
import wicket.model.IModel;
import wicket.model.Model;
import wicket.protocol.http.WebRequest;
@@ -86,6 +88,12 @@
/** log. */
private static final Log log = LogFactory.getLog(WebPage.class);
+ static
+ {
+ // register "wicket:head"
+ WicketTagIdentifier.registerWellKnownTagName("head");
+ }
+
/** meta data key for missing body tags logging. */
private static final MetaDataKey PAGEMAP_ACCESS_MDK = new MetaDataKey(
PageMapAccessMetaData.class)
@@ -172,12 +180,23 @@
*
* @return The body container
*/
- public BodyContainer getBodyContainer()
+ public final BodyContainer getBodyContainer()
{
return bodyContainer;
}
/**
+ * Gets the container for the <head> tag, which will also render
+ * the <wicket:head> tags.
+ *
+ * @return The header container
+ */
+ public final HeaderContainer getHeaderContainer()
+ {
+ return (HeaderContainer)get(HtmlHeaderSectionHandler.HEADER_ID);
+ }
+
+ /**
* Gets the markup type for a WebPage, which is "html" by default. Support
* for pages in another markup language, such as VXML, would require the
* creation of a different Page subclass in an appropriate package under
@@ -264,48 +283,40 @@
*/
protected void onAssociatedMarkupLoaded(final MarkupFragment markup)
{
- // Add a Body container if the associated markup contains a <body> tag
- // get markup stream gracefully
- MarkupStream markupStream = new MarkupStream(markup);
-
- // The <body> container. It can be accessed, replaced
- // and attribute modifiers can be attached. <body> tags without
- // wicket:id get automatically a wicket:id assigned.
- while (markupStream.hasMoreComponentTags())
+ if (get(HtmlHeaderSectionHandler.HEADER_ID) == null)
{
- final ComponentTag tag = markupStream.getTag();
- if (tag.isOpen() && tag.isBodyTag())
+ // Add a Body container if the associated markup contains a <body> tag
+ // get markup stream gracefully
+ MarkupStream markupStream = new MarkupStream(markup);
+
+ // The <body> container. It can be accessed, replaced
+ // and attribute modifiers can be attached. <body> tags without
+ // wicket:id get automatically a wicket:id assigned.
+ while (markupStream.hasMoreComponentTags())
{
- // Add a default container if the tag has the default
- // name. If the tag has a wicket:id, than the user
- // must create the component.
- if (BodyOnLoadHandler.BODY_ID.equals(tag.getId()))
+ final ComponentTag tag = markupStream.getTag();
+ if (tag.isOpen() && tag.isBodyTag())
{
- new HtmlBodyContainer(this, tag.getId());
+ // Add a default container if the tag has the default
+ // name. If the tag has a wicket:id, than the user
+ // must create the component.
+ if (BodyOnLoadHandler.BODY_ID.equals(tag.getId()))
+ {
+ new HtmlBodyContainer(this, tag.getId());
+ }
+ // remember the id of the tag
+ bodyContainer = new BodyContainer(this, tag.getId());
+ break;
}
- // remember the id of the tag
- bodyContainer = new BodyContainer(this, tag.getId());
- break;
}
}
-
+
// The <head> container. It can be accessed, replaced
// and attribute modifiers can be attached.
- markupStream.setCurrentIndex(0);
- while (markupStream.hasMoreComponentTags())
+ // HtmlHeaderSectionHandler guarantees the <head> tag does exist.
+ if (get(HtmlHeaderSectionHandler.HEADER_ID) == null)
{
- final ComponentTag tag = markupStream.getTag();
- if (tag.isOpen() && tag.isHeadTag())
- {
- // Add a default container if the tag has the default
- // name. If the tag has a wicket:id, than the user
- // must create the component.
- if (HtmlHeaderSectionHandler.HEADER_ID.equals(tag.getId()))
- {
- new HtmlHeaderContainer(this, tag.getId());
- }
- break;
- }
+ new HtmlHeaderContainer(this, HtmlHeaderSectionHandler.HEADER_ID);
}
// if automatic multi window support is on, add a page checker instance
@@ -313,6 +324,9 @@
{
add(new PageMapChecker());
}
+
+ // Do all the default staff
+ super.onAssociatedMarkupLoaded(markup);
}
/**
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/border/Border.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/border/Border.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/border/Border.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/border/Border.java Sat Nov 4 05:47:06 2006
@@ -27,7 +27,7 @@
import wicket.markup.MarkupStream;
import wicket.markup.html.WebMarkupContainer;
import wicket.markup.html.WebMarkupContainerWithAssociatedMarkup;
-import wicket.markup.html.internal.HeaderContainer;
+import wicket.markup.html.internal.WicketHeadContainer;
import wicket.markup.parser.XmlTag;
import wicket.markup.parser.filter.WicketTagIdentifier;
import wicket.markup.resolver.IComponentResolver;
@@ -184,7 +184,7 @@
{
// If, and only if, a body container exists, than redirect new
// components to become children of the body.
- return (this.body != null ? this.body : this);
+ return ((this.body == null) || WicketHeadContainer.class.isInstance(childClass) ? this : this.body);
}
/**
@@ -219,8 +219,16 @@
public MarkupFragment getMarkupFragment(final String id)
{
// Find the tag in the associated markup
- return getAssociatedMarkup(true).getWicketFragment(BORDER, true)
+ MarkupFragment fragment = getAssociatedMarkup(true).getWicketFragment(BORDER, true)
.getChildFragment(id, false);
+
+ if (fragment != null)
+ {
+ return fragment;
+ }
+
+ // wicket:head must be search for outside wicket:border
+ return getAssociatedMarkup(true).getChildFragment(id, true);
}
/**
@@ -269,20 +277,6 @@
// Unable to resolve the request
return false;
- }
-
- /**
- *
- * @see wicket.Component#renderHead(wicket.markup.html.internal.HeaderContainer)
- */
- @Override
- public void renderHead(final HeaderContainer container)
- {
- if (isHeadRendered() == false)
- {
- this.renderHeadFromAssociatedMarkupFile(container);
- }
- super.renderHead(container);
}
/**
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderContainer.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderContainer.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderContainer.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderContainer.java Sat Nov 4 05:47:06 2006
@@ -18,20 +18,20 @@
*/
package wicket.markup.html.internal;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import wicket.Component;
import wicket.MarkupContainer;
import wicket.Page;
+import wicket.annot.OnBeforeRender;
+import wicket.annot.OnDetach;
import wicket.markup.html.IHeaderResponse;
import wicket.markup.html.WebMarkupContainer;
/**
* HeaderContainer is a base class for {@link HtmlHeaderContainer} and
- * {$link PortletHeaderContainer}
+ * {@link PortletHeaderContainer}
*
* @author Juergen Donnerstag
* @author Janne Hietamäki
@@ -47,12 +47,14 @@
* markup which contains the wicket:head. It can be modified by means of the
* scope attribute.
*/
- private Map<String, List<String>> renderedComponentsPerScope;
+ private transient Map<String, Map<Class, MarkupContainer>> componentsPerScope;
/**
- * Header response that is responsible for filtering duplicate contributions.
+ * Header response that is responsible for filtering duplicate
+ * contributions.
*/
- private transient IHeaderResponse headerResponse = null;
+ private transient IHeaderResponse headerResponse = null;
+
/**
* Construct
*
@@ -68,46 +70,23 @@
// including the page does have a <head> or <wicket:head> tag.
setRenderBodyOnly(true);
}
-
+
/**
* Ask all child components of the Page if they have something to contribute
* to the <head> section of the HTML output. Every component
- * interested must implement IHeaderContributor.
+ * interested must subclass Component.renderHead().
* <p>
* Note: HtmlHeaderContainer will be removed from the component hierachie at
* the end of the request (@see #onEndRequest()) and thus can not transport
* status from one request to the next. This is true for all components
- * added to the header.
+ * added to the header as well.
*
* @param page
* The page object
- * @param container
- * The header component container
*/
- protected final void renderHeaderSections(final Page page, final HeaderContainer container)
+ protected final void renderHeaderSections(final Page page)
{
- // Make sure all Components interested in contributing to the header
- // and there attached behaviors are asked.
- page.visitChildren(new IVisitor()
- {
- /**
- * @see wicket.Component.IVisitor#component(wicket.Component)
- */
- public Object component(Component component)
- {
- if (component.isVisible())
- {
- component.renderHead(container);
- return IVisitor.CONTINUE_TRAVERSAL;
- }
- else
- {
- return IVisitor.CONTINUE_TRAVERSAL_BUT_DONT_GO_DEEPER;
- }
- }
- });
-
- page.renderHead(container);
+ page.renderHead(new HeaderResponse(getResponse()));
}
/**
@@ -122,58 +101,58 @@
/**
* Check if the header component is ok to render within the scope given.
*
- * @param scope
- * The scope of the header component
- * @param id
- * The component's id
- * @return true, if the component ok to render
+ * @param header
+ * The header part container to check
+ * @return true, if the component is eligable to create and render
*/
- public final boolean okToRenderComponent(final String scope, final String id)
+ public boolean okToRender(final WicketHeadContainer header)
{
- if (this.renderedComponentsPerScope == null)
+ if (this.componentsPerScope == null)
{
- this.renderedComponentsPerScope = new HashMap<String, List<String>>();
+ this.componentsPerScope = new HashMap<String, Map<Class, MarkupContainer>>();
}
- // if (scope == null)
- // {
- // scope = header.getMarkupStream().getContainerClass().getName();
- // }
-
- List<String> componentScope = this.renderedComponentsPerScope.get(scope);
+ String scope = header.getScope();
+ Map<Class, MarkupContainer> componentScope = this.componentsPerScope.get(scope);
if (componentScope == null)
{
- componentScope = new ArrayList<String>();
- this.renderedComponentsPerScope.put(scope, componentScope);
+ componentScope = new HashMap<Class, MarkupContainer>();
+ this.componentsPerScope.put(scope, componentScope);
}
- if (componentScope.contains(id))
+ Class markupClass = header.getMarkupFragment().getMarkup().getResource().getMarkupClass();
+ Component creator = componentScope.get(markupClass);
+ if (creator != null)
{
+ if (creator == header.getParent())
+ {
+ return true;
+ }
return false;
}
- componentScope.add(id);
+
+ componentScope.put(markupClass, header.getParent());
return true;
}
- @Override
- protected void onDetach()
+ /**
+ *
+ * @see wicket.Component#onBeforeRender()
+ */
+ @OnBeforeRender
+ protected void onBeforeRender()
{
- super.onDetach();
-
- this.renderedComponentsPerScope = null;
- this.headerResponse = null;
+ // not needed anymore, which is why it can be transient
+ this.componentsPerScope = null;
}
/**
- * Returns the header response.
- *
- * @return header response
+ * @see wicket.Component#onDetach()
*/
- public IHeaderResponse getHeaderResponse() {
- if (this.headerResponse == null)
- {
- headerResponse = new HeaderResponse(getResponse());
- }
- return headerResponse;
+ @OnDetach
+ protected void onDetach()
+ {
+ this.componentsPerScope = null;
+ this.headerResponse = null;
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderResponse.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderResponse.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderResponse.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderResponse.java Sat Nov 4 05:47:06 2006
@@ -34,7 +34,7 @@
*
* @author Matej Knopp
*/
-class HeaderResponse implements IHeaderResponse
+public class HeaderResponse implements IHeaderResponse
{
private static final long serialVersionUID = 1L;
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HtmlHeaderContainer.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HtmlHeaderContainer.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HtmlHeaderContainer.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HtmlHeaderContainer.java Sat Nov 4 05:47:06 2006
@@ -104,7 +104,7 @@
// with the markup
super.onComponentTagBody(markupStream, openTag);
- renderHeaderSections(getPage(), this);
+ renderHeaderSections(getPage());
// Automatically add <head> if necessary
CharSequence output = response.getBuffer();
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/PortletHeaderContainer.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/PortletHeaderContainer.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/PortletHeaderContainer.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/PortletHeaderContainer.java Sat Nov 4 05:47:06 2006
@@ -84,7 +84,7 @@
// must be a Page
if (parent instanceof Page)
{
- renderHeaderSections((Page)parent, this);
+ renderHeaderSections((Page)parent);
}
else
{
Copied: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/WicketHeadContainer.java (from r464848, incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderPartContainer.java)
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/WicketHeadContainer.java?view=diff&rev=471185&p1=incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderPartContainer.java&r1=464848&p2=incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/WicketHeadContainer.java&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/HeaderPartContainer.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/internal/WicketHeadContainer.java Sat Nov 4 05:47:06 2006
@@ -18,46 +18,65 @@
*/
package wicket.markup.html.internal;
-import wicket.Component;
import wicket.MarkupContainer;
-import wicket.markup.ComponentTag;
+import wicket.Response;
+import wicket.markup.MarkupFragment;
import wicket.markup.MarkupStream;
import wicket.markup.html.WebMarkupContainer;
-import wicket.markup.resolver.IComponentResolver;
+import wicket.response.NullResponse;
/**
- * For each wicket:head tag a HeaderPartContainer is created and added to the
+ * For each wicket:head tag a WicketHeadContainer is created and added to the
* HtmlHeaderContainer which has been added to the Page.
*
* @author Juergen Donnerstag
*/
-public final class HeaderPartContainer extends WebMarkupContainer implements IComponentResolver
+public final class WicketHeadContainer extends WebMarkupContainer
{
private static final long serialVersionUID = 1L;
- /** The panel or bordered page the header part is associated with */
- private final MarkupContainer container;
+ /** The scope attribute of the wicket:head tag */
+ private String scope;
- /** <wicket:head scope="...">. A kind of namespace */
- private final String scope;
+ private boolean enable = true;
/**
* @param parent
- * The parent of this component
+ * The owner parent of this component
* @param id
* The component id
- * @param container
- * The Panel (or bordered page) the header part is associated
- * with
- * @param scope
- * The scope of the wicket:head tag
+ * @param fragment
+ * The markup fragment associated with the wicket:head
*/
- public HeaderPartContainer(MarkupContainer parent, final String id,
- final MarkupContainer container, final String scope)
+ public WicketHeadContainer(final MarkupContainer parent, final String id,
+ final MarkupFragment fragment)
{
super(parent, id);
- this.container = container;
- this.scope = scope;
+
+ // It is an auto component; make sure the markup loads properly
+ getMarkupFragment();
+
+ setRenderBodyOnly(true);
+ }
+
+ /**
+ * Enable/disable the header part and its childs. It is very similar to
+ * setVisible() but as childs are added to the parent (Panel, Border) and
+ * not the HeaderContainer, does setVisible() not work.
+ *
+ * @param enable
+ */
+ public final void setEnable(final boolean enable)
+ {
+ this.enable = enable;
+ }
+
+ /**
+ * @return True, if header part and it childs are to be rendered.
+ */
+ public final boolean isEnable()
+ {
+ return this.enable;
}
/**
@@ -67,35 +86,43 @@
*/
public final String getScope()
{
+ if (this.scope == null)
+ {
+ String namespace = getMarkupFragment().getMarkup().getWicketNamespace();
+ this.scope = getMarkupFragment().getTag().getAttributes().getString(namespace + ":scope");
+ }
+
return this.scope;
}
/**
- * @see IComponentResolver#resolve(MarkupContainer, MarkupStream,
- * ComponentTag)
+ * @see wicket.MarkupContainer#isTransparentResolver()
*/
- public final boolean resolve(final MarkupContainer container, final MarkupStream markupStream,
- final ComponentTag tag)
+ @Override
+ public boolean isTransparentResolver()
{
- // The tag must be resolved against the panel and not against the
- // page
- Component component = this.container.get(tag.getId());
- if (component != null)
- {
- component.render(markupStream);
- return true;
- }
-
- return false;
+ return true;
}
/**
- * @see #setMarkupStream(MarkupStream)
- *
- * @param markupStream
+ * @see wicket.MarkupContainer#onRender(wicket.markup.MarkupStream)
*/
- public final void setMyMarkupStream(final MarkupStream markupStream)
+ @Override
+ protected void onRender(final MarkupStream markupStream)
{
- super.setMarkupStream(markupStream);
+ Response response = getRequestCycle().getResponse();
+ try
+ {
+ if (this.enable == false)
+ {
+ getRequestCycle().setResponse(NullResponse.getInstance());
+ }
+ super.onRender(new MarkupStream(getMarkupFragment()));
+ }
+ finally
+ {
+ markupStream.skipComponent();
+ getRequestCycle().setResponse(response);
+ }
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/Panel.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/Panel.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/Panel.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/Panel.java Sat Nov 4 05:47:06 2006
@@ -22,7 +22,6 @@
import wicket.markup.MarkupFragment;
import wicket.markup.MarkupStream;
import wicket.markup.html.WebMarkupContainerWithAssociatedMarkup;
-import wicket.markup.html.internal.HeaderContainer;
import wicket.markup.parser.XmlTag;
import wicket.markup.parser.filter.WicketTagIdentifier;
import wicket.model.IModel;
@@ -97,8 +96,19 @@
* @param id
* @return MarkupFragment
*/
+ @Override
public MarkupFragment getMarkupFragment(final String id)
{
+ // Find the tag in the associated markup
+ MarkupFragment fragment = getAssociatedMarkup(true).getWicketFragment(PANEL, true)
+ .getChildFragment(id, false);
+
+ if (fragment != null)
+ {
+ return fragment;
+ }
+
+ // wicket:head must be searched for outside wicket:panel
return getAssociatedMarkup(true).getChildFragment(id, true);
}
@@ -137,20 +147,5 @@
// Skip any raw markup in the body
markupStream.skipRawMarkup();
}
- }
-
- /**
- * Check the associated markup file for a wicket header tag
- *
- * @see wicket.Component#renderHead(wicket.markup.html.internal.HeaderContainer)
- */
- @Override
- public void renderHead(HeaderContainer container)
- {
- if (isHeadRendered() == false)
- {
- this.renderHeadFromAssociatedMarkupFile(container);
- }
- super.renderHead(container);
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/DefaultMarkupLoader.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/DefaultMarkupLoader.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/DefaultMarkupLoader.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/DefaultMarkupLoader.java Sat Nov 4 05:47:06 2006
@@ -22,6 +22,7 @@
import wicket.Application;
import wicket.MarkupContainer;
+import wicket.markup.MarkupElement;
import wicket.markup.MarkupFragment;
import wicket.markup.MarkupResourceStream;
import wicket.util.resource.ResourceStreamNotFoundException;
@@ -59,6 +60,42 @@
MarkupFragment markup = application.getMarkupSettings().getMarkupParserFactory()
.newMarkupParser(markupResourceStream).readAndParse();
+ checkHeaders(markup);
+
return markup;
+ }
+
+ /**
+ * On Pages with wicket:head and automatically added head tag, move the
+ * wicket:head tags inside the head tag.
+ *
+ * @param markup
+ */
+ private void checkHeaders(final MarkupFragment markup)
+ {
+ final MarkupFragment header = MarkupFragmentUtils.getHeadTag(markup);
+ if (header != null)
+ {
+ markup.visitChildren(MarkupFragment.class, new MarkupFragment.IVisitor()
+ {
+ public Object visit(final MarkupElement element, final MarkupFragment parent)
+ {
+ if (element == header)
+ {
+ return CONTINUE_TRAVERSAL_BUT_DONT_GO_DEEPER;
+ }
+
+ if (((MarkupFragment)element).getTag().isWicketHeadTag())
+ {
+ if (parent.removeMarkupElement(element) == true)
+ {
+ header.addMarkupElement(header.size() - 1, element);
+ }
+ }
+
+ return CONTINUE_TRAVERSAL;
+ }
+ });
+ }
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/InheritedMarkupMarkupLoader.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/InheritedMarkupMarkupLoader.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/InheritedMarkupMarkupLoader.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/InheritedMarkupMarkupLoader.java Sat Nov 4 05:47:06 2006
@@ -25,6 +25,7 @@
import org.apache.commons.logging.LogFactory;
import wicket.Application;
+import wicket.Component;
import wicket.MarkupContainer;
import wicket.Page;
import wicket.markup.ComponentTag;
@@ -433,6 +434,24 @@
{
ComponentTag tag = (ComponentTag)element;
tag.setMarkupClass(parent.getMarkup().getResource().getMarkupClass());
+ return CONTINUE_TRAVERSAL;
+ }
+ });
+
+ // Make sure that wicket:head tags don't have doublicate ids.
+ mergedMarkup.visitChildren(MarkupFragment.class, new MarkupFragment.IVisitor()
+ {
+ private int index = 0;
+
+ public Object visit(final MarkupElement element, final MarkupFragment parent)
+ {
+ MarkupFragment fragment = (MarkupFragment) element;
+ ComponentTag tag = fragment.getTag();
+ if ((tag != null) && tag.isWicketHeadTag())
+ {
+ String id = Component.AUTO_COMPONENT_PREFIX + tag.getName() + index++;
+ tag.setId(id);
+ }
return CONTINUE_TRAVERSAL;
}
});
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/MarkupFragmentUtils.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/MarkupFragmentUtils.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/MarkupFragmentUtils.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/loader/MarkupFragmentUtils.java Sat Nov 4 05:47:06 2006
@@ -119,9 +119,10 @@
}
/**
+ * Gets the <head> fragment
*
* @param fragment
- * @return True, if <head> was found
+ * @return Null, if not found
*/
public static final MarkupFragment getHeadTag(final MarkupFragment fragment)
{
@@ -147,6 +148,8 @@
}
/**
+ * Gets the parent fragment of <head> and the position of the
+ * <head> tag
*
* @param fragment
* @return Null, if no <head> was found
@@ -260,6 +263,7 @@
}
/**
+ * Gets the <wicket:head> markup
*
* @param fragment
* @return Null, if no wicket:head found
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/HtmlHeaderSectionHandler.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/HtmlHeaderSectionHandler.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/HtmlHeaderSectionHandler.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/HtmlHeaderSectionHandler.java Sat Nov 4 05:47:06 2006
@@ -24,6 +24,7 @@
import wicket.markup.ComponentTag;
import wicket.markup.MarkupElement;
import wicket.markup.MarkupFragment;
+import wicket.markup.MarkupParser;
import wicket.markup.parser.AbstractMarkupFilter;
import wicket.markup.parser.XmlTag;
@@ -41,29 +42,26 @@
*/
public final class HtmlHeaderSectionHandler extends AbstractMarkupFilter
{
- private static final String BODY = "body";
private static final String HEAD = "head";
/** The automatically assigned wicket:id to >head< tag */
- public static final String HEADER_ID = Component.AUTO_COMPONENT_PREFIX + "<header>";
-
- /** True if <head> has been found already */
- private boolean foundHead = false;
+ public static final String HEADER_ID = Component.AUTO_COMPONENT_PREFIX + "header";
/** True if all the rest of the markup file can be ignored */
private boolean ignoreTheRest = false;
-
- /** The Markup available so far for the resource */
- private final MarkupFragment markup;
-
+
+ /** The markup parser */
+ private final MarkupParser parser;
+
/**
* Construct.
*
- * @param markup The Markup object being filled while reading the markup resource
+ * @param parser
+ * The markup parser
*/
- public HtmlHeaderSectionHandler(final MarkupFragment markup)
+ public HtmlHeaderSectionHandler(final MarkupParser parser)
{
- this.markup = markup;
+ this.parser = parser;
}
/**
@@ -92,41 +90,26 @@
}
// if it is <head> or </head>
- if (HEAD.equalsIgnoreCase(tag.getName()))
+ if (tag.isHeadTag())
{
- if (tag.getNamespace() == null)
- {
- // we found <head>
- if (tag.isClose())
- {
- foundHead = true;
- }
- else if (tag.getId() == null)
- {
- tag.setId(HEADER_ID);
- }
-
- // Usually <head> is not a wicket special tag. But because we want
- // transparent header support we insert it automatically if missing
- // and while rendering its content all child components are asked if
- // they want to contribute something to the header. Thus we have to
- // handle <head> accordingly.
- tag.setInternalTag(true);
- return tag;
- }
- else
+ ignoreTheRest = true;
+
+ if (tag.getId() == null)
{
- // we found <wicket:head>
- foundHead = true;
+ tag.setId(HEADER_ID);
}
+
+ // Usually <head> is not a wicket special tag. But because we want
+ // transparent header support we insert it automatically if missing
+ // and while rendering its content all child components are asked if
+ // they want to contribute something to the header. Thus we have to
+ // handle <head> accordingly.
+ tag.setInternalTag(true);
+ return tag;
}
- else if (BODY.equalsIgnoreCase(tag.getName()) && (tag.getNamespace() == null))
+ else if (tag.isBodyTag())
{
- // We found <body>
- if (foundHead == false)
- {
- insertHeadTag();
- }
+ insertHeadTag();
// <head> must always be before <body>
ignoreTheRest = true;
@@ -145,12 +128,14 @@
// Note: only the open-tag must be a AutoComponentTag
final ComponentTag openTag = new ComponentTag(HEAD, XmlTag.Type.OPEN);
openTag.setId(HEADER_ID);
-
+
final ComponentTag closeTag = new ComponentTag(HEAD, XmlTag.Type.CLOSE);
closeTag.setOpenTag(openTag);
// insert the tags into the markup stream
- this.markup.addMarkupElement(openTag);
- this.markup.addMarkupElement(closeTag);
+ MarkupFragment fragment = new MarkupFragment(parser.getMarkup());
+ fragment.addMarkupElement(openTag);
+ fragment.addMarkupElement(closeTag);
+ this.parser.getCurrentMarkupFragment().addMarkupElement(fragment);
}
}
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/TagTypeHandler.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/TagTypeHandler.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/TagTypeHandler.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/TagTypeHandler.java Sat Nov 4 05:47:06 2006
@@ -46,7 +46,7 @@
static
{
// Tags which require open-body-close
- requireOpenBodyCloseTag.put("select", Boolean.TRUE);
+ registerOpenBodyCloseTag("select");
}
/**
@@ -54,6 +54,17 @@
*/
public TagTypeHandler()
{
+ }
+
+ /**
+ * Register the tags which will be converted from open-close to
+ * open-blody-close if necessary.
+ *
+ * @param name
+ */
+ public static final void registerOpenBodyCloseTag(final String name)
+ {
+ requireOpenBodyCloseTag.put(name, Boolean.TRUE);
}
/**
Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/WicketTagIdentifier.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/WicketTagIdentifier.java?view=diff&rev=471185&r1=471184&r2=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/WicketTagIdentifier.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/filter/WicketTagIdentifier.java Sat Nov 4 05:47:06 2006
@@ -44,11 +44,23 @@
public final class WicketTagIdentifier extends AbstractMarkupFilter
{
/** List of well known wicket tag namses */
- private static List<String> wellKnownTagNames;
+ private static List<String> wellKnownTagNames = new ArrayList<String>();
+ /** wicket tag which require unique ids */
+ private static List<String> requiresUniqueId = new ArrayList<String>();
+
+ static
+ {
+ // register wicket:head
+ registerTagWhichRequiresUniqueId("head");
+ }
+
/** The current markup needed to get the markups namespace */
private final IMarkup markup;
+ /** auto increment to create unique ids */
+ private int index;
+
/**
* Construct.
*
@@ -59,7 +71,7 @@
{
this.markup = markup;
}
-
+
/**
* Get the next tag from the next MarkupFilter in the chain and search for
* Wicket specific tags.
@@ -94,7 +106,12 @@
tag.setWicketTag(true);
// Make it a wicket component. Otherwise it would be RawMarkup
- tag.setId(Component.AUTO_COMPONENT_PREFIX + tag.getName());
+ String id = Component.AUTO_COMPONENT_PREFIX + tag.getName();
+ if (requiresUniqueId.contains(tag.getName()))
+ {
+ id = id + this.index++;
+ }
+ tag.setId(id);
if (wellKnownTagNames.contains(xmlTag.getName()) == false)
{
@@ -129,14 +146,19 @@
*/
public final static void registerWellKnownTagName(final String name)
{
- if (wellKnownTagNames == null)
- {
- wellKnownTagNames = new ArrayList<String>();
- }
-
if (wellKnownTagNames.contains(name) == false)
{
wellKnownTagNames.add(name);
}
+ }
+
+ /**
+ * Register tags, such as wicket:head, which require unique ids.
+ *
+ * @param tag
+ */
+ public final static void registerTagWhichRequiresUniqueId(final String tag)
+ {
+ requiresUniqueId.add(tag);
}
}
Added: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/IMarkupLoadListener.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/IMarkupLoadListener.java?view=auto&rev=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/IMarkupLoadListener.java (added)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/IMarkupLoadListener.java Sat Nov 4 05:47:06 2006
@@ -0,0 +1,46 @@
+/*
+ * $Id: org.eclipse.jdt.ui.prefs 5004 2006-03-17 20:47:08 -0800 (Fri, 17 Mar 2006) eelco12 $
+ * $Revision$
+ * $Date: 2006-03-17 20:47:08 -0800 (Fri, 17 Mar 2006) $
+ *
+ * ==============================================================================
+ * Licensed 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 wicket.markup.parser.onLoadListener;
+
+import wicket.MarkupContainer;
+import wicket.markup.MarkupFragment;
+import wicket.markup.html.WebMarkupContainerWithAssociatedMarkup;
+
+/**
+ * Markup load listeners can be registered with the application and are invoked
+ * after Markup has been loaded from disk. As Wicket will internally cache the
+ * markup it is really only called when loaded.
+ *
+ * @see WebMarkupContainerWithAssociatedMarkup#getAssociatedMarkup(boolean)
+ *
+ * @author Juergen Donnerstag
+ */
+public interface IMarkupLoadListener
+{
+ /**
+ * Invoked after a markup file has been loaded.
+ *
+ * @param container
+ * The container which is associated with the markup
+ *
+ * @param markup
+ * The markup
+ */
+ void onAssociatedMarkupLoaded(final MarkupContainer container, final MarkupFragment markup);
+}
Propchange: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/IMarkupLoadListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/IMarkupLoadListener.java
------------------------------------------------------------------------------
svn:keywords = "LastChangedDate LastChangedRevision URL"
Added: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/WicketHeaderLoader.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/WicketHeaderLoader.java?view=auto&rev=471185
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/WicketHeaderLoader.java (added)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/WicketHeaderLoader.java Sat Nov 4 05:47:06 2006
@@ -0,0 +1,164 @@
+/*
+ * $Id: org.eclipse.jdt.ui.prefs 5004 2006-03-17 20:47:08 -0800 (Fri, 17 Mar 2006) eelco12 $
+ * $Revision$
+ * $Date: 2006-03-17 20:47:08 -0800 (Fri, 17 Mar 2006) $
+ *
+ * ==============================================================================
+ * Licensed 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 wicket.markup.parser.onLoadListener;
+
+import wicket.Component;
+import wicket.MarkupContainer;
+import wicket.Page;
+import wicket.Component.IVisitor;
+import wicket.markup.ComponentTag;
+import wicket.markup.MarkupElement;
+import wicket.markup.MarkupException;
+import wicket.markup.MarkupFragment;
+import wicket.markup.MarkupStream;
+import wicket.markup.html.WebPage;
+import wicket.markup.html.internal.HeaderContainer;
+import wicket.markup.html.internal.WicketHeadContainer;
+import wicket.markup.parser.filter.HtmlHeaderSectionHandler;
+
+/**
+ * Add a markup load listener which adds the wicket:head containers to Page,
+ * Panel, Border etc.
+ *
+ * @author Juergen Donnerstag
+ */
+public class WicketHeaderLoader implements IMarkupLoadListener
+{
+ /** body tag attribute */
+ private static final String ONUNLOAD = "onunload";
+
+ /** body tag attribute */
+ private static final String ONLOAD = "onload";
+
+ /**
+ * @see wicket.markup.parser.onLoadListener.IMarkupLoadListener#onAssociatedMarkupLoaded(wicket.MarkupContainer,
+ * wicket.markup.MarkupFragment)
+ */
+ public void onAssociatedMarkupLoaded(final MarkupContainer container,
+ final MarkupFragment fragment)
+ {
+ // Remove any wicket header container
+ container.visitChildren(WicketHeadContainer.class, new IVisitor()
+ {
+ public Object component(final Component<?> component)
+ {
+ component.remove();
+ return CONTINUE_TRAVERSAL;
+ }
+ });
+
+ // Get the container for the headers from the page
+ final Page page = container.getPage();
+ final HeaderContainer headerContainer;
+ if (container instanceof WebPage)
+ {
+ headerContainer = ((WebPage)page).getHeaderContainer();
+ }
+ else
+ {
+ headerContainer = (HeaderContainer)page.get(HtmlHeaderSectionHandler.HEADER_ID);
+ }
+
+ // Search for wicket:head in the associated markup and copy the body
+ // onload and onunload attributes
+ fragment.visitChildren(MarkupFragment.class, new MarkupFragment.IVisitor()
+ {
+ private boolean foundBody = false;
+
+ /**
+ * @see wicket.markup.MarkupFragment.IVisitor#visit(wicket.markup.MarkupElement,
+ * wicket.markup.MarkupFragment)
+ */
+ public Object visit(final MarkupElement element, final MarkupFragment parent)
+ {
+ final MarkupFragment frag = (MarkupFragment)element;
+ final ComponentTag tag = frag.getTag();
+ if (tag.isWicketHeadTag())
+ {
+ if (foundBody == true)
+ {
+ // Create a MarkupStream and position it at the error
+ // location
+ MarkupStream markupStream = new MarkupStream(fragment);
+ while (markupStream.hasMore())
+ {
+ if (markupStream.next() == tag)
+ {
+ break;
+ }
+ }
+ throw new MarkupException(
+ "<wicket:head> must be before the <body>, <wicket:panel> ... tag");
+ }
+
+ WicketHeadContainer header = newWicketHeaderContainer(container, frag);
+ // TODO check again why setVisible() doesn't work here
+ header.setEnable(headerContainer.okToRender(header));
+
+ return CONTINUE_TRAVERSAL_BUT_DONT_GO_DEEPER;
+ }
+ else if (tag.isBodyTag())
+ {
+ foundBody = true;
+ if (page instanceof WebPage)
+ {
+ WebPage webPage = (WebPage)page;
+ final CharSequence onLoad = tag.getString(ONLOAD);
+ if (onLoad != null)
+ {
+ // Attach an AttributeModifier to the body container
+ // which appends the new value to the onLoad
+ // attribute
+ webPage.getBodyContainer().addOnLoadModifier(onLoad, container);
+ }
+
+ final CharSequence onUnLoad = tag.getString(ONUNLOAD);
+ if (onUnLoad != null)
+ {
+ // Same for unload
+ webPage.getBodyContainer().addOnUnLoadModifier(onUnLoad, container);
+ }
+ }
+ }
+ else if (tag.isMajorWicketComponentTag())
+ {
+ foundBody = true;
+ }
+
+ return CONTINUE_TRAVERSAL;
+ }
+ });
+ }
+
+ /**
+ * Create a new WicketHeadContainer. Users may wish subclass the method to
+ * implemented more sophisticated header scoping stragegies.
+ *
+ * @param parent
+ * The parent for the header
+ * @param fragment
+ * The markup fragment associated with the wicket:head
+ * @return The new header part container s
+ */
+ public WicketHeadContainer newWicketHeaderContainer(final MarkupContainer parent,
+ final MarkupFragment fragment)
+ {
+ return new WicketHeadContainer(parent, fragment.getTag().getId(), fragment);
+ }
+}
Propchange: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/WicketHeaderLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/wicket/trunk/wicket/src/main/java/wicket/markup/parser/onLoadListener/WicketHeaderLoader.java
------------------------------------------------------------------------------
svn:keywords = "LastChangedDate LastChangedRevision URL"