[
https://issues.apache.org/jira/browse/MYFACES-1897?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12619915#action_12619915
]
Paul Rivera commented on MYFACES-1897:
--------------------------------------
Hi!
I've attached myfaces-1897.patch that fixes your problem. Here are the details
of the fix:
I) I've modified HtmlRenderUtils.renderLabel to accept the SelectItem
parameter. This way, we are passing less parameters and we can get both
labelValue and escape values plus any other SelectItem attribute we might need
to use inside renderLabel() in the future.
public static void renderLabel(ResponseWriter writer,
UIComponent component,
String forClientId,
- String labelValue,
+ SelectItem item,
boolean disabled) throws IOException
I also modified the part where escape gets evaluated (almost identical to the
fix suggested in the first post):
- if ((labelValue != null) && (labelValue.length() > 0))
+ if ((item.getLabel() != null) && (item.getLabel().length() > 0))
{
writer.write(HTML.NBSP_ENTITY);
- writer.writeText(labelValue, null);
+
+ if(item.isEscape())
+ {
+ writer.writeText(item.getLabel(), null);
+ }
+ else
+ {
+ writer.write(item.getLabel());
+ }
}
Now, this fix is enough if you are creating your SelectItem objects with its
constructor. I.e.:
new SelectItem("1","<b>Escaped</b>","choose_one",false,true)
But if you make it using its tag:
<f:selectItem itemLabel="<b>Escaped</b>" itemValue="choose_one" escape="true" />
The tag above will be treated as if escape="false". There is a problem with
SelectItemTagBase.setProperties(). SelectItemTagBase sets the property of your
UISelectItem using UISelectItem.setEscape(). But UISelectItem doesn't have
setEscape(). It has setItemEscaped(). Note that UISelectItem.getItemEscaped()
returns false by default. Since setItemEscaped() is never called, it will
always return false.
Root cause of this is because in your SelectItemTagBase.setProperties(), this
gets called:
setBooleanProperty(component, JSFAttr.ESCAPE_ATTR, _escape, Boolean.TRUE);
The value of JSFAttr.ESCAPE_ATTR is 'escape'. If you dig deep into this
method, you will notice that it will look for UISelectItem.setEscape() in
_ComponentAttributes.put(). Again, UISelectItem does not have a setEscape(),
it uses setItemEscaped(). In _ComponentAttributes.put() L299,
propertyDescriptor will be null and the value gets added to _attributes instead
of calling setComponentProperty().
To fix this, either:
A) change JSFAttr.ESCAPE_ATTR from 'escape' to 'itemEscaped'
CONS: ESCAPE_ATTR is being used by a lot of other classes which expect the
value 'escape'.
B) change UISelectItem's method from isItemEscaped()/setItemEscaped() to
isEscape()/setEscape()
CONS: Breaks API for JSF 1.2.
C) Add a new JSFAttr.ITEM_ESCAPED_ATTR with the value 'itemEscaped'
Option C was for me the most logical one. So I've updated
SelectItemTagBase.setProperties():
- setBooleanProperty(component, JSFAttr.ESCAPE_ATTR, _escape,
Boolean.TRUE);
+ setBooleanProperty(component, JSFAttr.ITEM_ESCAPED_ATTR, _escape,
Boolean.TRUE);
II) I've updated both HtmlCheckboxRendererBase and HtmlRadioRendererBase that
makes calls to HtmlRenderUtils.renderLabel().
III) To fix selectOneMenu, selectManyMenu, selectOneListbox, and
selectManyListbox, I've modified
HtmlRendererUtils.renderSelectOptions():
- boolean escape;
- if (component instanceof EscapeCapable)
+ if(selectItem.isEscape())
{
- escape = ((EscapeCapable)component).isEscape();
- }
- else
- {
- escape = RendererUtils.getBooleanAttribute(component,
JSFAttr.ESCAPE_ATTR,
- true);
//default is to escape
- }
-
- if (escape || selectItem.isEscape())
- {
writer.writeText(selectItem.getLabel(), null);
} else
{
The original code checks for isEscape() in the component parameter which is can
be an HtmlSelectOneMenu, HtmlSelectOneListbox, HtmlSelectManyMenu,
HtmlSelectManyListbox -> all of which don't have an 'escape' attribute defined
in the TLD. In the JSF 1.2 RI, these components don't have the escape
attribute as well.
So I removed the checking for isEscape() from the component and focused on the
isEscape() of the SelectItem instead.
> escape value of a selectItem is never evaluated
> -----------------------------------------------
>
> Key: MYFACES-1897
> URL: https://issues.apache.org/jira/browse/MYFACES-1897
> Project: MyFaces Core
> Issue Type: Bug
> Components: JSR-252
> Affects Versions: 1.2.3
> Reporter: Jörg Rothbarth
> Assignee: Leonardo Uribe
> Attachments: myfaces-1897.patch, SelectItemEscapeBean.java,
> selectOneManyEscape.jsp
>
>
> The escape Attribute of a selectItem Component is not evaluated inside a
> selectOneRadio component.
> The selectItem Component has a escape member, but the member is never used.
> To fix the problem i've done this:
> HtmlRadioRendererBase.renderGroupOrItemRadio() Line ~199 :
> // label element after the input
> boolean componentDisabled = isDisabled(facesContext, selectOne);
> boolean disabled = (componentDisabled || itemDisabled);
> boolean escape = selectItem.isEscape();
> HtmlRendererUtils.renderLabel(writer, selectOne, itemId,
> selectItem.getLabel(), disabled,escape);
> HtmlRendererUtils.renderLabel() Line ~1352:
> public static void renderLabel(ResponseWriter writer, UIComponent
> component, String forClientId,String labelValue, boolean
> disabled) throws IOException {
> renderLabel(writer, component, forClientId, labelValue, disabled, true);
> }
> /**
> * Renders a label HTML element
> */
> public static void renderLabel(ResponseWriter writer, UIComponent
> component, String forClientId,String labelValue, boolean
> disabled, boolean escape) throws IOException {
> ...
> if ((labelValue != null) && (labelValue.length() > 0)) {
> writer.write(HTML.NBSP_ENTITY);
> if (escape) {
> writer.writeText(labelValue, null);
> } else {
> writer.write(labelValue);
> }
> }
> ...
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.