Merge pull request #1218 from AndreyAkinshin/master
[mono.git] / mcs / class / System.Web.Extensions / System.Web.UI / ScriptManager.cs
1 //
2 // ScriptManager.cs
3 //
4 // Authors:
5 //   Igor Zelmanovich <igorz@mainsoft.com>
6 //   Marek Habersack <grendel@twistedcode.net>
7 //
8 // (C) 2007 Mainsoft, Inc.  http://www.mainsoft.com
9 // (C) 2007-2010 Novell, Inc (http://novell.com/)
10 //
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System;
33 using System.Collections.Generic;
34 using System.Text;
35 using System.ComponentModel;
36 using System.Security.Permissions;
37 using System.Collections.Specialized;
38 using System.Collections;
39 using System.Web.Handlers;
40 using System.Reflection;
41 using System.Web.Configuration;
42 using System.Web.UI.HtmlControls;
43 using System.IO;
44 using System.Globalization;
45 using System.Threading;
46 using System.Web.Script.Serialization;
47 using System.Web.Script.Services;
48 using System.Xml;
49 using System.Collections.ObjectModel;
50 using System.Web.Util;
51
52 namespace System.Web.UI
53 {
54         [ParseChildrenAttribute (true)]
55         [DefaultPropertyAttribute ("Scripts")]
56         [DesignerAttribute ("System.Web.UI.Design.ScriptManagerDesigner, System.Web.Extensions.Design, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")]
57         [NonVisualControlAttribute]
58         [PersistChildrenAttribute (false)]
59         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
60         [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
61         public class ScriptManager : Control, IPostBackDataHandler, IScriptManager
62         {
63                 // the keywords are used in fomatting async response
64                 const string updatePanel = "updatePanel";
65                 const string hiddenField = "hiddenField";
66                 const string arrayDeclaration = "arrayDeclaration";
67                 const string scriptBlock = "scriptBlock";
68                 const string scriptStartupBlock = "scriptStartupBlock";
69                 const string expando = "expando";
70                 const string onSubmit = "onSubmit";
71                 const string asyncPostBackControlIDs = "asyncPostBackControlIDs";
72                 const string postBackControlIDs = "postBackControlIDs";
73                 const string updatePanelIDs = "updatePanelIDs";
74                 const string asyncPostBackTimeout = "asyncPostBackTimeout";
75                 const string childUpdatePanelIDs = "childUpdatePanelIDs";
76                 const string panelsToRefreshIDs = "panelsToRefreshIDs";
77                 const string formAction = "formAction";
78                 const string dataItem = "dataItem";
79                 const string dataItemJson = "dataItemJson";
80                 const string scriptDispose = "scriptDispose";
81                 const string pageRedirect = "pageRedirect";
82                 const string error = "error";
83                 const string pageTitle = "pageTitle";
84                 const string focus = "focus";
85                 const string scriptContentNoTags = "ScriptContentNoTags";
86                 const string scriptContentWithTags = "ScriptContentWithTags";
87                 const string scriptPath = "ScriptPath";
88
89                 static readonly object ScriptManagerKey = typeof (IScriptManager);
90
91                 int _asyncPostBackTimeout = 90;
92                 List<Control> _asyncPostBackControls;
93                 List<Control> _postBackControls;
94                 List<UpdatePanel> _childUpdatePanels;
95                 List<UpdatePanel> _panelsToRefresh;
96                 List<UpdatePanel> _updatePanels;
97                 ScriptReferenceCollection _scripts;
98                 CompositeScriptReference _compositeScript;
99                 ServiceReferenceCollection _services;
100                 bool _isInAsyncPostBack;
101                 bool _isInPartialRendering;
102                 string _asyncPostBackSourceElementID;
103                 ScriptMode _scriptMode = ScriptMode.Auto;
104                 bool _enableScriptGlobalization;
105                 bool _enableScriptLocalization;
106                 string _scriptPath;
107                 List<RegisteredScript> _clientScriptBlocks;
108                 List<RegisteredScript> _startupScriptBlocks;
109                 List<RegisteredScript> _onSubmitStatements;
110                 List<RegisteredArrayDeclaration> _arrayDeclarations;
111                 List<RegisteredExpandoAttribute> _expandoAttributes;
112                 List<RegisteredHiddenField> _hiddenFields;
113                 List<IScriptControl> _registeredScriptControls;
114                 Dictionary<IExtenderControl, Control> _registeredExtenderControls;
115                 bool? _supportsPartialRendering;
116                 bool _enablePartialRendering = true;
117                 bool _init;
118                 string _panelToRefreshID;
119                 Dictionary<Control, DataItemEntry> _dataItems;
120                 bool _enablePageMethods;
121                 string _controlIDToFocus;
122                 bool _allowCustomErrorsRedirect = true;
123                 string _asyncPostBackErrorMessage;
124                 List<RegisteredDisposeScript> _disposeScripts;
125                 List<ScriptReferenceEntry> _scriptToRegister;
126                 bool _loadScriptsBeforeUI = true;
127                 AuthenticationServiceManager _authenticationService;
128                 ProfileServiceManager _profileService;
129                 List<ScriptManagerProxy> _proxies;
130
131                 [DefaultValue (true)]
132                 [Category ("Behavior")]
133                 public bool AllowCustomErrorsRedirect {
134                         get {
135                                 return _allowCustomErrorsRedirect;
136                         }
137                         set {
138                                 _allowCustomErrorsRedirect = value;
139                         }
140                 }
141
142                 [Category ("Behavior")]
143                 [DefaultValue ("")]
144                 public string AsyncPostBackErrorMessage {
145                         get {
146                                 if (String.IsNullOrEmpty (_asyncPostBackErrorMessage))
147                                         return String.Empty;
148                                 return _asyncPostBackErrorMessage;
149                         }
150                         set {
151                                 _asyncPostBackErrorMessage = value;
152                         }
153                 }
154
155                 [Browsable (false)]
156                 public string AsyncPostBackSourceElementID {
157                         get {
158                                 if (_asyncPostBackSourceElementID == null)
159                                         return String.Empty;
160                                 return _asyncPostBackSourceElementID;
161                         }
162                 }
163
164                 [DefaultValue (90)]
165                 [Category ("Behavior")]
166                 public int AsyncPostBackTimeout {
167                         get {
168                                 return _asyncPostBackTimeout;
169                         }
170                         set {
171                                 _asyncPostBackTimeout = value;
172                         }
173                 }
174
175                 [Category ("Behavior")]
176                 [MergableProperty (false)]
177                 [DefaultValue ("")]
178                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
179                 [PersistenceMode (PersistenceMode.InnerProperty)]
180                 public AuthenticationServiceManager AuthenticationService {
181                         get {
182                                 if (_authenticationService == null)
183                                         _authenticationService = new AuthenticationServiceManager ();
184                                 return _authenticationService;
185                         }
186                 }
187
188                 [Category ("Behavior")]
189                 [DefaultValue (false)]
190                 public bool EnablePageMethods {
191                         get {
192                                 return _enablePageMethods;
193                         }
194                         set {
195                                 _enablePageMethods = value;
196                         }
197                 }
198
199                 [DefaultValue (true)]
200                 [Category ("Behavior")]
201                 public bool EnablePartialRendering {
202                         get {
203                                 return _enablePartialRendering;
204                         }
205                         set {
206                                 if (_init)
207                                         throw new InvalidOperationException ();
208                                 _enablePartialRendering = value;
209                         }
210                 }
211
212                 [DefaultValue (false)]
213                 [Category ("Behavior")]
214                 public bool EnableScriptGlobalization {
215                         get {
216                                 return _enableScriptGlobalization;
217                         }
218                         set {
219                                 _enableScriptGlobalization = value;
220                         }
221                 }
222
223                 [Category ("Behavior")]
224                 [DefaultValue (false)]
225                 public bool EnableScriptLocalization {
226                         get {
227                                 return _enableScriptLocalization;
228                         }
229                         set {
230                                 _enableScriptLocalization = value;
231                         }
232                 }
233
234                 [Browsable (false)]
235                 public bool IsDebuggingEnabled {
236                         get {
237                                 if (IsDeploymentRetail)
238                                         return false;
239
240                                 if (!RuntimeHelpers.DebuggingEnabled && (ScriptMode == ScriptMode.Auto || ScriptMode == ScriptMode.Inherit))
241                                         return false;
242
243                                 if (ScriptMode == ScriptMode.Release)
244                                         return false;
245
246                                 return true;
247                         }
248                 }
249
250                 internal bool IsDeploymentRetail {
251                         get {
252                                 DeploymentSection deployment = (DeploymentSection) WebConfigurationManager.GetSection ("system.web/deployment");
253                                 return deployment.Retail;
254                         }
255                 }
256
257                 [Browsable (false)]
258                 public bool IsInAsyncPostBack {
259                         get {
260                                 return _isInAsyncPostBack;
261                         }
262                 }
263
264                 internal bool IsInPartialRendering {
265                         get {
266                                 return _isInPartialRendering;
267                         }
268                         set {
269                                 _isInPartialRendering = value;
270                         }
271                 }
272
273                 [Category ("Behavior")]
274                 [DefaultValue (true)]
275                 public bool LoadScriptsBeforeUI {
276                         get {
277                                 return _loadScriptsBeforeUI;
278                         }
279                         set {
280                                 _loadScriptsBeforeUI = value;
281                         }
282                 }
283
284                 [PersistenceMode (PersistenceMode.InnerProperty)]
285                 [DefaultValue ("")]
286                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
287                 [Category ("Behavior")]
288                 [MergableProperty (false)]
289                 public ProfileServiceManager ProfileService {
290                         get {
291                                 if (_profileService == null)
292                                         _profileService = new ProfileServiceManager ();
293                                 return _profileService;
294                         }
295                 }
296
297                 [Category ("Behavior")]
298                 public ScriptMode ScriptMode {
299                         get {
300                                 return _scriptMode;
301                         }
302                         set {
303                                 if (value == ScriptMode.Inherit)
304                                         value = ScriptMode.Auto;
305                                 _scriptMode = value;
306                         }
307                 }
308
309                 [DefaultValue ("")]
310                 [Category ("Behavior")]
311                 public string ScriptPath {
312                         get {
313                                 if (_scriptPath == null)
314                                         return String.Empty;
315                                 return _scriptPath;
316                         }
317                         set {
318                                 _scriptPath = value;
319                         }
320                 }
321
322                 [PersistenceMode (PersistenceMode.InnerProperty)]
323                 [DefaultValue ("")]
324                 [Category ("Behavior")]
325                 [MergableProperty (false)]
326                 public ScriptReferenceCollection Scripts {
327                         get {
328                                 if (_scripts == null)
329                                         _scripts = new ScriptReferenceCollection ();
330
331                                 return _scripts;
332                         }
333                 }
334                 [PersistenceMode (PersistenceMode.InnerProperty)]
335                 [Category ("Behavior")]
336                 [DefaultValue (null)]
337                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
338                 [MergableProperty (false)]
339                 public CompositeScriptReference CompositeScript {
340                         get {
341                                 if (_compositeScript == null)
342                                         _compositeScript = new CompositeScriptReference ();
343                                 return _compositeScript;
344                         }
345                 }
346                 [PersistenceMode (PersistenceMode.InnerProperty)]
347                 [DefaultValue ("")]
348                 [MergableProperty (false)]
349                 [Category ("Behavior")]
350                 public ServiceReferenceCollection Services {
351                         get {
352                                 if (_services == null)
353                                         _services = new ServiceReferenceCollection ();
354
355                                 return _services;
356                         }
357                 }
358
359                 [DefaultValue (true)]
360                 [Browsable (false)]
361                 public bool SupportsPartialRendering {
362                         get {
363                                 if (!_supportsPartialRendering.HasValue)
364                                         _supportsPartialRendering = CheckSupportsPartialRendering ();
365                                 return _supportsPartialRendering.Value;
366                         }
367                         set {
368                                 if (_init)
369                                         throw new InvalidOperationException ();
370                                 if (!EnablePartialRendering && value)
371                                         throw new InvalidOperationException ("The SupportsPartialRendering property cannot be set when EnablePartialRendering is false.");
372
373                                 _supportsPartialRendering = value;
374                         }
375                 }
376
377                 bool CheckSupportsPartialRendering () {
378                         if (!EnablePartialRendering)
379                                 return false;
380                         // TODO: consider browser capabilities
381                         return true;
382                 }
383
384                 [EditorBrowsable (EditorBrowsableState.Never)]
385                 [Browsable (false)]
386                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
387                 public override bool Visible {
388                         get {
389                                 return true;
390                         }
391                         set {
392                                 throw new NotImplementedException ();
393                         }
394                 }
395
396                 [Category ("Action")]
397                 public event EventHandler<AsyncPostBackErrorEventArgs> AsyncPostBackError;
398
399                 [Category ("Action")]
400                 public event EventHandler<ScriptReferenceEventArgs> ResolveScriptReference;
401                 [Category ("Action")]
402                 public event EventHandler<CompositeScriptReferenceEventArgs> ResolveCompositeScriptReference;
403                 public static ScriptManager GetCurrent (Page page) {
404                         if (page == null)
405                                 throw new ArgumentNullException ("page");
406                         return GetCurrentInternal (page);
407                 }
408
409                 internal static ScriptManager GetCurrentInternal (Page page)
410                 {
411                         if (page == null)
412                                 return null;
413
414                         return (ScriptManager) page.Items [ScriptManagerKey];
415                 }
416                 
417                 static void SetCurrent (Page page, ScriptManager instance) {
418                         page.Items [ScriptManagerKey] = instance;
419                         page.ClientScript.RegisterWebFormClientScript ();
420                 }
421
422                 UpdatePanel FindPanelWithId (string id)
423                 {
424                         if (_updatePanels == null)
425                                 return null;
426                         foreach (UpdatePanel panel in _updatePanels) {
427                                 if (panel.ID == id)
428                                         return panel;
429                         }
430                         return null;
431                 }
432                 
433                 protected virtual bool LoadPostData (string postDataKey, NameValueCollection postCollection) {
434                         _isInAsyncPostBack = true;
435                         string arg = postCollection [postDataKey];
436                         if (!String.IsNullOrEmpty (arg)) {
437                                 string [] args = arg.Split ('|');
438                                 switch (args.Length) {
439                                         case 1:
440                                                 _asyncPostBackSourceElementID = args [0];
441                                                 break;
442
443                                         case 2:
444                                                 _panelToRefreshID = args [0];
445                                                 _asyncPostBackSourceElementID = args [1];
446                                                 break;
447
448                                         default: // "impossible situation"
449                                                 throw new InvalidOperationException ("Unexpected format of post data.");
450                                 }
451                                 
452                                 return true;
453                         }
454                         return false;
455                 }
456
457                 protected internal virtual void OnAsyncPostBackError (AsyncPostBackErrorEventArgs e) {
458                         if (AsyncPostBackError != null)
459                                 AsyncPostBackError (this, e);
460                 }
461
462                 protected internal override void OnInit (EventArgs e) {
463                         base.OnInit (e);
464
465                         if (GetCurrentInternal (Page) != null)
466                                 throw new InvalidOperationException ("Only one instance of a ScriptManager can be added to the page.");
467
468                         SetCurrent (Page, this);
469                         Page.Error += new EventHandler (OnPageError);
470                         _init = true;
471                 }
472
473                 void OnPageError (object sender, EventArgs e) {
474                         if (IsInAsyncPostBack)
475                                 OnAsyncPostBackError (new AsyncPostBackErrorEventArgs (Context.Error));
476                 }
477
478                 protected internal override void OnPreRender (EventArgs e) {
479                         base.OnPreRender (e);
480
481                         Page.PreRenderComplete += new EventHandler (OnPreRenderComplete);
482
483                         if (IsInAsyncPostBack) {
484                                 Page.SetRenderMethodDelegate (RenderPageCallback);
485                         }
486                         else {
487                                 if (EnableScriptGlobalization) {
488                                         CultureInfo culture = Thread.CurrentThread.CurrentCulture;
489                                         string script = String.Format ("var __cultureInfo = '{0}';", JavaScriptSerializer.DefaultSerializer.Serialize (new CultureInfoSerializer (culture)));
490                                         RegisterClientScriptBlock (this, typeof (ScriptManager), "ScriptGlobalization", script, true);
491                                 }
492
493                                 // Register dispose script
494                                 if (_disposeScripts != null && _disposeScripts.Count > 0) {
495                                         StringBuilder sb = new StringBuilder ();
496                                         sb.AppendLine ();
497                                         for (int i = 0; i < _disposeScripts.Count; i++) {
498                                                 RegisteredDisposeScript entry = _disposeScripts [i];
499                                                 if (IsMultiForm)
500                                                         sb.Append ("Sys.WebForms.PageRequestManager.getInstance($get(\"" + Page.Form.ClientID + "\"))._registerDisposeScript(\"");
501                                                 else
502                                                         sb.Append ("Sys.WebForms.PageRequestManager.getInstance()._registerDisposeScript(\"");
503                                                 sb.Append (entry.UpdatePanel.ClientID);
504                                                 sb.Append ("\", ");
505                                                 sb.Append (JavaScriptSerializer.DefaultSerializer.Serialize (entry.Script)); //JavaScriptSerializer.Serialize used escape script literal 
506                                                 sb.AppendLine (");");
507                                         }
508                                         RegisterStartupScript (this, typeof (ExtenderControl), "disposeScripts;", sb.ToString (), true);
509                                 }
510
511 #if TARGET_DOTNET
512                                 // to cause webform client script being included
513                                 Page.ClientScript.GetPostBackEventReference (new PostBackOptions (this, null, null, false, false, false, true, true, null));
514 #else
515                                 Page.ClientScript.GetPostBackEventReference (this, null);
516 #endif
517                         }
518                 }
519
520                 ScriptReference CreateScriptReference (string path, string assembly, bool notifyScriptLoaded)
521                 {
522                         var ret = new ScriptReference (path, assembly);
523                         if (!notifyScriptLoaded)
524                                 ret.NotifyScriptLoaded = false;
525                         OnResolveScriptReference (new ScriptReferenceEventArgs (ret));
526
527                         return ret;
528                 }
529
530                 ScriptReference CreateScriptReference (string path, string assembly)
531                 {
532                         return CreateScriptReference (path, assembly, true);
533                 }
534                 
535                 void OnPreRenderComplete (object sender, EventArgs e)
536                 {
537                         // Resolve Scripts
538                         ScriptReference ajaxScript = CreateScriptReference ("MicrosoftAjax.js", String.Empty, false);
539                         ScriptReference ajaxWebFormsScript = CreateScriptReference ("MicrosoftAjaxWebForms.js", String.Empty, false);
540                         ScriptReference ajaxExtensionScript = null;
541                         ScriptReference ajaxWebFormsExtensionScript = null;
542                         if (IsMultiForm) {
543                                 ajaxExtensionScript = CreateScriptReference ("MicrosoftAjaxExtension.js", String.Empty);
544                                 ajaxWebFormsExtensionScript = CreateScriptReference ("MicrosoftAjaxWebFormsExtension.js", String.Empty);
545                         }
546
547                         foreach (ScriptReferenceEntry script in GetScriptReferences ()) {
548                                 OnResolveScriptReference (new ScriptReferenceEventArgs (script.ScriptReference));
549                                         if (_scriptToRegister == null)
550                                                 _scriptToRegister = new List<ScriptReferenceEntry> ();
551                                         _scriptToRegister.Add (script);
552                         }
553
554                         if (!IsInAsyncPostBack) {
555                                 // Register Ajax framework script.
556                                 RegisterScriptReference (this, ajaxScript, true);
557                                 if (IsMultiForm) {
558                                         RegisterScriptReference (this, ajaxExtensionScript, true);
559                                         RegisterClientScriptBlock (this, typeof (ScriptManager), "Sys.Application", "\nSys.Application._initialize(document.getElementById('" + Page.Form.ClientID + "'));\n", true);
560                                 }
561
562                                 StringBuilder sb = new StringBuilder ();
563                                 sb.AppendLine ("if (typeof(Sys) === 'undefined') throw new Error('ASP.NET Ajax client-side framework failed to load.');");
564
565                                 ScriptingProfileServiceSection profileService = (ScriptingProfileServiceSection) WebConfigurationManager.GetSection ("system.web.extensions/scripting/webServices/profileService");
566                                 if (profileService != null && profileService.Enabled)
567                                         sb.AppendLine ("Sys.Services._ProfileService.DefaultWebServicePath = '" + ResolveClientUrl ("~" + System.Web.Script.Services.ProfileService.DefaultWebServicePath) + "';");
568                                 string profileServicePath = GetProfileServicePath ();
569                                 if (!String.IsNullOrEmpty (profileServicePath))
570                                         sb.AppendLine ("Sys.Services.ProfileService.set_path('" + profileServicePath + "');");
571
572                                 ScriptingAuthenticationServiceSection authenticationService = (ScriptingAuthenticationServiceSection) WebConfigurationManager.GetSection ("system.web.extensions/scripting/webServices/authenticationService");
573                                 if (authenticationService != null && authenticationService.Enabled) {
574                                         sb.AppendLine ("Sys.Services._AuthenticationService.DefaultWebServicePath = '" + ResolveClientUrl ("~/Authentication_JSON_AppService.axd") + "';");
575                                         if (Page.User.Identity.IsAuthenticated)
576                                                 sb.AppendLine ("Sys.Services.AuthenticationService._setAuthenticated(true);");
577                                 }
578                                 string authenticationServicePath = GetAuthenticationServicePath ();
579                                 if (!String.IsNullOrEmpty (authenticationServicePath))
580                                         sb.AppendLine ("Sys.Services.AuthenticationService.set_path('" + authenticationServicePath + "');");
581
582                                 RegisterClientScriptBlock (this, typeof (ScriptManager), "Framework", sb.ToString (), true);
583
584                                 RegisterScriptReference (this, ajaxWebFormsScript, true);
585
586                                 if (IsMultiForm)
587                                         RegisterScriptReference (this, ajaxWebFormsExtensionScript, true);
588                         }
589                         if (_compositeScript != null && _compositeScript.HaveScripts ()) {
590                                 OnResolveCompositeScriptReference (new CompositeScriptReferenceEventArgs (_compositeScript));
591                                 RegisterScriptReference (this, _compositeScript, true);
592                         }
593                         // Register Scripts
594                         if (_scriptToRegister != null)
595                                 for (int i = 0; i < _scriptToRegister.Count; i++)
596                                         RegisterScriptReference (_scriptToRegister [i].Control, _scriptToRegister [i].ScriptReference, _scriptToRegister [i].LoadScriptsBeforeUI);
597
598                         if (!IsInAsyncPostBack) {
599                                 // Register services
600                                 if (_services != null && _services.Count > 0) {
601                                         for (int i = 0; i < _services.Count; i++) {
602                                                 RegisterServiceReference (this, _services [i]);
603                                         }
604                                 }
605
606                                 if (_proxies != null && _proxies.Count > 0) {
607                                         for (int i = 0; i < _proxies.Count; i++) {
608                                                 ScriptManagerProxy proxy = _proxies [i];
609                                                 for (int j = 0; j < proxy.Services.Count; j++) {
610                                                         RegisterServiceReference (proxy, proxy.Services [j]);
611                                                 }
612                                         }
613                                 }
614
615                                 if (EnablePageMethods) {
616                                         LogicalTypeInfo logicalTypeInfo = LogicalTypeInfo.GetLogicalTypeInfo (Page.GetType (), Page.Request.FilePath);
617                                         RegisterClientScriptBlock (this, typeof (ScriptManager), "PageMethods", logicalTypeInfo.Proxy, true);
618                                 }
619
620                                 // Register startup script
621                                 if (IsMultiForm)
622                                         RegisterStartupScript (this, typeof (ExtenderControl), "Sys.Application.initialize();", "Sys.Application.getInstance($get(\"" + Page.Form.ClientID + "\")).initialize();\n", true);
623                                 else
624                                         RegisterStartupScript (this, typeof (ExtenderControl), "Sys.Application.initialize();", "Sys.Application.initialize();\n", true);
625                         }
626                 }
627
628                 string GetProfileServicePath () {
629                         if (_profileService != null && !String.IsNullOrEmpty (_profileService.Path))
630                                 return ResolveClientUrl (_profileService.Path);
631
632                         if (_proxies != null && _proxies.Count > 0)
633                                 for (int i = 0; i < _proxies.Count; i++)
634                                         if (!String.IsNullOrEmpty (_proxies [i].ProfileService.Path))
635                                                 return _proxies [i].ResolveClientUrl (_proxies [i].ProfileService.Path);
636                         return null;
637                 }
638
639                 string GetAuthenticationServicePath () {
640                         if (_authenticationService != null && !String.IsNullOrEmpty (_authenticationService.Path))
641                                 return ResolveClientUrl (_authenticationService.Path);
642
643                         if (_proxies != null && _proxies.Count > 0)
644                                 for (int i = 0; i < _proxies.Count; i++)
645                                         if (!String.IsNullOrEmpty (_proxies [i].AuthenticationService.Path))
646                                                 return _proxies [i].ResolveClientUrl (_proxies [i].AuthenticationService.Path);
647                         return null;
648                 }
649
650                 public ReadOnlyCollection<RegisteredArrayDeclaration> GetRegisteredArrayDeclarations () {
651                         if (_arrayDeclarations == null)
652                                 _arrayDeclarations = new List<RegisteredArrayDeclaration> ();
653                         return new ReadOnlyCollection<RegisteredArrayDeclaration> (_arrayDeclarations);
654                 }
655
656                 public ReadOnlyCollection<RegisteredScript> GetRegisteredClientScriptBlocks () {
657                         if (_clientScriptBlocks == null)
658                                 _clientScriptBlocks = new List<RegisteredScript> ();
659                         return new ReadOnlyCollection<RegisteredScript> (_clientScriptBlocks);
660                 }
661
662                 public ReadOnlyCollection<RegisteredDisposeScript> GetRegisteredDisposeScripts () {
663                         if (_disposeScripts == null)
664                                 _disposeScripts = new List<RegisteredDisposeScript> ();
665                         return new ReadOnlyCollection<RegisteredDisposeScript> (_disposeScripts);
666                 }
667
668                 public ReadOnlyCollection<RegisteredExpandoAttribute> GetRegisteredExpandoAttributes () {
669                         if (_expandoAttributes == null)
670                                 _expandoAttributes = new List<RegisteredExpandoAttribute> ();
671                         return new ReadOnlyCollection<RegisteredExpandoAttribute> (_expandoAttributes);
672                 }
673
674                 public ReadOnlyCollection<RegisteredHiddenField> GetRegisteredHiddenFields () {
675                         if (_hiddenFields == null)
676                                 _hiddenFields = new List<RegisteredHiddenField> ();
677                         return new ReadOnlyCollection<RegisteredHiddenField> (_hiddenFields);
678                 }
679
680                 public ReadOnlyCollection<RegisteredScript> GetRegisteredOnSubmitStatements () {
681                         if (_onSubmitStatements == null)
682                                 _onSubmitStatements = new List<RegisteredScript> ();
683                         return new ReadOnlyCollection<RegisteredScript> (_onSubmitStatements);
684                 }
685
686                 public ReadOnlyCollection<RegisteredScript> GetRegisteredStartupScripts () {
687                         if (_startupScriptBlocks == null)
688                                 _startupScriptBlocks = new List<RegisteredScript> ();
689                         return new ReadOnlyCollection<RegisteredScript> (_startupScriptBlocks);
690                 }
691
692                 bool IsMultiForm {
693                         get { return false; }
694                 }
695
696                 bool PanelRequiresUpdate (UpdatePanel panel)
697                 {
698                         if (panel == null || _panelsToRefresh == null || _panelsToRefresh.Count == 0)
699                                 return false;
700
701                         return _panelsToRefresh.Contains (panel);
702                 }
703                 
704                 bool HasBeenRendered (Control control)
705                 {
706                         if (control == null)
707                                 return false;
708
709                         UpdatePanel panel = control as UpdatePanel;
710                         if (PanelRequiresUpdate (panel))
711                                 return true;
712
713                         return HasBeenRendered (control.Parent);
714                 }
715
716                 IEnumerable<ScriptReferenceEntry> GetScriptReferences () {
717                         if (_scripts != null && _scripts.Count > 0) {
718                                 for (int i = 0; i < _scripts.Count; i++) {
719                                         yield return new ScriptReferenceEntry (this, _scripts [i], LoadScriptsBeforeUI);
720                                 }
721                         }
722
723                         if (_proxies != null && _proxies.Count > 0) {
724                                 for (int i = 0; i < _proxies.Count; i++) {
725                                         ScriptManagerProxy proxy = _proxies [i];
726                                         for (int j = 0; j < proxy.Scripts.Count; j++)
727                                                 yield return new ScriptReferenceEntry (proxy, proxy.Scripts [j], LoadScriptsBeforeUI);
728                                 }
729                         }
730
731                         if (_registeredScriptControls != null && _registeredScriptControls.Count > 0) {
732                                 for (int i = 0; i < _registeredScriptControls.Count; i++) {
733                                         IEnumerable<ScriptReference> scripts = _registeredScriptControls [i].GetScriptReferences ();
734                                         if (scripts != null)
735                                                 foreach (ScriptReference s in scripts)
736                                                         yield return new ScriptReferenceEntry ((Control) _registeredScriptControls [i], s, LoadScriptsBeforeUI);
737                                 }
738                         }
739
740                         if (_registeredExtenderControls != null && _registeredExtenderControls.Count > 0) {
741                                 foreach (IExtenderControl ex in _registeredExtenderControls.Keys) {
742                                         IEnumerable<ScriptReference> scripts = ex.GetScriptReferences ();
743                                         if (scripts != null)
744                                                 foreach (ScriptReference s in scripts)
745                                                         yield return new ScriptReferenceEntry ((Control) ex, s, LoadScriptsBeforeUI);
746                                 }
747                         }
748                 }
749                 protected virtual void OnResolveCompositeScriptReference (CompositeScriptReferenceEventArgs e)
750                 {
751                         EventHandler <CompositeScriptReferenceEventArgs> evt = ResolveCompositeScriptReference;
752                         if (evt != null)
753                                 evt (this, e);
754                 }
755                 protected virtual void OnResolveScriptReference (ScriptReferenceEventArgs e) {
756                         if (ResolveScriptReference != null)
757                                 ResolveScriptReference (this, e);
758                 }
759
760                 protected virtual void RaisePostDataChangedEvent ()
761                 {
762                         // Why override?
763                 }
764
765                 public static void RegisterArrayDeclaration (Page page, string arrayName, string arrayValue) {
766                         RegisterArrayDeclaration ((Control) page, arrayName, arrayValue);
767                 }
768
769                 public static void RegisterArrayDeclaration (Control control, string arrayName, string arrayValue) {
770                         Page page = control.Page;
771                         ScriptManager sm = GetCurrentInternal (page);
772
773                         if (sm == null)
774                                 return;
775                         
776                         if (sm._arrayDeclarations == null)
777                                 sm._arrayDeclarations = new List<RegisteredArrayDeclaration> ();
778
779                         sm._arrayDeclarations.Add (new RegisteredArrayDeclaration (control, arrayName, arrayValue));
780
781                         if (!sm.IsInAsyncPostBack)
782                                 page.ClientScript.RegisterArrayDeclaration (arrayName, arrayValue);
783                 }
784
785                 public void RegisterAsyncPostBackControl (Control control) {
786                         if (control == null)
787                                 return;
788
789                         if (_asyncPostBackControls == null)
790                                 _asyncPostBackControls = new List<Control> ();
791
792                         if (_asyncPostBackControls.Contains (control))
793                                 return;
794
795                         _asyncPostBackControls.Add (control);
796                 }
797
798                 public static void RegisterClientScriptBlock (Page page, Type type, string key, string script, bool addScriptTags) {
799                         RegisterClientScriptBlock ((Control) page, type, key, script, addScriptTags);
800                 }
801
802                 public static void RegisterClientScriptBlock (Control control, Type type, string key, string script, bool addScriptTags) {
803                         Page page = control.Page;
804                         ScriptManager sm = GetCurrentInternal (page);
805
806                         if (sm == null)
807                                 return;
808                         
809                         RegisterScript (ref sm._clientScriptBlocks, control, type, key, script, null, addScriptTags, RegisteredScriptType.ClientScriptBlock);
810
811                         if (!sm.IsInAsyncPostBack)
812                                 page.ClientScript.RegisterClientScriptBlock (type, key, script, addScriptTags);
813                 }
814
815                 public static void RegisterClientScriptInclude (Page page, Type type, string key, string url) {
816                         RegisterClientScriptInclude ((Control) page, type, key, url);
817                 }
818
819                 public static void RegisterClientScriptInclude (Control control, Type type, string key, string url) {
820                         Page page = control.Page;
821                         ScriptManager sm = GetCurrentInternal (page);
822
823                         if (sm == null)
824                                 return;
825                         
826                         RegisterScript (ref sm._clientScriptBlocks, control, type, key, null, url, false, RegisteredScriptType.ClientScriptInclude);
827
828                         if (!sm.IsInAsyncPostBack)
829                                 page.ClientScript.RegisterClientScriptInclude (type, key, url);
830                 }
831
832                 public static void RegisterClientScriptResource (Page page, Type type, string resourceName) {
833                         RegisterClientScriptResource ((Control) page, type, resourceName);
834                 }
835
836                 public static void RegisterClientScriptResource (Control control, Type type, string resourceName) {
837                         RegisterClientScriptInclude (control, type, resourceName, ScriptResourceHandler.GetResourceUrl (type.Assembly, resourceName, true));
838                 }
839
840                 void RegisterScriptReference (Control control, ScriptReferenceBase script, bool loadScriptsBeforeUI)
841                 {
842                         string scriptPath = script.Path;
843                         string url = String.IsNullOrEmpty (scriptPath) ? script.GetUrl (this, false) : scriptPath;
844                         if (control != this && !String.IsNullOrEmpty (scriptPath))
845                                 url = control.ResolveClientUrl (scriptPath);
846
847                         if (String.IsNullOrEmpty (url))
848                                 return;
849                         
850                         if (loadScriptsBeforeUI)
851                                 RegisterClientScriptInclude (control, typeof (ScriptManager), url, url);
852                         else
853                                 RegisterStartupScript (control, typeof (ScriptManager), url, String.Format ("<script src=\"{0}\" type=\"text/javascript\"></script>", url), false);
854                 }
855
856                 void RegisterServiceReference (Control control, ServiceReference serviceReference)
857                 {
858                         if (serviceReference.InlineScript) {
859                                 string url = control.ResolveUrl (serviceReference.Path);
860                                 Type type = WebServiceParser.GetCompiledType (url, Context);
861                                 if (type != null) {
862                                         object[] attributes = type.GetCustomAttributes (typeof (ScriptServiceAttribute), true);
863                                         if (attributes.Length == 0)
864                                                 throw new InvalidOperationException ("Only Web services with a [ScriptService] attribute on the class definition can be called from script.");
865                                 }
866                                 
867                                 LogicalTypeInfo logicalTypeInfo = LogicalTypeInfo.GetLogicalTypeInfo (type, url);
868                                 RegisterClientScriptBlock (control, typeof (ScriptManager), url, logicalTypeInfo.Proxy, true);
869                         }
870                         else {
871                                 string pathInfo = "/js";
872                                 if (IsDebuggingEnabled)
873                                         pathInfo += "debug";
874                                 string url = String.Concat (control.ResolveClientUrl (serviceReference.Path), pathInfo);
875                                 RegisterClientScriptInclude (control, typeof (ScriptManager), url, url);
876                         }
877                 }
878
879                 public void RegisterDataItem (Control control, string dataItem) {
880                         RegisterDataItem (control, dataItem, false);
881                 }
882
883                 public void RegisterDataItem (Control control, string dataItem, bool isJsonSerialized) {
884                         if (!IsInAsyncPostBack)
885                                 throw new InvalidOperationException ("RegisterDataItem can only be called during an async postback.");
886                         if (control == null)
887                                 throw new ArgumentNullException ("control");
888
889                         if (_dataItems == null)
890                                 _dataItems = new Dictionary<Control, DataItemEntry> ();
891
892                         if (_dataItems.ContainsKey (control))
893                                 throw new ArgumentException (String.Format ("'{0}' already has a data item registered.", control.ID), "control");
894
895                         _dataItems.Add (control, new DataItemEntry (dataItem, isJsonSerialized));
896                 }
897
898                 public void RegisterDispose (Control control, string disposeScript) {
899                         if (control == null)
900                                 throw new ArgumentNullException ("control");
901                         if (disposeScript == null)
902                                 throw new ArgumentNullException ("disposeScript");
903
904                         UpdatePanel updatePanel = GetUpdatePanel (control);
905                         if (updatePanel == null)
906                                 return;
907
908                         if (_disposeScripts == null)
909                                 _disposeScripts = new List<RegisteredDisposeScript> ();
910                         _disposeScripts.Add (new RegisteredDisposeScript (control, disposeScript, updatePanel));
911                 }
912
913                 static UpdatePanel GetUpdatePanel (Control control) {
914                         if (control == null)
915                                 return null;
916
917                         UpdatePanel parent = control.Parent as UpdatePanel;
918                         if (parent != null)
919                                 return parent;
920
921                         return GetUpdatePanel (control.Parent);
922                 }
923
924                 public static void RegisterExpandoAttribute (Control control, string controlId, string attributeName, string attributeValue, bool encode) {
925                         Page page = control.Page;
926                         ScriptManager sm = GetCurrentInternal (page);
927
928                         if (sm == null)
929                                 return;
930                         
931                         if (sm._expandoAttributes == null)
932                                 sm._expandoAttributes = new List<RegisteredExpandoAttribute> ();
933
934                         sm._expandoAttributes.Add (new RegisteredExpandoAttribute (control, controlId, attributeName, attributeValue, encode));
935
936                         if (!sm.IsInAsyncPostBack)
937                                 page.ClientScript.RegisterExpandoAttribute (controlId, attributeName, attributeValue, encode);
938                 }
939
940                 public static void RegisterHiddenField (Page page, string hiddenFieldName, string hiddenFieldInitialValue) {
941                         RegisterHiddenField ((Control) page, hiddenFieldName, hiddenFieldInitialValue);
942                 }
943
944                 public static void RegisterHiddenField (Control control, string hiddenFieldName, string hiddenFieldInitialValue) {
945                         Page page = control.Page;
946                         ScriptManager sm = GetCurrentInternal (page);
947
948                         if (sm == null)
949                                 return;
950                         
951                         if (sm._hiddenFields == null)
952                                 sm._hiddenFields = new List<RegisteredHiddenField> ();
953
954                         sm._hiddenFields.Add (new RegisteredHiddenField (control, hiddenFieldName, hiddenFieldInitialValue));
955
956                         if (!sm.IsInAsyncPostBack)
957                                 page.ClientScript.RegisterHiddenField (hiddenFieldName, hiddenFieldInitialValue);
958                 }
959
960                 public static void RegisterOnSubmitStatement (Page page, Type type, string key, string script) {
961                         RegisterOnSubmitStatement ((Control) page, type, key, script);
962                 }
963
964                 public static void RegisterOnSubmitStatement (Control control, Type type, string key, string script) {
965                         Page page = control.Page;
966                         ScriptManager sm = GetCurrentInternal (page);
967
968                         if (sm == null)
969                                 return;
970                         
971                         RegisterScript (ref sm._onSubmitStatements, control, type, key, script, null, false, RegisteredScriptType.OnSubmitStatement);
972
973                         if (!sm.IsInAsyncPostBack)
974                                 page.ClientScript.RegisterOnSubmitStatement (type, key, script);
975                 }
976
977                 public void RegisterPostBackControl (Control control) {
978                         if (control == null)
979                                 return;
980
981                         if (_postBackControls == null)
982                                 _postBackControls = new List<Control> ();
983
984                         if (_postBackControls.Contains (control))
985                                 return;
986
987                         _postBackControls.Add (control);
988                 }
989
990                 internal void RegisterUpdatePanel (UpdatePanel updatePanel) {
991                         if (_updatePanels == null)
992                                 _updatePanels = new List<UpdatePanel> ();
993
994                         if (_updatePanels.Contains (updatePanel))
995                                 return;
996
997                         _updatePanels.Add (updatePanel);
998                 }
999
1000                 public void RegisterScriptDescriptors (IExtenderControl extenderControl) {
1001                         if (extenderControl == null)
1002                                 return;
1003
1004                         if (_registeredExtenderControls == null || !_registeredExtenderControls.ContainsKey (extenderControl))
1005                                 return;
1006
1007                         Control targetControl = _registeredExtenderControls [extenderControl];
1008                         RegisterScriptDescriptors ((Control) extenderControl, extenderControl.GetScriptDescriptors (targetControl));
1009                 }
1010
1011                 public void RegisterScriptDescriptors (IScriptControl scriptControl) {
1012                         if (scriptControl == null)
1013                                 return;
1014
1015                         if (_registeredScriptControls == null || !_registeredScriptControls.Contains (scriptControl))
1016                                 return;
1017
1018                         RegisterScriptDescriptors ((Control) scriptControl, scriptControl.GetScriptDescriptors ());
1019                 }
1020
1021                 void RegisterScriptDescriptors (Control control, IEnumerable<ScriptDescriptor> scriptDescriptors)
1022                 {
1023                         if (scriptDescriptors == null)
1024                                 return;
1025
1026                         StringBuilder sb = new StringBuilder ();
1027                         foreach (ScriptDescriptor scriptDescriptor in scriptDescriptors) {
1028                                 if (IsMultiForm) {
1029                                         scriptDescriptor.FormID = Page.Form.ClientID;
1030                                         sb.AppendLine ("Sys.Application.getInstance($get(\"" + Page.Form.ClientID + "\")).add_init(function() {");
1031                                 }
1032                                 else
1033                                         sb.AppendLine ("Sys.Application.add_init(function() {");
1034                                 sb.Append ("\t");
1035                                 sb.AppendLine (scriptDescriptor.GetScript ());
1036                                 sb.AppendLine ("});");
1037                         }
1038                         string script = sb.ToString ();
1039                         RegisterStartupScript (control, typeof (ScriptDescriptor), script, script, true);
1040                 }
1041
1042                 public static void RegisterStartupScript (Page page, Type type, string key, string script, bool addScriptTags) {
1043                         RegisterStartupScript ((Control) page, type, key, script, addScriptTags);
1044                 }
1045
1046                 public static void RegisterStartupScript (Control control, Type type, string key, string script, bool addScriptTags) {
1047                         Page page = control.Page;
1048                         ScriptManager sm = GetCurrentInternal (page);
1049
1050                         if (sm == null)
1051                                 return;
1052                         
1053                         RegisterScript (ref sm._startupScriptBlocks, control, type, key, script, null, addScriptTags, RegisteredScriptType.ClientStartupScript);
1054
1055                         if (!sm.IsInAsyncPostBack)
1056                                 page.ClientScript.RegisterStartupScript (type, key, script, addScriptTags);
1057                 }
1058
1059                 public void RegisterScriptControl<TScriptControl> (TScriptControl scriptControl) where TScriptControl : Control, IScriptControl {
1060                         if (scriptControl == null)
1061                                 throw new ArgumentNullException ("scriptControl");
1062
1063                         if (_registeredScriptControls == null)
1064                                 _registeredScriptControls = new List<IScriptControl> ();
1065
1066                         if (!_registeredScriptControls.Contains (scriptControl))
1067                                 _registeredScriptControls.Add (scriptControl);
1068                 }
1069
1070                 public void RegisterExtenderControl<TExtenderControl> (TExtenderControl extenderControl, Control targetControl) where TExtenderControl : Control, IExtenderControl {
1071                         if (extenderControl == null)
1072                                 throw new ArgumentNullException ("extenderControl");
1073                         if (targetControl == null)
1074                                 throw new ArgumentNullException ("targetControl");
1075
1076                         if (_registeredExtenderControls == null)
1077                                 _registeredExtenderControls = new Dictionary<IExtenderControl, Control> ();
1078
1079                         if (!_registeredExtenderControls.ContainsKey (extenderControl))
1080                                 _registeredExtenderControls.Add (extenderControl, targetControl);
1081                 }
1082
1083                 static void RegisterScript (ref List<RegisteredScript> scriptList, Control control, Type type, string key, string script, string url, bool addScriptTag, RegisteredScriptType scriptType) {
1084                         if (scriptList == null)
1085                                 scriptList = new List<RegisteredScript> ();
1086
1087                         scriptList.Add (new RegisteredScript (control, type, key, script, url, addScriptTag, scriptType));
1088                 }
1089
1090                 protected internal override void Render (HtmlTextWriter writer) {
1091                         // MSDN: This method is used by control developers to extend the ScriptManager control. 
1092                         // Notes to Inheritors: 
1093                         // When overriding this method, call the base Render(HtmlTextWriter) method 
1094                         // so that PageRequestManager is rendered on the page.
1095                         if (SupportsPartialRendering) {
1096                                 writer.WriteLine ("<script type=\"text/javascript\">");
1097                                 writer.WriteLine ("//<![CDATA[");
1098                                 writer.WriteLine ("Sys.WebForms.PageRequestManager._initialize('{0}', document.getElementById('{1}'));", UniqueID, Page.Form.ClientID);
1099                                 if (IsMultiForm)
1100                                         writer.WriteLine ("Sys.WebForms.PageRequestManager.getInstance($get(\"{0}\"))._updateControls([{1}], [{2}], [{3}], {4});",
1101                                                           Page.Form.ClientID,
1102                                                           FormatUpdatePanelIDs (_updatePanels, true),
1103                                                           FormatListIDs (_asyncPostBackControls, true, false),
1104                                                           FormatListIDs (_postBackControls, true, false),
1105                                                           AsyncPostBackTimeout);
1106                                 else
1107                                         writer.WriteLine ("Sys.WebForms.PageRequestManager.getInstance()._updateControls([{0}], [{1}], [{2}], {3});",
1108                                                           FormatUpdatePanelIDs (_updatePanels, true),
1109                                                           FormatListIDs (_asyncPostBackControls, true, false),
1110                                                           FormatListIDs (_postBackControls, true, false),
1111                                                           AsyncPostBackTimeout);
1112                                 writer.WriteLine ("//]]");
1113                                 writer.WriteLine ("</script>");
1114                         }
1115                         base.Render (writer);
1116                 }
1117
1118                 static string FormatUpdatePanelIDs (List<UpdatePanel> list, bool useSingleQuote) {
1119                         return FormatUpdatePanelIDs (list, useSingleQuote, false);
1120                 }
1121                 
1122                 static string FormatUpdatePanelIDs (List<UpdatePanel> list, bool useSingleQuote, bool useUntaggedName) {
1123                         if (list == null || list.Count == 0)
1124                                 return null;
1125
1126                         string quote = useSingleQuote ? "'" : String.Empty;
1127                         string id;
1128                         StringBuilder sb = new StringBuilder ();
1129                         foreach (UpdatePanel panel in list) {
1130                                 if (!panel.Visible)
1131                                         continue;
1132
1133                                 id = panel.UniqueID;
1134                                 sb.AppendFormat ("{0}{1}{2}{0},", quote, panel.ChildrenAsTriggers ? "t" : "f", id);
1135                                 if (useUntaggedName)
1136                                         sb.AppendFormat ("{0}{1}{0},", quote, id);
1137                         }
1138                         
1139                         if (sb.Length > 0)
1140                                 sb.Length--;
1141
1142                         return sb.ToString ();
1143                 }
1144
1145                 static string FormatListIDs<T> (List<T> list, bool useSingleQuote, bool skipInvisible) where T : Control
1146                 {
1147                         if (list == null || list.Count == 0)
1148                                 return null;
1149
1150                         StringBuilder sb = new StringBuilder ();
1151                         for (int i = 0; i < list.Count; i++) {
1152                                 if (skipInvisible && !list [i].Visible)
1153                                         continue;
1154                                 
1155                                 sb.AppendFormat ("{0}{1}{0},", useSingleQuote ? "'" : String.Empty, list [i].UniqueID);
1156                         }
1157                         if (sb.Length > 0)
1158                                 sb.Length--;
1159
1160                         return sb.ToString ();
1161                 }
1162
1163                 public void SetFocus (Control control) {
1164                         if (control == null)
1165                                 throw new ArgumentNullException ("control");
1166
1167                         if (IsInAsyncPostBack) {
1168                                 EnsureFocusClientScript ();
1169                                 _controlIDToFocus = control.ClientID;
1170                         }
1171                         else
1172                                 Page.SetFocus (control);
1173                 }
1174
1175                 public void SetFocus (string clientID) {
1176                         if (String.IsNullOrEmpty (clientID))
1177                                 throw new ArgumentNullException ("control");
1178
1179                         if (IsInAsyncPostBack) {
1180                                 EnsureFocusClientScript ();
1181                                 _controlIDToFocus = clientID;
1182                         }
1183                         else
1184                                 Page.SetFocus (clientID);
1185                 }
1186
1187                 void EnsureFocusClientScript () {
1188 #if     TARGET_DOTNET
1189                         RegisterClientScriptResource (this, typeof (ClientScriptManager), "Focus.js");
1190 #endif
1191                 }
1192
1193                 #region IPostBackDataHandler Members
1194
1195                 bool IPostBackDataHandler.LoadPostData (string postDataKey, NameValueCollection postCollection) {
1196                         return LoadPostData (postDataKey, postCollection);
1197                 }
1198
1199                 void IPostBackDataHandler.RaisePostDataChangedEvent () {
1200                         RaisePostDataChangedEvent ();
1201                 }
1202
1203                 #endregion
1204
1205                 internal static void WriteCallbackException (ScriptManager current, TextWriter output, Exception ex, bool writeMessage)
1206                 {
1207 #if TARGET_DOTNET
1208                         if (ex is HttpUnhandledException)
1209                                 ex = ex.InnerException;
1210 #endif
1211                         HttpException httpEx = ex as HttpException;
1212                         string message = current != null ? current.AsyncPostBackErrorMessage : null;
1213                         if (String.IsNullOrEmpty (message) && writeMessage) {
1214                                 if ((current != null && current.IsDebuggingEnabled) || (current == null && RuntimeHelpers.DebuggingEnabled))
1215                                         message = ex.ToString ();
1216                                 else
1217                                         message = ex.Message;
1218                         }
1219                         
1220                         WriteCallbackOutput (output, error, httpEx == null ? "500" : httpEx.GetHttpCode ().ToString (), message);
1221                 }
1222
1223                 static internal void WriteCallbackRedirect (TextWriter output, string redirectUrl) {
1224                         WriteCallbackOutput (output, pageRedirect, null, redirectUrl);
1225                 }
1226
1227                 void RegisterPanelForRefresh (UpdatePanel panel)
1228                 {
1229                         if (_panelsToRefresh == null)
1230                                 _panelsToRefresh = new List<UpdatePanel> ();
1231                         else if (_panelsToRefresh.Contains (panel))
1232                                 return;
1233
1234                         _panelsToRefresh.Add (panel);
1235                         RegisterUpdatePanel (panel);
1236                 }
1237                 
1238                 internal void WriteCallbackPanel (TextWriter output, UpdatePanel panel, StringBuilder panelOutput)
1239                 {
1240                         WriteCallbackOutput (output, updatePanel, panel.ClientID, panelOutput);
1241                 }
1242
1243                 internal void RegisterChildUpdatePanel (UpdatePanel updatePanel) {
1244                         if (_childUpdatePanels == null)
1245                                 _childUpdatePanels = new List<UpdatePanel> ();
1246                         _childUpdatePanels.Add (updatePanel);
1247                 }
1248
1249                 static void WriteCallbackOutput (TextWriter output, string type, string name, object value) {
1250                         string str = value as string;
1251                         StringBuilder sb = str == null ? value as StringBuilder : null;
1252                         int length = 0;
1253                         if (str != null)
1254                                 length = str.Length;
1255                         else if (sb != null)
1256                                 length = sb.Length;
1257
1258                         //output.Write ("{0}|{1}|{2}|{3}|", value == null ? 0 : value.Length, type, name, value);
1259                         output.Write (length);
1260                         output.Write ('|');
1261                         output.Write (type);
1262                         output.Write ('|');
1263                         output.Write (name);
1264                         output.Write ('|');
1265                         for (int i = 0; i < length; i++)
1266                                 if (str != null)
1267                                         output.Write (str [i]);
1268                                 else
1269                                         output.Write (sb [i]);
1270                         output.Write ('|');
1271                 }
1272
1273                 void RenderPageCallback (HtmlTextWriter output, Control container)
1274                 {
1275                         Page page = (Page) container;
1276
1277                         // MSDN: http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.aspx
1278                         //
1279                         // Refreshing UpdatePanel Content
1280                         //
1281                         // When partial-page rendering is enabled, a control can perform a postback
1282                         // that updates the whole page or an asynchronous postback that updates the
1283                         // content of one or more UpdatePanel controls. Whether a control causes an
1284                         // asynchronous postback and updates an UpdatePanel control depends on the
1285                         // following:
1286                         //
1287                         // * If the UpdateMode property of the UpdatePanel control is set to Always,
1288                         //   the UpdatePanel control's content is updated on every postback that
1289                         //   originates from the page. This includes asynchronous postbacks from
1290                         //   controls that are inside other UpdatePanel controls and postbacks from
1291                         //   controls that are not inside UpdatePanel controls.
1292                         //
1293                         // * If the UpdateMode property is set to Conditional, the UpdatePanel
1294                         //   control's content is updated in the following circumstances:
1295                         //
1296                         //       o When you call the Update method of the UpdatePanel control
1297                         //         explicitly.
1298                         //       o When the UpdatePanel control is nested inside another UpdatePanel
1299                         //         control, and the parent panel is updated.
1300                         //       o When a postback is caused by a control that is defined as a
1301                         //         trigger by using the Triggers property of the UpdatePanel
1302                         //         control. In this scenario, the control explicitly triggers an
1303                         //         update of the panel content. The control can be either inside or
1304                         //         outside the UpdatePanel control that the trigger is associated
1305                         //         with.
1306                         //       o When the ChildrenAsTriggers property is set to true and a child
1307                         //         control of the UpdatePanel control causes a postback. Child
1308                         //         controls of nested UpdatePanel controls do not cause an update to
1309                         //         the outer UpdatePanel control unless they are explicitly defined
1310                         //         as triggers.
1311                         //
1312                         if (_updatePanels != null && _updatePanels.Count > 0) {
1313                                 bool needsUpdate;
1314                                 foreach (UpdatePanel panel in _updatePanels) {
1315                                         if (panel.RequiresUpdate || (!String.IsNullOrEmpty (_panelToRefreshID) && String.Compare (_panelToRefreshID, panel.UniqueID, StringComparison.Ordinal) == 0))
1316                                                 needsUpdate = true;
1317                                         else
1318                                                 needsUpdate = false;
1319
1320                                         panel.SetInPartialRendering (needsUpdate);
1321                                         if (needsUpdate)
1322                                                 RegisterPanelForRefresh (panel);
1323                                 }
1324                         }
1325                         
1326                         page.Form.SetRenderMethodDelegate (RenderFormCallback);
1327                         HtmlTextParser parser = new HtmlTextParser (output);
1328                         page.Form.RenderControl (parser);
1329
1330                         Dictionary <string, string> pageHiddenFields = parser.HiddenFields;
1331                         if (pageHiddenFields != null)
1332                                 foreach (KeyValuePair <string, string> kvp in pageHiddenFields)
1333                                         WriteCallbackOutput (output, hiddenField, kvp.Key, kvp.Value);
1334                         
1335                         WriteCallbackOutput (output, asyncPostBackControlIDs, null, FormatListIDs (_asyncPostBackControls, false, false));
1336                         WriteCallbackOutput (output, postBackControlIDs, null, FormatListIDs (_postBackControls, false, false));
1337                         WriteCallbackOutput (output, updatePanelIDs, null, FormatUpdatePanelIDs (_updatePanels, false, true));
1338                         WriteCallbackOutput (output, childUpdatePanelIDs, null, FormatListIDs (_childUpdatePanels, false, true));
1339                         WriteCallbackOutput (output, panelsToRefreshIDs, null, FormatListIDs (_panelsToRefresh, false, true));
1340                         WriteCallbackOutput (output, asyncPostBackTimeout, null, AsyncPostBackTimeout.ToString ());
1341                         if (!IsMultiForm)
1342                                 WriteCallbackOutput (output, pageTitle, null, Page.Title);
1343
1344                         if (_dataItems != null)
1345                                 foreach (Control control in _dataItems.Keys) {
1346                                         DataItemEntry entry = _dataItems [control];
1347                                         WriteCallbackOutput (output, entry.IsJsonSerialized ? dataItemJson : dataItem, control.ClientID, entry.DataItem);
1348                                 }
1349
1350                         WriteArrayDeclarations (output);
1351                         WriteExpandoAttributes (output);
1352                         WriteScriptBlocks (output, _clientScriptBlocks);
1353                         WriteScriptBlocks (output, _startupScriptBlocks);
1354                         WriteScriptBlocks (output, _onSubmitStatements);
1355                         WriteHiddenFields (output);
1356
1357                         if (!String.IsNullOrEmpty (_controlIDToFocus))
1358                                 WriteCallbackOutput (output, focus, null, _controlIDToFocus);
1359
1360                         if (_disposeScripts != null)
1361                                 for (int i = 0; i < _disposeScripts.Count; i++) {
1362                                         RegisteredDisposeScript entry = _disposeScripts [i];
1363                                         if ((_panelsToRefresh != null && _panelsToRefresh.IndexOf (entry.UpdatePanel) >= 0) || (_childUpdatePanels != null && _childUpdatePanels.IndexOf (entry.UpdatePanel) >= 0))
1364                                                 WriteCallbackOutput (output, scriptDispose, entry.UpdatePanel.ClientID, entry.Script);
1365                                 }
1366                 }
1367
1368                 private void WriteExpandoAttributes (HtmlTextWriter writer) {
1369                         if (_expandoAttributes != null) {
1370                                 for (int i = 0; i < _expandoAttributes.Count; i++) {
1371                                         RegisteredExpandoAttribute attr = _expandoAttributes [i];
1372                                         if (HasBeenRendered (attr.Control)) {
1373                                                 string value;
1374                                                 if (attr.Encode) {
1375                                                         StringWriter sw = new StringWriter ();
1376                                                         Newtonsoft.Json.JavaScriptUtils.WriteEscapedJavaScriptString (attr.Value, sw);
1377                                                         value = sw.ToString ();
1378                                                 }
1379                                                 else
1380                                                         value = "\"" + attr.Value + "\"";
1381                                                 WriteCallbackOutput (writer, expando, "document.getElementById('" + attr.ControlId + "')['" + attr.Name + "']", value);
1382                                         }
1383                                 }
1384                         }
1385                 }
1386
1387                 void WriteArrayDeclarations (HtmlTextWriter writer) {
1388                         if (_arrayDeclarations != null) {
1389                                 for (int i = 0; i < _arrayDeclarations.Count; i++) {
1390                                         RegisteredArrayDeclaration array = _arrayDeclarations [i];
1391                                         if (Page == array.Control || HasBeenRendered (array.Control))
1392                                                 WriteCallbackOutput (writer, arrayDeclaration, array.Name, array.Value);
1393                                 }
1394                         }
1395                 }
1396
1397                 void WriteScriptBlocks (HtmlTextWriter output, List<RegisteredScript> scriptList) {
1398                         if (scriptList == null)
1399                                 return;
1400                         var registeredScripts = new Dictionary <string, RegisteredScript> ();
1401                         Control control;
1402                         Page page = Page;
1403                         
1404                         for (int i = 0; i < scriptList.Count; i++) {
1405                                 RegisteredScript scriptEntry = scriptList [i];
1406                                 if (registeredScripts.ContainsKey (scriptEntry.Key))
1407                                         continue;
1408
1409                                 control = scriptEntry.Control;
1410                                 if (page == control || HasBeenRendered (control)) {
1411                                         registeredScripts.Add (scriptEntry.Key, scriptEntry);
1412                                         switch (scriptEntry.ScriptType) {
1413                                                 case RegisteredScriptType.ClientScriptBlock:
1414                                                         if (scriptEntry.AddScriptTags)
1415                                                                 WriteCallbackOutput (output, scriptBlock, scriptContentNoTags, scriptEntry.Script);
1416                                                         else
1417                                                                 WriteCallbackOutput (output, scriptBlock, scriptContentWithTags, SerializeScriptBlock (scriptEntry));
1418                                                         break;
1419                                                 case RegisteredScriptType.ClientStartupScript:
1420                                                         if (scriptEntry.AddScriptTags)
1421                                                                 WriteCallbackOutput (output, scriptStartupBlock, scriptContentNoTags, scriptEntry.Script);
1422                                                         else
1423                                                                 WriteCallbackOutput (output, scriptStartupBlock, scriptContentWithTags, SerializeScriptBlock (scriptEntry));
1424                                                         break;
1425                                                 case RegisteredScriptType.ClientScriptInclude:
1426                                                         WriteCallbackOutput (output, scriptBlock, scriptPath, scriptEntry.Url);
1427                                                         break;
1428                                                 case RegisteredScriptType.OnSubmitStatement:
1429                                                         WriteCallbackOutput (output, onSubmit, null, scriptEntry.Script);
1430                                                         break;
1431                                         }
1432                                 }
1433                         }
1434                 }
1435
1436                 void WriteHiddenFields (HtmlTextWriter output) {
1437                         if (_hiddenFields == null)
1438                                 return;
1439                         Hashtable registeredFields = new Hashtable ();
1440                         for (int i = 0; i < _hiddenFields.Count; i++) {
1441                                 RegisteredHiddenField field = _hiddenFields [i];
1442                                 if (registeredFields.ContainsKey (field.Name))
1443                                         continue;
1444                                 if (Page == field.Control || HasBeenRendered (field.Control)) {
1445                                         registeredFields.Add (field.Name, field);
1446                                         WriteCallbackOutput (output, hiddenField, field.Name, field.InitialValue);
1447                                 }
1448                         }
1449                 }
1450
1451                 static string SerializeScriptBlock (RegisteredScript scriptEntry) {
1452                         try {
1453                                 XmlTextReader reader = new XmlTextReader (new StringReader (scriptEntry.Script));
1454                                 while (reader.Read ()) {
1455                                         switch (reader.NodeType) {
1456                                         case XmlNodeType.Element:
1457                                                 if (String.Compare ("script", reader.Name, StringComparison.OrdinalIgnoreCase) == 0) {
1458                                                         Dictionary<string, string> dic = new Dictionary<string, string> ();
1459                                                         while (reader.MoveToNextAttribute ()) {
1460                                                                 dic.Add (reader.Name, reader.Value);
1461                                                         }
1462                                                         reader.MoveToContent ();
1463                                                         dic.Add ("text", reader.ReadInnerXml ());
1464                                                         return JavaScriptSerializer.DefaultSerializer.Serialize (dic);
1465                                                 }
1466                                                 break;
1467                                         default:
1468                                                 continue;
1469                                         }
1470                                 }
1471                         }
1472                         catch {
1473                         }
1474                         throw new InvalidOperationException (String.Format ("The script tag registered for type '{0}' and key '{1}' has invalid characters outside of the script tags: {2}. Only properly formatted script tags can be registered.", scriptEntry.Type, scriptEntry.Key, scriptEntry.Script));
1475                 }
1476
1477                 void RenderFormCallback (HtmlTextWriter output, Control container)
1478                 {
1479                         output = ((HtmlTextParser) output).ResponseOutput;
1480                         HtmlForm form = (HtmlForm) container;
1481                         HtmlTextWriter writer = new HtmlDropWriter (output);
1482                         
1483                         if (form.HasControls ()) {
1484                                 foreach (Control control in form.Controls)
1485                                         control.RenderControl (writer);
1486                         }
1487                 }
1488
1489                 internal class AlternativeHtmlTextWriter : HtmlTextWriter
1490                 {
1491                         readonly HtmlTextWriter _responseOutput;
1492
1493                         public HtmlTextWriter ResponseOutput {
1494                                 get { return _responseOutput; }
1495                         }
1496
1497                         public AlternativeHtmlTextWriter (TextWriter writer, HtmlTextWriter responseOutput)
1498                                 : base (writer) {
1499                                 _responseOutput = responseOutput;
1500                         }
1501                 }
1502
1503                 sealed class HtmlTextParser : AlternativeHtmlTextWriter
1504                 {
1505                         bool _done;
1506
1507                         public Dictionary <string, string> _hiddenFields;
1508
1509                         public Dictionary <string, string> HiddenFields {
1510                                 get { return _hiddenFields; }
1511                         }
1512                         
1513                         public HtmlTextParser (HtmlTextWriter responseOutput)
1514                                 : this (new TextParser (responseOutput), responseOutput) {
1515                         }
1516
1517                         HtmlTextParser (TextParser parser, HtmlTextWriter responseOutput)
1518                                 : base (parser, responseOutput)
1519                         {
1520                                 parser.HiddenFieldParsed += new TextParser.TextParserHiddenFieldParsedEventHandler (OnHiddenFieldParsed);
1521                         }
1522                         
1523                         void OnHiddenFieldParsed (TextParser sender, TextParserHiddenFieldParsedEventArgs args)
1524                         {
1525                                 if (_hiddenFields == null)
1526                                         _hiddenFields = new Dictionary <string, string> ();
1527                                 _hiddenFields [args.Name] = args.Value;
1528                         }
1529                         
1530                         public override void WriteAttribute (string name, string value) {
1531                                 if (!_done && String.Compare ("action", name, StringComparison.OrdinalIgnoreCase) == 0) {
1532                                         _done = true;
1533                                         ScriptManager.WriteCallbackOutput (ResponseOutput, formAction, null, value);
1534                                         return;
1535                                 }
1536                                 base.WriteAttribute (name, value);
1537                         }
1538                 }
1539
1540                 sealed class TextParserHiddenFieldParsedEventArgs : EventArgs
1541                 {
1542                         public string Name {
1543                                 get;
1544                                 private set;
1545                         }
1546
1547                         public string Value {
1548                                 get;
1549                                 private set;
1550                         }
1551                         
1552                         public TextParserHiddenFieldParsedEventArgs (string name, string value)
1553                         {
1554                                 this.Name = name;
1555                                 this.Value = value;
1556                         }
1557                 }
1558                 
1559                 sealed class TextParser : TextWriter
1560                 {
1561                         public delegate void TextParserHiddenFieldParsedEventHandler (TextParser sender, TextParserHiddenFieldParsedEventArgs args);
1562
1563                         int _state;
1564                         char _charState = (char) 255;
1565                         const char nullCharState = (char) 255;
1566                         StringBuilder _sb = new StringBuilder ();
1567                         Dictionary<string, string> _currentField;
1568                         string _currentAttribute;
1569                         readonly HtmlTextWriter _responseOutput;
1570                         TextParserHiddenFieldParsedEventHandler _hiddenFieldParsedHandler;
1571                         
1572                         public event TextParserHiddenFieldParsedEventHandler HiddenFieldParsed {
1573                                 add { _hiddenFieldParsedHandler = value; }
1574                                 remove { _hiddenFieldParsedHandler = null; }
1575                         }
1576                         
1577                         public override Encoding Encoding {
1578                                 get { return Encoding.UTF8; }
1579                         }
1580
1581                         public TextParser (HtmlTextWriter responseOutput) {
1582                                 _responseOutput = responseOutput;
1583                         }
1584
1585                         public override void Write (char value) {
1586                                 switch (_state) {
1587                                 case 0:
1588                                         ParseBeginTag (value);
1589                                         break;
1590                                 case 1:
1591                                         ParseAttributeName (value);
1592                                         break;
1593                                 case 2:
1594                                         ParseAttributeValue (value);
1595                                         break;
1596                                 }
1597                         }
1598
1599                         private void ParseAttributeValue (char value) {
1600                                 switch (value) {
1601                                 case '>':
1602                                         ResetState ();
1603                                         break;
1604                                 case '"':
1605                                         _currentField.Add (_currentAttribute, _sb.ToString ());
1606                                         _state = 1;
1607                                         _sb.Length = 0;
1608                                         ProbeWriteOutput ();
1609                                         break;
1610                                 default:
1611                                         _sb.Append (value);
1612                                         break;
1613                                 }
1614                         }
1615
1616                         private void ParseAttributeName (char value) {
1617                                 switch (value) {
1618                                 case '>':
1619                                         ResetState ();
1620                                         break;
1621                                 case ' ':
1622                                 case '=':
1623                                         break;
1624                                 case '"':
1625                                         _currentAttribute = _sb.ToString ();
1626                                         _state = 2;
1627                                         _sb.Length = 0;
1628                                         break;
1629                                 default:
1630                                         _sb.Append (value);
1631                                         break;
1632                                 }
1633                         }
1634
1635                         void ParseBeginTag (char value) {
1636                                 switch (_charState) {
1637                                 case nullCharState:
1638                                         if (value == '<')
1639                                                 _charState = value;
1640                                         break;
1641                                 case '<':
1642                                         if (value == 'i')
1643                                                 _charState = value;
1644                                         else
1645                                                 ResetState ();
1646                                         break;
1647                                 case 'i':
1648                                         if (value == 'n')
1649                                                 _charState = value;
1650                                         else
1651                                                 ResetState ();
1652                                         break;
1653                                 case 'n':
1654                                         if (value == 'p')
1655                                                 _charState = value;
1656                                         else
1657                                                 ResetState ();
1658                                         break;
1659                                 case 'p':
1660                                         if (value == 'u')
1661                                                 _charState = value;
1662                                         else
1663                                                 ResetState ();
1664                                         break;
1665                                 case 'u':
1666                                         if (value == 't')
1667                                                 _charState = value;
1668                                         else
1669                                                 ResetState ();
1670                                         break;
1671                                 case 't':
1672                                         if (value == ' ') {
1673                                                 _state = 1;
1674                                                 _currentField = new Dictionary<string, string> ();
1675                                         }
1676                                         else
1677                                                 ResetState ();
1678                                         break;
1679                                 }
1680                         }
1681
1682                         private void ResetState () {
1683                                 _charState = nullCharState;
1684                                 _state = 0;
1685                                 _sb.Length = 0;
1686                         }
1687
1688                         private void ProbeWriteOutput () {
1689                                 if (!_currentField.ContainsKey ("name"))
1690                                         return;
1691                                 if (!_currentField.ContainsKey ("value"))
1692                                         return;
1693
1694                                 string value = _currentField ["value"];
1695                                 if (value == null)
1696                                         return;
1697
1698                                 if (_hiddenFieldParsedHandler != null)
1699                                         _hiddenFieldParsedHandler (this, new TextParserHiddenFieldParsedEventArgs (_currentField ["name"], HttpUtility.HtmlDecode (value)));
1700                                 else
1701                                         ScriptManager.WriteCallbackOutput (_responseOutput, hiddenField, _currentField ["name"], HttpUtility.HtmlDecode (value));
1702                         }
1703                 }
1704
1705                 sealed class HtmlDropWriter : AlternativeHtmlTextWriter
1706                 {
1707                         public HtmlDropWriter (HtmlTextWriter responseOutput)
1708                                 : base (new DropWriter (), responseOutput) {
1709                         }
1710                 }
1711
1712                 sealed class DropWriter : TextWriter
1713                 {
1714                         public override Encoding Encoding {
1715                                 get { return Encoding.UTF8; }
1716                         }
1717                 }
1718
1719                 sealed class CultureInfoSerializer
1720                 {
1721                         readonly CultureInfo _ci;
1722                         public CultureInfoSerializer (CultureInfo ci) {
1723                                 if (ci == null)
1724                                         throw new ArgumentNullException ("ci");
1725                                 _ci = ci;
1726                         }
1727
1728                         public string name {
1729                                 get { return _ci.Name; }
1730                         }
1731
1732                         public NumberFormatInfo numberFormat {
1733                                 get { return _ci.NumberFormat; }
1734                         }
1735
1736                         public DateTimeFormatInfo dateTimeFormat {
1737                                 get { return _ci.DateTimeFormat; }
1738                         }                       
1739                 }
1740
1741                 sealed class ScriptReferenceEntry
1742                 {
1743                         readonly Control _control;
1744                         readonly ScriptReference _scriptReference;
1745                         readonly bool _loadBeforeUI;
1746
1747                         public Control Control { get { return _control; } }
1748                         public ScriptReference ScriptReference { get { return _scriptReference; } }
1749                         public bool LoadScriptsBeforeUI { get { return _loadBeforeUI; } }
1750
1751                         public ScriptReferenceEntry (Control control, ScriptReference scriptReference, bool loadBeforeUI) {
1752                                 _control = control;
1753                                 _scriptReference = scriptReference;
1754                                 _loadBeforeUI = loadBeforeUI;
1755                         }
1756                 }
1757
1758                 sealed class DataItemEntry
1759                 {
1760                         readonly string _dataItem;
1761                         readonly bool _isJsonSerialized;
1762
1763                         public string DataItem { get { return _dataItem; } }
1764                         public bool IsJsonSerialized { get { return _isJsonSerialized; } }
1765
1766                         public DataItemEntry (string dataItem, bool isJsonSerialized) {
1767                                 _dataItem = dataItem;
1768                                 _isJsonSerialized = isJsonSerialized;
1769                         }
1770                 }
1771
1772                 internal void RegisterProxy (ScriptManagerProxy scriptManagerProxy) {
1773                         if (_proxies == null)
1774                                 _proxies = new List<ScriptManagerProxy> ();
1775
1776                         _proxies.Add (scriptManagerProxy);
1777                 }
1778
1779                 #region IScriptManager Members
1780
1781                 void IScriptManager.RegisterOnSubmitStatementExternal (Control control, Type type, string key, string script) {
1782                         RegisterOnSubmitStatement (control, type, key, script);
1783                 }
1784
1785                 void IScriptManager.RegisterExpandoAttributeExternal (Control control, string controlId, string attributeName, string attributeValue, bool encode) {
1786                         RegisterExpandoAttribute (control, controlId, attributeName, attributeValue, encode);
1787                 }
1788
1789                 void IScriptManager.RegisterHiddenFieldExternal (Control control, string hiddenFieldName, string hiddenFieldInitialValue) {
1790                         RegisterHiddenField (control, hiddenFieldName, hiddenFieldInitialValue);
1791                 }
1792
1793                 void IScriptManager.RegisterStartupScriptExternal (Control control, Type type, string key, string script, bool addScriptTags) {
1794                         RegisterStartupScript (control, type, key, script, addScriptTags);
1795                 }
1796
1797                 void IScriptManager.RegisterArrayDeclarationExternal (Control control, string arrayName, string arrayValue) {
1798                         RegisterArrayDeclaration (control, arrayName, arrayValue);
1799                 }
1800
1801                 void IScriptManager.RegisterClientScriptBlockExternal (Control control, Type type, string key, string script, bool addScriptTags) {
1802                         RegisterClientScriptBlock (control, type, key, script, addScriptTags);
1803                 }
1804
1805                 void IScriptManager.RegisterClientScriptIncludeExternal (Control control, Type type, string key, string url) {
1806                         RegisterClientScriptInclude (control, type, key, url);
1807                 }
1808
1809                 void IScriptManager.RegisterClientScriptResourceExternal (Control control, Type type, string resourceName) {
1810                         RegisterClientScriptResource (control, type, resourceName);
1811                 }
1812
1813                 #endregion
1814         }
1815 }