ClientScriptManager.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. //
  2. // System.Web.UI.ClientScriptManager.cs
  3. //
  4. // Authors:
  5. // Duncan Mak ([email protected])
  6. // Gonzalo Paniagua ([email protected])
  7. // Andreas Nahr ([email protected])
  8. // Lluis Sanchez ([email protected])
  9. //
  10. // (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
  11. // (c) 2003 Novell, Inc. (http://www.novell.com)
  12. //
  13. //
  14. // Permission is hereby granted, free of charge, to any person obtaining
  15. // a copy of this software and associated documentation files (the
  16. // "Software"), to deal in the Software without restriction, including
  17. // without limitation the rights to use, copy, modify, merge, publish,
  18. // distribute, sublicense, and/or sell copies of the Software, and to
  19. // permit persons to whom the Software is furnished to do so, subject to
  20. // the following conditions:
  21. //
  22. // The above copyright notice and this permission notice shall be
  23. // included in all copies or substantial portions of the Software.
  24. //
  25. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  26. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  27. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  28. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  29. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  30. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  31. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  32. //
  33. using System;
  34. using System.Collections;
  35. using System.Text;
  36. namespace System.Web.UI
  37. {
  38. #if NET_2_0
  39. public sealed
  40. #else
  41. internal
  42. #endif
  43. class ClientScriptManager
  44. {
  45. Hashtable registeredArrayDeclares;
  46. ScriptEntry clientScriptBlocks;
  47. ScriptEntry startupScriptBlocks;
  48. Hashtable hiddenFields;
  49. ScriptEntry submitStatements;
  50. ScriptEntry scriptIncludes;
  51. Page page;
  52. internal ClientScriptManager (Page page)
  53. {
  54. this.page = page;
  55. }
  56. #if !NET_2_0
  57. public string GetPostBackClientEvent (Control control, string argument)
  58. {
  59. return GetPostBackEventReference (control, argument);
  60. }
  61. #endif
  62. public string GetPostBackClientHyperlink (Control control, string argument)
  63. {
  64. return "javascript:" + GetPostBackEventReference (control, argument);
  65. }
  66. public string GetPostBackEventReference (Control control, string argument)
  67. {
  68. page.RequiresPostBackScript ();
  69. return String.Format ("__doPostBack('{0}','{1}')", control.UniqueID, argument);
  70. }
  71. #if NET_2_0
  72. public string GetPostBackEventReference (PostBackOptions options)
  73. {
  74. if (options.ActionUrl == null && options.ValidationGroup == null && !options.TrackFocus &&
  75. !options.AutoPostBack && !options.PerformValidation)
  76. {
  77. if (options.RequiresJavaScriptProtocol)
  78. return GetPostBackClientHyperlink (options.TargetControl, options.Argument);
  79. else
  80. return GetPostBackEventReference (options.TargetControl, options.Argument);
  81. }
  82. if (!IsClientScriptIncludeRegistered (typeof(Page), "webform")) {
  83. RegisterClientScriptInclude (typeof(Page), "webform", GetWebResourceUrl (typeof(Page), "webform.js"));
  84. }
  85. if (options.ActionUrl != null)
  86. RegisterHiddenField (Page.PreviousPageID, page.Request.FilePath);
  87. if (options.ClientSubmit || options.ActionUrl != null)
  88. page.RequiresPostBackScript ();
  89. return String.Format ("{0}WebForm_DoPostback({1},{2},{3},{4},{5},{6},{7},{8})",
  90. options.RequiresJavaScriptProtocol ? "javascript:" : "",
  91. ClientScriptManager.GetScriptLiteral (options.TargetControl.UniqueID),
  92. ClientScriptManager.GetScriptLiteral (options.Argument),
  93. ClientScriptManager.GetScriptLiteral (options.ActionUrl),
  94. ClientScriptManager.GetScriptLiteral (options.AutoPostBack),
  95. ClientScriptManager.GetScriptLiteral (options.PerformValidation),
  96. ClientScriptManager.GetScriptLiteral (options.TrackFocus),
  97. ClientScriptManager.GetScriptLiteral (options.ClientSubmit),
  98. ClientScriptManager.GetScriptLiteral (options.ValidationGroup)
  99. );
  100. }
  101. public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context)
  102. {
  103. return GetCallbackEventReference (control.UniqueID, argument, clientCallback, context, null, false);
  104. }
  105. public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context, bool useAsync)
  106. {
  107. return GetCallbackEventReference (control.UniqueID, argument, clientCallback, context, null, useAsync);
  108. }
  109. public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context, string clientErrorCallback, bool useAsync)
  110. {
  111. return GetCallbackEventReference (control.UniqueID, argument, clientCallback, context, clientErrorCallback, useAsync);
  112. }
  113. public string GetCallbackEventReference (string target, string argument, string clientCallback, string context, string clientErrorCallback, bool useAsync)
  114. {
  115. page.RequiresPostBackScript ();
  116. if (!IsClientScriptIncludeRegistered (typeof(Page), "callback"))
  117. RegisterClientScriptInclude (typeof(Page), "callback", GetWebResourceUrl (typeof(Page), "callback.js"));
  118. return string.Format ("WebForm_DoCallback ('{0}', {1}, {2}, {3}, {4})", target, argument, clientCallback, context, clientErrorCallback);
  119. }
  120. #endif
  121. #if NET_2_0
  122. public
  123. #else
  124. internal
  125. #endif
  126. string GetWebResourceUrl(Type type, string resourceName)
  127. {
  128. if (type == null)
  129. throw new ArgumentNullException ("type");
  130. if (resourceName == null || resourceName.Length == 0)
  131. throw new ArgumentNullException ("type");
  132. return System.Web.Handlers.AssemblyResourceLoader.GetResourceUrl (type, resourceName);
  133. }
  134. public bool IsClientScriptBlockRegistered (string key)
  135. {
  136. return IsScriptRegistered (clientScriptBlocks, GetType(), key);
  137. }
  138. public bool IsClientScriptBlockRegistered (Type type, string key)
  139. {
  140. return IsScriptRegistered (clientScriptBlocks, type, key);
  141. }
  142. public bool IsStartupScriptRegistered (string key)
  143. {
  144. return IsScriptRegistered (startupScriptBlocks, GetType(), key);
  145. }
  146. public bool IsStartupScriptRegistered (Type type, string key)
  147. {
  148. return IsScriptRegistered (startupScriptBlocks, type, key);
  149. }
  150. public bool IsOnSubmitStatementRegistered (string key)
  151. {
  152. return IsScriptRegistered (submitStatements, GetType(), key);
  153. }
  154. public bool IsOnSubmitStatementRegistered (Type type, string key)
  155. {
  156. return IsScriptRegistered (submitStatements, type, key);
  157. }
  158. public bool IsClientScriptIncludeRegistered (string key)
  159. {
  160. return IsScriptRegistered (scriptIncludes, GetType(), key);
  161. }
  162. public bool IsClientScriptIncludeRegistered (Type type, string key)
  163. {
  164. return IsScriptRegistered (scriptIncludes, type, key);
  165. }
  166. bool IsScriptRegistered (ScriptEntry scriptList, Type type, string key)
  167. {
  168. while (scriptList != null) {
  169. if (scriptList.Type == type && scriptList.Key == key)
  170. return true;
  171. scriptList = scriptList.Next;
  172. }
  173. return false;
  174. }
  175. public void RegisterArrayDeclaration (string arrayName, string arrayValue)
  176. {
  177. if (registeredArrayDeclares == null)
  178. registeredArrayDeclares = new Hashtable();
  179. if (!registeredArrayDeclares.ContainsKey (arrayName))
  180. registeredArrayDeclares.Add (arrayName, new ArrayList());
  181. ((ArrayList) registeredArrayDeclares[arrayName]).Add(arrayValue);
  182. }
  183. void RegisterScript (ref ScriptEntry scriptList, Type type, string key, string script, bool addScriptTags)
  184. {
  185. ScriptEntry last = null;
  186. ScriptEntry entry = scriptList;
  187. while (entry != null) {
  188. if (entry.Type == type && entry.Key == key)
  189. return;
  190. last = entry;
  191. entry = entry.Next;
  192. }
  193. if (addScriptTags)
  194. script = "<script language=javascript>\n<!--\n" + script + "\n// -->\n</script>";
  195. entry = new ScriptEntry (type, key, script);
  196. if (last != null) last.Next = entry;
  197. else scriptList = entry;
  198. }
  199. internal void RegisterClientScriptBlock (string key, string script)
  200. {
  201. RegisterScript (ref clientScriptBlocks, GetType(), key, script, false);
  202. }
  203. public void RegisterClientScriptBlock (Type type, string key, string script)
  204. {
  205. RegisterScript (ref clientScriptBlocks, type, key, script, false);
  206. }
  207. public void RegisterClientScriptBlock (Type type, string key, string script, bool addScriptTags)
  208. {
  209. RegisterScript (ref clientScriptBlocks, type, key, script, addScriptTags);
  210. }
  211. public void RegisterHiddenField (string hiddenFieldName, string hiddenFieldInitialValue)
  212. {
  213. if (hiddenFields == null)
  214. hiddenFields = new Hashtable ();
  215. if (!hiddenFields.ContainsKey (hiddenFieldName))
  216. hiddenFields.Add (hiddenFieldName, hiddenFieldInitialValue);
  217. }
  218. internal void RegisterOnSubmitStatement (string key, string script)
  219. {
  220. RegisterScript (ref submitStatements, GetType (), key, script, false);
  221. }
  222. public void RegisterOnSubmitStatement (Type type, string key, string script)
  223. {
  224. RegisterScript (ref submitStatements, type, key, script, false);
  225. }
  226. internal void RegisterStartupScript (string key, string script)
  227. {
  228. RegisterScript (ref startupScriptBlocks, GetType(), key, script, false);
  229. }
  230. public void RegisterStartupScript (Type type, string key, string script)
  231. {
  232. RegisterScript (ref startupScriptBlocks, type, key, script, false);
  233. }
  234. public void RegisterStartupScript (Type type, string key, string script, bool addScriptTags)
  235. {
  236. RegisterScript (ref startupScriptBlocks, type, key, script, addScriptTags);
  237. }
  238. public void RegisterClientScriptInclude (string key, string url)
  239. {
  240. RegisterScript (ref scriptIncludes, GetType(), key, url, false);
  241. }
  242. public void RegisterClientScriptInclude (Type type, string key, string url)
  243. {
  244. RegisterScript (ref scriptIncludes, type, key, url, false);
  245. }
  246. #if NET_2_0
  247. public void RegisterClientScriptResource (Type type, string resourceName)
  248. {
  249. RegisterScript (ref scriptIncludes, type, "resource-" + resourceName, GetWebResourceUrl (type, resourceName), false);
  250. }
  251. [MonoTODO]
  252. public void RegisterExpandoAttribute (string controlId,
  253. string name,
  254. string value)
  255. {
  256. throw new NotImplementedException ();
  257. }
  258. [MonoTODO]
  259. public void RegisterExpandoAttribute(string controlId,
  260. string attributeName,
  261. string attributeValue,
  262. bool encode)
  263. {
  264. throw new NotImplementedException ();
  265. }
  266. #endif
  267. void WriteScripts (HtmlTextWriter writer, ScriptEntry scriptList)
  268. {
  269. while (scriptList != null) {
  270. writer.WriteLine (scriptList.Script);
  271. scriptList = scriptList.Next;
  272. }
  273. }
  274. internal void WriteHiddenFields (HtmlTextWriter writer)
  275. {
  276. if (hiddenFields == null)
  277. return;
  278. foreach (string key in hiddenFields.Keys) {
  279. string value = hiddenFields [key] as string;
  280. writer.WriteLine ("\n<input type=\"hidden\" name=\"{0}\" value=\"{1}\" />", key, value);
  281. }
  282. hiddenFields = null;
  283. }
  284. internal void WriteClientScriptIncludes (HtmlTextWriter writer)
  285. {
  286. ScriptEntry entry = scriptIncludes;
  287. while (entry != null) {
  288. writer.WriteLine ("\n<script src=\"{0}\" type=\"text/javascript\"></script>", entry.Script);
  289. entry = entry.Next;
  290. }
  291. }
  292. internal void WriteClientScriptBlocks (HtmlTextWriter writer)
  293. {
  294. WriteScripts (writer, clientScriptBlocks);
  295. }
  296. internal void WriteStartupScriptBlocks (HtmlTextWriter writer)
  297. {
  298. WriteScripts (writer, startupScriptBlocks);
  299. }
  300. internal void WriteArrayDeclares (HtmlTextWriter writer)
  301. {
  302. if (registeredArrayDeclares != null) {
  303. writer.WriteLine();
  304. writer.WriteLine("<script language=\"javascript\">");
  305. writer.WriteLine("<!--");
  306. IDictionaryEnumerator arrayEnum = registeredArrayDeclares.GetEnumerator();
  307. while (arrayEnum.MoveNext()) {
  308. writer.Write("\tvar ");
  309. writer.Write(arrayEnum.Key);
  310. writer.Write(" = new Array(");
  311. IEnumerator arrayListEnum = ((ArrayList) arrayEnum.Value).GetEnumerator();
  312. bool isFirst = true;
  313. while (arrayListEnum.MoveNext()) {
  314. if (isFirst)
  315. isFirst = false;
  316. else
  317. writer.Write(", ");
  318. writer.Write(arrayListEnum.Current);
  319. }
  320. writer.WriteLine(");");
  321. }
  322. writer.WriteLine("// -->");
  323. writer.WriteLine("</script>");
  324. writer.WriteLine();
  325. }
  326. }
  327. internal string GetClientValidationEvent ()
  328. {
  329. return "if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate();";
  330. }
  331. internal string WriteSubmitStatements ()
  332. {
  333. if (submitStatements == null) return null;
  334. StringBuilder sb = new StringBuilder ();
  335. ScriptEntry entry = submitStatements;
  336. while (entry != null) {
  337. sb.Append (entry.Script);
  338. entry = entry.Next;
  339. }
  340. return sb.ToString ();
  341. }
  342. internal static string GetScriptLiteral (object ob)
  343. {
  344. if (ob == null)
  345. return "null";
  346. else if (ob is string) {
  347. string s = (string)ob;
  348. s = s.Replace ("\"", "\\\"");
  349. return "\"" + s + "\"";
  350. } else if (ob is bool) {
  351. return ob.ToString().ToLower();
  352. } else {
  353. return ob.ToString ();
  354. }
  355. }
  356. class ScriptEntry
  357. {
  358. public Type Type;
  359. public string Key;
  360. public string Script;
  361. public ScriptEntry Next;
  362. public ScriptEntry (Type type, string key, string script)
  363. {
  364. Key = key;
  365. Type = type;
  366. Script = script;
  367. }
  368. }
  369. }
  370. }