2008-11-18 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.HtmlControls / HtmlForm.cs
index f1615b861cf09a7b4ec459bac288c181411539a8..b56ecaa11e2033240f0ee917f699f531935e1d88 100644 (file)
@@ -31,6 +31,7 @@ using System.Collections.Specialized;
 using System.Security.Permissions;
 using System.Web.Util;
 using System.Web.UI.WebControls;
+using System.Web.Configuration;
 
 namespace System.Web.UI.HtmlControls 
 {
@@ -46,27 +47,46 @@ namespace System.Web.UI.HtmlControls
                }
 
 #if NET_2_0
-               string defaultbutton = "";
+               // LAMESPEC: This is undocumented on MSDN, but apparently it does exist on MS.NET.
+               // See https://bugzilla.novell.com/show_bug.cgi?id=442104
+               public string Action {
+                       get {
+                               string action = Attributes ["action"];
+                               if (String.IsNullOrEmpty (action))
+                                       return String.Empty;
+
+                               return action;
+                       }
+
+                       set {
+                               if (String.IsNullOrEmpty (value))
+                                       Attributes ["action"] = null;
+                               else
+                                       Attributes ["action"] = value;
+                       }
+               }
+               
+               string _defaultbutton;
                [DefaultValue ("")]
                public string DefaultButton
                {
                        get {
-                               return defaultbutton;
+                               return _defaultbutton ?? String.Empty;
                        }
                        set {
-                               defaultbutton = (value == null ? "" : value);
+                               _defaultbutton = value;
                        }
                }
 
-               string defaultfocus = "";
+               string _defaultfocus;
                [DefaultValue ("")]
                public string DefaultFocus
                {
                        get {
-                               return defaultfocus;
+                               return _defaultfocus ?? String.Empty;
                        }
                        set {
-                               defaultfocus = (value == null ? "" : value);
+                               _defaultfocus = value;
                        }
                }
 #endif         
@@ -195,126 +215,122 @@ namespace System.Web.UI.HtmlControls
                }
 
 #if NET_2_0
