2 // System.Web.UI.ClientScriptManager.cs
5 // Duncan Mak (duncan@ximian.com)
6 // Gonzalo Paniagua (gonzalo@ximian.com)
7 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 // Lluis Sanchez (lluis@novell.com)
10 // (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
11 // (c) 2003 Novell, Inc. (http://www.novell.com)
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System.Collections;
39 namespace System.Web.UI
46 class ClientScriptManager
48 Hashtable registeredArrayDeclares;
49 ScriptEntry clientScriptBlocks;
50 ScriptEntry startupScriptBlocks;
51 Hashtable hiddenFields;
52 ScriptEntry submitStatements;
53 ScriptEntry scriptIncludes;
56 internal ClientScriptManager (Page page)
62 public string GetPostBackClientEvent (Control control, string argument)
64 return GetPostBackEventReference (control, argument);
68 public string GetPostBackClientHyperlink (Control control, string argument)
70 return "javascript:" + GetPostBackEventReference (control, argument);
73 public string GetPostBackEventReference (Control control, string argument)
75 page.RequiresPostBackScript ();
76 return String.Format ("__doPostBack('{0}','{1}')", control.UniqueID, argument);
80 public string GetPostBackEventReference (PostBackOptions options)
82 if (options.ActionUrl == null && options.ValidationGroup == null && !options.TrackFocus &&
83 !options.AutoPostBack && !options.PerformValidation)
85 if (!options.ClientSubmit)
88 if (options.RequiresJavaScriptProtocol)
89 return GetPostBackClientHyperlink (options.TargetControl, options.Argument);
91 return GetPostBackEventReference (options.TargetControl, options.Argument);
94 if (!IsClientScriptIncludeRegistered (typeof(Page), "webform")) {
95 RegisterClientScriptInclude (typeof(Page), "webform", GetWebResourceUrl (typeof(Page), "webform.js"));
98 if (options.ActionUrl != null)
99 RegisterHiddenField (Page.PreviousPageID, page.Request.FilePath);
101 if (options.ClientSubmit || options.ActionUrl != null)
102 page.RequiresPostBackScript ();
104 return String.Format ("{0}WebForm_DoPostback({1},{2},{3},{4},{5},{6},{7},{8})",
105 options.RequiresJavaScriptProtocol ? "javascript:" : "",
106 ClientScriptManager.GetScriptLiteral (options.TargetControl.UniqueID),
107 ClientScriptManager.GetScriptLiteral (options.Argument),
108 ClientScriptManager.GetScriptLiteral (options.ActionUrl),
109 ClientScriptManager.GetScriptLiteral (options.AutoPostBack),
110 ClientScriptManager.GetScriptLiteral (options.PerformValidation),
111 ClientScriptManager.GetScriptLiteral (options.TrackFocus),
112 ClientScriptManager.GetScriptLiteral (options.ClientSubmit),
113 ClientScriptManager.GetScriptLiteral (options.ValidationGroup)
117 public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context)
119 return GetCallbackEventReference (control, argument, clientCallback, context, null, false);
122 public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context, bool useAsync)
124 return GetCallbackEventReference (control, argument, clientCallback, context, null, useAsync);
127 public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context, string clientErrorCallback, bool useAsync)
130 throw new ArgumentNullException ("control");
131 if(!(control is ICallbackEventHandler))
132 throw new InvalidOperationException ("The control must implement the ICallbackEventHandler interface and provide a RaiseCallbackEvent method.");
134 return GetCallbackEventReference (control.UniqueID, argument, clientCallback, context, clientErrorCallback, useAsync);
137 public string GetCallbackEventReference (string target, string argument, string clientCallback, string context, string clientErrorCallback, bool useAsync)
139 page.RequiresPostBackScript ();
141 if (!IsClientScriptIncludeRegistered (typeof(Page), "callback"))
142 RegisterClientScriptInclude (typeof(Page), "callback", GetWebResourceUrl (typeof(Page), "callback.js"));
144 return string.Format ("WebForm_DoCallback('{0}',{1},{2},{3},{4},{5})", target, argument, clientCallback, context, ((clientErrorCallback == null) ? "null" : clientErrorCallback), (useAsync ? "true" : "false"));
153 string GetWebResourceUrl(Type type, string resourceName)
156 throw new ArgumentNullException ("type");
158 if (resourceName == null || resourceName.Length == 0)
159 throw new ArgumentNullException ("type");
161 return System.Web.Handlers.AssemblyResourceLoader.GetResourceUrl (type, resourceName);
165 public bool IsClientScriptBlockRegistered (string key)
167 return IsScriptRegistered (clientScriptBlocks, GetType(), key);
170 public bool IsClientScriptBlockRegistered (Type type, string key)
172 return IsScriptRegistered (clientScriptBlocks, type, key);
175 public bool IsStartupScriptRegistered (string key)
177 return IsScriptRegistered (startupScriptBlocks, GetType(), key);
180 public bool IsStartupScriptRegistered (Type type, string key)
182 return IsScriptRegistered (startupScriptBlocks, type, key);
185 public bool IsOnSubmitStatementRegistered (string key)
187 return IsScriptRegistered (submitStatements, GetType(), key);
190 public bool IsOnSubmitStatementRegistered (Type type, string key)
192 return IsScriptRegistered (submitStatements, type, key);
195 public bool IsClientScriptIncludeRegistered (string key)
197 return IsScriptRegistered (scriptIncludes, GetType(), key);
200 public bool IsClientScriptIncludeRegistered (Type type, string key)
202 return IsScriptRegistered (scriptIncludes, type, key);
205 bool IsScriptRegistered (ScriptEntry scriptList, Type type, string key)
207 while (scriptList != null) {
208 if (scriptList.Type == type && scriptList.Key == key)
210 scriptList = scriptList.Next;
215 public void RegisterArrayDeclaration (string arrayName, string arrayValue)
217 if (registeredArrayDeclares == null)
218 registeredArrayDeclares = new Hashtable();
220 if (!registeredArrayDeclares.ContainsKey (arrayName))
221 registeredArrayDeclares.Add (arrayName, new ArrayList());
223 ((ArrayList) registeredArrayDeclares[arrayName]).Add(arrayValue);
226 void RegisterScript (ref ScriptEntry scriptList, Type type, string key, string script, bool addScriptTags)
228 ScriptEntry last = null;
229 ScriptEntry entry = scriptList;
231 while (entry != null) {
232 if (entry.Type == type && entry.Key == key)
239 script = "<script language=javascript>\n<!--\n" + script + "\n// -->\n</script>";
241 entry = new ScriptEntry (type, key, script);
243 if (last != null) last.Next = entry;
244 else scriptList = entry;
247 internal void RegisterClientScriptBlock (string key, string script)
249 RegisterScript (ref clientScriptBlocks, GetType(), key, script, false);
252 public void RegisterClientScriptBlock (Type type, string key, string script)
254 RegisterClientScriptBlock (type, key, script, false);
257 public void RegisterClientScriptBlock (Type type, string key, string script, bool addScriptTags)
260 throw new ArgumentNullException ("type");
262 RegisterScript (ref clientScriptBlocks, type, key, script, addScriptTags);
265 public void RegisterHiddenField (string hiddenFieldName, string hiddenFieldInitialValue)
267 if (hiddenFields == null)
268 hiddenFields = new Hashtable ();
270 if (!hiddenFields.ContainsKey (hiddenFieldName))
271 hiddenFields.Add (hiddenFieldName, hiddenFieldInitialValue);
274 internal void RegisterOnSubmitStatement (string key, string script)
276 RegisterScript (ref submitStatements, GetType (), key, script, false);
279 public void RegisterOnSubmitStatement (Type type, string key, string script)
282 throw new ArgumentNullException ("type");
284 RegisterScript (ref submitStatements, type, key, script, false);
287 internal void RegisterStartupScript (string key, string script)
289 RegisterScript (ref startupScriptBlocks, GetType(), key, script, false);
292 public void RegisterStartupScript (Type type, string key, string script)
294 RegisterStartupScript (type, key, script, false);
297 public void RegisterStartupScript (Type type, string key, string script, bool addScriptTags)
300 throw new ArgumentNullException ("type");
302 RegisterScript (ref startupScriptBlocks, type, key, script, addScriptTags);
305 public void RegisterClientScriptInclude (string key, string url)
307 RegisterClientScriptInclude (GetType (), key, url);
310 public void RegisterClientScriptInclude (Type type, string key, string url)
313 throw new ArgumentNullException ("type");
314 if (url == null || url.Length == 0)
315 throw new ArgumentException ("url");
317 RegisterScript (ref scriptIncludes, type, key, url, false);
321 public void RegisterClientScriptResource (Type type, string resourceName)
323 RegisterScript (ref scriptIncludes, type, "resource-" + resourceName, GetWebResourceUrl (type, resourceName), false);
327 public void RegisterExpandoAttribute (string controlId,
331 throw new NotImplementedException ();
335 public void RegisterExpandoAttribute(string controlId,
336 string attributeName,
337 string attributeValue,
340 throw new NotImplementedException ();
344 public void RegisterForEventValidation (PostBackOptions options)
346 throw new NotImplementedException ();
350 public void RegisterForEventValidation (string uniqueId)
352 throw new NotImplementedException ();
356 public void RegisterForEventValidation (string uniqueId, string argument)
358 throw new NotImplementedException ();
362 public void ValidateEvent (string uniqueId)
364 throw new NotImplementedException ();
368 public void ValidateEvent (string uniqueId, string argument)
370 throw new NotImplementedException ();
373 void WriteScripts (HtmlTextWriter writer, ScriptEntry scriptList)
375 while (scriptList != null) {
376 writer.WriteLine (scriptList.Script);
377 scriptList = scriptList.Next;
381 internal void WriteHiddenFields (HtmlTextWriter writer)
383 if (hiddenFields == null)
386 foreach (string key in hiddenFields.Keys) {
387 string value = hiddenFields [key] as string;
388 writer.WriteLine ("\n<input type=\"hidden\" name=\"{0}\" id=\"{0}\" value=\"{1}\" />", key, value);
394 internal void WriteClientScriptIncludes (HtmlTextWriter writer)
396 ScriptEntry entry = scriptIncludes;
397 while (entry != null) {
398 writer.WriteLine ("\n<script src=\"{0}\" type=\"text/javascript\"></script>", entry.Script);
403 internal void WriteClientScriptBlocks (HtmlTextWriter writer)
405 WriteScripts (writer, clientScriptBlocks);
408 internal void WriteStartupScriptBlocks (HtmlTextWriter writer)
410 WriteScripts (writer, startupScriptBlocks);
413 internal void WriteArrayDeclares (HtmlTextWriter writer)
415 if (registeredArrayDeclares != null) {
417 writer.WriteLine("<script language=\"javascript\">");
418 writer.WriteLine("<!--");
419 IDictionaryEnumerator arrayEnum = registeredArrayDeclares.GetEnumerator();
420 while (arrayEnum.MoveNext()) {
421 writer.Write("\tvar ");
422 writer.Write(arrayEnum.Key);
423 writer.Write(" = new Array(");
424 IEnumerator arrayListEnum = ((ArrayList) arrayEnum.Value).GetEnumerator();
426 while (arrayListEnum.MoveNext()) {
431 writer.Write(arrayListEnum.Current);
433 writer.WriteLine(");");
435 writer.WriteLine("// -->");
436 writer.WriteLine("</script>");
442 internal string GetClientValidationEvent (string validationGroup) {
443 return "if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate('" + validationGroup + "');";
447 internal string GetClientValidationEvent ()
449 return "if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate();";
453 internal string WriteSubmitStatements ()
455 if (submitStatements == null) return null;
457 StringBuilder sb = new StringBuilder ();
458 ScriptEntry entry = submitStatements;
459 while (entry != null) {
460 sb.Append (entry.Script);
463 return sb.ToString ();
466 internal static string GetScriptLiteral (object ob)
470 else if (ob is string) {
471 string s = (string)ob;
472 s = s.Replace ("\"", "\\\"");
473 return "\"" + s + "\"";
474 } else if (ob is bool) {
475 return ob.ToString().ToLower();
477 return ob.ToString ();
485 public string Script;
486 public ScriptEntry Next;
488 public ScriptEntry (Type type, string key, string script)
498 internal static string EnsureEndsWithSemicolon (string value) {
499 if (value != null && value.Length > 0 && !value.EndsWith (";"))