2004-06-03 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI / HtmlTextWriter.cs
1 /*      System.Web.UI\r
2 *       Authors\r
3 *               Leen Toelen (toelen@hotmail.com)\r
4 */\r
5 \r
6 using System;\r
7 using System.IO;\r
8 using System.Collections;\r
9 using System.Web;\r
10 using System.Web.UI;\r
11 \r
12 namespace System.Web.UI{\r
13 \r
14 public class HtmlTextWriter : System.IO.TextWriter {\r
15 \r
16 static HtmlTextWriter(){\r
17         HtmlTextWriter._tagKeyLookupTable = new Hashtable(97);\r
18         HtmlTextWriter._tagNameLookupArray = new TagInformation[97];\r
19         HtmlTextWriter.RegisterTag("", HtmlTextWriterTag.Unknown, TagType.Other);\r
20         HtmlTextWriter.RegisterTag("a", HtmlTextWriterTag.A, TagType.Inline);\r
21         HtmlTextWriter.RegisterTag("acronym", HtmlTextWriterTag.Acronym, TagType.Inline);\r
22         HtmlTextWriter.RegisterTag("address", HtmlTextWriterTag.Address, TagType.Other);\r
23         HtmlTextWriter.RegisterTag("area", HtmlTextWriterTag.Area, TagType.Other);\r
24         HtmlTextWriter.RegisterTag("b", HtmlTextWriterTag.B, TagType.Inline);\r
25         HtmlTextWriter.RegisterTag("base", HtmlTextWriterTag.Base, TagType.NonClosing);\r
26         HtmlTextWriter.RegisterTag("basefont", HtmlTextWriterTag.Basefont, TagType.NonClosing);\r
27         HtmlTextWriter.RegisterTag("bdo", HtmlTextWriterTag.Bdo, TagType.Inline);\r
28         HtmlTextWriter.RegisterTag("bgsound", HtmlTextWriterTag.Bgsound, TagType.NonClosing);\r
29         HtmlTextWriter.RegisterTag("big", HtmlTextWriterTag.Big, TagType.Inline);\r
30         HtmlTextWriter.RegisterTag("blockquote", HtmlTextWriterTag.Blockquote, TagType.Other);\r
31         HtmlTextWriter.RegisterTag("body", HtmlTextWriterTag.Body, TagType.Other);\r
32         HtmlTextWriter.RegisterTag("br", HtmlTextWriterTag.Br, TagType.Other);\r
33         HtmlTextWriter.RegisterTag("button", HtmlTextWriterTag.Button, TagType.Inline);\r
34         HtmlTextWriter.RegisterTag("caption", HtmlTextWriterTag.Caption, TagType.Other);\r
35         HtmlTextWriter.RegisterTag("center", HtmlTextWriterTag.Center, TagType.Other);\r
36         HtmlTextWriter.RegisterTag("cite", HtmlTextWriterTag.Cite, TagType.Inline);\r
37         HtmlTextWriter.RegisterTag("code", HtmlTextWriterTag.Code, TagType.Inline);\r
38         HtmlTextWriter.RegisterTag("col", HtmlTextWriterTag.Col, TagType.NonClosing);\r
39         HtmlTextWriter.RegisterTag("colgroup", HtmlTextWriterTag.Colgroup, TagType.Other);\r
40         HtmlTextWriter.RegisterTag("del", HtmlTextWriterTag.Del, TagType.Inline);\r
41         HtmlTextWriter.RegisterTag("dd", HtmlTextWriterTag.Dd, TagType.Inline);\r
42         HtmlTextWriter.RegisterTag("dfn", HtmlTextWriterTag.Dfn, TagType.Inline);\r
43         HtmlTextWriter.RegisterTag("dir", HtmlTextWriterTag.Dir, TagType.Other);\r
44         HtmlTextWriter.RegisterTag("div", HtmlTextWriterTag.Div, TagType.Other);\r
45         HtmlTextWriter.RegisterTag("dl", HtmlTextWriterTag.Dl, TagType.Other);\r
46         HtmlTextWriter.RegisterTag("dt", HtmlTextWriterTag.Dt, TagType.Inline);\r
47         HtmlTextWriter.RegisterTag("em", HtmlTextWriterTag.Em, TagType.Inline);\r
48         HtmlTextWriter.RegisterTag("embed", HtmlTextWriterTag.Embed, TagType.NonClosing);\r
49         HtmlTextWriter.RegisterTag("fieldset", HtmlTextWriterTag.Fieldset, TagType.Other);\r
50         HtmlTextWriter.RegisterTag("font", HtmlTextWriterTag.Font, TagType.Inline);\r
51         HtmlTextWriter.RegisterTag("form", HtmlTextWriterTag.Form, TagType.Other);\r
52         HtmlTextWriter.RegisterTag("frame", HtmlTextWriterTag.Frame, TagType.NonClosing);\r
53         HtmlTextWriter.RegisterTag("frameset", HtmlTextWriterTag.Frameset, TagType.Other);\r
54         HtmlTextWriter.RegisterTag("h1", HtmlTextWriterTag.H1, TagType.Other);\r
55         HtmlTextWriter.RegisterTag("h2", HtmlTextWriterTag.H2, TagType.Other);\r
56         HtmlTextWriter.RegisterTag("h3", HtmlTextWriterTag.H3, TagType.Other);\r
57         HtmlTextWriter.RegisterTag("h4", HtmlTextWriterTag.H4, TagType.Other);\r
58         HtmlTextWriter.RegisterTag("h5", HtmlTextWriterTag.H5, TagType.Other);\r
59         HtmlTextWriter.RegisterTag("h6", HtmlTextWriterTag.H6, TagType.Other);\r
60         HtmlTextWriter.RegisterTag("head", HtmlTextWriterTag.Head, TagType.Other);\r
61         HtmlTextWriter.RegisterTag("hr", HtmlTextWriterTag.Hr, TagType.NonClosing);\r
62         HtmlTextWriter.RegisterTag("html", HtmlTextWriterTag.Html, TagType.Other);\r
63         HtmlTextWriter.RegisterTag("i", HtmlTextWriterTag.I, TagType.Inline);\r
64         HtmlTextWriter.RegisterTag("iframe", HtmlTextWriterTag.Iframe, TagType.Other);\r
65         HtmlTextWriter.RegisterTag("img", HtmlTextWriterTag.Img, TagType.NonClosing);\r
66         HtmlTextWriter.RegisterTag("input", HtmlTextWriterTag.Input, TagType.NonClosing);\r
67         HtmlTextWriter.RegisterTag("ins", HtmlTextWriterTag.Ins, TagType.Inline);\r
68         HtmlTextWriter.RegisterTag("isindex", HtmlTextWriterTag.Isindex, TagType.NonClosing);\r
69         HtmlTextWriter.RegisterTag("kbd", HtmlTextWriterTag.Kbd, TagType.Inline);\r
70         HtmlTextWriter.RegisterTag("label", HtmlTextWriterTag.Label, TagType.Inline);\r
71         HtmlTextWriter.RegisterTag("legend", HtmlTextWriterTag.Legend, TagType.Other);\r
72         HtmlTextWriter.RegisterTag("li", HtmlTextWriterTag.Li, TagType.Inline);\r
73         HtmlTextWriter.RegisterTag("link", HtmlTextWriterTag.Link, TagType.NonClosing);\r
74         HtmlTextWriter.RegisterTag("map", HtmlTextWriterTag.Map, TagType.Other);\r
75         HtmlTextWriter.RegisterTag("marquee", HtmlTextWriterTag.Marquee, TagType.Other);\r
76         HtmlTextWriter.RegisterTag("menu", HtmlTextWriterTag.Menu, TagType.Other);\r
77         HtmlTextWriter.RegisterTag("meta", HtmlTextWriterTag.Meta, TagType.NonClosing);\r
78         HtmlTextWriter.RegisterTag("nobr", HtmlTextWriterTag.Nobr, TagType.Inline);\r
79         HtmlTextWriter.RegisterTag("noframes", HtmlTextWriterTag.Noframes, TagType.Other);\r
80         HtmlTextWriter.RegisterTag("noscript", HtmlTextWriterTag.Noscript, TagType.Other);\r
81         HtmlTextWriter.RegisterTag("object", HtmlTextWriterTag.Object, TagType.Other);\r
82         HtmlTextWriter.RegisterTag("ol", HtmlTextWriterTag.Ol, TagType.Other);\r
83         HtmlTextWriter.RegisterTag("option", HtmlTextWriterTag.Option, TagType.Other);\r
84         HtmlTextWriter.RegisterTag("p", HtmlTextWriterTag.P, TagType.Inline);\r
85         HtmlTextWriter.RegisterTag("param", HtmlTextWriterTag.Param, TagType.Other);\r
86         HtmlTextWriter.RegisterTag("pre", HtmlTextWriterTag.Pre, TagType.Other);\r
87         HtmlTextWriter.RegisterTag("q", HtmlTextWriterTag.Q, TagType.Inline);\r
88         HtmlTextWriter.RegisterTag("rt", HtmlTextWriterTag.Rt, TagType.Other);\r
89         HtmlTextWriter.RegisterTag("ruby", HtmlTextWriterTag.Ruby, TagType.Other);\r
90         HtmlTextWriter.RegisterTag("s", HtmlTextWriterTag.S, TagType.Inline);\r
91         HtmlTextWriter.RegisterTag("samp", HtmlTextWriterTag.Samp, TagType.Inline);\r
92         HtmlTextWriter.RegisterTag("script", HtmlTextWriterTag.Script, TagType.Other);\r
93         HtmlTextWriter.RegisterTag("select", HtmlTextWriterTag.Select, TagType.Other);\r
94         HtmlTextWriter.RegisterTag("small", HtmlTextWriterTag.Small, TagType.Other);\r
95         HtmlTextWriter.RegisterTag("span", HtmlTextWriterTag.Span, TagType.Inline);\r
96         HtmlTextWriter.RegisterTag("strike", HtmlTextWriterTag.Strike, TagType.Inline);\r
97         HtmlTextWriter.RegisterTag("strong", HtmlTextWriterTag.Strong, TagType.Inline);\r
98         HtmlTextWriter.RegisterTag("style", HtmlTextWriterTag.Style, TagType.Other);\r
99         HtmlTextWriter.RegisterTag("sub", HtmlTextWriterTag.Sub, TagType.Inline);\r
100         HtmlTextWriter.RegisterTag("sup", HtmlTextWriterTag.Sup, TagType.Inline);\r
101         HtmlTextWriter.RegisterTag("table", HtmlTextWriterTag.Table, TagType.Other);\r
102         HtmlTextWriter.RegisterTag("tbody", HtmlTextWriterTag.Tbody, TagType.Other);\r
103         HtmlTextWriter.RegisterTag("td", HtmlTextWriterTag.Td, TagType.Inline);\r
104         HtmlTextWriter.RegisterTag("textarea", HtmlTextWriterTag.Textarea, TagType.Inline);\r
105         HtmlTextWriter.RegisterTag("tfoot", HtmlTextWriterTag.Tfoot, TagType.Other);\r
106         HtmlTextWriter.RegisterTag("th", HtmlTextWriterTag.Th, TagType.Inline);\r
107         HtmlTextWriter.RegisterTag("thead", HtmlTextWriterTag.Thead, TagType.Other);\r
108         HtmlTextWriter.RegisterTag("title", HtmlTextWriterTag.Title, TagType.Other);\r
109         HtmlTextWriter.RegisterTag("tr", HtmlTextWriterTag.Tr, TagType.Other);\r
110         HtmlTextWriter.RegisterTag("tt", HtmlTextWriterTag.Tt, TagType.Inline);\r
111         HtmlTextWriter.RegisterTag("u", HtmlTextWriterTag.U, TagType.Inline);\r
112         HtmlTextWriter.RegisterTag("ul", HtmlTextWriterTag.Ul, TagType.Other);\r
113         HtmlTextWriter.RegisterTag("var", HtmlTextWriterTag.Var, TagType.Inline);\r
114         HtmlTextWriter.RegisterTag("wbr", HtmlTextWriterTag.Wbr, TagType.NonClosing);\r
115         HtmlTextWriter.RegisterTag("xml", HtmlTextWriterTag.Xml, TagType.Other);\r
116 \r
117         HtmlTextWriter._attrKeyLookupTable = new Hashtable(40);\r
118         HtmlTextWriter._attrNameLookupArray = new AttributeInformation[40];\r
119         HtmlTextWriter.RegisterAttribute("accesskey", HtmlTextWriterAttribute.Accesskey, true);\r
120         HtmlTextWriter.RegisterAttribute("align", HtmlTextWriterAttribute.Align, false);\r
121         HtmlTextWriter.RegisterAttribute("alt", HtmlTextWriterAttribute.Alt, true);\r
122         HtmlTextWriter.RegisterAttribute("background", HtmlTextWriterAttribute.Background, true);\r
123         HtmlTextWriter.RegisterAttribute("bgcolor", HtmlTextWriterAttribute.Bgcolor, false);\r
124         HtmlTextWriter.RegisterAttribute("border", HtmlTextWriterAttribute.Border, false);\r
125         HtmlTextWriter.RegisterAttribute("bordercolor", HtmlTextWriterAttribute.Bordercolor, false);\r
126         HtmlTextWriter.RegisterAttribute("cellpadding", HtmlTextWriterAttribute.Cellpadding, false);\r
127         HtmlTextWriter.RegisterAttribute("cellspacing", HtmlTextWriterAttribute.Cellspacing, false);\r
128         HtmlTextWriter.RegisterAttribute("checked", HtmlTextWriterAttribute.Checked, false);\r
129         HtmlTextWriter.RegisterAttribute("class", HtmlTextWriterAttribute.Class, true);\r
130         HtmlTextWriter.RegisterAttribute("cols", HtmlTextWriterAttribute.Cols, false);\r
131         HtmlTextWriter.RegisterAttribute("colspan", HtmlTextWriterAttribute.Colspan, false);\r
132         HtmlTextWriter.RegisterAttribute("disabled", HtmlTextWriterAttribute.Disabled, false);\r
133         HtmlTextWriter.RegisterAttribute("for", HtmlTextWriterAttribute.For, false);\r
134         HtmlTextWriter.RegisterAttribute("height", HtmlTextWriterAttribute.Height, false);\r
135         HtmlTextWriter.RegisterAttribute("href", HtmlTextWriterAttribute.Href, true);\r
136         HtmlTextWriter.RegisterAttribute("id", HtmlTextWriterAttribute.Id, false);\r
137         HtmlTextWriter.RegisterAttribute("maxlength", HtmlTextWriterAttribute.Maxlength, false);\r
138         HtmlTextWriter.RegisterAttribute("multiple", HtmlTextWriterAttribute.Multiple, false);\r
139         HtmlTextWriter.RegisterAttribute("name", HtmlTextWriterAttribute.Name, false);\r
140         HtmlTextWriter.RegisterAttribute("nowrap", HtmlTextWriterAttribute.Nowrap, false);\r
141         HtmlTextWriter.RegisterAttribute("onchange", HtmlTextWriterAttribute.Onchange, true);\r
142         HtmlTextWriter.RegisterAttribute("onclick", HtmlTextWriterAttribute.Onclick, true);\r
143         HtmlTextWriter.RegisterAttribute("readonly", HtmlTextWriterAttribute.ReadOnly, false);\r
144         HtmlTextWriter.RegisterAttribute("rows", HtmlTextWriterAttribute.Rows, false);\r
145         HtmlTextWriter.RegisterAttribute("rowspan", HtmlTextWriterAttribute.Rowspan, false);\r
146         HtmlTextWriter.RegisterAttribute("rules", HtmlTextWriterAttribute.Rules, false);\r
147         HtmlTextWriter.RegisterAttribute("selected", HtmlTextWriterAttribute.Selected, false);\r
148         HtmlTextWriter.RegisterAttribute("size", HtmlTextWriterAttribute.Size, false);\r
149         HtmlTextWriter.RegisterAttribute("src", HtmlTextWriterAttribute.Src, true);\r
150         HtmlTextWriter.RegisterAttribute("style", HtmlTextWriterAttribute.Style, false);\r
151         HtmlTextWriter.RegisterAttribute("tabindex", HtmlTextWriterAttribute.Tabindex, false);\r
152         HtmlTextWriter.RegisterAttribute("target", HtmlTextWriterAttribute.Target, false);\r
153         HtmlTextWriter.RegisterAttribute("title", HtmlTextWriterAttribute.Title, true);\r
154         HtmlTextWriter.RegisterAttribute("type", HtmlTextWriterAttribute.Type, false);\r
155         HtmlTextWriter.RegisterAttribute("valign", HtmlTextWriterAttribute.Valign, false);\r
156         HtmlTextWriter.RegisterAttribute("value", HtmlTextWriterAttribute.Value, true);\r
157         HtmlTextWriter.RegisterAttribute("width", HtmlTextWriterAttribute.Width, false);\r
158         HtmlTextWriter.RegisterAttribute("wrap", HtmlTextWriterAttribute.Wrap, false);\r
159 \r
160         HtmlTextWriter._styleKeyLookupTable = new Hashtable(14);\r
161         HtmlTextWriter._styleNameLookupArray = new String[14];\r
162         HtmlTextWriter.RegisterStyle("background-color", HtmlTextWriterStyle.BackgroundColor);\r
163         HtmlTextWriter.RegisterStyle("background-image", HtmlTextWriterStyle.BackgroundImage);\r
164         HtmlTextWriter.RegisterStyle("border-collapse", HtmlTextWriterStyle.BorderCollapse);\r
165         HtmlTextWriter.RegisterStyle("border-color", HtmlTextWriterStyle.BorderColor);\r
166         HtmlTextWriter.RegisterStyle("border-style", HtmlTextWriterStyle.BorderStyle);\r
167         HtmlTextWriter.RegisterStyle("border-width", HtmlTextWriterStyle.BorderWidth);\r
168         HtmlTextWriter.RegisterStyle("color", HtmlTextWriterStyle.Color);\r
169         HtmlTextWriter.RegisterStyle("font-family", HtmlTextWriterStyle.FontFamily);\r
170         HtmlTextWriter.RegisterStyle("font-size", HtmlTextWriterStyle.FontSize);\r
171         HtmlTextWriter.RegisterStyle("font-style", HtmlTextWriterStyle.FontStyle);\r
172         HtmlTextWriter.RegisterStyle("font-weight", HtmlTextWriterStyle.FontWeight);\r
173         HtmlTextWriter.RegisterStyle("height", HtmlTextWriterStyle.Height);\r
174         HtmlTextWriter.RegisterStyle("text-decoration", HtmlTextWriterStyle.TextDecoration);\r
175         HtmlTextWriter.RegisterStyle("width", HtmlTextWriterStyle.Width);\r
176 }\r
177 \r
178 public HtmlTextWriter(TextWriter writer):this(writer, " "){}\r
179 \r
180 public HtmlTextWriter(TextWriter writer, string tabString) : base() {\r
181         this.writer = writer;\r
182         this.tabString = tabString;\r
183         indentLevel = 0;\r
184         tabsPending = false;\r
185         _httpWriter = writer as HttpWriter;\r
186         _isDescendant = GetType() == typeof(HtmlTextWriter) == false;\r
187         _attrList = new RenderAttribute[20];\r
188         _attrCount = 0;\r
189         _styleList = new RenderStyle[20];\r
190         _styleCount = 0;\r
191         _endTags = new TagStackEntry[16];\r
192         _endTagCount = 0;\r
193         _inlineCount = 0;\r
194 }\r
195 \r
196 public virtual void AddAttribute(HtmlTextWriterAttribute key, string value){\r
197         if ((int) key >= 0 && (int) key < HtmlTextWriter._attrNameLookupArray.Length) {\r
198                 AttributeInformation attrInfo = HtmlTextWriter._attrNameLookupArray[(int) key];\r
199                 AddAttribute(attrInfo.name, value, key, attrInfo.encode);\r
200         }\r
201 }\r
202 \r
203 public virtual void AddAttribute(HtmlTextWriterAttribute key, string value, bool fEncode){\r
204         if ((int) key >= 0 && (int) key < HtmlTextWriter._attrNameLookupArray.Length) {\r
205                 AddAttribute(HtmlTextWriter._attrNameLookupArray[(int) key].name, value, key, fEncode);\r
206         }\r
207 }\r
208 \r
209 public virtual void AddAttribute(string name, string value){\r
210         HtmlTextWriterAttribute attr = GetAttributeKey(name);\r
211         value = EncodeAttributeValue(GetAttributeKey(name), value);\r
212         AddAttribute(name, value, attr);\r
213 }\r
214 \r
215 public virtual void AddAttribute(string name, string value, bool fEndode){\r
216         value = EncodeAttributeValue(value, fEndode);\r
217         AddAttribute(name, value, GetAttributeKey(name));\r
218 }\r
219 \r
220 protected virtual void AddAttribute(string name, string value, HtmlTextWriterAttribute key){\r
221         AddAttribute(name, value, key, false);\r
222 }\r
223 \r
224 private void AddAttribute(string name, string value, HtmlTextWriterAttribute key, bool encode){\r
225         if (_attrCount >= (int) _attrList.Length) {\r
226                 RenderAttribute[] rAttrArr = new RenderAttribute[_attrList.Length * 2];\r
227                 System.Array.Copy(_attrList, rAttrArr, (int) _attrList.Length);\r
228                 _attrList = rAttrArr;\r
229         }\r
230         RenderAttribute rAttr;\r
231         rAttr.name = name;\r
232         rAttr.value = value;\r
233         rAttr.key = key;\r
234         rAttr.encode = encode;\r
235         _attrList [_attrCount++] = rAttr;\r
236 }\r
237 \r
238 public virtual void AddStyleAttribute(HtmlTextWriterStyle key, string value){\r
239         AddStyleAttribute(GetStyleName(key), value, key);\r
240 }\r
241 \r
242 public virtual void AddStyleAttribute(string name, string value){\r
243         AddStyleAttribute(name, value, GetStyleKey(name));\r
244 }\r
245 \r
246 protected virtual void AddStyleAttribute(string name, string value, HtmlTextWriterStyle key){\r
247         if (_styleCount >= (int) _styleList.Length) {\r
248                 RenderStyle[] rAttrArr = new RenderStyle[_styleList.Length * 2];\r
249                 System.Array.Copy(_styleList, rAttrArr, (int) _styleList.Length);\r
250                 _styleList = rAttrArr;\r
251         }\r
252         RenderStyle rAttr;\r
253         rAttr.name = name;\r
254         rAttr.value = value;\r
255         rAttr.key = key;\r
256         _styleList [_styleCount++] = rAttr;\r
257 }\r
258 \r
259 public override void Close(){\r
260         writer.Close();\r
261 }\r
262 \r
263 protected virtual string EncodeAttributeValue(HtmlTextWriterAttribute attrKey, string value){\r
264         bool valid = true;\r
265         if (0 <= (int) attrKey && (int) attrKey < HtmlTextWriter._attrNameLookupArray.Length)\r
266                 valid = HtmlTextWriter._attrNameLookupArray[(int) attrKey].encode;\r
267         return EncodeAttributeValue(value, valid);\r
268 }\r
269 \r
270 protected string EncodeAttributeValue(string value, bool fEncode){\r
271         if (value == null)\r
272                 return null;\r
273         if (!(fEncode))\r
274                 return value;\r
275         return System.Web.HttpUtility.HtmlAttributeEncode(value);\r
276 }\r
277 \r
278 protected string EncodeUrl(string url){\r
279         if (url.IndexOf(SpaceChar) < 0)\r
280                 return url;\r
281         System.Text.StringBuilder sb = new System.Text.StringBuilder();\r
282         for(int i=0; i <= url.Length; i++){\r
283                 char temp = url[i];\r
284                 if (temp != 32)\r
285                         sb.Append(temp);\r
286                 else\r
287                         sb.Append("%20");\r
288         }\r
289         return sb.ToString();\r
290 }\r
291 \r
292 protected virtual void FilterAttributes(){\r
293         int count = 0;\r
294         for(int i=0; i < _styleCount; i++){\r
295                 RenderStyle rStyle = _styleList[i];\r
296                 if (OnStyleAttributeRender(rStyle.name, rStyle.value, rStyle.key)) {\r
297                         count++;\r
298                 }\r
299         }\r
300         _styleCount = count;\r
301         count = 0;\r
302         for(int i=0; i <= _attrCount; i++){\r
303                 RenderAttribute rAttr = _attrList[i];\r
304                 if (OnAttributeRender(rAttr.name, rAttr.value, rAttr.key)) {\r
305                         count++;\r
306                 }\r
307         }\r
308         _attrCount = count;\r
309 }\r
310 \r
311 public override void Flush(){\r
312         writer.Flush();\r
313 }\r
314 \r
315 protected HtmlTextWriterAttribute GetAttributeKey(string attrName){\r
316         if (attrName != null && attrName.Length > 0) {\r
317                 object attr = HtmlTextWriter._attrKeyLookupTable[attrName.ToLower()];\r
318                 if (attr != null)\r
319                         return (HtmlTextWriterAttribute) attr;\r
320         }\r
321         return (HtmlTextWriterAttribute) (-1);\r
322 }\r
323 \r
324 protected string GetAttributeName(HtmlTextWriterAttribute attrKey){\r
325         if ((int) attrKey >= 0 && (int) attrKey < HtmlTextWriter._attrNameLookupArray.Length)\r
326                 return HtmlTextWriter._attrNameLookupArray[(int) attrKey].name;\r
327         return System.String.Empty;\r
328 }\r
329 \r
330 protected HtmlTextWriterStyle GetStyleKey(string styleName){\r
331         if (styleName != null && styleName.Length > 0) {\r
332                 object style = HtmlTextWriter._styleKeyLookupTable[styleName.ToLower()];\r
333                 if (style != null)\r
334                         return (HtmlTextWriterStyle) style;\r
335         }\r
336         return (HtmlTextWriterStyle) (-1);\r
337 }\r
338 \r
339 protected string GetStyleName(HtmlTextWriterStyle styleKey){\r
340         if ((int) styleKey >= 0 && (int) styleKey < HtmlTextWriter._styleNameLookupArray.Length)\r
341                 return HtmlTextWriter._styleNameLookupArray[(int) styleKey];\r
342         return System.String.Empty;\r
343 }\r
344 \r
345 protected virtual HtmlTextWriterTag GetTagKey(string tagName){\r
346         if (tagName != null && tagName.Length > 0) {\r
347                 object tag = HtmlTextWriter._tagKeyLookupTable[tagName.ToLower()];\r
348                 if (tag != null)\r
349                         return (HtmlTextWriterTag) tag;\r
350         }\r
351         return 0;\r
352 }\r
353 \r
354 protected virtual string GetTagName(HtmlTextWriterTag tagKey){\r
355         if ((int) tagKey >= 0 && (int) tagKey < HtmlTextWriter._tagNameLookupArray.Length)\r
356                 return HtmlTextWriter._tagNameLookupArray[(int) tagKey].name;\r
357         return System.String.Empty;\r
358 }\r
359 \r
360 protected bool IsAttributeDefined(HtmlTextWriterAttribute key){\r
361         for (int i=0; i < _attrCount; i++) {\r
362                 if (_attrList[i].key == key)\r
363                         return true;\r
364         }\r
365         return false;\r
366 }\r
367 \r
368 protected bool IsAttributeDefined(HtmlTextWriterAttribute key, out string value){\r
369         value = null;\r
370         for (int i=0; i < _attrCount; i++) {\r
371                 if (_attrList[i].key == key) {\r
372                         value = _attrList[i].value;\r
373                         return true;\r
374                 }\r
375         }\r
376         return false;\r
377 }\r
378 \r
379 protected bool IsStyleAttributeDefined(HtmlTextWriterStyle key){\r
380         for (int i= 0; i < _styleCount; i++) {\r
381                 if (_styleList[i].key == key)\r
382                         return true;\r
383         }\r
384         return false;\r
385 }\r
386 \r
387 protected bool IsStyleAttributeDefined(HtmlTextWriterStyle key, out string value){\r
388         value = null;\r
389         for( int i=0; i < _styleCount; i++) {\r
390                 if (_styleList[i].key == key) {\r
391                         value = _styleList[i].value;\r
392                         return true;\r
393                 }\r
394         }\r
395         return false;\r
396 }\r
397 \r
398 protected virtual bool OnAttributeRender(string name, string value, HtmlTextWriterAttribute key){\r
399         return true;\r
400 }\r
401 \r
402 protected virtual bool OnStyleAttributeRender(string name, string value, HtmlTextWriterStyle key){\r
403         return true;\r
404 }\r
405 \r
406 protected virtual bool OnTagRender(string name, HtmlTextWriterTag key){\r
407         return true;\r
408 }\r
409 \r
410 protected virtual void OutputTabs(){\r
411         if (tabsPending) {\r
412                 for(int i=0; i < indentLevel; i++) {\r
413                         writer.Write(tabString);\r
414                 }\r
415                 tabsPending = false;\r
416         }\r
417 }\r
418 \r
419 protected string PopEndTag(){\r
420         if (_endTagCount <= 0)\r
421                 throw new InvalidOperationException("A PopEndTag was called without a corresponding PushEndTag");\r
422         _endTagCount--;\r
423         TagKey = _endTags[_endTagCount].tagKey;\r
424         return _endTags[_endTagCount].endTagText;\r
425 }\r
426 \r
427 protected void PushEndTag(string endTag){\r
428         if (_endTagCount >= (int) _endTags.Length) {\r
429                 TagStackEntry[] temp = new TagStackEntry[(int) _endTags.Length * 2];\r
430                 System.Array.Copy(_endTags, temp, (int) _endTags.Length);\r
431                 _endTags = temp;\r
432         }\r
433         _endTags[_endTagCount].tagKey = _tagKey;\r
434         _endTags[_endTagCount].endTagText = endTag;\r
435         _endTagCount++;\r
436 }\r
437 \r
438 protected static void RegisterAttribute(string name, HtmlTextWriterAttribute key){\r
439         HtmlTextWriter.RegisterAttribute(name, key, false);\r
440 }\r
441 \r
442 private static void RegisterAttribute(string name, HtmlTextWriterAttribute key, bool fEncode){\r
443         name = name.ToLower();\r
444         HtmlTextWriter._attrKeyLookupTable.Add(name, key);\r
445         if ((int) key < (int) HtmlTextWriter._attrNameLookupArray.Length)\r
446                 HtmlTextWriter._attrNameLookupArray[(int) key] = new AttributeInformation(name, fEncode);\r
447 }\r
448 \r
449 protected static void RegisterStyle(string name, HtmlTextWriterStyle key){\r
450         name = name.ToLower();\r
451         HtmlTextWriter._styleKeyLookupTable.Add(name, key);\r
452         if ((int) key < (int) HtmlTextWriter._styleNameLookupArray.Length)\r
453                 HtmlTextWriter._styleNameLookupArray[(int) key] = name;\r
454 }\r
455 \r
456 protected static void RegisterTag(string name, HtmlTextWriterTag key){\r
457         HtmlTextWriter.RegisterTag(name, key, TagType.Other);\r
458 }\r
459 \r
460 private static void RegisterTag(string name, HtmlTextWriterTag key, TagType type){\r
461         name = name.ToLower();\r
462         HtmlTextWriter._tagKeyLookupTable.Add(name, key);\r
463         string fullTag = null;\r
464         if ((int) type != 1 && (int) key != 0) {\r
465                 fullTag = EndTagLeftChars + name + TagRightChar;\r
466         }\r
467         if ((int) key < HtmlTextWriter._tagNameLookupArray.Length)\r
468                 HtmlTextWriter._tagNameLookupArray[(int) key] = new TagInformation(name, type, fullTag);\r
469 }\r
470 \r
471 protected virtual string RenderAfterContent(){\r
472         return null;\r
473 }\r
474 \r
475 protected virtual string RenderAfterTag(){\r
476         return null;\r
477 }\r
478 \r
479 protected virtual string RenderBeforeContent(){\r
480         return null;\r
481 }\r
482 \r
483 protected virtual string RenderBeforeTag(){\r
484         return null;\r
485 }\r
486 \r
487 public virtual void RenderBeginTag(HtmlTextWriterTag tagKey){\r
488         TagKey = tagKey;\r
489         bool tagRendered = true;\r
490         bool tagRender = true;\r
491         if (_isDescendant) {\r
492                 tagRender = OnTagRender(_tagName, _tagKey);\r
493                 FilterAttributes();\r
494                 string beforeTag = RenderBeforeTag();\r
495                 if (beforeTag != null) {\r
496                         if (tabsPending)\r
497                                 OutputTabs();\r
498                         writer.Write(beforeTag);\r
499                 }\r
500         }\r
501         TagInformation currentTag = HtmlTextWriter._tagNameLookupArray[_tagIndex];\r
502         if (currentTag.closingTag == null)\r
503                 currentTag.closingTag = EndTagLeftChars + _tagName + TagRightChar;\r
504         if (tagRender) {\r
505                 tagRendered = false;\r
506                 if (tabsPending)\r
507                         OutputTabs();\r
508                 writer.Write(TagLeftChar);\r
509                 writer.Write(_tagName);\r
510                 RenderAttribute rAttr;\r
511                 string rAttrValue = null;\r
512                 for (int i=0; i < _attrCount; i++) {\r
513                         rAttr = _attrList[i];\r
514                         if (rAttr.key == HtmlTextWriterAttribute.Style)\r
515                                 rAttrValue = rAttr.value;\r
516                         else {\r
517                                 writer.Write(SpaceChar);\r
518                                 writer.Write(rAttr.name);\r
519                                 if (rAttr.value != null) {\r
520                                         writer.Write(EqualsChar);\r
521                                         writer.Write(DoubleQuoteChar);\r
522                                         if (rAttr.encode) {\r
523                                                 if (_httpWriter == null) {\r
524                                                         System.Web.HttpUtility.HtmlAttributeEncode(rAttr.value, writer);\r
525                                                 }\r
526                                                 else {\r
527                                                         System.Web.HttpUtility.HtmlAttributeEncode(rAttr.value, (TextWriter) _httpWriter);\r
528                                                 }\r
529                                         }\r
530                                         else {\r
531                                                 writer.Write(rAttr.value);\r
532                                         }\r
533                                         writer.Write(DoubleQuoteChar);\r
534                                 }\r
535                         }\r
536                 }\r
537                 if (_styleCount > 0 || rAttrValue != null) {\r
538                         writer.Write(SpaceChar);\r
539                         writer.Write("style");\r
540                         writer.Write(EqualsChar);\r
541                         writer.Write(DoubleQuoteChar);\r
542                         RenderStyle rStyle;\r
543                         for (int i=0; i < _styleCount; i++) {\r
544                                 rStyle = _styleList[i];\r
545                                 writer.Write(rStyle.name);\r
546                                 writer.Write(StyleEqualsChar);\r
547                                 writer.Write(rStyle.value);\r
548                                 writer.Write(SemicolonChar);\r
549                         }\r
550                         if (rAttrValue != null)\r
551                                 writer.Write(rAttrValue);\r
552                         writer.Write(DoubleQuoteChar);\r
553                 }\r
554                 if (currentTag.tagType == TagType.NonClosing) {\r
555                         writer.Write(SpaceChar);\r
556                         writer.Write(SlashChar);\r
557                         writer.Write(TagRightChar);\r
558                 }\r
559                 else\r
560                         writer.Write(TagRightChar);\r
561         }\r
562         string beforeContent = RenderBeforeContent();\r
563         if (beforeContent != null) {\r
564                 if (tabsPending)\r
565                         OutputTabs();\r
566                 writer.Write(beforeContent);\r
567         }\r
568         if (tagRendered) {\r
569                 if (currentTag.tagType == TagType.Inline)\r
570                         _inlineCount++;\r
571                 else {\r
572                         WriteLine();\r
573                         Indent++;\r
574                 }\r
575                 if (currentTag.closingTag == null) {\r
576                         currentTag.closingTag = EndTagLeftChars + _tagName + TagRightChar;\r
577                 }\r
578         }\r
579         if (_isDescendant) {\r
580                 string afterContent = RenderAfterContent();\r
581                 if (afterContent != null) {\r
582                         if (currentTag.closingTag != null)\r
583                                 currentTag.closingTag = afterContent;\r
584                 }\r
585                 string afterTag = RenderAfterTag();\r
586                 if (afterTag != null) {\r
587                         if (currentTag.closingTag != null)\r
588                                 currentTag.closingTag = afterTag;\r
589                 }\r
590         }\r
591         PushEndTag(currentTag.closingTag);\r
592         _attrCount = 0;\r
593         _styleCount = 0;\r
594 }\r
595 \r
596 public virtual void RenderBeginTag(string tagName){\r
597         TagName = tagName;\r
598         RenderBeginTag(_tagKey);\r
599 }\r
600 \r
601 public virtual void RenderEndTag(){\r
602         string endTagText = PopEndTag();\r
603         if (endTagText != null) {\r
604                 if (HtmlTextWriter._tagNameLookupArray[_tagIndex].tagType == 0) {\r
605                         _inlineCount--;\r
606                         Write(endTagText);\r
607                 }\r
608                 else{\r
609                         WriteLine();\r
610                         Indent--;\r
611                         Write(endTagText);\r
612                 }\r
613         }\r
614 }\r
615 \r
616 public override void Write(bool value){\r
617         if (tabsPending)\r
618                 OutputTabs();\r
619         writer.Write(value);\r
620 }\r
621 \r
622 public override void Write(char value){\r
623         if (tabsPending)\r
624                 OutputTabs();\r
625         writer.Write(value);\r
626 }\r
627 \r
628 public override void Write(char[] buffer){\r
629         if (tabsPending)\r
630                 OutputTabs();\r
631         writer.Write(buffer);\r
632 }\r
633 \r
634 public override void Write(char[] buffer, int index, int count){\r
635         if (tabsPending)\r
636                 OutputTabs();\r
637         writer.Write(buffer, index, count);\r
638 }\r
639 \r
640 public override void Write(double value){\r
641         if (tabsPending)\r
642                 OutputTabs();\r
643         writer.Write(value);\r
644 }\r
645 \r
646 public override void Write(int value){\r
647         if (tabsPending)\r
648                 OutputTabs();\r
649         writer.Write(value);\r
650 }\r
651 \r
652 public override void Write(long value){\r
653         if (tabsPending)\r
654                 OutputTabs();\r
655         writer.Write(value);\r
656 }\r
657 \r
658 public override void Write(object value){\r
659         if (tabsPending)\r
660                 OutputTabs();\r
661         writer.Write(value);\r
662 }\r
663 \r
664 public override void Write(float value){\r
665         if (tabsPending)\r
666                 OutputTabs();\r
667         writer.Write(value);\r
668 }\r
669 \r
670 public override void Write(string s){\r
671         if (tabsPending)\r
672                 OutputTabs();\r
673         writer.Write(s);\r
674 }\r
675 \r
676 public override void Write(string format, object arg0){\r
677         if (tabsPending)\r
678                 OutputTabs();\r
679         writer.Write(format, arg0);\r
680 }\r
681 \r
682 public override void Write(string format, object arg0, object arg1){\r
683         if (tabsPending)\r
684                 OutputTabs();\r
685         writer.Write(format, arg0, arg1);\r
686 }\r
687 \r
688 public override void Write(string format, params object[] arg){\r
689         if (tabsPending)\r
690                 OutputTabs();\r
691         writer.Write(format, arg);\r
692 }\r
693 \r
694 public virtual void WriteAttribute(string name, string value){\r
695         WriteAttribute(name, value, false);\r
696 }\r
697 \r
698 public virtual void WriteAttribute(string name, string value, bool fEncode){\r
699         writer.Write(SpaceChar);\r
700         writer.Write(name);\r
701         if (value != null) {\r
702                 writer.Write(EqualsChar);\r
703                 writer.Write(DoubleQuoteChar);\r
704                 if (fEncode) {\r
705                         if (_httpWriter == null) {\r
706                                 System.Web.HttpUtility.HtmlAttributeEncode(value, writer);\r
707                         }\r
708                         else{\r
709                                 System.Web.HttpUtility.HtmlAttributeEncode(value, (TextWriter) _httpWriter);\r
710                         }\r
711                 }\r
712                 else{\r
713                         writer.Write(value);\r
714                 }\r
715                 writer.Write(DoubleQuoteChar);\r
716         }\r
717 }\r
718 \r
719 public virtual void WriteBeginTag(string tagName){\r
720         if (tabsPending)\r
721                 OutputTabs();\r
722         writer.Write(TagLeftChar);\r
723         writer.Write(tagName);\r
724 }\r
725 \r
726 public virtual void WriteEndTag(string tagName){\r
727         if (tabsPending)\r
728                 OutputTabs();\r
729         writer.Write(TagLeftChar);\r
730         writer.Write(SlashChar);\r
731         writer.Write(tagName);\r
732         writer.Write(TagRightChar);\r
733 }\r
734 \r
735 public virtual void WriteFullBeginTag(string tagName){\r
736         if (tabsPending)\r
737                 OutputTabs();\r
738         writer.Write(TagLeftChar);\r
739         writer.Write(tagName);\r
740         writer.Write(TagRightChar);\r
741 }\r
742 \r
743 public override void WriteLine(){\r
744         writer.WriteLine();\r
745         tabsPending = true;\r
746 }\r
747 \r
748 public override void WriteLine(bool value){\r
749         if (tabsPending)\r
750                 OutputTabs();\r
751         writer.WriteLine(value);\r
752         tabsPending = true;\r
753 }\r
754 \r
755 public override void WriteLine(char value){\r
756         if (tabsPending)\r
757                 OutputTabs();\r
758         writer.WriteLine(value);\r
759         tabsPending = true;\r
760 }\r
761 \r
762 public override void WriteLine(char[] buffer){\r
763         if (tabsPending)\r
764                 OutputTabs();\r
765         writer.WriteLine(buffer);\r
766         tabsPending = true;\r
767 }\r
768 \r
769 public override void WriteLine(char[] buffer, int index, int count){\r
770         if (tabsPending)\r
771                 OutputTabs();\r
772         writer.WriteLine(buffer, index, count);\r
773         tabsPending = true;\r
774 }\r
775 \r
776 public override void WriteLine(double value){\r
777         if (tabsPending)\r
778                 OutputTabs();\r
779         writer.WriteLine(value);\r
780         tabsPending = true;\r
781 }\r
782 \r
783 public override void WriteLine(int value){\r
784         if (tabsPending)\r
785                 OutputTabs();\r
786         writer.WriteLine(value);\r
787         tabsPending = true;\r
788 }\r
789 \r
790 public override void WriteLine(long value){\r
791         if (tabsPending)\r
792                 OutputTabs();\r
793         writer.WriteLine(value);\r
794         tabsPending = true;\r
795 }\r
796 \r
797 public override void WriteLine(object value){\r
798         if (tabsPending)\r
799                 OutputTabs();\r
800         writer.WriteLine(value);\r
801         tabsPending = true;\r
802 }\r
803 \r
804 public override void WriteLine(float value){\r
805         if (tabsPending)\r
806                 OutputTabs();\r
807         writer.WriteLine(value);\r
808         tabsPending = true;\r
809 }\r
810 \r
811 public override void WriteLine(string s){\r
812         if (tabsPending)\r
813                 OutputTabs();\r
814         writer.WriteLine(s);\r
815         tabsPending = true;\r
816 }\r
817 \r
818 public override void WriteLine(string format, object arg0){\r
819         if (tabsPending)\r
820                 OutputTabs();\r
821         writer.WriteLine(format, arg0);\r
822         tabsPending = true;\r
823 }\r
824 \r
825 public override void WriteLine(string format, object arg0, object arg1){\r
826         if (tabsPending)\r
827                 OutputTabs();\r
828         writer.WriteLine(format, arg0, arg1);\r
829         tabsPending = true;\r
830 }\r
831 \r
832 public override void WriteLine(string format, params object[] arg){\r
833         if (tabsPending)\r
834                 OutputTabs();\r
835         writer.WriteLine(format, arg);\r
836         tabsPending = true;\r
837 }\r
838 \r
839 [CLSCompliant(false)]\r
840 public override void WriteLine(uint value){\r
841         if (tabsPending)\r
842                 OutputTabs();\r
843         writer.WriteLine(value);\r
844         tabsPending = true;\r
845 }\r
846 \r
847 public void WriteLineNoTabs(string s){\r
848         writer.WriteLine(s);\r
849 }\r
850 \r
851 public virtual void WriteStyleAttribute(string name, string value){\r
852         WriteStyleAttribute(name, value, false);\r
853 }\r
854 \r
855 public virtual void WriteStyleAttribute(string name, string value, bool fEncode){\r
856         writer.Write(name);\r
857         writer.Write(StyleEqualsChar);\r
858         if (fEncode) {\r
859                 if (_httpWriter == null) {\r
860                         System.Web.HttpUtility.HtmlAttributeEncode(value, writer);\r
861                 }\r
862                 else{\r
863                         System.Web.HttpUtility.HtmlAttributeEncode(value, (TextWriter) _httpWriter);\r
864                 }\r
865         }\r
866         else {\r
867                 writer.Write(value);\r
868         }\r
869         writer.Write(SemicolonChar);\r
870 }\r
871 \r
872 public override System.Text.Encoding Encoding { \r
873         get{\r
874                 return writer.Encoding;\r
875         }\r
876 }\r
877 \r
878 public int Indent { \r
879         get{\r
880                 return indentLevel;\r
881         }\r
882         set{\r
883                 if (value < 0)\r
884                         value = 0;\r
885                 indentLevel = value;\r
886         }\r
887 }\r
888 \r
889 public TextWriter InnerWriter { \r
890         get{\r
891                 return writer;\r
892         }\r
893         set{\r
894                 writer = value;\r
895                 _httpWriter = value as HttpWriter;\r
896         }\r
897 }\r
898 \r
899 public override string NewLine { \r
900         get{\r
901                 return writer.NewLine;\r
902         }\r
903         set{\r
904                 writer.NewLine = value;\r
905         }\r
906 }\r
907 \r
908 protected HtmlTextWriterTag TagKey { \r
909         get{\r
910                 return _tagKey;\r
911         }\r
912         set{\r
913                 _tagIndex = (int) value;\r
914                 if (_tagIndex < 0 || _tagIndex >= (int) HtmlTextWriter._tagNameLookupArray.Length)\r
915                         throw new ArgumentOutOfRangeException("value");\r
916                 _tagKey = value;\r
917                 if (value != 0)\r
918                         _tagName = HtmlTextWriter._tagNameLookupArray[_tagIndex].name;\r
919         }\r
920 }\r
921 \r
922 protected string TagName { \r
923         get{\r
924                 return _tagName;\r
925         }\r
926         set{\r
927                 _tagName = value;\r
928                 _tagKey = GetTagKey(_tagName);\r
929                 _tagIndex = (int) _tagKey;\r
930         }\r
931 }\r
932 \r
933 public const string DefaultTabString = "\t";\r
934 public const char DoubleQuoteChar = '"';\r
935 public const string EndTagLeftChars = "</";\r
936 public const char EqualsChar = '=';\r
937 public const string EqualsDoubleQuoteString = "=\"";\r
938 public const string SelfClosingChars = " /";\r
939 public const string SelfClosingTagEnd = " />";\r
940 public const char SemicolonChar = ';';\r
941 public const char SingleQuoteChar = '\'';\r
942 public const char SlashChar = '/';\r
943 public const char SpaceChar = ' ';\r
944 public const char StyleEqualsChar = ':';\r
945 public const char TagLeftChar = '<';\r
946 public const char TagRightChar = '>';\r
947 \r
948 private int _attrCount;\r
949 private int _endTagCount;\r
950 private int _styleCount;\r
951 private int indentLevel;\r
952 private int _inlineCount;\r
953 private int _tagIndex;\r
954 \r
955 private bool _isDescendant;\r
956 private bool tabsPending;\r
957 \r
958 private HtmlTextWriterTag _tagKey;\r
959 private TextWriter writer;\r
960 private HttpWriter _httpWriter;\r
961 \r
962 private static Hashtable _attrKeyLookupTable;\r
963 private static Hashtable _styleKeyLookupTable;\r
964 private static Hashtable _tagKeyLookupTable;\r
965 \r
966 private string _tagName;\r
967 private string tabString;\r
968 private static string[] _styleNameLookupArray;\r
969 \r
970 private RenderAttribute[] _attrList;\r
971 private static AttributeInformation[] _attrNameLookupArray;\r
972 private static TagInformation[] _tagNameLookupArray;\r
973 private TagStackEntry[] _endTags;\r
974 private RenderStyle[] _styleList;\r
975 \r
976 } //HtmlTextWriter\r
977 \r
978 struct AttributeInformation {\r
979         public bool encode;\r
980         public string name;\r
981 \r
982         public AttributeInformation(string name, bool encode){\r
983                 this.encode = encode;\r
984                 this.name = name;\r
985         }\r
986\r
987  \r
988 struct RenderAttribute {\r
989         public bool encode;\r
990         public HtmlTextWriterAttribute key;\r
991         public string name;\r
992         public string value;\r
993\r
994  \r
995 struct RenderStyle {\r
996         public HtmlTextWriterStyle key;\r
997         public string name;\r
998         public string value;\r
999\r
1000  \r
1001 struct TagInformation {\r
1002         public string closingTag;\r
1003         public string name;\r
1004         public TagType tagType;\r
1005 \r
1006         public TagInformation(string name, TagType tagType, string closingTag){\r
1007                 this.name = name;\r
1008                 this.tagType = tagType;\r
1009                 this.closingTag = closingTag;   \r
1010         }\r
1011\r
1012  \r
1013 struct TagStackEntry {\r
1014         public string endTagText;\r
1015         public HtmlTextWriterTag tagKey;\r
1016\r
1017  \r
1018 enum TagType {\r
1019         Inline,\r
1020         NonClosing,\r
1021         Other\r
1022\r
1023 \r
1024 \r
1025 } // namespace System.Web.UI.HtmlControls\r
1026 \r