[ 
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.

Reply via email to