perform case insensitive compare; return correct key in default case
[mono.git] / mcs / class / System.Web / System.Web.UI / HtmlTextWriter.cs
1 // 
2 // System.Web.UI.HtmlTextWriter
3 //
4 // Author:
5 //        Ben Maurer <bmaurer@novell.com>
6 //
7 // (c) 2005 Novell
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System.IO;
30 using System.Globalization;
31 using System.Collections;
32 using System.Security.Permissions;
33 using System.Text;
34
35 namespace System.Web.UI {
36         
37         // CAS
38         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
39         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
40         public class HtmlTextWriter : TextWriter {
41
42
43                 public HtmlTextWriter (TextWriter writer) : this (writer, DefaultTabString)
44                 {
45                 }
46         
47                 public HtmlTextWriter (TextWriter writer, string tabString)
48                 {
49                         if (writer == null)
50                                 throw new ArgumentNullException ();
51
52                         b = writer;
53                         tab_string = tabString;
54                 }
55
56                 internal static string StaticGetStyleName (System.Web.UI.HtmlTextWriterStyle styleKey) 
57                 {
58                         if ((int) styleKey < htmlstyles.Length)
59                                 return htmlstyles [(int) styleKey].name;
60
61                         return null;
62                 }
63                 
64                 [MonoTODO]
65                 protected static void RegisterAttribute (string name, HtmlTextWriterAttribute key)
66                 {
67                 }
68                 
69                 [MonoTODO]
70                 protected static void RegisterStyle (string name, HtmlTextWriterStyle key)
71                 {
72                 }
73                 
74                 [MonoTODO]
75                 protected static void RegisterTag (string name, HtmlTextWriterTag key)
76                 {
77                 }
78                 
79         
80                 public virtual void AddAttribute (HtmlTextWriterAttribute key, string value, bool fEncode)
81                 {
82                         if (fEncode)
83                                 value = EncodeAttributeValue (key, value);
84                         AddAttribute (GetAttributeName (key), value, key);
85                 }
86                 
87                 
88                 public virtual void AddAttribute (HtmlTextWriterAttribute key, string value)
89                 {
90                         AddAttribute (key, value, true);
91                 }
92         
93         
94                 public virtual void AddAttribute (string name, string value, bool fEncode)
95                 {
96                         if (fEncode)
97                                 value = HttpUtility.HtmlAttributeEncode (value);
98
99                         AddAttribute (name, value, GetAttributeKey (name));
100                 }
101                 
102                 public virtual void AddAttribute (string name, string value)
103                 {
104                         AddAttribute (name, value, true);
105                 }
106         
107                 protected virtual void AddAttribute (string name, string value, HtmlTextWriterAttribute key)
108                 {
109                         NextAttrStack ();
110                         attrs [attrs_pos].name = name;
111                         attrs [attrs_pos].value = value;
112                         attrs [attrs_pos].key = key;
113                 }
114                 
115                 
116                 protected virtual void AddStyleAttribute (string name, string value, HtmlTextWriterStyle key)
117                 {
118                         NextStyleStack ();
119                         styles [styles_pos].name = name;
120                         styles [styles_pos].value = value;
121                         styles [styles_pos].key = key;
122                 }
123                 
124
125                 public virtual void AddStyleAttribute (string name, string value)
126                 {
127                         AddStyleAttribute (name, value, GetStyleKey (name));
128                 }
129                 
130                 public virtual void AddStyleAttribute (HtmlTextWriterStyle key, string value)
131                 {
132                         AddStyleAttribute (GetStyleName (key), value, key);
133                 }
134         
135                 public override void Close ()
136                 {
137                         b.Close ();     
138                 }
139
140                 protected virtual string EncodeAttributeValue (HtmlTextWriterAttribute attrKey, string value)
141                 {
142                         return HttpUtility.HtmlEncode (value);
143                 }
144                 
145                 protected string EncodeAttributeValue (string value, bool fEncode)
146                 {
147                         if (fEncode)
148                                 return HttpUtility.HtmlEncode (value);
149                         return value;
150                 }
151                 
152                 protected string EncodeUrl (string url)
153                 {
154                         return HttpUtility.UrlPathEncode (url);
155                 }
156                 
157
158                 protected virtual void FilterAttributes ()
159                 {
160                         AddedAttr style_attr = new AddedAttr ();
161                         
162                         for (int i = 0; i <= attrs_pos; i ++) {
163                                 AddedAttr a = attrs [i];
164                                 if (OnAttributeRender (a.name, a.value, a.key)) {
165                                         if (a.key == HtmlTextWriterAttribute.Style) {
166                                                 style_attr = a;
167                                                 continue;
168                                         }
169                                         
170                                         WriteAttribute (a.name, a.value, false);
171                                 }
172                         }
173
174                         if (styles_pos != -1 || style_attr.value != null) {
175                                 Write (SpaceChar);
176                                 Write ("style");
177                                 Write (EqualsDoubleQuoteString);
178                                 
179                                 
180                                 for (int i = 0; i <= styles_pos; i ++) {
181                                         AddedStyle a = styles [i];
182                                         if (OnStyleAttributeRender (a.name, a.value, a.key))
183                                                 WriteStyleAttribute (a.name, a.value, false);
184                                 }
185
186                                 Write (style_attr.value);                               
187                                 Write (DoubleQuoteChar);
188                         }
189
190                         styles_pos = attrs_pos = -1;
191                 }
192         
193                 public override void Flush ()
194                 {
195                         b.Flush ();
196                 }
197
198                 [MonoTODO]
199                 protected HtmlTextWriterAttribute GetAttributeKey (string attrName)
200                 {
201                         // I don't think we want to binary search
202                         // because there might be something added to
203                         // the enum later. Do we really need anything
204                         // faster than a linear search?
205                         
206                         foreach (HtmlAttribute t in htmlattrs) {
207                                 if (String.Compare(t.name, attrName, true, CultureInfo.InvariantCulture) == 0)
208                                         return t.key;
209                         }
210
211                         return (HtmlTextWriterAttribute)(-1);           
212                 }
213
214                 [MonoTODO]
215                 protected string GetAttributeName (HtmlTextWriterAttribute attrKey)
216                 {
217                         if ((int) attrKey < htmlattrs.Length)
218                                 return htmlattrs [(int) attrKey].name;
219
220                         return null;
221                 }
222                 
223                 [MonoTODO]
224                 protected HtmlTextWriterStyle GetStyleKey (string styleName)
225                 {
226                         // I don't think we want to binary search
227                         // because there might be something added to
228                         // the enum later. Do we really need anything
229                         // faster than a linear search?
230                         
231                         foreach (HtmlStyle t in htmlstyles) {
232                                 if (String.Compare(t.name, styleName, true, CultureInfo.InvariantCulture) == 0)
233                                         return t.key;
234                         }
235
236                         return (HtmlTextWriterStyle)(-1);                       
237                 }
238                 
239                 [MonoTODO]
240                 protected string GetStyleName (HtmlTextWriterStyle styleKey)
241                 {
242                         return StaticGetStyleName (styleKey);
243                 }
244                 
245                 [MonoTODO]
246                 protected virtual HtmlTextWriterTag GetTagKey (string tagName) 
247                 {
248                         // I don't think we want to binary search
249                         // because there might be something added to
250                         // the enum later. Do we really need anything
251                         // faster than a linear search?
252                         
253                         foreach (HtmlTag t in tags) {
254                                 if (String.Compare(t.name, tagName, true, CultureInfo.InvariantCulture) == 0)
255                                         return t.key;
256                         }
257
258                         return HtmlTextWriterTag.Unknown;
259                 }
260
261                 internal static string StaticGetTagName (HtmlTextWriterTag tagKey)
262                 {
263                         if ((int) tagKey < tags.Length)
264                                 return tags [(int) tagKey].name;
265
266                         return null;    
267                 }
268                 
269                 
270                 [MonoTODO]
271                 protected virtual string GetTagName (HtmlTextWriterTag tagKey)
272                 {
273                         if ((int) tagKey < tags.Length)
274                                 return tags [(int) tagKey].name;
275
276                         return null;
277                 }
278                 
279                 protected bool IsAttributeDefined (HtmlTextWriterAttribute key)
280                 {
281                         string value;
282                         return IsAttributeDefined (key, out value);
283                 }
284         
285                 protected bool IsAttributeDefined (HtmlTextWriterAttribute key, out string value)
286                 {
287                         for (int i = 0; i <= attrs_pos; i ++)
288                                 if (attrs [i].key == key){
289                                         value = attrs [i].value;
290                                         return true;
291                                 }
292
293                         value = null;
294                         return false;
295                 }
296                 
297                 protected bool IsStyleAttributeDefined (HtmlTextWriterStyle key)
298                 {
299                         string value;
300                         return IsStyleAttributeDefined (key, out value);
301                 }
302         
303                 protected bool IsStyleAttributeDefined (HtmlTextWriterStyle key, out string value)
304                 {
305                         for (int i = 0; i <= styles_pos; i ++)
306                                 if (styles [i].key == key){
307                                         value = styles [i].value;
308                                         return true;
309                                 }
310
311                         value = null;
312                         return false;
313                 }
314                 
315                 protected virtual bool OnAttributeRender (string name, string value, HtmlTextWriterAttribute key)
316                 {
317                         return true;
318                 }
319                 
320                 protected virtual bool OnStyleAttributeRender (string name, string value, HtmlTextWriterStyle key)
321                 {
322                         return true;
323                 }
324                 
325                 protected virtual bool OnTagRender (string name, HtmlTextWriterTag key)
326                 {
327                         return true;
328                 }
329                 
330         
331                 protected virtual void OutputTabs ()
332                 {
333                         if (! newline)
334                                 return;
335                         newline = false;
336                         
337                         for (int i = 0; i < Indent; i ++)
338                                 b.Write (tab_string);
339                 }
340         
341
342                         
343                 protected string PopEndTag ()
344                 {
345                         if (tagstack_pos == -1)
346                                 throw new InvalidOperationException ();
347                         
348                         string s = TagName;
349                         tagstack_pos --;
350                         return s;
351                 }
352                 
353                 protected void PushEndTag (string endTag)
354                 {
355                         NextTagStack ();
356                         TagName = endTag;
357                 }
358
359                 void PushEndTag (HtmlTextWriterTag t)
360                 {
361                         NextTagStack ();
362                         TagKey = t;
363                 }
364                 
365
366                 protected virtual string RenderAfterContent ()
367                 {
368                         return null;
369                 }
370                 
371                 protected virtual string RenderAfterTag ()
372                 {
373                         return null;
374                 }
375                 
376                 protected virtual string RenderBeforeContent ()
377                 {
378                         return null;
379                 }
380                         
381                 protected virtual string RenderBeforeTag ()
382                 {
383                         return null;
384                 }
385
386                 public virtual void RenderBeginTag (string tagName)
387                 {
388                         if (! OnTagRender (tagName, GetTagKey (tagName)))
389                                 return;
390
391                         PushEndTag (tagName);
392                         
393                         DoBeginTag ();
394                 }
395                 
396                 public virtual void RenderBeginTag (HtmlTextWriterTag tagKey)
397                 {
398                         if (! OnTagRender (GetTagName (tagKey), tagKey))
399                                 return;
400
401                         PushEndTag (tagKey);
402
403                         DoBeginTag ();
404                 }
405
406                 void WriteIfNotNull (string s)
407                 {
408                         if (s != null)
409                                 Write (s);
410                 }
411                 
412
413                 void DoBeginTag ()
414                 {
415                         WriteIfNotNull (RenderBeforeTag ());
416                         WriteBeginTag (TagName);
417                         FilterAttributes ();
418
419                         HtmlTextWriterTag key = (int) TagKey < tags.Length ? TagKey : HtmlTextWriterTag.Unknown;
420
421                         switch (tags [(int) key].tag_type) {
422                         case TagType.Inline:
423                                 Write (TagRightChar);
424                                 break;
425                         case TagType.Block:
426                                 Write (TagRightChar);
427                                 WriteLine ();
428                                 Indent ++;
429                                 break;
430                         case TagType.SelfClosing:
431                                 Write (SelfClosingTagEnd);
432                                 break;
433                         }
434                         
435                         // FIXME what do i do for self close here?
436                         WriteIfNotNull (RenderBeforeContent ());
437                 }
438                 
439
440                 public virtual void RenderEndTag ()
441                 {
442                         // FIXME what do i do for self close here?
443                         WriteIfNotNull (RenderAfterContent ());
444                         
445                         HtmlTextWriterTag key = (int) TagKey < tags.Length ? TagKey : HtmlTextWriterTag.Unknown;
446
447                         switch (tags [(int) key].tag_type) {
448                         case TagType.Inline:
449                                 WriteEndTag (TagName);
450                                 break;
451                         case TagType.Block:
452                                 Indent --;
453                                 WriteLineNoTabs ("");
454                                 WriteEndTag (TagName);
455                                 
456                                 break;
457                         case TagType.SelfClosing:
458                                 // NADA
459                                 break;
460                         }
461                         WriteIfNotNull (RenderAfterTag ());
462
463                         PopEndTag ();
464                 }
465                 
466
467                 public virtual void WriteAttribute (string name, string value, bool fEncode)
468                 {
469                         Write (SpaceChar);
470                         Write (name);
471                         if (value != null) {
472                                 Write (EqualsDoubleQuoteString);
473                                 value = EncodeAttributeValue (value, fEncode);
474                                 Write (value);
475                                 Write (DoubleQuoteChar);
476                         }
477                 }
478                 
479         
480                 public virtual void WriteBeginTag (string tagName)
481                 {
482                         Write (TagLeftChar);
483                         Write (tagName);
484                 }
485                 
486                 public virtual void WriteEndTag (string tagName)
487                 {
488                         Write (EndTagLeftChars);
489                         Write (tagName);
490                         Write (TagRightChar);   
491                 }
492                 
493                 public virtual void WriteFullBeginTag (string tagName)
494                 {
495                         Write (TagLeftChar);
496                         Write (tagName);
497                         Write (TagRightChar);
498                 }
499                         
500                 public virtual void WriteStyleAttribute (string name, string value)
501                 {
502                         WriteStyleAttribute (name, value, true);
503                 }
504
505                 public virtual void WriteStyleAttribute (string name, string value, bool fEncode)
506                 {
507 #if NET_2_0
508                         if (name == "background-image") {
509                                 value = String.Concat ("url(", value, ")");
510                         }
511 #endif
512                         Write (name);
513                         Write (StyleEqualsChar);
514                         Write (EncodeAttributeValue (value, fEncode));
515                         Write (SemicolonChar);
516                 }
517                 
518                 public override void Write (char [] buffer, int index, int count)
519                 {
520                         OutputTabs ();
521                         b.Write (buffer, index, count);
522                 }
523         
524                 public override void Write (double value)
525                 {
526                         OutputTabs ();
527                         b.Write (value);
528                 }
529         
530                 public override void Write (char value)
531                 {
532                         OutputTabs ();
533                         b.Write (value);
534                 }
535         
536                 public override void Write (char [] buffer)
537                 {
538                         OutputTabs ();
539                         b.Write (buffer);
540                 }
541         
542                 public override void Write (int value)
543                 {
544                         OutputTabs ();
545                         b.Write (value);
546                 }
547         
548                 public override void Write (string format, object arg0)
549                 {
550                         OutputTabs ();
551                         b.Write (format, arg0);
552                 }
553         
554                 public override void Write (string format, object arg0, object arg1)
555                 {
556                         OutputTabs ();
557                         b.Write (format, arg0, arg1);
558                 }
559         
560                 public override void Write (string format, params object [] args)
561                 {
562                         OutputTabs ();
563                         b.Write (format, args);
564                 }
565
566                 public override void Write (string s)
567                 {
568                         OutputTabs ();
569                         b.Write (s);
570                 }
571                 
572                 public override void Write (long value)
573                 {
574                         OutputTabs ();
575                         b.Write (value);
576                 }
577         
578                 public override void Write (object value)
579                 {
580                         OutputTabs ();
581                         b.Write (value);
582                 }
583                 
584                 public override void Write (float value)
585                 {
586                         OutputTabs ();
587                         b.Write (value);
588                 }
589         
590                 public override void Write (bool value)
591                 {
592                         OutputTabs ();
593                         b.Write (value);
594                 }
595         
596                 public virtual void WriteAttribute (string name, string value)
597                 {
598                         WriteAttribute (name, value, true);
599                 }
600
601                 public override void WriteLine (char value)
602                 {
603                         OutputTabs ();
604                         b.WriteLine (value);
605                         newline = true;
606                 }
607         
608                 public override void WriteLine (long value)
609                 {
610                         OutputTabs ();
611                         b.WriteLine (value);
612                         newline = true;
613                 }
614         
615                 public override void WriteLine (object value)
616                 {
617                         OutputTabs ();
618                         b.WriteLine (value);
619                         newline = true; 
620                 }
621         
622                 public override void WriteLine (double value)
623                 {
624                         OutputTabs ();
625                         b.WriteLine (value);
626                         newline = true;
627                 }
628         
629                 public override void WriteLine (char [] buffer, int index, int count)
630                 {
631                         OutputTabs ();
632                         b.WriteLine (buffer, index, count);
633                         newline = true;
634                 }
635         
636                 public override void WriteLine (char [] buffer)
637                 {
638                         OutputTabs ();
639                         b.WriteLine (buffer);
640                         newline = true;
641                 }
642                 
643                 public override void WriteLine (bool value)
644                 {
645                         OutputTabs ();
646                         b.WriteLine (value);
647                         newline = true;
648                 }
649         
650                 public override void WriteLine ()
651                 {
652                         OutputTabs ();
653                         b.WriteLine ();
654                         newline = true;
655                 }
656         
657                 public override void WriteLine (int value)
658                 {
659                         OutputTabs ();
660                         b.WriteLine (value);
661                         newline = true;
662                 }
663         
664                 public override void WriteLine (string format, object arg0, object arg1)
665                 {
666                         OutputTabs ();
667                         b.WriteLine (format, arg0, arg1);
668                         newline = true;
669                 }
670         
671                 public override void WriteLine (string format, object arg0)
672                 {
673                         OutputTabs ();
674                         b.WriteLine (format, arg0);
675                         newline = true;
676                 }
677         
678                 public override void WriteLine (string format, params object [] args)
679                 {
680                         OutputTabs ();
681                         b.WriteLine (format, args);
682                         newline = true;
683                 }
684                 
685                 [CLSCompliant (false)]
686                 public override void WriteLine (uint value)
687                 {
688                         OutputTabs ();
689                         b.WriteLine (value);
690                         newline = true;
691                 }
692         
693                 public override void WriteLine (string s)
694                 {
695                         OutputTabs ();
696                         b.WriteLine (s);
697                         newline = true;
698                 }
699         
700                 public override void WriteLine (float value)
701                 {
702                         OutputTabs ();
703                         b.WriteLine (value);
704                         newline = true;
705                 }
706         
707                 public void WriteLineNoTabs (string s)
708                 {
709                         b.WriteLine (s);
710                         newline = true;
711                 }
712
713                 public override Encoding Encoding {
714                         get {
715                                 return b.Encoding;      
716                         }
717                 }
718
719                 int indent;
720                 public int Indent {
721                         get {
722                                 return indent;
723                         }
724                         set {
725                                 indent = value;
726                         }
727                 }
728         
729                 public System.IO.TextWriter InnerWriter {
730                         get {
731                                 return b;
732                         }
733                         set {
734                                 b = value;
735                         }       
736                 }
737         
738                 public override string NewLine {
739                         get {
740                                 return b.NewLine;
741                         }
742                         set {
743                                 b.NewLine = value;
744                         }
745                 }
746         
747                 protected HtmlTextWriterTag TagKey {
748                         get {
749                                 if (tagstack_pos == -1)
750                                         throw new InvalidOperationException ();
751
752                                 return tagstack [tagstack_pos].key;
753                         }
754                         set {
755                                 tagstack [tagstack_pos].key = value;
756                                 tagstack [tagstack_pos].name = GetTagName (value);
757                         }
758                 }
759         
760                 protected string TagName {
761                         get {
762                                 if (tagstack_pos == -1)
763                                         throw new InvalidOperationException ();
764                                 
765                                 return tagstack [tagstack_pos].name;
766                         }
767                         set {
768                                 tagstack [tagstack_pos].name = value;
769                                 tagstack [tagstack_pos].key = GetTagKey (value);
770                                 if (tagstack [tagstack_pos].key != HtmlTextWriterTag.Unknown)
771                                         tagstack [tagstack_pos].name = GetTagName (tagstack [tagstack_pos].key);
772                         }
773                 }
774                 
775
776                 TextWriter b;
777                 string tab_string;
778                 bool newline;
779                 
780                 //
781                 // These emulate generic Stack <T>, since we can't use that ;-(. _pos is the current
782                 // element.IE, you edit blah [blah_pos]. I *really* want generics, sigh.
783                 //
784                 AddedStyle [] styles;
785                 AddedAttr [] attrs;
786                 AddedTag [] tagstack;
787
788                 int styles_pos = -1, attrs_pos = -1, tagstack_pos = -1;
789                 
790                 struct AddedTag {
791                         public string name;
792                         public HtmlTextWriterTag key;
793                 }
794                 
795                 struct AddedStyle {
796                         public string name;
797                         public HtmlTextWriterStyle key;
798                         public string value;
799                 }
800                 
801                 struct AddedAttr {
802                         public string name;
803                         public HtmlTextWriterAttribute key;
804                         public string value;
805                 }
806
807                 void NextStyleStack ()
808                 {
809                         if (styles == null)
810                                 styles = new AddedStyle [16];
811                                 
812                         if (++styles_pos < styles.Length)
813                                 return;
814                         
815                         int nsize = styles.Length * 2;
816                         AddedStyle [] ncontents = new AddedStyle [nsize];
817
818                         Array.Copy (styles, ncontents, styles.Length);
819                         styles = ncontents;
820                 }
821
822                 void NextAttrStack ()
823                 {
824                         if (attrs == null)
825                                 attrs = new AddedAttr [16];
826                                 
827                         if (++attrs_pos < attrs.Length)
828                                 return;
829                         
830                         int nsize = attrs.Length * 2;
831                         AddedAttr [] ncontents = new AddedAttr [nsize];
832
833                         Array.Copy (attrs, ncontents, attrs.Length);
834                         attrs = ncontents;
835                 }
836
837                 void NextTagStack ()
838                 {
839                         if (tagstack == null)
840                                 tagstack = new AddedTag [16];
841                                 
842                         if (++tagstack_pos < tagstack.Length)
843                                 return;
844                                                 
845                         int nsize = tagstack.Length * 2;
846                         AddedTag [] ncontents = new AddedTag [nsize];
847
848                         Array.Copy (tagstack, ncontents, tagstack.Length);
849                         tagstack = ncontents;
850                 }
851         
852                 public const string DefaultTabString = "\t";
853                 public const char DoubleQuoteChar = '"';
854                 public const string EndTagLeftChars = "</";
855                 public const char EqualsChar = '=';
856                 public const string EqualsDoubleQuoteString = "=\"";
857                 public const string SelfClosingChars = " /";
858                 public const string SelfClosingTagEnd = " />";
859                 public const char SemicolonChar = ';';
860                 public const char SingleQuoteChar = '\'';
861                 public const char SlashChar = '/';
862                 public const char SpaceChar = ' ' ;
863                 public const char StyleEqualsChar = ':';
864                 public const char TagLeftChar = '<';
865                 public const char TagRightChar = '>';
866
867                 enum TagType {
868                         Block,
869                         Inline,
870                         SelfClosing,
871                 }
872                 
873                 
874                 struct HtmlTag {
875                         public HtmlTextWriterTag key;
876                         public string name;
877                         public TagType tag_type;
878
879                         public HtmlTag (HtmlTextWriterTag k, string n, TagType tt)
880                         {
881                                 key = k;
882                                 name = n;
883                                 tag_type = tt;
884                         }
885                 }
886
887                 struct HtmlStyle {
888                         public HtmlTextWriterStyle key;
889                         public string name;
890                         
891                         public HtmlStyle (HtmlTextWriterStyle k, string n)
892                         {
893                                 key = k;
894                                 name = n;
895                         }
896                 }
897
898                 
899                 struct HtmlAttribute {
900                         public HtmlTextWriterAttribute key;
901                         public string name;
902
903                         public HtmlAttribute (HtmlTextWriterAttribute k, string n)
904                         {
905                                 key = k;
906                                 name = n;
907                         }
908                 }
909                 
910                 static HtmlTag [] tags = {
911                         new HtmlTag (HtmlTextWriterTag.Unknown,    "",                  TagType.Block),
912                         new HtmlTag (HtmlTextWriterTag.A,          "a",                 TagType.Inline),
913                         new HtmlTag (HtmlTextWriterTag.Acronym,    "acronym",           TagType.Inline),
914                         new HtmlTag (HtmlTextWriterTag.Address,    "address",           TagType.Block),
915                         new HtmlTag (HtmlTextWriterTag.Area,       "area",              TagType.Block),
916                         new HtmlTag (HtmlTextWriterTag.B,          "b",                 TagType.Inline),
917                         new HtmlTag (HtmlTextWriterTag.Base,       "base",              TagType.SelfClosing),
918                         new HtmlTag (HtmlTextWriterTag.Basefont,   "basefont",          TagType.SelfClosing),
919                         new HtmlTag (HtmlTextWriterTag.Bdo,        "bdo",               TagType.Inline),
920                         new HtmlTag (HtmlTextWriterTag.Bgsound,    "bgsound",           TagType.SelfClosing),
921                         new HtmlTag (HtmlTextWriterTag.Big,        "big",               TagType.Inline),
922                         new HtmlTag (HtmlTextWriterTag.Blockquote, "blockquote",        TagType.Block),
923                         new HtmlTag (HtmlTextWriterTag.Body,       "body",              TagType.Block),
924                         new HtmlTag (HtmlTextWriterTag.Br,         "br",                TagType.Block),
925                         new HtmlTag (HtmlTextWriterTag.Button,     "button",            TagType.Inline),
926                         new HtmlTag (HtmlTextWriterTag.Caption,    "caption",           TagType.Block),
927                         new HtmlTag (HtmlTextWriterTag.Center,     "center",            TagType.Block),
928                         new HtmlTag (HtmlTextWriterTag.Cite,       "cite",              TagType.Inline),
929                         new HtmlTag (HtmlTextWriterTag.Code,       "code",              TagType.Inline),
930                         new HtmlTag (HtmlTextWriterTag.Col,        "col",               TagType.SelfClosing),
931                         new HtmlTag (HtmlTextWriterTag.Colgroup,   "colgroup",          TagType.Block),
932                         new HtmlTag (HtmlTextWriterTag.Dd,         "dd",                TagType.Inline),
933                         new HtmlTag (HtmlTextWriterTag.Del,        "del",               TagType.Inline),
934                         new HtmlTag (HtmlTextWriterTag.Dfn,        "dfn",               TagType.Inline),
935                         new HtmlTag (HtmlTextWriterTag.Dir,        "dir",               TagType.Block),
936                         new HtmlTag (HtmlTextWriterTag.Div,        "div",               TagType.Block),
937                         new HtmlTag (HtmlTextWriterTag.Dl,         "dl",                TagType.Block),
938                         new HtmlTag (HtmlTextWriterTag.Dt,         "dt",                TagType.Inline),
939                         new HtmlTag (HtmlTextWriterTag.Em,         "em",                TagType.Inline),
940                         new HtmlTag (HtmlTextWriterTag.Embed,      "embed",             TagType.SelfClosing),
941                         new HtmlTag (HtmlTextWriterTag.Fieldset,   "fieldset",          TagType.Block),
942                         new HtmlTag (HtmlTextWriterTag.Font,       "font",              TagType.Inline),
943                         new HtmlTag (HtmlTextWriterTag.Form,       "form",              TagType.Block),
944                         new HtmlTag (HtmlTextWriterTag.Frame,      "frame",             TagType.SelfClosing),
945                         new HtmlTag (HtmlTextWriterTag.Frameset,   "frameset",          TagType.Block),
946                         new HtmlTag (HtmlTextWriterTag.H1,         "h1",                TagType.Block),
947                         new HtmlTag (HtmlTextWriterTag.H2,         "h2",                TagType.Block),
948                         new HtmlTag (HtmlTextWriterTag.H3,         "h3",                TagType.Block),
949                         new HtmlTag (HtmlTextWriterTag.H4,         "h4",                TagType.Block),
950                         new HtmlTag (HtmlTextWriterTag.H5,         "h5",                TagType.Block),
951                         new HtmlTag (HtmlTextWriterTag.H6,         "h6",                TagType.Block),
952                         new HtmlTag (HtmlTextWriterTag.Head,       "head",              TagType.Block),
953                         new HtmlTag (HtmlTextWriterTag.Hr,         "hr",                TagType.SelfClosing),
954                         new HtmlTag (HtmlTextWriterTag.Html,       "html",              TagType.Block),
955                         new HtmlTag (HtmlTextWriterTag.I,          "i",                 TagType.Inline),
956                         new HtmlTag (HtmlTextWriterTag.Iframe,     "iframe",            TagType.Block),
957                         new HtmlTag (HtmlTextWriterTag.Img,        "img",               TagType.SelfClosing),
958                         new HtmlTag (HtmlTextWriterTag.Input,      "input",             TagType.SelfClosing),
959                         new HtmlTag (HtmlTextWriterTag.Ins,        "ins",               TagType.Inline),
960                         new HtmlTag (HtmlTextWriterTag.Isindex,    "isindex",           TagType.SelfClosing),
961                         new HtmlTag (HtmlTextWriterTag.Kbd,        "kbd",               TagType.Inline),
962                         new HtmlTag (HtmlTextWriterTag.Label,      "label",             TagType.Inline),
963                         new HtmlTag (HtmlTextWriterTag.Legend,     "legend",            TagType.Block),
964                         new HtmlTag (HtmlTextWriterTag.Li,         "li",                TagType.Inline),
965                         new HtmlTag (HtmlTextWriterTag.Link,       "link",              TagType.SelfClosing),
966                         new HtmlTag (HtmlTextWriterTag.Map,        "map",               TagType.Block),
967                         new HtmlTag (HtmlTextWriterTag.Marquee,    "marquee",           TagType.Block),
968                         new HtmlTag (HtmlTextWriterTag.Menu,       "menu",              TagType.Block),
969                         new HtmlTag (HtmlTextWriterTag.Meta,       "meta",              TagType.SelfClosing),
970                         new HtmlTag (HtmlTextWriterTag.Nobr,       "nobr",              TagType.Inline),
971                         new HtmlTag (HtmlTextWriterTag.Noframes,   "noframes",          TagType.Block),
972                         new HtmlTag (HtmlTextWriterTag.Noscript,   "noscript",          TagType.Block),
973                         new HtmlTag (HtmlTextWriterTag.Object,     "object",            TagType.Block),
974                         new HtmlTag (HtmlTextWriterTag.Ol,         "ol",                TagType.Block),
975                         new HtmlTag (HtmlTextWriterTag.Option,     "option",            TagType.Block),
976                         new HtmlTag (HtmlTextWriterTag.P,          "p",                 TagType.Inline),
977                         new HtmlTag (HtmlTextWriterTag.Param,      "param",             TagType.Block),
978                         new HtmlTag (HtmlTextWriterTag.Pre,        "pre",               TagType.Block),
979                         new HtmlTag (HtmlTextWriterTag.Q,          "q",                 TagType.Inline),
980                         new HtmlTag (HtmlTextWriterTag.Rt,         "rt",                TagType.Block),
981                         new HtmlTag (HtmlTextWriterTag.Ruby,       "ruby",              TagType.Block),
982                         new HtmlTag (HtmlTextWriterTag.S,          "s",                 TagType.Inline),
983                         new HtmlTag (HtmlTextWriterTag.Samp,       "samp",              TagType.Inline),
984                         new HtmlTag (HtmlTextWriterTag.Script,     "script",            TagType.Block),
985                         new HtmlTag (HtmlTextWriterTag.Select,     "select",            TagType.Block),
986                         new HtmlTag (HtmlTextWriterTag.Small,      "small",             TagType.Block),
987                         new HtmlTag (HtmlTextWriterTag.Span,       "span",              TagType.Inline),
988                         new HtmlTag (HtmlTextWriterTag.Strike,     "strike",            TagType.Inline),
989                         new HtmlTag (HtmlTextWriterTag.Strong,     "strong",            TagType.Inline),
990                         new HtmlTag (HtmlTextWriterTag.Style,      "style",             TagType.Block),
991                         new HtmlTag (HtmlTextWriterTag.Sub,        "sub",               TagType.Inline),
992                         new HtmlTag (HtmlTextWriterTag.Sup,        "sup",               TagType.Inline),
993                         new HtmlTag (HtmlTextWriterTag.Table,      "table",             TagType.Block),
994                         new HtmlTag (HtmlTextWriterTag.Tbody,      "tbody",             TagType.Block),
995                         new HtmlTag (HtmlTextWriterTag.Td,         "td",                TagType.Inline),
996                         new HtmlTag (HtmlTextWriterTag.Textarea,   "textarea",          TagType.Inline),
997                         new HtmlTag (HtmlTextWriterTag.Tfoot,      "tfoot",             TagType.Block),
998                         new HtmlTag (HtmlTextWriterTag.Th,         "th",                TagType.Inline),
999                         new HtmlTag (HtmlTextWriterTag.Thead,      "thead",             TagType.Block),
1000                         new HtmlTag (HtmlTextWriterTag.Title,      "title",             TagType.Block),
1001                         new HtmlTag (HtmlTextWriterTag.Tr,         "tr",                TagType.Block),
1002                         new HtmlTag (HtmlTextWriterTag.Tt,         "tt",                TagType.Inline),
1003                         new HtmlTag (HtmlTextWriterTag.U,          "u",                 TagType.Inline),
1004                         new HtmlTag (HtmlTextWriterTag.Ul,         "ul",                TagType.Block),
1005                         new HtmlTag (HtmlTextWriterTag.Var,        "var",               TagType.Inline),
1006                         new HtmlTag (HtmlTextWriterTag.Wbr,        "wbr",               TagType.SelfClosing),
1007                         new HtmlTag (HtmlTextWriterTag.Xml,        "xml",               TagType.Block),
1008                 };
1009
1010                 static HtmlAttribute [] htmlattrs = {
1011                         new HtmlAttribute (HtmlTextWriterAttribute.Accesskey,         "accesskey"),
1012                         new HtmlAttribute (HtmlTextWriterAttribute.Align,             "align"),
1013                         new HtmlAttribute (HtmlTextWriterAttribute.Alt,               "alt"),
1014                         new HtmlAttribute (HtmlTextWriterAttribute.Background,        "background"),
1015                         new HtmlAttribute (HtmlTextWriterAttribute.Bgcolor,           "bgcolor"),
1016                         new HtmlAttribute (HtmlTextWriterAttribute.Border,            "border"),
1017                         new HtmlAttribute (HtmlTextWriterAttribute.Bordercolor,       "bordercolor"),
1018                         new HtmlAttribute (HtmlTextWriterAttribute.Cellpadding,       "cellpadding"),
1019                         new HtmlAttribute (HtmlTextWriterAttribute.Cellspacing,       "cellspacing"),
1020                         new HtmlAttribute (HtmlTextWriterAttribute.Checked,           "checked"),
1021                         new HtmlAttribute (HtmlTextWriterAttribute.Class,             "class"),
1022                         new HtmlAttribute (HtmlTextWriterAttribute.Cols,              "cols"),
1023                         new HtmlAttribute (HtmlTextWriterAttribute.Colspan,           "colspan"),
1024                         new HtmlAttribute (HtmlTextWriterAttribute.Disabled,          "disabled"),
1025                         new HtmlAttribute (HtmlTextWriterAttribute.For,               "for"),
1026                         new HtmlAttribute (HtmlTextWriterAttribute.Height,            "height"),
1027                         new HtmlAttribute (HtmlTextWriterAttribute.Href,              "href"),
1028                         new HtmlAttribute (HtmlTextWriterAttribute.Id,                "id"),
1029                         new HtmlAttribute (HtmlTextWriterAttribute.Maxlength,         "maxlength"),
1030                         new HtmlAttribute (HtmlTextWriterAttribute.Multiple,          "multiple"),
1031                         new HtmlAttribute (HtmlTextWriterAttribute.Name,              "name"),
1032                         new HtmlAttribute (HtmlTextWriterAttribute.Nowrap,            "nowrap"),
1033                         new HtmlAttribute (HtmlTextWriterAttribute.Onchange,          "onchange"),
1034                         new HtmlAttribute (HtmlTextWriterAttribute.Onclick,           "onclick"),
1035                         new HtmlAttribute (HtmlTextWriterAttribute.ReadOnly,          "readonly"),
1036                         new HtmlAttribute (HtmlTextWriterAttribute.Rows,              "rows"),
1037                         new HtmlAttribute (HtmlTextWriterAttribute.Rowspan,           "rowspan"),
1038                         new HtmlAttribute (HtmlTextWriterAttribute.Rules,             "rules"),
1039                         new HtmlAttribute (HtmlTextWriterAttribute.Selected,          "selected"),
1040                         new HtmlAttribute (HtmlTextWriterAttribute.Size,              "size"),
1041                         new HtmlAttribute (HtmlTextWriterAttribute.Src,               "src"),
1042                         new HtmlAttribute (HtmlTextWriterAttribute.Style,             "style"),
1043                         new HtmlAttribute (HtmlTextWriterAttribute.Tabindex,          "tabindex"),
1044                         new HtmlAttribute (HtmlTextWriterAttribute.Target,            "target"),
1045                         new HtmlAttribute (HtmlTextWriterAttribute.Title,             "title"),
1046                         new HtmlAttribute (HtmlTextWriterAttribute.Type,              "type"),
1047                         new HtmlAttribute (HtmlTextWriterAttribute.Valign,            "valign"),
1048                         new HtmlAttribute (HtmlTextWriterAttribute.Value,             "value"),
1049                         new HtmlAttribute (HtmlTextWriterAttribute.Width,             "width"),
1050                         new HtmlAttribute (HtmlTextWriterAttribute.Wrap,              "wrap"),
1051 #if NET_2_0
1052                         new HtmlAttribute (HtmlTextWriterAttribute.Abbr,              "abbr"),
1053                         new HtmlAttribute (HtmlTextWriterAttribute.AutoComplete,      "autocomplete"),
1054                         new HtmlAttribute (HtmlTextWriterAttribute.Axis,              "axis"),
1055                         new HtmlAttribute (HtmlTextWriterAttribute.Content,           "content"),
1056                         new HtmlAttribute (HtmlTextWriterAttribute.Coords,            "coords"),
1057                         new HtmlAttribute (HtmlTextWriterAttribute.DesignerRegion,    "_designerregion"),
1058                         new HtmlAttribute (HtmlTextWriterAttribute.Dir,               "dir"),
1059                         new HtmlAttribute (HtmlTextWriterAttribute.Headers,           "headers"),
1060                         new HtmlAttribute (HtmlTextWriterAttribute.Longdesc,          "longdesc"),
1061                         new HtmlAttribute (HtmlTextWriterAttribute.Rel,               "rel"),
1062                         new HtmlAttribute (HtmlTextWriterAttribute.Scope,             "scope"),
1063                         new HtmlAttribute (HtmlTextWriterAttribute.Shape,             "shape"),
1064                         new HtmlAttribute (HtmlTextWriterAttribute.Usemap,            "usemap"),
1065                         new HtmlAttribute (HtmlTextWriterAttribute.VCardName,         "vcard_name"),
1066 #endif
1067                 };
1068
1069                 static HtmlStyle [] htmlstyles = {
1070                         new HtmlStyle (HtmlTextWriterStyle.BackgroundColor,    "background-color"),
1071                         new HtmlStyle (HtmlTextWriterStyle.BackgroundImage,    "background-image"),
1072                         new HtmlStyle (HtmlTextWriterStyle.BorderCollapse,     "border-collapse"),
1073                         new HtmlStyle (HtmlTextWriterStyle.BorderColor,        "border-color"),
1074                         new HtmlStyle (HtmlTextWriterStyle.BorderStyle,        "border-style"),
1075                         new HtmlStyle (HtmlTextWriterStyle.BorderWidth,        "border-width"),
1076                         new HtmlStyle (HtmlTextWriterStyle.Color,              "color"),
1077                         new HtmlStyle (HtmlTextWriterStyle.FontFamily,         "font-family"),
1078                         new HtmlStyle (HtmlTextWriterStyle.FontSize,           "font-size"),
1079                         new HtmlStyle (HtmlTextWriterStyle.FontStyle,          "font-style"),
1080                         new HtmlStyle (HtmlTextWriterStyle.FontWeight,         "font-weight"),
1081                         new HtmlStyle (HtmlTextWriterStyle.Height,             "height"),
1082                         new HtmlStyle (HtmlTextWriterStyle.TextDecoration,     "text-decoration"),
1083                         new HtmlStyle (HtmlTextWriterStyle.Width,              "width"),
1084 #if NET_2_0
1085                         new HtmlStyle (HtmlTextWriterStyle.ListStyleImage,     "list-style-image"),
1086                         new HtmlStyle (HtmlTextWriterStyle.ListStyleType,      "list-style-type"),
1087                         new HtmlStyle (HtmlTextWriterStyle.Cursor,             "cursor"),
1088                         new HtmlStyle (HtmlTextWriterStyle.Direction,          "direction"),
1089                         new HtmlStyle (HtmlTextWriterStyle.Display,            "display"),
1090                         new HtmlStyle (HtmlTextWriterStyle.Filter,             "filter"),
1091                         new HtmlStyle (HtmlTextWriterStyle.FontVariant,        "font-variant"),
1092                         new HtmlStyle (HtmlTextWriterStyle.Left,               "left"),
1093                         new HtmlStyle (HtmlTextWriterStyle.Margin,             "margin"),
1094                         new HtmlStyle (HtmlTextWriterStyle.MarginBottom,       "margin-bottom"),
1095                         new HtmlStyle (HtmlTextWriterStyle.MarginLeft,         "margin-left"),
1096                         new HtmlStyle (HtmlTextWriterStyle.MarginRight,        "margin-right"),
1097                         new HtmlStyle (HtmlTextWriterStyle.MarginTop,          "margin-top"),
1098                         new HtmlStyle (HtmlTextWriterStyle.Overflow,           "overflow"),
1099                         new HtmlStyle (HtmlTextWriterStyle.OverflowX,          "overflow-x"),
1100                         new HtmlStyle (HtmlTextWriterStyle.OverflowY,          "overflow-y"),
1101                         new HtmlStyle (HtmlTextWriterStyle.Padding,            "padding"),
1102                         new HtmlStyle (HtmlTextWriterStyle.PaddingBottom,      "padding-bottom"),
1103                         new HtmlStyle (HtmlTextWriterStyle.PaddingLeft,        "padding-left"),
1104                         new HtmlStyle (HtmlTextWriterStyle.PaddingRight,       "padding-right"),
1105                         new HtmlStyle (HtmlTextWriterStyle.PaddingTop,         "padding-top"),
1106                         new HtmlStyle (HtmlTextWriterStyle.Position,           "position"),
1107                         new HtmlStyle (HtmlTextWriterStyle.TextAlign,          "text-align"),
1108                         new HtmlStyle (HtmlTextWriterStyle.VerticalAlign,      "vertical-align"),
1109                         new HtmlStyle (HtmlTextWriterStyle.TextOverflow,       "text-overflow"),
1110                         new HtmlStyle (HtmlTextWriterStyle.Top,                "top"),
1111                         new HtmlStyle (HtmlTextWriterStyle.Visibility,         "visibility"),
1112                         new HtmlStyle (HtmlTextWriterStyle.WhiteSpace,         "white-space"),
1113                         new HtmlStyle (HtmlTextWriterStyle.ZIndex,             "z-index"),
1114 #endif
1115                 };
1116         }
1117 }