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.Iterator;
23 import java.util.Map;
24 import java.util.Set;
25 import java.util.logging.Logger;
26
27 import javax.faces.context.ExternalContext;
28 import javax.faces.context.FacesContext;
29 import javax.faces.context.ResponseWriter;
30
31 import org.apache.myfaces.shared.config.MyfacesConfig;
32 import org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils.ScriptContext;
33 import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
34 import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
35
36 public final class HtmlJavaScriptUtils
37 {
38 private static final Logger log = Logger.getLogger(HtmlJavaScriptUtils.class
39 .getName());
40
41 private static final String AUTO_SCROLL_PARAM = "autoScroll";
42 private static final String AUTO_SCROLL_FUNCTION = "getScrolling";
43
44 private static final String SET_HIDDEN_INPUT_FN_NAME = "oamSetHiddenInput";
45 private static final String SET_HIDDEN_INPUT_FN_NAME_JSF2 = "myfaces.oam.setHiddenInput";
46
47 private static final String FIRST_SUBMIT_SCRIPT_ON_PAGE = "org.apache.MyFaces.FIRST_SUBMIT_SCRIPT_ON_PAGE";
48 private static final String CLEAR_HIDDEN_INPUT_FN_NAME = "oamClearHiddenInput";
49
50
51 @SuppressWarnings("unchecked")
52 public static void renderFormSubmitScript(FacesContext facesContext)
53 throws IOException
54 {
55 if (facesContext.getPartialViewContext() != null &&
56 (facesContext.getPartialViewContext().isPartialRequest() ||
57 facesContext.getPartialViewContext().isAjaxRequest() )
58 )
59 {
60 return;
61 }
62
63 Map map = facesContext.getExternalContext().getRequestMap();
64 Boolean firstScript = (Boolean) map.get(FIRST_SUBMIT_SCRIPT_ON_PAGE);
65
66 if (firstScript == null || firstScript.equals(Boolean.TRUE))
67 {
68 map.put(FIRST_SUBMIT_SCRIPT_ON_PAGE, Boolean.FALSE);
69 renderFormSubmitScriptIfNecessary(facesContext);
70
71
72 renderConfigOptionsIfNecessary(facesContext);
73 }
74 }
75
76
77
78
79
80 private static void renderFormSubmitScriptIfNecessary(
81 FacesContext facesContext) throws IOException
82 {
83 ResponseWriter writer = facesContext.getResponseWriter();
84 ResourceUtils
85 .renderMyfacesJSInlineIfNecessary(facesContext, writer);
86 }
87
88 private static void renderConfigOptionsIfNecessary(FacesContext facesContext)
89 throws IOException
90 {
91 ResponseWriter writer = facesContext.getResponseWriter();
92 MyfacesConfig config = MyfacesConfig.getCurrentInstance(facesContext
93 .getExternalContext());
94 ScriptContext script = new ScriptContext();
95 boolean autoScroll = config.isAutoScroll();
96 boolean autoSave = JavascriptUtils.isSaveFormSubmitLinkIE(facesContext
97 .getExternalContext());
98
99 if (autoScroll || autoSave)
100 {
101 script.prettyLine();
102 script.increaseIndent();
103 script.append("(!window.myfaces) ? window.myfaces = {} : null;");
104 script.append("(!myfaces.core) ? myfaces.core = {} : null;");
105 script.append("(!myfaces.core.config) ? myfaces.core.config = {} : null;");
106 }
107
108 if (autoScroll)
109 {
110 script.append("myfaces.core.config.autoScroll = true;");
111 }
112 if (autoSave)
113 {
114 script.append("myfaces.core.config.ieAutoSave = true;");
115 }
116 if (autoScroll || autoSave)
117 {
118 writer.startElement(HTML.SCRIPT_ELEM, null);
119 writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", null);
120 writer.writeText(script.toString(), null);
121 writer.endElement(HTML.SCRIPT_ELEM);
122 }
123 }
124
125 public static void appendAutoScrollAssignment(StringBuilder onClickValue,
126 String formName)
127 {
128 appendAutoScrollAssignment(FacesContext.getCurrentInstance(),
129 new ScriptContext(onClickValue, false), formName);
130 }
131
132
133
134
135
136 public static void appendAutoScrollAssignment(FacesContext context,
137 StringBuilder onClickValue, String formName)
138 {
139 appendAutoScrollAssignment(context, new ScriptContext(onClickValue,
140 false), formName);
141 }
142
143 private static void appendAutoScrollAssignment(FacesContext context,
144 ScriptContext scriptContext, String formName)
145 {
146 String formNameStr = formName == null ? "formName" : (new StringBuilder(
147 "'").append(formName).append("'").toString());
148 String paramName = new StringBuilder().append("'")
149 .append(AUTO_SCROLL_PARAM).append("'").toString();
150 String value = new StringBuilder().append(AUTO_SCROLL_FUNCTION)
151 .append("()").toString();
152
153 scriptContext.prettyLine();
154 scriptContext.append("if(typeof window." + AUTO_SCROLL_FUNCTION
155 + "!='undefined')");
156 scriptContext.append("{");
157 scriptContext.append(SET_HIDDEN_INPUT_FN_NAME_JSF2);
158 scriptContext.append("(").append(formNameStr).append(",")
159 .append(paramName).append(",").append(value).append(");");
160 scriptContext.append("}");
161
162 }
163
164 public static String getAutoScrollFunction(FacesContext facesContext)
165 {
166 ScriptContext script = new ScriptContext();
167
168 script.prettyLineIncreaseIndent();
169
170 script.append("function ");
171 script.append(AUTO_SCROLL_FUNCTION);
172 script.append("()");
173 script.append("{");
174 script.append("var x = 0; var y = 0;");
175 script.append("if (self.pageXOffset || self.pageYOffset)");
176 script.append("{");
177 script.append("x = self.pageXOffset;");
178 script.prettyLine();
179 script.append("y = self.pageYOffset;");
180 script.append("}");
181 script.append(" else if ((document.documentElement && document.documentElement.scrollLeft)||"+
182 "(document.documentElement && document.documentElement.scrollTop))");
183 script.append("{");
184 script.append("x = document.documentElement.scrollLeft;");
185 script.prettyLine();
186 script.append("y = document.documentElement.scrollTop;");
187 script.append("}");
188 script.append(" else if (document.body) ");
189 script.append("{");
190 script.append("x = document.body.scrollLeft;");
191 script.prettyLine();
192 script.append("y = document.body.scrollTop;");
193 script.append("}");
194 script.append("return x + \",\" + y;");
195 script.append("}");
196
197 ExternalContext externalContext = facesContext.getExternalContext();
198 String oldViewId = JavascriptUtils.getOldViewId(externalContext);
199 if (oldViewId != null
200 && oldViewId.equals(facesContext.getViewRoot().getViewId()))
201 {
202
203 String scrolling = (String) externalContext
204 .getRequestParameterMap().get(AUTO_SCROLL_PARAM);
205 if (scrolling != null && scrolling.length() > 0)
206 {
207 double x = 0;
208 double y = 0;
209 int comma = scrolling.indexOf(',');
210 if (comma == -1)
211 {
212 log.warning("Illegal autoscroll request parameter: "
213 + scrolling);
214 }
215 else
216 {
217 try
218 {
219
220 x = Double.parseDouble(scrolling.substring(0, comma));
221 }
222 catch (NumberFormatException e)
223 {
224 log.warning("Error getting x offset for autoscroll feature. Bad param value: "
225 + scrolling);
226 x = 0;
227 }
228
229 try
230 {
231
232 y = Integer.parseInt(scrolling.substring(comma + 1));
233 }
234 catch (NumberFormatException e)
235 {
236 log.warning("Error getting y offset for autoscroll feature. Bad param value: "
237 + scrolling);
238 y = 0;
239 }
240 }
241 script.append("window.scrollTo(").append(String.valueOf(x)).append(",")
242 .append(String.valueOf(y)).append(");\n");
243 }
244 }
245
246 return script.toString();
247 }
248
249
250
251
252 public static void renderAutoScrollHiddenInput(FacesContext facesContext,
253 ResponseWriter writer) throws IOException
254 {
255 writer.startElement(HTML.INPUT_ELEM, null);
256 writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
257 writer.writeAttribute(HTML.NAME_ATTR, AUTO_SCROLL_PARAM, null);
258 writer.endElement(HTML.INPUT_ELEM);
259 }
260
261
262
263
264 public static void renderAutoScrollFunction(FacesContext facesContext,
265 ResponseWriter writer) throws IOException
266 {
267 writer.startElement(HTML.SCRIPT_ELEM, null);
268 writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR,
269 HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
270 writer.writeText(getAutoScrollFunction(facesContext), null);
271 writer.endElement(HTML.SCRIPT_ELEM);
272 }
273
274 public static void appendClearHiddenCommandFormParamsFunctionCall(
275 StringBuilder buf, String formName)
276 {
277 appendClearHiddenCommandFormParamsFunctionCall(new ScriptContext(buf,
278 false), formName);
279 }
280
281 private static void appendClearHiddenCommandFormParamsFunctionCall(
282 ScriptContext context, String formName)
283 {
284 String functionName = HtmlRendererUtils
285 .getClearHiddenCommandFormParamsFunctionName(formName);
286 if (formName == null)
287 {
288 context.prettyLine();
289 context.append("var clearFn = ");
290 context.append(functionName);
291 context.append(";");
292 context.prettyLine();
293 context.append("if(typeof window[clearFn] =='function')");
294 context.append("{");
295 context.append("window[clearFn](formName);");
296 context.append("}");
297 }
298 else
299 {
300 context.prettyLine();
301 context.append("if(typeof window.");
302 context.append(functionName);
303 context.append("=='function')");
304 context.append("{");
305 context.append(functionName).append("('").append(formName)
306 .append("');");
307 context.append("}");
308 }
309 }
310
311
312
313
314
315
316
317 public static String getClearHiddenCommandFormParamsFunctionName(
318 String formName)
319 {
320 final char separatorChar = FacesContext.getCurrentInstance().getNamingContainerSeparatorChar();
321 if (formName == null)
322 {
323 return "'" + HtmlRendererUtils.CLEAR_HIDDEN_FIELD_FN_NAME
324 + "_'+formName.replace(/-/g, '\\$" + separatorChar
325 + "').replace(/" + separatorChar + "/g,'_')";
326 }
327
328 return JavascriptUtils
329 .getValidJavascriptNameAsInRI(HtmlRendererUtils.CLEAR_HIDDEN_FIELD_FN_NAME + "_"
330 + formName.replace(separatorChar, '_'));
331 }
332
333 public static String getClearHiddenCommandFormParamsFunctionNameMyfacesLegacy(
334 String formName)
335 {
336 return "clear_"
337 + JavascriptUtils.getValidJavascriptName(formName, false);
338 }
339
340
341
342
343
344
345
346
347
348
349
350
351
352 public static void renderClearHiddenCommandFormParamsFunction(
353 ResponseWriter writer, String formName, Set dummyFormParams,
354 String formTarget) throws IOException
355 {
356
357 String functionName = getClearHiddenCommandFormParamsFunctionName(formName);
358 writer.startElement(HTML.SCRIPT_ELEM, null);
359 writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", null);
360
361
362 StringBuilder script = new StringBuilder();
363 script.append("function ");
364 script.append(functionName);
365 script.append("() {");
366 if (dummyFormParams != null)
367 {
368 script.append("\n var f = document.forms['");
369 script.append(formName);
370 script.append("'];");
371 int i = 0;
372 for (Iterator it = dummyFormParams.iterator(); it.hasNext();)
373 {
374 String elemVarName = "elem" + i;
375 script.append("\n var ").append(elemVarName).append(" = ");
376 script.append("f.elements['").append((String) it.next())
377 .append("'];");
378 script.append("\n if(typeof ").append(elemVarName)
379 .append(" !='undefined' && ");
380 script.append(elemVarName).append(".nodeName=='INPUT'){");
381 script.append("\n if (").append(elemVarName)
382 .append(".value != '') {");
383 script.append("\n " + elemVarName + ".value='';");
384 script.append("\n }");
385 script.append("\n }");
386 i++;
387 }
388 }
389
390 script.append("\n f.target=");
391 if (formTarget == null || formTarget.length() == 0)
392 {
393
394
395
396 script.append("'';");
397 }
398 else
399 {
400 script.append("'");
401 script.append(formTarget);
402 script.append("';");
403 }
404 script.append("\n}");
405
406
407
408
409 script.append("\n");
410 script.append(functionName);
411 script.append("();");
412
413 writer.writeText(script.toString(), null);
414 writer.endElement(HTML.SCRIPT_ELEM);
415 }
416
417
418
419
420
421
422
423
424
425 public static String escapeJavaScriptForChain(String javaScript)
426 {
427
428
429
430
431
432
433
434
435
436 StringBuilder out = null;
437 for (int pos = 0; pos < javaScript.length(); pos++)
438 {
439 char c = javaScript.charAt(pos);
440
441 if (c == '\\' || c == '\'')
442 {
443 if (out == null)
444 {
445 out = new StringBuilder(javaScript.length() + 8);
446 if (pos > 0)
447 {
448 out.append(javaScript, 0, pos);
449 }
450 }
451 out.append('\\');
452 }
453 if (out != null)
454 {
455 out.append(c);
456 }
457 }
458
459 if (out == null)
460 {
461 return javaScript;
462 }
463 else
464 {
465 return out.toString();
466 }
467 }
468 }