Back to index

lightning-sunbird  0.9+nobinonly
nsHTMLTags.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsHTMLTags.h"
00039 #include "nsCRT.h"
00040 #include "nsReadableUtils.h"
00041 #include "plhash.h"
00042 #include "nsString.h"
00043 #include "nsStaticAtom.h"
00044 
00045 // C++ sucks! There's no way to do this with a macro, at least not
00046 // that I know, if you know how to do this with a macro then please do
00047 // so...
00048 static const PRUnichar sHTMLTagUnicodeName_a[] =
00049   {'a', '\0'};
00050 static const PRUnichar sHTMLTagUnicodeName_abbr[] =
00051   {'a', 'b', 'b', 'r', '\0'};
00052 static const PRUnichar sHTMLTagUnicodeName_acronym[] =
00053   {'a', 'c', 'r', 'o', 'n', 'y', 'm', '\0'};
00054 static const PRUnichar sHTMLTagUnicodeName_address[] =
00055   {'a', 'd', 'd', 'r', 'e', 's', 's', '\0'};
00056 static const PRUnichar sHTMLTagUnicodeName_applet[] =
00057   {'a', 'p', 'p', 'l', 'e', 't', '\0'};
00058 static const PRUnichar sHTMLTagUnicodeName_area[] =
00059   {'a', 'r', 'e', 'a', '\0'};
00060 static const PRUnichar sHTMLTagUnicodeName_b[] =
00061   {'b', '\0'};
00062 static const PRUnichar sHTMLTagUnicodeName_base[] =
00063   {'b', 'a', 's', 'e', '\0'};
00064 static const PRUnichar sHTMLTagUnicodeName_basefont[] =
00065   {'b', 'a', 's', 'e', 'f', 'o', 'n', 't', '\0'};
00066 static const PRUnichar sHTMLTagUnicodeName_bdo[] =
00067   {'b', 'd', 'o', '\0'};
00068 static const PRUnichar sHTMLTagUnicodeName_bgsound[] =
00069   {'b', 'g', 's', 'o', 'u', 'n', 'd', '\0'};
00070 static const PRUnichar sHTMLTagUnicodeName_big[] =
00071   {'b', 'i', 'g', '\0'};
00072 static const PRUnichar sHTMLTagUnicodeName_blink[] =
00073   {'b', 'l', 'i', 'n', 'k', '\0'};
00074 static const PRUnichar sHTMLTagUnicodeName_blockquote[] =
00075   {'b', 'l', 'o', 'c', 'k', 'q', 'u', 'o', 't', 'e', '\0'};
00076 static const PRUnichar sHTMLTagUnicodeName_body[] =
00077   {'b', 'o', 'd', 'y', '\0'};
00078 static const PRUnichar sHTMLTagUnicodeName_br[] =
00079   {'b', 'r', '\0'};
00080 static const PRUnichar sHTMLTagUnicodeName_button[] =
00081   {'b', 'u', 't', 't', 'o', 'n', '\0'};
00082 static const PRUnichar sHTMLTagUnicodeName_canvas[] =
00083   {'c', 'a', 'n', 'v', 'a', 's', '\0'};
00084 static const PRUnichar sHTMLTagUnicodeName_caption[] =
00085   {'c', 'a', 'p', 't', 'i', 'o', 'n', '\0'};
00086 static const PRUnichar sHTMLTagUnicodeName_center[] =
00087   {'c', 'e', 'n', 't', 'e', 'r', '\0'};
00088 static const PRUnichar sHTMLTagUnicodeName_cite[] =
00089   {'c', 'i', 't', 'e', '\0'};
00090 static const PRUnichar sHTMLTagUnicodeName_code[] =
00091   {'c', 'o', 'd', 'e', '\0'};
00092 static const PRUnichar sHTMLTagUnicodeName_col[] =
00093   {'c', 'o', 'l', '\0'};
00094 static const PRUnichar sHTMLTagUnicodeName_colgroup[] =
00095   {'c', 'o', 'l', 'g', 'r', 'o', 'u', 'p', '\0'};
00096 static const PRUnichar sHTMLTagUnicodeName_counter[] =
00097   {'c', 'o', 'u', 'n', 't', 'e', 'r', '\0'};
00098 static const PRUnichar sHTMLTagUnicodeName_dd[] =
00099   {'d', 'd', '\0'};
00100 static const PRUnichar sHTMLTagUnicodeName_del[] =
00101   {'d', 'e', 'l', '\0'};
00102 static const PRUnichar sHTMLTagUnicodeName_dfn[] =
00103   {'d', 'f', 'n', '\0'};
00104 static const PRUnichar sHTMLTagUnicodeName_dir[] =
00105   {'d', 'i', 'r', '\0'};
00106 static const PRUnichar sHTMLTagUnicodeName_div[] =
00107   {'d', 'i', 'v', '\0'};
00108 static const PRUnichar sHTMLTagUnicodeName_dl[] =
00109   {'d', 'l', '\0'};
00110 static const PRUnichar sHTMLTagUnicodeName_dt[] =
00111   {'d', 't', '\0'};
00112 static const PRUnichar sHTMLTagUnicodeName_em[] =
00113   {'e', 'm', '\0'};
00114 static const PRUnichar sHTMLTagUnicodeName_embed[] =
00115   {'e', 'm', 'b', 'e', 'd', '\0'};
00116 static const PRUnichar sHTMLTagUnicodeName_fieldset[] =
00117   {'f', 'i', 'e', 'l', 'd', 's', 'e', 't', '\0'};
00118 static const PRUnichar sHTMLTagUnicodeName_font[] =
00119   {'f', 'o', 'n', 't', '\0'};
00120 static const PRUnichar sHTMLTagUnicodeName_form[] =
00121   {'f', 'o', 'r', 'm', '\0'};
00122 static const PRUnichar sHTMLTagUnicodeName_frame[] =
00123   {'f', 'r', 'a', 'm', 'e', '\0'};
00124 static const PRUnichar sHTMLTagUnicodeName_frameset[] =
00125   {'f', 'r', 'a', 'm', 'e', 's', 'e', 't', '\0'};
00126 static const PRUnichar sHTMLTagUnicodeName_h1[] =
00127   {'h', '1', '\0'};
00128 static const PRUnichar sHTMLTagUnicodeName_h2[] =
00129   {'h', '2', '\0'};
00130 static const PRUnichar sHTMLTagUnicodeName_h3[] =
00131   {'h', '3', '\0'};
00132 static const PRUnichar sHTMLTagUnicodeName_h4[] =
00133   {'h', '4', '\0'};
00134 static const PRUnichar sHTMLTagUnicodeName_h5[] =
00135   {'h', '5', '\0'};
00136 static const PRUnichar sHTMLTagUnicodeName_h6[] =
00137   {'h', '6', '\0'};
00138 static const PRUnichar sHTMLTagUnicodeName_head[] =
00139   {'h', 'e', 'a', 'd', '\0'};
00140 static const PRUnichar sHTMLTagUnicodeName_hr[] =
00141   {'h', 'r', '\0'};
00142 static const PRUnichar sHTMLTagUnicodeName_html[] =
00143   {'h', 't', 'm', 'l', '\0'};
00144 static const PRUnichar sHTMLTagUnicodeName_i[] =
00145   {'i', '\0'};
00146 static const PRUnichar sHTMLTagUnicodeName_iframe[] =
00147   {'i', 'f', 'r', 'a', 'm', 'e', '\0'};
00148 static const PRUnichar sHTMLTagUnicodeName_image[] =
00149   {'i', 'm', 'a', 'g', 'e', '\0'};
00150 static const PRUnichar sHTMLTagUnicodeName_img[] =
00151   {'i', 'm', 'g', '\0'};
00152 static const PRUnichar sHTMLTagUnicodeName_input[] =
00153   {'i', 'n', 'p', 'u', 't', '\0'};
00154 static const PRUnichar sHTMLTagUnicodeName_ins[] =
00155   {'i', 'n', 's', '\0'};
00156 static const PRUnichar sHTMLTagUnicodeName_isindex[] =
00157   {'i', 's', 'i', 'n', 'd', 'e', 'x', '\0'};
00158 static const PRUnichar sHTMLTagUnicodeName_kbd[] =
00159   {'k', 'b', 'd', '\0'};
00160 static const PRUnichar sHTMLTagUnicodeName_keygen[] =
00161   {'k', 'e', 'y', 'g', 'e', 'n', '\0'};
00162 static const PRUnichar sHTMLTagUnicodeName_label[] =
00163   {'l', 'a', 'b', 'e', 'l', '\0'};
00164 static const PRUnichar sHTMLTagUnicodeName_legend[] =
00165   {'l', 'e', 'g', 'e', 'n', 'd', '\0'};
00166 static const PRUnichar sHTMLTagUnicodeName_li[] =
00167   {'l', 'i', '\0'};
00168 static const PRUnichar sHTMLTagUnicodeName_link[] =
00169   {'l', 'i', 'n', 'k', '\0'};
00170 static const PRUnichar sHTMLTagUnicodeName_listing[] =
00171   {'l', 'i', 's', 't', 'i', 'n', 'g', '\0'};
00172 static const PRUnichar sHTMLTagUnicodeName_map[] =
00173   {'m', 'a', 'p', '\0'};
00174 static const PRUnichar sHTMLTagUnicodeName_marquee[] =
00175   {'m', 'a', 'r', 'q', 'u', 'e', 'e', '\0'};
00176 static const PRUnichar sHTMLTagUnicodeName_menu[] =
00177   {'m', 'e', 'n', 'u', '\0'};
00178 static const PRUnichar sHTMLTagUnicodeName_meta[] =
00179   {'m', 'e', 't', 'a', '\0'};
00180 static const PRUnichar sHTMLTagUnicodeName_multicol[] =
00181   {'m', 'u', 'l', 't', 'i', 'c', 'o', 'l', '\0'};
00182 static const PRUnichar sHTMLTagUnicodeName_nobr[] =
00183   {'n', 'o', 'b', 'r', '\0'};
00184 static const PRUnichar sHTMLTagUnicodeName_noembed[] =
00185   {'n', 'o', 'e', 'm', 'b', 'e', 'd', '\0'};
00186 static const PRUnichar sHTMLTagUnicodeName_noframes[] =
00187   {'n', 'o', 'f', 'r', 'a', 'm', 'e', 's', '\0'};
00188 static const PRUnichar sHTMLTagUnicodeName_noscript[] =
00189   {'n', 'o', 's', 'c', 'r', 'i', 'p', 't', '\0'};
00190 static const PRUnichar sHTMLTagUnicodeName_object[] =
00191   {'o', 'b', 'j', 'e', 'c', 't', '\0'};
00192 static const PRUnichar sHTMLTagUnicodeName_ol[] =
00193   {'o', 'l', '\0'};
00194 static const PRUnichar sHTMLTagUnicodeName_optgroup[] =
00195   {'o', 'p', 't', 'g', 'r', 'o', 'u', 'p', '\0'};
00196 static const PRUnichar sHTMLTagUnicodeName_option[] =
00197   {'o', 'p', 't', 'i', 'o', 'n', '\0'};
00198 static const PRUnichar sHTMLTagUnicodeName_p[] =
00199   {'p', '\0'};
00200 static const PRUnichar sHTMLTagUnicodeName_param[] =
00201   {'p', 'a', 'r', 'a', 'm', '\0'};
00202 static const PRUnichar sHTMLTagUnicodeName_plaintext[] =
00203   {'p', 'l', 'a', 'i', 'n', 't', 'e', 'x', 't', '\0'};
00204 static const PRUnichar sHTMLTagUnicodeName_pre[] =
00205   {'p', 'r', 'e', '\0'};
00206 static const PRUnichar sHTMLTagUnicodeName_q[] =
00207   {'q', '\0'};
00208 static const PRUnichar sHTMLTagUnicodeName_s[] =
00209   {'s', '\0'};
00210 static const PRUnichar sHTMLTagUnicodeName_samp[] =
00211   {'s', 'a', 'm', 'p', '\0'};
00212 static const PRUnichar sHTMLTagUnicodeName_script[] =
00213   {'s', 'c', 'r', 'i', 'p', 't', '\0'};
00214 static const PRUnichar sHTMLTagUnicodeName_select[] =
00215   {'s', 'e', 'l', 'e', 'c', 't', '\0'};
00216 static const PRUnichar sHTMLTagUnicodeName_server[] =
00217   {'s', 'e', 'r', 'v', 'e', 'r', '\0'};
00218 static const PRUnichar sHTMLTagUnicodeName_small[] =
00219   {'s', 'm', 'a', 'l', 'l', '\0'};
00220 static const PRUnichar sHTMLTagUnicodeName_sound[] =
00221   {'s', 'o', 'u', 'n', 'd', '\0'};
00222 static const PRUnichar sHTMLTagUnicodeName_spacer[] =
00223   {'s', 'p', 'a', 'c', 'e', 'r', '\0'};
00224 static const PRUnichar sHTMLTagUnicodeName_span[] =
00225   {'s', 'p', 'a', 'n', '\0'};
00226 static const PRUnichar sHTMLTagUnicodeName_strike[] =
00227   {'s', 't', 'r', 'i', 'k', 'e', '\0'};
00228 static const PRUnichar sHTMLTagUnicodeName_strong[] =
00229   {'s', 't', 'r', 'o', 'n', 'g', '\0'};
00230 static const PRUnichar sHTMLTagUnicodeName_style[] =
00231   {'s', 't', 'y', 'l', 'e', '\0'};
00232 static const PRUnichar sHTMLTagUnicodeName_sub[] =
00233   {'s', 'u', 'b', '\0'};
00234 static const PRUnichar sHTMLTagUnicodeName_sup[] =
00235   {'s', 'u', 'p', '\0'};
00236 static const PRUnichar sHTMLTagUnicodeName_table[] =
00237   {'t', 'a', 'b', 'l', 'e', '\0'};
00238 static const PRUnichar sHTMLTagUnicodeName_tbody[] =
00239   {'t', 'b', 'o', 'd', 'y', '\0'};
00240 static const PRUnichar sHTMLTagUnicodeName_td[] =
00241   {'t', 'd', '\0'};
00242 static const PRUnichar sHTMLTagUnicodeName_textarea[] =
00243   {'t', 'e', 'x', 't', 'a', 'r', 'e', 'a', '\0'};
00244 static const PRUnichar sHTMLTagUnicodeName_tfoot[] =
00245   {'t', 'f', 'o', 'o', 't', '\0'};
00246 static const PRUnichar sHTMLTagUnicodeName_th[] =
00247   {'t', 'h', '\0'};
00248 static const PRUnichar sHTMLTagUnicodeName_thead[] =
00249   {'t', 'h', 'e', 'a', 'd', '\0'};
00250 static const PRUnichar sHTMLTagUnicodeName_title[] =
00251   {'t', 'i', 't', 'l', 'e', '\0'};
00252 static const PRUnichar sHTMLTagUnicodeName_tr[] =
00253   {'t', 'r', '\0'};
00254 static const PRUnichar sHTMLTagUnicodeName_tt[] =
00255   {'t', 't', '\0'};
00256 static const PRUnichar sHTMLTagUnicodeName_u[] =
00257   {'u', '\0'};
00258 static const PRUnichar sHTMLTagUnicodeName_ul[] =
00259   {'u', 'l', '\0'};
00260 static const PRUnichar sHTMLTagUnicodeName_var[] =
00261   {'v', 'a', 'r', '\0'};
00262 static const PRUnichar sHTMLTagUnicodeName_wbr[] =
00263   {'w', 'b', 'r', '\0'};
00264 static const PRUnichar sHTMLTagUnicodeName_xmp[] =
00265   {'x', 'm', 'p', '\0'};
00266 
00267 // static array of unicode tag names
00268 #define HTML_TAG(_tag, _classname) sHTMLTagUnicodeName_##_tag,
00269 #define HTML_OTHER(_tag)
00270 static const PRUnichar* const kTagUnicodeTable[] = {
00271 #include "nsHTMLTagList.h"
00272 };
00273 #undef HTML_TAG
00274 
00275 // static array of tag atoms
00276 static nsIAtom* kTagAtomTable[eHTMLTag_userdefined - 1];
00277 
00278 // static array of tag StaticAtom structs
00279 #define HTML_TAG(_tag, _classname) { #_tag, &kTagAtomTable[eHTMLTag_##_tag - 1] },
00280 static const nsStaticAtom kTagAtoms_info[] = {
00281 #include "nsHTMLTagList.h"
00282 };
00283 #undef HTML_TAG
00284 #undef HTML_OTHER
00285 
00286 static PRInt32 gTableRefCount;
00287 static PLHashTable* gTagTable;
00288 
00289 
00290 PR_STATIC_CALLBACK(PLHashNumber)
00291 HTMLTagsHashCodeUCPtr(const void *key)
00292 {
00293   const PRUnichar *str = (const PRUnichar *)key;
00294 
00295   return nsCRT::HashCode(str);
00296 }
00297 
00298 PR_STATIC_CALLBACK(PRIntn)
00299 HTMLTagsKeyCompareUCPtr(const void *key1, const void *key2)
00300 {
00301   const PRUnichar *str1 = (const PRUnichar *)key1;
00302   const PRUnichar *str2 = (const PRUnichar *)key2;
00303 
00304   return nsCRT::strcmp(str1, str2) == 0;
00305 }
00306 
00307 
00308 static PRUint32 sMaxTagNameLength;
00309 #define NS_HTMLTAG_NAME_MAX_LENGTH 10
00310 
00311 // static
00312 nsresult
00313 nsHTMLTags::AddRefTable(void)
00314 {
00315   if (gTableRefCount++ == 0) {
00316     NS_ASSERTION(!gTagTable, "pre existing hash!");
00317 
00318     gTagTable = PL_NewHashTable(64, HTMLTagsHashCodeUCPtr,
00319                                 HTMLTagsKeyCompareUCPtr, PL_CompareValues,
00320                                 nsnull, nsnull);
00321     NS_ENSURE_TRUE(gTagTable, NS_ERROR_OUT_OF_MEMORY);
00322 
00323     // Fill in gTagTable with the above static PRUnichar strings as
00324     // keys and the value of the corresponding enum as the value in
00325     // the table.
00326 
00327     PRInt32 i;
00328     for (i = 0; i < NS_HTML_TAG_MAX; ++i) {
00329       PRUint32 len = nsCRT::strlen(kTagUnicodeTable[i]);
00330 
00331       PL_HashTableAdd(gTagTable, kTagUnicodeTable[i],
00332                       NS_INT32_TO_PTR(i + 1));
00333 
00334       if (len > sMaxTagNameLength) {
00335         sMaxTagNameLength = len;
00336       }
00337     }
00338 
00339     NS_ASSERTION(sMaxTagNameLength == NS_HTMLTAG_NAME_MAX_LENGTH,
00340                  "NS_HTMLTAG_NAME_MAX_LENGTH not set correctly!");
00341 
00342     // Fill in our static atom pointers
00343     NS_RegisterStaticAtoms(kTagAtoms_info, NS_ARRAY_LENGTH(kTagAtoms_info));
00344 
00345 #ifdef DEBUG
00346     {
00347       // let's verify that all names in the the table are lowercase...
00348       for (i = 0; i < NS_HTML_TAG_MAX; ++i) {
00349         nsCAutoString temp1(kTagAtoms_info[i].mString);
00350         nsCAutoString temp2(kTagAtoms_info[i].mString);
00351         ToLowerCase(temp1);
00352         NS_ASSERTION(temp1.Equals(temp2), "upper case char in table");
00353       }
00354 
00355       // let's verify that all names in the unicode strings above are
00356       // correct.
00357       for (i = 0; i < NS_HTML_TAG_MAX; ++i) {
00358         nsAutoString temp1(kTagUnicodeTable[i]);
00359         nsAutoString temp2; temp2.AssignWithConversion(kTagAtoms_info[i].mString);
00360         NS_ASSERTION(temp1.Equals(temp2), "Bad unicode tag name!");
00361       }
00362     }
00363 #endif
00364   }
00365 
00366   return NS_OK;
00367 }
00368 
00369 // static
00370 void
00371 nsHTMLTags::ReleaseTable(void)
00372 {
00373   if (0 == --gTableRefCount) {
00374     if (gTagTable) {
00375       // Nothing to delete/free in this table, just destroy the table.
00376 
00377       PL_HashTableDestroy(gTagTable);
00378 
00379       gTagTable = nsnull;
00380     }
00381   }
00382 }
00383 
00384 // static
00385 nsHTMLTag
00386 nsHTMLTags::CaseSensitiveLookupTag(const PRUnichar* aTagName)
00387 {
00388   NS_ASSERTION(gTagTable, "no lookup table, needs addref");
00389   NS_ASSERTION(aTagName, "null tagname!");
00390 
00391   PRUint32 tag = NS_PTR_TO_INT32(PL_HashTableLookupConst(gTagTable, aTagName));
00392 
00393   return tag == eHTMLTag_unknown ? eHTMLTag_userdefined : (nsHTMLTag)tag;
00394 }
00395 
00396 // static
00397 nsHTMLTag
00398 nsHTMLTags::LookupTag(const nsAString& aTagName)
00399 {
00400   PRUint32 length = aTagName.Length();
00401 
00402   if (length > sMaxTagNameLength) {
00403     return eHTMLTag_userdefined;
00404   }
00405 
00406   static PRUnichar buf[NS_HTMLTAG_NAME_MAX_LENGTH + 1];
00407 
00408   nsAString::const_iterator iter;
00409   PRUint32 i = 0;
00410   PRUnichar c;
00411 
00412   aTagName.BeginReading(iter);
00413 
00414   // Fast lowercasing-while-copying of ASCII characters into a
00415   // PRUnichar buffer
00416 
00417   while (i < length) {
00418     c = *iter;
00419 
00420     if (c <= 'Z' && c >= 'A') {
00421       c |= 0x20; // Lowercase the ASCII character.
00422     }
00423 
00424     buf[i] = c; // Copy ASCII character.
00425 
00426     ++i;
00427     ++iter;
00428   }
00429 
00430   buf[i] = 0;
00431 
00432   return CaseSensitiveLookupTag(buf);
00433 }
00434 
00435 // static
00436 const PRUnichar *
00437 nsHTMLTags::GetStringValue(nsHTMLTag aEnum)
00438 {
00439   if (aEnum <= eHTMLTag_unknown || aEnum > NS_HTML_TAG_MAX) {
00440     return nsnull;
00441   }
00442 
00443   return kTagUnicodeTable[aEnum - 1];
00444 }
00445 
00446 // static
00447 nsIAtom *
00448 nsHTMLTags::GetAtom(nsHTMLTag aEnum)
00449 {
00450   if (aEnum <= eHTMLTag_unknown || aEnum > NS_HTML_TAG_MAX) {
00451     return nsnull;
00452   }
00453 
00454   return kTagAtomTable[aEnum - 1];
00455 }
00456 
00457 
00458 #ifdef NS_DEBUG
00459 
00460 // tag table verification class.
00461 
00462 class nsTestTagTable {
00463 public:
00464    nsTestTagTable() {
00465      const PRUnichar *tag;
00466      nsHTMLTag id;
00467 
00468      nsHTMLTags::AddRefTable();
00469      // Make sure we can find everything we are supposed to
00470      for (int i = 0; i < NS_HTML_TAG_MAX; ++i) {
00471        tag = kTagUnicodeTable[i];
00472        id = nsHTMLTags::LookupTag(nsDependentString(tag));
00473        NS_ASSERTION(id != eHTMLTag_userdefined, "can't find tag id");
00474        const PRUnichar* check = nsHTMLTags::GetStringValue(id);
00475        NS_ASSERTION(0 == nsCRT::strcmp(check, tag), "can't map id back to tag");
00476      }
00477 
00478      // Make sure we don't find things that aren't there
00479      id = nsHTMLTags::LookupTag(NS_LITERAL_STRING("@"));
00480      NS_ASSERTION(id == eHTMLTag_userdefined, "found @");
00481      id = nsHTMLTags::LookupTag(NS_LITERAL_STRING("zzzzz"));
00482      NS_ASSERTION(id == eHTMLTag_userdefined, "found zzzzz");
00483 
00484      tag = nsHTMLTags::GetStringValue((nsHTMLTag) 0);
00485      NS_ASSERTION(!tag, "found enum 0");
00486      tag = nsHTMLTags::GetStringValue((nsHTMLTag) -1);
00487      NS_ASSERTION(!tag, "found enum -1");
00488      tag = nsHTMLTags::GetStringValue((nsHTMLTag) (NS_HTML_TAG_MAX + 1));
00489      NS_ASSERTION(!tag, "found past max enum");
00490 
00491      nsHTMLTags::ReleaseTable();
00492    }
00493 };
00494 
00495 static const nsTestTagTable validateTagTable;
00496 
00497 #endif