001 package org.apache.myfaces.tobago.renderkit.html; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more 005 * contributor license agreements. See the NOTICE file distributed with 006 * this work for additional information regarding copyright ownership. 007 * The ASF licenses this file to You under the Apache License, Version 2.0 008 * (the "License"); you may not use this file except in compliance with 009 * the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 import org.apache.commons.lang.StringUtils; 021 import org.apache.commons.logging.Log; 022 import org.apache.commons.logging.LogFactory; 023 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_FOCUS; 024 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_INLINE; 025 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_INNER_HEIGHT; 026 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_INNER_WIDTH; 027 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LAYOUT_HEIGHT; 028 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_LAYOUT_WIDTH; 029 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE; 030 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE_BODY; 031 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE_HEADER; 032 import static org.apache.myfaces.tobago.TobagoConstants.ATTR_TIP; 033 import static org.apache.myfaces.tobago.TobagoConstants.FACET_LAYOUT; 034 import static org.apache.myfaces.tobago.TobagoConstants.RENDERER_TYPE_OUT; 035 import org.apache.myfaces.tobago.component.ComponentUtil; 036 import org.apache.myfaces.tobago.component.SupportsMarkup; 037 import org.apache.myfaces.tobago.component.UICommand; 038 import org.apache.myfaces.tobago.component.UIData; 039 import org.apache.myfaces.tobago.component.UIPage; 040 import org.apache.myfaces.tobago.context.ResourceManagerUtil; 041 import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey; 042 import org.apache.myfaces.tobago.renderkit.LayoutInformationProvider; 043 import org.apache.myfaces.tobago.renderkit.LayoutableRendererBase; 044 import org.apache.myfaces.tobago.renderkit.RenderUtil; 045 import org.apache.myfaces.tobago.renderkit.RendererBaseWrapper; 046 import org.apache.myfaces.tobago.util.LayoutUtil; 047 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter; 048 import org.apache.myfaces.tobago.webapp.TobagoResponseWriterWrapper; 049 050 import javax.faces.component.NamingContainer; 051 import javax.faces.component.UIComponent; 052 import javax.faces.component.UIInput; 053 import javax.faces.context.FacesContext; 054 import javax.faces.context.ResponseWriter; 055 import javax.faces.model.SelectItem; 056 import javax.faces.model.SelectItemGroup; 057 import java.io.IOException; 058 import java.util.Arrays; 059 import java.util.List; 060 import java.util.Locale; 061 import java.util.Map; 062 import java.util.StringTokenizer; 063 064 /* 065 * User: weber 066 * Date: Jan 11, 2005 067 * Time: 4:59:36 PM 068 */ 069 public final class HtmlRendererUtil { 070 071 private static final Log LOG = LogFactory.getLog(HtmlRendererUtil.class); 072 073 private HtmlRendererUtil() { 074 // to prevent instantiation 075 } 076 077 public static void renderFocusId(FacesContext facesContext, UIComponent component) 078 throws IOException { 079 080 if (ComponentUtil.getBooleanAttribute(component, ATTR_FOCUS)) { 081 UIPage page = ComponentUtil.findPage(facesContext, component); 082 String id = component.getClientId(facesContext); 083 if (!StringUtils.isBlank(page.getFocusId()) && !page.getFocusId().equals(id)) { 084 LOG.warn("page focusId = \"" + page.getFocusId() + "\" ignoring new value \"" 085 + id + "\""); 086 } else { 087 TobagoResponseWriter writer = HtmlRendererUtil.getTobagoResponseWriter(facesContext); 088 writer.writeJavascript("Tobago.focusId = '" + id + "';"); 089 } 090 } 091 } 092 093 public static void prepareRender(FacesContext facesContext, UIComponent component) { 094 // xxx find a better way for this question: isTobago or isLayoutable something like that. 095 LayoutableRendererBase layoutRendererBase = ComponentUtil.getRenderer(facesContext, component); 096 if (layoutRendererBase != null && !(layoutRendererBase instanceof RendererBaseWrapper)) { 097 createCssClass(facesContext, component); 098 layoutWidth(facesContext, component); 099 layoutHeight(facesContext, component); 100 } 101 } 102 103 public static HtmlStyleMap prepareInnerStyle(UIComponent component) { 104 HtmlStyleMap htmlStyleMap = new HtmlStyleMap(); 105 Integer innerSpaceInteger = (Integer) 106 component.getAttributes().get(ATTR_INNER_WIDTH); 107 if (innerSpaceInteger != null && innerSpaceInteger != -1) { 108 htmlStyleMap.put("width", innerSpaceInteger); 109 } 110 innerSpaceInteger = (Integer) 111 component.getAttributes().get(ATTR_INNER_HEIGHT); 112 if (innerSpaceInteger != null && innerSpaceInteger != -1) { 113 htmlStyleMap.put("height", innerSpaceInteger); 114 } 115 return htmlStyleMap; 116 } 117 118 119 public static void createCssClass(FacesContext facesContext, UIComponent component) { 120 String rendererName = getRendererName(facesContext, component); 121 if (rendererName != null) { 122 StyleClasses classes = StyleClasses.ensureStyleClasses(component); 123 classes.updateClassAttributeAndMarkup(component, rendererName); 124 } 125 } 126 127 public static String getRendererName(FacesContext facesContext, UIComponent component) { 128 final String rendererType = component.getRendererType(); 129 //final String family = component.getFamily(); 130 if (rendererType != null//&& !"facelets".equals(family) 131 ) { 132 LayoutableRendererBase layoutableRendererBase = ComponentUtil.getRenderer(facesContext, component); 133 if (layoutableRendererBase != null) { 134 return layoutableRendererBase.getRendererName(rendererType); 135 } 136 } 137 return null; 138 } 139 140 public static void writeLabelWithAccessKey(TobagoResponseWriter writer, LabelWithAccessKey label) 141 throws IOException { 142 int pos = label.getPos(); 143 String text = label.getText(); 144 if (pos == -1) { 145 writer.writeText(text); 146 } else { 147 writer.writeText(text.substring(0, pos)); 148 writer.startElement(HtmlConstants.U, null); 149 writer.writeText(Character.toString(text.charAt(pos))); 150 writer.endElement(HtmlConstants.U); 151 writer.writeText(text.substring(pos + 1)); 152 } 153 } 154 155 public static void setDefaultTransition(FacesContext facesContext, boolean transition) 156 throws IOException { 157 writeScriptLoader(facesContext, null, new String[]{"Tobago.transition = " + transition + ";"}); 158 } 159 160 public static void addClickAcceleratorKey( 161 FacesContext facesContext, String clientId, char key) 162 throws IOException { 163 addClickAcceleratorKey(facesContext, clientId, key, null); 164 } 165 166 public static void addClickAcceleratorKey( 167 FacesContext facesContext, String clientId, char key, String modifier) 168 throws IOException { 169 String str 170 = createOnclickAcceleratorKeyJsStatement(clientId, key, modifier); 171 writeScriptLoader(facesContext, null, new String[]{str}); 172 } 173 174 public static void addAcceleratorKey( 175 FacesContext facesContext, String func, char key) throws IOException { 176 addAcceleratorKey(facesContext, func, key, null); 177 } 178 179 public static void addAcceleratorKey( 180 FacesContext facesContext, String func, char key, String modifier) 181 throws IOException { 182 String str = createAcceleratorKeyJsStatement(func, key, modifier); 183 writeScriptLoader(facesContext, null, new String[]{str}); 184 } 185 186 public static String createOnclickAcceleratorKeyJsStatement( 187 String clientId, char key, String modifier) { 188 String func = "Tobago.clickOnElement('" + clientId + "');"; 189 return createAcceleratorKeyJsStatement(func, key, modifier); 190 } 191 192 public static String createAcceleratorKeyJsStatement( 193 String func, char key, String modifier) { 194 StringBuilder buffer = new StringBuilder(); 195 buffer.append("new Tobago.AcceleratorKey(function() {"); 196 buffer.append(func); 197 if (!func.endsWith(";")) { 198 buffer.append(';'); 199 } 200 buffer.append("}, \""); 201 buffer.append(key); 202 if (modifier != null) { 203 buffer.append("\", \""); 204 buffer.append(modifier); 205 } 206 buffer.append("\");"); 207 return buffer.toString(); 208 } 209 210 public static String getLayoutSpaceStyle(UIComponent component) { 211 StringBuilder sb = new StringBuilder(); 212 Integer space = LayoutUtil.getLayoutSpace(component, ATTR_LAYOUT_WIDTH, ATTR_LAYOUT_WIDTH); 213 if (space != null) { 214 sb.append(" width: "); 215 sb.append(space); 216 sb.append("px;"); 217 } 218 space = LayoutUtil.getLayoutSpace(component, ATTR_LAYOUT_HEIGHT, ATTR_LAYOUT_HEIGHT); 219 if (space != null) { 220 sb.append(" height: "); 221 sb.append(space); 222 sb.append("px;"); 223 } 224 return sb.toString(); 225 } 226 227 public static Integer getStyleAttributeIntValue(HtmlStyleMap style, String name) { 228 if (style == null) { 229 return null; 230 } 231 return style.getInt(name); 232 } 233 234 public static String getStyleAttributeValue(String style, String name) { 235 if (style == null) { 236 return null; 237 } 238 String value = null; 239 StringTokenizer st = new StringTokenizer(style, ";"); 240 while (st.hasMoreTokens()) { 241 String attribute = st.nextToken().trim(); 242 if (attribute.startsWith(name)) { 243 value = attribute.substring(attribute.indexOf(':') + 1).trim(); 244 } 245 } 246 return value; 247 } 248 249 250 public static void replaceStyleAttribute(UIComponent component, String styleAttribute, String value) { 251 HtmlStyleMap style = ensureStyleAttributeMap(component); 252 style.put(styleAttribute, value); 253 } 254 255 public static void replaceStyleAttribute(UIComponent component, String attribute, 256 String styleAttribute, String value) { 257 HtmlStyleMap style = ensureStyleAttributeMap(component, attribute); 258 style.put(styleAttribute, value); 259 } 260 261 public static void replaceStyleAttribute(UIComponent component, String styleAttribute, int value) { 262 HtmlStyleMap style = ensureStyleAttributeMap(component); 263 style.put(styleAttribute, value); 264 } 265 266 public static void replaceStyleAttribute(UIComponent component, String attribute, 267 String styleAttribute, int value) { 268 HtmlStyleMap style = ensureStyleAttributeMap(component, attribute); 269 style.put(styleAttribute, value); 270 271 } 272 273 private static HtmlStyleMap ensureStyleAttributeMap(UIComponent component) { 274 return ensureStyleAttributeMap(component, ATTR_STYLE); 275 } 276 277 private static HtmlStyleMap ensureStyleAttributeMap(UIComponent component, String attribute) { 278 final Map attributes = component.getAttributes(); 279 HtmlStyleMap style = (HtmlStyleMap) attributes.get(attribute); 280 if (style == null) { 281 style = new HtmlStyleMap(); 282 attributes.put(attribute, style); 283 } 284 return style; 285 } 286 287 /** 288 * @deprecated 289 */ 290 public static String replaceStyleAttribute(String style, String name, 291 String value) { 292 style = removeStyleAttribute(style != null ? style : "", name); 293 return style + " " + name + ": " + value + ";"; 294 } 295 296 /** 297 * @deprecated 298 */ 299 public static String removeStyleAttribute(String style, String name) { 300 if (style == null) { 301 return null; 302 } 303 String pattern = name + "\\s*?:[^;]*?;"; 304 return style.replaceAll(pattern, "").trim(); 305 } 306 307 public static void removeStyleAttribute(UIComponent component, String name) { 308 ensureStyleAttributeMap(component).remove(name); 309 } 310 311 /** 312 * @deprecated Please use StyleClasses.ensureStyleClasses(component).add(clazz); 313 */ 314 @Deprecated 315 public static void addCssClass(UIComponent component, String clazz) { 316 StyleClasses.ensureStyleClasses(component).addFullQualifiedClass(clazz); 317 } 318 319 public static void layoutWidth(FacesContext facesContext, UIComponent component) { 320 layoutSpace(facesContext, component, true); 321 } 322 323 public static void layoutHeight(FacesContext facesContext, UIComponent component) { 324 layoutSpace(facesContext, component, false); 325 } 326 327 public static void layoutSpace(FacesContext facesContext, UIComponent component, 328 boolean width) { 329 330 // prepare html 'style' attribute 331 Integer layoutSpace; 332 String layoutAttribute; 333 String styleAttribute; 334 if (width) { 335 layoutSpace = LayoutUtil.getLayoutWidth(component); 336 layoutAttribute = ATTR_LAYOUT_WIDTH; 337 styleAttribute = HtmlAttributes.WIDTH; 338 } else { 339 layoutSpace = LayoutUtil.getLayoutHeight(component); 340 layoutAttribute = ATTR_LAYOUT_HEIGHT; 341 styleAttribute = HtmlAttributes.HEIGHT; 342 } 343 int space = -1; 344 if (layoutSpace != null) { 345 space = layoutSpace.intValue(); 346 } 347 if (space == -1 && (!RENDERER_TYPE_OUT.equals(component.getRendererType()))) { 348 UIComponent parent = component.getParent(); 349 space = LayoutUtil.getInnerSpace(facesContext, parent, width); 350 if (space > 0 && !ComponentUtil.isFacetOf(component, parent)) { 351 component.getAttributes().put(layoutAttribute, Integer.valueOf(space)); 352 if (width) { 353 component.getAttributes().remove(ATTR_INNER_WIDTH); 354 } else { 355 component.getAttributes().remove(ATTR_INNER_HEIGHT); 356 } 357 } 358 } 359 if (space > 0) { 360 LayoutInformationProvider renderer = ComponentUtil.getRenderer(facesContext, component); 361 if (layoutSpace != null 362 || !ComponentUtil.getBooleanAttribute(component, ATTR_INLINE)) { 363 int styleSpace = space; 364 if (renderer != null) { 365 if (width) { 366 styleSpace -= renderer.getComponentExtraWidth(facesContext, component); 367 } else { 368 styleSpace -= renderer.getComponentExtraHeight(facesContext, component); 369 } 370 } 371 372 replaceStyleAttribute(component, styleAttribute, styleSpace); 373 374 } 375 UIComponent layout = component.getFacet(FACET_LAYOUT); 376 if (layout != null) { 377 int layoutSpace2 = LayoutUtil.getInnerSpace(facesContext, component, 378 width); 379 if (layoutSpace2 > 0) { 380 layout.getAttributes().put(layoutAttribute, Integer.valueOf(layoutSpace2)); 381 } 382 } 383 } 384 } 385 386 public static void createHeaderAndBodyStyles(FacesContext facesContext, UIComponent component) { 387 createHeaderAndBodyStyles(facesContext, component, true); 388 createHeaderAndBodyStyles(facesContext, component, false); 389 } 390 391 public static void createHeaderAndBodyStyles(FacesContext facesContext, UIComponent component, boolean width) { 392 LayoutInformationProvider renderer = ComponentUtil.getRenderer(facesContext, component); 393 HtmlStyleMap style = (HtmlStyleMap) component.getAttributes().get(ATTR_STYLE); 394 Integer styleSpace = null; 395 try { 396 styleSpace = style.getInt(width ? "width" : "height"); 397 } catch (Exception e) { 398 /* ignore */ 399 } 400 if (styleSpace != null) { 401 int bodySpace = 0; 402 int headerSpace = 0; 403 if (!width) { 404 if (renderer != null) { 405 headerSpace = renderer.getHeaderHeight(facesContext, component); 406 } 407 bodySpace = styleSpace - headerSpace; 408 } 409 HtmlStyleMap headerStyle = ensureStyleAttributeMap(component, ATTR_STYLE_HEADER); 410 HtmlStyleMap bodyStyle = ensureStyleAttributeMap(component, ATTR_STYLE_BODY); 411 if (width) { 412 headerStyle.put("width", styleSpace); 413 bodyStyle.put("width", styleSpace); 414 } else { 415 headerStyle.put("height", headerSpace); 416 bodyStyle.put("height", bodySpace); 417 } 418 } 419 } 420 421 /** 422 * @deprecated Please use StyleClasses.ensureStyleClasses(component).updateClassAttribute(renderer, component); 423 */ 424 @Deprecated 425 public static void updateClassAttribute(String cssClass, String rendererName, UIComponent component) { 426 throw new UnsupportedOperationException( 427 "Please use StyleClasses.ensureStyleClasses(component).updateClassAttribute(renderer, component)"); 428 } 429 430 /** 431 * @deprecated Please use StyleClasses.addMarkupClass() 432 */ 433 @Deprecated 434 public static void addMarkupClass(UIComponent component, String rendererName, 435 String subComponent, StringBuilder tobagoClass) { 436 throw new UnsupportedOperationException("Please use StyleClasses.addMarkupClass()"); 437 } 438 439 /** 440 * @deprecated Please use StyleClasses.addMarkupClass() 441 */ 442 @Deprecated 443 public static void addMarkupClass(UIComponent component, String rendererName, StyleClasses classes) { 444 classes.addMarkupClass(component, rendererName); 445 } 446 447 public static void addImageSources(FacesContext facesContext, TobagoResponseWriter writer, String src, String id) 448 throws IOException { 449 StringBuilder buffer = new StringBuilder(); 450 buffer.append("new Tobago.Image('"); 451 buffer.append(id); 452 buffer.append("','"); 453 buffer.append(ResourceManagerUtil.getImageWithPath(facesContext, src, false)); 454 buffer.append("','"); 455 buffer.append(ResourceManagerUtil.getImageWithPath(facesContext, createSrc(src, "Disabled"), true)); 456 buffer.append("','"); 457 buffer.append(ResourceManagerUtil.getImageWithPath(facesContext, createSrc(src, "Hover"), true)); 458 buffer.append("');"); 459 writer.writeJavascript(buffer.toString()); 460 } 461 462 public static String createSrc(String src, String ext) { 463 int dot = src.lastIndexOf('.'); 464 if (dot == -1) { 465 LOG.warn("Image src without extension: '" + src + "'"); 466 return src; 467 } else { 468 return src.substring(0, dot) + ext + src.substring(dot); 469 } 470 } 471 472 public static TobagoResponseWriter getTobagoResponseWriter(FacesContext facesContext) { 473 474 ResponseWriter writer = facesContext.getResponseWriter(); 475 if (writer instanceof TobagoResponseWriter) { 476 return (TobagoResponseWriter) writer; 477 } else { 478 return new TobagoResponseWriterWrapper(writer); 479 } 480 } 481 482 /** 483 * @deprecated use TobagoResponseWriter.writeJavascript() 484 */ 485 @Deprecated 486 public static void writeJavascript(ResponseWriter writer, String script) throws IOException { 487 startJavascript(writer); 488 writer.write(script); 489 endJavascript(writer); 490 } 491 492 /** 493 * @deprecated use TobagoResponseWriter.writeJavascript() 494 */ 495 @Deprecated 496 public static void startJavascript(ResponseWriter writer) throws IOException { 497 writer.startElement(HtmlConstants.SCRIPT, null); 498 writer.writeAttribute(HtmlAttributes.TYPE, "text/javascript", null); 499 writer.write("\n<!--\n"); 500 } 501 502 /** 503 * @deprecated use TobagoResponseWriter.writeJavascript() 504 */ 505 @Deprecated 506 public static void endJavascript(ResponseWriter writer) throws IOException { 507 writer.write("\n// -->\n"); 508 writer.endElement(HtmlConstants.SCRIPT); 509 } 510 511 public static void writeScriptLoader(FacesContext facesContext, String script) 512 throws IOException { 513 writeScriptLoader(facesContext, new String[]{script}, null); 514 } 515 516 public static void writeScriptLoader(FacesContext facesContext, String[] scripts, String[] afterLoadCmds) 517 throws IOException { 518 TobagoResponseWriter writer = HtmlRendererUtil.getTobagoResponseWriter(facesContext); 519 520 String allScripts = "[]"; 521 if (scripts != null) { 522 allScripts = ResourceManagerUtil.getScriptsAsJSArray(facesContext, scripts); 523 } 524 525 StringBuilder script = new StringBuilder(); 526 script.append("new Tobago.ScriptLoader(\n "); 527 script.append(allScripts); 528 529 if (afterLoadCmds != null && afterLoadCmds.length > 0) { 530 script.append(", \n"); 531 boolean first = true; 532 for (String afterLoadCmd : afterLoadCmds) { 533 String[] splittedStrings = StringUtils.split(afterLoadCmd, '\n'); // split on <CR> to have nicer JS 534 for (String splitted : splittedStrings) { 535 String cmd = StringUtils.replace(splitted, "\\", "\\\\"); 536 cmd = StringUtils.replace(cmd, "\"", "\\\""); 537 script.append(first ? " " : " + "); 538 script.append("\""); 539 script.append(cmd); 540 script.append("\"\n"); 541 first = false; 542 } 543 } 544 } 545 script.append(");"); 546 547 writer.writeJavascript(script.toString()); 548 } 549 550 public static void writeStyleLoader( 551 FacesContext facesContext, String[] styles) throws IOException { 552 TobagoResponseWriter writer = HtmlRendererUtil.getTobagoResponseWriter(facesContext); 553 554 StringBuilder builder = new StringBuilder(); 555 builder.append("Tobago.ensureStyleFiles(\n "); 556 builder.append(ResourceManagerUtil.getStylesAsJSArray(facesContext, styles)); 557 builder.append(");"); 558 writer.writeJavascript(builder.toString()); 559 } 560 561 public static String getTitleFromTipAndMessages(FacesContext facesContext, UIComponent component) { 562 String messages = ComponentUtil.getFacesMessageAsString(facesContext, component); 563 return HtmlRendererUtil.addTip(messages, component.getAttributes().get(ATTR_TIP)); 564 } 565 566 public static String addTip(String title, Object tip) { 567 if (tip != null) { 568 if (title != null && title.length() > 0) { 569 title += " :: "; 570 } else { 571 title = ""; 572 } 573 title += tip; 574 } 575 return title; 576 } 577 578 public static void renderSelectItems(UIInput component, List<SelectItem> items, Object[] values, 579 TobagoResponseWriter writer, FacesContext facesContext) throws IOException { 580 581 if (LOG.isDebugEnabled()) { 582 LOG.debug("value = '" + Arrays.toString(values) + "'"); 583 } 584 for (SelectItem item : items) { 585 if (item instanceof SelectItemGroup) { 586 writer.startElement(HtmlConstants.OPTGROUP, null); 587 writer.writeAttribute(HtmlAttributes.LABEL, item.getLabel(), true); 588 if (item.isDisabled()) { 589 writer.writeAttribute(HtmlAttributes.DISABLED, true); 590 } 591 SelectItem[] selectItems = ((SelectItemGroup) item).getSelectItems(); 592 renderSelectItems(component, Arrays.asList(selectItems), values, writer, facesContext); 593 writer.endElement(HtmlConstants.OPTGROUP); 594 } else { 595 writer.startElement(HtmlConstants.OPTION, null); 596 final Object itemValue = item.getValue(); 597 String formattedValue = RenderUtil.getFormattedValue(facesContext, component, itemValue); 598 writer.writeAttribute(HtmlAttributes.VALUE, formattedValue, true); 599 if (item instanceof org.apache.myfaces.tobago.model.SelectItem) { 600 String image = ((org.apache.myfaces.tobago.model.SelectItem) item).getImage(); 601 if (image != null) { 602 String imagePath = ResourceManagerUtil.getImageWithPath(facesContext, image); 603 writer.writeStyleAttribute("background-image: url('" + imagePath + "')"); 604 } 605 } 606 if (item instanceof SupportsMarkup) { 607 StyleClasses optionStyle = new StyleClasses(); 608 optionStyle.addMarkupClass((SupportsMarkup) item, getRendererName(facesContext, component), "option"); 609 writer.writeClassAttribute(optionStyle); 610 } 611 if (RenderUtil.contains(values, item.getValue())) { 612 writer.writeAttribute(HtmlAttributes.SELECTED, true); 613 } 614 if (item.isDisabled()) { 615 writer.writeAttribute(HtmlAttributes.DISABLED, true); 616 } 617 writer.writeText(item.getLabel()); 618 writer.endElement(HtmlConstants.OPTION); 619 } 620 } 621 } 622 623 public static String getComponentId(FacesContext context, UIComponent component, String componentId) { 624 UIComponent partiallyComponent = ComponentUtil.findComponent(component, componentId); 625 if (partiallyComponent != null) { 626 String clientId = partiallyComponent.getClientId(context); 627 if (partiallyComponent instanceof UIData) { 628 int rowIndex = ((UIData) partiallyComponent).getRowIndex(); 629 if (rowIndex >= 0 && clientId.endsWith(Integer.toString(rowIndex))) { 630 return clientId.substring(0, clientId.lastIndexOf(NamingContainer.SEPARATOR_CHAR)); 631 } 632 } 633 return clientId; 634 } 635 LOG.error("No Component found for id " + componentId + " search base component " + component.getClientId(context)); 636 return null; 637 } 638 639 public static String toStyleString(String key, Integer value) { 640 StringBuilder buf = new StringBuilder(); 641 buf.append(key); 642 buf.append(":"); 643 buf.append(value); 644 buf.append("px; "); 645 return buf.toString(); 646 } 647 648 public static String toStyleString(String key, String value) { 649 StringBuilder buf = new StringBuilder(); 650 buf.append(key); 651 buf.append(":"); 652 buf.append(value); 653 buf.append("; "); 654 return buf.toString(); 655 } 656 657 public static void renderTip(UIComponent component, TobagoResponseWriter writer) throws IOException { 658 Object objTip = component.getAttributes().get(ATTR_TIP); 659 if (objTip != null) { 660 writer.writeAttribute(HtmlAttributes.TITLE, String.valueOf(objTip), true); 661 } 662 } 663 664 public static void renderImageTip(UIComponent component, TobagoResponseWriter writer) throws IOException { 665 Object objTip = component.getAttributes().get(ATTR_TIP); 666 if (objTip != null) { 667 writer.writeAttribute(HtmlAttributes.ALT, String.valueOf(objTip), true); 668 } else { 669 writer.writeAttribute(HtmlAttributes.ALT, "", false); 670 } 671 } 672 673 public static String getJavascriptString(String str) { 674 if (str != null) { 675 return "\"" + str + "\""; 676 } 677 return null; 678 } 679 680 public static String getRenderedPartiallyJavascriptArray(FacesContext facesContext, UICommand command) { 681 if (command == null) { 682 return null; 683 } 684 String[] list = command.getRenderedPartially(); 685 StringBuilder strBuilder = new StringBuilder(); 686 strBuilder.append("["); 687 for (int i = 0; i < list.length; i++) { 688 if (i != 0) { 689 strBuilder.append(","); 690 } 691 strBuilder.append("\""); 692 strBuilder.append(HtmlRendererUtil.getComponentId(facesContext, command, list[i])); 693 strBuilder.append("\""); 694 } 695 strBuilder.append("]"); 696 return strBuilder.toString(); 697 } 698 699 public static String getJavascriptArray(String[] list) { 700 StringBuilder strBuilder = new StringBuilder(); 701 strBuilder.append("["); 702 for (int i = 0; i < list.length; i++) { 703 if (i != 0) { 704 strBuilder.append(","); 705 } 706 strBuilder.append("\""); 707 strBuilder.append(list[i]); 708 strBuilder.append("\""); 709 } 710 strBuilder.append("]"); 711 return strBuilder.toString(); 712 } 713 714 public static void removeStyleClasses(UIComponent cell) { 715 Object obj = cell.getAttributes().get(org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE_CLASS); 716 if (obj != null && obj instanceof StyleClasses && cell.getRendererType() != null) { 717 StyleClasses styleClasses = (StyleClasses) obj; 718 if (!styleClasses.isEmpty()) { 719 String rendererName = cell.getRendererType().substring(0, 1).toLowerCase(Locale.ENGLISH) 720 + cell.getRendererType().substring(1); 721 styleClasses.removeTobagoClasses(rendererName); 722 } 723 if (styleClasses.isEmpty()) { 724 cell.getAttributes().remove(org.apache.myfaces.tobago.TobagoConstants.ATTR_STYLE_CLASS); 725 } 726 } 727 } 728 }