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