Coverage Report - org.apache.myfaces.shared_impl.renderkit.html.HtmlRendererUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
HtmlRendererUtils
0%
0/744
0%
0/302
0
HtmlRendererUtils$LinkParameter
0%
0/7
N/A
0
HtmlRendererUtils$ScriptContext
0%
0/52
0%
0/18
0
 
 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_impl.renderkit.html;
 20  
 
 21  
 import org.apache.commons.logging.Log;
 22  
 import org.apache.commons.logging.LogFactory;
 23  
 import org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable;
 24  
 import org.apache.myfaces.shared_impl.component.EscapeCapable;
 25  
 import org.apache.myfaces.shared_impl.config.MyfacesConfig;
 26  
 import org.apache.myfaces.shared_impl.renderkit.JSFAttr;
 27  
 import org.apache.myfaces.shared_impl.renderkit.RendererUtils;
 28  
 import org.apache.myfaces.shared_impl.renderkit.html.util.FormInfo;
 29  
 import org.apache.myfaces.shared_impl.renderkit.html.util.HTMLEncoder;
 30  
 import org.apache.myfaces.shared_impl.renderkit.html.util.JavascriptUtils;
 31  
 
 32  
 import javax.faces.FacesException;
 33  
 import javax.faces.component.*;
 34  
 import javax.faces.component.html.HtmlDataTable;
 35  
 import javax.faces.component.html.HtmlPanelGrid;
 36  
 import javax.faces.context.ExternalContext;
 37  
 import javax.faces.context.FacesContext;
 38  
 import javax.faces.context.ResponseWriter;
 39  
 import javax.faces.convert.Converter;
 40  
 import javax.faces.model.SelectItem;
 41  
 import javax.faces.model.SelectItemGroup;
 42  
 import java.io.IOException;
 43  
 import java.util.*;
 44  
 
 45  
 /**
 46  
  * @author Manfred Geiler (latest modification by $Author: lu4242 $)
 47  
  * @version $Revision: 889471 $ $Date: 2009-12-10 18:54:31 -0500 (Thu, 10 Dec 2009) $
 48  
  */
 49  0
 public final class HtmlRendererUtils {
 50  0
     private static final Log log = LogFactory.getLog(HtmlRendererUtils.class);
 51  
 
 52  
     //private static final String[] EMPTY_STRING_ARRAY = new String[0];
 53  0
     private static final String LINE_SEPARATOR = System.getProperty(
 54  
             "line.separator", "\r\n");
 55  
     private static final char TABULATOR = '\t';
 56  
 
 57  
     public static final String HIDDEN_COMMANDLINK_FIELD_NAME = "_idcl";
 58  
     public static final String HIDDEN_COMMANDLINK_FIELD_NAME_MYFACES_OLD = "_link_hidden_";
 59  
     public static final String HIDDEN_COMMANDLINK_FIELD_NAME_TRINIDAD = "source";
 60  
 
 61  
     public static final String CLEAR_HIDDEN_FIELD_FN_NAME =
 62  
         "clearFormHiddenParams";
 63  
     public static final String SUBMIT_FORM_FN_NAME = "oamSubmitForm";
 64  
     public static final String ALLOW_CDATA_SECTION_ON = "org.apache.myfaces.ResponseWriter.CdataSectionOn";
 65  
 
 66  
     private static final String SET_HIDDEN_INPUT_FN_NAME = "oamSetHiddenInput";
 67  
     private static final String CLEAR_HIDDEN_INPUT_FN_NAME = "oamClearHiddenInput";
 68  
 
 69  
     private static final String AUTO_SCROLL_PARAM = "autoScroll";
 70  
     private static final String AUTO_SCROLL_FUNCTION = "getScrolling";
 71  
 
 72  
     private static final String FIRST_SUBMIT_SCRIPT_ON_PAGE = "org.apache.MyFaces.FIRST_SUBMIT_SCRIPT_ON_PAGE";
 73  
 
 74  
     public static final String NON_SUBMITTED_VALUE_WARNING
 75  
     = "There should always be a submitted value for an input if it is rendered,"
 76  
     + " its form is submitted, and it was not originally rendered disabled or read-only."
 77  
     + "  You cannot submit a form after disabling an input element via javascript."
 78  
     + "  Consider setting read-only to true instead"
 79  
     + " or resetting the disabled value back to false prior to form submission.";
 80  
 
 81  
 
 82  0
     private HtmlRendererUtils() {
 83  
         // utility class, do not instantiate
 84  0
     }
 85  
 
 86  
     /**
 87  
      * Utility to set the submitted value of the provided component from the
 88  
      * data in the current request object.
 89  
      * <p>
 90  
      * Param component is required to be an EditableValueHolder. On return
 91  
      * from this method, the component's submittedValue property will be
 92  
      * set if the submitted form contained that component.
 93  
      */
 94  
     public static void decodeUIInput(FacesContext facesContext,
 95  
                                      UIComponent component) {
 96  0
         if (!(component instanceof EditableValueHolder)) {
 97  0
             throw new IllegalArgumentException("Component "
 98  
                                                + component.getClientId(facesContext)
 99  
                                                + " is not an EditableValueHolder");
 100  
         }
 101  0
         Map paramMap = facesContext.getExternalContext()
 102  
                 .getRequestParameterMap();
 103  0
         String clientId = component.getClientId(facesContext);
 104  
 
 105  0
         if(isDisabledOrReadOnly(component))
 106  0
             return;
 107  
 
 108  0
         if(paramMap.containsKey(clientId))
 109  
         {
 110  0
             ((EditableValueHolder) component).setSubmittedValue(paramMap
 111  
                     .get(clientId));
 112  
         }
 113  
         else {
 114  0
             log.warn(NON_SUBMITTED_VALUE_WARNING +
 115  
                 " Component : " +
 116  
                     RendererUtils.getPathToComponent(component));
 117  
         }
 118  0
     }
 119  
 
 120  
     /**
 121  
      * X-CHECKED: tlddoc h:selectBooleanCheckbox
 122  
      *
 123  
      * @param facesContext
 124  
      * @param component
 125  
      */
 126  
     public static void decodeUISelectBoolean(FacesContext facesContext,
 127  
                                              UIComponent component) {
 128  0
         if (!(component instanceof EditableValueHolder)) {
 129  0
             throw new IllegalArgumentException("Component "
 130  
                                                + component.getClientId(facesContext)
 131  
                                                + " is not an EditableValueHolder");
 132  
         }
 133  
 
 134  0
         if(isDisabledOrReadOnly(component))
 135  0
             return;
 136  
 
 137  0
         Map paramMap = facesContext.getExternalContext()
 138  
                 .getRequestParameterMap();
 139  0
         String clientId = component.getClientId(facesContext);
 140  0
         if (paramMap.containsKey(clientId)) {
 141  0
             String reqValue = (String) paramMap.get(clientId);
 142  0
             if ((reqValue.equalsIgnoreCase("on")
 143  
                  || reqValue.equalsIgnoreCase("yes") || reqValue
 144  
                     .equalsIgnoreCase("true"))) {
 145  0
                 ((EditableValueHolder) component)
 146  
                         .setSubmittedValue(Boolean.TRUE);
 147  
             } else {
 148  0
                 ((EditableValueHolder) component)
 149  
                         .setSubmittedValue(Boolean.FALSE);
 150  
             }
 151  0
         } else {
 152  0
             ((EditableValueHolder) component)
 153  
                     .setSubmittedValue(Boolean.FALSE);
 154  
         }
 155  0
     }
 156  
 
 157  
     public static boolean isDisabledOrReadOnly(UIComponent component)
 158  
     {
 159  0
         return isDisplayValueOnly(component) ||
 160  
             isDisabled(component) ||
 161  
             isReadOnly(component);
 162  
     }
 163  
 
 164  
     public static boolean isDisabled(UIComponent component)
 165  
     {
 166  0
         return isTrue(component.getAttributes().get("disabled"));
 167  
     }
 168  
 
 169  
     public static boolean isReadOnly(UIComponent component)
 170  
     {
 171  0
         return isTrue(component.getAttributes().get("readonly"));
 172  
     }
 173  
 
 174  
     private static boolean isTrue(Object obj)
 175  
     {
 176  0
         if(!(obj instanceof Boolean))
 177  0
             return false;
 178  
 
 179  0
         return ((Boolean) obj).booleanValue();
 180  
     }
 181  
 
 182  
     /**
 183  
      * X-CHECKED: tlddoc h:selectManyListbox
 184  
      *
 185  
      * @param facesContext
 186  
      * @param component
 187  
      */
 188  
     public static void decodeUISelectMany(FacesContext facesContext,
 189  
                                           UIComponent component) {
 190  0
         if (!(component instanceof EditableValueHolder)) {
 191  0
             throw new IllegalArgumentException("Component "
 192  
                                                + component.getClientId(facesContext)
 193  
                                                + " is not an EditableValueHolder");
 194  
         }
 195  0
         Map paramValuesMap = facesContext.getExternalContext()
 196  
                 .getRequestParameterValuesMap();
 197  0
         String clientId = component.getClientId(facesContext);
 198  
 
 199  0
         if(isDisabledOrReadOnly(component))
 200  0
             return;
 201  
 
 202  0
         if (paramValuesMap.containsKey(clientId)) {
 203  0
             String[] reqValues = (String[]) paramValuesMap.get(clientId);
 204  0
             ((EditableValueHolder) component).setSubmittedValue(reqValues);
 205  0
         } else {
 206  
             /* request parameter not found, nothing to decode - set submitted value to an empty array
 207  
                as we should get here only if the component is on a submitted form, is rendered
 208  
                and if the component is not readonly or has not been disabled.
 209  
 
 210  
                So in fact, there must be component value at this location, but for listboxes, comboboxes etc.
 211  
                the submitted value is not posted if no item is selected. */
 212  0
             ((EditableValueHolder) component).setSubmittedValue( new String[]{});
 213  
         }
 214  0
     }
 215  
 
 216  
     /**
 217  
      * X-CHECKED: tlddoc h:selectManyListbox
 218  
      *
 219  
      * @param facesContext
 220  
      * @param component
 221  
      */
 222  
     public static void decodeUISelectOne(FacesContext facesContext,
 223  
                                          UIComponent component) {
 224  0
         if (!(component instanceof EditableValueHolder)) {
 225  0
             throw new IllegalArgumentException("Component "
 226  
                                                + component.getClientId(facesContext)
 227  
                                                + " is not an EditableValueHolder");
 228  
         }
 229  
 
 230  0
         if(isDisabledOrReadOnly(component))
 231  0
             return;
 232  
 
 233  0
         Map paramMap = facesContext.getExternalContext()
 234  
                 .getRequestParameterMap();
 235  0
         String clientId = component.getClientId(facesContext);
 236  0
         if (paramMap.containsKey(clientId)) {
 237  
             //request parameter found, set submitted value
 238  0
             ((EditableValueHolder) component).setSubmittedValue(paramMap
 239  
                     .get(clientId));
 240  
         } else {
 241  
             //see reason for this action at decodeUISelectMany
 242  0
             ((EditableValueHolder) component).setSubmittedValue( RendererUtils.NOTHING );
 243  
         }
 244  0
     }
 245  
 
 246  
     /*
 247  
      * public static void renderCheckbox(FacesContext facesContext, UIComponent
 248  
      * uiComponent, String value, String label, boolean checked) throws
 249  
      * IOException { String clientId = uiComponent.getClientId(facesContext);
 250  
      *
 251  
      * ResponseWriter writer = facesContext.getResponseWriter();
 252  
      *
 253  
      * writer.startElement(HTML.INPUT_ELEM, uiComponent);
 254  
      * writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_CHECKBOX, null);
 255  
      * writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
 256  
      * writer.writeAttribute(HTML.ID_ATTR, clientId, null);
 257  
      *
 258  
      * if (checked) { writer.writeAttribute(HTML.CHECKED_ATTR,
 259  
      * HTML.CHECKED_ATTR, null); }
 260  
      *
 261  
      * if ((value != null) && (value.length() > 0)) {
 262  
      * writer.writeAttribute(HTML.VALUE_ATTR, value, null); }
 263  
      *
 264  
      * renderHTMLAttributes(writer, uiComponent,
 265  
      * HTML.INPUT_PASSTHROUGH_ATTRIBUTES); renderDisabledOnUserRole(writer,
 266  
      * uiComponent, facesContext);
 267  
      *
 268  
      * if ((label != null) && (label.length() > 0)) {
 269  
      * writer.write(HTML.NBSP_ENTITY); writer.writeText(label, null); }
 270  
      *
 271  
      * writer.endElement(HTML.INPUT_ELEM); }
 272  
      */
 273  
 
 274  
     public static void renderListbox(FacesContext facesContext,
 275  
                                      UISelectOne selectOne, boolean disabled, int size)
 276  
             throws IOException {
 277  0
         internalRenderSelect(facesContext, selectOne, disabled, size, false);
 278  0
     }
 279  
 
 280  
     public static void renderListbox(FacesContext facesContext,
 281  
                                      UISelectMany selectMany, boolean disabled, int size)
 282  
             throws IOException {
 283  0
         internalRenderSelect(facesContext, selectMany, disabled, size, true);
 284  0
     }
 285  
 
 286  
     public static void renderMenu(FacesContext facesContext,
 287  
                                   UISelectOne selectOne, boolean disabled) throws IOException {
 288  0
         internalRenderSelect(facesContext, selectOne, disabled, 1, false);
 289  0
     }
 290  
 
 291  
     public static void renderMenu(FacesContext facesContext,
 292  
                                   UISelectMany selectMany, boolean disabled) throws IOException {
 293  0
         internalRenderSelect(facesContext, selectMany, disabled, 1, true);
 294  0
     }
 295  
 
 296  
     private static void internalRenderSelect(FacesContext facesContext,
 297  
                                              UIComponent uiComponent, boolean disabled, int size,
 298  
                                              boolean selectMany) throws IOException {
 299  0
         ResponseWriter writer = facesContext.getResponseWriter();
 300  
 
 301  0
         writer.startElement(HTML.SELECT_ELEM, uiComponent);
 302  0
         HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
 303  0
         writer.writeAttribute(HTML.NAME_ATTR, uiComponent
 304  
                 .getClientId(facesContext), null);
 305  
 
 306  
         List selectItemList;
 307  
         Converter converter;
 308  0
         if (selectMany) {
 309  0
             writer.writeAttribute(HTML.MULTIPLE_ATTR, HTML.MULTIPLE_ATTR, null);
 310  0
             selectItemList = org.apache.myfaces.shared_impl.renderkit.RendererUtils
 311  
                     .getSelectItemList((UISelectMany) uiComponent);
 312  0
             converter = findUISelectManyConverterFailsafe(facesContext, uiComponent);
 313  
         } else {
 314  0
             selectItemList = RendererUtils
 315  
                     .getSelectItemList((UISelectOne) uiComponent);
 316  0
             converter = findUIOutputConverterFailSafe(facesContext, uiComponent);
 317  
         }
 318  
 
 319  0
         if (size == Integer.MIN_VALUE) {
 320  
             //No size given (Listbox) --> size is number of select items
 321  0
             writer.writeAttribute(HTML.SIZE_ATTR, Integer
 322  
                     .toString(selectItemList.size()), null);
 323  
         } else {
 324  0
             writer.writeAttribute(HTML.SIZE_ATTR, Integer.toString(size), null);
 325  
         }
 326  0
         renderHTMLAttributes(writer, uiComponent,
 327  
                              HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
 328  0
         if (disabled) {
 329  0
             writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
 330  
         }
 331  
 
 332  0
         if (isReadOnly(uiComponent))
 333  
         {
 334  0
             writer.writeAttribute(HTML.READONLY_ATTR, HTML.READONLY_ATTR, null);
 335  
         }
 336  
 
 337  0
         Set lookupSet = getSubmittedOrSelectedValuesAsSet(selectMany, uiComponent, facesContext, converter);
 338  
 
 339  0
         renderSelectOptions(facesContext, uiComponent, converter, lookupSet,
 340  
                             selectItemList);
 341  
         // bug #970747: force separate end tag
 342  0
         writer.writeText("", null);
 343  0
         writer.endElement(HTML.SELECT_ELEM);
 344  0
     }
 345  
 
 346  
     public static Set getSubmittedOrSelectedValuesAsSet(boolean selectMany, UIComponent uiComponent, FacesContext facesContext, Converter converter) {
 347  
         Set lookupSet;
 348  
 
 349  0
         if (selectMany) {
 350  0
             UISelectMany uiSelectMany = (UISelectMany) uiComponent;
 351  0
             lookupSet = RendererUtils.getSubmittedValuesAsSet(facesContext, uiComponent, converter, uiSelectMany);
 352  0
             if (lookupSet == null)
 353  
             {
 354  0
                 lookupSet = RendererUtils.getSelectedValuesAsSet(facesContext, uiComponent, converter, uiSelectMany);
 355  
             }
 356  0
         } else {
 357  0
             UISelectOne uiSelectOne = (UISelectOne) uiComponent;
 358  0
             Object lookup = uiSelectOne.getSubmittedValue();
 359  0
             if (lookup == null)
 360  
             {
 361  0
                 lookup = uiSelectOne.getValue();
 362  0
                 String lookupString = RendererUtils.getConvertedStringValue(facesContext, uiComponent, converter, lookup);
 363  0
                 lookupSet = Collections.singleton(lookupString);
 364  0
             }
 365  0
             else if(org.apache.myfaces.shared_impl.renderkit.RendererUtils.NOTHING.equals(lookup))
 366  
             {
 367  0
                 lookupSet = Collections.EMPTY_SET;
 368  
             }
 369  
             else
 370  
             {
 371  0
                 lookupSet = Collections.singleton(lookup);
 372  
             }
 373  
         }
 374  0
         return lookupSet;
 375  
     }
 376  
 
 377  
     public static Converter findUISelectManyConverterFailsafe(FacesContext facesContext, UIComponent uiComponent) {
 378  
         Converter converter;
 379  
         try {
 380  0
             converter = RendererUtils.findUISelectManyConverter(
 381  
                     facesContext, (UISelectMany) uiComponent);
 382  0
         } catch (FacesException e) {
 383  0
             log.error("Error finding Converter for component with id "
 384  
                       + uiComponent.getClientId(facesContext), e);
 385  0
             converter = null;
 386  0
         }
 387  0
         return converter;
 388  
     }
 389  
 
 390  
     public static Converter findUIOutputConverterFailSafe(FacesContext facesContext, UIComponent uiComponent) {
 391  
         Converter converter;
 392  
         try {
 393  0
             converter = RendererUtils.findUIOutputConverter(facesContext,
 394  
                                                             (UIOutput) uiComponent);
 395  0
         } catch (FacesException e) {
 396  0
             log.error("Error finding Converter for component with id "
 397  
                       + uiComponent.getClientId(facesContext), e);
 398  0
             converter = null;
 399  0
         }
 400  0
         return converter;
 401  
     }
 402  
 
 403  
     /**
 404  
      * Renders the select options for a <code>UIComponent</code> that is
 405  
      * rendered as an HTML select element.
 406  
      *
 407  
      * @param context
 408  
      *            the current <code>FacesContext</code>.
 409  
      * @param component
 410  
      *            the <code>UIComponent</code> whose options need to be
 411  
      *            rendered.
 412  
      * @param converter
 413  
      *            <code>component</code>'s converter
 414  
      * @param lookupSet
 415  
      *            the <code>Set</code> to use to look up selected options
 416  
      * @param selectItemList
 417  
      *            the <code>List</code> of <code>SelectItem</code> s to be
 418  
      *            rendered as HTML option elements.
 419  
      * @throws IOException
 420  
      */
 421  
     public static void renderSelectOptions(FacesContext context,
 422  
                                            UIComponent component, Converter converter, Set lookupSet,
 423  
                                            List selectItemList) throws IOException {
 424  0
         ResponseWriter writer = context.getResponseWriter();
 425  
 
 426  0
         for (Iterator it = selectItemList.iterator(); it.hasNext();) {
 427  0
             SelectItem selectItem = (SelectItem) it.next();
 428  
 
 429  0
             if (selectItem instanceof SelectItemGroup) {
 430  0
                 writer.startElement(HTML.OPTGROUP_ELEM, component);
 431  0
                 writer.writeAttribute(HTML.LABEL_ATTR, selectItem.getLabel(),
 432  
                                       null);
 433  0
                 SelectItem[] selectItems = ((SelectItemGroup) selectItem)
 434  
                         .getSelectItems();
 435  0
                 renderSelectOptions(context, component, converter, lookupSet,
 436  
                                     Arrays.asList(selectItems));
 437  0
                 writer.endElement(HTML.OPTGROUP_ELEM);
 438  0
             } else {
 439  0
                 String itemStrValue = org.apache.myfaces.shared_impl.renderkit.RendererUtils.getConvertedStringValue(context, component,
 440  
                                                                             converter, selectItem);
 441  
 
 442  0
                 writer.write(TABULATOR);
 443  0
                 writer.startElement(HTML.OPTION_ELEM, component);
 444  0
                 if (itemStrValue != null) {
 445  0
                     writer.writeAttribute(HTML.VALUE_ATTR, itemStrValue, null);
 446  
                 }
 447  
 
 448  0
                 if (lookupSet.contains(itemStrValue)) {  //TODO/FIX: we always compare the String vales, better fill lookupSet with Strings only when useSubmittedValue==true, else use the real item value Objects
 449  0
                     writer.writeAttribute(HTML.SELECTED_ATTR,
 450  
                                           HTML.SELECTED_ATTR, null);
 451  
                 }
 452  
 
 453  0
                 boolean disabled = selectItem.isDisabled();
 454  0
                 if (disabled) {
 455  0
                     writer.writeAttribute(HTML.DISABLED_ATTR,
 456  
                                           HTML.DISABLED_ATTR, null);
 457  
                 }
 458  
 
 459  0
                 String labelClass = null;
 460  0
                 boolean componentDisabled = isTrue(component.getAttributes().get("disabled"));
 461  
 
 462  0
                 if (componentDisabled || disabled) {
 463  0
                     labelClass = (String) component.getAttributes().get(JSFAttr.DISABLED_CLASS_ATTR);
 464  
                 } else {
 465  0
                     labelClass = (String) component.getAttributes().get(JSFAttr.ENABLED_CLASS_ATTR);
 466  
                 }
 467  0
                 if (labelClass != null) {
 468  0
                     writer.writeAttribute("class", labelClass, "labelClass");
 469  
                 }
 470  
 
 471  
                 boolean escape;
 472  0
                 if (component instanceof EscapeCapable)
 473  
                 {
 474  0
                     escape = ((EscapeCapable)component).isEscape();
 475  
                     
 476  
                     // Preserve tomahawk semantic. If escape=false
 477  
                     // all items should be non escaped. If escape
 478  
                     // is true check if selectItem.isEscape() is
 479  
                     // true and do it.
 480  
                     // This is done for remain compatibility.
 481  0
                     if (escape && selectItem.isEscape())
 482  
                     {
 483  0
                         writer.writeText(selectItem.getLabel(), null);
 484  
                     } else
 485  
                     {
 486  0
                         writer.write(selectItem.getLabel());
 487  
                     }
 488  
                 }
 489  
                 else
 490  
                 {
 491  0
                     escape = RendererUtils.getBooleanAttribute(component, JSFAttr.ESCAPE_ATTR,
 492  
                                                                false);
 493  
                     //default is to escape
 494  
                     //In JSF 1.2, when a SelectItem is created by default 
 495  
                     //selectItem.isEscape() returns true (this property
 496  
                     //is not available on JSF 1.1).
 497  
                     //so, if we found a escape property on the component
 498  
                     //set to true, escape every item, but if not
 499  
                     //check if isEscape() = true first.
 500  0
                     if (escape || selectItem.isEscape())
 501  
                     {
 502  0
                         writer.writeText(selectItem.getLabel(), null);
 503  
                     } else
 504  
                     {
 505  0
                         writer.write(selectItem.getLabel());
 506  
                     }
 507  
                 }
 508  
 
 509  0
                 writer.endElement(HTML.OPTION_ELEM);
 510  
             }
 511  0
         }
 512  0
     }
 513  
 
 514  
     /*
 515  
      * public static void renderRadio(FacesContext facesContext, UIInput
 516  
      * uiComponent, String value, String label, boolean checked) throws
 517  
      * IOException { String clientId = uiComponent.getClientId(facesContext);
 518  
      *
 519  
      * ResponseWriter writer = facesContext.getResponseWriter();
 520  
      *
 521  
      * writer.startElement(HTML.INPUT_ELEM, uiComponent);
 522  
      * writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_RADIO, null);
 523  
      * writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
 524  
      * writer.writeAttribute(HTML.ID_ATTR, clientId, null);
 525  
      *
 526  
      * if (checked) { writer.writeAttribute(HTML.CHECKED_ATTR,
 527  
      * HTML.CHECKED_ATTR, null); }
 528  
      *
 529  
      * if ((value != null) && (value.length() > 0)) {
 530  
      * writer.writeAttribute(HTML.VALUE_ATTR, value, null); }
 531  
      *
 532  
      * renderHTMLAttributes(writer, uiComponent,
 533  
      * HTML.INPUT_PASSTHROUGH_ATTRIBUTES); renderDisabledOnUserRole(writer,
 534  
      * uiComponent, facesContext);
 535  
      *
 536  
      * if ((label != null) && (label.length() > 0)) {
 537  
      * writer.write(HTML.NBSP_ENTITY); writer.writeText(label, null); }
 538  
      *
 539  
      * writer.endElement(HTML.INPUT_ELEM); }
 540  
      */
 541  
 
 542  
     public static void writePrettyLineSeparator(FacesContext facesContext)
 543  
             throws IOException {
 544  0
         if (org.apache.myfaces.shared_impl.config.MyfacesConfig.getCurrentInstance(facesContext.getExternalContext())
 545  
                 .isPrettyHtml()) {
 546  0
             facesContext.getResponseWriter().write(LINE_SEPARATOR);
 547  
         }
 548  0
     }
 549  
 
 550  
     public static void writePrettyIndent(FacesContext facesContext)
 551  
             throws IOException {
 552  0
         if (org.apache.myfaces.shared_impl.config.MyfacesConfig.getCurrentInstance(facesContext.getExternalContext())
 553  
                 .isPrettyHtml()) {
 554  0
             facesContext.getResponseWriter().write('\t');
 555  
         }
 556  0
     }
 557  
 
 558  
     /**
 559  
      * @return true, if the attribute was written
 560  
      * @throws java.io.IOException
 561  
      */
 562  
     public static boolean renderHTMLAttribute(ResponseWriter writer,
 563  
                                               String componentProperty, String attrName, Object value)
 564  
             throws IOException {
 565  0
         if (!RendererUtils.isDefaultAttributeValue(value)) {
 566  
             // render JSF "styleClass" and "itemStyleClass" attributes as "class"
 567  0
             String htmlAttrName =
 568  
                     attrName.equals(HTML.STYLE_CLASS_ATTR) ?
 569  
                     HTML.CLASS_ATTR : attrName;
 570  0
             writer.writeAttribute(htmlAttrName, value, componentProperty);
 571  0
             return true;
 572  
         }
 573  
 
 574  0
         return false;
 575  
     }
 576  
 
 577  
     /**
 578  
      * @return true, if the attribute was written
 579  
      * @throws java.io.IOException
 580  
      */
 581  
     public static boolean renderHTMLAttribute(ResponseWriter writer,
 582  
                                               UIComponent component, String componentProperty, String htmlAttrName)
 583  
             throws IOException {
 584  0
         Object value = component.getAttributes().get(componentProperty);
 585  0
         return renderHTMLAttribute(writer, componentProperty, htmlAttrName,
 586  
                                    value);
 587  
     }
 588  
 
 589  
     /**
 590  
      * @return true, if an attribute was written
 591  
      * @throws java.io.IOException
 592  
      */
 593  
     public static boolean renderHTMLAttributes(ResponseWriter writer,
 594  
                                                UIComponent component, String[] attributes) throws IOException {
 595  0
         boolean somethingDone = false;
 596  0
         for (int i = 0, len = attributes.length; i < len; i++) {
 597  0
             String attrName = attributes[i];
 598  0
             if (renderHTMLAttribute(writer, component, attrName, attrName)) {
 599  0
                 somethingDone = true;
 600  
             }
 601  
         }
 602  0
         return somethingDone;
 603  
     }
 604  
 
 605  
     public static boolean renderHTMLAttributeWithOptionalStartElement(
 606  
             ResponseWriter writer, UIComponent component, String elementName,
 607  
             String attrName, Object value, boolean startElementWritten)
 608  
             throws IOException {
 609  0
         if (!org.apache.myfaces.shared_impl.renderkit.RendererUtils.isDefaultAttributeValue(value)) {
 610  0
             if (!startElementWritten) {
 611  0
                 writer.startElement(elementName, component);
 612  0
                 startElementWritten = true;
 613  
             }
 614  0
             renderHTMLAttribute(writer, attrName, attrName, value);
 615  
         }
 616  0
         return startElementWritten;
 617  
     }
 618  
 
 619  
     public static boolean renderHTMLAttributesWithOptionalStartElement(
 620  
             ResponseWriter writer, UIComponent component, String elementName,
 621  
             String[] attributes) throws IOException {
 622  0
         boolean startElementWritten = false;
 623  0
         for (int i = 0, len = attributes.length; i < len; i++) {
 624  0
             String attrName = attributes[i];
 625  0
             Object value = component.getAttributes().get(attrName);
 626  0
             if (!RendererUtils.isDefaultAttributeValue(value)) {
 627  0
                 if (!startElementWritten) {
 628  0
                     writer.startElement(elementName, component);
 629  0
                     startElementWritten = true;
 630  
                 }
 631  0
                 renderHTMLAttribute(writer, attrName, attrName, value);
 632  
             }
 633  
         }
 634  0
         return startElementWritten;
 635  
     }
 636  
 
 637  
     public static boolean renderOptionalEndElement(ResponseWriter writer,
 638  
                                                    UIComponent component, String elementName, String[] attributes)
 639  
             throws IOException {
 640  0
         boolean endElementNeeded = false;
 641  0
         for (int i = 0, len = attributes.length; i < len; i++) {
 642  0
             String attrName = attributes[i];
 643  0
             Object value = component.getAttributes().get(attrName);
 644  0
             if (!RendererUtils.isDefaultAttributeValue(value)) {
 645  0
                 endElementNeeded = true;
 646  0
                 break;
 647  
             }
 648  
         }
 649  0
         if (endElementNeeded) {
 650  0
             writer.endElement(elementName);
 651  0
             return true;
 652  
         }
 653  
 
 654  0
         return false;
 655  
     }
 656  
 
 657  
     public static void writeIdIfNecessary(ResponseWriter writer, UIComponent component,
 658  
                                           FacesContext facesContext)
 659  
             throws IOException
 660  
     {
 661  0
         if(component.getId()!=null && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
 662  
         {
 663  0
             writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext),null);
 664  
         }
 665  0
     }
 666  
 
 667  
     public static void writeIdAndNameIfNecessary(ResponseWriter writer, UIComponent component,
 668  
                                                  FacesContext facesContext)
 669  
             throws IOException
 670  
     {
 671  0
         if(component.getId()!=null && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
 672  
         {
 673  0
             String clientId = component.getClientId(facesContext);
 674  0
             writer.writeAttribute(HTML.ID_ATTR, clientId, null);
 675  0
             writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
 676  
         }
 677  0
     }
 678  
 
 679  
     public static void renderDisplayValueOnlyForSelects(FacesContext facesContext, UIComponent
 680  
             uiComponent)
 681  
             throws IOException
 682  
     {
 683  0
         ResponseWriter writer = facesContext.getResponseWriter();
 684  
 
 685  0
         List selectItemList=null;
 686  0
         Converter converter=null;
 687  0
         boolean isSelectOne=false;
 688  
 
 689  0
         if(uiComponent instanceof UISelectBoolean)
 690  
         {
 691  0
             converter = findUIOutputConverterFailSafe(facesContext, uiComponent);
 692  
 
 693  0
             writer.startElement(HTML.SPAN_ELEM, uiComponent);
 694  0
             writeIdIfNecessary(writer, uiComponent, facesContext);
 695  0
             renderDisplayValueOnlyAttributes(uiComponent, writer);
 696  0
             writer.writeText(RendererUtils.getConvertedStringValue(facesContext,uiComponent,
 697  
                                                                    converter,((UISelectBoolean) uiComponent).getValue()),JSFAttr.VALUE_ATTR);
 698  0
             writer.endElement(HTML.SPAN_ELEM);
 699  
 
 700  
         }
 701  
         else
 702  
         {
 703  0
             if (uiComponent instanceof UISelectMany) {
 704  0
                 isSelectOne = false;
 705  0
                 selectItemList = RendererUtils
 706  
                         .getSelectItemList((UISelectMany) uiComponent);
 707  0
                 converter = findUISelectManyConverterFailsafe(facesContext, uiComponent);
 708  0
             } else if(uiComponent instanceof UISelectOne){
 709  0
                 isSelectOne = true;
 710  0
                 selectItemList = RendererUtils
 711  
                         .getSelectItemList((UISelectOne) uiComponent);
 712  0
                 converter = findUIOutputConverterFailSafe(facesContext, uiComponent);
 713  
             }
 714  
 
 715  0
             writer.startElement(isSelectOne ? HTML.SPAN_ELEM : HTML.UL_ELEM, uiComponent);
 716  0
             writeIdIfNecessary(writer, uiComponent, facesContext);
 717  
 
 718  0
             renderDisplayValueOnlyAttributes(uiComponent, writer);
 719  
 
 720  0
             Set lookupSet = getSubmittedOrSelectedValuesAsSet(
 721  
                     uiComponent instanceof UISelectMany,
 722  
                     uiComponent, facesContext, converter);
 723  
 
 724  0
             renderSelectOptionsAsText(facesContext, uiComponent, converter, lookupSet,
 725  
                                       selectItemList, isSelectOne);
 726  
 
 727  
             // bug #970747: force separate end tag
 728  0
             writer.writeText("", null);
 729  0
             writer.endElement(isSelectOne ? HTML.SPAN_ELEM : HTML.UL_ELEM);
 730  
         }
 731  
 
 732  0
     }
 733  
 
 734  
     public static void renderDisplayValueOnlyAttributes(UIComponent uiComponent, ResponseWriter writer) throws IOException {
 735  0
         if(!(uiComponent instanceof org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable))
 736  
         {
 737  0
             log.error("Wrong type of uiComponent. needs DisplayValueOnlyCapable.");
 738  0
             renderHTMLAttributes(writer, uiComponent,
 739  
                                  HTML.COMMON_PASSTROUGH_ATTRIBUTES);
 740  
 
 741  0
             return;
 742  
         }
 743  
 
 744  0
         if(getDisplayValueOnlyStyle(uiComponent) != null || getDisplayValueOnlyStyleClass(uiComponent)!=null)
 745  
         {
 746  0
             if(getDisplayValueOnlyStyle(uiComponent) != null )
 747  
             {
 748  0
                 writer.writeAttribute(HTML.STYLE_ATTR, getDisplayValueOnlyStyle(uiComponent), null);
 749  
             }
 750  0
             else if(uiComponent.getAttributes().get("style")!=null)
 751  
             {
 752  0
                 writer.writeAttribute(HTML.STYLE_ATTR, uiComponent.getAttributes().get("style"), null);
 753  
             }
 754  
 
 755  0
             if(getDisplayValueOnlyStyleClass(uiComponent) != null )
 756  
             {
 757  0
                 writer.writeAttribute(HTML.CLASS_ATTR, getDisplayValueOnlyStyleClass(uiComponent), null);
 758  
             }
 759  0
             else if(uiComponent.getAttributes().get("styleClass")!=null)
 760  
             {
 761  0
                 writer.writeAttribute(HTML.CLASS_ATTR, uiComponent.getAttributes().get("styleClass"), null);
 762  
             }
 763  
 
 764  0
             renderHTMLAttributes(writer, uiComponent,
 765  
                                  HTML.COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_STYLE);
 766  
         }
 767  
         else
 768  
         {
 769  0
             renderHTMLAttributes(writer, uiComponent,
 770  
                                  HTML.COMMON_PASSTROUGH_ATTRIBUTES);
 771  
         }
 772  0
     }
 773  
 
 774  
     private static void renderSelectOptionsAsText(FacesContext context,
 775  
                                                   UIComponent component, Converter converter, Set lookupSet,
 776  
                                                   List selectItemList, boolean isSelectOne) throws IOException {
 777  0
         ResponseWriter writer = context.getResponseWriter();
 778  
 
 779  0
         for (Iterator it = selectItemList.iterator(); it.hasNext();) {
 780  0
             SelectItem selectItem = (SelectItem) it.next();
 781  
 
 782  0
             if (selectItem instanceof SelectItemGroup) {
 783  0
                 SelectItem[] selectItems = ((SelectItemGroup) selectItem)
 784  
                         .getSelectItems();
 785  0
                 renderSelectOptionsAsText(context, component, converter, lookupSet,
 786  
                                           Arrays.asList(selectItems), isSelectOne);
 787  0
             } else {
 788  0
                 String itemStrValue = RendererUtils.getConvertedStringValue(context, component,
 789  
                                                                             converter, selectItem);
 790  
 
 791  0
                 if (lookupSet.contains(itemStrValue)) {  //TODO/FIX: we always compare the String vales, better fill lookupSet with Strings only when useSubmittedValue==true, else use the real item value Objects
 792  
 
 793  0
                     if( ! isSelectOne )
 794  0
                         writer.startElement(HTML.LI_ELEM, component);
 795  0
                     writer.writeText(selectItem.getLabel(), null);
 796  0
                     if( ! isSelectOne )
 797  0
                         writer.endElement(HTML.LI_ELEM);
 798  
 
 799  0
                     if( isSelectOne )
 800  
                     {
 801  
                         //take care of several choices with the same value; use only the first one
 802  0
                         return;
 803  
                     }
 804  
                 }
 805  
             }
 806  0
         }
 807  0
     }
 808  
 
 809  
     public static void renderTableCaption(FacesContext context,
 810  
                                  ResponseWriter writer,
 811  
                                  UIComponent component)
 812  
             throws IOException
 813  
     {
 814  0
         UIComponent captionFacet = component.getFacet("caption");
 815  0
         if (captionFacet == null) return;
 816  
 
 817  
         String captionClass;
 818  
         String captionStyle;
 819  
 
 820  0
         if (component instanceof HtmlPanelGrid)
 821  
         {
 822  0
             HtmlPanelGrid panelGrid = (HtmlPanelGrid) component;
 823  0
             captionClass = panelGrid.getCaptionClass();
 824  0
             captionStyle = panelGrid.getCaptionStyle();
 825  0
         }
 826  0
         else if (component instanceof HtmlDataTable)
 827  
         {
 828  0
             HtmlDataTable dataTable = (HtmlDataTable) component;
 829  0
             captionClass = dataTable.getCaptionClass();
 830  0
             captionStyle = dataTable.getCaptionStyle();
 831  0
         }
 832  
         else
 833  
         {
 834  0
             captionClass = (String)component.getAttributes().get(org.apache.myfaces.shared_impl.renderkit.JSFAttr.CAPTION_CLASS_ATTR);
 835  0
             captionStyle = (String)component.getAttributes().get(org.apache.myfaces.shared_impl.renderkit.JSFAttr.CAPTION_STYLE_ATTR);
 836  
         }
 837  
 
 838  0
         HtmlRendererUtils.writePrettyLineSeparator(context);
 839  0
         writer.startElement(HTML.CAPTION_ELEM, component);
 840  
 
 841  0
         if (captionClass != null)
 842  
         {
 843  0
             writer.writeAttribute(HTML.CLASS_ATTR, captionClass, null);
 844  
         }
 845  
 
 846  0
         if (captionStyle != null)
 847  
         {
 848  0
             writer.writeAttribute(HTML.STYLE_ATTR, captionStyle, null);
 849  
         }
 850  
 
 851  0
         RendererUtils.renderChild(context, captionFacet);
 852  
 
 853  0
         writer.endElement(HTML.CAPTION_ELEM);
 854  0
     }
 855  
 
 856  
     public static String getDisplayValueOnlyStyleClass(UIComponent component) {
 857  
 
 858  0
         if(component instanceof org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable)
 859  
         {
 860  0
             if(((org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable) component).getDisplayValueOnlyStyleClass()!=null)
 861  0
                 return ((org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable) component).getDisplayValueOnlyStyleClass();
 862  
 
 863  0
             UIComponent parent=component;
 864  
 
 865  0
             while((parent = parent.getParent())!=null)
 866  
             {
 867  0
                 if(parent instanceof org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable &&
 868  
                    ((org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable) parent).getDisplayValueOnlyStyleClass()!=null)
 869  
                 {
 870  0
                     return ((org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable) parent).getDisplayValueOnlyStyleClass();
 871  
                 }
 872  
             }
 873  
         }
 874  
 
 875  0
         return null;
 876  
     }
 877  
 
 878  
     public static String getDisplayValueOnlyStyle(UIComponent component) {
 879  
 
 880  0
         if(component instanceof DisplayValueOnlyCapable)
 881  
         {
 882  0
             if(((org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable) component).getDisplayValueOnlyStyle()!=null)
 883  0
                 return ((org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable) component).getDisplayValueOnlyStyle();
 884  
 
 885  0
             UIComponent parent=component;
 886  
 
 887  0
             while((parent = parent.getParent())!=null)
 888  
             {
 889  0
                 if(parent instanceof org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable &&
 890  
                    ((DisplayValueOnlyCapable) parent).getDisplayValueOnlyStyle()!=null)
 891  
                 {
 892  0
                     return ((DisplayValueOnlyCapable) parent).getDisplayValueOnlyStyle();
 893  
                 }
 894  
             }
 895  
         }
 896  
 
 897  0
         return null;
 898  
     }
 899  
 
 900  
     public static boolean isDisplayValueOnly(UIComponent component) {
 901  
 
 902  0
         if(component instanceof DisplayValueOnlyCapable)
 903  
         {
 904  0
             if(((DisplayValueOnlyCapable) component).isSetDisplayValueOnly())
 905  0
                 return ((org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable) component).isDisplayValueOnly();
 906  
 
 907  0
             UIComponent parent=component;
 908  
 
 909  0
             while((parent = parent.getParent())!=null)
 910  
             {
 911  0
                 if(parent instanceof DisplayValueOnlyCapable &&
 912  
                    ((DisplayValueOnlyCapable) parent).isSetDisplayValueOnly())
 913  
                 {
 914  0
                     return ((org.apache.myfaces.shared_impl.component.DisplayValueOnlyCapable) parent).isDisplayValueOnly();
 915  
                 }
 916  
             }
 917  
         }
 918  
 
 919  0
         return false;
 920  
     }
 921  
 
 922  
     public static void renderDisplayValueOnly(FacesContext facesContext, UIInput input) throws IOException {
 923  0
         ResponseWriter writer = facesContext.getResponseWriter();
 924  0
         writer.startElement(org.apache.myfaces.shared_impl.renderkit.html.HTML.SPAN_ELEM, input);
 925  
 
 926  0
         writeIdIfNecessary(writer, input, facesContext);
 927  
 
 928  0
         renderDisplayValueOnlyAttributes(input, writer);
 929  
 
 930  0
         String strValue = RendererUtils.getStringValue(facesContext, input);
 931  0
         writer.write( HTMLEncoder.encode(strValue, true, true) );
 932  
 
 933  0
         writer.endElement(HTML.SPAN_ELEM);
 934  0
     }
 935  
 
 936  
     public static void appendClearHiddenCommandFormParamsFunctionCall(StringBuffer buf, String formName) {
 937  0
         appendClearHiddenCommandFormParamsFunctionCall(new ScriptContext(buf,false), formName);
 938  0
     }
 939  
 
 940  
     private static void appendClearHiddenCommandFormParamsFunctionCall(ScriptContext context, String formName) {
 941  
 
 942  0
         String functionName = HtmlRendererUtils.getClearHiddenCommandFormParamsFunctionName(formName);
 943  
 
 944  0
         if(formName == null)
 945  
         {
 946  0
             context.prettyLine();
 947  0
             context.append("var clearFn = ");
 948  0
             context.append(functionName);
 949  0
             context.append(";");
 950  0
             context.prettyLine();
 951  0
             context.append("if(typeof window[clearFn] =='function')");
 952  0
             context.append("{");
 953  0
             context.append("window[clearFn](formName);");
 954  0
             context.append("}");
 955  
         }
 956  
         else
 957  
         {
 958  0
             context.prettyLine();
 959  0
             context.append("if(typeof window.");
 960  0
             context.append(functionName);
 961  0
             context.append("=='function')");
 962  0
             context.append("{");
 963  0
             context.append(functionName).append("('").append(formName).append("');");
 964  0
             context.append("}");
 965  
         }
 966  0
     }
 967  
 
 968  
 
 969  
     public static void renderFormSubmitScript(FacesContext facesContext)
 970  
             throws IOException
 971  
     {
 972  
 
 973  0
         Map map = facesContext.getExternalContext().getRequestMap();
 974  0
         Boolean firstScript = (Boolean) map.get(FIRST_SUBMIT_SCRIPT_ON_PAGE);
 975  
 
 976  0
         if (firstScript == null || firstScript.equals(Boolean.TRUE)) {
 977  0
             map.put(FIRST_SUBMIT_SCRIPT_ON_PAGE, Boolean.FALSE);
 978  0
             HtmlRendererUtils.renderFormSubmitScriptIfNecessary(facesContext);
 979  
 
 980  
         }
 981  0
     }
 982  
 
 983  
     private static void renderFormSubmitScriptIfNecessary(FacesContext facesContext) throws IOException {
 984  0
         ResponseWriter writer = facesContext.getResponseWriter();
 985  
 
 986  0
         writer.startElement(HTML.SCRIPT_ELEM, null);
 987  0
         writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", null);
 988  
 
 989  0
         final ExternalContext externalContext = facesContext.getExternalContext();
 990  0
         final MyfacesConfig currentInstance = MyfacesConfig.getCurrentInstance(externalContext);
 991  0
         boolean autoScroll = currentInstance.isAutoScroll();
 992  
 
 993  0
         ScriptContext context = new ScriptContext(currentInstance
 994  
             .isPrettyHtml());
 995  0
         context.prettyLine();
 996  0
         context.increaseIndent();
 997  
 
 998  0
         prepareScript(context, autoScroll);
 999  
 
 1000  0
         writer.writeText(context.toString(),null);
 1001  
 
 1002  0
         writer.endElement(HTML.SCRIPT_ELEM);
 1003  0
     }
 1004  
 
 1005  
     private static void prepareScript(ScriptContext context, boolean autoScroll)
 1006  
     {
 1007  
 
 1008  0
         context.prettyLine();
 1009  
 
 1010  
         //render a function to create a hidden input, if it doesn't exist
 1011  0
         context.append("function ");
 1012  0
         context.append(SET_HIDDEN_INPUT_FN_NAME).append("(formname, name, value)");
 1013  0
         context.append("{");
 1014  0
         context.append("var form = document.forms[formname];");
 1015  0
         context.prettyLine();
 1016  0
         context.append("if (typeof form == 'undefined')");
 1017  0
         context.append("{");
 1018  0
         context.append("form = document.getElementById(formname);");
 1019  0
         context.append("}");
 1020  0
         context.prettyLine();
 1021  0
         context.append("if(typeof form.elements[name]!='undefined' && (form.elements[name].nodeName=='INPUT' || form.elements[name].nodeName=='input'))");
 1022  0
         context.append("{");
 1023  0
         context.append("form.elements[name].value=value;");        
 1024  0
         context.append("}");
 1025  0
         context.append("else");
 1026  0
         context.append("{");
 1027  0
         context.append("var newInput = document.createElement('input');");
 1028  0
         context.prettyLine();
 1029  0
         context.append("newInput.setAttribute('type','hidden');");
 1030  0
         context.prettyLine();
 1031  0
         context.append("newInput.setAttribute('id',name);");  // IE hack; See MYFACES-1805
 1032  0
         context.prettyLine();
 1033  0
         context.append("newInput.setAttribute('name',name);");
 1034  0
         context.prettyLine();
 1035  0
         context.append("newInput.setAttribute('value',value);");
 1036  0
         context.prettyLine();
 1037  0
         context.append("form.appendChild(newInput);");
 1038  0
         context.append("}");
 1039  
 
 1040  0
         context.append("}");
 1041  
 
 1042  0
         context.prettyLine();
 1043  
 
 1044  0
         context.prettyLine();
 1045  
 
 1046  
         //render a function to clear a hidden input, if it exists        
 1047  0
         context.append("function ");
 1048  0
         context.append(CLEAR_HIDDEN_INPUT_FN_NAME).append("(formname, name, value)");
 1049  0
         context.append("{");
 1050  0
         context.append("var form = document.forms[formname];");
 1051  0
         context.prettyLine();
 1052  0
         context.append("if (typeof form == 'undefined')");
 1053  0
         context.append("{");
 1054  0
         context.append("form = document.getElementById(formname);");
 1055  0
         context.append("}");
 1056  0
         context.prettyLine();
 1057  0
         context.append("var hInput = form.elements[name];");
 1058  0
         context.prettyLine();
 1059  0
         context.append("if(typeof hInput !='undefined')");
 1060  0
         context.append("{");
 1061  
         //context.append("form.elements[name].value=null;");
 1062  0
         context.append("form.removeChild(hInput);");
 1063  0
         context.append("}");
 1064  
 
 1065  0
         context.append("}");
 1066  
 
 1067  0
         context.prettyLine();
 1068  
 
 1069  0
         context.append("function ");
 1070  0
         context.append(SUBMIT_FORM_FN_NAME).append("(formName, linkId, target, params)");
 1071  0
         context.append("{");
 1072  
 
 1073  
         //call the script to clear the form (clearFormHiddenParams_<formName>) method - optionally, only necessary for IE5.5.
 1074  
         //todo: if IE5.5. is ever desupported, we can get rid of this and instead rely on the last part of this script to
 1075  
         //clear the parameters
 1076  0
         HtmlRendererUtils.appendClearHiddenCommandFormParamsFunctionCall(context, null);
 1077  
 
 1078  0
         if (autoScroll)
 1079  
         {
 1080  0
             appendAutoScrollAssignment(context, null);
 1081  
         }
 1082  
 
 1083  0
         context.prettyLine();
 1084  
 
 1085  0
         context.append("var form = document.forms[formName];");
 1086  0
         context.prettyLine();
 1087  0
         context.append("if (typeof form == 'undefined')");
 1088  0
         context.append("{");
 1089  0
         context.append("form = document.getElementById(formName);");
 1090  0
         context.append("}");
 1091  0
         context.prettyLine();
 1092  
         
 1093  0
         if (JavascriptUtils.isSaveFormSubmitLinkIE(FacesContext.getCurrentInstance().getExternalContext())){
 1094  0
             context.append("var agentString = navigator.userAgent.toLowerCase();");
 1095  0
             context.prettyLine();
 1096  
             //context.append("var isIE = false;");
 1097  0
             context.prettyLine();
 1098  0
             context.append("if (agentString.indexOf('msie') != -1)");
 1099  
         
 1100  0
             context.append("{");
 1101  0
             context.append("if (!(agentString.indexOf('ppc') != -1 && agentString.indexOf('windows ce') != -1 && version >= 4.0))");              
 1102  0
             context.append("{");
 1103  0
             context.append("window.external.AutoCompleteSaveForm(form);");        
 1104  
 //        context.append("isIE = false;");
 1105  0
             context.append("}");
 1106  
 //        context.append("else");
 1107  
 //        context.append("{");
 1108  
 //        context.append("isIE = true;");
 1109  
 //        context.prettyLine();
 1110  
 //        context.append("}");
 1111  
         
 1112  0
             context.append("}");
 1113  
 
 1114  0
             context.prettyLine();
 1115  
         }
 1116  
         //set the target (and save it). This should be done always, 
 1117  
         //and the default value of target is always valid.
 1118  0
         context.append("var oldTarget = form.target;");
 1119  0
         context.prettyLine();
 1120  0
         context.append("if(target != null)");
 1121  0
         context.append("{");
 1122  0
         context.prettyLine();
 1123  0
         context.append("form.target=target;");
 1124  0
         context.append("}");
 1125  
 
 1126  
         //set the submit parameters
 1127  
 
 1128  0
         context.append("if((typeof params!='undefined') && params != null)");
 1129  0
         context.append("{");
 1130  0
         context.prettyLine();
 1131  0
         context.append("for(var i=0, param; (param = params[i]); i++)");
 1132  0
         context.append("{");
 1133  0
         context.append(SET_HIDDEN_INPUT_FN_NAME).append("(formName,param[0], param[1]);");
 1134  0
         context.append("}");
 1135  0
         context.append("}");
 1136  
 
 1137  0
         context.prettyLine();
 1138  
 
 1139  0
         context.append(SET_HIDDEN_INPUT_FN_NAME);
 1140  0
         context.append("(formName,formName +'"+NamingContainer.SEPARATOR_CHAR+
 1141  
                 "'+'"+HtmlRendererUtils.HIDDEN_COMMANDLINK_FIELD_NAME+"',linkId);");
 1142  
 
 1143  0
         context.prettyLine();
 1144  0
         context.prettyLine();
 1145  
 
 1146  
         //do the actual submit calls
 1147  
 
 1148  0
         context.append("if(form.onsubmit)");
 1149  0
         context.append("{");
 1150  0
         context.append("var result=form.onsubmit();");
 1151  0
         context.prettyLine();
 1152  0
         context.append("if((typeof result=='undefined')||result)");
 1153  0
         context.append("{");
 1154  0
         context.append("try");
 1155  0
         context.append("{");
 1156  0
         context.append("form.submit();");
 1157  0
         context.append("}");
 1158  0
         context.append("catch(e){}");
 1159  0
         context.append("}");
 1160  0
         context.append("}");
 1161  0
         context.append("else ");
 1162  0
         context.append("{");
 1163  0
         context.append("try");
 1164  0
         context.append("{");        
 1165  0
         context.append("form.submit();");
 1166  0
         context.append("}");
 1167  0
         context.append("catch(e){}");        
 1168  0
         context.append("}");
 1169  
 
 1170  
         //reset the target
 1171  0
         context.prettyLine();
 1172  
         //Restore the old target, no more questions asked
 1173  0
         context.append("form.target=oldTarget;");
 1174  0
         context.prettyLine();
 1175  
 
 1176  
         //clear the individual parameters - to make sure that even if the clear-function isn't called,
 1177  
         // the back button/resubmit functionality will still work in all browsers except IE 5.5.
 1178  
 
 1179  0
         context.append("if((typeof params!='undefined') && params != null)");
 1180  0
         context.append("{");
 1181  0
         context.prettyLine();
 1182  0
         context.append("for(var i=0, param; (param = params[i]); i++)");        
 1183  0
         context.append("{");
 1184  0
         context.append(CLEAR_HIDDEN_INPUT_FN_NAME).append("(formName,param[0], param[1]);");
 1185  0
         context.append("}");
 1186  0
         context.append("}");
 1187  
 
 1188  0
         context.prettyLine();
 1189  
 
 1190  0
         context.append(CLEAR_HIDDEN_INPUT_FN_NAME);
 1191  0
         context.append("(formName,formName +'"+NamingContainer.SEPARATOR_CHAR+
 1192  
                 "'+'"+HtmlRendererUtils.HIDDEN_COMMANDLINK_FIELD_NAME+"',linkId);");
 1193  
 
 1194  
 
 1195  
         //return false, so that browser does not handle the click
 1196  0
         context.append("return false;");
 1197  0
         context.append("}");
 1198  
 
 1199  0
         context.prettyLineDecreaseIndent();
 1200  0
     }
 1201  
 
 1202  
     /**
 1203  
      * Adds the hidden form input value assignment that is necessary for the autoscroll
 1204  
      * feature to an html link or button onclick attribute.
 1205  
      */
 1206  
     public static void appendAutoScrollAssignment(StringBuffer onClickValue, String formName)
 1207  
     {
 1208  0
         appendAutoScrollAssignment(new ScriptContext(onClickValue,false),formName);
 1209  0
     }
 1210  
 
 1211  
     private static void appendAutoScrollAssignment(ScriptContext scriptContext, String formName)
 1212  
     {
 1213  0
         String formNameStr = formName == null? "formName" : (new StringBuffer("'").append(formName).append("'").toString());
 1214  0
         String paramName = new StringBuffer().append("'").
 1215  
                 append(AUTO_SCROLL_PARAM).append("'").toString();
 1216  0
         String value = new StringBuffer().append(AUTO_SCROLL_FUNCTION).append("()").toString();
 1217  
 
 1218  0
         scriptContext.prettyLine();
 1219  0
         scriptContext.append("if(typeof window."+AUTO_SCROLL_FUNCTION+"!='undefined')");
 1220  0
         scriptContext.append("{");
 1221  0
         scriptContext.append(SET_HIDDEN_INPUT_FN_NAME);
 1222  0
         scriptContext.append("(").append(formNameStr).append(",").append(paramName).append(",").append(value).append(");");
 1223  0
         scriptContext.append("}");
 1224  
 
 1225  0
     }
 1226  
 
 1227  
     /**
 1228  
      * Renders the hidden form input that is necessary for the autoscroll feature.
 1229  
      */
 1230  
     public static void renderAutoScrollHiddenInput(FacesContext facesContext, ResponseWriter writer) throws IOException
 1231  
     {
 1232  0
         writePrettyLineSeparator(facesContext);
 1233  0
         writer.startElement(HTML.INPUT_ELEM, null);
 1234  0
         writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
 1235  0
         writer.writeAttribute(HTML.NAME_ATTR, AUTO_SCROLL_PARAM, null);
 1236  0
         writer.endElement(HTML.INPUT_ELEM);
 1237  0
         writePrettyLineSeparator(facesContext);
 1238  0
     }
 1239  
 
 1240  
     /**
 1241  
      * Renders the autoscroll javascript function.
 1242  
      */
 1243  
     public static void renderAutoScrollFunction(FacesContext facesContext,
 1244  
                                                 ResponseWriter writer) throws IOException
 1245  
     {
 1246  0
         writePrettyLineSeparator(facesContext);
 1247  0
         writer.startElement(HTML.SCRIPT_ELEM,null);
 1248  0
         writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT,null);
 1249  
 
 1250  0
         ScriptContext script = new ScriptContext(
 1251  
                 MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isPrettyHtml());
 1252  
 
 1253  0
         script.prettyLineIncreaseIndent();
 1254  
 
 1255  0
         script.append("function ");
 1256  0
         script.append(AUTO_SCROLL_FUNCTION);
 1257  0
         script.append("()");
 1258  0
         script.append("{");
 1259  0
         script.append("var x = 0; var y = 0;");
 1260  0
         script.append( "if (self.pageXOffset || self.pageYOffset)");
 1261  0
         script.append("{");
 1262  0
         script.append("x = self.pageXOffset;");
 1263  0
         script.prettyLine();
 1264  0
         script.append("y = self.pageYOffset;");
 1265  0
         script.append("}");
 1266  0
         script.append(" else if ((document.documentElement && document.documentElement.scrollLeft)||(document.documentElement && document.documentElement.scrollTop))");
 1267  0
         script.append("{");
 1268  0
         script.append("x = document.documentElement.scrollLeft;");
 1269  0
         script.prettyLine();
 1270  0
         script.append("y = document.documentElement.scrollTop;");
 1271  0
         script.append("}");
 1272  0
         script.append(" else if (document.body) ");
 1273  0
         script.append("{");
 1274  0
         script.append("x = document.body.scrollLeft;");
 1275  0
         script.prettyLine();
 1276  0
         script.append("y = document.body.scrollTop;");
 1277  0
         script.append("}");
 1278  0
         script.append("return x + \",\" + y;");
 1279  0
         script.append("}");
 1280  
 
 1281  0
         ExternalContext externalContext = facesContext.getExternalContext();
 1282  0
         String oldViewId = JavascriptUtils.getOldViewId(externalContext);
 1283  0
         if (oldViewId != null && oldViewId.equals(facesContext.getViewRoot().getViewId()))
 1284  
         {
 1285  
             //ok, we stayed on the same page, so let's scroll it to the former place
 1286  0
             String scrolling = (String)externalContext.getRequestParameterMap().get(AUTO_SCROLL_PARAM);
 1287  0
             if (scrolling != null && scrolling.length() > 0)
 1288  
             {
 1289  0
                 int x = 0;
 1290  0
                 int y = 0;
 1291  0
                 int comma = scrolling.indexOf(',');
 1292  0
                 if (comma == -1)
 1293  
                 {
 1294  0
                     log.warn("Illegal autoscroll request parameter: " + scrolling);
 1295  
                 }
 1296  
                 else
 1297  
                 {
 1298  
                     try {
 1299  
                         //we convert to int against XSS vulnerability
 1300  0
                         x = Integer.parseInt(scrolling.substring(0, comma));
 1301  0
                     } catch (NumberFormatException e) {
 1302  0
                         log.warn("Error getting x offset for autoscroll feature. Bad param value: " + scrolling);
 1303  0
                         x = 0; //ignore false numbers
 1304  0
                     }
 1305  
 
 1306  
                     try {
 1307  
                         //we convert to int against XSS vulnerability
 1308  0
                         y = Integer.parseInt(scrolling.substring(comma + 1));
 1309  0
                     } catch (NumberFormatException e) {
 1310  0
                         log.warn("Error getting y offset for autoscroll feature. Bad param value: " + scrolling);
 1311  0
                         y = 0; //ignore false numbers
 1312  0
                     }
 1313  
                 }
 1314  0
                 script.append("window.scrollTo(").append(x).append(",").append(y).append(");\n");
 1315  
             }
 1316  
         }
 1317  
 
 1318  0
         writer.writeText(script.toString(),null);
 1319  
 
 1320  0
         writer.endElement(HTML.SCRIPT_ELEM);
 1321  0
         writePrettyLineSeparator(facesContext);
 1322  0
     }
 1323  
 
 1324  
     public static boolean isAllowedCdataSection(FacesContext fc) {
 1325  0
         Boolean value = null;
 1326  
 
 1327  0
         if (fc != null) {
 1328  0
             value = (Boolean) fc.getExternalContext().getRequestMap().get(ALLOW_CDATA_SECTION_ON);
 1329  
         }
 1330  
 
 1331  0
         return value != null && ((Boolean) value).booleanValue();
 1332  
     }
 1333  
 
 1334  
     public static void allowCdataSection(FacesContext fc, boolean cdataSectionAllowed)
 1335  
     {
 1336  0
           fc.getExternalContext().getRequestMap().put(ALLOW_CDATA_SECTION_ON,Boolean.valueOf(cdataSectionAllowed));
 1337  0
     }
 1338  
 
 1339  0
     public static class LinkParameter {
 1340  
         private String _name;
 1341  
 
 1342  
         private Object _value;
 1343  
 
 1344  
         public String getName() {
 1345  0
             return _name;
 1346  
         }
 1347  
 
 1348  
         public void setName(String name) {
 1349  0
             _name = name;
 1350  0
         }
 1351  
 
 1352  
         public Object getValue() {
 1353  0
             return _value;
 1354  
         }
 1355  
 
 1356  
         public void setValue(Object value) {
 1357  0
             _value = value;
 1358  0
         }
 1359  
 
 1360  
     }
 1361  
 
 1362  
     public static void renderHiddenCommandFormParams(ResponseWriter writer,
 1363  
                                                      Set dummyFormParams) throws IOException {
 1364  0
         for (Iterator it = dummyFormParams.iterator(); it.hasNext();) {
 1365  0
             Object name = it.next();
 1366  0
             renderHiddenInputField(writer, name, null);
 1367  0
         }
 1368  0
     }
 1369  
 
 1370  
     public static void renderHiddenInputField(ResponseWriter writer, Object name, Object value)
 1371  
             throws IOException
 1372  
     {
 1373  0
         writer.startElement(HTML.INPUT_ELEM, null);
 1374  0
         writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
 1375  0
         writer.writeAttribute(HTML.NAME_ATTR, name, null);
 1376  0
         if(value!=null)
 1377  
         {
 1378  0
             writer.writeAttribute(HTML.VALUE_ATTR,value,null);
 1379  
         }
 1380  0
         writer.endElement(HTML.INPUT_ELEM);
 1381  0
     }
 1382  
 
 1383  
     /**
 1384  
      * @deprecated Replaced by 
 1385  
      * renderLabel(ResponseWriter writer,
 1386  
                                    UIComponent component,
 1387  
                                    String forClientId,
 1388  
                                    SelectItem item,
 1389  
                                    boolean disabled).
 1390  
      * Renders a label HTML element
 1391  
      */
 1392  
     @Deprecated
 1393  
     public static void renderLabel(ResponseWriter writer,
 1394  
                                    UIComponent component,
 1395  
                                    String forClientId,
 1396  
                                    String labelValue,
 1397  
                                    boolean disabled) throws IOException
 1398  
     {
 1399  0
             writer.startElement(HTML.LABEL_ELEM, component);
 1400  0
             writer.writeAttribute(HTML.FOR_ATTR, forClientId, null);
 1401  
 
 1402  0
             String labelClass = null;
 1403  
 
 1404  0
             if (disabled)
 1405  
             {
 1406  0
                 labelClass = (String) component.getAttributes().get(JSFAttr.DISABLED_CLASS_ATTR);
 1407  
             }
 1408  
             else
 1409  
             {
 1410  0
                 labelClass = (String) component.getAttributes().get(org.apache.myfaces.shared_impl.renderkit.JSFAttr.ENABLED_CLASS_ATTR);
 1411  
             }
 1412  0
             if (labelClass != null)
 1413  
             {
 1414  0
                 writer.writeAttribute("class", labelClass, "labelClass");
 1415  
             }
 1416  
 
 1417  0
             if ((labelValue != null) && (labelValue.length() > 0))
 1418  
             {
 1419  0
                 writer.write(HTML.NBSP_ENTITY);
 1420  0
                 writer.writeText(labelValue, null);
 1421  
             }
 1422  
 
 1423  0
             writer.endElement(HTML.LABEL_ELEM);
 1424  0
     }
 1425  
     
 1426  
     /**
 1427  
      * Renders a label HTML element
 1428  
      */
 1429  
     public static void renderLabel(ResponseWriter writer,
 1430  
                                    UIComponent component,
 1431  
                                    String forClientId,
 1432  
                                    SelectItem item,
 1433  
                                    boolean disabled) throws IOException
 1434  
     {
 1435  0
             writer.startElement(HTML.LABEL_ELEM, component);
 1436  0
             writer.writeAttribute(HTML.FOR_ATTR, forClientId, null);
 1437  
 
 1438  0
             String labelClass = null;
 1439  
 
 1440  0
             if (disabled)
 1441  
             {
 1442  0
                 labelClass = (String) component.getAttributes().get(JSFAttr.DISABLED_CLASS_ATTR);
 1443  
             }
 1444  
             else
 1445  
             {
 1446  0
                 labelClass = (String) component.getAttributes().get(org.apache.myfaces.shared_impl.renderkit.JSFAttr.ENABLED_CLASS_ATTR);
 1447  
             }
 1448  0
             if (labelClass != null)
 1449  
             {
 1450  0
                 writer.writeAttribute("class", labelClass, "labelClass");
 1451  
             }
 1452  
 
 1453  0
             if ((item.getLabel() != null) && (item.getLabel().length() > 0))
 1454  
             {
 1455  0
                 writer.write(HTML.NBSP_ENTITY);
 1456  0
                 if(item.isEscape())
 1457  
                 {
 1458  0
                     writer.writeText(item.getLabel(), null);
 1459  
                 }
 1460  
                 else
 1461  
                 {
 1462  0
                     writer.write(item.getLabel());
 1463  
                 }
 1464  
             }
 1465  
 
 1466  0
             writer.endElement(HTML.LABEL_ELEM);
 1467  0
     }
 1468  
 
 1469  
     /**
 1470  
      * Render the javascript function that is called on a click on a commandLink
 1471  
      * to clear the hidden inputs. This is necessary because on a browser back,
 1472  
      * each hidden input still has it's old value (browser cache!) and therefore
 1473  
      * a new submit would cause the according action once more!
 1474  
      *
 1475  
      * @param writer
 1476  
      * @param formName
 1477  
      * @param dummyFormParams
 1478  
      * @param formTarget
 1479  
      * @throws IOException
 1480  
      */
 1481  
     public static void renderClearHiddenCommandFormParamsFunction(
 1482  
             ResponseWriter writer, String formName, Set dummyFormParams,
 1483  
             String formTarget) throws IOException {
 1484  
         //render the clear hidden inputs javascript function
 1485  0
         String functionName = getClearHiddenCommandFormParamsFunctionName(formName);
 1486  0
         writer.startElement(HTML.SCRIPT_ELEM, null);
 1487  0
         writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", null);
 1488  
 
 1489  
         // Using writeComment instead of write with <!-- tag
 1490  0
         StringBuffer script = new StringBuffer();
 1491  0
         script.append("function ");
 1492  0
         script.append(functionName);
 1493  0
         script.append("() {");
 1494  0
         if (dummyFormParams != null) {
 1495  0
             script.append("\n  var f = document.forms['");
 1496  0
             script.append(formName);
 1497  0
             script.append("'];");
 1498  0
             int i=0;
 1499  0
             for (Iterator it = dummyFormParams.iterator(); it.hasNext();) {
 1500  0
                 String elemVarName = "elem"+i;
 1501  0
                 script.append("\n  var ").append(elemVarName).append(" = ");
 1502  0
                 script.append("f.elements['").append((String) it.next()).append("'];");
 1503  0
                 script.append("\n  if(typeof ").append(elemVarName).append(" !='undefined' && ");
 1504  0
                 script.append(elemVarName).append(".nodeName=='INPUT'){");
 1505  0
                 script.append("\n   if (").append(elemVarName).append(".value != '') {");
 1506  0
                 script.append("\n    "+elemVarName+".value='';");
 1507  0
                 script.append("\n   }");
 1508  0
                 script.append("\n  }");
 1509  0
                 i++;
 1510  0
             }
 1511  
         }
 1512  
         // clear form target
 1513  0
         script.append("\n  f.target=");
 1514  0
         if (formTarget == null || formTarget.length() == 0) {
 1515  
             //Normally one would think that setting target to null has the
 1516  
             //desired effect, but once again IE is different...
 1517  
             //Setting target to null causes IE to open a new window!
 1518  0
             script.append("'';");
 1519  
         } else {
 1520  0
             script.append("'");
 1521  0
             script.append(formTarget);
 1522  0
             script.append("';");
 1523  
         }
 1524  0
         script.append("\n}");
 1525  
 
 1526  
         //Just to be sure we call this clear method on each load.
 1527  
         //Otherwise in the case, that someone submits a form by pressing Enter
 1528  
         //within a text input, the hidden inputs won't be cleared!
 1529  0
         script.append("\n");
 1530  0
         script.append(functionName);
 1531  0
         script.append("();");
 1532  
 
 1533  0
         writer.writeText(script.toString(),null);
 1534  0
         writer.endElement(HTML.SCRIPT_ELEM);
 1535  0
     }
 1536  
 
 1537  
     /**
 1538  
      * Prefixes the given String with "clear_" and removes special characters
 1539  
      *
 1540  
      * @param formName
 1541  
      * @return String
 1542  
      */
 1543  
     public static String getClearHiddenCommandFormParamsFunctionName(
 1544  
             String formName)
 1545  
     {
 1546  0
         if (formName == null)
 1547  
         {
 1548  0
             return "'" + CLEAR_HIDDEN_FIELD_FN_NAME
 1549  
                     + "_'+formName.replace(/-/g, '\\$" + NamingContainer.SEPARATOR_CHAR + "').replace(/" + NamingContainer.SEPARATOR_CHAR + "/g,'_')";
 1550  
         }
 1551  
 
 1552  0
         return JavascriptUtils.getValidJavascriptNameAsInRI(CLEAR_HIDDEN_FIELD_FN_NAME
 1553  
                 + "_"
 1554  
                 + formName
 1555  
                 .replace(NamingContainer.SEPARATOR_CHAR, '_'));
 1556  
     }
 1557  
 
 1558  
     public static String getClearHiddenCommandFormParamsFunctionNameMyfacesLegacy(
 1559  
             String formName)
 1560  
     {
 1561  0
         return "clear_"
 1562  
                 + JavascriptUtils.getValidJavascriptName(formName, false);
 1563  
     }
 1564  
 
 1565  
 
 1566  
     /**
 1567  
      * Get the name of the request parameter that holds the id of the
 1568  
      * link-type component that caused the form to be submitted.
 1569  
      * <p/>
 1570  
      * Within each page there may be multiple "link" type components that
 1571  
      * cause page submission. On the server it is necessary to know which
 1572  
      * of these actually caused the submit, in order to invoke the correct
 1573  
      * listeners. Such components therefore store their id into the
 1574  
      * "hidden command link field" in their associated form before
 1575  
      * submitting it.
 1576  
      * <p/>
 1577  
      * The field is always a direct child of each form, and has the same
 1578  
      * <i>name</i> in each form. The id of the form component is therefore
 1579  
      * both necessary and sufficient to determine the full name of the
 1580  
      * field.
 1581  
      */
 1582  
     public static String getHiddenCommandLinkFieldName(FormInfo formInfo) {
 1583  0
         if (RendererUtils.isAdfOrTrinidadForm(formInfo.getForm())) {
 1584  0
             return HIDDEN_COMMANDLINK_FIELD_NAME_TRINIDAD;
 1585  
         }
 1586  0
         return formInfo.getFormName() + NamingContainer.SEPARATOR_CHAR
 1587  
             + HIDDEN_COMMANDLINK_FIELD_NAME;
 1588  
     }
 1589  
 
 1590  
     /**
 1591  
      * 
 1592  
      * @param formInfo
 1593  
      * @deprecated Use getHiddenCommandLinkFieldNameMyfaces(FormInfo) instead
 1594  
      * @return
 1595  
      */
 1596  
     public static String getHiddenCommandLinkFieldNameMyfacesOld(FormInfo formInfo) {
 1597  0
         return formInfo.getFormName() + NamingContainer.SEPARATOR_CHAR
 1598  
             + HIDDEN_COMMANDLINK_FIELD_NAME_MYFACES_OLD;
 1599  
     }
 1600  
 
 1601  
 
 1602  0
     private static String HTML_CONTENT_TYPE = "text/html";
 1603  0
     private static String TEXT_ANY_CONTENT_TYPE = "text/*";
 1604  0
     private static String ANY_CONTENT_TYPE = "*/*";
 1605  
 
 1606  0
     public static String DEFAULT_CHAR_ENCODING = "ISO-8859-1";
 1607  0
     private static String XHTML_CONTENT_TYPE = "application/xhtml+xml";
 1608  0
     private static String APPLICATION_XML_CONTENT_TYPE = "application/xml";
 1609  0
     private static String TEXT_XML_CONTENT_TYPE = "text/xml";
 1610  
 
 1611  
 
 1612  
     public static String selectContentType(String contentTypeListString)
 1613  
     {
 1614  0
         if (contentTypeListString == null)
 1615  
         {
 1616  0
             FacesContext context = FacesContext.getCurrentInstance();
 1617  0
             if(context != null)
 1618  
             {
 1619  0
                 contentTypeListString = (String)
 1620  
                     context.getExternalContext().getRequestHeaderMap().get("Accept");
 1621  
                 
 1622  
                 // There is a windows mobile IE client (6.12) sending
 1623  
                 // "application/vnd.wap.mms-message;*/*"
 1624  
                 // Note that the Accept header should be written as 
 1625  
                 // "application/vnd.wap.mms-message,*/*" ,
 1626  
                 // so this is bug of the client. Anyway, this is a workaround ...
 1627  0
                 if (contentTypeListString != null && 
 1628  
                     contentTypeListString.startsWith("application/vnd.wap.mms-message;*/*"))
 1629  
                 {
 1630  0
                         contentTypeListString = "*/*";
 1631  
                 }
 1632  
             }
 1633  
 
 1634  0
             if(contentTypeListString == null)
 1635  
             {
 1636  0
                 if (log.isDebugEnabled())
 1637  0
                     log.debug("No content type list given, creating HtmlResponseWriterImpl with default content type.");
 1638  
 
 1639  0
                 contentTypeListString = HTML_CONTENT_TYPE;
 1640  
             }
 1641  
         }
 1642  
 
 1643  0
         List contentTypeList = splitContentTypeListString(contentTypeListString);
 1644  0
         String[] supportedContentTypeArray = getSupportedContentTypes();
 1645  
 
 1646  0
         String selectedContentType = null;
 1647  
 
 1648  0
         for (int i = 0; i < supportedContentTypeArray.length; i++)
 1649  
         {
 1650  0
             String supportedContentType = supportedContentTypeArray[i].trim();
 1651  
 
 1652  0
             for (int j = 0; j < contentTypeList.size(); j++)
 1653  
             {
 1654  0
                 String contentType = (String) contentTypeList.get(j);
 1655  
 
 1656  0
                 if (contentType.indexOf(supportedContentType) != -1)
 1657  
                 {
 1658  0
                     if (isHTMLContentType(contentType)) {
 1659  0
                         selectedContentType = HTML_CONTENT_TYPE;
 1660  
                     }
 1661  
 
 1662  0
                     else if (isXHTMLContentType(contentType)) {
 1663  0
                         selectedContentType = XHTML_CONTENT_TYPE;
 1664  
                     }
 1665  
                     break;
 1666  
                 }
 1667  
             }
 1668  0
             if (selectedContentType!=null)
 1669  
             {
 1670  0
                 break;
 1671  
             }
 1672  
         }
 1673  
 
 1674  0
         if(selectedContentType==null)
 1675  
         {
 1676  0
             throw new IllegalArgumentException("ContentTypeList does not contain a supported content type: " +
 1677  
                                                contentTypeListString);
 1678  
         }
 1679  0
         return selectedContentType;
 1680  
     }
 1681  
 
 1682  
     public static String[] getSupportedContentTypes()
 1683  
     {
 1684  0
         String[] supportedContentTypeArray = new String[]{HTML_CONTENT_TYPE,TEXT_ANY_CONTENT_TYPE,ANY_CONTENT_TYPE,
 1685  
                                                           XHTML_CONTENT_TYPE,APPLICATION_XML_CONTENT_TYPE,TEXT_XML_CONTENT_TYPE};
 1686  0
         return supportedContentTypeArray;
 1687  
     }
 1688  
 
 1689  
     private static boolean isHTMLContentType(String contentType)
 1690  
     {
 1691  0
         return contentType.indexOf(HTML_CONTENT_TYPE) != -1 ||
 1692  
             contentType.indexOf(ANY_CONTENT_TYPE) != -1 ||
 1693  
             contentType.indexOf(TEXT_ANY_CONTENT_TYPE) != -1 ;
 1694  
     }
 1695  
 
 1696  
     public static boolean isXHTMLContentType(String contentType)
 1697  
     {
 1698  0
         return contentType.indexOf(XHTML_CONTENT_TYPE) != -1 ||
 1699  
                contentType.indexOf(APPLICATION_XML_CONTENT_TYPE) != -1 ||
 1700  
                contentType.indexOf(TEXT_XML_CONTENT_TYPE) != -1;
 1701  
     }
 1702  
 
 1703  
     private static List splitContentTypeListString(String contentTypeListString)
 1704  
     {
 1705  0
         List contentTypeList = new ArrayList();
 1706  
 
 1707  0
         StringTokenizer st = new StringTokenizer(contentTypeListString, ",");
 1708  0
         while (st.hasMoreTokens())
 1709  
         {
 1710  0
             String contentType = st.nextToken().trim();
 1711  
 
 1712  0
             int semicolonIndex = contentType.indexOf(";");
 1713  
 
 1714  0
             if (semicolonIndex!=-1)
 1715  
             {
 1716  0
                 contentType = contentType.substring(0,semicolonIndex);
 1717  
             }
 1718  
 
 1719  0
             contentTypeList.add(contentType);
 1720  0
         }
 1721  
 
 1722  0
         return contentTypeList;
 1723  
     }
 1724  
 
 1725  
     public static String getJavascriptLocation(UIComponent component)
 1726  
     {
 1727  0
         if(component==null)
 1728  0
             return null;
 1729  
 
 1730  0
         return (String)component.getAttributes().get(JSFAttr.JAVASCRIPT_LOCATION);
 1731  
     }
 1732  
 
 1733  
     public static String getImageLocation(UIComponent component)
 1734  
     {
 1735  0
         if(component==null)
 1736  0
             return null;
 1737  
 
 1738  0
         return (String)component.getAttributes().get(JSFAttr.IMAGE_LOCATION);
 1739  
     }
 1740  
 
 1741  
     public static String getStyleLocation(UIComponent component)
 1742  
     {
 1743  0
         if(component==null)
 1744  0
             return null;
 1745  
 
 1746  0
         return (String)component.getAttributes().get(JSFAttr.STYLE_LOCATION);
 1747  
     }
 1748  
 
 1749  
     public static void renderViewStateJavascript(FacesContext facesContext, String hiddenId, String serializedState) throws IOException {
 1750  0
         ResponseWriter writer = facesContext.getResponseWriter();
 1751  
 
 1752  0
         writer.startElement(HTML.SCRIPT_ELEM, null);
 1753  0
         writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", null);
 1754  
 
 1755  0
         final ExternalContext externalContext = facesContext.getExternalContext();
 1756  0
         final MyfacesConfig currentInstance = MyfacesConfig.getCurrentInstance(externalContext);
 1757  
 
 1758  0
         ScriptContext context = new ScriptContext(currentInstance.isPrettyHtml());
 1759  0
         context.prettyLine();
 1760  0
         context.increaseIndent();
 1761  
 
 1762  0
         context.append("function setViewState() {\n");
 1763  0
         context.append("\tvar state = '");
 1764  0
         context.append(serializedState);
 1765  0
         context.append("';\n");
 1766  0
         context.append("\tfor (var i = 0; i < document.forms.length; i++) {\n");
 1767  0
         context.append("\t\tdocument.forms[i]['" + hiddenId + "'].value = state;\n");
 1768  0
         context.append("\t}\n");
 1769  0
         context.append("}\n");
 1770  0
         context.append("setViewState();\n");
 1771  
 
 1772  0
         context.decreaseIndent();
 1773  
 
 1774  0
         writer.writeText(context.toString(), null);
 1775  
 
 1776  0
         writer.endElement(HTML.SCRIPT_ELEM);
 1777  0
     }
 1778  
     /**
 1779  
      * The ScriptContext offers methods and fields
 1780  
      * to help with rendering out a script and keeping a
 1781  
      * proper formatting.
 1782  
      */
 1783  
     public static class ScriptContext
 1784  
     {
 1785  
         private long currentIndentationLevel;
 1786  0
         private StringBuffer buffer = new StringBuffer();
 1787  0
         private boolean prettyPrint = false;
 1788  
         /**
 1789  
          *  automatic formatting will render
 1790  
          *  new-lines and indents if blocks are opened
 1791  
          *  and closed - attention: you need to append
 1792  
          *  opening and closing brackets of blocks separately in this case!
 1793  
          */
 1794  0
         private boolean automaticFormatting = true;
 1795  
 
 1796  
         public ScriptContext()
 1797  0
         {
 1798  
 
 1799  0
         }
 1800  
 
 1801  
         public ScriptContext(boolean prettyPrint)
 1802  0
         {
 1803  0
             this.prettyPrint = prettyPrint;
 1804  0
         }
 1805  
 
 1806  
         public ScriptContext(StringBuffer buf, boolean prettyPrint)
 1807  0
         {
 1808  0
             this.prettyPrint = prettyPrint;
 1809  0
             this.buffer = buf;
 1810  0
         }
 1811  
 
 1812  
         public void increaseIndent()
 1813  
         {
 1814  0
             currentIndentationLevel++;
 1815  0
         }
 1816  
 
 1817  
         public void decreaseIndent()
 1818  
         {
 1819  0
             currentIndentationLevel--;
 1820  
 
 1821  0
             if(currentIndentationLevel<0)
 1822  0
                 currentIndentationLevel=0;
 1823  0
         }
 1824  
 
 1825  
         public void prettyLine()
 1826  
         {
 1827  0
             if(prettyPrint)
 1828  
             {
 1829  0
                 append(LINE_SEPARATOR);
 1830  
 
 1831  0
                 for(int i=0; i<getCurrentIndentationLevel(); i++)
 1832  0
                     append(TABULATOR);
 1833  
             }
 1834  0
         }
 1835  
 
 1836  
         public void prettyLineIncreaseIndent()
 1837  
         {
 1838  0
             increaseIndent();
 1839  0
             prettyLine();
 1840  0
         }
 1841  
 
 1842  
         public void prettyLineDecreaseIndent()
 1843  
         {
 1844  0
             decreaseIndent();
 1845  0
             prettyLine();
 1846  0
         }
 1847  
 
 1848  
         public long getCurrentIndentationLevel()
 1849  
         {
 1850  0
             return currentIndentationLevel;
 1851  
         }
 1852  
 
 1853  
         public void setCurrentIndentationLevel(long currentIndentationLevel)
 1854  
         {
 1855  0
             this.currentIndentationLevel = currentIndentationLevel;
 1856  0
         }
 1857  
 
 1858  
         public ScriptContext append(String str)
 1859  
         {
 1860  
 
 1861  0
             if(automaticFormatting && str.length()==1)
 1862  
             {
 1863  0
                 boolean openBlock = str.equals("{");
 1864  0
                 boolean closeBlock = str.equals("}");
 1865  
 
 1866  0
                 if(openBlock)
 1867  
                 {
 1868  0
                     prettyLine();
 1869  
                 }
 1870  0
                 else if(closeBlock)
 1871  
                 {
 1872  0
                     prettyLineDecreaseIndent();
 1873  
                 }
 1874  
 
 1875  0
                 buffer.append(str);
 1876  
 
 1877  0
                 if(openBlock)
 1878  
                 {
 1879  0
                     prettyLineIncreaseIndent();
 1880  
                 }
 1881  0
                 else if(closeBlock)
 1882  
                 {
 1883  0
                     prettyLine();
 1884  
                 }
 1885  0
             }
 1886  
             else
 1887  
             {
 1888  0
                 buffer.append(str);
 1889  
             }
 1890  0
             return this;
 1891  
         }
 1892  
 
 1893  
         public ScriptContext append(char c)
 1894  
         {
 1895  0
             buffer.append(c);
 1896  0
             return this;
 1897  
         }
 1898  
 
 1899  
         public ScriptContext append(int i) {
 1900  0
             buffer.append(i);
 1901  0
             return this;
 1902  
         }
 1903  
 
 1904  
         public String toString()
 1905  
         {
 1906  0
             return buffer.toString();
 1907  
         }
 1908  
     }
 1909  
 }