Coverage Report - org.apache.myfaces.shared.renderkit.html.HtmlButtonRendererBase
 
Classes in this File Line Coverage Branch Coverage Complexity
HtmlButtonRendererBase
0%
0/212
0%
0/162
5.882
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *   http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.myfaces.shared.renderkit.html;
 20  
 
 21  
 import java.io.IOException;
 22  
 import java.util.Collection;
 23  
 import java.util.Collections;
 24  
 import java.util.List;
 25  
 import java.util.Map;
 26  
 
 27  
 import javax.faces.component.UICommand;
 28  
 import javax.faces.component.UIComponent;
 29  
 import javax.faces.component.UIParameter;
 30  
 import javax.faces.component.ValueHolder;
 31  
 import javax.faces.component.behavior.ClientBehavior;
 32  
 import javax.faces.component.behavior.ClientBehaviorContext;
 33  
 import javax.faces.component.behavior.ClientBehaviorHolder;
 34  
 import javax.faces.component.html.HtmlCommandButton;
 35  
 import javax.faces.component.html.HtmlCommandLink;
 36  
 import javax.faces.context.FacesContext;
 37  
 import javax.faces.context.ResponseWriter;
 38  
 import javax.faces.event.ActionEvent;
 39  
 
 40  
 import org.apache.myfaces.shared.config.MyfacesConfig;
 41  
 import org.apache.myfaces.shared.renderkit.ClientBehaviorEvents;
 42  
 import org.apache.myfaces.shared.renderkit.JSFAttr;
 43  
 import org.apache.myfaces.shared.renderkit.RendererUtils;
 44  
 import org.apache.myfaces.shared.renderkit.html.util.FormInfo;
 45  
 import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
 46  
 import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
 47  
 import org.apache.myfaces.shared.util._ComponentUtils;
 48  
 
 49  0
 public class HtmlButtonRendererBase
 50  
     extends HtmlRenderer
 51  
 {
 52  
     private static final String IMAGE_BUTTON_SUFFIX_X = ".x";
 53  
     private static final String IMAGE_BUTTON_SUFFIX_Y = ".y";
 54  
 
 55  
     public static final String ACTION_FOR_LIST = "org.apache.myfaces.ActionForList";
 56  
 
 57  
     public void decode(FacesContext facesContext, UIComponent uiComponent)
 58  
     {
 59  0
         org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(
 60  
                 facesContext, uiComponent, UICommand.class);
 61  
 
 62  
         //super.decode must not be called, because value is handled here
 63  0
         boolean disabled = isDisabled(facesContext, uiComponent);
 64  
         // MYFACES-3960 Decode, decode client behavior and queue action event at the end
 65  0
         boolean activateActionEvent = !isReset(uiComponent) && isSubmitted(facesContext, uiComponent) &&
 66  
             !disabled;
 67  0
         if (activateActionEvent)
 68  
         {
 69  0
             org.apache.myfaces.shared.renderkit.RendererUtils.initPartialValidationAndModelUpdate(
 70  
                     uiComponent, facesContext);
 71  
         }
 72  
         
 73  0
         if (uiComponent instanceof ClientBehaviorHolder &&
 74  
                 !disabled)
 75  
         {
 76  0
             HtmlRendererUtils.decodeClientBehaviors(facesContext, uiComponent);
 77  
         }
 78  
         
 79  0
         if (activateActionEvent)
 80  
         {
 81  0
             uiComponent.queueEvent(new ActionEvent(uiComponent));
 82  
         }
 83  0
     }
 84  
 
 85  
     private static boolean isReset(UIComponent uiComponent)
 86  
     {
 87  0
         return "reset".equals((String) uiComponent.getAttributes().get(HTML.TYPE_ATTR));
 88  
     }
 89  
     
 90  
     private static boolean isButton(UIComponent uiComponent)
 91  
     {
 92  0
         return "button".equals((String) uiComponent.getAttributes().get(HTML.TYPE_ATTR));
 93  
     }
 94  
 
 95  
     private static boolean isSubmitted(FacesContext facesContext, UIComponent uiComponent)
 96  
     {
 97  0
         String clientId = uiComponent.getClientId(facesContext);
 98  0
         Map paramMap = facesContext.getExternalContext().getRequestParameterMap();
 99  0
         FormInfo formInfo = _ComponentUtils.findNestingForm(uiComponent, facesContext);
 100  0
         String hiddenLink = null;
 101  
          
 102  0
         if (formInfo != null)
 103  
         {
 104  0
             hiddenLink = (String) facesContext.getExternalContext().getRequestParameterMap().get(
 105  
                 HtmlRendererUtils.getHiddenCommandLinkFieldName(formInfo, facesContext));
 106  
         }
 107  0
         return paramMap.containsKey(clientId) || paramMap.containsKey(clientId + IMAGE_BUTTON_SUFFIX_X) 
 108  
             || paramMap.containsKey(clientId + IMAGE_BUTTON_SUFFIX_Y)
 109  
             || (hiddenLink != null && hiddenLink.equals (clientId))
 110  
             || HtmlRendererUtils.isPartialOrBehaviorSubmit(facesContext, clientId);
 111  
     }
 112  
 
 113  
     @Override
 114  
     public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
 115  
     {
 116  0
         org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(
 117  
                 facesContext, uiComponent, UICommand.class);
 118  
 
 119  0
         String clientId = uiComponent.getClientId(facesContext);
 120  
 
 121  0
         ResponseWriter writer = facesContext.getResponseWriter();
 122  
         
 123  
         // commandButton does not need to be nested in a form since JSF 2.0
 124  0
         FormInfo formInfo = findNestingForm(uiComponent, facesContext);
 125  
 
 126  0
         boolean reset = isReset(uiComponent);
 127  0
         boolean button = isButton(uiComponent);
 128  
 
 129  0
         Map<String, List<ClientBehavior>> behaviors = null;
 130  0
         if (uiComponent instanceof ClientBehaviorHolder)
 131  
         {
 132  0
             behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
 133  0
             if (!behaviors.isEmpty())
 134  
             {
 135  0
                 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, writer);
 136  
             }
 137  
         }
 138  
         
 139  
         // If we are nested in a form, and we have javascript enabled, and autoscroll is enabled, 
 140  
         // we should write the form submit script
 141  
         // (define oamSetHiddenInput, oamClearHiddenInput, oamSubmitForm)
 142  
         // because oamSetHiddenInput is called on onclick function
 143  0
         List<UIComponent> childrenList = null;
 144  0
         if (getChildCount(uiComponent) > 0)
 145  
         {
 146  0
             childrenList = getChildren(uiComponent);
 147  
         }
 148  
         else
 149  
         {
 150  0
            childrenList = Collections.emptyList();
 151  
         }
 152  0
         List<UIParameter> validParams = HtmlRendererUtils.getValidUIParameterChildren(
 153  
                 facesContext, childrenList, false, false);
 154  
         
 155  0
         if (formInfo != null 
 156  
                 && (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoScroll() ||
 157  
                         (validParams != null && !validParams.isEmpty() )))
 158  
         {        
 159  0
             HtmlRendererUtils.renderFormSubmitScript(facesContext);
 160  
         }
 161  
         
 162  0
         String commandOnclick = (String)uiComponent.getAttributes().get(HTML.ONCLICK_ATTR);
 163  
         
 164  0
         if (commandOnclick != null && (validParams != null && !validParams.isEmpty() ) )
 165  
         {
 166  0
             ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, writer);
 167  
         }
 168  
 
 169  0
         writer.startElement(HTML.INPUT_ELEM, uiComponent);
 170  
 
 171  0
         writer.writeAttribute(HTML.ID_ATTR, clientId, org.apache.myfaces.shared.renderkit.JSFAttr.ID_ATTR);
 172  0
         writer.writeAttribute(HTML.NAME_ATTR, clientId, JSFAttr.ID_ATTR);
 173  
 
 174  0
         String image = RendererUtils.getIconSrc(facesContext, uiComponent, JSFAttr.IMAGE_ATTR);
 175  0
         if (image != null)
 176  
         {
 177  0
             writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_IMAGE, 
 178  
                     org.apache.myfaces.shared.renderkit.JSFAttr.TYPE_ATTR);
 179  0
             writer.writeURIAttribute(HTML.SRC_ATTR, image, org.apache.myfaces.shared.renderkit.JSFAttr.IMAGE_ATTR);
 180  
         }
 181  
         else
 182  
         {
 183  0
             String type = getType(uiComponent);
 184  
 
 185  0
             if (type == null || (!reset && !button))
 186  
             {
 187  0
                 type = HTML.INPUT_TYPE_SUBMIT;
 188  
             }
 189  0
             writer.writeAttribute(HTML.TYPE_ATTR, type, org.apache.myfaces.shared.renderkit.JSFAttr.TYPE_ATTR);
 190  0
             Object value = getValue(uiComponent);
 191  0
             if (value != null)
 192  
             {
 193  0
                 writer.writeAttribute(org.apache.myfaces.shared.renderkit.html.HTML.VALUE_ATTR, value, 
 194  
                         org.apache.myfaces.shared.renderkit.JSFAttr.VALUE_ATTR);
 195  
             }
 196  
         }
 197  
         
 198  0
         if ((HtmlRendererUtils.hasClientBehavior(ClientBehaviorEvents.CLICK, behaviors, facesContext) ||
 199  
              HtmlRendererUtils.hasClientBehavior(ClientBehaviorEvents.ACTION, behaviors, facesContext)))
 200  
         {
 201  0
             if (!reset && !button)
 202  
             {
 203  0
                 String onClick = buildBehaviorizedOnClick(
 204  
                         uiComponent, behaviors, facesContext, writer, formInfo, validParams);
 205  0
                 if (onClick.length() != 0)
 206  
                 {
 207  0
                     writer.writeAttribute(HTML.ONCLICK_ATTR, onClick, null);
 208  
                 }
 209  0
             }
 210  
             else
 211  
             {
 212  0
                 Collection<ClientBehaviorContext.Parameter> paramList = 
 213  
                     HtmlRendererUtils.getClientBehaviorContextParameters(
 214  
                         HtmlRendererUtils.mapAttachedParamsToStringValues(facesContext, uiComponent));
 215  
                     
 216  0
                 String onClick = HtmlRendererUtils.buildBehaviorChain(facesContext, uiComponent,
 217  
                         ClientBehaviorEvents.CLICK, paramList, ClientBehaviorEvents.ACTION, paramList, behaviors,
 218  
                         commandOnclick , null);
 219  0
                 if (onClick.length() != 0)
 220  
                 {
 221  0
                     writer.writeAttribute(HTML.ONCLICK_ATTR, onClick, null);
 222  
                 }
 223  
             }
 224  
             
 225  0
             Map<String, Object> attributes = uiComponent.getAttributes(); 
 226  
             
 227  0
             HtmlRendererUtils.buildBehaviorChain(
 228  
                     facesContext, uiComponent, ClientBehaviorEvents.DBLCLICK, null, behaviors,   
 229  
                         (String) attributes.get(HTML.ONDBLCLICK_ATTR), "");
 230  0
         }
 231  
         else
 232  
         {
 233  
             //fallback into the pre 2.0 code to keep backwards compatibility with libraries which rely on internals
 234  0
             if (!reset && !button)
 235  
             {
 236  0
                 StringBuilder onClick = buildOnClick(uiComponent, facesContext, writer, validParams);
 237  0
                 if (onClick.length() != 0)
 238  
                 {
 239  0
                     writer.writeAttribute(HTML.ONCLICK_ATTR, onClick.toString(), null);
 240  
                 }
 241  0
             }
 242  
             else
 243  
             {
 244  0
                 HtmlRendererUtils.renderHTMLStringAttribute(writer, uiComponent, HTML.ONCLICK_ATTR, HTML.ONCLICK_ATTR);
 245  
             }
 246  
         }
 247  
         
 248  
         //if (javascriptAllowed)
 249  
         //{
 250  0
             if (isCommonPropertiesOptimizationEnabled(facesContext))
 251  
             {
 252  0
                 CommonPropertyUtils.renderButtonPassthroughPropertiesWithoutDisabledAndEvents(writer, 
 253  
                         CommonPropertyUtils.getCommonPropertiesMarked(uiComponent), uiComponent);
 254  
             }
 255  
             else
 256  
             {
 257  0
                 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
 258  
                                                        HTML.BUTTON_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
 259  
             }
 260  
         //}
 261  
 
 262  0
         if (behaviors != null && !behaviors.isEmpty())
 263  
         {
 264  0
             HtmlRendererUtils.renderBehaviorizedEventHandlersWithoutOnclick(
 265  
                     facesContext, writer, uiComponent, behaviors);
 266  0
             HtmlRendererUtils.renderBehaviorizedFieldEventHandlers(facesContext, writer, uiComponent, behaviors);
 267  
         }
 268  
         else
 269  
         {
 270  0
             if (isCommonPropertiesOptimizationEnabled(facesContext))
 271  
             {
 272  0
                 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
 273  0
                 CommonPropertyUtils.renderEventPropertiesWithoutOnclick(writer, commonPropertiesMarked, uiComponent);
 274  0
                 CommonPropertyUtils.renderCommonFieldEventProperties(writer, commonPropertiesMarked, uiComponent);
 275  0
             }
 276  
             else
 277  
             {
 278  0
                 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
 279  
                         HTML.EVENT_HANDLER_ATTRIBUTES_WITHOUT_ONCLICK);
 280  0
                 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
 281  
                         HTML.COMMON_FIELD_EVENT_ATTRIBUTES);
 282  
             }
 283  
         }
 284  
 
 285  0
         if (isDisabled(facesContext, uiComponent))
 286  
         {
 287  0
             writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, 
 288  
                     org.apache.myfaces.shared.renderkit.JSFAttr.DISABLED_ATTR);
 289  
         }
 290  
         
 291  0
         if (isReadonly(facesContext, uiComponent))
 292  
         {
 293  0
             writer.writeAttribute(HTML.READONLY_ATTR, Boolean.TRUE, 
 294  
                     org.apache.myfaces.shared.renderkit.JSFAttr.READONLY_ATTR);
 295  
         }
 296  0
     }
 297  
     
 298  
     public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
 299  
             throws IOException
 300  
     {
 301  0
         ResponseWriter writer = facesContext.getResponseWriter();
 302  
 
 303  0
         writer.endElement(HTML.INPUT_ELEM);
 304  
         
 305  0
         FormInfo formInfo = findNestingForm(uiComponent, facesContext);
 306  0
         if (formInfo != null)
 307  
         {
 308  0
             HtmlFormRendererBase.renderScrollHiddenInputIfNecessary(
 309  
                     formInfo.getForm(), facesContext, writer);
 310  
         }
 311  
         
 312  
         // render the UIParameter children of the commandButton (since 2.0)
 313  
         /*
 314  
         List<UIParameter> validParams = HtmlRendererUtils.getValidUIParameterChildren(
 315  
                 facesContext, uiComponent.getChildren(), false, false);
 316  
         for (UIParameter param : validParams)
 317  
         {
 318  
             HtmlInputHidden parameterComponent = new HtmlInputHidden();
 319  
             parameterComponent.setId(param.getName());
 320  
             parameterComponent.setValue(param.getValue());
 321  
             parameterComponent.encodeAll(facesContext);
 322  
         }*/
 323  0
     }
 324  
 
 325  
     protected String buildBehaviorizedOnClick(UIComponent uiComponent, Map<String, List<ClientBehavior>> behaviors, 
 326  
                                               FacesContext facesContext, ResponseWriter writer, 
 327  
                                               FormInfo nestedFormInfo, List<UIParameter> validParams)
 328  
         throws IOException
 329  
     {
 330  
         //we can omit autoscroll here for now maybe we should check if it is an ajax 
 331  
         //behavior and omit it only in this case
 332  0
         StringBuilder userOnClick = new StringBuilder();
 333  
         //user onclick part 
 334  0
         String commandOnClick = (String) uiComponent.getAttributes().get(HTML.ONCLICK_ATTR);
 335  
 
 336  0
         if (commandOnClick != null)
 337  
         {
 338  0
             userOnClick.append(commandOnClick);
 339  0
             userOnClick.append(';');
 340  
         }
 341  
 
 342  0
         StringBuilder rendererOnClick = new StringBuilder();
 343  
 
 344  0
         if (nestedFormInfo != null) 
 345  
         {
 346  
             // There is no clean way to detect if a "submit" behavior has been added to the component, 
 347  
             // so to keep things simple, if the button is submit type, it is responsibility of the 
 348  
             // developer to add a client behavior that submit the form, for example using a f:ajax tag.
 349  
             // Otherwise, there will be a situation where a full submit could be trigger after an ajax
 350  
             // operation. Note we still need to append two scripts if necessary: autoscroll and clear
 351  
             // hidden fields, because this code is called for a submit button.
 352  
             //if (behaviors.isEmpty() && validParams != null && !validParams.isEmpty() )
 353  
             //{
 354  
             //    rendererOnClick.append(buildServerOnclick(facesContext, uiComponent, 
 355  
             //            uiComponent.getClientId(facesContext), nestedFormInfo, validParams));
 356  
             //}
 357  
             //else
 358  
             //{
 359  0
                 String formName = nestedFormInfo.getFormName();
 360  0
                 if (JavascriptUtils.isRenderClearJavascriptOnButton(facesContext.getExternalContext()))
 361  
                 {
 362  
                     //call the script to clear the form (clearFormHiddenParams_<formName>) method
 363  0
                     HtmlRendererUtils.appendClearHiddenCommandFormParamsFunctionCall(rendererOnClick, formName);
 364  
                 }
 365  
         
 366  0
                 if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoScroll())
 367  
                 {
 368  0
                     HtmlRendererUtils.appendAutoScrollAssignment(rendererOnClick, formName);
 369  
                 }
 370  
             //}
 371  
         }
 372  
 
 373  
         //according to the specification in jsf.util.chain jdocs and the spec document we have to use
 374  
         //jsf.util.chain to chain the functions and
 375  0
         Collection<ClientBehaviorContext.Parameter> paramList = HtmlRendererUtils.getClientBehaviorContextParameters(
 376  
                 HtmlRendererUtils.mapAttachedParamsToStringValues(facesContext, uiComponent));
 377  
         
 378  0
         return HtmlRendererUtils.buildBehaviorChain(facesContext, uiComponent,
 379  
                 ClientBehaviorEvents.CLICK, paramList, ClientBehaviorEvents.ACTION, paramList, behaviors,
 380  
                 userOnClick.toString() , rendererOnClick.toString());
 381  
     }
 382  
     
 383  
     protected String buildServerOnclick(FacesContext facesContext, UIComponent component, 
 384  
             String clientId, FormInfo formInfo, List<UIParameter> validParams) throws IOException
 385  
     {
 386  0
         UIComponent nestingForm = formInfo.getForm();
 387  0
         String formName = formInfo.getFormName();
 388  
 
 389  0
         StringBuilder onClick = new StringBuilder();
 390  
 
 391  0
         if (RendererUtils.isAdfOrTrinidadForm(formInfo.getForm()))
 392  
         {
 393  0
             onClick.append("submitForm('");
 394  0
             onClick.append(formInfo.getForm().getClientId(facesContext));
 395  0
             onClick.append("',1,{source:'");
 396  0
             onClick.append(component.getClientId(facesContext));
 397  0
             onClick.append("'});return false;");
 398  
         }
 399  
         else
 400  
         {
 401  0
             StringBuilder params = addChildParameters(facesContext, nestingForm, validParams);
 402  
 
 403  0
             String target = getTarget(component);
 404  
 
 405  0
             onClick.append("return ").
 406  
                 append(HtmlRendererUtils.SUBMIT_FORM_FN_NAME_JSF2).append("('").
 407  
                 append(formName).append("','").
 408  
                 append(component.getClientId(facesContext)).append("'");
 409  
 
 410  0
             if (params.length() > 2 || target != null)
 411  
             {
 412  0
                 onClick.append(",").
 413  
                     append(target == null ? "null" : ("'" + target + "'")).append(",").
 414  
                     append(params);
 415  
             }
 416  0
             onClick.append(");");
 417  
 
 418  
             //Not necessary since we are using oamSetHiddenInput to create input hidden fields
 419  
             //render hidden field - todo: in here for backwards compatibility
 420  
             //String hiddenFieldName = HtmlRendererUtils.getHiddenCommandLinkFieldName(formInfo);
 421  
             //addHiddenCommandParameter(facesContext, nestingForm, hiddenFieldName);
 422  
 
 423  
         }
 424  0
         return onClick.toString();
 425  
     }
 426  
     
 427  
     private StringBuilder addChildParameters(FacesContext context, 
 428  
             UIComponent nestingForm, List<UIParameter> validParams)
 429  
     {
 430  
         //add child parameters
 431  0
         StringBuilder params = new StringBuilder();
 432  0
         params.append("[");
 433  
         
 434  0
         for (UIParameter param : validParams) 
 435  
         {
 436  0
             String name = param.getName();
 437  
 
 438  
             //Not necessary, since we are using oamSetHiddenInput to create hidden fields
 439  0
             if (MyfacesConfig.getCurrentInstance(context.getExternalContext()).isRenderHiddenFieldsForLinkParams())
 440  
             {
 441  0
                 addHiddenCommandParameter(context, nestingForm, name);
 442  
             }
 443  
 
 444  0
             Object value = param.getValue();
 445  
 
 446  
             //UIParameter is no ValueHolder, so no conversion possible - calling .toString on value....
 447  
             // MYFACES-1832 bad charset encoding for f:param
 448  
             // if HTMLEncoder.encode is called, then
 449  
             // when is called on writer.writeAttribute, encode method
 450  
             // is called again so we have a duplicated encode call.
 451  
             // MYFACES-2726 All '\' and "'" chars must be escaped 
 452  
             // because there will be inside "'" javascript quotes, 
 453  
             // otherwise the value will not correctly restored when
 454  
             // the command is post.
 455  
             //String strParamValue = value != null ? value.toString() : "";
 456  0
             String strParamValue = "";
 457  0
             if (value != null)
 458  
             {
 459  0
                 strParamValue = value.toString();
 460  0
                 StringBuilder buff = null;
 461  0
                 for (int i = 0; i < strParamValue.length(); i++)
 462  
                 {
 463  0
                     char c = strParamValue.charAt(i); 
 464  0
                     if (c == '\'' || c == '\\')
 465  
                     {
 466  0
                         if (buff == null)
 467  
                         {
 468  0
                             buff = new StringBuilder();
 469  0
                             buff.append(strParamValue.substring(0,i));
 470  
                         }
 471  0
                         buff.append('\\');
 472  0
                         buff.append(c);
 473  
                     }
 474  0
                     else if (buff != null)
 475  
                     {
 476  0
                         buff.append(c);
 477  
                     }
 478  
                 }
 479  0
                 if (buff != null)
 480  
                 {
 481  0
                     strParamValue = buff.toString();
 482  
                 }
 483  
             }
 484  
 
 485  0
             if (params.length() > 1) 
 486  
             {
 487  0
                 params.append(",");
 488  
             }
 489  
 
 490  0
             params.append("['");
 491  0
             params.append(name);
 492  0
             params.append("','");
 493  0
             params.append(strParamValue);
 494  0
             params.append("']");
 495  0
         }
 496  0
         params.append("]");
 497  0
         return params;
 498  
     }
 499  
 
 500  
     private String getTarget(UIComponent component)
 501  
     {
 502  
         // for performance reason: double check for the target attribute
 503  
         String target;
 504  0
         if (component instanceof HtmlCommandLink)
 505  
         {
 506  0
             target = ((HtmlCommandLink) component).getTarget();
 507  
         }
 508  
         else
 509  
         {
 510  0
             target = (String) component.getAttributes().get(HTML.TARGET_ATTR);
 511  
         }
 512  0
         return target;
 513  
     }
 514  
 
 515  
     protected StringBuilder buildOnClick(UIComponent uiComponent, FacesContext facesContext,
 516  
                                         ResponseWriter writer, List<UIParameter> validParams)
 517  
         throws IOException
 518  
     {
 519  
         /* DUMMY STUFF
 520  
         //Find form
 521  
         UIComponent parent = uiComponent.getParent();
 522  
         while (parent != null && !(parent instanceof UIForm))
 523  
         {
 524  
             parent = parent.getParent();
 525  
         }
 526  
 
 527  
         UIForm nestingForm = null;
 528  
         String formName;
 529  
 
 530  
         if (parent != null)
 531  
         {
 532  
             //link is nested inside a form
 533  
             nestingForm = (UIForm)parent;
 534  
             formName = nestingForm.getClientId(facesContext);
 535  
 
 536  
         }
 537  
         else
 538  
         {
 539  
             //not nested in form, we must add a dummy form at the end of the document
 540  
             formName = DummyFormUtils.DUMMY_FORM_NAME;
 541  
             //dummyFormResponseWriter = DummyFormUtils.getDummyFormResponseWriter(facesContext);
 542  
             //dummyFormResponseWriter.setWriteDummyForm(true);
 543  
             DummyFormUtils.setWriteDummyForm(facesContext, true);
 544  
         }
 545  
         */
 546  0
         StringBuilder onClick = new StringBuilder();
 547  0
         String commandOnClick = (String) uiComponent.getAttributes().get(HTML.ONCLICK_ATTR);
 548  
 
 549  0
         if (commandOnClick != null)
 550  
         {
 551  0
             onClick.append("var cf = function(){");
 552  0
             onClick.append(commandOnClick);
 553  0
             onClick.append('}');
 554  0
             onClick.append(';');
 555  0
             onClick.append("var oamSF = function(){");
 556  
         }
 557  
         
 558  0
         FormInfo nestedFormInfo = findNestingForm(uiComponent, facesContext);
 559  
         
 560  0
         if (nestedFormInfo != null)
 561  
         {
 562  0
             String formName = nestedFormInfo.getFormName();
 563  
             
 564  0
             if (validParams != null && !validParams.isEmpty() )
 565  
             {
 566  0
                 StringBuilder params = addChildParameters(
 567  
                         facesContext, nestedFormInfo.getForm(), validParams);
 568  
 
 569  0
                 String target = getTarget(uiComponent);
 570  
 
 571  0
                 onClick.append("return ").
 572  
                     append(HtmlRendererUtils.SUBMIT_FORM_FN_NAME_JSF2).append("('").
 573  
                     append(formName).append("','").
 574  
                     append(uiComponent.getClientId(facesContext)).append("'");
 575  
 
 576  0
                 if (params.length() > 2 || target != null)
 577  
                 {
 578  0
                     onClick.append(",").
 579  
                         append(target == null ? "null" : ("'" + target + "'")).append(",").
 580  
                         append(params);
 581  
                 }
 582  0
                 onClick.append(");");
 583  
 
 584  
                 //Not necessary since we are using oamSetHiddenInput to create input hidden fields
 585  
                 //render hidden field - todo: in here for backwards compatibility
 586  0
                 if (MyfacesConfig.getCurrentInstance(
 587  
                         facesContext.getExternalContext()).isRenderHiddenFieldsForLinkParams())
 588  
                 {
 589  0
                     String hiddenFieldName = HtmlRendererUtils.getHiddenCommandLinkFieldName(
 590  
                             nestedFormInfo, facesContext);
 591  0
                     addHiddenCommandParameter(facesContext, nestedFormInfo.getForm(), hiddenFieldName);
 592  
                 }
 593  0
             }
 594  
             else
 595  
             {
 596  
         
 597  0
                 if (JavascriptUtils.isRenderClearJavascriptOnButton(facesContext.getExternalContext()) ||
 598  
                         MyfacesConfig.getCurrentInstance(
 599  
                                 facesContext.getExternalContext()).isRenderHiddenFieldsForLinkParams() )
 600  
                 {
 601  
                     //call the script to clear the form (clearFormHiddenParams_<formName>) method
 602  0
                     HtmlRendererUtils.appendClearHiddenCommandFormParamsFunctionCall(onClick, formName);
 603  
                 }
 604  
         
 605  0
                 if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoScroll())
 606  
                 {
 607  0
                     HtmlRendererUtils.appendAutoScrollAssignment(onClick, formName);
 608  
                 }
 609  
             }
 610  
         }
 611  
         
 612  0
         if (commandOnClick != null)
 613  
         {
 614  0
             onClick.append('}');
 615  0
             onClick.append(';');
 616  0
             onClick.append("return (cf.apply(this, [])==false)? false : oamSF.apply(this, []); ");
 617  
         }  
 618  
 
 619  
         //The hidden field has only sense if isRenderClearJavascriptOnButton is
 620  
         //set to true. In other case, this hidden field should not be rendered.
 621  
         //if (JavascriptUtils.isRenderClearJavascriptOnButton(facesContext.getExternalContext()))
 622  
         //{
 623  
             //add hidden field for the case there is no commandLink in the form
 624  
             //String hiddenFieldName = HtmlRendererUtils.getHiddenCommandLinkFieldName(formInfo);
 625  
             //addHiddenCommandParameter(facesContext, nestingForm, hiddenFieldName);
 626  
         //}
 627  
 
 628  0
         return onClick;
 629  
     }
 630  
 
 631  
     protected void addHiddenCommandParameter(FacesContext facesContext, 
 632  
             UIComponent nestingForm, String hiddenFieldName)
 633  
     {
 634  0
         if (nestingForm != null)
 635  
         {
 636  0
             HtmlFormRendererBase.addHiddenCommandParameter(facesContext, nestingForm, hiddenFieldName);
 637  
         }
 638  0
     }
 639  
 
 640  
     /**
 641  
      * find nesting form<br />
 642  
      * need to be overrideable to deal with dummyForm stuff in tomahawk.
 643  
      */
 644  
     protected FormInfo findNestingForm(UIComponent uiComponent, FacesContext facesContext)
 645  
     {
 646  0
         return RendererUtils.findNestingForm(uiComponent, facesContext);
 647  
     }
 648  
 
 649  
     protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent)
 650  
     {
 651  
         //TODO: overwrite in extended HtmlButtonRenderer and check for enabledOnUserRole
 652  0
         if (uiComponent instanceof HtmlCommandButton)
 653  
         {
 654  0
             return ((HtmlCommandButton)uiComponent).isDisabled();
 655  
         }
 656  
 
 657  0
         return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(
 658  
                 uiComponent, HTML.DISABLED_ATTR, false);
 659  
         
 660  
     }
 661  
 
 662  
     protected boolean isReadonly(FacesContext facesContext, UIComponent uiComponent)
 663  
     {
 664  0
         if (uiComponent instanceof HtmlCommandButton)
 665  
         {
 666  0
             return ((HtmlCommandButton)uiComponent).isReadonly();
 667  
         }
 668  0
         return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(
 669  
                 uiComponent, HTML.READONLY_ATTR, false);
 670  
     }
 671  
 
 672  
     private String getType(UIComponent uiComponent)
 673  
     {
 674  0
         if (uiComponent instanceof HtmlCommandButton)
 675  
         {
 676  0
             return ((HtmlCommandButton)uiComponent).getType();
 677  
         }
 678  0
         return (String)uiComponent.getAttributes().get(org.apache.myfaces.shared.renderkit.JSFAttr.TYPE_ATTR);
 679  
     }
 680  
 
 681  
     private Object getValue(UIComponent uiComponent)
 682  
     {
 683  0
         if (uiComponent instanceof ValueHolder)
 684  
         {
 685  0
             return ((ValueHolder)uiComponent).getValue();
 686  
         }
 687  0
         return uiComponent.getAttributes().get(JSFAttr.VALUE_ATTR);
 688  
     }
 689  
 }