ClientScriptManager.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  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. #if NET_2_0
  36. using System.Collections.Generic;
  37. #endif
  38. using System.Text;
  39. using System.Collections.Specialized;
  40. using System.Web.Util;
  41. using System.Globalization;
  42. namespace System.Web.UI
  43. {
  44. #if NET_2_0
  45. public sealed partial
  46. #else
  47. internal
  48. #endif
  49. class ClientScriptManager
  50. {
  51. internal const string EventStateFieldName = "__EVENTVALIDATION";
  52. Hashtable registeredArrayDeclares;
  53. ScriptEntry clientScriptBlocks;
  54. ScriptEntry startupScriptBlocks;
  55. internal Hashtable hiddenFields;
  56. ScriptEntry submitStatements;
  57. Page page;
  58. #if NET_2_0
  59. int [] eventValidationValues;
  60. int eventValidationPos = 0;
  61. Hashtable expandoAttributes;
  62. bool _hasRegisteredForEventValidationOnCallback;
  63. bool _pageInRender;
  64. bool _initCallBackRegistered;
  65. bool _webFormClientScriptRendered;
  66. bool _webFormClientScriptRequired;
  67. internal bool ScriptsPresent {
  68. get {
  69. return _webFormClientScriptRequired ||
  70. _initCallBackRegistered ||
  71. _hasRegisteredForEventValidationOnCallback ||
  72. clientScriptBlocks != null ||
  73. startupScriptBlocks != null ||
  74. submitStatements != null ||
  75. registeredArrayDeclares != null ||
  76. expandoAttributes != null;
  77. }
  78. }
  79. #endif
  80. internal ClientScriptManager (Page page)
  81. {
  82. this.page = page;
  83. }
  84. #if !NET_2_0
  85. public string GetPostBackClientEvent (Control control, string argument)
  86. {
  87. return GetPostBackEventReference (control, argument);
  88. }
  89. #endif
  90. public string GetPostBackClientHyperlink (Control control, string argument)
  91. {
  92. return "javascript:" + GetPostBackEventReference (control, argument);
  93. }
  94. #if NET_2_0
  95. public string GetPostBackClientHyperlink (Control control, string argument, bool registerForEventValidation)
  96. {
  97. if (registerForEventValidation)
  98. RegisterForEventValidation (control.UniqueID, argument);
  99. return "javascript:" + GetPostBackEventReference (control, argument);
  100. }
  101. #endif
  102. #if !NET_2_0
  103. internal
  104. #else
  105. public
  106. #endif
  107. string GetPostBackEventReference (Control control, string argument)
  108. {
  109. if (control == null)
  110. throw new ArgumentNullException ("control");
  111. page.RequiresPostBackScript ();
  112. if(page.IsMultiForm)
  113. return page.theForm + ".__doPostBack('" + control.UniqueID + "','" + argument + "')";
  114. else
  115. return "__doPostBack('" + control.UniqueID + "','" + argument + "')";
  116. }
  117. #if NET_2_0
  118. public string GetPostBackEventReference (Control control, string argument, bool registerForEventValidation)
  119. {
  120. if (control == null)
  121. throw new ArgumentNullException ("control");
  122. if (registerForEventValidation)
  123. RegisterForEventValidation (control.UniqueID, argument);
  124. return GetPostBackEventReference (control, argument);
  125. }
  126. public string GetPostBackEventReference (PostBackOptions options, bool registerForEventValidation)
  127. {
  128. if (options == null)
  129. throw new ArgumentNullException ("options");
  130. if (registerForEventValidation)
  131. RegisterForEventValidation (options);
  132. return GetPostBackEventReference (options);
  133. }
  134. public string GetPostBackEventReference (PostBackOptions options)
  135. {
  136. if (options == null)
  137. throw new ArgumentNullException ("options");
  138. if (options.ActionUrl == null && options.ValidationGroup == null && !options.TrackFocus &&
  139. !options.AutoPostBack && !options.PerformValidation)
  140. {
  141. if (!options.ClientSubmit)
  142. return null;
  143. if (options.RequiresJavaScriptProtocol)
  144. return GetPostBackClientHyperlink (options.TargetControl, options.Argument);
  145. else
  146. return GetPostBackEventReference (options.TargetControl, options.Argument);
  147. }
  148. RegisterWebFormClientScript ();
  149. string actionUrl = options.ActionUrl;
  150. if (actionUrl != null)
  151. RegisterHiddenField (Page.PreviousPageID, page.Request.FilePath);
  152. if(options.TrackFocus)
  153. RegisterHiddenField (Page.LastFocusID, String.Empty);
  154. string prefix = options.RequiresJavaScriptProtocol ? "javascript:" : "";
  155. if (page.IsMultiForm)
  156. prefix += page.theForm + ".";
  157. return prefix + "WebForm_DoPostback(" +
  158. ClientScriptManager.GetScriptLiteral (options.TargetControl.UniqueID) + "," +
  159. ClientScriptManager.GetScriptLiteral (options.Argument) + "," +
  160. ClientScriptManager.GetScriptLiteral (actionUrl) + "," +
  161. ClientScriptManager.GetScriptLiteral (options.AutoPostBack) + "," +
  162. ClientScriptManager.GetScriptLiteral (options.PerformValidation) + "," +
  163. ClientScriptManager.GetScriptLiteral (options.TrackFocus) + "," +
  164. ClientScriptManager.GetScriptLiteral (options.ClientSubmit) + "," +
  165. ClientScriptManager.GetScriptLiteral (options.ValidationGroup) + ")";
  166. }
  167. internal void RegisterWebFormClientScript ()
  168. {
  169. if (_webFormClientScriptRequired)
  170. return;
  171. page.RequiresPostBackScript ();
  172. _webFormClientScriptRequired = true;
  173. }
  174. internal void WriteWebFormClientScript (HtmlTextWriter writer) {
  175. if (!_webFormClientScriptRendered && _webFormClientScriptRequired) {
  176. writer.WriteLine ();
  177. WriteClientScriptInclude (writer, GetWebResourceUrl (typeof (Page), "webform.js"), typeof (Page), "webform.js");
  178. WriteBeginScriptBlock (writer);
  179. writer.WriteLine ("WebForm_Initialize({0});", page.IsMultiForm ? page.theForm : "window");
  180. WriteEndScriptBlock (writer);
  181. _webFormClientScriptRendered = true;
  182. }
  183. }
  184. public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context)
  185. {
  186. return GetCallbackEventReference (control, argument, clientCallback, context, null, false);
  187. }
  188. public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context, bool useAsync)
  189. {
  190. return GetCallbackEventReference (control, argument, clientCallback, context, null, useAsync);
  191. }
  192. public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context, string clientErrorCallback, bool useAsync)
  193. {
  194. if (control == null)
  195. throw new ArgumentNullException ("control");
  196. if(!(control is ICallbackEventHandler))
  197. throw new InvalidOperationException ("The control must implement the ICallbackEventHandler interface and provide a RaiseCallbackEvent method.");
  198. return GetCallbackEventReference ("'" + control.UniqueID + "'", argument, clientCallback, context, clientErrorCallback, useAsync);
  199. }
  200. public string GetCallbackEventReference (string target, string argument, string clientCallback, string context, string clientErrorCallback, bool useAsync)
  201. {
  202. RegisterWebFormClientScript ();
  203. if (!_initCallBackRegistered) {
  204. _initCallBackRegistered = true;
  205. RegisterStartupScript (typeof (Page), "WebForm_InitCallback", page.WebFormScriptReference + ".WebForm_InitCallback();", true);
  206. }
  207. return page.WebFormScriptReference + ".WebForm_DoCallback(" +
  208. target + "," +
  209. (argument ?? "null") + "," +
  210. clientCallback + "," +
  211. (context ?? "null") + "," +
  212. (clientErrorCallback ?? "null") + "," +
  213. (useAsync ? "true" : "false") + ")";
  214. }
  215. #endif
  216. #if NET_2_0
  217. public
  218. #else
  219. internal
  220. #endif
  221. string GetWebResourceUrl(Type type, string resourceName)
  222. {
  223. if (type == null)
  224. throw new ArgumentNullException ("type");
  225. if (resourceName == null || resourceName.Length == 0)
  226. throw new ArgumentNullException ("type");
  227. return System.Web.Handlers.AssemblyResourceLoader.GetResourceUrl (type, resourceName);
  228. }
  229. public bool IsClientScriptBlockRegistered (string key)
  230. {
  231. return IsScriptRegistered (clientScriptBlocks, GetType(), key);
  232. }
  233. public bool IsClientScriptBlockRegistered (Type type, string key)
  234. {
  235. return IsScriptRegistered (clientScriptBlocks, type, key);
  236. }
  237. public bool IsStartupScriptRegistered (string key)
  238. {
  239. return IsScriptRegistered (startupScriptBlocks, GetType(), key);
  240. }
  241. public bool IsStartupScriptRegistered (Type type, string key)
  242. {
  243. return IsScriptRegistered (startupScriptBlocks, type, key);
  244. }
  245. public bool IsOnSubmitStatementRegistered (string key)
  246. {
  247. return IsScriptRegistered (submitStatements, GetType(), key);
  248. }
  249. public bool IsOnSubmitStatementRegistered (Type type, string key)
  250. {
  251. return IsScriptRegistered (submitStatements, type, key);
  252. }
  253. public bool IsClientScriptIncludeRegistered (string key)
  254. {
  255. return IsClientScriptIncludeRegistered (GetType (), key);
  256. }
  257. public bool IsClientScriptIncludeRegistered (Type type, string key)
  258. {
  259. return IsScriptRegistered (clientScriptBlocks, type, "include-" + key);
  260. }
  261. bool IsScriptRegistered (ScriptEntry scriptList, Type type, string key)
  262. {
  263. while (scriptList != null) {
  264. if (scriptList.Type == type && scriptList.Key == key)
  265. return true;
  266. scriptList = scriptList.Next;
  267. }
  268. return false;
  269. }
  270. public void RegisterArrayDeclaration (string arrayName, string arrayValue)
  271. {
  272. if (registeredArrayDeclares == null)
  273. registeredArrayDeclares = new Hashtable();
  274. if (!registeredArrayDeclares.ContainsKey (arrayName))
  275. registeredArrayDeclares.Add (arrayName, new ArrayList());
  276. ((ArrayList) registeredArrayDeclares[arrayName]).Add(arrayValue);
  277. page.RequiresFormScriptDeclaration ();
  278. }
  279. void RegisterScript (ref ScriptEntry scriptList, Type type, string key, string script, bool addScriptTags)
  280. {
  281. RegisterScript (ref scriptList, type, key, script, addScriptTags ? ScriptEntryFormat.AddScriptTag : ScriptEntryFormat.None);
  282. }
  283. void RegisterScript (ref ScriptEntry scriptList, Type type, string key, string script, ScriptEntryFormat format)
  284. {
  285. ScriptEntry last = null;
  286. ScriptEntry entry = scriptList;
  287. while (entry != null) {
  288. if (entry.Type == type && entry.Key == key)
  289. return;
  290. last = entry;
  291. entry = entry.Next;
  292. }
  293. entry = new ScriptEntry (type, key, script, format);
  294. if (last != null) last.Next = entry;
  295. else scriptList = entry;
  296. }
  297. internal void RegisterClientScriptBlock (string key, string script)
  298. {
  299. RegisterScript (ref clientScriptBlocks, GetType(), key, script, false);
  300. }
  301. public void RegisterClientScriptBlock (Type type, string key, string script)
  302. {
  303. RegisterClientScriptBlock (type, key, script, false);
  304. }
  305. public void RegisterClientScriptBlock (Type type, string key, string script, bool addScriptTags)
  306. {
  307. if (type == null)
  308. throw new ArgumentNullException ("type");
  309. RegisterScript (ref clientScriptBlocks, type, key, script, addScriptTags);
  310. }
  311. public void RegisterHiddenField (string hiddenFieldName, string hiddenFieldInitialValue)
  312. {
  313. if (hiddenFields == null)
  314. hiddenFields = new Hashtable ();
  315. if (!hiddenFields.ContainsKey (hiddenFieldName))
  316. hiddenFields.Add (hiddenFieldName, hiddenFieldInitialValue);
  317. }
  318. internal void RegisterOnSubmitStatement (string key, string script)
  319. {
  320. RegisterScript (ref submitStatements, GetType (), key, script, false);
  321. }
  322. public void RegisterOnSubmitStatement (Type type, string key, string script)
  323. {
  324. if (type == null)
  325. throw new ArgumentNullException ("type");
  326. RegisterScript (ref submitStatements, type, key, script, false);
  327. }
  328. internal void RegisterStartupScript (string key, string script)
  329. {
  330. RegisterScript (ref startupScriptBlocks, GetType(), key, script, false);
  331. }
  332. public void RegisterStartupScript (Type type, string key, string script)
  333. {
  334. RegisterStartupScript (type, key, script, false);
  335. }
  336. public void RegisterStartupScript (Type type, string key, string script, bool addScriptTags)
  337. {
  338. if (type == null)
  339. throw new ArgumentNullException ("type");
  340. RegisterScript (ref startupScriptBlocks, type, key, script, addScriptTags);
  341. }
  342. public void RegisterClientScriptInclude (string key, string url)
  343. {
  344. RegisterClientScriptInclude (GetType (), key, url);
  345. }
  346. public void RegisterClientScriptInclude (Type type, string key, string url)
  347. {
  348. if (type == null)
  349. throw new ArgumentNullException ("type");
  350. if (url == null || url.Length == 0)
  351. throw new ArgumentException ("url");
  352. RegisterScript (ref clientScriptBlocks, type, "include-" + key, url, ScriptEntryFormat.Include);
  353. }
  354. #if NET_2_0
  355. public void RegisterClientScriptResource (Type type, string resourceName)
  356. {
  357. RegisterScript (ref clientScriptBlocks, type, "resource-" + resourceName, GetWebResourceUrl (type, resourceName), ScriptEntryFormat.Include);
  358. }
  359. public void RegisterExpandoAttribute (string controlId, string attributeName, string attributeValue)
  360. {
  361. RegisterExpandoAttribute (controlId, attributeName, attributeValue, true);
  362. }
  363. public void RegisterExpandoAttribute (string controlId, string attributeName, string attributeValue, bool encode)
  364. {
  365. if (controlId == null)
  366. throw new ArgumentNullException ("controlId");
  367. if (attributeName == null)
  368. throw new ArgumentNullException ("attributeName");
  369. if (expandoAttributes == null)
  370. expandoAttributes = new Hashtable ();
  371. ListDictionary list = (ListDictionary)expandoAttributes [controlId];
  372. if (list == null) {
  373. list = new ListDictionary ();
  374. expandoAttributes [controlId] = list;
  375. }
  376. list.Add (attributeName, encode ? StrUtils.EscapeQuotesAndBackslashes (attributeValue) : attributeValue);
  377. }
  378. void EnsureEventValidationArray ()
  379. {
  380. if (eventValidationValues == null || eventValidationValues.Length == 0)
  381. eventValidationValues = new int [64];
  382. int len = eventValidationValues.Length;
  383. if (eventValidationPos >= len) {
  384. int [] tmp = new int [len * 2];
  385. Array.Copy (eventValidationValues, tmp, len);
  386. eventValidationValues = tmp;
  387. }
  388. }
  389. internal void ResetEventValidationState ()
  390. {
  391. _pageInRender = true;
  392. eventValidationPos = 0;
  393. }
  394. // Implemented following the description in http://odetocode.com/Blogs/scott/archive/2006/03/20/3145.aspx
  395. int CalculateEventHash (string uniqueId, string argument)
  396. {
  397. int uniqueIdHash = uniqueId.GetHashCode ();
  398. int argumentHash = String.IsNullOrEmpty (argument) ? 0 : argument.GetHashCode ();
  399. return (uniqueIdHash ^ argumentHash);
  400. }
  401. public void RegisterForEventValidation (PostBackOptions options)
  402. {
  403. // MS.NET does not check for options == null, so we won't too...
  404. RegisterForEventValidation (options.TargetControl.UniqueID, options.Argument);
  405. }
  406. public void RegisterForEventValidation (string uniqueId)
  407. {
  408. RegisterForEventValidation (uniqueId, null);
  409. }
  410. public void RegisterForEventValidation (string uniqueId, string argument)
  411. {
  412. if (!page.EnableEventValidation)
  413. return;
  414. if (uniqueId == null || uniqueId.Length == 0)
  415. return;
  416. if (page.IsCallback)
  417. _hasRegisteredForEventValidationOnCallback = true;
  418. else if (!_pageInRender)
  419. throw new InvalidOperationException ("RegisterForEventValidation may only be called from the Render method");
  420. EnsureEventValidationArray ();
  421. int hash = CalculateEventHash (uniqueId, argument);
  422. for (int i = 0; i < eventValidationPos; i++)
  423. if (eventValidationValues [i] == hash)
  424. return;
  425. eventValidationValues [eventValidationPos++] = hash;
  426. }
  427. public void ValidateEvent (string uniqueId)
  428. {
  429. ValidateEvent (uniqueId, null);
  430. }
  431. ArgumentException InvalidPostBackException ()
  432. {
  433. return new ArgumentException ("Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation=\"true\"/> in configuration or <%@ Page EnableEventValidation=\"true\" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.");
  434. }
  435. public void ValidateEvent (string uniqueId, string argument)
  436. {
  437. if (uniqueId == null || uniqueId.Length == 0)
  438. throw new ArgumentException ("must not be null or empty", "uniqueId");
  439. if (!page.EnableEventValidation)
  440. return;
  441. if (eventValidationValues == null)
  442. throw InvalidPostBackException ();
  443. int hash = CalculateEventHash (uniqueId, argument);
  444. for (int i = 0; i < eventValidationValues.Length; i++)
  445. if (eventValidationValues [i] == hash)
  446. return;
  447. throw InvalidPostBackException ();
  448. }
  449. #endif
  450. void WriteScripts (HtmlTextWriter writer, ScriptEntry scriptList)
  451. {
  452. if (scriptList == null)
  453. return;
  454. writer.WriteLine ();
  455. while (scriptList != null) {
  456. switch (scriptList.Format) {
  457. case ScriptEntryFormat.AddScriptTag:
  458. EnsureBeginScriptBlock (writer);
  459. writer.Write (scriptList.Script);
  460. break;
  461. case ScriptEntryFormat.Include:
  462. EnsureEndScriptBlock (writer);
  463. WriteClientScriptInclude (writer, scriptList.Script, scriptList.Type, scriptList.Key);
  464. break;
  465. default:
  466. EnsureEndScriptBlock (writer);
  467. writer.WriteLine (scriptList.Script);
  468. break;
  469. }
  470. scriptList = scriptList.Next;
  471. }
  472. EnsureEndScriptBlock (writer);
  473. }
  474. bool _scriptTagOpened;
  475. void EnsureBeginScriptBlock (HtmlTextWriter writer) {
  476. if (!_scriptTagOpened) {
  477. WriteBeginScriptBlock (writer);
  478. _scriptTagOpened = true;
  479. }
  480. }
  481. void EnsureEndScriptBlock (HtmlTextWriter writer) {
  482. if (_scriptTagOpened) {
  483. WriteEndScriptBlock (writer);
  484. _scriptTagOpened = false;
  485. }
  486. }
  487. #if NET_2_0
  488. internal void RestoreEventValidationState (string fieldValue)
  489. {
  490. if (!page.EnableEventValidation || fieldValue == null || fieldValue.Length == 0)
  491. return;
  492. IStateFormatter fmt = page.GetFormatter ();
  493. eventValidationValues = (int []) fmt.Deserialize (fieldValue);
  494. eventValidationPos = eventValidationValues.Length;
  495. }
  496. internal void SaveEventValidationState ()
  497. {
  498. if (!page.EnableEventValidation)
  499. return;
  500. string eventValidation = GetEventValidationStateFormatted ();
  501. if (eventValidation == null)
  502. return;
  503. RegisterHiddenField (EventStateFieldName, eventValidation);
  504. }
  505. internal string GetEventValidationStateFormatted ()
  506. {
  507. if (eventValidationValues == null || eventValidationValues.Length == 0)
  508. return null;
  509. if(page.IsCallback && !_hasRegisteredForEventValidationOnCallback)
  510. return null;
  511. IStateFormatter fmt = page.GetFormatter ();
  512. int [] array = new int [eventValidationPos];
  513. Array.Copy (eventValidationValues, array, eventValidationPos);
  514. return fmt.Serialize (array);
  515. }
  516. internal void WriteExpandoAttributes (HtmlTextWriter writer)
  517. {
  518. if (expandoAttributes == null)
  519. return;
  520. writer.WriteLine ();
  521. WriteBeginScriptBlock (writer);
  522. foreach (string controlId in expandoAttributes.Keys) {
  523. writer.WriteLine ("var {0} = document.all ? document.all [\"{0}\"] : document.getElementById (\"{0}\");", controlId);
  524. ListDictionary attrs = (ListDictionary) expandoAttributes [controlId];
  525. foreach (string attributeName in attrs.Keys) {
  526. writer.WriteLine ("{0}.{1} = \"{2}\";", controlId, attributeName, attrs [attributeName]);
  527. }
  528. }
  529. WriteEndScriptBlock (writer);
  530. writer.WriteLine ();
  531. }
  532. #endif
  533. #if NET_2_0
  534. internal const string SCRIPT_BLOCK_START = "//<![CDATA[";
  535. internal const string SCRIPT_BLOCK_END = "//]]>";
  536. internal const string SCRIPT_ELEMENT_START = @"<script type=""text/javascript"">" + SCRIPT_BLOCK_START;
  537. #else
  538. internal const string SCRIPT_BLOCK_START = "<!--";
  539. internal const string SCRIPT_BLOCK_END ="// -->";
  540. internal const string SCRIPT_ELEMENT_START = @"<script language=""javascript"" type=""text/javascript"">" + SCRIPT_BLOCK_START;
  541. #endif
  542. internal const string SCRIPT_ELEMENT_END = SCRIPT_BLOCK_END + "</script>";
  543. internal static void WriteBeginScriptBlock (HtmlTextWriter writer)
  544. {
  545. writer.WriteLine (SCRIPT_ELEMENT_START);
  546. }
  547. internal static void WriteEndScriptBlock (HtmlTextWriter writer)
  548. {
  549. writer.WriteLine (SCRIPT_ELEMENT_END);
  550. }
  551. internal void WriteHiddenFields (HtmlTextWriter writer)
  552. {
  553. if (hiddenFields == null)
  554. return;
  555. #if NET_2_0
  556. writer.WriteLine ();
  557. writer.RenderBeginTag (HtmlTextWriterTag.Div);
  558. int oldIndent = writer.Indent;
  559. writer.Indent = 0;
  560. bool first = true;
  561. #endif
  562. foreach (string key in hiddenFields.Keys) {
  563. string value = hiddenFields [key] as string;
  564. if (first)
  565. first = false;
  566. else
  567. writer.WriteLine ();
  568. #if NET_2_0
  569. writer.Write ("<input type=\"hidden\" name=\"{0}\" id=\"{0}\" value=\"{1}\" />", key, HttpUtility.HtmlAttributeEncode (value));
  570. #else
  571. writer.Write ("<input type=\"hidden\" name=\"{0}\" value=\"{1}\" />", key, HttpUtility.HtmlAttributeEncode (value));
  572. #endif
  573. }
  574. #if NET_2_0
  575. writer.Indent = oldIndent;
  576. writer.RenderEndTag (); // DIV
  577. writer.WriteLine ();
  578. #endif
  579. hiddenFields = null;
  580. }
  581. internal void WriteClientScriptInclude (HtmlTextWriter writer, string path, Type type, string key) {
  582. if (!page.IsMultiForm)
  583. writer.WriteLine ("<script src=\"{0}\" type=\"text/javascript\"></script>", path);
  584. else {
  585. string scriptKey = "inc_" + (type.FullName + key).GetHashCode ().ToString ("X");
  586. writer.WriteLine ("<script type=\"text/javascript\">");
  587. writer.WriteLine (SCRIPT_BLOCK_START);
  588. writer.WriteLine ("if (!window.{0}) {{", scriptKey);
  589. writer.WriteLine ("\twindow.{0} = true", scriptKey);
  590. writer.WriteLine ("\tdocument.write('<script src=\"{0}\" type=\"text/javascript\"><\\/script>'); }}", path);
  591. writer.WriteLine (SCRIPT_BLOCK_END);
  592. writer.WriteLine ("</script>");
  593. }
  594. }
  595. internal void WriteClientScriptBlocks (HtmlTextWriter writer)
  596. {
  597. WriteScripts (writer, clientScriptBlocks);
  598. }
  599. internal void WriteStartupScriptBlocks (HtmlTextWriter writer)
  600. {
  601. WriteScripts (writer, startupScriptBlocks);
  602. }
  603. internal void WriteArrayDeclares (HtmlTextWriter writer)
  604. {
  605. if (registeredArrayDeclares != null) {
  606. writer.WriteLine();
  607. WriteBeginScriptBlock (writer);
  608. IDictionaryEnumerator arrayEnum = registeredArrayDeclares.GetEnumerator();
  609. while (arrayEnum.MoveNext()) {
  610. if (page.IsMultiForm)
  611. writer.Write ("\t" + page.theForm + ".");
  612. else
  613. writer.Write ("\tvar ");
  614. writer.Write(arrayEnum.Key);
  615. writer.Write(" = new Array(");
  616. IEnumerator arrayListEnum = ((ArrayList) arrayEnum.Value).GetEnumerator();
  617. bool isFirst = true;
  618. while (arrayListEnum.MoveNext()) {
  619. if (isFirst)
  620. isFirst = false;
  621. else
  622. writer.Write(", ");
  623. writer.Write(arrayListEnum.Current);
  624. }
  625. writer.WriteLine(");");
  626. }
  627. WriteEndScriptBlock (writer);
  628. writer.WriteLine ();
  629. }
  630. }
  631. #if NET_2_0
  632. internal string GetClientValidationEvent (string validationGroup) {
  633. if (page.IsMultiForm)
  634. return "if (typeof(" + page.theForm + ".Page_ClientValidate) == 'function') " + page.theForm + ".Page_ClientValidate('" + validationGroup + "');";
  635. return "if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate('" + validationGroup + "');";
  636. }
  637. #endif
  638. internal string GetClientValidationEvent ()
  639. {
  640. if (page.IsMultiForm)
  641. return "if (typeof(" + page.theForm + ".Page_ClientValidate) == 'function') " + page.theForm + ".Page_ClientValidate();";
  642. return "if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate();";
  643. }
  644. internal string WriteSubmitStatements ()
  645. {
  646. if (submitStatements == null) return null;
  647. StringBuilder sb = new StringBuilder ();
  648. ScriptEntry entry = submitStatements;
  649. while (entry != null) {
  650. #if NET_2_0
  651. sb.Append (EnsureEndsWithSemicolon (entry.Script));
  652. #else
  653. sb.Append (entry.Script);
  654. #endif
  655. entry = entry.Next;
  656. }
  657. #if NET_2_0
  658. RegisterClientScriptBlock (GetType(), "HtmlForm-OnSubmitStatemen",
  659. @"
  660. " + page.WebFormScriptReference + @".WebForm_OnSubmit = function () {
  661. " + sb.ToString () + @"
  662. return true;
  663. }
  664. ", true);
  665. return "javascript:return " + page.WebFormScriptReference + ".WebForm_OnSubmit();";
  666. #else
  667. return sb.ToString ();
  668. #endif
  669. }
  670. internal static string GetScriptLiteral (object ob)
  671. {
  672. if (ob == null)
  673. return "null";
  674. else if (ob is string) {
  675. string s = (string)ob;
  676. bool escape = false;
  677. int len = s.Length;
  678. for (int i = 0; i < len; i++)
  679. if (s [i] == '\\' || s [i] == '\"') {
  680. escape = true;
  681. break;
  682. }
  683. if (!escape)
  684. return string.Concat ("\"", s, "\"");
  685. StringBuilder sb = new StringBuilder (len + 10);
  686. sb.Append ('\"');
  687. for (int si = 0; si < len; si++) {
  688. if (s [si] == '\"')
  689. sb.Append ("\\\"");
  690. else if (s [si] == '\\')
  691. sb.Append ("\\\\");
  692. else
  693. sb.Append (s [si]);
  694. }
  695. sb.Append ('\"');
  696. return sb.ToString ();
  697. } else if (ob is bool) {
  698. return ob.ToString ().ToLower (Helpers.InvariantCulture);
  699. } else {
  700. return ob.ToString ();
  701. }
  702. }
  703. sealed class ScriptEntry
  704. {
  705. public readonly Type Type;
  706. public readonly string Key;
  707. public readonly string Script;
  708. public readonly ScriptEntryFormat Format;
  709. public ScriptEntry Next;
  710. public ScriptEntry (Type type, string key, string script, ScriptEntryFormat format) {
  711. Key = key;
  712. Type = type;
  713. Script = script;
  714. Format = format;
  715. }
  716. }
  717. enum ScriptEntryFormat
  718. {
  719. None,
  720. AddScriptTag,
  721. Include,
  722. }
  723. #if NET_2_0
  724. // helper method
  725. internal static string EnsureEndsWithSemicolon (string value) {
  726. if (value != null && value.Length > 0 && value [value.Length - 1] != ';')
  727. return value += ";";
  728. return value;
  729. }
  730. #endif
  731. }
  732. }