1 //------------------------------------------------------------------------------ 2 // <copyright file="MenuRendererClassic.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 //------------------------------------------------------------------------------ 6 7 namespace System.Web.UI.WebControls { 8 using System.Drawing; 9 using System.Globalization; 10 using System.Text; 11 12 public partial class Menu { 13 /// <devdoc>The classic (pre-ASP.NET 4.0) Menu renderer</devdoc> 14 private class MenuRendererClassic : MenuRenderer { 15 private int _cssStyleIndex; 16 MenuRendererClassic(Menu menu)17 public MenuRendererClassic(Menu menu) : base(menu) { } 18 19 /// <devdoc> 20 /// Make sure we are set up to render 21 /// </devdoc> EnsureRenderSettings()22 internal void EnsureRenderSettings() { 23 if (Menu.Page == null) { 24 return; 25 } 26 27 // If we don't have access to the header, we can't add the necessary styles 28 if (Menu.Page.Header == null) { 29 if (Menu._staticHoverStyle != null) { 30 throw new InvalidOperationException(SR.GetString(SR.NeedHeader, "Menu.StaticHoverStyle")); 31 } 32 if (Menu._dynamicHoverStyle != null) { 33 throw new InvalidOperationException(SR.GetString(SR.NeedHeader, "Menu.DynamicHoverStyle")); 34 } 35 return; 36 } 37 38 Menu._isNotIE = (Menu.Page.Request.Browser.MSDomVersion.Major < 4); 39 40 if (Menu.Page.SupportsStyleSheets || (Menu.Page.ScriptManager != null && Menu.Page.ScriptManager.IsInAsyncPostBack)) { 41 // Register the styles. NB the order here is important: later wins over earlier 42 Menu._panelStyle = Menu.Panel.GetEmptyPopOutPanelStyle(); 43 RegisterStyle(Menu._panelStyle); 44 45 RegisterStyle(Menu.RootMenuItemStyle); 46 47 RegisterStyle(Menu.ControlStyle); 48 49 // It's also vitally important to register hyperlinkstyles BEFORE 50 // their associated styles as we need to copy the data from this style 51 // and a registered style appears empty except for RegisteredClassName 52 if (Menu._staticItemStyle != null) { 53 Menu._staticItemStyle.HyperLinkStyle.DoNotRenderDefaults = true; 54 RegisterStyle(Menu._staticItemStyle.HyperLinkStyle); 55 RegisterStyle(Menu._staticItemStyle); 56 } 57 if (Menu._staticMenuStyle != null) { 58 RegisterStyle(Menu._staticMenuStyle); 59 } 60 61 if (Menu._dynamicItemStyle != null) { 62 Menu._dynamicItemStyle.HyperLinkStyle.DoNotRenderDefaults = true; 63 RegisterStyle(Menu._dynamicItemStyle.HyperLinkStyle); 64 RegisterStyle(Menu._dynamicItemStyle); 65 } 66 if (Menu._dynamicMenuStyle != null) { 67 RegisterStyle(Menu._dynamicMenuStyle); 68 } 69 70 foreach (MenuItemStyle style in Menu.LevelMenuItemStyles) { 71 style.HyperLinkStyle.DoNotRenderDefaults = true; 72 RegisterStyle(style.HyperLinkStyle); 73 RegisterStyle(style); 74 } 75 foreach (SubMenuStyle style in Menu.LevelSubMenuStyles) { 76 RegisterStyle(style); 77 } 78 79 if (Menu._staticSelectedStyle != null) { 80 Menu._staticSelectedStyle.HyperLinkStyle.DoNotRenderDefaults = true; 81 RegisterStyle(Menu._staticSelectedStyle.HyperLinkStyle); 82 RegisterStyle(Menu._staticSelectedStyle); 83 } 84 if (Menu._dynamicSelectedStyle != null) { 85 Menu._dynamicSelectedStyle.HyperLinkStyle.DoNotRenderDefaults = true; 86 RegisterStyle(Menu._dynamicSelectedStyle.HyperLinkStyle); 87 RegisterStyle(Menu._dynamicSelectedStyle); 88 } 89 foreach (MenuItemStyle style in Menu.LevelSelectedStyles) { 90 style.HyperLinkStyle.DoNotRenderDefaults = true; 91 RegisterStyle(style.HyperLinkStyle); 92 RegisterStyle(style); 93 } 94 95 if (Menu._staticHoverStyle != null) { 96 Menu._staticHoverHyperLinkStyle = new HyperLinkStyle(Menu._staticHoverStyle); 97 Menu._staticHoverHyperLinkStyle.DoNotRenderDefaults = true; 98 RegisterStyle(Menu._staticHoverHyperLinkStyle); 99 RegisterStyle(Menu._staticHoverStyle); 100 } 101 if (Menu._dynamicHoverStyle != null) { 102 Menu._dynamicHoverHyperLinkStyle = new HyperLinkStyle(Menu._dynamicHoverStyle); 103 Menu._dynamicHoverHyperLinkStyle.DoNotRenderDefaults = true; 104 RegisterStyle(Menu._dynamicHoverHyperLinkStyle); 105 RegisterStyle(Menu._dynamicHoverStyle); 106 } 107 } 108 } 109 PreRender(bool registerScript)110 public override void PreRender(bool registerScript) { 111 EnsureRenderSettings(); 112 113 if (Menu.Page != null && registerScript) { 114 // The menu script requires the general webforms script 115 Menu.Page.RegisterWebFormsScript(); 116 // Register the external Menu javascript file. 117 Menu.Page.ClientScript.RegisterClientScriptResource(Menu, typeof(Menu), "Menu.js"); 118 119 string clientDataObjectID = Menu.ClientDataObjectID; 120 121 // 122 StringBuilder createDataObjectScript = new StringBuilder("var "); 123 createDataObjectScript.Append(clientDataObjectID); 124 createDataObjectScript.Append(" = new Object();\r\n"); 125 createDataObjectScript.Append(clientDataObjectID); 126 createDataObjectScript.Append(".disappearAfter = "); 127 createDataObjectScript.Append(Menu.DisappearAfter); 128 createDataObjectScript.Append(";\r\n"); 129 createDataObjectScript.Append(clientDataObjectID); 130 createDataObjectScript.Append(".horizontalOffset = "); 131 createDataObjectScript.Append(Menu.DynamicHorizontalOffset); 132 createDataObjectScript.Append(";\r\n"); 133 createDataObjectScript.Append(clientDataObjectID); 134 createDataObjectScript.Append(".verticalOffset = "); 135 createDataObjectScript.Append(Menu.DynamicVerticalOffset); 136 createDataObjectScript.Append(";\r\n"); 137 if (Menu._dynamicHoverStyle != null) { 138 createDataObjectScript.Append(clientDataObjectID); 139 createDataObjectScript.Append(".hoverClass = '"); 140 createDataObjectScript.Append(Menu._dynamicHoverStyle.RegisteredCssClass); 141 if (!String.IsNullOrEmpty(Menu._dynamicHoverStyle.CssClass)) { 142 if (!String.IsNullOrEmpty(Menu._dynamicHoverStyle.RegisteredCssClass)) { 143 createDataObjectScript.Append(' '); 144 } 145 createDataObjectScript.Append(Menu._dynamicHoverStyle.CssClass); 146 } 147 createDataObjectScript.Append("';\r\n"); 148 if (Menu._dynamicHoverHyperLinkStyle != null) { 149 createDataObjectScript.Append(clientDataObjectID); 150 createDataObjectScript.Append(".hoverHyperLinkClass = '"); 151 createDataObjectScript.Append(Menu._dynamicHoverHyperLinkStyle.RegisteredCssClass); 152 if (!String.IsNullOrEmpty(Menu._dynamicHoverStyle.CssClass)) { 153 if (!String.IsNullOrEmpty(Menu._dynamicHoverHyperLinkStyle.RegisteredCssClass)) { 154 createDataObjectScript.Append(' '); 155 } 156 createDataObjectScript.Append(Menu._dynamicHoverStyle.CssClass); 157 } 158 createDataObjectScript.Append("';\r\n"); 159 } 160 } 161 if (Menu._staticHoverStyle != null && Menu._staticHoverHyperLinkStyle != null) { 162 createDataObjectScript.Append(clientDataObjectID); 163 createDataObjectScript.Append(".staticHoverClass = '"); 164 createDataObjectScript.Append(Menu._staticHoverStyle.RegisteredCssClass); 165 if (!String.IsNullOrEmpty(Menu._staticHoverStyle.CssClass)) { 166 if (!String.IsNullOrEmpty(Menu._staticHoverStyle.RegisteredCssClass)) { 167 createDataObjectScript.Append(' '); 168 } 169 createDataObjectScript.Append(Menu._staticHoverStyle.CssClass); 170 } 171 createDataObjectScript.Append("';\r\n"); 172 if (Menu._staticHoverHyperLinkStyle != null) { 173 createDataObjectScript.Append(clientDataObjectID); 174 createDataObjectScript.Append(".staticHoverHyperLinkClass = '"); 175 createDataObjectScript.Append(Menu._staticHoverHyperLinkStyle.RegisteredCssClass); 176 if (!String.IsNullOrEmpty(Menu._staticHoverStyle.CssClass)) { 177 if (!String.IsNullOrEmpty(Menu._staticHoverHyperLinkStyle.RegisteredCssClass)) { 178 createDataObjectScript.Append(' '); 179 } 180 createDataObjectScript.Append(Menu._staticHoverStyle.CssClass); 181 } 182 createDataObjectScript.Append("';\r\n"); 183 } 184 } 185 if ((Menu.Page.RequestInternal != null) && 186 (String.Equals(Menu.Page.Request.Url.Scheme, "https", StringComparison.OrdinalIgnoreCase))) { 187 188 createDataObjectScript.Append(clientDataObjectID); 189 createDataObjectScript.Append(".iframeUrl = '"); 190 createDataObjectScript.Append(Util.QuoteJScriptString( 191 Menu.Page.ClientScript.GetWebResourceUrl(typeof(Menu), "SmartNav.htm"), 192 false)); 193 createDataObjectScript.Append("';\r\n"); 194 } 195 196 // Register a startup script that creates a tree data object 197 Menu.Page.ClientScript.RegisterStartupScript(Menu, GetType(), 198 Menu.ClientID + "_CreateDataObject", 199 createDataObjectScript.ToString(), 200 true); 201 } 202 } 203 RegisterStyle(Style style)204 private void RegisterStyle(Style style) { 205 if (Menu.Page != null && Menu.Page.SupportsStyleSheets) { 206 string name = Menu.ClientID + "_" + _cssStyleIndex++.ToString(NumberFormatInfo.InvariantInfo); 207 Menu.Page.Header.StyleSheet.CreateStyleRule(style, Menu, "." + name); 208 style.SetRegisteredCssClass(name); 209 } 210 } 211 RenderBeginTag(HtmlTextWriter writer, bool staticOnly)212 public override void RenderBeginTag(HtmlTextWriter writer, bool staticOnly) { 213 ControlRenderingHelper.WriteSkipLinkStart(writer, Menu.RenderingCompatibility, Menu.DesignMode, Menu.SkipLinkText, Menu.SpacerImageUrl, Menu.ClientID); 214 215 // <table cellpadding="0" cellspacing="0" border="0" height="nodespacing"> 216 // Determine root menu style 217 // First initialize the root menu style that depends on the control style before we change it. (VSWhidbey 354878) 218 Menu.EnsureRootMenuStyle(); 219 if (Menu.Font != null) { 220 // Relative sizes should not be multiplied (VSWhidbey 457610) 221 Menu.Font.Reset(); 222 } 223 Menu.ForeColor = Color.Empty; 224 SubMenuStyle rootMenuStyle = Menu.GetSubMenuStyle(Menu.RootItem); 225 if (Menu.Page != null && Menu.Page.SupportsStyleSheets) { 226 string styleClass = Menu.GetSubMenuCssClassName(Menu.RootItem); 227 if (styleClass.Length > 0) { 228 if (Menu.CssClass.Length == 0) { 229 Menu.CssClass = styleClass; 230 } 231 else { 232 Menu.CssClass += ' ' + styleClass; 233 } 234 } 235 } 236 else { 237 if (rootMenuStyle != null && !rootMenuStyle.IsEmpty) { 238 // Remove FontInfo and ForeColor from the submenustyle where they are not relevant 239 // but may get copied from by ControlStyle (VSWhidbey 438980) 240 rootMenuStyle.Font.Reset(); 241 rootMenuStyle.ForeColor = Color.Empty; 242 // It's ok to change the control style at this point because viewstate has already been saved 243 Menu.ControlStyle.CopyFrom(rootMenuStyle); 244 } 245 } 246 247 Menu.AddAttributesToRender(writer); 248 249 writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0"); 250 writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0"); 251 writer.AddAttribute(HtmlTextWriterAttribute.Border, "0"); 252 writer.RenderBeginTag(HtmlTextWriterTag.Table); 253 } 254 RenderContents(HtmlTextWriter writer, bool staticOnly)255 public override void RenderContents(HtmlTextWriter writer, bool staticOnly) { 256 if (Menu.Orientation == Orientation.Horizontal) { 257 // Render one global tr as items won't render any 258 writer.RenderBeginTag(HtmlTextWriterTag.Tr); 259 } 260 bool enabled = Menu.IsEnabled; 261 if (Menu.StaticDisplayLevels > 1) { 262 if (Menu.Orientation == Orientation.Vertical) { 263 // Render the items themselves 264 for (int i = 0; i < Menu.Items.Count; i++) { 265 Menu.Items[i].RenderItem(writer, i, enabled, Menu.Orientation, staticOnly); 266 // And their static subitems 267 if (Menu.Items[i].ChildItems.Count != 0) { 268 writer.RenderBeginTag(HtmlTextWriterTag.Tr); 269 writer.RenderBeginTag(HtmlTextWriterTag.Td); 270 Menu.Items[i].Render(writer, enabled, staticOnly); 271 writer.RenderEndTag(); // td 272 writer.RenderEndTag(); // tr 273 } 274 } 275 } 276 else { 277 // Render the items themselves 278 for (int i = 0; i < Menu.Items.Count; i++) { 279 Menu.Items[i].RenderItem(writer, i, enabled, Menu.Orientation, staticOnly); 280 // And their static subitems 281 if (Menu.Items[i].ChildItems.Count != 0) { 282 writer.RenderBeginTag(HtmlTextWriterTag.Td); 283 Menu.Items[i].Render(writer, enabled, staticOnly); 284 writer.RenderEndTag(); // td 285 } 286 } 287 } 288 } 289 else { 290 // Render the items themselves 291 for (int i = 0; i < Menu.Items.Count; i++) { 292 Menu.Items[i].RenderItem(writer, i, enabled, Menu.Orientation, staticOnly); 293 } 294 } 295 296 if (Menu.Orientation == Orientation.Horizontal) { 297 // Render global /tr 298 writer.RenderEndTag(); 299 } 300 301 // Reset all these cached values so things can pick up changes in the designer 302 if (Menu.DesignMode) { 303 Menu.ResetCachedStyles(); 304 } 305 } 306 RenderEndTag(HtmlTextWriter writer, bool staticOnly)307 public override void RenderEndTag(HtmlTextWriter writer, bool staticOnly) { 308 writer.RenderEndTag(); // Table 309 310 // Render the submenus 311 if (Menu.StaticDisplayLevels <= 1 && !staticOnly) { 312 bool enabled = Menu.IsEnabled; 313 for (int i = 0; i < Menu.Items.Count; i++) { 314 Menu.Items[i].Render(writer, enabled, staticOnly); 315 } 316 } 317 318 ControlRenderingHelper.WriteSkipLinkEnd(writer, Menu.DesignMode, Menu.SkipLinkText, Menu.ClientID); 319 } 320 } 321 } 322 } 323