Avoid redundant isElementNode() checks in Traversal<HTML*Element> / Traversal<SVG...
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Sep 2014 15:59:39 +0000 (15:59 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Sep 2014 15:59:39 +0000 (15:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=136719

Reviewed by Darin Adler.

Avoid redundant isElementNode() checks in Traversal<HTML*Element> /
Traversal<SVG*Element>.  We used to iterate through Elements, and then
call isElementOfType<HTML*Element>()  on each Element. This made sense
because hasTagName() used to be defined on Element. However, after
http://trac.webkit.org/changeset/165699, hasTagName() is now defined on
Node for HTMLQualifiedName / SVGQualifiedName arguments.

Node::hasTagName(HTMLQualifiedName) basically does the following check
"isHTMLElement() &&  toHTMLElement(*this).hasTagName(tagName)". As a
consequence, doing an isElementNode() check is now redundant as
isHTMLElement() is defined on Node.

This patch adds a template parameter to isElementOfType() so that it can
take any type in argument (particulaly Node, Element, HTMLElement,
SVGElement, MathMLElement), not just an Element. I had to add an
ElementTypeCastTraits struct to support partial specialization as C++
does not support partial specialization of template functions.
This patch also updates Traversal<ElementType> so that the methods use
NodeTraversal internally instead of Traversal<ElementType>. As a result,
we now iterate over Nodes (not Elements) and call the new
isElementOfType<ElementType>(Node) helpers (which are efficient after
r165699).

Before the patch, the code ended up doing the following checks for
Traversal<HTML*element>:
node.isElementNode() && toElement(node).isHTMLElement()
    && toHTMLElement(node).hasTagName(HTMLNames::fooTag)

After the patch, the code only does:
node.isHTMLElement()
    && toHTMLElement(node).hasTagName(HTMLNames::fooTag)

No new tests, no behavior change.

* dom/Element.h:
(WebCore::Element>):
(WebCore::isElementOfType):
Add template parameter to isElementOfType() function so that it can
handle any argument type, not just Elements. Also introduce an
ElementTypeCastTraits struct that is called by isElementOfType()
function so that we can so partial template specialization.

* dom/ElementTraversal.h:
(WebCore::Traversal<ElementType>::firstWithinTemplate):
(WebCore::Traversal<ElementType>::lastWithinTemplate):
(WebCore::Traversal<ElementType>::nextTemplate):
(WebCore::Traversal<ElementType>::previousTemplate):
Use NodeTraversal API internally instead of Traversal<Element> to avoid
redundant isElementNode() checks.

(WebCore::Traversal<Element>::lastWithinTemplate): Deleted.
The code is now identical to the generic version.

(WebCore::Traversal<Element>::previousTemplate): Deleted.
The code is now identical to the generic version.

* dom/make_names.pl:
(printTypeHelpers):
- Generate template specializations for ElementTypeCastTraits struct
  instead of isElementOfType(). This avoids having to provide overloads
  for specific argument types (e.g. Node, Element, HTMLElement, ...).
- Share more code between HTML code path and the other path (for SVG,
  MTHML).

* html/HTMLElement.h:
(WebCore::HTMLElement>):
Provide HTMLElement template specialization for ElementTypeCastTraits
struct instead of isElementOfType().

* html/HTMLFormControlElement.h:
(WebCore::HTMLFormControlElement>):
Provide HTMLFormControlElement template specialization for
ElementTypeCastTraits struct instead of isElementOfType().

* html/HTMLFrameElementBase.h:
(WebCore::isHTMLFrameElementBase):
- Remove helper taking an Element in argument as it does not bring any
  benefit. Instead, update the overload taking a Node in argument to
  remove the unnecessary isElementNode() check as isHTMLFrameElement(Node)
  is now efficient.
- Add an overload taking an HTMLElement in argument so that we can bypass
  the isHTMLElement() check when we know the input is an HTMLElement.

* html/HTMLMediaElement.h:
(WebCore::HTMLMediaElement>):
Provide HTMLMediaElement template specialization for ElementTypeCastTraits
struct instead of isElementOfType().

* html/HTMLPlugInImageElement.h:
(WebCore::HTMLPlugInImageElement>):
Provide HTMLPlugInImageElement template specialization for
ElementTypeCastTraits struct instead of isElementOfType().

* html/LabelableElement.h:
(WebCore::LabelableElement>):
Provide LabelableElement template specialization for ElementTypeCastTraits
struct instead of isElementOfType().

* mathml/MathMLElement.h:
(WebCore::MathMLElement>):
Provide MathMLElement template specialization for ElementTypeCastTraits
struct for consistency with HTMLElement / SVGElement.

* svg/SVGElement.h:
(WebCore::SVGElement>):
- Provide SVGElement template specialization for ElementTypeCastTraits
  struct instead of isElementOfType().
- include SVGElementTypeHelpers.h at the end of the file (similarly to
  what is already done in HTMLElement.h because
  isElementOfType(const SVGElement&) needs to be defiend because the
  include.

* svg/SVGFilterPrimitiveStandardAttributes.h:
(WebCore::SVGFilterPrimitiveStandardAttributes>):
Provide SVGFilterPrimitiveStandardAttributes template specialization for
ElementTypeCastTraits struct instead of isElementOfType().

* svg/animation/SVGSMILElement.h:
(WebCore::SVGSMILElement>):
Provide SVGSMILElement template specialization for ElementTypeCastTraits
struct instead of isElementOfType().

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@173622 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Element.h
Source/WebCore/dom/ElementTraversal.h
Source/WebCore/dom/make_names.pl
Source/WebCore/html/HTMLElement.h
Source/WebCore/html/HTMLFormControlElement.h
Source/WebCore/html/HTMLFrameElementBase.h
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLPlugInImageElement.h
Source/WebCore/html/LabelableElement.h
Source/WebCore/mathml/MathMLElement.h
Source/WebCore/svg/SVGElement.h
Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
Source/WebCore/svg/animation/SVGSMILElement.h

index 5de34ec..a252189 100644 (file)
@@ -1,3 +1,133 @@
+2014-09-15  Chris Dumez  <cdumez@apple.com>
+
+        Avoid redundant isElementNode() checks in Traversal<HTML*Element> / Traversal<SVG*Element>
+        https://bugs.webkit.org/show_bug.cgi?id=136719
+
+        Reviewed by Darin Adler.
+
+        Avoid redundant isElementNode() checks in Traversal<HTML*Element> /
+        Traversal<SVG*Element>.  We used to iterate through Elements, and then
+        call isElementOfType<HTML*Element>()  on each Element. This made sense
+        because hasTagName() used to be defined on Element. However, after
+        http://trac.webkit.org/changeset/165699, hasTagName() is now defined on
+        Node for HTMLQualifiedName / SVGQualifiedName arguments.
+
+        Node::hasTagName(HTMLQualifiedName) basically does the following check
+        "isHTMLElement() &&  toHTMLElement(*this).hasTagName(tagName)". As a
+        consequence, doing an isElementNode() check is now redundant as
+        isHTMLElement() is defined on Node.
+
+        This patch adds a template parameter to isElementOfType() so that it can
+        take any type in argument (particulaly Node, Element, HTMLElement,
+        SVGElement, MathMLElement), not just an Element. I had to add an
+        ElementTypeCastTraits struct to support partial specialization as C++
+        does not support partial specialization of template functions.
+        This patch also updates Traversal<ElementType> so that the methods use
+        NodeTraversal internally instead of Traversal<ElementType>. As a result,
+        we now iterate over Nodes (not Elements) and call the new
+        isElementOfType<ElementType>(Node) helpers (which are efficient after
+        r165699).
+
+        Before the patch, the code ended up doing the following checks for
+        Traversal<HTML*element>:
+        node.isElementNode() && toElement(node).isHTMLElement()
+            && toHTMLElement(node).hasTagName(HTMLNames::fooTag)
+
+        After the patch, the code only does:
+        node.isHTMLElement()
+            && toHTMLElement(node).hasTagName(HTMLNames::fooTag)
+
+        No new tests, no behavior change.
+
+        * dom/Element.h:
+        (WebCore::Element>):
+        (WebCore::isElementOfType):
+        Add template parameter to isElementOfType() function so that it can
+        handle any argument type, not just Elements. Also introduce an
+        ElementTypeCastTraits struct that is called by isElementOfType()
+        function so that we can so partial template specialization.
+
+        * dom/ElementTraversal.h:
+        (WebCore::Traversal<ElementType>::firstWithinTemplate):
+        (WebCore::Traversal<ElementType>::lastWithinTemplate):
+        (WebCore::Traversal<ElementType>::nextTemplate):
+        (WebCore::Traversal<ElementType>::previousTemplate):
+        Use NodeTraversal API internally instead of Traversal<Element> to avoid
+        redundant isElementNode() checks.
+
+        (WebCore::Traversal<Element>::lastWithinTemplate): Deleted.
+        The code is now identical to the generic version.
+
+        (WebCore::Traversal<Element>::previousTemplate): Deleted.
+        The code is now identical to the generic version.
+
+        * dom/make_names.pl:
+        (printTypeHelpers):
+        - Generate template specializations for ElementTypeCastTraits struct
+          instead of isElementOfType(). This avoids having to provide overloads
+          for specific argument types (e.g. Node, Element, HTMLElement, ...).
+        - Share more code between HTML code path and the other path (for SVG,
+          MTHML).
+
+        * html/HTMLElement.h:
+        (WebCore::HTMLElement>):
+        Provide HTMLElement template specialization for ElementTypeCastTraits
+        struct instead of isElementOfType().
+
+        * html/HTMLFormControlElement.h:
+        (WebCore::HTMLFormControlElement>):
+        Provide HTMLFormControlElement template specialization for
+        ElementTypeCastTraits struct instead of isElementOfType().
+
+        * html/HTMLFrameElementBase.h:
+        (WebCore::isHTMLFrameElementBase):
+        - Remove helper taking an Element in argument as it does not bring any
+          benefit. Instead, update the overload taking a Node in argument to
+          remove the unnecessary isElementNode() check as isHTMLFrameElement(Node)
+          is now efficient.
+        - Add an overload taking an HTMLElement in argument so that we can bypass
+          the isHTMLElement() check when we know the input is an HTMLElement.
+
+        * html/HTMLMediaElement.h:
+        (WebCore::HTMLMediaElement>):
+        Provide HTMLMediaElement template specialization for ElementTypeCastTraits
+        struct instead of isElementOfType().
+
+        * html/HTMLPlugInImageElement.h:
+        (WebCore::HTMLPlugInImageElement>):
+        Provide HTMLPlugInImageElement template specialization for
+        ElementTypeCastTraits struct instead of isElementOfType().
+
+        * html/LabelableElement.h:
+        (WebCore::LabelableElement>):
+        Provide LabelableElement template specialization for ElementTypeCastTraits
+        struct instead of isElementOfType().
+
+        * mathml/MathMLElement.h:
+        (WebCore::MathMLElement>):
+        Provide MathMLElement template specialization for ElementTypeCastTraits
+        struct for consistency with HTMLElement / SVGElement.
+
+        * svg/SVGElement.h:
+        (WebCore::SVGElement>):
+        - Provide SVGElement template specialization for ElementTypeCastTraits
+          struct instead of isElementOfType().
+        - include SVGElementTypeHelpers.h at the end of the file (similarly to
+          what is already done in HTMLElement.h because
+          isElementOfType(const SVGElement&) needs to be defiend because the
+          include.
+
+        * svg/SVGFilterPrimitiveStandardAttributes.h:
+        (WebCore::SVGFilterPrimitiveStandardAttributes>):
+        Provide SVGFilterPrimitiveStandardAttributes template specialization for
+        ElementTypeCastTraits struct instead of isElementOfType().
+
+        * svg/animation/SVGSMILElement.h:
+        (WebCore::SVGSMILElement>):
+        Provide SVGSMILElement template specialization for ElementTypeCastTraits
+        struct instead of isElementOfType().
+
+
 2014-08-07  Sergio Villar Senin  <svillar@igalia.com>
 
         [CSS Grid Layout] Sort items by span when resolving content-based track sizing functions
index 74c2fbb..1e37eec 100644 (file)
@@ -670,9 +670,24 @@ inline bool isElement(const Node& node) { return node.isElementNode(); }
 
 NODE_TYPE_CASTS(Element)
 
-template <typename Type> bool isElementOfType(const Element&);
-template <typename Type> inline bool isElementOfType(const Node& node) { return node.isElementNode() && isElementOfType<const Type>(toElement(node)); }
-template <> inline bool isElementOfType<const Element>(const Element&) { return true; }
+template <typename ExpectedType, typename ArgType>
+struct ElementTypeCastTraits {
+    static bool is(ArgType&);
+};
+
+// This is needed so that the compiler can deduce the second template parameter (ArgType).
+template <typename ExpectedType, typename ArgType>
+inline bool isElementOfType(const ArgType& node) { return ElementTypeCastTraits<ExpectedType, const ArgType>::is(node); }
+
+template <>
+struct ElementTypeCastTraits<const Element, const Node> {
+    static bool is(const Node& node) { return node.isElementNode(); }
+};
+
+template <typename ExpectedType>
+struct ElementTypeCastTraits<ExpectedType, ExpectedType> {
+    static bool is(ExpectedType&) { return true; }
+};
 
 inline bool Node::hasAttributes() const
 {
index a03b96d..fe67983 100644 (file)
@@ -92,16 +92,6 @@ inline Element* Traversal<Element>::firstWithinTemplate(CurrentType* current)
 
 template <>
 template <typename CurrentType>
-inline Element* Traversal<Element>::lastWithinTemplate(CurrentType* current)
-{
-    Node* node = NodeTraversal::last(current);
-    while (node && !node->isElementNode())
-        node = NodeTraversal::previous(node, current);
-    return toElement(node);
-}
-
-template <>
-template <typename CurrentType>
 inline Element* Traversal<Element>::nextTemplate(CurrentType* current)
 {
     Node* node = NodeTraversal::next(current);
@@ -120,24 +110,6 @@ inline Element* Traversal<Element>::nextTemplate(CurrentType* current, const Nod
     return toElement(node);
 }
 
-template <>
-inline Element* Traversal<Element>::previous(const Node* current)
-{
-    Node* node = NodeTraversal::previous(current);
-    while (node && !node->isElementNode())
-        node = NodeTraversal::previous(node);
-    return toElement(node);
-}
-
-template <>
-inline Element* Traversal<Element>::previous(const Node* current, const Node* stayWithin)
-{
-    Node* node = NodeTraversal::previous(current, stayWithin);
-    while (node && !node->isElementNode())
-        node = NodeTraversal::previous(node, stayWithin);
-    return toElement(node);
-}
-
 // Generic versions.
 template <typename ElementType>
 template <typename CurrentType>
@@ -163,58 +135,58 @@ template <typename ElementType>
 template <typename CurrentType>
 inline ElementType* Traversal<ElementType>::firstWithinTemplate(CurrentType* current)
 {
-    Element* element = Traversal<Element>::firstWithin(current);
-    while (element && !isElementOfType<const ElementType>(*element))
-        element = Traversal<Element>::next(element, current);
-    return static_cast<ElementType*>(element);
+    Node* node = current->firstChild();
+    while (node && !isElementOfType<const ElementType>(*node))
+        node = NodeTraversal::next(node, current);
+    return static_cast<ElementType*>(node);
 }
 
 template <typename ElementType>
 template <typename CurrentType>
 inline ElementType* Traversal<ElementType>::lastWithinTemplate(CurrentType* current)
 {
-    Element* element = Traversal<Element>::lastWithin(current);
-    while (element && !isElementOfType<const ElementType>(*element))
-        element = Traversal<Element>::previous(element, current);
-    return static_cast<ElementType*>(element);
+    Node* node = NodeTraversal::last(current);
+    while (node && !isElementOfType<const ElementType>(*node))
+        node = NodeTraversal::previous(node, current);
+    return static_cast<ElementType*>(node);
 }
 
 template <typename ElementType>
 template <typename CurrentType>
 inline ElementType* Traversal<ElementType>::nextTemplate(CurrentType* current)
 {
-    Element* element = Traversal<Element>::next(current);
-    while (element && !isElementOfType<const ElementType>(*element))
-        element = Traversal<Element>::next(element);
-    return static_cast<ElementType*>(element);
+    Node* node = NodeTraversal::next(current);
+    while (node && !isElementOfType<const ElementType>(*node))
+        node = NodeTraversal::next(node);
+    return static_cast<ElementType*>(node);
 }
 
 template <typename ElementType>
 template <typename CurrentType>
 inline ElementType* Traversal<ElementType>::nextTemplate(CurrentType* current, const Node* stayWithin)
 {
-    Element* element = Traversal<Element>::next(current, stayWithin);
-    while (element && !isElementOfType<const ElementType>(*element))
-        element = Traversal<Element>::next(element, stayWithin);
-    return static_cast<ElementType*>(element);
+    Node* node = NodeTraversal::next(current, stayWithin);
+    while (node && !isElementOfType<const ElementType>(*node))
+        node = NodeTraversal::next(node, stayWithin);
+    return static_cast<ElementType*>(node);
 }
 
 template <typename ElementType>
 inline ElementType* Traversal<ElementType>::previous(const Node* current)
 {
-    Element* element = Traversal<Element>::previous(current);
-    while (element && !isElementOfType<const ElementType>(*element))
-        element = Traversal<Element>::previous(element);
-    return static_cast<ElementType*>(element);
+    Node* node = NodeTraversal::previous(current);
+    while (node && !isElementOfType<const ElementType>(*node))
+        node = NodeTraversal::previous(node);
+    return static_cast<ElementType*>(node);
 }
 
 template <typename ElementType>
 inline ElementType* Traversal<ElementType>::previous(const Node* current, const Node* stayWithin)
 {
-    Element* element = Traversal<Element>::previous(current, stayWithin);
-    while (element && !isElementOfType<const ElementType>(*element))
-        element = Traversal<Element>::previous(element, stayWithin);
-    return static_cast<ElementType*>(element);
+    Node* node = NodeTraversal::previous(current, stayWithin);
+    while (node && !isElementOfType<const ElementType>(*node))
+        node = NodeTraversal::previous(node, stayWithin);
+    return static_cast<ElementType*>(node);
 }
 
 template <typename ElementType>
index a46f10b..389c2b8 100755 (executable)
@@ -642,40 +642,29 @@ void $checkHelper(const $class*); // Catch unnecessary runtime check of type kno
 END
         ;
 
-        if ($parameters{namespace} eq "HTML") {
-            if ($parsedTags{$name}{wrapperOnlyIfMediaIsAvailable}) {
-                # We need to check for HTMLUnknownElement if it might have been created by the factory.
-                print F <<END
+        if ($parameters{namespace} eq "HTML" && $parsedTags{$name}{wrapperOnlyIfMediaIsAvailable}) {
+            # We need to check for HTMLUnknownElement if it might have been created by the factory.
+            print F <<END
 inline bool $checkHelper(const HTMLElement& element) { return !element.isHTMLUnknownElement() && element.hasTagName($parameters{namespace}Names::${name}Tag); }
-inline bool $checkHelper(const HTMLElement* element) { ASSERT(element); return $checkHelper(*element); }
-END
-                ;
-            } else {
-                print F <<END
-inline bool $checkHelper(const HTMLElement& element) { return element.hasTagName(HTMLNames::${name}Tag); }
-inline bool $checkHelper(const HTMLElement* element) { ASSERT(element); return $checkHelper(*element); }
-END
-                ;
-            }
-
-                print F <<END
 inline bool $checkHelper(const Node& node) { return node.isHTMLElement() && $checkHelper(toHTMLElement(node)); }
-inline bool $checkHelper(const Node* node) { ASSERT(node); return $checkHelper(*node); }
-template <> inline bool isElementOfType<const $class>(const HTMLElement& element) { return $checkHelper(element); }
-template <> inline bool isElementOfType<const $class>(const Element& element) { return $checkHelper(element); }
 END
-                ;
-
+            ;
         } else {
             print F <<END
-inline bool $checkHelper(const Element& element) { return element.hasTagName($parameters{namespace}Names::${name}Tag); }
-inline bool $checkHelper(const Element* element) { ASSERT(element); return $checkHelper(*element); }
-inline bool $checkHelper(const Node& node) { return node.isElementNode() && $checkHelper(toElement(node)); }
-inline bool $checkHelper(const Node* node) { ASSERT(node); return node->isElementNode() && $checkHelper(toElement(node)); }
-template <> inline bool isElementOfType<const $class>(const Element& element) { return $checkHelper(element); }
+inline bool $checkHelper(const $parameters{namespace}Element& element) { return element.hasTagName($parameters{namespace}Names::${name}Tag); }
+inline bool $checkHelper(const Node& node) { return node.hasTagName($parameters{namespace}Names::${name}Tag); }
 END
             ;
         }
+        print F <<END
+inline bool $checkHelper(const $parameters{namespace}Element* element) { ASSERT(element); return $checkHelper(*element); }
+inline bool $checkHelper(const Node* node) { ASSERT(node); return $checkHelper(*node); }
+template <typename ArgType>
+struct ElementTypeCastTraits<const $class, ArgType> {
+    static bool is(ArgType& node) { return $checkHelper(node); }
+};
+END
+        ;
 
         print F "\n";
     }
index ba58781..6734be1 100644 (file)
@@ -146,12 +146,13 @@ inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document& document
     ASSERT(tagName.localName().impl());
 }
 
-template <typename Type> bool isElementOfType(const HTMLElement&);
-
 void isHTMLElement(const HTMLElement&); // Catch unnecessary runtime check of type known at compile time.
 inline bool isHTMLElement(const Node& node) { return node.isHTMLElement(); }
-template <> inline bool isElementOfType<const HTMLElement>(const HTMLElement&) { return true; }
-template <> inline bool isElementOfType<const HTMLElement>(const Element& element) { return element.isHTMLElement(); }
+
+template <typename ArgType>
+struct ElementTypeCastTraits<const HTMLElement, ArgType> {
+    static bool is(ArgType& node) { return isHTMLElement(node); }
+};
 
 NODE_TYPE_CASTS(HTMLElement)
 
index c10fcf8..d56cfaa 100644 (file)
@@ -193,7 +193,11 @@ private:
 void isHTMLFormControlElement(const HTMLFormControlElement&); // Catch unnecessary runtime check of type known at compile time.
 inline bool isHTMLFormControlElement(const Element& element) { return element.isFormControlElement(); }
 inline bool isHTMLFormControlElement(const Node& node) { return node.isElementNode() && toElement(node).isFormControlElement(); }
-template <> inline bool isElementOfType<const HTMLFormControlElement>(const Element& element) { return isHTMLFormControlElement(element); }
+
+template <typename ArgType>
+struct ElementTypeCastTraits<const HTMLFormControlElement, ArgType> {
+    static bool is(ArgType& node) { return isHTMLFormControlElement(node); }
+};
 
 NODE_TYPE_CASTS(HTMLFormControlElement)
 
index 5df749c..279ebd8 100644 (file)
@@ -77,8 +77,8 @@ private:
 };
 
 void isHTMLFrameElementBase(const HTMLFrameElementBase&); // Catch unnecessary runtime check of type known at compile time.
-inline bool isHTMLFrameElementBase(const Element& element) { return isHTMLFrameElement(element) || isHTMLIFrameElement(element); }
-inline bool isHTMLFrameElementBase(const Node& node) { return node.isElementNode() && isHTMLFrameElementBase(toElement(node)); }
+inline bool isHTMLFrameElementBase(const HTMLElement& element) { return isHTMLFrameElement(element) || isHTMLIFrameElement(element); }
+inline bool isHTMLFrameElementBase(const Node& node) { return isHTMLFrameElement(node) || isHTMLIFrameElement(node); }
 
 NODE_TYPE_CASTS(HTMLFrameElementBase)
 
index a142524..4834814 100644 (file)
@@ -916,7 +916,11 @@ struct ValueToString<TextTrackCue*> {
 void isHTMLMediaElement(const HTMLMediaElement&); // Catch unnecessary runtime check of type known at compile time.
 inline bool isHTMLMediaElement(const Element& element) { return element.isMediaElement(); }
 inline bool isHTMLMediaElement(const Node& node) { return node.isElementNode() && toElement(node).isMediaElement(); }
-template <> inline bool isElementOfType<const HTMLMediaElement>(const Element& element) { return element.isMediaElement(); }
+
+template <typename ArgType>
+struct ElementTypeCastTraits<const HTMLMediaElement, ArgType> {
+    static bool is(ArgType& node) { return isHTMLMediaElement(node); }
+};
 
 NODE_TYPE_CASTS(HTMLMediaElement)
 
index 856fc26..73361a0 100644 (file)
@@ -160,7 +160,12 @@ private:
 void isHTMLPlugInImageElement(const HTMLPlugInImageElement&); // Catch unnecessary runtime check of type known at compile time.
 inline bool isHTMLPlugInImageElement(const HTMLPlugInElement& element) { return element.isPlugInImageElement(); }
 inline bool isHTMLPlugInImageElement(const Node& node) { return node.isPluginElement() && toHTMLPlugInElement(node).isPlugInImageElement(); }
-template <> inline bool isElementOfType<const HTMLPlugInImageElement>(const Element& element) { return isHTMLPlugInImageElement(element); }
+
+template <typename ArgType>
+struct ElementTypeCastTraits<const HTMLPlugInImageElement, ArgType> {
+    static bool is(ArgType& node) { return isHTMLPlugInImageElement(node); }
+};
+
 NODE_TYPE_CASTS(HTMLPlugInImageElement)
 
 } // namespace WebCore
index 014f111..bbad69d 100644 (file)
@@ -53,7 +53,11 @@ private:
 void isLabelableElement(const LabelableElement&); // Catch unnecessary runtime check of type known at compile time.
 inline bool isLabelableElement(const HTMLElement& element) { return element.isLabelable(); }
 inline bool isLabelableElement(const Node& node) { return node.isHTMLElement() && toHTMLElement(node).isLabelable(); }
-template <> inline bool isElementOfType<const LabelableElement>(const Element& element) { return isLabelableElement(element); }
+
+template <typename ArgType>
+struct ElementTypeCastTraits<const LabelableElement, ArgType> {
+    static bool is(ArgType& node) { return isLabelableElement(node); }
+};
 
 NODE_TYPE_CASTS(LabelableElement)
 
index f9c3bcf..801b194 100644 (file)
@@ -75,6 +75,12 @@ private:
 
 void isMathMLElement(const MathMLElement&); // Catch unnecessary runtime check of type known at compile time.
 inline bool isMathMLElement(const Node& node) { return node.isMathMLElement(); }
+
+template <typename ArgType>
+struct ElementTypeCastTraits<const MathMLElement, ArgType> {
+    static bool is(ArgType& node) { return isMathMLElement(node); }
+};
+
 NODE_TYPE_CASTS(MathMLElement)
 
 inline bool Node::hasTagName(const MathMLQualifiedName& name) const
index c5c17f8..bedd879 100644 (file)
@@ -25,9 +25,9 @@
 
 #include "CSSPropertyNames.h"
 #include "SVGAnimatedString.h"
-#include "SVGElementTypeHelpers.h"
 #include "SVGLangSpace.h"
 #include "SVGLocatable.h"
+#include "SVGNames.h"
 #include "SVGParsingError.h"
 #include "SVGPropertyInfo.h"
 #include "StyledElement.h"
@@ -225,7 +225,11 @@ struct SVGAttributeHashTranslator {
 
 void isSVGElement(const SVGElement&); // Catch unnecessary runtime check of type known at compile time.
 inline bool isSVGElement(const Node& node) { return node.isSVGElement(); }
-template <> inline bool isElementOfType<const SVGElement>(const Element& element) { return element.isSVGElement(); }
+
+template <typename ArgType>
+struct ElementTypeCastTraits<const SVGElement, ArgType> {
+    static bool is(ArgType& node) { return isSVGElement(node); }
+};
 
 NODE_TYPE_CASTS(SVGElement)
 
@@ -234,6 +238,8 @@ inline bool Node::hasTagName(const SVGQualifiedName& name) const
     return isSVGElement() && toSVGElement(*this).hasTagName(name);
 }
 
-}
+} // namespace WebCore
+
+#include "SVGElementTypeHelpers.h"
 
 #endif
index 5fdcb66..81b63e3 100644 (file)
@@ -85,7 +85,11 @@ void invalidateFilterPrimitiveParent(SVGElement*);
 void isSVGFilterPrimitiveStandardAttributes(const SVGFilterPrimitiveStandardAttributes&); // Catch unnecessary runtime check of type known at compile time.
 inline bool isSVGFilterPrimitiveStandardAttributes(const SVGElement& element) { return element.isFilterEffect(); }
 inline bool isSVGFilterPrimitiveStandardAttributes(const Node& node) { return node.isSVGElement() && toSVGElement(node).isFilterEffect(); }
-template <> inline bool isElementOfType<const SVGFilterPrimitiveStandardAttributes>(const Element& element) { return isSVGFilterPrimitiveStandardAttributes(element); }
+
+template <typename ArgType>
+struct ElementTypeCastTraits<const SVGFilterPrimitiveStandardAttributes, ArgType> {
+    static bool is(ArgType& node) { return isSVGFilterPrimitiveStandardAttributes(node); }
+};
 
 NODE_TYPE_CASTS(SVGFilterPrimitiveStandardAttributes)
 
index 1eef318..bfdd10e 100644 (file)
@@ -240,7 +240,12 @@ private:
 void isSVGSMILElement(const SVGSMILElement&); // Catch unnecessary runtime check of type known at compile time.
 inline bool isSVGSMILElement(const SVGElement& element) { return element.isSMILElement(); }
 inline bool isSVGSMILElement(const Node& node) { return node.isSVGElement() && toSVGElement(node).isSMILElement(); }
-template <> inline bool isElementOfType<const SVGSMILElement>(const Element& element) { return isSVGSMILElement(element); }
+
+template <typename ArgType>
+struct ElementTypeCastTraits<const SVGSMILElement, ArgType> {
+    static bool is(ArgType& node) { return isSVGSMILElement(node); }
+};
+
 
 NODE_TYPE_CASTS(SVGSMILElement)