Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / MIT / System / Web / UI / MobileControls / Adapters / XhtmlAdapters / XhtmlMobileTextWriter.cs / 1305376 / XhtmlMobileTextWriter.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- using System; using System.Security.Permissions; using System.Web; using System.Web.Caching; using System.Web.Mobile; using System.Web.UI.MobileControls; using System.Web.UI.MobileControls.Adapters; using System.IO; using System.Text; using System.Drawing; using System.Collections; using System.Diagnostics; using System.Collections.Specialized; using System.Globalization; using System.Web.SessionState; #if COMPILING_FOR_SHIPPED_SOURCE namespace System.Web.UI.MobileControls.ShippedAdapterSource.XhtmlAdapters #else namespace System.Web.UI.MobileControls.Adapters.XhtmlAdapters #endif { ///[AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] public class XhtmlMobileTextWriter : MobileTextWriter { private int _styleCount = 0; private static readonly Style _defaultStyle = new Style (); private static readonly XhtmlStyleClass _defaultStyleClass = new XhtmlStyleClass(_defaultStyle, XhtmlConstants.All); // For certain WML 2.0 devices, we have to render a WML onevent element. // Therefore we need two markup builders -a preWmlOnEventLocation and a postWmlOnEventLocation. // Calling MarkWmlOnEventLocation switches the markup string builder from the pre to the post // builder. Everything is concatenated in order in EndCachedRendering / WriteCachedMarkup. private XhtmlStyleClass _bodyStyle = null; private TextWriter _cachedInnerWriter = null; private String _cacheKey; private String _cachedMarkup; private string _cachedEndTag = null; private bool _cacheKeyValid = false; private bool _cachingRendering; private string _customBodyStyles = null; private IDictionary _doctypeDeclarations = new Hashtable (); private bool _isStyleSheetEmpty = true; private ArrayList _orderedStyleClassKeys = new ArrayList (); private bool _pendingBreak = false; private Stack _physicalCssClasses = new Stack(); private StringBuilder _preWmlOnEventMarkupBuilder = new StringBuilder(); private StringBuilder _postWmlOnEventMarkupBuilder = new StringBuilder(); private string _sessionKey; private bool _sessionKeyValid = false; private IDictionary _styleHash = new Hashtable (); private bool _supportsNoWrapStyle = true; private bool _suppressNewLines = false; private ArrayList _wmlOnEnterForwardVarNames = new ArrayList(); private bool _useDivsForBreaks = false; /// public XhtmlMobileTextWriter (TextWriter writer, MobileCapabilities device) : base(writer, device) { _doctypeDeclarations[Doctype.XhtmlBasic] = ""; _doctypeDeclarations[Doctype.XhtmlMobileProfile] = ""; _doctypeDeclarations[Doctype.Wml20] = ""; } internal String CachedEndTag { get { return _cachedEndTag; } } /// public virtual String CacheKey { get { // Exception is for extensibility scenarios. if (!_cacheKeyValid) { throw new Exception (SR.GetString( SR.XhtmlMobileTextWriter_CacheKeyNotSet)); } return _cacheKey; } } #if UNUSED_CODE internal bool CssClassOnStack { get { return _physicalCssClasses.Count > 0; } } #endif // Saves a couple of lines of code in most cases. internal XhtmlStyleClass CurrentStyleClass { get { if (_styleStack.Count > 0) { StylePair pair = (StylePair) _styleStack.Peek (); return pair.Class; } else { // If the style stack is empty, the current style is default. return _defaultStyleClass; } } } /// public String CustomBodyStyles { get { return _customBodyStyles; } set { _isStyleSheetEmpty = false; _customBodyStyles = value; } } /// public virtual String SessionKey { // Exception is for extensibility scenarios. get { if (!_sessionKeyValid) { throw new Exception (SR.GetString( SR.XhtmlMobileTextWriter_SessionKeyNotSet)); } return _sessionKey; } } public virtual bool SupportsNoWrapStyle { get { return _supportsNoWrapStyle; } set { _supportsNoWrapStyle = value; } } /// public bool SuppressNewLine { get { return _suppressNewLines; } set { _suppressNewLines = value; } } /// public bool UseDivsForBreaks { get { return _useDivsForBreaks; } set { _useDivsForBreaks = value; } } // Add a variable name to clear. /// public virtual void AddOnEnterForwardSetVar(String var) { AddOnEnterForwardSetVar(var, String.Empty); } /// public virtual void AddOnEnterForwardSetVar(String var, String value) { _wmlOnEnterForwardVarNames.Add(new String[2]{var, value}); } /// public virtual void BeginCachedRendering () { _cachedInnerWriter = InnerWriter; InnerWriter = new StringWriter (_preWmlOnEventMarkupBuilder, CultureInfo.InvariantCulture); _cachingRendering = true; } internal void ClearCachedEndTag() { _cachedEndTag = null; } /// public virtual void ClearPendingBreak() { _pendingBreak = false; } //////////////////////////////////////////////////////////////////////////////////////////////////// // Optimization for physical stylesheets. We only write the cssClass attribute if it differs // (case-sensitive) from the current cssClass. The current cssClass is kept in a stack. //////////////////////////////////////////////////////////////////////////////////////////////////// internal bool DiffersFromCurrentPhysicalCssClass(String cssClass) { // Case sensitive comparison. return _physicalCssClasses.Count == 0 || String.Compare(cssClass, (String)_physicalCssClasses.Peek(), StringComparison.Ordinal) != 0; } private void EncodeAttributeValue(String value, StringBuilder encodedValue) { StringWriter writer = new StringWriter(encodedValue, CultureInfo.InvariantCulture); HttpUtility.HtmlEncode(value, writer); } // Expose base method to xhtml control adapter. internal string EncodeUrlInternal(String url) { return base.EncodeUrl(url); } /// public virtual void EndCachedRendering () { StringBuilder cachedMarkupBuilder = new StringBuilder(); cachedMarkupBuilder.Append(_preWmlOnEventMarkupBuilder.ToString()); cachedMarkupBuilder.Append(GetWmlOnEventSubtree()); cachedMarkupBuilder.Append(_postWmlOnEventMarkupBuilder.ToString()); _cachedMarkup = cachedMarkupBuilder.ToString (); InnerWriter = _cachedInnerWriter; _cachingRendering = false; } private XhtmlStyleClass EnsureXhtmlStyleClassInHashtable (XhtmlStyleClass styleClass) { if (styleClass.Filter == StyleFilter.None) { return CurrentStyleClass; } // We hash the style classes by the class definition. String classKey = styleClass.GetClassDefinition (); XhtmlStyleClass existingClass = (XhtmlStyleClass) _styleHash [classKey]; string className = existingClass == null ? "s" + _styleCount++ : existingClass.StyleClassName; if (existingClass == null) { // Used to retrieve style classes in order from the hash table. _orderedStyleClassKeys.Add (classKey); styleClass.StyleClassName = className; _styleHash [classKey] = styleClass; _isStyleSheetEmpty = false; } return existingClass == null ? styleClass : existingClass; } /// public override void EnterFormat(Style style) { StyleFilter filter = CurrentStyleClass.GetFilter(style); EnterStyleInternal(new XhtmlFormatStyleClass(style, filter), "span", null /* no additional attributes */); } /// public override void EnterLayout (Style style) { StyleFilter filter = CurrentStyleClass.GetFilter(style); if (!SupportsNoWrapStyle) { filter &= ~StyleFilter.Wrapping; } EnterStyleInternal (new XhtmlLayoutStyleClass(style, filter), "div", null /* no additional attributes */, true /* force tag to be written */); } // Hiding inherited member works because dynamic type is same as static type. /// public new void EnterStyle (Style style) { StyleFilter filter = CurrentStyleClass.GetFilter(style); if (!SupportsNoWrapStyle) { filter &= ~StyleFilter.Wrapping; } // We prefer span to div because span is inline. if ((filter & XhtmlConstants.Layout) == 0) { EnterStyleInternal (style, "span", filter); } else { EnterStyleInternal (new XhtmlStyleClass(style, filter), "div", null /*additional attributes */, true /* force tag to be written */); } } // This internal overload can be used to enter style by setting the class element // on a caller-specified tag, such as or