merge -r 53370:58178
[mono.git] / mcs / class / System.Web / System.Web.UI / ClientScriptManager.cs
1 //
2 // System.Web.UI.ClientScriptManager.cs
3 //
4 // Authors:
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)
9 //
10 // (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
11 // (c) 2003 Novell, Inc. (http://www.novell.com)
12 //
13
14 //
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:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
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.
33 //
34
35 using System;
36 using System.Collections;
37 using System.Text;
38
39 namespace System.Web.UI
40 {
41         #if NET_2_0
42         public sealed
43         #else
44         internal
45         #endif
46                 class ClientScriptManager
47         {
48                 Hashtable registeredArrayDeclares;
49                 ScriptEntry clientScriptBlocks;
50                 ScriptEntry startupScriptBlocks;
51                 Hashtable hiddenFields;
52                 ScriptEntry submitStatements;
53                 ScriptEntry scriptIncludes;
54                 Page page;
55         
56                 internal ClientScriptManager (Page page)
57                 {
58                         this.page = page;
59                 }
60
61                 [Obsolete ("Use GetPostBackEventReference instead")]
62                 public string GetPostBackClientEvent (Control control, string argument)
63                 {
64                         return GetPostBackEventReference (control, argument);
65                 }
66         
67                 public string GetPostBackClientHyperlink (Control control, string argument)
68                 {
69                         return "javascript:" + GetPostBackEventReference (control, argument);
70                 }
71         
72                 public string GetPostBackEventReference (Control control, string argument)
73                 {
74                         page.RequiresPostBackScript ();
75                         return String.Format ("__doPostBack('{0}','{1}')", control.UniqueID, argument);
76                 }
77                 
78 #if NET_2_0
79                 public string GetPostBackEventReference (PostBackOptions options)
80                 {
81                         if (options.ActionUrl == null && options.ValidationGroup == null && !options.TrackFocus && 
82                                 !options.AutoPostBack && !options.PerformValidation)
83                         {
84                                 if (options.RequiresJavaScriptProtocol)
85                                         return GetPostBackClientHyperlink (options.TargetControl, options.Argument);
86                                 else
87                                         return GetPostBackEventReference (options.TargetControl, options.Argument);
88                         }
89                         
90                         if (!IsClientScriptIncludeRegistered (typeof(Page), "webform")) {
91                                 RegisterClientScriptInclude (typeof(Page), "webform", GetWebResourceUrl (typeof(Page), "webform.js"));
92                         }
93                         
94                         if (options.ActionUrl != null)
95                                 RegisterHiddenField (Page.PreviousPageID, page.Request.FilePath);
96                         
97                         if (options.ClientSubmit || options.ActionUrl != null)
98                                 page.RequiresPostBackScript ();
99                         
100                         return String.Format ("{0}WebForm_DoPostback({1},{2},{3},{4},{5},{6},{7},{8})", 
101                                         options.RequiresJavaScriptProtocol ? "javascript:" : "",
102                                         ClientScriptManager.GetScriptLiteral (options.TargetControl.UniqueID), 
103                                         ClientScriptManager.GetScriptLiteral (options.Argument),
104                                         ClientScriptManager.GetScriptLiteral (options.ActionUrl),
105                                         ClientScriptManager.GetScriptLiteral (options.AutoPostBack),
106                                         ClientScriptManager.GetScriptLiteral (options.PerformValidation),
107                                         ClientScriptManager.GetScriptLiteral (options.TrackFocus),
108                                         ClientScriptManager.GetScriptLiteral (options.ClientSubmit),
109                                         ClientScriptManager.GetScriptLiteral (options.ValidationGroup)
110                                 );
111                 }
112                 
113                 public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context)
114                 {
115                         return GetCallbackEventReference (control.UniqueID, argument, clientCallback, context, null, false);
116                 }
117
118                 public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context, bool useAsync)
119                 {
120                         return GetCallbackEventReference (control.UniqueID, argument, clientCallback, context, null, useAsync);
121                 }
122
123                 public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context, string clientErrorCallback, bool useAsync)
124                 {
125                         return GetCallbackEventReference (control.UniqueID, argument, clientCallback, context, clientErrorCallback, useAsync);
126                 }
127
128                 public string GetCallbackEventReference (string target, string argument, string clientCallback, string context, string clientErrorCallback, bool useAsync)
129                 {
130                         page.RequiresPostBackScript ();
131
132                         if (!IsClientScriptIncludeRegistered (typeof(Page), "callback"))
133                                 RegisterClientScriptInclude (typeof(Page), "callback", GetWebResourceUrl (typeof(Page), "callback.js"));
134                         
135                         return string.Format ("WebForm_DoCallback ('{0}', {1}, {2}, {3}, {4})", target, argument, clientCallback, context, clientErrorCallback);
136                 }
137 #endif
138                 
139 #if NET_2_0
140                 public
141 #else
142                 internal
143 #endif
144                 string GetWebResourceUrl(Type type, string resourceName)
145                 {
146                         if (type == null)
147                                 throw new ArgumentNullException ("type");
148                 
149                         if (resourceName == null || resourceName.Length == 0)
150                                 throw new ArgumentNullException ("type");
151                 
152                         return System.Web.Handlers.AssemblyResourceLoader.GetResourceUrl (type, resourceName); 
153                 }
154                 
155
156                 public bool IsClientScriptBlockRegistered (string key)
157                 {
158                         return IsScriptRegistered (clientScriptBlocks, GetType(), key);
159                 }
160         
161                 public bool IsClientScriptBlockRegistered (Type type, string key)
162                 {
163                         return IsScriptRegistered (clientScriptBlocks, type, key);
164                 }
165         
166                 public bool IsStartupScriptRegistered (string key)
167                 {
168                         return IsScriptRegistered (startupScriptBlocks, GetType(), key);
169                 }
170         
171                 public bool IsStartupScriptRegistered (Type type, string key)
172                 {
173                         return IsScriptRegistered (startupScriptBlocks, type, key);
174                 }
175                 
176                 public bool IsOnSubmitStatementRegistered (string key)
177                 {
178                         return IsScriptRegistered (submitStatements, GetType(), key);
179                 }
180         
181                 public bool IsOnSubmitStatementRegistered (Type type, string key)
182                 {
183                         return IsScriptRegistered (submitStatements, type, key);
184                 }
185                 
186                 public bool IsClientScriptIncludeRegistered (string key)
187                 {
188                         return IsScriptRegistered (scriptIncludes, GetType(), key);
189                 }
190         
191                 public bool IsClientScriptIncludeRegistered (Type type, string key)
192                 {
193                         return IsScriptRegistered (scriptIncludes, type, key);
194                 }
195                 
196                 bool IsScriptRegistered (ScriptEntry scriptList, Type type, string key)
197                 {
198                         while (scriptList != null) {
199                                 if (scriptList.Type == type && scriptList.Key == key)
200                                         return true;
201                                 scriptList = scriptList.Next;
202                         }
203                         return false;
204                 }
205                 
206                 public void RegisterArrayDeclaration (string arrayName, string arrayValue)
207                 {
208                         if (registeredArrayDeclares == null)
209                                 registeredArrayDeclares = new Hashtable();
210         
211                         if (!registeredArrayDeclares.ContainsKey (arrayName))
212                                 registeredArrayDeclares.Add (arrayName, new ArrayList());
213         
214                         ((ArrayList) registeredArrayDeclares[arrayName]).Add(arrayValue);
215                 }
216         
217                 void RegisterScript (ref ScriptEntry scriptList, Type type, string key, string script, bool addScriptTags)
218                 {
219                         ScriptEntry last = null;
220                         ScriptEntry entry = scriptList;
221
222                         while (entry != null) {
223                                 if (entry.Type == type && entry.Key == key)
224                                         return;
225                                 last = entry;
226                                 entry = entry.Next;
227                         }
228                         
229                         if (addScriptTags)
230                                 script = "<script language=javascript>\n<!--\n" + script + "\n// -->\n</script>";
231
232                         entry = new ScriptEntry (type, key, script);
233                         
234                         if (last != null) last.Next = entry;
235                         else scriptList = entry;
236                 }
237         
238                 internal void RegisterClientScriptBlock (string key, string script)
239                 {
240                         RegisterScript (ref clientScriptBlocks, GetType(), key, script, false);
241                 }
242         
243                 public void RegisterClientScriptBlock (Type type, string key, string script)
244                 {
245                         RegisterScript (ref clientScriptBlocks, type, key, script, false);
246                 }
247         
248                 public void RegisterClientScriptBlock (Type type, string key, string script, bool addScriptTags)
249                 {
250                         RegisterScript (ref clientScriptBlocks, type, key, script, addScriptTags);
251                 }
252         
253                 public void RegisterHiddenField (string hiddenFieldName, string hiddenFieldInitialValue)
254                 {
255                         if (hiddenFields == null)
256                                 hiddenFields = new Hashtable ();
257
258                         if (!hiddenFields.ContainsKey (hiddenFieldName))
259                                 hiddenFields.Add (hiddenFieldName, hiddenFieldInitialValue);
260                 }
261         
262                 internal void RegisterOnSubmitStatement (string key, string script)
263                 {
264                         RegisterScript (ref submitStatements, GetType (), key, script, false);
265                 }
266         
267                 public void RegisterOnSubmitStatement (Type type, string key, string script)
268                 {
269                         RegisterScript (ref submitStatements, type, key, script, false);
270                 }
271         
272                 internal void RegisterStartupScript (string key, string script)
273                 {
274                         RegisterScript (ref startupScriptBlocks, GetType(), key, script, false);
275                 }
276                 
277                 public void RegisterStartupScript (Type type, string key, string script)
278                 {
279                         RegisterScript (ref startupScriptBlocks, type, key, script, false);
280                 }
281                 
282                 public void RegisterStartupScript (Type type, string key, string script, bool addScriptTags)
283                 {
284                         RegisterScript (ref startupScriptBlocks, type, key, script, addScriptTags);
285                 }
286
287                 public void RegisterClientScriptInclude (string key, string url)
288                 {
289                         RegisterScript (ref scriptIncludes, GetType(), key, url, false);
290                 }
291                 
292                 public void RegisterClientScriptInclude (Type type, string key, string url)
293                 {
294                         RegisterScript (ref scriptIncludes, type, key, url, false);
295                 }
296
297 #if NET_2_0
298                 [MonoTODO]
299                 public void RegisterClientScriptResource (Type type, string resourceName)
300                 {
301                         throw new NotImplementedException ();
302                 }
303
304                 [MonoTODO]
305                 public void RegisterExpandoAttribute (string controlId, 
306                                                       string name, 
307                                                       string value)
308                 {
309                         throw new NotImplementedException ();
310                 }
311
312                 [MonoTODO]
313                 public void RegisterExpandoAttribute(string controlId, 
314                                                      string attributeName, 
315                                                      string attributeValue, 
316                                                      bool encode)
317                 {
318                         throw new NotImplementedException ();
319                 }
320 #endif
321                 void WriteScripts (HtmlTextWriter writer, ScriptEntry scriptList)
322                 {
323                         while (scriptList != null) {
324                                 writer.WriteLine (scriptList.Script);
325                                 scriptList = scriptList.Next;
326                         }
327                 }
328                 
329                 internal void WriteHiddenFields (HtmlTextWriter writer)
330                 {
331                         if (hiddenFields == null)
332                                 return;
333         
334                         foreach (string key in hiddenFields.Keys) {
335                                 string value = hiddenFields [key] as string;
336                                 writer.WriteLine ("\n<input type=\"hidden\" name=\"{0}\" value=\"{1}\" />", key, value);
337                         }
338         
339                         hiddenFields = null;
340                 }
341                 
342                 internal void WriteClientScriptIncludes (HtmlTextWriter writer)
343                 {
344                         ScriptEntry entry = scriptIncludes;
345                         while (entry != null) {
346                                 writer.WriteLine ("\n<script src=\"{0}\" type=\"text/javascript\"></script>", entry.Script);
347                                 entry = entry.Next;
348                         }
349                 }
350                 
351                 internal void WriteClientScriptBlocks (HtmlTextWriter writer)
352                 {
353                         WriteScripts (writer, clientScriptBlocks);
354                 }
355         
356                 internal void WriteStartupScriptBlocks (HtmlTextWriter writer)
357                 {
358                         WriteScripts (writer, startupScriptBlocks);
359                 }
360         
361                 internal void WriteArrayDeclares (HtmlTextWriter writer)
362                 {
363                         if (registeredArrayDeclares != null) {
364                                 writer.WriteLine();
365                                 writer.WriteLine("<script language=\"javascript\">");
366                                 writer.WriteLine("<!--");
367                                 IDictionaryEnumerator arrayEnum = registeredArrayDeclares.GetEnumerator();
368                                 while (arrayEnum.MoveNext()) {
369                                         writer.Write("\tvar ");
370                                         writer.Write(arrayEnum.Key);
371                                         writer.Write(" =  new Array(");
372                                         IEnumerator arrayListEnum = ((ArrayList) arrayEnum.Value).GetEnumerator();
373                                         bool isFirst = true;
374                                         while (arrayListEnum.MoveNext()) {
375                                                 if (isFirst)
376                                                         isFirst = false;
377                                                 else
378                                                         writer.Write(", ");
379                                                 writer.Write(arrayListEnum.Current);
380                                         }
381                                         writer.WriteLine(");");
382                                 }
383                                 writer.WriteLine("// -->");
384                                 writer.WriteLine("</script>");
385                                 writer.WriteLine();
386                         }
387                 }
388
389                 internal string GetClientValidationEvent ()
390                 {
391                         return "if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate();";
392                 }
393
394
395                 internal string WriteSubmitStatements ()
396                 {
397                         if (submitStatements == null) return null;
398                         
399                         StringBuilder sb = new StringBuilder ();
400                         ScriptEntry entry = submitStatements;
401                         while (entry != null) {
402                                 sb.Append (entry.Script);
403                                 entry = entry.Next;
404                         }
405                         return sb.ToString ();
406                 }
407                 
408                 internal static string GetScriptLiteral (object ob)
409                 {
410                         if (ob == null)
411                                 return "null";
412                         else if (ob is string) {
413                                 string s = (string)ob;
414                                 s = s.Replace ("\"", "\\\"");
415                                 return "\"" + s + "\"";
416                         } else if (ob is bool) {
417                                 return ob.ToString().ToLower();
418                         } else {
419                                 return ob.ToString ();
420                         }
421                 }
422                 
423                 class ScriptEntry
424                 {
425                         public Type Type;
426                         public string Key;
427                         public string Script;
428                         public ScriptEntry Next;
429                          
430                         public ScriptEntry (Type type, string key, string script)
431                         {
432                                 Key = key;
433                                 Type = type;
434                                 Script = script;
435                         }
436                 }
437         }
438 }