+               bool? isUplevel;
                internal bool DetermineRenderUplevel ()
                {
-                       /* this bit is c&p'ed from BaseValidator.DetermineRenderUplevel */
-                       try {
-                               if (Page != null && Page.Request != null)
-                                       return (
-                                               /* From someplace on the web: "JavaScript 1.2
-                                                * and later (also known as ECMAScript) has
-                                                * built-in support for regular
-                                                * expressions" */
-                                               ((Page.Request.Browser.EcmaScriptVersion.Major == 1
-                                                 && Page.Request.Browser.EcmaScriptVersion.Minor >= 2)
-                                                || (Page.Request.Browser.EcmaScriptVersion.Major > 1))
-
-                                               /* document.getElementById, .getAttribute,
-                                                * etc, are all DOM level 1.  I don't think we
-                                                * use anything in level 2.. */
-                                               && Page.Request.Browser.W3CDomVersion.Major >= 1);
-                       }
-                       catch {
-                               /* this can happen with a fake Page in nunit
-                                * tests, since Page.Context == null */
-                               ;
-                       }
-
-                       return false;
+#if TARGET_J2EE
+                       if (HttpContext.Current == null)
+                               return false;
+
+                       return (
+                               /* From someplace on the web: "JavaScript 1.2
+                                * and later (also known as ECMAScript) has
+                                * built-in support for regular
+                                * expressions" */
+                               ((Page.Request.Browser.EcmaScriptVersion.Major == 1
+                                 && Page.Request.Browser.EcmaScriptVersion.Minor >= 2)
+                                || (Page.Request.Browser.EcmaScriptVersion.Major > 1))
+
+                               /* document.getElementById, .getAttribute,
+                                * etc, are all DOM level 1.  I don't think we
+                                * use anything in level 2.. */
+                               && Page.Request.Browser.W3CDomVersion.Major >= 1);
+#else
+                       if (isUplevel != null)
+                               return (bool) isUplevel;
+                       
+                       isUplevel = UplevelHelper.IsUplevel (
+                               System.Web.Configuration.HttpCapabilitiesBase.GetUserAgentForDetection (HttpContext.Current.Request));
+                       return (bool) isUplevel;
+#endif
                }
 
                protected internal override void OnPreRender (EventArgs e)
                {
-                       string focus_id = null;
-                       bool need_script_block = false;
-                       bool render_uplevel;
-
                        base.OnPreRender(e);
-
-                       render_uplevel = DetermineRenderUplevel ();
-
-                       /* figure out if we have some control we're going to focus */
-                       if (DefaultFocus != null && DefaultFocus != "")
-                               focus_id = DefaultFocus;
-                       else if (DefaultButton != null && DefaultButton != "")
-                               focus_id = DefaultButton;
-
-                       /* decide if we need to include the script block */
-                       need_script_block = (focus_id != null || submitdisabledcontrols);
-
-                       if (render_uplevel) {
-                               Page.RequiresPostBackScript();
-
-                               if (need_script_block && !Page.ClientScript.IsClientScriptBlockRegistered ("Mono-System.Web-HtmlScriptBlock")) {
-                                       Page.ClientScript.RegisterClientScriptBlock ("Mono-System.Web-HtmlScriptBlock",
-                                                                                    String.Format ("<script language=\"JavaScript\" src=\"{0}\"></script>",
-                                                                                                   Page.ClientScript.GetWebResourceUrl (GetType(),
-                                                                                                                                        "webform.js")));
-                               }
-
-
-                               if (focus_id != null) {
-                                       Page.ClientScript.RegisterStartupScript ("HtmlForm-DefaultButton-StartupScript",
-                                                                                String.Format ("<script language=\"JavaScript\">\n" + 
-                                                                                               "<!--\n" + 
-                                                                                               "WebForm_AutoFocus('{0}');// -->\n" + 
-                                                                                               "</script>\n", focus_id));
-                               }
-
-                               if (submitdisabledcontrols) {
-                                       Page.ClientScript.RegisterOnSubmitStatement ("HtmlForm-SubmitDisabledControls-SubmitStatement",
-                                                                                    "javascript: return WebForm_OnSubmit();");
-                                       Page.ClientScript.RegisterStartupScript ("HtmlForm-SubmitDisabledControls-StartupScript",
-@"<script language=""JavaScript"">
-<!--
-function WebForm_OnSubmit() {
-WebForm_ReEnableControls();
-return true;
-} // -->
-</script>");
-                               }
-                       }
                }
 #endif         
 
                protected override void RenderAttributes (HtmlTextWriter w)
                {
-                       /* Need to always render: name, method, action
-                        * and id
+                       /* Need to always render: method, action and id
                         */
-
+                       /* The name attribute is rendered _only_ if we're not in
+                          2.0 mode or if the xhtml conformance mode is set to
+                          Legacy for 2.0 according to http://msdn2.microsoft.com/en-us/library/system.web.ui.htmlcontrols.htmlform.name.aspx
+                       */
+                       
                        string action;
-                       string file_path = Page.Request.FilePath;
-                       string current_path = Page.Request.CurrentExecutionFilePath;
-                       if (file_path == current_path) {
-                               // Just the filename will do
-                               action = UrlUtils.GetFile (file_path);
-                       } else {
-                               // Fun. We need to make cookieless sessions work, so no
-                               // absolute paths here.
-                               Uri current_uri = new Uri ("http://host" + current_path);
-                               Uri fp_uri = new Uri ("http://host" + file_path);
-                               action = fp_uri.MakeRelative (current_uri);
+#if NET_2_0
+                       string customAction = Attributes ["action"];
+#endif
+                       
+#if !TARGET_J2EE
+#if NET_2_0
+                       if (String.IsNullOrEmpty (customAction)) {
+#endif
+                               string file_path = Page.Request.FilePath;
+                               string current_path = Page.Request.CurrentExecutionFilePath;
+                               if (file_path == current_path) {
+                                       // Just the filename will do
+                                       action = UrlUtils.GetFile (file_path);
+                               } else {
+                                       // Fun. We need to make cookieless sessions work, so no
+                                       // absolute paths here.
+                                       Uri current_uri = new Uri ("http://host" + current_path);
+                                       Uri fp_uri = new Uri ("http://host" + file_path);
+                                       action = fp_uri.MakeRelative (current_uri);
+                               }
+#if NET_2_0
+                       } else
+                               action = customAction;
+#endif
+                       action += Page.Request.QueryStringRaw;
+#else
+                       // Allow the page to transform action to a portlet action url
+                       if (String.IsNullOrEmpty (customAction)) {
+                               string queryString = Page.Request.QueryStringRaw;
+                               action = CreateActionUrl (VirtualPathUtility.ToAppRelative (Page.Request.CurrentExecutionFilePath) +
+                                       (string.IsNullOrEmpty (queryString) ? string.Empty : "?" + queryString));
                        }
+                       else
+                               action = customAction;
 
-                       action += Page.Request.QueryStringRaw;
+#endif
 
-                       w.WriteAttribute ("name", Name);
+#if NET_2_0
+                       XhtmlConformanceSection xhtml = WebConfigurationManager.GetSection ("system.web/xhtmlConformance") as
+                               XhtmlConformanceSection;
+                       
+                       if (xhtml != null && xhtml.Mode == XhtmlConformanceMode.Legacy)
+#endif
+                               w.WriteAttribute ("name", Name);
 
                        w.WriteAttribute ("method", Method);
-                       w.WriteAttribute ("action", action);
-
+#if NET_2_0
+                       if (String.IsNullOrEmpty (customAction))
+#endif
+                               w.WriteAttribute ("action", action, true);
+
+                       /*
+                        * This is a hack that guarantees the ID is set properly for HtmlControl to
+                        * render it later on. As ugly as it is, we use it here because of the way
+                        * the ID, ClientID and UniqueID properties work internally in our Control
+                        * code.
+                        *
+                        * Fixes bug #82596
+                        */
                        if (ID == null) {
-                               /* If ID != null then HtmlControl will
-                                * write the id attribute
-                                */
-                               w.WriteAttribute ("id", ClientID);
-                               Attributes.Remove ("id");
+#pragma warning disable 219
+                               string client = ClientID;
+#pragma warning restore 219
                        }
-
+                       
                        string submit = Page.GetSubmitStatements ();
-                       if (submit != null && submit != "")
+                       if (submit != null && submit != "") {
+                               Attributes.Remove ("onsubmit");
                                w.WriteAttribute ("onsubmit", submit);
+                       }
                        
                        /* enctype and target should not be written if
                         * they are empty
@@ -331,12 +347,18 @@ return true;
 
 #if NET_2_0
                        string defaultbutton = DefaultButton;
-                       if (defaultbutton != null && defaultbutton != "") {
+                       if (!String.IsNullOrEmpty (defaultbutton)) {
                                Control c = FindControl (defaultbutton);
 
                                if (c == null || !(c is IButtonControl))
                                        throw new InvalidOperationException(String.Format ("The DefaultButton of '{0}' must be the ID of a control of type IButtonControl.",
                                                                                           ID));
+
+                               if (DetermineRenderUplevel ()) {
+                                       w.WriteAttribute (
+                                               "onkeypress",
+                                               "javascript:return " + Page.WebFormScriptReference + ".WebForm_FireDefaultButton(event, '" + c.ClientID + "')");
+                               }
                        }
 #endif