HTMLTextWriter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / UI / HTMLTextWriter.cs / 1305376 / HTMLTextWriter.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

// HtmlTextWriter.cs 
// 
namespace System.Web.UI {
    using System; 
    using System.Collections;
    using System.Collections.Specialized;
    using System.IO;
    using System.Text; 
    using System.Globalization;
    using System.Security.Permissions; 
    using System.Web.UI.WebControls; 
    using System.Web.Util;
 
    public class HtmlTextWriter : TextWriter {
        private Layout _currentLayout = new Layout(HorizontalAlign.NotSet, true /* wrap */);
        private Layout _currentWrittenLayout = null;
 
        internal virtual bool RenderDivAroundHiddenInputs {
            get { 
                return true; 
            }
        } 

        public virtual void EnterStyle(Style style, HtmlTextWriterTag tag) {
            if (!style.IsEmpty || tag != HtmlTextWriterTag.Span) {
                style.AddAttributesToRender(this); 
                RenderBeginTag(tag);
            } 
        } 

        public virtual void ExitStyle(System.Web.UI.WebControls.Style style, HtmlTextWriterTag tag) { 
            // Review: This requires that the style doesn't change between beginstyle/endstyle.
            if (!style.IsEmpty || tag != HtmlTextWriterTag.Span) {
                RenderEndTag();
            } 
        }
 
        internal virtual void OpenDiv() { 
            OpenDiv(_currentLayout,
                    (_currentLayout != null) && (_currentLayout.Align != HorizontalAlign.NotSet), 
                    (_currentLayout != null) && !_currentLayout.Wrap);
        }

        private void OpenDiv(Layout layout, bool writeHorizontalAlign, bool writeWrapping) { 
            WriteBeginTag("div");
            if (writeHorizontalAlign) { 
                String alignment; 
                switch (layout.Align) {
                case HorizontalAlign.Right: 
                    alignment = "text-align:right";
                    break;

                case HorizontalAlign.Center: 
                    alignment = "text-align:center";
                    break; 
 
                default:
                    alignment = "text-align:left"; 
                    break;
                }

                WriteAttribute("style", alignment); 
            }
            if (writeWrapping) { 
                WriteAttribute("mode", 
                               layout.Wrap == true ? "wrap" : "nowrap");
            } 
            Write('>');
            _currentWrittenLayout = layout;
        }
 
        public virtual bool IsValidFormAttribute(String attribute) {
            return true; 
        } 

        private TextWriter writer; 
        private int indentLevel;
        private bool tabsPending;
        private string tabString;
        public const char TagLeftChar = '<'; 
        public const char TagRightChar = '>';
        public const string SelfClosingChars = " /"; 
        public const string SelfClosingTagEnd = " />"; 
        public const string EndTagLeftChars = "= 0, "Bogus Indent... probably caused by mismatched Indent++ and Indent--");
                if (value < 0) { 
                    value = 0;
                } 
                indentLevel = value; 
            }
        } 

        //Gets or sets the TextWriter to use.
        public TextWriter InnerWriter {
            get { 
                return writer;
            } 
            set { 
                writer = value;
                _httpWriter = value as HttpWriter; 
            }
        }
