View Javadoc

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