Jonathan S. Fisher created MYFACES-4428:
-------------------------------------------
Summary: Separate "begin tag" code from "end tag" code in
HtmlTextRendererBase
Key: MYFACES-4428
URL: https://issues.apache.org/jira/browse/MYFACES-4428
Project: MyFaces Core
Issue Type: Improvement
Components: General
Affects Versions: 2.3.9
Reporter: Jonathan S. Fisher
We're trying to implement a few JSF components that extend from the generic JSF
components/renderers. This particular component is extending
javax.faces.component.html.HtmlInputText.
On the renderer side, we're grabbing a handle to the default renderer of the
component:
{code:java}
private static final String PARENT_FAMILY = "javax.faces.Input";
private static final String PARENT_RENDERER = "javax.faces.Text";
static final Renderer getWrappedRenderer(FacesContext context) {
Renderer baseRenderer =
context.getRenderKit().getRenderer(PARENT_FAMILY, PARENT_RENDERER);
return baseRenderer;
}{code}
Then we're going to attempt to write out some new CSS classes for the component
and leave the rest of everything alone:
{code:java}
@Override
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException {
Renderer baseRenderer = getWrappedRenderer(context);
baseRenderer.encodeBegin(context, component);
XXFaces.writeClasses(context, null, SF_FORM_CONTROL,
BS_FORM_CONTROL);
}
@Override
public void encodeEnd(FacesContext context, UIComponent component)
throws IOException {
Renderer baseRenderer = getWrappedRenderer(context);
baseRenderer.encodeEnd(context, component);
} {code}
This unfortuantely presents a problem. HtmlTextRendererBase does not have an
encodeBegin() method, instead it does all of the "Start tag" encoding in the
encodeEnd() method. This makes it impossible to create custom components that
wrap the functionality of the default render kit without extending myfaces
renderers and breaks any chance cross-platform components.
I propose adding this method to HtmlTextRendererBase:
{code:java}
@Override
public void encodeBegin(FacesContext context, UIComponent component) throws
IOException {
if (component instanceof UIInput) {
renderInputBegin(context, component);
}
} {code}
and changing encodeEnd() to this following:
{code:java}
public void encodeEnd(FacesContext facesContext, UIComponent component)
throws IOException
{
org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext,component,null);
Map<String, List<ClientBehavior>> behaviors = null;
if (component instanceof ClientBehaviorHolder)
{
behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
if (!behaviors.isEmpty())
{
ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext,
facesContext.getResponseWriter());
}
}
if (component instanceof UIInput)
{
renderInputEnd(facesContext, component);
}
else if (component instanceof UIOutput)
{
renderOutput(facesContext, component);
}
else
{
throw new IllegalArgumentException("Unsupported component class " +
component.getClass().getName());
}
} {code}
This changes this section of encodeEnd()
{code:java}
if (component instanceof UIInput)
{
renderInput(facesContext, component);
}{code}
And removes the renderInput() method which just calls renderInputBegin()
followed by renderInputEnd() anyway.
I'm open to ideas an improvements. And one more note, open source work often
goes unthanked, and I would like to express my gratitude for your work and
passion on the MyFaces project at the ASF.
--
This message was sent by Atlassian Jira
(v8.20.1#820001)