[asp.net] HtmlForum.Name rendering updates + test updates
[mono.git] / mcs / class / System.Web / System.Web.UI / ClientScriptManager.cs
index 01f6dd78d5263a6d0bff7be8a921523e35450108..0ad416d30f211adde4e86ddedee0872bae3adb0e 100644 (file)
@@ -8,7 +8,7 @@
 //   Lluis Sanchez (lluis@novell.com)
 //
 // (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
-// (c) 2003 Novell, Inc. (http://www.novell.com)
+// (c) 2003-2010 Novell, Inc. (http://www.novell.com)
 //
 
 //
@@ -34,9 +34,7 @@
 
 using System;
 using System.Collections;
-#if NET_2_0
 using System.Collections.Generic;
-#endif
 using System.Text;
 using System.Collections.Specialized;
 using System.Web.Util;
@@ -44,70 +42,67 @@ using System.Globalization;
 
 namespace System.Web.UI
 {
-       #if NET_2_0
-       public sealed
-       #else
-       internal
-       #endif
-               class ClientScriptManager
+       public sealed partial class ClientScriptManager
        {
+               internal const string EventStateFieldName = "__EVENTVALIDATION";
+               
                Hashtable registeredArrayDeclares;
                ScriptEntry clientScriptBlocks;
                ScriptEntry startupScriptBlocks;
                internal Hashtable hiddenFields;
                ScriptEntry submitStatements;
                Page page;
-#if NET_2_0
                int [] eventValidationValues;
                int eventValidationPos = 0;
                Hashtable expandoAttributes;
                bool _hasRegisteredForEventValidationOnCallback;
-#endif
+               bool _pageInRender;
+               bool _initCallBackRegistered;
+               bool _webFormClientScriptRendered;
+               bool _webFormClientScriptRequired;
+               
+               internal bool ScriptsPresent {
+                       get {
+                               return _webFormClientScriptRequired ||
+                                       _initCallBackRegistered ||
+                                       _hasRegisteredForEventValidationOnCallback ||
+                                       clientScriptBlocks != null ||
+                                       startupScriptBlocks != null ||
+                                       submitStatements != null ||
+                                       registeredArrayDeclares != null ||
+                                       expandoAttributes != null;
+                       }
+               }
                
                internal ClientScriptManager (Page page)
                {
                        this.page = page;
                }
 
-#if !NET_2_0
-               public string GetPostBackClientEvent (Control control, string argument)
-               {
-                       return GetPostBackEventReference (control, argument);
-               }
-#endif
-
                public string GetPostBackClientHyperlink (Control control, string argument)
                {
                        return "javascript:" + GetPostBackEventReference (control, argument);
                }
        
-#if NET_2_0
                public string GetPostBackClientHyperlink (Control control, string argument, bool registerForEventValidation)
                {
                        if (registerForEventValidation)
                                RegisterForEventValidation (control.UniqueID, argument);
                        return "javascript:" + GetPostBackEventReference (control, argument);
                }
-#endif         
 
-#if !NET_2_0
-               internal
-#else
-               public
-#endif
-               string GetPostBackEventReference (Control control, string argument)
+               public string GetPostBackEventReference (Control control, string argument)
                {
                        if (control == null)
                                throw new ArgumentNullException ("control");
                        
                        page.RequiresPostBackScript ();
-               if(page.IsMultiForm)
-                       return String.Format ("{0}.__doPostBack('{1}','{2}')", page.theForm, control.UniqueID, argument);
-               else
-                       return String.Format ("__doPostBack('{0}','{1}')", control.UniqueID, argument);
+                       if(page.IsMultiForm)
+                               return page.theForm + ".__doPostBack('" + control.UniqueID + "','" + argument + "')";
+                       else
+                               return "__doPostBack('" + control.UniqueID + "','" + argument + "')";
                }
 
-#if NET_2_0
                public string GetPostBackEventReference (Control control, string argument, bool registerForEventValidation)
                {
                        if (control == null)
@@ -153,28 +148,19 @@ namespace System.Web.UI
                        if(options.TrackFocus)
                                RegisterHiddenField (Page.LastFocusID, String.Empty);
 
-                       string prefix = options.RequiresJavaScriptProtocol ? "javascript:" : "";
+                       string prefix = options.RequiresJavaScriptProtocol ? "javascript:" : String.Empty;
                        if (page.IsMultiForm)
                                prefix += page.theForm + ".";
-#if TARGET_J2EE
-                       // Allow the page to transform ActionUrl to a portlet action url
-                       if (actionUrl != null && page.PortletNamespace != null) {
-                               actionUrl = page.CreateActionUrl(actionUrl);
-                               prefix += "Portal";
-                       }
-#endif
 
-                       return String.Format ("{0}WebForm_DoPostback({1},{2},{3},{4},{5},{6},{7},{8})", 
-                                       prefix,
-                                       ClientScriptManager.GetScriptLiteral (options.TargetControl.UniqueID), 
-                                       ClientScriptManager.GetScriptLiteral (options.Argument),
-                                       ClientScriptManager.GetScriptLiteral (actionUrl),
-                                       ClientScriptManager.GetScriptLiteral (options.AutoPostBack),
-                                       ClientScriptManager.GetScriptLiteral (options.PerformValidation),
-                                       ClientScriptManager.GetScriptLiteral (options.TrackFocus),
-                                       ClientScriptManager.GetScriptLiteral (options.ClientSubmit),
-                                       ClientScriptManager.GetScriptLiteral (options.ValidationGroup)
-                               );
+                       return prefix + "WebForm_DoPostback(" +
+                               ClientScriptManager.GetScriptLiteral (options.TargetControl.UniqueID) + "," +
+                               ClientScriptManager.GetScriptLiteral (options.Argument) + "," +
+                               ClientScriptManager.GetScriptLiteral (actionUrl) + "," +
+                               ClientScriptManager.GetScriptLiteral (options.AutoPostBack) + "," +
+                               ClientScriptManager.GetScriptLiteral (options.PerformValidation) + "," +
+                               ClientScriptManager.GetScriptLiteral (options.TrackFocus) + "," +
+                               ClientScriptManager.GetScriptLiteral (options.ClientSubmit) + "," +
+                               ClientScriptManager.GetScriptLiteral (options.ValidationGroup) + ")";
                }
 
                internal void RegisterWebFormClientScript ()
@@ -186,13 +172,10 @@ namespace System.Web.UI
                        _webFormClientScriptRequired = true;
                }
 
-               bool _webFormClientScriptRendered;
-               bool _webFormClientScriptRequired;
-
                internal void WriteWebFormClientScript (HtmlTextWriter writer) {
                        if (!_webFormClientScriptRendered && _webFormClientScriptRequired) {
                                writer.WriteLine ();
-                               WriteClientScriptInclude (writer, GetWebResourceUrl (typeof (Page), "webform.js"));
+                               WriteClientScriptInclude (writer, GetWebResourceUrl (typeof (Page), "webform.js"), typeof (Page), "webform.js");
                                WriteBeginScriptBlock (writer);
                                writer.WriteLine ("WebForm_Initialize({0});", page.IsMultiForm ? page.theForm : "window");
                                WriteEndScriptBlock (writer);
@@ -223,17 +206,21 @@ namespace System.Web.UI
                public string GetCallbackEventReference (string target, string argument, string clientCallback, string context, string clientErrorCallback, bool useAsync)
                {
                        RegisterWebFormClientScript ();
-                       
-                       return string.Format ("{6}WebForm_DoCallback({0},{1},{2},{3},{4},{5})", target, ((argument == null) ? "null" : argument), clientCallback, ((context == null) ? "null" : context), ((clientErrorCallback == null) ? "null" : clientErrorCallback), (useAsync ? "true" : "false"), (page.IsMultiForm ? page.theForm + "." : null));
+
+                       if (!_initCallBackRegistered) {
+                               _initCallBackRegistered = true;
+                               RegisterStartupScript (typeof (Page), "WebForm_InitCallback", page.WebFormScriptReference + ".WebForm_InitCallback();", true);
+                       }
+                       return page.WebFormScriptReference + ".WebForm_DoCallback(" +
+                               target + "," +
+                               (argument ?? "null") + "," +
+                               clientCallback + "," +
+                               (context ?? "null") + "," +
+                               (clientErrorCallback ?? "null") + "," +
+                               (useAsync ? "true" : "false") + ")";
                }
-#endif
                
-#if NET_2_0
-               public
-#else
-               internal
-#endif
-               string GetWebResourceUrl(Type type, string resourceName)
+               public string GetWebResourceUrl(Type type, string resourceName)
                {
                        if (type == null)
                                throw new ArgumentNullException ("type");
@@ -304,6 +291,7 @@ namespace System.Web.UI
                                registeredArrayDeclares.Add (arrayName, new ArrayList());
        
                        ((ArrayList) registeredArrayDeclares[arrayName]).Add(arrayValue);
+                       page.RequiresFormScriptDeclaration ();
                }
 
                void RegisterScript (ref ScriptEntry scriptList, Type type, string key, string script, bool addScriptTags)
@@ -402,7 +390,6 @@ namespace System.Web.UI
                        RegisterScript (ref clientScriptBlocks, type, "include-" + key, url, ScriptEntryFormat.Include);
                }
 
-#if NET_2_0
                public void RegisterClientScriptResource (Type type, string resourceName)
                {
                        RegisterScript (ref clientScriptBlocks, type, "resource-" + resourceName, GetWebResourceUrl (type, resourceName), ScriptEntryFormat.Include);
@@ -433,9 +420,9 @@ namespace System.Web.UI
                        list.Add (attributeName, encode ? StrUtils.EscapeQuotesAndBackslashes (attributeValue) : attributeValue);
                }
 
-               private void EnsureEventValidationArray ()
+               void EnsureEventValidationArray ()
                {
-                       if (eventValidationValues == null)
+                       if (eventValidationValues == null || eventValidationValues.Length == 0)
                                eventValidationValues = new int [64];
 
                        int len = eventValidationValues.Length;
@@ -449,11 +436,12 @@ namespace System.Web.UI
 
                internal void ResetEventValidationState ()
                {
+                       _pageInRender = true;
                        eventValidationPos = 0;
                }
 
                // Implemented following the description in http://odetocode.com/Blogs/scott/archive/2006/03/20/3145.aspx
-               private int CalculateEventHash (string uniqueId, string argument)
+               int CalculateEventHash (string uniqueId, string argument)
                {
                        int uniqueIdHash = uniqueId.GetHashCode ();
                        int argumentHash = String.IsNullOrEmpty (argument) ? 0 : argument.GetHashCode ();
@@ -479,7 +467,7 @@ namespace System.Web.UI
                                return;
                        if (page.IsCallback)
                                _hasRegisteredForEventValidationOnCallback = true;
-                       else if (page.LifeCycle < PageLifeCycle.Render)
+                       else if (!_pageInRender)
                                throw new InvalidOperationException ("RegisterForEventValidation may only be called from the Render method");
 
                        EnsureEventValidationArray ();
@@ -496,6 +484,11 @@ namespace System.Web.UI
                        ValidateEvent (uniqueId, null);
                }
 
+               ArgumentException InvalidPostBackException ()
+               {
+                       return new ArgumentException ("Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation=\"true\"/> in configuration or <%@ Page EnableEventValidation=\"true\" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.");
+               }
+               
                public void ValidateEvent (string uniqueId, string argument)
                {
                        if (uniqueId == null || uniqueId.Length == 0)
@@ -503,17 +496,16 @@ namespace System.Web.UI
                        if (!page.EnableEventValidation)
                                return;
                        if (eventValidationValues == null)
-                               goto bad;
+                               throw InvalidPostBackException ();
                        
                        int hash = CalculateEventHash (uniqueId, argument);
                        for (int i = 0; i < eventValidationValues.Length; i++)
                                if (eventValidationValues [i] == hash)
                                        return;
                        
-                       bad:
-                       throw new ArgumentException ("Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation=\"true\"/> in configuration or <%@ Page EnableEventValidation=\"true\" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.");
+                       throw InvalidPostBackException ();
                }
-#endif
+
                void WriteScripts (HtmlTextWriter writer, ScriptEntry scriptList)
                {
                        if (scriptList == null)
@@ -529,7 +521,7 @@ namespace System.Web.UI
                                        break;
                                case ScriptEntryFormat.Include:
                                        EnsureEndScriptBlock (writer);
-                                       WriteClientScriptInclude (writer, scriptList.Script);
+                                       WriteClientScriptInclude (writer, scriptList.Script, scriptList.Type, scriptList.Key);
                                        break;
                                default:
                                        EnsureEndScriptBlock (writer);
@@ -557,7 +549,6 @@ namespace System.Web.UI
                        }
                }
 
-#if NET_2_0
                internal void RestoreEventValidationState (string fieldValue)
                {
                        if (!page.EnableEventValidation || fieldValue == null || fieldValue.Length == 0)
@@ -593,11 +584,6 @@ namespace System.Web.UI
                        return fmt.Serialize (array);
                }
 
-               internal string EventStateFieldName
-               {
-                       get { return "__EVENTVALIDATION"; }
-               }
-
                internal void WriteExpandoAttributes (HtmlTextWriter writer)
                {
                        if (expandoAttributes == null)
@@ -617,21 +603,19 @@ namespace System.Web.UI
                        writer.WriteLine ();
                }
 
-#endif
+               internal const string SCRIPT_BLOCK_START = "//<![CDATA[";
+               internal const string SCRIPT_BLOCK_END = "//]]>";
+               internal const string SCRIPT_ELEMENT_START = @"<script type=""text/javascript"">" + SCRIPT_BLOCK_START;
+               internal const string SCRIPT_ELEMENT_END = SCRIPT_BLOCK_END + "</script>";
+               
                internal static void WriteBeginScriptBlock (HtmlTextWriter writer)
                {
-                       writer.WriteLine ("<script"+
-#if !NET_2_0
-                               " language=\"javascript\""+
-#endif
-                               " type=\"text/javascript\">");
-                       writer.WriteLine ("<!--");
+                       writer.WriteLine (SCRIPT_ELEMENT_START);
                }
 
                internal static void WriteEndScriptBlock (HtmlTextWriter writer)
                {
-                       writer.WriteLine ("// -->");
-                       writer.WriteLine ("</script>");
+                       writer.WriteLine (SCRIPT_ELEMENT_END);
                }
                
                internal void WriteHiddenFields (HtmlTextWriter writer)
@@ -639,26 +623,48 @@ namespace System.Web.UI
                        if (hiddenFields == null)
                                return;
 
+                       writer.WriteLine ();
+#if NET_4_0
+                       writer.AddAttribute (HtmlTextWriterAttribute.Class, "aspNetHidden");
+#endif
                        writer.RenderBeginTag (HtmlTextWriterTag.Div);
+                       int oldIndent = writer.Indent;
+                       writer.Indent = 0;
+                       bool first = true;
+                       var sb = new StringBuilder ();
+                       
                        foreach (string key in hiddenFields.Keys) {
                                string value = hiddenFields [key] as string;
-                               writer.WriteLine ("<input type=\"hidden\" name=\"{0}\" id=\"{0}\" value=\"{1}\" />", key, value);
+                               if (first)
+                                       first = false;
+                               else
+                                       writer.WriteLine ();
+                               sb.Append ("<input type=\"hidden\" name=\"");
+                               sb.Append (key);
+                               sb.Append ("\" id=\"");
+                               sb.Append (key);
+                               sb.Append ("\" value=\"");
+                               sb.Append (HttpUtility.HtmlAttributeEncode (value));
+                               sb.Append ("\" />");
                        }
+                       writer.Write (sb.ToString ());
+                       writer.Indent = oldIndent;
                        writer.RenderEndTag (); // DIV
+                       writer.WriteLine ();
                        hiddenFields = null;
                }
                
-               internal void WriteClientScriptInclude (HtmlTextWriter writer, string path) {
+               internal void WriteClientScriptInclude (HtmlTextWriter writer, string path, Type type, string key) {
                                        if (!page.IsMultiForm)
                                                writer.WriteLine ("<script src=\"{0}\" type=\"text/javascript\"></script>", path);
                                        else {
-                                               string scriptKey = "inc_" + path.GetHashCode ().ToString ("X");
+                                               string scriptKey = "inc_" + (type.FullName + key).GetHashCode ().ToString ("X");
                                                writer.WriteLine ("<script type=\"text/javascript\">");
-                                               writer.WriteLine ("<!--");
-                                               writer.WriteLine ("if (document.{0} == null) {{", scriptKey);
-                                               writer.WriteLine ("\tdocument.{0} = true", scriptKey);
+                                               writer.WriteLine (SCRIPT_BLOCK_START);
+                                               writer.WriteLine ("if (!window.{0}) {{", scriptKey);
+                                               writer.WriteLine ("\twindow.{0} = true", scriptKey);
                                                writer.WriteLine ("\tdocument.write('<script src=\"{0}\" type=\"text/javascript\"><\\/script>'); }}", path);
-                                               writer.WriteLine ("// -->");
+                                               writer.WriteLine (SCRIPT_BLOCK_END);
                                                writer.WriteLine ("</script>");
                                        }
                }
@@ -702,13 +708,11 @@ namespace System.Web.UI
                        }
                }
 
