Author: ivaynberg
Date: Sat Jul 9 07:24:18 2011
New Revision: 1144611
URL: http://svn.apache.org/viewvc?rev=1144611&view=rev
Log:
ported wicket:for attribute to trunk
Issue: WICKET-1469
Added:
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
(with props)
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java
(with props)
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java
(with props)
Modified:
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupParser.java
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
Modified:
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupParser.java
URL:
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupParser.java?rev=1144611&r1=1144610&r2=1144611&view=diff
==============================================================================
---
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupParser.java
(original)
+++
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/MarkupParser.java
Sat Jul 9 07:24:18 2011
@@ -19,6 +19,7 @@ package org.apache.wicket.markup;
import java.util.ArrayList;
import org.apache.wicket.Page;
+import org.apache.wicket.markup.html.form.AutoLabelTagHandler;
import org.apache.wicket.markup.parser.IMarkupFilter;
import org.apache.wicket.markup.parser.IXmlPullParser;
import org.apache.wicket.markup.parser.filter.ConditionalCommentFilter;
@@ -146,6 +147,7 @@ public class MarkupParser extends Abstra
filters.add(new HtmlHandler());
filters.add(new WicketRemoveTagHandler());
filters.add(new WicketLinkTagHandler());
+ filters.add(new AutoLabelTagHandler());
filters.add(new WicketNamespaceHandler(markupResourceStream));
// Provided the wicket component requesting the markup is known
...
Added:
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
URL:
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java?rev=1144611&view=auto
==============================================================================
---
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
(added)
+++
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
Sat Jul 9 07:24:18 2011
@@ -0,0 +1,365 @@
+package org.apache.wicket.markup.html.form;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.MarkupStream;
+import org.apache.wicket.markup.RawMarkup;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.parser.XmlPullParser;
+import org.apache.wicket.markup.parser.XmlTag;
+import org.apache.wicket.markup.resolver.IComponentResolver;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.util.string.AppendingStringBuffer;
+import org.apache.wicket.util.string.Strings;
+import org.apache.wicket.util.visit.IVisit;
+import org.apache.wicket.util.visit.IVisitor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Resolver that implements the {@code wicket:for} attribute functionality.
The attribute makes it
+ * easy to set up {@code <label>} tags for form components by providing the
following features
+ * without having to add any additional components in code:
+ * <ul>
+ * <li>Outputs the {@code for} attribute with the value equivalent to the
markup id of the
+ * referenced form component</li>
+ * <li>Appends {@code required} css class to the {@code <label>} tag if the
referenced form
+ * component is required</li>
+ * <li>Appends {@code error} css class to the {@code <label>} tag if the
referenced form component
+ * has failed validation</li>
+ * <li>If the {@code <label>} tag contains {@code <span class='text'></span>}
markup and the form
+ * component has a label configured either via the label model or a property
files, the body of the
+ * {code <span>} will be replaced with the label</li>
+ * <li>If the {@code <label>} tag contains {@code <span
class='text'>body</span>} markup and the
+ * form component does not have a label configured either via the label model
or a properties file,
+ * the label of the form component will be set to the body of the {@code
<span>} tag - in this
+ * example {@code body}</li>
+ * </ul>
+ *
+ * <p>
+ * The value of the {@code wicket:for} atribute can either contain an id of
the form component or a
+ * path a path to it using the standard {@code :} path separator. Note that
{@code ..} can be used
+ * as part of the path to construct a reference to the parent container, eg
{@code ..:..:foo:bar}.
+ * First the value of the attribute will be treated as a path and the {@code
<label>} tag's closest
+ * parent container will be queried for the form component. If the form
component cannot be resolved
+ * the value of the {@code wicket:for} attribute will be treated as an id and
all containers will be
+ * searched from the closest parent to the page.
+ * </p>
+ *
+ * <p>
+ * Given markup like this:
+ *
+ * <code>
+ * [label wicket:for="name"][span class="text"]Name[/span]:[/label][input
wicket:id="name" type="text"/]
+ * </code>
+ *
+ * If the {@code name} component has its label set to 'First Name' the
resulting output will be:
+ * <code>
+ * [label for="name5"][span class="text"]First Name[/span]:[/label][input
name="name" type="text" id="name5"/]
+ * </code>
+ *
+ * However, if the {@code name} component does not have a label set then it
will be set to
+ * {@code Name} based on the markup.
+ * </p>
+ *
+ * @author igor
+ */
+public class AutoLabelResolver implements IComponentResolver
+{
+ private static Logger logger =
LoggerFactory.getLogger(AutoLabelResolver.class);
+
+ public Component resolve(MarkupContainer container, MarkupStream
markupStream, ComponentTag tag)
+ {
+ if (!AutoLabelTagHandler.class.getName().equals(tag.getId()))
+ {
+ return null;
+ }
+
+ final String id = tag.getAttribute("wicket:for").trim();
+
+ FormComponent<?> component = findRelatedComponent(container,
id);
+
+ if (component == null)
+ {
+ throw new WicketRuntimeException("Could not find form
component with id: " + id +
+ " while trying to resolve wicket:for
attribute");
+ }
+ if (!(component instanceof FormComponent<?>))
+ {
+ throw new WicketRuntimeException("Component pointed to
by wicket:for attribute: " + id +
+ " is not a form component");
+ }
+
+ if (!component.getOutputMarkupId())
+ {
+ component.setOutputMarkupId(true);
+ if (!component.hasBeenRendered())
+ {
+ logger.warn(
+ "Form component: {} is reference via a
wicket:for attribute but does not have its outputMarkupId property set to true",
+ component.toString(false));
+ }
+ }
+ final FormComponent<?> fc = component;
+
+ return new AutoLabel("label" +
container.getPage().getAutoIndex(), fc);
+ }
+
+ protected FormComponent<?> findRelatedComponent(MarkupContainer
container, final String id)
+ {
+ // try the quick and easy route first
+
+ Component component = container.get(id);
+ if (component != null && (component instanceof
FormComponent<?>))
+ {
+ return (FormComponent<?>)component;
+ }
+
+ // try the long way, search the hierarchy from the closest
container up to the page
+
+ final Component[] searched = new Component[] { null };
+ while (container != null)
+ {
+ component = container.visitChildren(Component.class,
+ new IVisitor<Component, Component>()
+ {
+ public void component(Component child,
IVisit<Component> visit)
+ {
+ if (child == searched[0])
+ {
+ // this container was
already searched
+ visit.dontGoDeeper();
+ return;
+ }
+ if (id.equals(child.getId()) &&
(child instanceof FormComponent))
+ {
+ visit.stop(child);
+ return;
+ }
+ }
+ });
+
+ if (component != null && (component instanceof
FormComponent))
+ {
+ return (FormComponent<?>)component;
+ }
+
+ // remember the container so we dont search it again,
and search the parent
+ searched[0] = container;
+ container = container.getParent();
+ }
+
+ return null;
+ }
+
+ /**
+ * Component that is attached to the {@code <label>} tag and takes care
of writing out the label
+ * text as well as setting classes on the {@code <label>} tag
+ *
+ * @author igor
+ */
+ protected static class AutoLabel extends WebMarkupContainer
+ {
+ private final FormComponent<?> fc;
+
+ public AutoLabel(String id, FormComponent<?> fc)
+ {
+ super(id);
+ this.fc = fc;
+ }
+
+ @Override
+ protected void onComponentTag(ComponentTag tag)
+ {
+ super.onComponentTag(tag);
+ tag.put("for", fc.getMarkupId());
+ if (fc.isRequired())
+ {
+ tag.append("class", "required", " ");
+ }
+ if (!fc.isValid())
+ {
+ tag.append("class", "error", " ");
+ }
+ }
+
+ @Override
+ public void onComponentTagBody(MarkupStream markupStream,
ComponentTag openTag)
+ {
+ if (!(markupStream.get() instanceof RawMarkup))
+ {
+ // no raw markup found inside the label, do not
modify the contents
+ return;
+ }
+
+ // read all raw markup in the body and find the range
of the label text inside it. the
+ // range is specified as the body of the <span
class='text'></span> tag.
+
+ AppendingStringBuffer markup =
readBodyMarkup(markupStream);
+ int[] range = findLabelTextRange(markup);
+ final int start = range[0];
+ final int end = range[1];
+
+ if (start < 0)
+ {
+ // if we could not find the range of the label
text in the markup we have nothing
+ // further to do
+
+ super.onComponentTagBody(markupStream, openTag);
+ return;
+ }
+
+ // based on whether or not the form component has a
label set read or write it into the
+ // markup
+
+ String label = getFormComponentLabelText(fc);
+
+ if (label != null)
+ {
+ // if label is set write it into the markup
+
+ markup = markup.replace(start, end, label);
+ replaceComponentTagBody(markupStream, openTag,
markup);
+ }
+ else
+ {
+ // if label is not set, read it from the markup
into the form component
+
+ String markupLabel = markup.substring(start,
end);
+ fc.setLabel(Model.of(markupLabel));
+ super.onComponentTagBody(markupStream, openTag);
+ }
+ }
+
+ /**
+ * Finds start and end index of text in the label. This range
is represented by the body of
+ * the {@code <span class='text'></span>} tag
+ *
+ * @param markup
+ * @return
+ */
+ protected int[] findLabelTextRange(AppendingStringBuffer markup)
+ {
+ int[] range = new int[] { -1, -1 };
+
+ XmlPullParser parser = new XmlPullParser();
+ XmlTag opening = null; // opening label text span tag
+ XmlTag closing = null; // close label text span tag
+
+ try
+ {
+ parser.parse(markup);
+
+ XmlTag tag = null; // current tag
+
+ int depth = 0; // depth of span tags
+ int openDepth = -1; // depth of the label text
open span tag
+
+ while (((tag = parser.nextTag()) != null))
+ {
+ if
(!"span".equalsIgnoreCase(tag.getName()) || tag.getNamespace() != null)
+ {
+ // skip non-span tags
+ continue;
+ }
+
+ if (opening != null && tag.isClose() &&
depth == openDepth)
+ {
+ // found the closing tag we
need, we are done
+ closing = tag;
+ break;
+ }
+
+ depth += tag.isOpen() ? 1 : -1;
+
+ if (opening == null && isTextSpan(tag))
+ {
+ // found the opening tag, keep
looking for the closing one
+ opening = tag;
+ openDepth = depth;
+ continue;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new WicketRuntimeException(
+ "Could not parse markup while
processing an auto label for component: " +
+ fc.toString(false), e);
+ }
+
+ if (opening != null)
+ {
+ // calculate the range of the tag's body, this
is where the label text is/will be
+ range[0] = opening.getPos() +
opening.getLength();
+ range[1] = closing.getPos();
+ }
+
+ return range;
+ }
+
+ protected AppendingStringBuffer readBodyMarkup(MarkupStream
markupStream)
+ {
+ int streamIndex = markupStream.getCurrentIndex();
+
+ AppendingStringBuffer markup = new
AppendingStringBuffer();
+ do
+ {
+
markup.append(((RawMarkup)markupStream.get()).toString());
+ markupStream.next();
+ }
+ while ((markupStream.get() instanceof RawMarkup));
+
+ markupStream.setCurrentIndex(streamIndex);
+
+ return markup;
+ }
+
+ protected String getFormComponentLabelText(FormComponent<?> fc)
+ {
+ String label = fc.getLabel() != null ?
fc.getLabel().getObject() : null;
+ if (label == null)
+ {
+ label = fc.getDefaultLabel("wicket:unknown");
+ if ("wicket:unknown".equals(label))
+ {
+ label = null;
+ }
+ }
+ return label;
+ }
+
+ protected final boolean isTextSpan(XmlTag tag)
+ {
+ if (!tag.isOpen())
+ return false;
+
+ if (!"span".equalsIgnoreCase(tag.getName()) ||
tag.getNamespace() != null)
+ return false;
+
+ String classNames =
tag.getAttributes().getString("class");
+ if (Strings.isEmpty(classNames))
+ return false;
+
+ boolean textClassFound = false;
+ for (String className : classNames.split(" "))
+ {
+ if ("text".equals(className))
+ {
+ textClassFound = true;
+ break;
+ }
+ }
+ if (!textClassFound)
+ return false;
+
+
+ return true;
+ }
+
+ }
+
+
+}
Propchange:
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelResolver.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java
URL:
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java?rev=1144611&view=auto
==============================================================================
---
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java
(added)
+++
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java
Sat Jul 9 07:24:18 2011
@@ -0,0 +1,53 @@
+package org.apache.wicket.markup.html.form;
+
+import java.text.ParseException;
+
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.MarkupElement;
+import org.apache.wicket.markup.WicketTag;
+import org.apache.wicket.markup.parser.AbstractMarkupFilter;
+
+/**
+ * Markup filter that identifies tags with the {@code wicket:for} attribute.
See
+ * {@link AutoLabelResolver} for details.
+ *
+ * @author igor
+ */
+public class AutoLabelTagHandler extends AbstractMarkupFilter
+{
+ @Override
+ protected MarkupElement onComponentTag(ComponentTag tag) throws
ParseException
+ {
+ if (tag == null || tag.isClose() || tag instanceof WicketTag)
+ {
+ return tag;
+ }
+
+ String related = tag.getAttribute("wicket:for");
+ if (related == null)
+ {
+ return tag;
+ }
+
+ related = related.trim();
+ if (related.isEmpty())
+ {
+ throw new ParseException("Tag contains an empty
wicket:for attribute", tag.getPos());
+ }
+ if (!"label".equalsIgnoreCase(tag.getName()))
+ {
+ throw new ParseException("Attribute wicket:for can only
be attached to <label> tag",
+ tag.getPos());
+ }
+ if (tag.getId() != null)
+ {
+ throw new ParseException(
+ "Attribute wicket:for cannot be used in
conjunction with wicket:id", tag.getPos());
+ }
+
+ tag.setId(getClass().getName());
+ tag.setModified(true);
+ return tag;
+ }
+
+}
Propchange:
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/AutoLabelTagHandler.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified:
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
URL:
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java?rev=1144611&r1=1144610&r2=1144611&view=diff
==============================================================================
---
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
(original)
+++
wicket/trunk/wicket-core/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
Sat Jul 9 07:24:18 2011
@@ -33,6 +33,7 @@ import org.apache.wicket.ajax.AjaxReques
import org.apache.wicket.ajax.AjaxRequestTargetListenerCollection;
import org.apache.wicket.markup.MarkupType;
import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.form.AutoLabelResolver;
import org.apache.wicket.markup.html.pages.AccessDeniedPage;
import org.apache.wicket.markup.html.pages.InternalErrorPage;
import org.apache.wicket.markup.html.pages.PageExpiredErrorPage;
@@ -535,6 +536,7 @@ public abstract class WebApplication ext
// Add resolver for automatically resolving HTML links
getPageSettings().addComponentResolver(new AutoLinkResolver());
+ getPageSettings().addComponentResolver(new AutoLabelResolver());
// Set resource finder to web app path
getResourceSettings().setResourceFinder(getResourceFinder());
Added:
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java
URL:
http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java?rev=1144611&view=auto
==============================================================================
---
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java
(added)
+++
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java
Sat Jul 9 07:24:18 2011
@@ -0,0 +1,206 @@
+/*
+ * 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.markup.html.form;
+
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.Page;
+import org.apache.wicket.WicketTestCase;
+import org.apache.wicket.markup.IMarkupCacheKeyProvider;
+import org.apache.wicket.markup.IMarkupResourceStreamProvider;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.util.resource.IResourceStream;
+import org.apache.wicket.util.resource.StringResourceStream;
+
+/**
+ * Tests {@code wicket:for} attribute functionality
+ *
+ * @author igor
+ */
+public class AutoLabelTest extends WicketTestCase
+{
+ public void testLabelIntoMarkupInsertion()
+ {
+ class MyTestPage extends TestPage
+ {
+ public MyTestPage(String labelMarkup)
+ {
+ super("<label wicket:for='t'>" + labelMarkup +
"</label>");
+ field.setLabel(Model.of("t"));
+ }
+ }
+
+ // simple insertion
+ assertRendered(new MyTestPage("<span class='text'>text</span>"),
+ "<span class='text'>t</span>");
+
+
+ // preserves markup before and after
+ assertRendered(new MyTestPage(" <div> a </div> <span
class='text'>text</span> b "),
+ " <div> a </div> <span class='text'>t</span> b ");
+
+
+ // embedded span tags
+ assertRendered(new MyTestPage(" a <div> b <span
class='text'>text</span> c </div> d"),
+ " a <div> b <span class='text'>t</span> c </div> d");
+
+ // double text span tags - only the first one is touched
+ assertRendered(new MyTestPage(
+ "<span class='text'>text</span><span
class='text'>text</span>"),
+ "<span class='text'>t</span><span
class='text'>text</span>");
+
+ // no span - no insertion
+ assertRendered(new MyTestPage(" text "), " text ");
+
+ // empty label tag
+ assertRendered(new MyTestPage(""), "></label>");
+
+ // empty span tag
+ assertRendered(new MyTestPage("<span class='text'></span>"),
"<span class='text'>t</span>");
+
+ // open/close span tag
+ assertRendered(new MyTestPage("<span class='text'/>"), "<span
class='text'>t</span>");
+
+ // test additional classes on the span are preserved
+ assertRendered(new MyTestPage("<span class='foo text bar'/>"),
+ "<span class='foo text bar'>t</span>");
+ }
+
+ public void testMarkupIntoLabelInsertion()
+ {
+ class MyTestPage extends TestPage
+ {
+ public MyTestPage(String labelMarkup)
+ {
+ super("<label wicket:for='t'>" + labelMarkup +
"</label>");
+ }
+ }
+
+ // test form component label is defaulted to the contents of
span class='text'
+
+ MyTestPage page = new MyTestPage("<span
class='text'>text</span>");
+ tester.startPage(page);
+ assertEquals("text",
((MyTestPage)tester.getLastRenderedPage()).field.getLabel()
+ .getObject());
+ }
+
+ public void testLabelTagClasses()
+ {
+ class MyTestPage extends TestPage
+ {
+ public MyTestPage()
+ {
+ super("<label wicket:for='t'><span
class='text'>field</span></label>");
+ }
+ }
+ class MyErrorTestPage extends MyTestPage
+ {
+ @Override
+ protected void onConfigure()
+ {
+ super.onConfigure();
+ field.error("too short");
+ }
+ }
+
+ // test required class
+ TestPage page = new MyTestPage();
+ assertNotRendered(page, "class='required'");
+ page.field.setRequired(true);
+ assertRendered(page, "class='required'");
+
+ // test error class
+ page = new MyTestPage();
+ assertNotRendered(page, "class='error'");
+ page = new MyErrorTestPage();
+ assertRendered(page, "class='error'");
+
+ // test classes are appended and not overridden
+ page = new MyErrorTestPage();
+ page.field.setRequired(true);
+ tester.startPage(page);
+ String markup = tester.getLastResponse().getDocument();
+ assertTrue(markup.contains("class=\"required error\"") ||
+ markup.contains("class=\"error required\""));
+
+ // test existing classes are preserved
+ class MyTestPage2 extends TestPage
+ {
+ public MyTestPage2()
+ {
+ super("<label class='long' wicket:for='t'><span
class='text'>field</span></label>");
+ }
+ }
+
+ MyTestPage2 page2 = new MyTestPage2();
+ page2.field.setRequired(true);
+ tester.startPage(page2);
+ markup = tester.getLastResponse().getDocument();
+ assertTrue(markup.contains("class=\"required long\"") ||
+ markup.contains("class=\"long required\""));
+
+ }
+
+ private void assertRendered(Page page, String markupFragment)
+ {
+ tester.startPage(page);
+ String markup = tester.getLastResponse().getDocument();
+ markup = markup.replace("'", "\"");
+ assertTrue("fragment: [" + markupFragment + "] not found in
generated markup: [" + markup +
+ "]", markup.contains(markupFragment.replace("'",
"\"")));
+ }
+
+ private void assertNotRendered(Page page, String markupFragment)
+ {
+ tester.startPage(page);
+ String markup = tester.getLastResponse().getDocument();
+ markup = markup.replace("'", "\"");
+ assertFalse("fragment: [" + markupFragment + "] not found in
generated markup: [" + markup +
+ "]", markup.contains(markupFragment.replace("'",
"\"")));
+ }
+
+ private static class TestPage extends WebPage
+ implements
+ IMarkupResourceStreamProvider,
+ IMarkupCacheKeyProvider
+ {
+ TextField<String> field;
+
+ private final String labelMarkup;
+
+ public TestPage(String labelMarkup)
+ {
+ this.labelMarkup = labelMarkup;
+ Form<?> form = new Form<Void>("f");
+ add(form);
+ form.add(field = new TextField<String>("t",
Model.of("")));
+ }
+
+ public IResourceStream getMarkupResourceStream(MarkupContainer
container,
+ Class<?> containerClass)
+ {
+ return new StringResourceStream("<html><body><form
wicket:id='f'>\n" + labelMarkup +
+ "\n<input type='text'
wicket:id='t'/>\n</form></body></html>");
+ }
+
+ public String getCacheKey(MarkupContainer container, Class<?>
containerClass)
+ {
+ // no cache
+ return null;
+ }
+ }
+}
\ No newline at end of file
Propchange:
wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/AutoLabelTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain