1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.renderkit.html.scarborough.standard.tag;
21
22 import org.apache.myfaces.tobago.component.Attributes;
23 import org.apache.myfaces.tobago.component.Facets;
24 import org.apache.myfaces.tobago.component.UIButton;
25 import org.apache.myfaces.tobago.config.Configurable;
26 import org.apache.myfaces.tobago.context.ResourceManagerUtils;
27 import org.apache.myfaces.tobago.internal.component.AbstractUIForm;
28 import org.apache.myfaces.tobago.internal.util.AccessKeyMap;
29 import org.apache.myfaces.tobago.layout.Measure;
30 import org.apache.myfaces.tobago.renderkit.CommandRendererBase;
31 import org.apache.myfaces.tobago.renderkit.LabelWithAccessKey;
32 import org.apache.myfaces.tobago.renderkit.css.Classes;
33 import org.apache.myfaces.tobago.renderkit.css.Style;
34 import org.apache.myfaces.tobago.renderkit.html.Command;
35 import org.apache.myfaces.tobago.renderkit.html.CommandMap;
36 import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
37 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
38 import org.apache.myfaces.tobago.renderkit.html.HtmlButtonTypes;
39 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
40 import org.apache.myfaces.tobago.renderkit.html.JsonUtils;
41 import org.apache.myfaces.tobago.renderkit.html.Popup;
42 import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
43 import org.apache.myfaces.tobago.renderkit.util.RenderUtils;
44 import org.apache.myfaces.tobago.util.ComponentUtils;
45 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 import javax.faces.component.UIComponent;
50 import javax.faces.component.ValueHolder;
51 import javax.faces.context.FacesContext;
52 import java.io.IOException;
53
54 public class ButtonRenderer extends CommandRendererBase {
55
56 private static final Logger LOG = LoggerFactory.getLogger(ButtonRenderer.class);
57
58 public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
59
60 final UIButton button = (UIButton) component;
61 final String clientId = button.getClientId(facesContext);
62 final boolean disabled = button.isDisabled();
63 final LabelWithAccessKey label = new LabelWithAccessKey(button);
64
65 final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
66
67 writer.startElement(HtmlElements.BUTTON, button);
68 writer.writeAttribute(HtmlAttributes.TYPE, HtmlButtonTypes.BUTTON, false);
69 writer.writeNameAttribute(clientId);
70 writer.writeIdAttribute(clientId);
71 HtmlRendererUtils.writeDataAttributes(facesContext, writer, button);
72 HtmlRendererUtils.renderTip(button, writer);
73 writer.writeAttribute(HtmlAttributes.DISABLED, disabled);
74
75 if (!disabled) {
76 final ValueHolder confirmationFacet = (ValueHolder) component.getFacet(Facets.CONFIRMATION);
77 final String confirmation = confirmationFacet != null ? "" + confirmationFacet.getValue() : null;
78
79 final String url = RenderUtils.generateUrl(facesContext, button);
80 final CommandMap map = new CommandMap();
81 final String[] partialIds
82 = HtmlRendererUtils.getComponentIdsAsList(facesContext, button, button.getRenderedPartially());
83 final Popup popup = Popup.createPopup(button);
84 final Command click = new Command(
85 null, button.isTransition(), button.getTarget(), url, partialIds, null, confirmation, null, popup);
86 if (button.getOnclick() != null) {
87 click.setScript(button.getOnclick());
88 }
89 map.setClick(click);
90 writer.writeAttribute(DataAttributes.COMMANDS, JsonUtils.encode(map), true);
91
92 writer.writeAttribute(HtmlAttributes.HREF, "#", false);
93
94 if (label.getAccessKey() != null) {
95 writer.writeAttribute(HtmlAttributes.ACCESSKEY, Character.toString(label.getAccessKey()), false);
96 }
97
98 final Integer tabIndex = button.getTabIndex();
99 if (tabIndex != null) {
100 writer.writeAttribute(HtmlAttributes.TABINDEX, tabIndex);
101 }
102 }
103
104 Style style = new Style(facesContext, button);
105 writer.writeStyleAttribute(style);
106 HtmlRendererUtils.renderDojoDndItem(component, writer, true);
107 writer.writeClassAttribute(Classes.create(button));
108 if (((UIButton) component).isDefaultCommand()) {
109 final AbstractUIForm form = ComponentUtils.findAncestor(component, AbstractUIForm.class);
110 writer.writeAttribute(DataAttributes.DEFAULT, form.getClientId(facesContext), false);
111 }
112 writer.flush();
113
114 String image = (String) button.getAttributes().get(Attributes.IMAGE);
115 if (image != null) {
116 if (ResourceManagerUtils.isAbsoluteResource(image)) {
117
118 } else {
119 image = getImageWithPath(facesContext, image, disabled);
120 }
121 writer.startElement(HtmlElements.IMG, null);
122 writer.writeAttribute(HtmlAttributes.SRC, image, true);
123 String tip = button.getTip();
124 writer.writeAttribute(HtmlAttributes.ALT, tip != null ? tip : "", true);
125 writer.endElement(HtmlElements.IMG);
126 }
127
128 if (label.getText() != null) {
129 writer.startElement(HtmlElements.SPAN, null);
130 HtmlRendererUtils.writeLabelWithAccessKey(writer, label);
131 writer.endElement(HtmlElements.SPAN);
132 }
133
134 writer.endElement(HtmlElements.BUTTON);
135 if (label.getAccessKey() != null) {
136 if (LOG.isInfoEnabled()
137 && !AccessKeyMap.addAccessKey(facesContext, label.getAccessKey())) {
138 LOG.info("duplicated accessKey : " + label.getAccessKey());
139 }
140 HtmlRendererUtils.addClickAcceleratorKey(
141 facesContext, button.getClientId(facesContext), label.getAccessKey());
142 }
143 }
144
145 @Override
146 public Measure getPreferredWidth(FacesContext facesContext, Configurable component) {
147
148 UIButton button = (UIButton) component;
149 Measure width = Measure.ZERO;
150 boolean image = button.getImage() != null;
151 if (image) {
152 width = getResourceManager().getThemeMeasure(facesContext, button, "imageWidth");
153 }
154 LabelWithAccessKey label = new LabelWithAccessKey(button);
155
156 width = width.add(RenderUtils.calculateStringWidth(facesContext, button, label.getText()));
157 Measure padding = getResourceManager().getThemeMeasure(facesContext, button, "paddingWidth");
158
159 width = width.add(padding.multiply(image && label.getText() != null ? 3 : 2));
160
161 return width;
162 }
163 }