[ https://issues.apache.org/jira/browse/MYFACES-4430?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Melloware resolved MYFACES-4430. -------------------------------- Resolution: Fixed PR merged > Separate "begin tag" code from "end tag" code for HtmlCheckboxRendererBase > -------------------------------------------------------------------------- > > Key: MYFACES-4430 > URL: https://issues.apache.org/jira/browse/MYFACES-4430 > Project: MyFaces Core > Issue Type: Improvement > Components: General > Affects Versions: 2.3.9 > Reporter: glynn leininiger > Assignee: Melloware > Priority: Major > Fix For: 2.3.10, 2.3-next-M7, 3.0.2 > > > This ticket is very similar to MYFACES-4428, except it applies to > HtmlSelectBooleanCheckbox. > 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.HtmlSelectBooleanCheckbox. > 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.Checkbox"; > private static final String PARENT_RENDERER = > "javax.faces.SelectBoolean"; > 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} > > The problem is HtmlCheckboxRendererBase 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 in HtmlCheckboxRendererBase: > {code:java} > @Override > public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) > throws IOException > { > > org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, > uiComponent, null); > > Map<String, List<ClientBehavior>> behaviors = null; > if (uiComponent instanceof ClientBehaviorHolder) > { > behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors(); > if (!behaviors.isEmpty()) > { > ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, > facesContext.getResponseWriter()); > } > } > > if (uiComponent instanceof UISelectBoolean) > { > Boolean value = > org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanValue( > uiComponent ); > boolean isChecked = value != null ? value.booleanValue() : false; > renderCheckbox(facesContext, uiComponent, EXTERNAL_TRUE_VALUE, > false,isChecked, true, null); > //TODO: the selectBoolean is never disabled > } > else if (uiComponent instanceof UISelectMany) > { > // let the current impl do what it does in encodeEnd do nothing here > just don't want exception > // throw if it is this case > log.finest("encodeBegin() doing nothing intentionally for > UISelectMany"); > } > else > { > throw new IllegalArgumentException("Unsupported component class " > + uiComponent.getClass().getName()); > } > }{code} > and changing encodeEnd() to this following: > {code:keyword} > public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) > throws IOException > { > if (uiComponent instanceof UISelectBoolean) > { > ResponseWriter writer = facesContext.getResponseWriter(); > writer.endElement(HTML.INPUT_ELEM); > } > else if (uiComponent instanceof UISelectMany) > { > renderCheckboxList(facesContext, (UISelectMany) uiComponent); > } > else > { > throw new IllegalArgumentException("Unsupported component class " + > uiComponent.getClass().getName()); > } > }{code} > and add this to the end of renderCheckbox() > {code:java} > if (uiComponent instanceof UISelectMany) > { > writer.endElement(HTML.INPUT_ELEM); > }{code} > These changes split the logic for encode end and begin for renderCheckbox() > and leaves the rendering logic alone for renderCheckboxList(). Encode begin > calls renderCheckbox and encodeEnd writes the end element. Encode begin does > nothing for UISelectMany elements as it is implemented in encodeEnd. > Im open to any feedback on this proposed change. -- This message was sent by Atlassian Jira (v8.20.1#820001)