-#if NET_2_0
                internal string GetClientValidationEvent (string validationGroup) {
                        if (page.IsMultiForm)
                                return "if (typeof(" + page.theForm + ".Page_ClientValidate) == 'function') " + page.theForm + ".Page_ClientValidate('" + validationGroup + "');";
                        return "if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate('" + validationGroup + "');";
                }
-#endif
 
                internal string GetClientValidationEvent ()
                {
@@ -725,29 +729,17 @@ namespace System.Web.UI
                        StringBuilder sb = new StringBuilder ();
                        ScriptEntry entry = submitStatements;
                        while (entry != null) {
-#if NET_2_0
                                sb.Append (EnsureEndsWithSemicolon (entry.Script));
-#else
-                               sb.Append (entry.Script);
-#endif
                                entry = entry.Next;
                        }
-#if NET_2_0
                        RegisterClientScriptBlock (GetType(), "HtmlForm-OnSubmitStatemen",
 @"
-" + (page.IsMultiForm ? page.theForm + "." : null) + @"WebForm_OnSubmit = function () {
+" + page.WebFormScriptReference + @".WebForm_OnSubmit = function () {
 " + sb.ToString () + @"
 return true;
 }
 ", true);
-                       if (page.IsMultiForm)
-                               return "javascript:return this.WebForm_OnSubmit();";
-                       else
-                               return "javascript:return WebForm_OnSubmit();";
-
-#else
-                       return sb.ToString ();
-#endif
+                       return "javascript:return " + page.WebFormScriptReference + ".WebForm_OnSubmit();";
                }
                
                internal static string GetScriptLiteral (object ob)
@@ -783,7 +775,7 @@ return true;
 
                                return sb.ToString ();
                        } else if (ob is bool) {
-                               return ob.ToString ().ToLower (CultureInfo.InvariantCulture);
+                               return ob.ToString ().ToLower (Helpers.InvariantCulture);
                        } else {
                                return ob.ToString ();
                        }
@@ -812,13 +804,11 @@ return true;
                        Include,
                }
 
-#if NET_2_0
                // helper method
                internal static string EnsureEndsWithSemicolon (string value) {
                        if (value != null && value.Length > 0 && value [value.Length - 1] != ';')
                                return value += ";";
                        return value;
                }
-#endif
        }
 }