From 992697d99f40920dcd772c6e66e8eaeede8b1bb2 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 7 Jun 2020 23:27:03 +0200 Subject: [PATCH] LibWeb: Add HTML::TagNames namespace for global tag name FlyStrings Instead of "iframe", we can now say HTML::TagNames::iframe and avoid a FlyString lookup. --- Libraries/LibWeb/CMakeLists.txt | 1 + Libraries/LibWeb/DOM/Document.cpp | 1 + Libraries/LibWeb/DOM/Element.h | 1 + Libraries/LibWeb/DOM/ElementFactory.cpp | 50 +++++------ Libraries/LibWeb/DOM/HTMLAnchorElement.h | 2 +- Libraries/LibWeb/DOM/HTMLBRElement.h | 2 +- Libraries/LibWeb/DOM/HTMLBlinkElement.h | 6 ++ Libraries/LibWeb/DOM/HTMLBodyElement.h | 2 +- Libraries/LibWeb/DOM/HTMLCanvasElement.h | 2 +- Libraries/LibWeb/DOM/HTMLFontElement.h | 6 ++ Libraries/LibWeb/DOM/HTMLFormElement.h | 2 +- Libraries/LibWeb/DOM/HTMLHRElement.h | 6 ++ Libraries/LibWeb/DOM/HTMLIFrameElement.h | 2 +- Libraries/LibWeb/DOM/HTMLImageElement.h | 2 +- Libraries/LibWeb/DOM/HTMLInputElement.h | 2 +- Libraries/LibWeb/DOM/HTMLLinkElement.h | 2 +- Libraries/LibWeb/DOM/HTMLScriptElement.h | 2 +- Libraries/LibWeb/DOM/HTMLStyleElement.h | 7 ++ Libraries/LibWeb/DOM/HTMLTableCellElement.h | 2 +- Libraries/LibWeb/DOM/HTMLTableElement.h | 2 +- Libraries/LibWeb/DOM/HTMLTableRowElement.h | 2 +- Libraries/LibWeb/DOM/TagNames.cpp | 53 ++++++++++++ Libraries/LibWeb/DOM/TagNames.h | 95 +++++++++++++++++++++ 23 files changed, 210 insertions(+), 42 deletions(-) create mode 100644 Libraries/LibWeb/DOM/TagNames.cpp create mode 100644 Libraries/LibWeb/DOM/TagNames.h diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index aac8fde6054..f1b926ca9d6 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -62,6 +62,7 @@ set(SOURCES DOM/ImageData.cpp DOM/Node.cpp DOM/ParentNode.cpp + DOM/TagNames.cpp DOM/Text.cpp DOM/Window.cpp DOM/XMLHttpRequest.cpp diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index b716b789ab0..9973310dd9f 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -68,6 +68,7 @@ Document::Document(const URL& url) , m_window(Window::create_with_document(*this)) { HTML::AttributeNames::initialize(); + HTML::TagNames::initialize(); m_style_update_timer = Core::Timer::create_single_shot(0, [this] { update_style(); diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h index e7d88d84aed..e8d0e4fabab 100644 --- a/Libraries/LibWeb/DOM/Element.h +++ b/Libraries/LibWeb/DOM/Element.h @@ -31,6 +31,7 @@ #include #include #include +#include #include namespace Web { diff --git a/Libraries/LibWeb/DOM/ElementFactory.cpp b/Libraries/LibWeb/DOM/ElementFactory.cpp index 04874247a00..c8ba8bdb606 100644 --- a/Libraries/LibWeb/DOM/ElementFactory.cpp +++ b/Libraries/LibWeb/DOM/ElementFactory.cpp @@ -52,55 +52,47 @@ namespace Web { NonnullRefPtr create_element(Document& document, const FlyString& tag_name) { auto lowercase_tag_name = tag_name.to_lowercase(); - if (lowercase_tag_name == "a") + if (lowercase_tag_name == HTML::TagNames::a) return adopt(*new HTMLAnchorElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "html") + if (lowercase_tag_name == HTML::TagNames::html) return adopt(*new HTMLHtmlElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "head") + if (lowercase_tag_name == HTML::TagNames::head) return adopt(*new HTMLHeadElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "body") + if (lowercase_tag_name == HTML::TagNames::body) return adopt(*new HTMLBodyElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "font") + if (lowercase_tag_name == HTML::TagNames::font) return adopt(*new HTMLFontElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "hr") + if (lowercase_tag_name == HTML::TagNames::hr) return adopt(*new HTMLHRElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "style") + if (lowercase_tag_name == HTML::TagNames::style) return adopt(*new HTMLStyleElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "title") + if (lowercase_tag_name == HTML::TagNames::title) return adopt(*new HTMLTitleElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "link") + if (lowercase_tag_name == HTML::TagNames::link) return adopt(*new HTMLLinkElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "img") + if (lowercase_tag_name == HTML::TagNames::img) return adopt(*new HTMLImageElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "blink") + if (lowercase_tag_name == HTML::TagNames::blink) return adopt(*new HTMLBlinkElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "form") + if (lowercase_tag_name == HTML::TagNames::form) return adopt(*new HTMLFormElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "input") + if (lowercase_tag_name == HTML::TagNames::input) return adopt(*new HTMLInputElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "br") + if (lowercase_tag_name == HTML::TagNames::br) return adopt(*new HTMLBRElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "iframe") + if (lowercase_tag_name == HTML::TagNames::iframe) return adopt(*new HTMLIFrameElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "table") + if (lowercase_tag_name == HTML::TagNames::table) return adopt(*new HTMLTableElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "tr") + if (lowercase_tag_name == HTML::TagNames::tr) return adopt(*new HTMLTableRowElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "td" || lowercase_tag_name == "th") + if (lowercase_tag_name == HTML::TagNames::td || lowercase_tag_name == HTML::TagNames::th) return adopt(*new HTMLTableCellElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "iframe") - return adopt(*new HTMLIFrameElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "h1" - || lowercase_tag_name == "h2" - || lowercase_tag_name == "h3" - || lowercase_tag_name == "h4" - || lowercase_tag_name == "h5" - || lowercase_tag_name == "h6") { + if (lowercase_tag_name.is_one_of(HTML::TagNames::h1, HTML::TagNames::h2, HTML::TagNames::h3, HTML::TagNames::h4, HTML::TagNames::h5, HTML::TagNames::h6)) return adopt(*new HTMLHeadingElement(document, lowercase_tag_name)); - } - if (lowercase_tag_name == "script") + if (lowercase_tag_name == HTML::TagNames::script) return adopt(*new HTMLScriptElement(document, lowercase_tag_name)); - if (lowercase_tag_name == "canvas") + if (lowercase_tag_name == HTML::TagNames::canvas) return adopt(*new HTMLCanvasElement(document, lowercase_tag_name)); return adopt(*new Element(document, lowercase_tag_name)); } diff --git a/Libraries/LibWeb/DOM/HTMLAnchorElement.h b/Libraries/LibWeb/DOM/HTMLAnchorElement.h index 925d149cf5a..d52557b8c33 100644 --- a/Libraries/LibWeb/DOM/HTMLAnchorElement.h +++ b/Libraries/LibWeb/DOM/HTMLAnchorElement.h @@ -42,7 +42,7 @@ public: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("a"); + return is(node) && to(node).tag_name() == HTML::TagNames::a; } } diff --git a/Libraries/LibWeb/DOM/HTMLBRElement.h b/Libraries/LibWeb/DOM/HTMLBRElement.h index f0321664383..b922c459fb0 100644 --- a/Libraries/LibWeb/DOM/HTMLBRElement.h +++ b/Libraries/LibWeb/DOM/HTMLBRElement.h @@ -41,7 +41,7 @@ public: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("br"); + return is(node) && to(node).tag_name() == HTML::TagNames::br; } } diff --git a/Libraries/LibWeb/DOM/HTMLBlinkElement.h b/Libraries/LibWeb/DOM/HTMLBlinkElement.h index 743f8a8af04..d9ff921fa40 100644 --- a/Libraries/LibWeb/DOM/HTMLBlinkElement.h +++ b/Libraries/LibWeb/DOM/HTMLBlinkElement.h @@ -42,4 +42,10 @@ private: NonnullRefPtr m_timer; }; +template<> +inline bool is(const Node& node) +{ + return is(node) && to(node).tag_name() == HTML::TagNames::blink; +} + } diff --git a/Libraries/LibWeb/DOM/HTMLBodyElement.h b/Libraries/LibWeb/DOM/HTMLBodyElement.h index 4dafb726334..75a80743dc5 100644 --- a/Libraries/LibWeb/DOM/HTMLBodyElement.h +++ b/Libraries/LibWeb/DOM/HTMLBodyElement.h @@ -45,7 +45,7 @@ private: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("body"); + return is(node) && to(node).tag_name() == HTML::TagNames::body; } } diff --git a/Libraries/LibWeb/DOM/HTMLCanvasElement.h b/Libraries/LibWeb/DOM/HTMLCanvasElement.h index fb1c9d141a3..ce2f8c38d1a 100644 --- a/Libraries/LibWeb/DOM/HTMLCanvasElement.h +++ b/Libraries/LibWeb/DOM/HTMLCanvasElement.h @@ -60,7 +60,7 @@ private: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("canvas"); + return is(node) && to(node).tag_name() == HTML::TagNames::canvas; } } diff --git a/Libraries/LibWeb/DOM/HTMLFontElement.h b/Libraries/LibWeb/DOM/HTMLFontElement.h index f958f03eebd..4f9484d370a 100644 --- a/Libraries/LibWeb/DOM/HTMLFontElement.h +++ b/Libraries/LibWeb/DOM/HTMLFontElement.h @@ -38,4 +38,10 @@ public: virtual void apply_presentational_hints(StyleProperties&) const override; }; +template<> +inline bool is(const Node& node) +{ + return is(node) && to(node).tag_name() == HTML::TagNames::font; +} + } diff --git a/Libraries/LibWeb/DOM/HTMLFormElement.h b/Libraries/LibWeb/DOM/HTMLFormElement.h index dbfb97f6713..db0297e1f27 100644 --- a/Libraries/LibWeb/DOM/HTMLFormElement.h +++ b/Libraries/LibWeb/DOM/HTMLFormElement.h @@ -45,7 +45,7 @@ public: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("form"); + return is(node) && to(node).tag_name() == HTML::TagNames::form; } } diff --git a/Libraries/LibWeb/DOM/HTMLHRElement.h b/Libraries/LibWeb/DOM/HTMLHRElement.h index d6d3bfdbfba..31c23deae4b 100644 --- a/Libraries/LibWeb/DOM/HTMLHRElement.h +++ b/Libraries/LibWeb/DOM/HTMLHRElement.h @@ -36,4 +36,10 @@ public: virtual ~HTMLHRElement() override; }; +template<> +inline bool is(const Node& node) +{ + return is(node) && to(node).tag_name() == HTML::TagNames::hr; +} + } diff --git a/Libraries/LibWeb/DOM/HTMLIFrameElement.h b/Libraries/LibWeb/DOM/HTMLIFrameElement.h index f984eac0e9b..7520779af94 100644 --- a/Libraries/LibWeb/DOM/HTMLIFrameElement.h +++ b/Libraries/LibWeb/DOM/HTMLIFrameElement.h @@ -52,7 +52,7 @@ private: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("iframe"); + return is(node) && to(node).tag_name() == HTML::TagNames::iframe; } } diff --git a/Libraries/LibWeb/DOM/HTMLImageElement.h b/Libraries/LibWeb/DOM/HTMLImageElement.h index 533569514f0..c1b28160e37 100644 --- a/Libraries/LibWeb/DOM/HTMLImageElement.h +++ b/Libraries/LibWeb/DOM/HTMLImageElement.h @@ -82,7 +82,7 @@ private: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("img"); + return is(node) && to(node).tag_name() == HTML::TagNames::img; } } diff --git a/Libraries/LibWeb/DOM/HTMLInputElement.h b/Libraries/LibWeb/DOM/HTMLInputElement.h index 0bc318e9da1..2277b6a8c33 100644 --- a/Libraries/LibWeb/DOM/HTMLInputElement.h +++ b/Libraries/LibWeb/DOM/HTMLInputElement.h @@ -45,7 +45,7 @@ public: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("input"); + return is(node) && to(node).tag_name() == HTML::TagNames::input; } } diff --git a/Libraries/LibWeb/DOM/HTMLLinkElement.h b/Libraries/LibWeb/DOM/HTMLLinkElement.h index bae7d8d9f00..c2fc343bba7 100644 --- a/Libraries/LibWeb/DOM/HTMLLinkElement.h +++ b/Libraries/LibWeb/DOM/HTMLLinkElement.h @@ -57,7 +57,7 @@ private: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("link"); + return is(node) && to(node).tag_name() == HTML::TagNames::link; } } diff --git a/Libraries/LibWeb/DOM/HTMLScriptElement.h b/Libraries/LibWeb/DOM/HTMLScriptElement.h index 9aba63d8659..55bc9d024ff 100644 --- a/Libraries/LibWeb/DOM/HTMLScriptElement.h +++ b/Libraries/LibWeb/DOM/HTMLScriptElement.h @@ -69,7 +69,7 @@ private: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("script"); + return is(node) && to(node).tag_name() == HTML::TagNames::script; } } diff --git a/Libraries/LibWeb/DOM/HTMLStyleElement.h b/Libraries/LibWeb/DOM/HTMLStyleElement.h index 06bd7d9feb5..f4d6f30c73f 100644 --- a/Libraries/LibWeb/DOM/HTMLStyleElement.h +++ b/Libraries/LibWeb/DOM/HTMLStyleElement.h @@ -44,4 +44,11 @@ private: RefPtr m_stylesheet; }; +template<> +inline bool is(const Node& node) +{ + return is(node) && to(node).tag_name() == HTML::TagNames::style; +} + + } diff --git a/Libraries/LibWeb/DOM/HTMLTableCellElement.h b/Libraries/LibWeb/DOM/HTMLTableCellElement.h index 486c2e698f4..40272aab9fd 100644 --- a/Libraries/LibWeb/DOM/HTMLTableCellElement.h +++ b/Libraries/LibWeb/DOM/HTMLTableCellElement.h @@ -39,7 +39,7 @@ public: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().is_one_of("td", "th"); + return is(node) && to(node).tag_name().is_one_of(HTML::TagNames::td, HTML::TagNames::th); } } diff --git a/Libraries/LibWeb/DOM/HTMLTableElement.h b/Libraries/LibWeb/DOM/HTMLTableElement.h index 423345f9ce5..b68a08d56e1 100644 --- a/Libraries/LibWeb/DOM/HTMLTableElement.h +++ b/Libraries/LibWeb/DOM/HTMLTableElement.h @@ -39,7 +39,7 @@ public: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("table"); + return is(node) && to(node).tag_name() == HTML::TagNames::table; } } diff --git a/Libraries/LibWeb/DOM/HTMLTableRowElement.h b/Libraries/LibWeb/DOM/HTMLTableRowElement.h index f3b3870bf20..6e485799148 100644 --- a/Libraries/LibWeb/DOM/HTMLTableRowElement.h +++ b/Libraries/LibWeb/DOM/HTMLTableRowElement.h @@ -39,7 +39,7 @@ public: template<> inline bool is(const Node& node) { - return is(node) && to(node).tag_name().equals_ignoring_case("tr"); + return is(node) && to(node).tag_name() == HTML::TagNames::tr; } } diff --git a/Libraries/LibWeb/DOM/TagNames.cpp b/Libraries/LibWeb/DOM/TagNames.cpp new file mode 100644 index 00000000000..b60666de26e --- /dev/null +++ b/Libraries/LibWeb/DOM/TagNames.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +namespace Web { +namespace HTML { +namespace TagNames { + +#define __ENUMERATE_HTML_TAG(name) FlyString name; +ENUMERATE_HTML_TAGS +#undef __ENUMERATE_HTML_TAG + +void initialize() +{ + static bool s_initialized = false; + if (s_initialized) + return; + +#define __ENUMERATE_HTML_TAG(name) \ + name = #name; + ENUMERATE_HTML_TAGS +#undef __ENUMERATE_HTML_TAG + + s_initialized = true; +} + +} +} +} diff --git a/Libraries/LibWeb/DOM/TagNames.h b/Libraries/LibWeb/DOM/TagNames.h new file mode 100644 index 00000000000..415636b2866 --- /dev/null +++ b/Libraries/LibWeb/DOM/TagNames.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace Web { +namespace HTML { +namespace TagNames { + +void initialize(); + +#define ENUMERATE_HTML_TAGS \ + __ENUMERATE_HTML_TAG(a) \ + __ENUMERATE_HTML_TAG(article) \ + __ENUMERATE_HTML_TAG(b) \ + __ENUMERATE_HTML_TAG(blink) \ + __ENUMERATE_HTML_TAG(body) \ + __ENUMERATE_HTML_TAG(br) \ + __ENUMERATE_HTML_TAG(button) \ + __ENUMERATE_HTML_TAG(canvas) \ + __ENUMERATE_HTML_TAG(div) \ + __ENUMERATE_HTML_TAG(em) \ + __ENUMERATE_HTML_TAG(font) \ + __ENUMERATE_HTML_TAG(form) \ + __ENUMERATE_HTML_TAG(h1) \ + __ENUMERATE_HTML_TAG(h2) \ + __ENUMERATE_HTML_TAG(h3) \ + __ENUMERATE_HTML_TAG(h4) \ + __ENUMERATE_HTML_TAG(h5) \ + __ENUMERATE_HTML_TAG(h6) \ + __ENUMERATE_HTML_TAG(head) \ + __ENUMERATE_HTML_TAG(hr) \ + __ENUMERATE_HTML_TAG(html) \ + __ENUMERATE_HTML_TAG(i) \ + __ENUMERATE_HTML_TAG(iframe) \ + __ENUMERATE_HTML_TAG(img) \ + __ENUMERATE_HTML_TAG(input) \ + __ENUMERATE_HTML_TAG(li) \ + __ENUMERATE_HTML_TAG(link) \ + __ENUMERATE_HTML_TAG(main) \ + __ENUMERATE_HTML_TAG(marquee) \ + __ENUMERATE_HTML_TAG(meta) \ + __ENUMERATE_HTML_TAG(nav) \ + __ENUMERATE_HTML_TAG(ol) \ + __ENUMERATE_HTML_TAG(pre) \ + __ENUMERATE_HTML_TAG(s) \ + __ENUMERATE_HTML_TAG(script) \ + __ENUMERATE_HTML_TAG(section) \ + __ENUMERATE_HTML_TAG(span) \ + __ENUMERATE_HTML_TAG(strong) \ + __ENUMERATE_HTML_TAG(style) \ + __ENUMERATE_HTML_TAG(table) \ + __ENUMERATE_HTML_TAG(tbody) \ + __ENUMERATE_HTML_TAG(td) \ + __ENUMERATE_HTML_TAG(textarea) \ + __ENUMERATE_HTML_TAG(tfoot) \ + __ENUMERATE_HTML_TAG(th) \ + __ENUMERATE_HTML_TAG(thead) \ + __ENUMERATE_HTML_TAG(title) \ + __ENUMERATE_HTML_TAG(tr) \ + __ENUMERATE_HTML_TAG(u) \ + __ENUMERATE_HTML_TAG(ul) + +#define __ENUMERATE_HTML_TAG(name) extern FlyString name; +ENUMERATE_HTML_TAGS +#undef __ENUMERATE_HTML_TAG + +} +} +}