/*
        // 

 
 

 



 

 
 
*/
        public virtual void BeginRender() { 
        }

        //Closes the document being written to.
        public override void Close() { 
            writer.Close();
        } 
 
        public virtual void EndRender() {
        } 

        public virtual void EnterStyle(System.Web.UI.WebControls.Style style) {
            EnterStyle(style, HtmlTextWriterTag.Span);
        } 

        public virtual void ExitStyle(System.Web.UI.WebControls.Style style) { 
            ExitStyle(style, HtmlTextWriterTag.Span); 
        }
 
        public override void Flush() {
            writer.Flush();
        }
 
        protected virtual void OutputTabs() {
            if (tabsPending) { 
                for (int i=0; i < indentLevel; i++) { 
                    writer.Write(tabString);
                } 
                tabsPending = false;
            }
        }
 
        //Writes a string to the text stream.
        [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] 
        public override void Write(string s) { 
            if (tabsPending) {
                OutputTabs(); 
            }
            writer.Write(s);
        }
 
        //Writes the text representation of a Boolean value to the text stream.
        public override void Write(bool value) { 
            if (tabsPending) { 
                OutputTabs();
            } 
            writer.Write(value);
        }

        //Writes a character to the text stream. 
        [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public override void Write(char value) { 
            if (tabsPending) { 
                OutputTabs();
            } 
            writer.Write(value);
        }

        // Writes a character array to the text stream. 
        public override void Write(char[] buffer) {
            if (tabsPending) { 
                OutputTabs(); 
            }
            writer.Write(buffer); 
        }

        // Writes a subarray of characters to the text stream.
        public override void Write(char[] buffer, int index, int count) { 
            if (tabsPending) {
                OutputTabs(); 
            } 
            writer.Write(buffer, index, count);
        } 

        // Writes the text representation of a Double to the text stream.
        public override void Write(double value) {
            if (tabsPending) { 
                OutputTabs();
            } 
            writer.Write(value); 
        }
 
        // Writes the text representation of a Single to the text stream.
        public override void Write(float value) {
            if (tabsPending) {
                OutputTabs(); 
            }
            writer.Write(value); 
        } 

        // Writes the text representation of an integer to the text stream. 
        public override void Write(int value) {
            if (tabsPending) {
                OutputTabs();
            } 
            writer.Write(value);
        } 
 
        // Writes the text representation of an 8-byte integer to the text stream.
        public override void Write(long value) { 
            if (tabsPending) {
                OutputTabs();
            }
            writer.Write(value); 
        }
 
        // Writes the text representation of an object to the text stream. 
        public override void Write(object value) {
            if (tabsPending) { 
                OutputTabs();
            }
            writer.Write(value);
        } 

        // Writes out a formatted string, using the same semantics as specified. 
        public override void Write(string format, object arg0) { 
            if (tabsPending) {
                OutputTabs(); 
            }
            writer.Write(format, arg0);
        }
 
        // Writes out a formatted string, using the same semantics as specified.
        public override void Write(string format, object arg0, object arg1) { 
            if (tabsPending) { 
                OutputTabs();
            } 
            writer.Write(format, arg0, arg1);
        }

        // Writes out a formatted string, using the same semantics as specified. 
        public override void Write(string format, params object[] arg) {
            if (tabsPending) { 
                OutputTabs(); 
            }
            writer.Write(format, arg); 
        }

        // Writes the specified string to a line without tabs.
        public void WriteLineNoTabs(string s) { 
            writer.WriteLine(s);
            tabsPending = true; 
        } 

        // Writes the specified string followed by a line terminator to the text stream. 
        public override void WriteLine(string s) {
            if (tabsPending) {
                OutputTabs();
            } 
            writer.WriteLine(s);
            tabsPending = true; 
        } 

        // Writes a line terminator. 
        public override void WriteLine() {
            writer.WriteLine();
            tabsPending = true;
        } 

        // Writes the text representation of a Boolean followed by a line terminator to the text stream. 
        public override void WriteLine(bool value) { 
            if (tabsPending) {
                OutputTabs(); 
            }
            writer.WriteLine(value);
            tabsPending = true;
        } 

        public override void WriteLine(char value) { 
            if (tabsPending) { 
                OutputTabs();
            } 
            writer.WriteLine(value);
            tabsPending = true;
        }
 
        public override void WriteLine(char[] buffer) {
            if (tabsPending) { 
                OutputTabs(); 
            }
            writer.WriteLine(buffer); 
            tabsPending = true;
        }

        public override void WriteLine(char[] buffer, int index, int count) { 
            if (tabsPending) {
                OutputTabs(); 
            } 
            writer.WriteLine(buffer, index, count);
            tabsPending = true; 
        }

        public override void WriteLine(double value) {
            if (tabsPending) { 
                OutputTabs();
            } 
            writer.WriteLine(value); 
            tabsPending = true;
        } 

        public override void WriteLine(float value) {
            if (tabsPending) {
                OutputTabs(); 
            }
            writer.WriteLine(value); 
            tabsPending = true; 
        }
 
        public override void WriteLine(int value) {
            if (tabsPending) {
                OutputTabs();
            } 
            writer.WriteLine(value);
            tabsPending = true; 
        } 

        public override void WriteLine(long value) { 
            if (tabsPending) {
                OutputTabs();
            }
            writer.WriteLine(value); 
            tabsPending = true;
        } 
 
        public override void WriteLine(object value) {
            if (tabsPending) { 
                OutputTabs();
            }
            writer.WriteLine(value);
            tabsPending = true; 
        }
 
        public override void WriteLine(string format, object arg0) { 
            if (tabsPending) {
                OutputTabs(); 
            }
            writer.WriteLine(format, arg0);
            tabsPending = true;
        } 

        public override void WriteLine(string format, object arg0, object arg1) { 
            if (tabsPending) { 
                OutputTabs();
            } 
            writer.WriteLine(format, arg0, arg1);
            tabsPending = true;
        }
 
        public override void WriteLine(string format, params object[] arg) {
            if (tabsPending) { 
                OutputTabs(); 
            }
            writer.WriteLine(format, arg); 
            tabsPending = true;
        }

        [CLSCompliant(false)] 
        public override void WriteLine(UInt32 value) {
            if (tabsPending) { 
                OutputTabs(); 
            }
            writer.WriteLine(value); 
            tabsPending = true;
        }

        protected static void RegisterTag(string name, HtmlTextWriterTag key) { 
            RegisterTag(name, key, TagType.Other);
        } 
 
        private static void RegisterTag(string name, HtmlTextWriterTag key, TagType type) {
            string nameLCase = name.ToLower(CultureInfo.InvariantCulture); 

            _tagKeyLookupTable.Add(nameLCase, key);

            // Pre-resolve the end tag 
            string endTag = null;
            if (type != TagType.NonClosing && key != HtmlTextWriterTag.Unknown) { 
                endTag = EndTagLeftChars + nameLCase + TagRightChar.ToString(CultureInfo.InvariantCulture); 
            }
 
            if ((int)key < _tagNameLookupArray.Length) {
                _tagNameLookupArray[(int)key] = new TagInformation(name, type, endTag);
            }
        } 

        protected static void RegisterAttribute(string name, HtmlTextWriterAttribute key) { 
            RegisterAttribute(name, key, false); 
        }
 
        private static void RegisterAttribute(string name, HtmlTextWriterAttribute key, bool encode) {
            RegisterAttribute(name, key, encode, false);
        }
 
        private static void RegisterAttribute(string name, HtmlTextWriterAttribute key, bool encode, bool isUrl) {
            string nameLCase = name.ToLower(CultureInfo.InvariantCulture); 
 
            _attrKeyLookupTable.Add(nameLCase, key);
 
            if ((int)key < _attrNameLookupArray.Length) {
                _attrNameLookupArray[(int)key] = new AttributeInformation(name, encode, isUrl);
            }
        } 

        protected static void RegisterStyle(string name, HtmlTextWriterStyle key) { 
            CssTextWriter.RegisterAttribute(name, key); 
        }
 
        public HtmlTextWriter(TextWriter writer) : this(writer, DefaultTabString) {
        }

        public HtmlTextWriter(TextWriter writer, string tabString) : base(CultureInfo.InvariantCulture) { 
            this.writer = writer;
            this.tabString = tabString; 
            indentLevel = 0; 
            tabsPending = false;
 
            // If it's an http writer, save it
            _httpWriter = writer as HttpWriter;

            _isDescendant = (GetType() != typeof(HtmlTextWriter)); 

            _attrCount = 0; 
            _styleCount = 0; 
            _endTagCount = 0;
            _inlineCount = 0; 
        }

        protected HtmlTextWriterTag TagKey {
            get { 
                return _tagKey;
            } 
            set { 
                _tagIndex = (int) value;
                if (_tagIndex < 0 || _tagIndex >= _tagNameLookupArray.Length) { 
                    throw new ArgumentOutOfRangeException("value");
                }
                _tagKey = value;
                // If explicitly setting to uknown, keep the old tag name. This allows a string tag 
                // to be set without clobbering it if setting TagKey to itself.
                if (value != HtmlTextWriterTag.Unknown) { 
                    _tagName = _tagNameLookupArray[_tagIndex].name; 
                }
            } 
        }

        protected string TagName {
            get { 
                return _tagName;
            } 
            set { 
                _tagName = value;
                _tagKey = GetTagKey(_tagName); 
                _tagIndex = (int) _tagKey;
                Debug.Assert(_tagIndex >= 0 && _tagIndex < _tagNameLookupArray.Length);
            }
        } 

        public virtual void AddAttribute(string name,string value) { 
            HtmlTextWriterAttribute attributeKey = GetAttributeKey(name); 
            value = EncodeAttributeValue(attributeKey, value);
 
            AddAttribute(name, value, attributeKey);
        }

        //do not fix this spelling error 
        //believe it or not, it is a backwards breaking change for languages that
        //support late binding with named parameters VB.Net 
        public virtual void AddAttribute(string name,string value, bool fEndode) { 
            value = EncodeAttributeValue(value, fEndode);
            AddAttribute(name, value, GetAttributeKey(name)); 
        }

        public virtual void AddAttribute(HtmlTextWriterAttribute key,string value) {
            int attributeIndex = (int) key; 
            if (attributeIndex >= 0 &&  attributeIndex < _attrNameLookupArray.Length) {
                AttributeInformation info = _attrNameLookupArray[attributeIndex]; 
                AddAttribute(info.name,value,key, info.encode, info.isUrl); 
            }
        } 

        public virtual void AddAttribute(HtmlTextWriterAttribute key,string value, bool fEncode) {
            int attributeIndex = (int) key;
            if (attributeIndex >= 0 &&  attributeIndex < _attrNameLookupArray.Length) { 
                AttributeInformation info = _attrNameLookupArray[attributeIndex];
                AddAttribute(info.name,value,key, fEncode, info.isUrl); 
            } 
        }
 
        protected virtual void AddAttribute(string name, string value, HtmlTextWriterAttribute key) {
            AddAttribute(name, value, key, false, false);
        }
 

        private void AddAttribute(string name, string value, HtmlTextWriterAttribute key, bool encode, bool isUrl) { 
            if(_attrList == null) { 
                _attrList = new RenderAttribute[20];
            } 
            else if (_attrCount >= _attrList.Length) {
                RenderAttribute[] newArray = new RenderAttribute[_attrList.Length * 2];
                Array.Copy(_attrList, newArray, _attrList.Length);
                _attrList = newArray; 
            }
            RenderAttribute attr; 
            attr.name = name; 
            attr.value = value;
            attr.key = key; 
            attr.encode = encode;
            attr.isUrl = isUrl;
            _attrList[_attrCount] = attr;
            _attrCount++; 
        }
 
        public virtual void AddStyleAttribute(string name, string value) { 
            AddStyleAttribute(name, value, CssTextWriter.GetStyleKey(name));
        } 

        public virtual void AddStyleAttribute(HtmlTextWriterStyle key, string value) {
            AddStyleAttribute(CssTextWriter.GetStyleName(key), value, key);
        } 

        protected virtual void AddStyleAttribute(string name, string value, HtmlTextWriterStyle key) { 
            if(_styleList == null) { 
                _styleList = new RenderStyle[20];
            } 
            else if (_styleCount > _styleList.Length) {
                RenderStyle[] newArray = new RenderStyle[_styleList.Length * 2];
                Array.Copy(_styleList, newArray, _styleList.Length);
                _styleList = newArray; 
            }
 
            RenderStyle style; 

            style.name = name; 
            style.key = key;

            string attributeValue = value;
            if (CssTextWriter.IsStyleEncoded(key)) { 
                // note that only css attributes in an inline style value need to be attribute encoded
                // since CssTextWriter is used to render both embedded stylesheets and style attributes 
                // the attribute encoding is done here. 
                attributeValue = HttpUtility.HtmlAttributeEncode(value);
            } 
            style.value = attributeValue;

            _styleList[_styleCount] = style;
            _styleCount++; 
        }
 
        protected string EncodeAttributeValue(string value, bool fEncode) { 
            if (value == null) {
                return null; 
            }

            if (!fEncode)
                return value; 

            return HttpUtility.HtmlAttributeEncode(value); 
        } 

        protected virtual string EncodeAttributeValue(HtmlTextWriterAttribute attrKey, string value) { 
            bool encode = true;

            if (0 <= (int)attrKey && (int)attrKey < _attrNameLookupArray.Length) {
                encode = _attrNameLookupArray[(int)attrKey].encode; 
            }
 
            return EncodeAttributeValue(value, encode); 
        }
 
        // This does minimal URL encoding by converting spaces in the url to "%20".
        protected string EncodeUrl(string url) {
            // VSWhidbey 454348: escaped spaces in UNC share paths don't work in IE, so
            // we're not going to encode if it's a share. 
            if (!UrlPath.IsUncSharePath(url)) {
                return HttpUtility.UrlPathEncode(url); 
            } 
            return url;
        } 

        protected HtmlTextWriterAttribute GetAttributeKey(string attrName) {
            if (!String.IsNullOrEmpty(attrName)) {
                object key = _attrKeyLookupTable[attrName.ToLower(CultureInfo.InvariantCulture)]; 
                if (key != null)
                    return(HtmlTextWriterAttribute)key; 
            } 

            return(HtmlTextWriterAttribute)(-1); 
        }

        protected string GetAttributeName(HtmlTextWriterAttribute attrKey) {
            if ((int)attrKey >= 0 && (int)attrKey < _attrNameLookupArray.Length) 
                return _attrNameLookupArray[(int)attrKey].name;
 
            return string.Empty; 
        }
 
        protected HtmlTextWriterStyle GetStyleKey(string styleName) {
            return CssTextWriter.GetStyleKey(styleName);
        }
 
        protected string GetStyleName(HtmlTextWriterStyle styleKey) {
            return CssTextWriter.GetStyleName(styleKey); 
        } 

        protected virtual HtmlTextWriterTag GetTagKey(string tagName) { 
            if (!String.IsNullOrEmpty(tagName)) {
                object key = _tagKeyLookupTable[tagName.ToLower(CultureInfo.InvariantCulture)];
                if (key != null)
                    return(HtmlTextWriterTag)key; 
            }
 
            return HtmlTextWriterTag.Unknown; 
        }
 
        protected virtual string GetTagName(HtmlTextWriterTag tagKey) {
            int tagIndex = (int) tagKey;
            if (tagIndex >= 0 && tagIndex < _tagNameLookupArray.Length)
                return _tagNameLookupArray[tagIndex].name; 

            return string.Empty; 
        } 

        protected bool IsAttributeDefined(HtmlTextWriterAttribute key) { 
            for (int i = 0; i < _attrCount; i++) {
                if (_attrList[i].key == key) {
                    return true;
                } 
            }
            return false; 
        } 

        protected bool IsAttributeDefined(HtmlTextWriterAttribute key, out string value) { 
            value = null;
            for (int i = 0; i < _attrCount; i++) {
                if (_attrList[i].key == key) {
                    value = _attrList[i].value; 
                    return true;
                } 
            } 
            return false;
        } 

        protected bool IsStyleAttributeDefined(HtmlTextWriterStyle key) {
            for (int i = 0; i < _styleCount; i++) {
                if (_styleList[i].key == key) { 
                    return true;
                } 
            } 
            return false;
        } 

        protected bool IsStyleAttributeDefined(HtmlTextWriterStyle key, out string value) {
            value = null;
            for (int i = 0; i < _styleCount; i++) { 
                if (_styleList[i].key == key) {
                    value = _styleList[i].value; 
                    return true; 
                }
            } 
            return false;
        }

        protected virtual bool OnAttributeRender(string name, string value, HtmlTextWriterAttribute key) { 
            return true;
        } 
 
        protected virtual bool OnStyleAttributeRender(string name, string value, HtmlTextWriterStyle key) {
            return true; 
        }

        protected virtual bool OnTagRender(string name, HtmlTextWriterTag key) {
            return true; 
        }
 
        protected string PopEndTag() { 
            if (_endTagCount <= 0) {
                throw new InvalidOperationException(SR.GetString(SR.HTMLTextWriterUnbalancedPop)); 
            }
            _endTagCount--;
            TagKey = _endTags[_endTagCount].tagKey;
            return _endTags[_endTagCount].endTagText; 
        }
 
        protected void PushEndTag(string endTag) { 
            if(_endTags == null) {
                _endTags = new TagStackEntry[16]; 
            }
            else if (_endTagCount >= _endTags.Length) {
                TagStackEntry[] newArray = new TagStackEntry[_endTags.Length * 2];
                Array.Copy(_endTags, newArray, _endTags.Length); 
                _endTags = newArray;
            } 
            _endTags[_endTagCount].tagKey = _tagKey; 
            _endTags[_endTagCount].endTagText= endTag;
            _endTagCount++; 
        }

        // This calls filers out all attributes and style attributes by calling OnAttributeRender
        // and OnStyleAttributeRender on all properites and updates the lists 
        protected virtual void FilterAttributes() {
 
            // Create the filtered list of styles 
            int newStyleCount = 0;
            for (int i = 0; i < _styleCount; i++) { 
                RenderStyle style = _styleList[i];
                if (OnStyleAttributeRender(style.name, style.value, style.key)) {
                    // Update the list. This can be done in place
                    _styleList[newStyleCount] = style; 
                    newStyleCount++;
                } 
            } 
            // Update the count
            _styleCount = newStyleCount; 

            // Create the filtered list of attributes
            int newAttrCount = 0;
            for (int i = 0; i < _attrCount; i++) { 
                RenderAttribute attr = _attrList[i];
                if (OnAttributeRender(attr.name, attr.value, attr.key)) { 
                    // Update the list. This can be done in place 
                    _attrList[newAttrCount] = attr;
                    newAttrCount++; 
                }
            }
            // Update the count
            _attrCount = newAttrCount; 
        }
 
        public virtual void RenderBeginTag(string tagName) { 
            this.TagName = tagName;
            RenderBeginTag(_tagKey); 
        }

        public virtual void RenderBeginTag(HtmlTextWriterTag tagKey) {
 
            this.TagKey = tagKey;
            bool renderTag = true; 
 
            if (_isDescendant) {
                renderTag = OnTagRender(_tagName, _tagKey); 

                // Inherited renderers will be expecting to be able to filter any of the attributes at this point
                FilterAttributes();
 
                // write text before begin tag
                string textBeforeTag = RenderBeforeTag(); 
                if (textBeforeTag != null) { 
                    if (tabsPending) {
                        OutputTabs(); 
                    }
                    writer.Write(textBeforeTag);
                }
            } 

            // gather information about this tag. 
            TagInformation tagInfo = _tagNameLookupArray[_tagIndex]; 
            TagType tagType = tagInfo.tagType;
            bool renderEndTag = renderTag && (tagType != TagType.NonClosing); 
            string endTag = renderEndTag? tagInfo.closingTag : null;

            // write the begin tag
            if (renderTag) { 
                if (tabsPending) {
                    OutputTabs(); 
                } 
                writer.Write(TagLeftChar);
                writer.Write(_tagName); 

                string styleValue = null;

                for (int i = 0; i < _attrCount; i++) { 
                    RenderAttribute attr = _attrList[i];
                    if (attr.key == HtmlTextWriterAttribute.Style) { 
                        // append style attribute in with other styles 
                        styleValue = attr.value;
                    } 
                    else {
                        writer.Write(SpaceChar);
                        writer.Write(attr.name);
                        if (attr.value != null) { 
                            writer.Write(EqualsDoubleQuoteString);
 
                            string attrValue = attr.value; 
                            if (attr.isUrl) {
                                if (attr.key != HtmlTextWriterAttribute.Href || !attrValue.StartsWith("javascript:", StringComparison.Ordinal)) { 
                                    attrValue = EncodeUrl(attrValue);
                                }
                            }
                            if (attr.encode) { 
                                WriteHtmlAttributeEncode(attrValue);
                            } 
                            else { 
                                writer.Write(attrValue);
                            } 
                            writer.Write(DoubleQuoteChar);
                        }
                    }
                } 

 
                if (_styleCount > 0 || styleValue != null) { 
                    writer.Write(SpaceChar);
                    writer.Write("style"); 
                    writer.Write(EqualsDoubleQuoteString);

                    CssTextWriter.WriteAttributes(writer, _styleList, _styleCount);
                    if (styleValue != null) { 
                        writer.Write(styleValue);
                    } 
                    writer.Write(DoubleQuoteChar); 
                }
 
                if (tagType == TagType.NonClosing) {
                    writer.Write(SelfClosingTagEnd);
                }
                else { 
                    writer.Write(TagRightChar);
                } 
            } 

            string textBeforeContent = RenderBeforeContent(); 
            if (textBeforeContent != null) {
                if (tabsPending) {
                    OutputTabs();
                } 
                writer.Write(textBeforeContent);
            } 
 
            // write text before the content
            if (renderEndTag) { 

                if (tagType == TagType.Inline) {
                    _inlineCount += 1;
                } 
                else {
                    // writeline and indent before rendering content 
                    WriteLine(); 
                    Indent++;
                } 
                // Manually build end tags for unknown tag types.
                if (endTag == null) {
                    endTag = EndTagLeftChars + _tagName + TagRightChar.ToString(CultureInfo.InvariantCulture);
                } 
            }
 
            if (_isDescendant) { 
                // append text after the tag
                string textAfterTag = RenderAfterTag(); 
                if (textAfterTag != null) {
                    endTag = (endTag == null) ? textAfterTag : textAfterTag + endTag;
                }
 
                // build end content and push it on stack to write in RenderEndTag
                // prepend text after the content 
                string textAfterContent = RenderAfterContent(); 
                if (textAfterContent != null) {
                    endTag = (endTag == null) ? textAfterContent : textAfterContent + endTag; 
                }
            }

            // push end tag onto stack 
            PushEndTag(endTag);
 
            // flush attribute and style lists for next tag 
            _attrCount = 0;
            _styleCount = 0; 

        }

        public virtual void RenderEndTag() { 
            string endTag = PopEndTag();
 
            if (endTag != null) { 
                if (_tagNameLookupArray[_tagIndex].tagType == TagType.Inline) {
                    _inlineCount -= 1; 
                    // Never inject crlfs at end of inline tags.
                    //
                    Write(endTag);
                } 
                else {
                    // unindent if not an inline tag 
                    WriteLine(); 
                    this.Indent--;
                    Write(endTag); 
                }
            }
        }
 
        [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        protected virtual string RenderBeforeTag() { 
            return null; 
        }
 
        [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        protected virtual string RenderBeforeContent() {
            return null;
        } 

        [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] 
        protected virtual string RenderAfterContent() { 
            return null;
        } 

        [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        protected virtual string RenderAfterTag() {
            return null; 
        }
 
        public virtual void WriteAttribute(string name, string value) { 
            WriteAttribute(name, value, false /*encode*/);
        } 

        public virtual void WriteAttribute(string name, string value, bool fEncode) {
            writer.Write(SpaceChar);
            writer.Write(name); 
            if (value != null) {
                writer.Write(EqualsDoubleQuoteString); 
                if (fEncode) { 
                    WriteHtmlAttributeEncode(value);
                } 
                else {
                    writer.Write(value);
                }
                writer.Write(DoubleQuoteChar); 
            }
        } 
 
        public virtual void WriteBeginTag(string tagName) {
            if (tabsPending) { 
                OutputTabs();
            }
            writer.Write(TagLeftChar);
            writer.Write(tagName); 
        }
 
        public virtual void WriteBreak() { 
            // Space between br and / is for improved html compatibility.  See XHTML 1.0 specification, section C.2.
            Write("
"); } // DevDiv 33149: A backward compat. switch for Everett rendering internal void WriteObsoleteBreak() { Write("
"); } public virtual void WriteFullBeginTag(string tagName) { if (tabsPending) { OutputTabs(); } writer.Write(TagLeftChar); writer.Write(tagName); writer.Write(TagRightChar); } public virtual void WriteEndTag(string tagName) { if (tabsPending) { OutputTabs(); } writer.Write(TagLeftChar); writer.Write(SlashChar); writer.Write(tagName); writer.Write(TagRightChar); } public virtual void WriteStyleAttribute(string name, string value) { WriteStyleAttribute(name, value, false /*encode*/); } public virtual void WriteStyleAttribute(string name, string value, bool fEncode) { writer.Write(name); writer.Write(StyleEqualsChar); if (fEncode) { WriteHtmlAttributeEncode(value); } else { writer.Write(value); } writer.Write(SemicolonChar); } internal void WriteUTF8ResourceString(IntPtr pv, int offset, int size, bool fAsciiOnly) { // If we have an http writer, we can use the faster code path. Otherwise, // get a String out of the resource and write it. if (_httpWriter != null) { if (tabsPending) { OutputTabs(); } _httpWriter.WriteUTF8ResourceString(pv, offset, size, fAsciiOnly); } else { Write(StringResourceManager.ResourceToString(pv, offset, size)); } } public virtual void WriteEncodedUrl(String url) { int i = url.IndexOf('?'); if (i != -1) { WriteUrlEncodedString(url.Substring(0, i), false); Write(url.Substring(i)); } else { WriteUrlEncodedString(url, false); } } public virtual void WriteEncodedUrlParameter(String urlText) { WriteUrlEncodedString(urlText, true); } public virtual void WriteEncodedText(String text) { if (text == null) { throw new ArgumentNullException("text"); } const char NBSP = '\u00A0'; // When inner text is retrieved for a text control,   is // decoded to 0x00A0 (code point for nbsp in Unicode). // HtmlEncode doesn't encode 0x00A0 to  , we need to do it // manually here. int length = text.Length; int pos = 0; while (pos < length) { int nbsp = text.IndexOf(NBSP, pos); if (nbsp < 0) { HttpUtility.HtmlEncode(pos == 0 ? text : text.Substring(pos, length - pos), this); pos = length; } else { if (nbsp > pos) { HttpUtility.HtmlEncode(text.Substring(pos, nbsp - pos), this); } Write(" "); pos = nbsp + 1; } } } protected void WriteUrlEncodedString(String text, bool argument) { int length = text.Length; for (int i = 0; i < length; i++) { char ch = text[i]; if (HttpEncoderUtility.IsUrlSafeChar(ch)) { Write(ch); } else if ( !argument && (ch == '/' || ch == ':' || ch == '#' || ch == ',' ) ) { Write(ch); } else if (ch == ' ' && argument) { Write('+'); } // for chars that their code number is less than 128 and have // not been handled above else if ((ch & 0xff80) == 0) { Write('%'); Write(HttpEncoderUtility.IntToHex((ch >> 4) & 0xf)); Write(HttpEncoderUtility.IntToHex((ch) & 0xf)); } else { // VSWhidbey 448625: For DBCS characters, use UTF8 encoding // which can be handled by IIS5 and above. Write(HttpUtility.UrlEncodeNonAscii(Char.ToString(ch), Encoding.UTF8)); } } } internal void WriteHtmlAttributeEncode(string s) { HttpUtility.HtmlAttributeEncode(s, _httpWriter ?? writer); } internal class Layout { private bool _wrap; private HorizontalAlign _align; /* public Layout(Layout currentLayout) { Align = currentLayout.Align; Wrap = currentLayout.Wrap; } */ public Layout(HorizontalAlign alignment, bool wrapping) { Align = alignment; Wrap = wrapping; } public bool Wrap { get { return _wrap; } set { _wrap = value; } } public HorizontalAlign Align { get { return _align; } set { _align = value; } } /* public bool Compare(Layout layout) { return Wrap == layout.Wrap && Align == layout.Align; } public void MergeWith(Layout layout) { if (Align == HorizontalAlign.NotSet) { Align = layout.Align; } if (Wrap) { Wrap = layout.Wrap; } } */ } private struct TagStackEntry { public HtmlTextWriterTag tagKey; public string endTagText; } private struct RenderAttribute { public string name; public string value; public HtmlTextWriterAttribute key; public bool encode; public bool isUrl; } private struct AttributeInformation { public string name; public bool isUrl; public bool encode; public AttributeInformation(string name, bool encode, bool isUrl) { this.name = name; this.encode = encode; this.isUrl = isUrl; } } private enum TagType { Inline, NonClosing, Other, } private struct TagInformation { public string name; public TagType tagType; public string closingTag; public TagInformation(string name, TagType tagType, string closingTag) { this.name = name; this.tagType = tagType; this.closingTag = closingTag; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- // HtmlTextWriter.cs // namespace System.Web.UI { using System; using System.Collections; using System.Collections.Specialized; using System.IO; using System.Text; using System.Globalization; using System.Security.Permissions; using System.Web.UI.WebControls; using System.Web.Util; public class HtmlTextWriter : TextWriter { private Layout _currentLayout = new Layout(HorizontalAlign.NotSet, true /* wrap */); private Layout _currentWrittenLayout = null; internal virtual bool RenderDivAroundHiddenInputs { get { return true; } } public virtual void EnterStyle(Style style, HtmlTextWriterTag tag) { if (!style.IsEmpty || tag != HtmlTextWriterTag.Span) { style.AddAttributesToRender(this); RenderBeginTag(tag); } } public virtual void ExitStyle(System.Web.UI.WebControls.Style style, HtmlTextWriterTag tag) { // Review: This requires that the style doesn't change between beginstyle/endstyle. if (!style.IsEmpty || tag != HtmlTextWriterTag.Span) { RenderEndTag(); } } internal virtual void OpenDiv() { OpenDiv(_currentLayout, (_currentLayout != null) && (_currentLayout.Align != HorizontalAlign.NotSet), (_currentLayout != null) && !_currentLayout.Wrap); } private void OpenDiv(Layout layout, bool writeHorizontalAlign, bool writeWrapping) { WriteBeginTag("div"); if (writeHorizontalAlign) { String alignment; switch (layout.Align) { case HorizontalAlign.Right: alignment = "text-align:right"; break; case HorizontalAlign.Center: alignment = "text-align:center"; break; default: alignment = "text-align:left"; break; } WriteAttribute("style", alignment); } if (writeWrapping) { WriteAttribute("mode", layout.Wrap == true ? "wrap" : "nowrap"); } Write('>'); _currentWrittenLayout = layout; } public virtual bool IsValidFormAttribute(String attribute) { return true; } private TextWriter writer; private int indentLevel; private bool tabsPending; private string tabString; public const char TagLeftChar = '<'; public const char TagRightChar = '>'; public const string SelfClosingChars = " /"; public const string SelfClosingTagEnd = " />"; public const string EndTagLeftChars = "= 0, "Bogus Indent... probably caused by mismatched Indent++ and Indent--"); if (value < 0) { value = 0; } indentLevel = value; } } //Gets or sets the TextWriter to use. public TextWriter InnerWriter { get { return writer; } set { writer = value; _httpWriter = value as HttpWriter; } } /* // */ public virtual void BeginRender() { } //Closes the document being written to. public override void Close() { writer.Close(); } public virtual void EndRender() { } public virtual void EnterStyle(System.Web.UI.WebControls.Style style) { EnterStyle(style, HtmlTextWriterTag.Span); } public virtual void ExitStyle(System.Web.UI.WebControls.Style style) { ExitStyle(style, HtmlTextWriterTag.Span); } public override void Flush() { writer.Flush(); } protected virtual void OutputTabs() { if (tabsPending) { for (int i=0; i < indentLevel; i++) { writer.Write(tabString); } tabsPending = false; } } //Writes a string to the text stream. [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] public override void Write(string s) { if (tabsPending) { OutputTabs(); } writer.Write(s); } //Writes the text representation of a Boolean value to the text stream. public override void Write(bool value) { if (tabsPending) { OutputTabs(); } writer.Write(value); } //Writes a character to the text stream. [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] public override void Write(char value) { if (tabsPending) { OutputTabs(); } writer.Write(value); } // Writes a character array to the text stream. public override void Write(char[] buffer) { if (tabsPending) { OutputTabs(); } writer.Write(buffer); } // Writes a subarray of characters to the text stream. public override void Write(char[] buffer, int index, int count) { if (tabsPending) { OutputTabs(); } writer.Write(buffer, index, count); } // Writes the text representation of a Double to the text stream. public override void Write(double value) { if (tabsPending) { OutputTabs(); } writer.Write(value); } // Writes the text representation of a Single to the text stream. public override void Write(float value) { if (tabsPending) { OutputTabs(); } writer.Write(value); } // Writes the text representation of an integer to the text stream. public override void Write(int value) { if (tabsPending) { OutputTabs(); } writer.Write(value); } // Writes the text representation of an 8-byte integer to the text stream. public override void Write(long value) { if (tabsPending) { OutputTabs(); } writer.Write(value); } // Writes the text representation of an object to the text stream. public override void Write(object value) { if (tabsPending) { OutputTabs(); } writer.Write(value); } // Writes out a formatted string, using the same semantics as specified. public override void Write(string format, object arg0) { if (tabsPending) { OutputTabs(); } writer.Write(format, arg0); } // Writes out a formatted string, using the same semantics as specified. public override void Write(string format, object arg0, object arg1) { if (tabsPending) { OutputTabs(); } writer.Write(format, arg0, arg1); } // Writes out a formatted string, using the same semantics as specified. public override void Write(string format, params object[] arg) { if (tabsPending) { OutputTabs(); } writer.Write(format, arg); } // Writes the specified string to a line without tabs. public void WriteLineNoTabs(string s) { writer.WriteLine(s); tabsPending = true; } // Writes the specified string followed by a line terminator to the text stream. public override void WriteLine(string s) { if (tabsPending) { OutputTabs(); } writer.WriteLine(s); tabsPending = true; } // Writes a line terminator. public override void WriteLine() { writer.WriteLine(); tabsPending = true; } // Writes the text representation of a Boolean followed by a line terminator to the text stream. public override void WriteLine(bool value) { if (tabsPending) { OutputTabs(); } writer.WriteLine(value); tabsPending = true; } public override void WriteLine(char value) { if (tabsPending) { OutputTabs(); } writer.WriteLine(value); tabsPending = true; } public override void WriteLine(char[] buffer) { if (tabsPending) { OutputTabs(); } writer.WriteLine(buffer); tabsPending = true; } public override void WriteLine(char[] buffer, int index, int count) { if (tabsPending) { OutputTabs(); } writer.WriteLine(buffer, index, count); tabsPending = true; } public override void WriteLine(double value) { if (tabsPending) { OutputTabs(); } writer.WriteLine(value); tabsPending = true; } public override void WriteLine(float value) { if (tabsPending) { OutputTabs(); } writer.WriteLine(value); tabsPending = true; } public override void WriteLine(int value) { if (tabsPending) { OutputTabs(); } writer.WriteLine(value); tabsPending = true; } public override void WriteLine(long value) { if (tabsPending) { OutputTabs(); } writer.WriteLine(value); tabsPending = true; } public override void WriteLine(object value) { if (tabsPending) { OutputTabs(); } writer.WriteLine(value); tabsPending = true; } public override void WriteLine(string format, object arg0) { if (tabsPending) { OutputTabs(); } writer.WriteLine(format, arg0); tabsPending = true; } public override void WriteLine(string format, object arg0, object arg1) { if (tabsPending) { OutputTabs(); } writer.WriteLine(format, arg0, arg1); tabsPending = true; } public override void WriteLine(string format, params object[] arg) { if (tabsPending) { OutputTabs(); } writer.WriteLine(format, arg); tabsPending = true; } [CLSCompliant(false)] public override void WriteLine(UInt32 value) { if (tabsPending) { OutputTabs(); } writer.WriteLine(value); tabsPending = true; } protected static void RegisterTag(string name, HtmlTextWriterTag key) { RegisterTag(name, key, TagType.Other); } private static void RegisterTag(string name, HtmlTextWriterTag key, TagType type) { string nameLCase = name.ToLower(CultureInfo.InvariantCulture); _tagKeyLookupTable.Add(nameLCase, key); // Pre-resolve the end tag string endTag = null; if (type != TagType.NonClosing && key != HtmlTextWriterTag.Unknown) { endTag = EndTagLeftChars + nameLCase + TagRightChar.ToString(CultureInfo.InvariantCulture); } if ((int)key < _tagNameLookupArray.Length) { _tagNameLookupArray[(int)key] = new TagInformation(name, type, endTag); } } protected static void RegisterAttribute(string name, HtmlTextWriterAttribute key) { RegisterAttribute(name, key, false); } private static void RegisterAttribute(string name, HtmlTextWriterAttribute key, bool encode) { RegisterAttribute(name, key, encode, false); } private static void RegisterAttribute(string name, HtmlTextWriterAttribute key, bool encode, bool isUrl) { string nameLCase = name.ToLower(CultureInfo.InvariantCulture); _attrKeyLookupTable.Add(nameLCase, key); if ((int)key < _attrNameLookupArray.Length) { _attrNameLookupArray[(int)key] = new AttributeInformation(name, encode, isUrl); } } protected static void RegisterStyle(string name, HtmlTextWriterStyle key) { CssTextWriter.RegisterAttribute(name, key); } public HtmlTextWriter(TextWriter writer) : this(writer, DefaultTabString) { } public HtmlTextWriter(TextWriter writer, string tabString) : base(CultureInfo.InvariantCulture) { this.writer = writer; this.tabString = tabString; indentLevel = 0; tabsPending = false; // If it's an http writer, save it _httpWriter = writer as HttpWriter; _isDescendant = (GetType() != typeof(HtmlTextWriter)); _attrCount = 0; _styleCount = 0; _endTagCount = 0; _inlineCount = 0; } protected HtmlTextWriterTag TagKey { get { return _tagKey; } set { _tagIndex = (int) value; if (_tagIndex < 0 || _tagIndex >= _tagNameLookupArray.Length) { throw new ArgumentOutOfRangeException("value"); } _tagKey = value; // If explicitly setting to uknown, keep the old tag name. This allows a string tag // to be set without clobbering it if setting TagKey to itself. if (value != HtmlTextWriterTag.Unknown) { _tagName = _tagNameLookupArray[_tagIndex].name; } } } protected string TagName { get { return _tagName; } set { _tagName = value; _tagKey = GetTagKey(_tagName); _tagIndex = (int) _tagKey; Debug.Assert(_tagIndex >= 0 && _tagIndex < _tagNameLookupArray.Length); } } public virtual void AddAttribute(string name,string value) { HtmlTextWriterAttribute attributeKey = GetAttributeKey(name); value = EncodeAttributeValue(attributeKey, value); AddAttribute(name, value, attributeKey); } //do not fix this spelling error //believe it or not, it is a backwards breaking change for languages that //support late binding with named parameters VB.Net public virtual void AddAttribute(string name,string value, bool fEndode) { value = EncodeAttributeValue(value, fEndode); AddAttribute(name, value, GetAttributeKey(name)); } public virtual void AddAttribute(HtmlTextWriterAttribute key,string value) { int attributeIndex = (int) key; if (attributeIndex >= 0 && attributeIndex < _attrNameLookupArray.Length) { AttributeInformation info = _attrNameLookupArray[attributeIndex]; AddAttribute(info.name,value,key, info.encode, info.isUrl); } } public virtual void AddAttribute(HtmlTextWriterAttribute key,string value, bool fEncode) { int attributeIndex = (int) key; if (attributeIndex >= 0 && attributeIndex < _attrNameLookupArray.Length) { AttributeInformation info = _attrNameLookupArray[attributeIndex]; AddAttribute(info.name,value,key, fEncode, info.isUrl); } } protected virtual void AddAttribute(string name, string value, HtmlTextWriterAttribute key) { AddAttribute(name, value, key, false, false); } private void AddAttribute(string name, string value, HtmlTextWriterAttribute key, bool encode, bool isUrl) { if(_attrList == null) { _attrList = new RenderAttribute[20]; } else if (_attrCount >= _attrList.Length) { RenderAttribute[] newArray = new RenderAttribute[_attrList.Length * 2]; Array.Copy(_attrList, newArray, _attrList.Length); _attrList = newArray; } RenderAttribute attr; attr.name = name; attr.value = value; attr.key = key; attr.encode = encode; attr.isUrl = isUrl; _attrList[_attrCount] = attr; _attrCount++; } public virtual void AddStyleAttribute(string name, string value) { AddStyleAttribute(name, value, CssTextWriter.GetStyleKey(name)); } public virtual void AddStyleAttribute(HtmlTextWriterStyle key, string value) { AddStyleAttribute(CssTextWriter.GetStyleName(key), value, key); } protected virtual void AddStyleAttribute(string name, string value, HtmlTextWriterStyle key) { if(_styleList == null) { _styleList = new RenderStyle[20]; } else if (_styleCount > _styleList.Length) { RenderStyle[] newArray = new RenderStyle[_styleList.Length * 2]; Array.Copy(_styleList, newArray, _styleList.Length); _styleList = newArray; } RenderStyle style; style.name = name; style.key = key; string attributeValue = value; if (CssTextWriter.IsStyleEncoded(key)) { // note that only css attributes in an inline style value need to be attribute encoded // since CssTextWriter is used to render both embedded stylesheets and style attributes // the attribute encoding is done here. attributeValue = HttpUtility.HtmlAttributeEncode(value); } style.value = attributeValue; _styleList[_styleCount] = style; _styleCount++; } protected string EncodeAttributeValue(string value, bool fEncode) { if (value == null) { return null; } if (!fEncode) return value; return HttpUtility.HtmlAttributeEncode(value); } protected virtual string EncodeAttributeValue(HtmlTextWriterAttribute attrKey, string value) { bool encode = true; if (0 <= (int)attrKey && (int)attrKey < _attrNameLookupArray.Length) { encode = _attrNameLookupArray[(int)attrKey].encode; } return EncodeAttributeValue(value, encode); } // This does minimal URL encoding by converting spaces in the url to "%20". protected string EncodeUrl(string url) { // VSWhidbey 454348: escaped spaces in UNC share paths don't work in IE, so // we're not going to encode if it's a share. if (!UrlPath.IsUncSharePath(url)) { return HttpUtility.UrlPathEncode(url); } return url; } protected HtmlTextWriterAttribute GetAttributeKey(string attrName) { if (!String.IsNullOrEmpty(attrName)) { object key = _attrKeyLookupTable[attrName.ToLower(CultureInfo.InvariantCulture)]; if (key != null) return(HtmlTextWriterAttribute)key; } return(HtmlTextWriterAttribute)(-1); } protected string GetAttributeName(HtmlTextWriterAttribute attrKey) { if ((int)attrKey >= 0 && (int)attrKey < _attrNameLookupArray.Length) return _attrNameLookupArray[(int)attrKey].name; return string.Empty; } protected HtmlTextWriterStyle GetStyleKey(string styleName) { return CssTextWriter.GetStyleKey(styleName); } protected string GetStyleName(HtmlTextWriterStyle styleKey) { return CssTextWriter.GetStyleName(styleKey); } protected virtual HtmlTextWriterTag GetTagKey(string tagName) { if (!String.IsNullOrEmpty(tagName)) { object key = _tagKeyLookupTable[tagName.ToLower(CultureInfo.InvariantCulture)]; if (key != null) return(HtmlTextWriterTag)key; } return HtmlTextWriterTag.Unknown; } protected virtual string GetTagName(HtmlTextWriterTag tagKey) { int tagIndex = (int) tagKey; if (tagIndex >= 0 && tagIndex < _tagNameLookupArray.Length) return _tagNameLookupArray[tagIndex].name; return string.Empty; } protected bool IsAttributeDefined(HtmlTextWriterAttribute key) { for (int i = 0; i < _attrCount; i++) { if (_attrList[i].key == key) { return true; } } return false; } protected bool IsAttributeDefined(HtmlTextWriterAttribute key, out string value) { value = null; for (int i = 0; i < _attrCount; i++) { if (_attrList[i].key == key) { value = _attrList[i].value; return true; } } return false; } protected bool IsStyleAttributeDefined(HtmlTextWriterStyle key) { for (int i = 0; i < _styleCount; i++) { if (_styleList[i].key == key) { return true; } } return false; } protected bool IsStyleAttributeDefined(HtmlTextWriterStyle key, out string value) { value = null; for (int i = 0; i < _styleCount; i++) { if (_styleList[i].key == key) { value = _styleList[i].value; return true; } } return false; } protected virtual bool OnAttributeRender(string name, string value, HtmlTextWriterAttribute key) { return true; } protected virtual bool OnStyleAttributeRender(string name, string value, HtmlTextWriterStyle key) { return true; } protected virtual bool OnTagRender(string name, HtmlTextWriterTag key) { return true; } protected string PopEndTag() { if (_endTagCount <= 0) { throw new InvalidOperationException(SR.GetString(SR.HTMLTextWriterUnbalancedPop)); } _endTagCount--; TagKey = _endTags[_endTagCount].tagKey; return _endTags[_endTagCount].endTagText; } protected void PushEndTag(string endTag) { if(_endTags == null) { _endTags = new TagStackEntry[16]; } else if (_endTagCount >= _endTags.Length) { TagStackEntry[] newArray = new TagStackEntry[_endTags.Length * 2]; Array.Copy(_endTags, newArray, _endTags.Length); _endTags = newArray; } _endTags[_endTagCount].tagKey = _tagKey; _endTags[_endTagCount].endTagText= endTag; _endTagCount++; } // This calls filers out all attributes and style attributes by calling OnAttributeRender // and OnStyleAttributeRender on all properites and updates the lists protected virtual void FilterAttributes() { // Create the filtered list of styles int newStyleCount = 0; for (int i = 0; i < _styleCount; i++) { RenderStyle style = _styleList[i]; if (OnStyleAttributeRender(style.name, style.value, style.key)) { // Update the list. This can be done in place _styleList[newStyleCount] = style; newStyleCount++; } } // Update the count _styleCount = newStyleCount; // Create the filtered list of attributes int newAttrCount = 0; for (int i = 0; i < _attrCount; i++) { RenderAttribute attr = _attrList[i]; if (OnAttributeRender(attr.name, attr.value, attr.key)) { // Update the list. This can be done in place _attrList[newAttrCount] = attr; newAttrCount++; } } // Update the count _attrCount = newAttrCount; } public virtual void RenderBeginTag(string tagName) { this.TagName = tagName; RenderBeginTag(_tagKey); } public virtual void RenderBeginTag(HtmlTextWriterTag tagKey) { this.TagKey = tagKey; bool renderTag = true; if (_isDescendant) { renderTag = OnTagRender(_tagName, _tagKey); // Inherited renderers will be expecting to be able to filter any of the attributes at this point FilterAttributes(); // write text before begin tag string textBeforeTag = RenderBeforeTag(); if (textBeforeTag != null) { if (tabsPending) { OutputTabs(); } writer.Write(textBeforeTag); } } // gather information about this tag. TagInformation tagInfo = _tagNameLookupArray[_tagIndex]; TagType tagType = tagInfo.tagType; bool renderEndTag = renderTag && (tagType != TagType.NonClosing); string endTag = renderEndTag? tagInfo.closingTag : null; // write the begin tag if (renderTag) { if (tabsPending) { OutputTabs(); } writer.Write(TagLeftChar); writer.Write(_tagName); string styleValue = null; for (int i = 0; i < _attrCount; i++) { RenderAttribute attr = _attrList[i]; if (attr.key == HtmlTextWriterAttribute.Style) { // append style attribute in with other styles styleValue = attr.value; } else { writer.Write(SpaceChar); writer.Write(attr.name); if (attr.value != null) { writer.Write(EqualsDoubleQuoteString); string attrValue = attr.value; if (attr.isUrl) { if (attr.key != HtmlTextWriterAttribute.Href || !attrValue.StartsWith("javascript:", StringComparison.Ordinal)) { attrValue = EncodeUrl(attrValue); } } if (attr.encode) { WriteHtmlAttributeEncode(attrValue); } else { writer.Write(attrValue); } writer.Write(DoubleQuoteChar); } } } if (_styleCount > 0 || styleValue != null) { writer.Write(SpaceChar); writer.Write("style"); writer.Write(EqualsDoubleQuoteString); CssTextWriter.WriteAttributes(writer, _styleList, _styleCount); if (styleValue != null) { writer.Write(styleValue); } writer.Write(DoubleQuoteChar); } if (tagType == TagType.NonClosing) { writer.Write(SelfClosingTagEnd); } else { writer.Write(TagRightChar); } } string textBeforeContent = RenderBeforeContent(); if (textBeforeContent != null) { if (tabsPending) { OutputTabs(); } writer.Write(textBeforeContent); } // write text before the content if (renderEndTag) { if (tagType == TagType.Inline) { _inlineCount += 1; } else { // writeline and indent before rendering content WriteLine(); Indent++; } // Manually build end tags for unknown tag types. if (endTag == null) { endTag = EndTagLeftChars + _tagName + TagRightChar.ToString(CultureInfo.InvariantCulture); } } if (_isDescendant) { // append text after the tag string textAfterTag = RenderAfterTag(); if (textAfterTag != null) { endTag = (endTag == null) ? textAfterTag : textAfterTag + endTag; } // build end content and push it on stack to write in RenderEndTag // prepend text after the content string textAfterContent = RenderAfterContent(); if (textAfterContent != null) { endTag = (endTag == null) ? textAfterContent : textAfterContent + endTag; } } // push end tag onto stack PushEndTag(endTag); // flush attribute and style lists for next tag _attrCount = 0; _styleCount = 0; } public virtual void RenderEndTag() { string endTag = PopEndTag(); if (endTag != null) { if (_tagNameLookupArray[_tagIndex].tagType == TagType.Inline) { _inlineCount -= 1; // Never inject crlfs at end of inline tags. // Write(endTag); } else { // unindent if not an inline tag WriteLine(); this.Indent--; Write(endTag); } } } [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] protected virtual string RenderBeforeTag() { return null; } [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] protected virtual string RenderBeforeContent() { return null; } [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] protected virtual string RenderAfterContent() { return null; } [System.Runtime.TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] protected virtual string RenderAfterTag() { return null; } public virtual void WriteAttribute(string name, string value) { WriteAttribute(name, value, false /*encode*/); } public virtual void WriteAttribute(string name, string value, bool fEncode) { writer.Write(SpaceChar); writer.Write(name); if (value != null) { writer.Write(EqualsDoubleQuoteString); if (fEncode) { WriteHtmlAttributeEncode(value); } else { writer.Write(value); } writer.Write(DoubleQuoteChar); } } public virtual void WriteBeginTag(string tagName) { if (tabsPending) { OutputTabs(); } writer.Write(TagLeftChar); writer.Write(tagName); } public virtual void WriteBreak() { // Space between br and / is for improved html compatibility. See XHTML 1.0 specification, section C.2. Write("
"); } // DevDiv 33149: A backward compat. switch for Everett rendering internal void WriteObsoleteBreak() { Write("
"); } public virtual void WriteFullBeginTag(string tagName) { if (tabsPending) { OutputTabs(); } writer.Write(TagLeftChar); writer.Write(tagName); writer.Write(TagRightChar); } public virtual void WriteEndTag(string tagName) { if (tabsPending) { OutputTabs(); } writer.Write(TagLeftChar); writer.Write(SlashChar); writer.Write(tagName); writer.Write(TagRightChar); } public virtual void WriteStyleAttribute(string name, string value) { WriteStyleAttribute(name, value, false /*encode*/); } public virtual void WriteStyleAttribute(string name, string value, bool fEncode) { writer.Write(name); writer.Write(StyleEqualsChar); if (fEncode) { WriteHtmlAttributeEncode(value); } else { writer.Write(value); } writer.Write(SemicolonChar); } internal void WriteUTF8ResourceString(IntPtr pv, int offset, int size, bool fAsciiOnly) { // If we have an http writer, we can use the faster code path. Otherwise, // get a String out of the resource and write it. if (_httpWriter != null) { if (tabsPending) { OutputTabs(); } _httpWriter.WriteUTF8ResourceString(pv, offset, size, fAsciiOnly); } else { Write(StringResourceManager.ResourceToString(pv, offset, size)); } } public virtual void WriteEncodedUrl(String url) { int i = url.IndexOf('?'); if (i != -1) { WriteUrlEncodedString(url.Substring(0, i), false); Write(url.Substring(i)); } else { WriteUrlEncodedString(url, false); } } public virtual void WriteEncodedUrlParameter(String urlText) { WriteUrlEncodedString(urlText, true); } public virtual void WriteEncodedText(String text) { if (text == null) { throw new ArgumentNullException("text"); } const char NBSP = '\u00A0'; // When inner text is retrieved for a text control,   is // decoded to 0x00A0 (code point for nbsp in Unicode). // HtmlEncode doesn't encode 0x00A0 to  , we need to do it // manually here. int length = text.Length; int pos = 0; while (pos < length) { int nbsp = text.IndexOf(NBSP, pos); if (nbsp < 0) { HttpUtility.HtmlEncode(pos == 0 ? text : text.Substring(pos, length - pos), this); pos = length; } else { if (nbsp > pos) { HttpUtility.HtmlEncode(text.Substring(pos, nbsp - pos), this); } Write(" "); pos = nbsp + 1; } } } protected void WriteUrlEncodedString(String text, bool argument) { int length = text.Length; for (int i = 0; i < length; i++) { char ch = text[i]; if (HttpEncoderUtility.IsUrlSafeChar(ch)) { Write(ch); } else if ( !argument && (ch == '/' || ch == ':' || ch == '#' || ch == ',' ) ) { Write(ch); } else if (ch == ' ' && argument) { Write('+'); } // for chars that their code number is less than 128 and have // not been handled above else if ((ch & 0xff80) == 0) { Write('%'); Write(HttpEncoderUtility.IntToHex((ch >> 4) & 0xf)); Write(HttpEncoderUtility.IntToHex((ch) & 0xf)); } else { // VSWhidbey 448625: For DBCS characters, use UTF8 encoding // which can be handled by IIS5 and above. Write(HttpUtility.UrlEncodeNonAscii(Char.ToString(ch), Encoding.UTF8)); } } } internal void WriteHtmlAttributeEncode(string s) { HttpUtility.HtmlAttributeEncode(s, _httpWriter ?? writer); } internal class Layout { private bool _wrap; private HorizontalAlign _align; /* public Layout(Layout currentLayout) { Align = currentLayout.Align; Wrap = currentLayout.Wrap; } */ public Layout(HorizontalAlign alignment, bool wrapping) { Align = alignment; Wrap = wrapping; } public bool Wrap { get { return _wrap; } set { _wrap = value; } } public HorizontalAlign Align { get { return _align; } set { _align = value; } } /* public bool Compare(Layout layout) { return Wrap == layout.Wrap && Align == layout.Align; } public void MergeWith(Layout layout) { if (Align == HorizontalAlign.NotSet) { Align = layout.Align; } if (Wrap) { Wrap = layout.Wrap; } } */ } private struct TagStackEntry { public HtmlTextWriterTag tagKey; public string endTagText; } private struct RenderAttribute { public string name; public string value; public HtmlTextWriterAttribute key; public bool encode; public bool isUrl; } private struct AttributeInformation { public string name; public bool isUrl; public bool encode; public AttributeInformation(string name, bool encode, bool isUrl) { this.name = name; this.encode = encode; this.isUrl = isUrl; } } private enum TagType { Inline, NonClosing, Other, } private struct TagInformation { public string name; public TagType tagType; public string closingTag; public TagInformation(string name, TagType tagType, string closingTag) { this.name = name; this.tagType = tagType; this.closingTag = closingTag; } } } } // 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