1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.renderkit.html;
20
21 import java.io.IOException;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.logging.Level;
25 import java.util.logging.Logger;
26
27 import javax.faces.component.UIComponent;
28 import javax.faces.component.UIInput;
29 import javax.faces.component.UIOutput;
30 import javax.faces.component.UIViewRoot;
31 import javax.faces.component.behavior.ClientBehavior;
32 import javax.faces.component.behavior.ClientBehaviorHolder;
33 import javax.faces.component.html.HtmlInputText;
34 import javax.faces.component.html.HtmlOutputText;
35 import javax.faces.context.FacesContext;
36 import javax.faces.context.ResponseWriter;
37 import javax.faces.convert.ConverterException;
38
39 import org.apache.myfaces.shared.component.EscapeCapable;
40 import org.apache.myfaces.shared.renderkit.JSFAttr;
41 import org.apache.myfaces.shared.renderkit.RendererUtils;
42 import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
43 import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
44
45
46
47
48
49
50 public class HtmlTextRendererBase
51 extends HtmlRenderer
52 {
53
54 private static final Logger log = Logger.getLogger(HtmlTextRendererBase.class.getName());
55
56 private static final String AUTOCOMPLETE_VALUE_OFF = "off";
57
58 public void encodeEnd(FacesContext facesContext, UIComponent component)
59 throws IOException
60 {
61 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext,component,null);
62
63 Map<String, List<ClientBehavior>> behaviors = null;
64 if (component instanceof ClientBehaviorHolder)
65 {
66 behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
67 if (!behaviors.isEmpty())
68 {
69 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
70 }
71 }
72
73 if (component instanceof UIInput)
74 {
75 renderInput(facesContext, component);
76 }
77 else if (component instanceof UIOutput)
78 {
79 renderOutput(facesContext, component);
80 }
81 else
82 {
83 throw new IllegalArgumentException("Unsupported component class " + component.getClass().getName());
84 }
85 }
86
87
88 protected void renderOutput(FacesContext facesContext, UIComponent component)
89 throws IOException
90 {
91
92 String text = org.apache.myfaces.shared.renderkit.RendererUtils.getStringValue(facesContext, component);
93 if (log.isLoggable(Level.FINE))
94 {
95 log.fine("renderOutput '" + text + "'");
96 }
97 boolean escape;
98 if (component instanceof HtmlOutputText || component instanceof EscapeCapable)
99 {
100 escape = ((HtmlOutputText)component).isEscape();
101 }
102 else
103 {
104 escape = RendererUtils.getBooleanAttribute(component,
105 org.apache.myfaces.shared.renderkit.JSFAttr.ESCAPE_ATTR,
106 true);
107 }
108 if (text != null)
109 {
110 ResponseWriter writer = facesContext.getResponseWriter();
111 boolean span = false;
112
113 if (isCommonPropertiesOptimizationEnabled(facesContext))
114 {
115 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(component);
116 if ( (commonPropertiesMarked & ~(CommonPropertyConstants.ESCAPE_PROP)) > 0)
117 {
118 span = true;
119 writer.startElement(HTML.SPAN_ELEM, component);
120 HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
121 }
122 else if (CommonPropertyUtils.isIdRenderingNecessary(component))
123 {
124 span = true;
125 writer.startElement(HTML.SPAN_ELEM, component);
126 writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext), null);
127 }
128
129 CommonPropertyUtils.renderUniversalProperties(writer, commonPropertiesMarked, component);
130 CommonPropertyUtils.renderStyleProperties(writer, commonPropertiesMarked, component);
131
132 if (isRenderOutputEventAttributes())
133 {
134 HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.EVENT_HANDLER_ATTRIBUTES);
135 }
136 }
137 else
138 {
139 if(component.getId()!=null && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
140 {
141 span = true;
142
143 writer.startElement(HTML.SPAN_ELEM, component);
144
145 HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
146
147 HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.COMMON_PASSTROUGH_ATTRIBUTES);
148
149 }
150 else
151 {
152 span = HtmlRendererUtils.renderHTMLAttributesWithOptionalStartElement(writer,component,
153 HTML.SPAN_ELEM,HTML.COMMON_PASSTROUGH_ATTRIBUTES);
154 }
155 }
156
157 if (escape)
158 {
159 if (log.isLoggable(Level.FINE))
160 {
161 log.fine("renderOutputText writing '" + text + "'");
162 }
163 writer.writeText(text, org.apache.myfaces.shared.renderkit.JSFAttr.VALUE_ATTR);
164 }
165 else
166 {
167 writer.write(text);
168 }
169
170 if(span)
171 {
172 writer.endElement(org.apache.myfaces.shared.renderkit.html.HTML.SPAN_ELEM);
173 }
174 }
175 }
176
177 protected boolean isRenderOutputEventAttributes()
178 {
179 return true;
180 }
181
182 protected void renderInput(FacesContext facesContext, UIComponent component)
183 throws IOException
184 {
185
186 renderInputBegin(facesContext, component);
187 renderInputEnd(facesContext, component);
188 }
189
190
191 protected void renderInputBegin(FacesContext facesContext,
192 UIComponent component) throws IOException
193 {
194 ResponseWriter writer = facesContext.getResponseWriter();
195
196 String clientId = component.getClientId(facesContext);
197 String value = org.apache.myfaces.shared.renderkit.RendererUtils.getStringValue(facesContext, component);
198 if (log.isLoggable(Level.FINE))
199 {
200 log.fine("renderInput '" + value + "'");
201 }
202 writer.startElement(HTML.INPUT_ELEM, component);
203 writer.writeAttribute(HTML.ID_ATTR, clientId, null);
204 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
205
206
207 String inputHtmlType = getInputHtmlType(component);
208 writer.writeAttribute(HTML.TYPE_ATTR, inputHtmlType, null);
209
210 if (value != null)
211 {
212 writer.writeAttribute(HTML.VALUE_ATTR, value, JSFAttr.VALUE_ATTR);
213 }
214
215 Map<String, List<ClientBehavior>> behaviors = null;
216 if (component instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(
217 facesContext.getExternalContext()))
218 {
219 behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
220
221 long commonPropertiesMarked = 0L;
222 if (isCommonPropertiesOptimizationEnabled(facesContext))
223 {
224 commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(component);
225 }
226 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
227 {
228 CommonPropertyUtils.renderChangeEventProperty(writer,
229 commonPropertiesMarked, component);
230 CommonPropertyUtils.renderEventProperties(writer,
231 commonPropertiesMarked, component);
232 CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer,
233 commonPropertiesMarked, component);
234 }
235 else
236 {
237 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, component, behaviors);
238 if (isCommonEventsOptimizationEnabled(facesContext))
239 {
240 Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(component);
241 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
242 commonPropertiesMarked, commonEventsMarked, component, behaviors);
243 CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
244 facesContext, writer, commonPropertiesMarked, commonEventsMarked, component, behaviors);
245 }
246 else
247 {
248 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, component, behaviors);
249 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
250 facesContext, writer, component, behaviors);
251 }
252 }
253 if (isCommonPropertiesOptimizationEnabled(facesContext))
254 {
255 CommonPropertyUtils.renderInputPassthroughPropertiesWithoutDisabledAndEvents(writer,
256 commonPropertiesMarked, component);
257 }
258 else
259 {
260 HtmlRendererUtils.renderHTMLAttributes(writer, component,
261 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
262 }
263 }
264 else
265 {
266 if (isCommonPropertiesOptimizationEnabled(facesContext))
267 {
268 CommonPropertyUtils.renderInputPassthroughPropertiesWithoutDisabled(writer,
269 CommonPropertyUtils.getCommonPropertiesMarked(component), component);
270 }
271 else
272 {
273 HtmlRendererUtils.renderHTMLAttributes(writer, component,
274 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
275 }
276 }
277
278 if (isDisabled(facesContext, component))
279 {
280 writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
281 }
282
283 if (isAutocompleteOff(facesContext, component))
284 {
285 writer.writeAttribute(HTML.AUTOCOMPLETE_ATTR, AUTOCOMPLETE_VALUE_OFF, HTML.AUTOCOMPLETE_ATTR);
286 }
287 }
288
289 protected void renderInputEnd(FacesContext facesContext, UIComponent component) throws IOException
290 {
291 ResponseWriter writer = facesContext.getResponseWriter();
292
293 writer.endElement(HTML.INPUT_ELEM);
294 }
295
296 protected boolean isDisabled(FacesContext facesContext, UIComponent component)
297 {
298
299 if (component instanceof HtmlInputText)
300 {
301 return ((HtmlInputText)component).isDisabled();
302 }
303
304 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(component,
305 HTML.DISABLED_ATTR, false);
306
307 }
308
309
310
311
312 protected boolean isAutocompleteOff(FacesContext facesContext, UIComponent component)
313 {
314 if (component instanceof HtmlInputText)
315 {
316 String autocomplete = ((HtmlInputText)component).getAutocomplete();
317 if (autocomplete != null)
318 {
319 return autocomplete.equals(AUTOCOMPLETE_VALUE_OFF);
320 }
321 }
322
323 return false;
324 }
325
326
327 public void decode(FacesContext facesContext, UIComponent component)
328 {
329 RendererUtils.checkParamValidity(facesContext,component,null);
330
331 if (component instanceof UIInput)
332 {
333 HtmlRendererUtils.decodeUIInput(facesContext, component);
334 if (component instanceof ClientBehaviorHolder &&
335 !HtmlRendererUtils.isDisabled(component))
336 {
337 HtmlRendererUtils.decodeClientBehaviors(facesContext, component);
338 }
339 }
340 else if (component instanceof UIOutput)
341 {
342
343 }
344 else
345 {
346 throw new IllegalArgumentException("Unsupported component class " + component.getClass().getName());
347 }
348 }
349
350
351 public Object getConvertedValue(FacesContext facesContext, UIComponent component, Object submittedValue)
352 throws ConverterException
353 {
354 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, UIOutput.class);
355 return RendererUtils.getConvertedUIOutputValue(facesContext,
356 (UIOutput)component,
357 submittedValue);
358 }
359
360
361
362
363 protected String getInputHtmlType(UIComponent component)
364 {
365
366 return HTML.INPUT_TYPE_TEXT;
367 }
368
369 public static void renderOutputText(FacesContext facesContext,
370 UIComponent component, String text, boolean escape)
371 throws IOException
372 {
373 if (text != null)
374 {
375 ResponseWriter writer = facesContext.getResponseWriter();
376 boolean span = false;
377
378 if (component.getId() != null
379 && !component.getId().startsWith(
380 UIViewRoot.UNIQUE_ID_PREFIX))
381 {
382 span = true;
383
384 writer.startElement(HTML.SPAN_ELEM, component);
385
386 HtmlRendererUtils.writeIdIfNecessary(writer, component,
387 facesContext);
388
389 HtmlRendererUtils.renderHTMLAttributes(writer, component,
390 HTML.COMMON_PASSTROUGH_ATTRIBUTES);
391
392 }
393 else
394 {
395 span = HtmlRendererUtils
396 .renderHTMLAttributesWithOptionalStartElement(writer,
397 component, HTML.SPAN_ELEM,
398 HTML.COMMON_PASSTROUGH_ATTRIBUTES);
399 }
400
401 if (escape)
402 {
403 if (log.isLoggable(Level.FINE))
404 {
405 log.fine("renderOutputText writing '" + text + "'");
406 }
407 writer.writeText(text,
408 org.apache.myfaces.shared.renderkit.JSFAttr.VALUE_ATTR);
409 }
410 else
411 {
412 writer.write(text);
413 }
414
415 if (span)
416 {
417 writer.endElement(org.apache.myfaces.shared.renderkit.html.HTML.SPAN_ELEM);
418 }
419 }
420 }
421 }