XhtmlMobileTextWriter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

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 .
        internal void EnterStyle(Style style, String styleTag) { 
            StyleFilter filter = CurrentStyleClass.GetFilter(style); 
            if (filter == StyleFilter.None) {
                WriteFullBeginTag(styleTag); 
                _styleStack.Push(new StylePair(styleTag, style, StyleFilter.None));
                return;
            }
            EnterStyleInternal (style, styleTag, filter); 
        }
 
        // This internal overload can be used to enter style by setting the class element 
        // on a caller-specified tag, such as  or 
. internal void EnterStyle(XhtmlStyleClass styleClass, String styleTag) { if (styleClass.Filter == StyleFilter.None) { WriteFullBeginTag(styleTag); _styleStack.Push(new StylePair(styleTag, styleClass)); return; } EnterStyleInternal (styleClass, styleTag, null); } private Stack _styleStack = new Stack (); // StyleTag is the tag used for the class attribute. Possible values are div, span, // p, or any elt. Div and span are preferred over p, since p can only contain inline elements. internal void EnterStyleInternal (Style style, String styleTag, StyleFilter filter) { EnterStyleInternal(style, styleTag, filter, null); } internal void EnterStyleInternal (XhtmlStyleClass styleClass, String styleTag, NameValueCollection additionalAttributes) { EnterStyleInternal(styleClass, styleTag, additionalAttributes, false /* force tag to be written */); } internal void EnterStyleInternal (XhtmlStyleClass styleClass, String styleTag, NameValueCollection additionalAttributes, bool forceTag) { // EnterStyle is only expected to be called when _cachingRendering is true. // Specifically, the active form is rendered to the markup cache, then the cached // markup is later rendered to the page. This allows efficient use of CSS. // The if clause exits gracefully if the expected precondition is not met. if (!_cachingRendering) { Debug.Fail ("Only call EnterStyleInternal when caching rendering"); _styleStack.Push (new StylePair (String.Empty, styleClass)); return; } if (styleClass.Filter == StyleFilter.None && !forceTag) { // value comparison WritePendingBreak(); // Push a placeholder for this style with Tag == "", indicating no // tag was written. _styleStack.Push (new StylePair (String.Empty, styleClass)); return; } // Swap styleClass for an equivalent style class already in the hashtable, if there is one. styleClass = EnsureXhtmlStyleClassInHashtable (styleClass); WriteBeginTag (styleTag); if (styleClass != null && styleClass != CurrentStyleClass && styleClass.Filter != StyleFilter.None) { WriteAttribute ("class", styleClass.StyleClassName); } if (additionalAttributes != null) { foreach (String key in additionalAttributes.Keys) { WriteAttribute (key, additionalAttributes[key], true /* encode */); } } Write (">"); _styleStack.Push (new StylePair (styleTag, styleClass)); } internal void EnterStyleInternal (Style style, String styleTag, StyleFilter filter, NameValueCollection additionalAttributes) { EnterStyleInternal(new XhtmlStyleClass(style, filter), styleTag, additionalAttributes, false /* force tag to be written */); } /// public override void ExitFormat (Style style) { ExitStyle (style); } /// public override void ExitFormat (Style style, bool breakafter) { ExitStyle (style); if (breakafter) { SetPendingBreak(); } } /// public override void ExitLayout (Style style) { ExitStyle (style); } /// public override void ExitLayout (Style style, bool breakafter) { ExitStyle (style); if (breakafter) { SetPendingBreak(); } } /// public new void ExitStyle (Style style) { StylePair pair = (StylePair) _styleStack.Pop (); if (pair.Tag != null && pair.Tag.Length > 0) WriteEndTag (pair.Tag); if (IsBlockElement(pair.Tag)) { ClearPendingBreak(); } WriteLine (); } // Please see ASURT 144034 for this device-specific issue. // Internal-only utility to return name of an XhtmlFormatStyleClass that represents the (format) diff of the // parameter from the current style. This does not push the style stack -it is used only for tags with // small content models such as . internal String GetCssFormatClassName(Style style) { if (!_cachingRendering) { Debug.Fail ("Only call when caching rendering"); return null; } if (style == null) { return null; // caller should check for this return value. } // We need to write all non-default properties, so get the filter from the _defaultStyleClass. StyleFilter filter = _defaultStyleClass.GetFilter(style); filter &= XhtmlConstants.Format; if (filter == StyleFilter.None) { return null; } XhtmlFormatStyleClass styleClass = new XhtmlFormatStyleClass(style, filter); // Value returned is a valid styleClass which can be added to the attributes of, e.g., an element // to cause character formatting. Please see 144034 for the device specific issue. XhtmlStyleClass hashStyleClass = EnsureXhtmlStyleClassInHashtable(styleClass); if (hashStyleClass == null) { return null; } return hashStyleClass.StyleClassName; } internal string GetStyles () { StringBuilder styleBuilder = new StringBuilder (); string bodyStyleClassDefinition = _bodyStyle == null ? null : _bodyStyle.GetClassDefinition(); if (bodyStyleClassDefinition != null && bodyStyleClassDefinition.Trim().Length > 0 || _customBodyStyles != null) { styleBuilder.Append("body{\r\n"); styleBuilder.Append(bodyStyleClassDefinition); // null ok. styleBuilder.Append(_customBodyStyles); // null ok. styleBuilder.Append("}\r\n"); } foreach (String key in _orderedStyleClassKeys) { styleBuilder.Append (((XhtmlStyleClass) _styleHash [key]).ToString()); } return styleBuilder.ToString (); } private String GetWmlOnEventSubtree() { if (_wmlOnEnterForwardVarNames.Count == 0) { return String.Empty; } StringBuilder wmlOnEventBuilder = new StringBuilder (); wmlOnEventBuilder.Append("\r\n"); wmlOnEventBuilder.Append("\r\n"); foreach (String[] varInfo in _wmlOnEnterForwardVarNames) { String varName = varInfo[0]; String varValue = varInfo[1]; // Clear each client variable by rendering a setvar. wmlOnEventBuilder.Append("\r\n"); } wmlOnEventBuilder.Append("\r\n"); wmlOnEventBuilder.Append("\r\n"); return wmlOnEventBuilder.ToString(); } private void HandleBreakForTag(String tag) { if (IsBlockElement(tag)) { ClearPendingBreak(); } else { WritePendingBreak(); } } private bool IsBlockElement(String tag){ tag = tag.ToLower(CultureInfo.InvariantCulture); return // From xhtml 1.0 transitional dtd, definition of %block; entity. tag == "p" || // %heading; tag == "h1" || tag == "h2" || tag == "h3" || tag == "h4" || tag == "h5" || tag == "h6" || tag == "div" || // %lists; tag == "ul" || tag == "ol" || tag == "dl" || tag == "menu" || tag == "dir" || // %blocktext; tag == "pre" || tag == "hr" || tag == "blockquote" || tag == "center" || tag == "noframes" || tag == "isindex" || tag == "fieldset" || tag == "table"; } /// public virtual bool IsStyleSheetEmpty () { return _isStyleSheetEmpty; } // Call to switch from markup above the wml:onevent (if any) to below. /// public virtual void MarkWmlOnEventLocation() { InnerWriter = new StringWriter(_postWmlOnEventMarkupBuilder, CultureInfo.InvariantCulture); } internal String PopPhysicalCssClass() { return(String)_physicalCssClasses.Pop(); } internal void PushPhysicalCssClass(String cssClass) { _physicalCssClasses.Push(cssClass); } /// public virtual void SetBodyStyle (Style style) { // Filter is not strictly needed here, since default property values are not written anyway // but it is a good practice to provide a meaningful filter. StyleFilter filter = _defaultStyleClass.GetFilter(style); _bodyStyle = new XhtmlStyleClass (style, filter); _isStyleSheetEmpty = filter == 0; } /// public virtual void SetCacheKey (Cache cache) { String styleText = GetStyles(); _cacheKey = styleText.GetHashCode ().ToString (CultureInfo.InvariantCulture); // Avoid hash collisions and app developer values in cache by finding a new string. while (cache [_cacheKey] != null && (cache [_cacheKey].GetType () != typeof (String) || styleText != (String) cache [_cacheKey])) { _cacheKey += "x"; } _cacheKeyValid = true; } /// public virtual void SetPendingBreak() { _pendingBreak = true; } /// public virtual void SetSessionKey (HttpSessionState session) { String styleText = GetStyles(); _sessionKey = XhtmlConstants.SessionKeyPrefix + styleText.GetHashCode ().ToString (CultureInfo.InvariantCulture); // Avoid hash collisions and app developer values in session by finding a new string. while (session [_sessionKey] != null && (session [_sessionKey].GetType () != typeof (String) || styleText != (String) session [_sessionKey])) { _sessionKey += "x"; } _sessionKeyValid = true; } /// public override void WriteAttribute(String attribute, String value, bool encode) { // If the value is null, we return without writing anything. This is different // from HtmlTextWriter, which writes the name of the attribute, but no value at all. // A name with no value is illegal in Xml. if (value == null) { return; } if (encode) { // Unlike HTML encoding, we need to replace <> with < and >. // For performance reasons we duplicate some code, // rather than piggybacking on the inherited method. Write(' '); Write(attribute); Write("=\""); WriteEncodedAttributeValue(value); Write('\"'); } else { base.WriteAttribute(attribute, value, encode); } } /// public override void WriteBeginTag(String tag) { HandleBreakForTag(tag); base.WriteBeginTag(tag); } /// public new virtual void WriteBreak() { if (UseDivsForBreaks) { if((string)Device["usePOverDiv"] == "true") WriteLine("
"); else WriteLine("
"); } else { WriteLine ("
"); } } // CachedEndTag used for devices that cannot render
/// public virtual void WriteCachedMarkup () { Write (_cachedMarkup); } /// public virtual void WriteDoctypeDeclaration (Doctype type){ WriteLine((String)_doctypeDeclarations[type]); } /// public virtual void WriteEncodedAttributeValue(String value) { StringBuilder builder = new StringBuilder(); EncodeAttributeValue(value, builder); Write(builder.ToString()); } /// public override void WriteEndTag(String tag) { if (IsBlockElement(tag)) { ClearPendingBreak(); } base.WriteEndTag(tag); _cachedEndTag = tag; } /// public override void WriteFullBeginTag(String tag) { HandleBreakForTag(tag); base.WriteFullBeginTag(tag); } /// public virtual void WriteHiddenField(String name, String value) { WriteBeginTag ("input"); WriteAttribute ("type", "hidden"); WriteAttribute ("name", name); WriteAttribute ("value", value, true); WriteLine ("/>"); } // Write a hidden field with no value attribute (useful for __ET hidden field). /// public virtual void WriteHiddenField(String name) { WriteBeginTag ("input"); WriteAttribute ("type", "hidden"); WriteAttribute ("name", name); WriteLine ("/>"); } /// public override void WriteLine() { if (!_suppressNewLines) base.WriteLine(); } /// public override void WriteLine(String format, Object[] arg) { if (_suppressNewLines) { Write(format, arg); } else { base.WriteLine(format, arg); } } /// public override void WriteLine(String format, Object arg) { if (_suppressNewLines) { Write(format, arg); } else { base.WriteLine(format, arg); } } /// public override void WriteLine(String format, Object arg0, Object arg1) { if (_suppressNewLines) { Write(format, arg0, arg1); } else { base.WriteLine(format, arg0, arg1); } } /// public override void WriteLine(Object v) { if (_suppressNewLines) { Write(v); } else { base.WriteLine(v); } } /// public override void WriteLine(String s) { if (_suppressNewLines) { Write(s); } else { base.WriteLine(s); } } /// public override void WriteLine(Double v) { if (_suppressNewLines) { Write(v); } else { base.WriteLine(v); } } /// public override void WriteLine(Single v) { if (_suppressNewLines) { Write(v); } else { base.WriteLine(v); } } /// public override void WriteLine(Int64 v) { if (_suppressNewLines) { Write(v); } else { base.WriteLine(v); } } // Note: type UInt32 is not CLS compliant, hence no override for UInt32 /// public override void WriteLine(Int32 v) { if (_suppressNewLines) { Write(v); } else { base.WriteLine(v); } } /// public override void WriteLine(Boolean v) { if (_suppressNewLines) { Write(v); } else { base.WriteLine(v); } } /// public override void WriteLine(Char[] buffer, Int32 index, Int32 count) { if (_suppressNewLines) { Write(buffer, index, count); } else { base.WriteLine(buffer, index, count); } } /// public override void WriteLine(Char[] v) { if (_suppressNewLines) { Write(v); } else { base.WriteLine(v); } } /// public override void WriteLine(Char v) { if (_suppressNewLines) { Write(v); } else { base.WriteLine(v); } } /// public virtual void WritePendingBreak(){ if (_pendingBreak) { WriteBreak(); _pendingBreak = false; } } /// public virtual void WriteUrlParameter (String name, String value) { WriteEncodedUrlParameter (name); Write ("="); WriteEncodedUrlParameter (value); } /// public virtual void WriteXmlDeclaration (){ Write (""); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Style stack elements are of type StylePair. //////////////////////////////////////////////////////////////////////////////////////////////////// private struct StylePair { internal StylePair (String styleTag, XhtmlStyleClass styleClass) { Tag = styleTag; Class = styleClass; } internal StylePair (String styleTag, Style style, StyleFilter filter) { Tag = styleTag; Class = new XhtmlStyleClass (style, filter); } // Review: public fields internal String Tag; internal XhtmlStyleClass Class; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK