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