Add initial is<>() / downcast<>() support for any type of Nodes
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Sep 2014 03:50:40 +0000 (03:50 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Sep 2014 03:50:40 +0000 (03:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=137056

Reviewed by Benjamin Poulain.

Source/WebCore:

Add initial is<>() / downcast<>() support for any type of Nodes, not
just Elements by:
- Moving the is<>() / downcast<>() declarations from Element.h to
  Node.h
- Introducing a SPECIALIZE_TYPE_TRAITS_*() macro that generates the
  needed template specializations for is<>() / downcast<>() to work.
  This macro will replace NODE_TYPE_CASTS() entirely once the code base
  is fully ported.

This patch makes use of SPECIALIZE_TYPE_TRAITS_*() macro for
HTMLFormControlElement, that is an HTMLElement for which the template
specializations cannot be automatically generated because it requires
special handling.

This patch also makes use of SPECIALIZE_TYPE_TRAITS_*() macro for
DocumentFragment to show that it can be used for non-Element Nodes.

No new tests, no behavior change.

* accessibility/AccessibilityNodeObject.cpp:
(WebCore::AccessibilityNodeObject::isReadOnly):
(WebCore::AccessibilityNodeObject::isRequired):
(WebCore::AccessibilityNodeObject::isControl):
* css/SelectorCheckerTestFunctions.h:
(WebCore::isAutofilled):
(WebCore::isDisabled):
(WebCore::isEnabled):
* css/StyleResolver.cpp:
(WebCore::StyleResolver::canShareStyleWithElement):
(WebCore::StyleResolver::adjustRenderStyle):
* dom/Document.cpp:
(WebCore::Document::importNode):
(WebCore::Document::setFocusedElement):
* dom/DocumentFragment.h:
(WebCore::isDocumentFragment):
* dom/Element.cpp:
(WebCore::Element::focus):
* dom/Element.h:
(WebCore::is): Deleted.
(WebCore::downcast): Deleted.
* dom/Node.h:
(WebCore::is):
(WebCore::downcast):
* dom/make_names.pl:
(printTypeHelpers):
* editing/FrameSelection.cpp:
(WebCore::scanForForm):
* editing/TextIterator.cpp:
(WebCore::isRendererReplacedElement):
* html/FormAssociatedElement.h:
* html/HTMLElement.h:
* html/HTMLFieldSetElement.cpp:
(WebCore::updateFromControlElementsAncestorDisabledStateUnder):
(WebCore::HTMLFieldSetElement::refreshElementsIfNeeded):
* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::enclosingFormControlElement):
* html/HTMLFormControlElement.h:
(WebCore::isHTMLFormControlElement):
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::submitImplicitly):
(WebCore::submitElementFromEvent):
(WebCore::HTMLFormElement::validateInteractively):
(WebCore::HTMLFormElement::submit):
(WebCore::HTMLFormElement::reset):
(WebCore::HTMLFormElement::formElementIndex):
(WebCore::HTMLFormElement::defaultButton):
(WebCore::HTMLFormElement::checkInvalidControlsAndCollectUnhandled):
(WebCore::HTMLFormElement::documentDidResumeFromPageCache):
* html/HTMLMediaElement.h:
* html/HTMLPlugInImageElement.h:
* html/HTMLSummaryElement.cpp:
(WebCore::isClickableControl):
* html/LabelableElement.h:
* html/RadioNodeList.cpp:
(WebCore::RadioNodeList::checkElementMatchesRadioNodeListFilter):
(WebCore::RadioNodeList::elementMatches):
* html/parser/HTMLConstructionSite.cpp:
(WebCore::HTMLConstructionSite::findFosterSite):
* html/parser/HTMLTreeBuilder.cpp:
(WebCore::disallowTelephoneNumberParsing):
* loader/FormSubmission.cpp:
(WebCore::FormSubmission::create):
* mathml/MathMLElement.h:
* page/ContextMenuController.cpp:
(WebCore::ContextMenuController::populate):
* page/Frame.cpp:
(WebCore::Frame::searchForLabelsBeforeElement):
* rendering/RenderButton.cpp:
(WebCore::RenderButton::formControlElement):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::resize):
* rendering/RenderTheme.cpp:
(WebCore::RenderTheme::isReadOnlyControl):
* svg/SVGElement.h:
* svg/SVGFilterPrimitiveStandardAttributes.h:
* svg/animation/SVGSMILElement.h:

Source/WebKit/mac:

Use is<HTMLFormControlElement>() / downcast<HTMLFormControlElement>()
instead of isFormControlElement() / toHTMLFormControlElement().

* WebView/WebHTMLRepresentation.mm:
(searchForLabelsBeforeElement):

Source/WebKit/win:

Use is<HTMLFormControlElement>() / downcast<HTMLFormControlElement>()
instead of isFormControlElement() / toHTMLFormControlElement().

* WebFrame.cpp:
(WebFrame::elementWithName):

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

39 files changed:
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityNodeObject.cpp
Source/WebCore/css/SelectorCheckerTestFunctions.h
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/DocumentFragment.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/Node.h
Source/WebCore/dom/make_names.pl
Source/WebCore/editing/FrameSelection.cpp
Source/WebCore/editing/TextIterator.cpp
Source/WebCore/html/FormAssociatedElement.h
Source/WebCore/html/HTMLElement.h
Source/WebCore/html/HTMLFieldSetElement.cpp
Source/WebCore/html/HTMLFormControlElement.cpp
Source/WebCore/html/HTMLFormControlElement.h
Source/WebCore/html/HTMLFormElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLPlugInImageElement.h
Source/WebCore/html/HTMLSummaryElement.cpp
Source/WebCore/html/LabelableElement.h
Source/WebCore/html/RadioNodeList.cpp
Source/WebCore/html/parser/HTMLConstructionSite.cpp
Source/WebCore/html/parser/HTMLTreeBuilder.cpp
Source/WebCore/loader/FormSubmission.cpp
Source/WebCore/mathml/MathMLElement.h
Source/WebCore/page/ContextMenuController.cpp
Source/WebCore/page/Frame.cpp
Source/WebCore/rendering/RenderButton.cpp
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderTheme.cpp
Source/WebCore/svg/SVGElement.h
Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h
Source/WebCore/svg/animation/SVGSMILElement.h
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebHTMLRepresentation.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/WebFrame.cpp

index ae04b7b..dabcc36 100644 (file)
@@ -1,3 +1,107 @@
+2014-09-24  Christophe Dumez  <cdumez@apple.com>
+
+        Add initial is<>() / downcast<>() support for any type of Nodes
+        https://bugs.webkit.org/show_bug.cgi?id=137056
+
+        Reviewed by Benjamin Poulain.
+
+        Add initial is<>() / downcast<>() support for any type of Nodes, not
+        just Elements by:
+        - Moving the is<>() / downcast<>() declarations from Element.h to
+          Node.h
+        - Introducing a SPECIALIZE_TYPE_TRAITS_*() macro that generates the
+          needed template specializations for is<>() / downcast<>() to work.
+          This macro will replace NODE_TYPE_CASTS() entirely once the code base
+          is fully ported.
+
+        This patch makes use of SPECIALIZE_TYPE_TRAITS_*() macro for
+        HTMLFormControlElement, that is an HTMLElement for which the template
+        specializations cannot be automatically generated because it requires
+        special handling.
+
+        This patch also makes use of SPECIALIZE_TYPE_TRAITS_*() macro for
+        DocumentFragment to show that it can be used for non-Element Nodes.
+
+        No new tests, no behavior change.
+
+        * accessibility/AccessibilityNodeObject.cpp:
+        (WebCore::AccessibilityNodeObject::isReadOnly):
+        (WebCore::AccessibilityNodeObject::isRequired):
+        (WebCore::AccessibilityNodeObject::isControl):
+        * css/SelectorCheckerTestFunctions.h:
+        (WebCore::isAutofilled):
+        (WebCore::isDisabled):
+        (WebCore::isEnabled):
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::canShareStyleWithElement):
+        (WebCore::StyleResolver::adjustRenderStyle):
+        * dom/Document.cpp:
+        (WebCore::Document::importNode):
+        (WebCore::Document::setFocusedElement):
+        * dom/DocumentFragment.h:
+        (WebCore::isDocumentFragment):
+        * dom/Element.cpp:
+        (WebCore::Element::focus):
+        * dom/Element.h:
+        (WebCore::is): Deleted.
+        (WebCore::downcast): Deleted.
+        * dom/Node.h:
+        (WebCore::is):
+        (WebCore::downcast):
+        * dom/make_names.pl:
+        (printTypeHelpers):
+        * editing/FrameSelection.cpp:
+        (WebCore::scanForForm):
+        * editing/TextIterator.cpp:
+        (WebCore::isRendererReplacedElement):
+        * html/FormAssociatedElement.h:
+        * html/HTMLElement.h:
+        * html/HTMLFieldSetElement.cpp:
+        (WebCore::updateFromControlElementsAncestorDisabledStateUnder):
+        (WebCore::HTMLFieldSetElement::refreshElementsIfNeeded):
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::enclosingFormControlElement):
+        * html/HTMLFormControlElement.h:
+        (WebCore::isHTMLFormControlElement):
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::submitImplicitly):
+        (WebCore::submitElementFromEvent):
+        (WebCore::HTMLFormElement::validateInteractively):
+        (WebCore::HTMLFormElement::submit):
+        (WebCore::HTMLFormElement::reset):
+        (WebCore::HTMLFormElement::formElementIndex):
+        (WebCore::HTMLFormElement::defaultButton):
+        (WebCore::HTMLFormElement::checkInvalidControlsAndCollectUnhandled):
+        (WebCore::HTMLFormElement::documentDidResumeFromPageCache):
+        * html/HTMLMediaElement.h:
+        * html/HTMLPlugInImageElement.h:
+        * html/HTMLSummaryElement.cpp:
+        (WebCore::isClickableControl):
+        * html/LabelableElement.h:
+        * html/RadioNodeList.cpp:
+        (WebCore::RadioNodeList::checkElementMatchesRadioNodeListFilter):
+        (WebCore::RadioNodeList::elementMatches):
+        * html/parser/HTMLConstructionSite.cpp:
+        (WebCore::HTMLConstructionSite::findFosterSite):
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::disallowTelephoneNumberParsing):
+        * loader/FormSubmission.cpp:
+        (WebCore::FormSubmission::create):
+        * mathml/MathMLElement.h:
+        * page/ContextMenuController.cpp:
+        (WebCore::ContextMenuController::populate):
+        * page/Frame.cpp:
+        (WebCore::Frame::searchForLabelsBeforeElement):
+        * rendering/RenderButton.cpp:
+        (WebCore::RenderButton::formControlElement):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::resize):
+        * rendering/RenderTheme.cpp:
+        (WebCore::RenderTheme::isReadOnlyControl):
+        * svg/SVGElement.h:
+        * svg/SVGFilterPrimitiveStandardAttributes.h:
+        * svg/animation/SVGSMILElement.h:
+
 2014-09-24  Darin Adler  <darin@apple.com>
 
         Old Turkic characters behave as left-to-right instead of right-to-left, because they are encoded as surrogate pairs.
index 34b532f..262fb97 100644 (file)
@@ -739,7 +739,7 @@ bool AccessibilityNodeObject::isReadOnly() const
         return true;
 
     if (is<HTMLTextAreaElement>(node))
-        return toHTMLFormControlElement(node)->isReadOnly();
+        return downcast<HTMLTextAreaElement>(node)->isReadOnly();
 
     if (is<HTMLInputElement>(node)) {
         HTMLInputElement& input = downcast<HTMLInputElement>(*node);
@@ -760,8 +760,8 @@ bool AccessibilityNodeObject::isRequired() const
         return false;
 
     Node* n = this->node();
-    if (n && (n->isElementNode() && toElement(n)->isFormControlElement()))
-        return toHTMLFormControlElement(n)->isRequired();
+    if (n && is<HTMLFormControlElement>(n))
+        return downcast<HTMLFormControlElement>(n)->isRequired();
 
     return false;
 }
@@ -898,8 +898,7 @@ bool AccessibilityNodeObject::isControl() const
     if (!node)
         return false;
 
-    return ((node->isElementNode() && toElement(node)->isFormControlElement())
-        || AccessibilityObject::isARIAControl(ariaRoleAttribute()));
+    return is<HTMLFormControlElement>(node) || AccessibilityObject::isARIAControl(ariaRoleAttribute());
 }
 
 bool AccessibilityNodeObject::isFieldset() const
index 546ecae..0ce2115 100644 (file)
@@ -44,7 +44,7 @@ namespace WebCore {
 
 ALWAYS_INLINE bool isAutofilled(const Element* element)
 {
-    if (element->isFormControlElement()) {
+    if (is<HTMLFormControlElement>(element)) {
         if (const HTMLInputElement* inputElement = element->toInputElement())
             return inputElement->isAutofilled();
     }
@@ -58,7 +58,7 @@ ALWAYS_INLINE bool isDefaultButtonForForm(const Element* element)
 
 ALWAYS_INLINE bool isDisabled(const Element* element)
 {
-    if (element->isFormControlElement() || is<HTMLOptionElement>(element) || is<HTMLOptGroupElement>(element))
+    if (is<HTMLFormControlElement>(element) || is<HTMLOptionElement>(element) || is<HTMLOptGroupElement>(element))
         return element->isDisabledFormControl();
     return false;
 }
@@ -66,7 +66,7 @@ ALWAYS_INLINE bool isDisabled(const Element* element)
 ALWAYS_INLINE bool isEnabled(const Element* element)
 {
     bool isEnabled = false;
-    if (element->isFormControlElement() || is<HTMLOptionElement>(element) || is<HTMLOptGroupElement>(element))
+    if (is<HTMLFormControlElement>(element) || is<HTMLOptionElement>(element) || is<HTMLOptGroupElement>(element))
         isEnabled = !element->isDisabledFormControl();
     else if (element->isLink())
         isEnabled = is<HTMLAnchorElement>(element) || is<HTMLAreaElement>(element);
index 068732c..90766bb 100644 (file)
@@ -626,9 +626,9 @@ bool StyleResolver::canShareStyleWithElement(StyledElement* element) const
     if (element->hasID() && m_ruleSets.features().idsInRules.contains(element->idForStyleResolution().impl()))
         return false;
 
-    bool isControl = element->isFormControlElement();
+    bool isControl = is<HTMLFormControlElement>(element);
 
-    if (isControl != state.element()->isFormControlElement())
+    if (isControl != is<HTMLFormControlElement>(state.element()))
         return false;
 
     if (isControl && !canShareStyleWithControl(element))
@@ -1335,7 +1335,7 @@ void StyleResolver::adjustRenderStyle(RenderStyle& style, const RenderStyle& par
 
     // Important: Intrinsic margins get added to controls before the theme has adjusted the style, since the theme will
     // alter fonts and heights/widths.
-    if (e && e->isFormControlElement() && style.fontSize() >= 11) {
+    if (e && is<HTMLFormControlElement>(e) && style.fontSize() >= 11) {
         // Don't apply intrinsic margins to image buttons. The designer knows how big the images are,
         // so we have to treat all image buttons as though they were explicitly sized.
         if (!is<HTMLInputElement>(e) || !downcast<HTMLInputElement>(*e).isImageButton())
index a3cf529..070d0e7 100644 (file)
@@ -973,7 +973,7 @@ PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCo
             // Either they are imported along with their host node, or created implicitly.
             break;
         }
-        DocumentFragment& oldFragment = toDocumentFragment(*importedNode);
+        DocumentFragment& oldFragment = downcast<DocumentFragment>(*importedNode);
         RefPtr<DocumentFragment> newFragment = createDocumentFragment();
         if (deep) {
             for (Node* oldChild = oldFragment.firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
@@ -3410,10 +3410,10 @@ bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, Focus
         oldFocusedElement->setFocus(false);
 
         // Dispatch a change event for form control elements that have been edited.
-        if (oldFocusedElement->isFormControlElement()) {
-            HTMLFormControlElement* formControlElement = toHTMLFormControlElement(oldFocusedElement.get());
-            if (formControlElement->wasChangedSinceLastFormControlChangeEvent())
-                formControlElement->dispatchFormControlChangeEvent();
+        if (is<HTMLFormControlElement>(*oldFocusedElement)) {
+            HTMLFormControlElement& formControlElement = downcast<HTMLFormControlElement>(*oldFocusedElement);
+            if (formControlElement.wasChangedSinceLastFormControlChangeEvent())
+                formControlElement.dispatchFormControlChangeEvent();
         }
 
         // Dispatch the blur event and let the node do any other blur related activities (important for text fields)
index 8eb9387..ac7d6f6 100644 (file)
@@ -52,10 +52,9 @@ private:
     virtual bool childTypeAllowed(NodeType) const override;
 };
 
-inline bool isDocumentFragment(const Node& node) { return node.isDocumentFragment(); }
-void isDocumentFragment(const DocumentFragment&); // Catch unnecessary runtime check of type known at compile time.
-
-NODE_TYPE_CASTS(DocumentFragment)
+SPECIALIZE_TYPE_TRAITS_BEGIN(DocumentFragment)
+    static bool isDocumentFragment(const Node& node) { return node.isDocumentFragment(); }
+SPECIALIZE_TYPE_TRAITS_END()
 
 } //namespace
 
index 7242e5b..6a9f870 100644 (file)
@@ -1928,7 +1928,7 @@ void Element::focus(bool restorePreviousSelection, FocusDirection direction)
     // Calling updateFocusAppearance() would generate an unnecessary call to ScrollView::setScrollPosition(),
     // which would jump us around during this animation. See <rdar://problem/6699741>.
     FrameView* view = document().view();
-    bool isFormControl = view && isFormControlElement();
+    bool isFormControl = view && is<HTMLFormControlElement>(*this);
     if (isFormControl)
         view->setProhibitsScrolling(true);
 #endif
index 16ed632..2892bdf 100644 (file)
@@ -670,52 +670,11 @@ inline bool isElement(const Node& node) { return node.isElementNode(); }
 
 NODE_TYPE_CASTS(Element)
 
-template <typename ExpectedType, typename ArgType>
-struct ElementTypeCastTraits {
-    static bool is(ArgType&);
-};
-
-// Type checking function for Elements, to use before casting with downcast<>().
-template <typename ExpectedType, typename ArgType>
-inline bool is(ArgType& node)
-{
-    static_assert(!std::is_base_of<ExpectedType, ArgType>::value, "Unnecessary type check");
-    return ElementTypeCastTraits<const ExpectedType, const ArgType>::is(node);
-}
-
-template <typename ExpectedType, typename ArgType>
-inline bool is(ArgType* node)
-{
-    ASSERT(node);
-    static_assert(!std::is_base_of<ExpectedType, ArgType>::value, "Unnecessary type check");
-    return ElementTypeCastTraits<const ExpectedType, const ArgType>::is(*node);
-}
-
 template <>
-struct ElementTypeCastTraits<const Element, const Node> {
+struct NodeTypeCastTraits<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; }
-};
-
-// Downcasting functions for Element types.
-template<typename Target, typename Source>
-inline typename std::conditional<std::is_const<Source>::value, const Target&, Target&>::type downcast(Source& source)
-{
-    static_assert(!std::is_base_of<Target, Source>::value, "Unnecessary cast");
-    ASSERT_WITH_SECURITY_IMPLICATION(is<Target>(source));
-    return static_cast<typename std::conditional<std::is_const<Source>::value, const Target&, Target&>::type>(source);
-}
-template<typename Target, typename Source> inline typename std::conditional<std::is_const<Source>::value, const Target*, Target*>::type downcast(Source* source)
-{
-    static_assert(!std::is_base_of<Target, Source>::value, "Unnecessary cast");
-    ASSERT_WITH_SECURITY_IMPLICATION(!source || is<Target>(*source));
-    return static_cast<typename std::conditional<std::is_const<Source>::value, const Target*, Target*>::type>(source);
-}
-
 inline bool Node::hasAttributes() const
 {
     return isElementNode() && toElement(this)->hasAttributes();
index f469fe5..c881725 100644 (file)
@@ -739,6 +739,59 @@ inline ContainerNode* Node::parentNodeGuaranteedHostFree() const
     return parentNode();
 }
 
+template <typename ExpectedType, typename ArgType>
+struct NodeTypeCastTraits {
+    static bool is(ArgType&);
+};
+
+template <typename ExpectedType>
+struct NodeTypeCastTraits<ExpectedType, ExpectedType> {
+    static bool is(ExpectedType&) { return true; }
+};
+
+// Type checking function for Nodes, to use before casting with downcast<>().
+template <typename ExpectedType, typename ArgType>
+inline bool is(ArgType& node)
+{
+    static_assert(!std::is_base_of<ExpectedType, ArgType>::value, "Unnecessary type check");
+    return NodeTypeCastTraits<const ExpectedType, const ArgType>::is(node);
+}
+
+template <typename ExpectedType, typename ArgType>
+inline bool is(ArgType* node)
+{
+    ASSERT(node);
+    static_assert(!std::is_base_of<ExpectedType, ArgType>::value, "Unnecessary type check");
+    return NodeTypeCastTraits<const ExpectedType, const ArgType>::is(*node);
+}
+
+// Downcasting functions for Node types.
+template<typename Target, typename Source>
+inline typename std::conditional<std::is_const<Source>::value, const Target&, Target&>::type downcast(Source& source)
+{
+    static_assert(!std::is_base_of<Target, Source>::value, "Unnecessary cast");
+    ASSERT_WITH_SECURITY_IMPLICATION(is<Target>(source));
+    return static_cast<typename std::conditional<std::is_const<Source>::value, const Target&, Target&>::type>(source);
+}
+template<typename Target, typename Source> inline typename std::conditional<std::is_const<Source>::value, const Target*, Target*>::type downcast(Source* source)
+{
+    static_assert(!std::is_base_of<Target, Source>::value, "Unnecessary cast");
+    ASSERT_WITH_SECURITY_IMPLICATION(!source || is<Target>(*source));
+    return static_cast<typename std::conditional<std::is_const<Source>::value, const Target*, Target*>::type>(source);
+}
+
+// Add support for type checking / casting using is<>() / downcast<>() helpers for a specific class.
+#define SPECIALIZE_TYPE_TRAITS_BEGIN(ClassName) \
+    template <typename ArgType> \
+    class NodeTypeCastTraits<const ClassName, ArgType> { \
+    public: \
+        static bool is(ArgType& node) { return is##ClassName(node); } \
+    private:
+
+#define SPECIALIZE_TYPE_TRAITS_END() \
+    };
+
+// FIXME: This should be removed and all uses should be replaced with SPECIALIZE_TYPE_TRAITS_*().
 #define NODE_TYPE_CASTS(ToClassName) \
     TYPE_CASTS_BASE(ToClassName, Node, node, WebCore::is##ToClassName(*node), WebCore::is##ToClassName(node))
 
index 18a71f8..ae9dc3b 100755 (executable)
@@ -636,7 +636,7 @@ sub printTypeHelpers
         print F <<END
 class $class;
 template <typename ArgType>
-class ElementTypeCastTraits<const $class, ArgType> {
+class NodeTypeCastTraits<const $class, ArgType> {
 public:
     static bool is(ArgType& node) { return checkTagName(node); }
 private:
index b7629cf..5ef4856 100644 (file)
@@ -2025,8 +2025,8 @@ static HTMLFormElement* scanForForm(Element* start)
         HTMLElement& element = *it;
         if (isHTMLFormElement(&element))
             return downcast<HTMLFormElement>(&element);
-        if (isHTMLFormControlElement(element))
-            return toHTMLFormControlElement(element).form();
+        if (is<HTMLFormControlElement>(element))
+            return downcast<HTMLFormControlElement>(element).form();
         if (isHTMLFrameElementBase(element)) {
             Document* contentDocument = toHTMLFrameElementBase(element).contentDocument();
             if (!contentDocument)
index d8c2513..11177ae 100644 (file)
@@ -256,7 +256,7 @@ bool isRendererReplacedElement(RenderObject* renderer)
 
     if (renderer->node() && renderer->node()->isElementNode()) {
         Element& element = toElement(*renderer->node());
-        if (element.isFormControlElement() || element.hasTagName(legendTag) || element.hasTagName(meterTag) || element.hasTagName(progressTag))
+        if (is<HTMLFormControlElement>(element) || is<HTMLLegendElement>(element) || is<HTMLMeterElement>(element) || is<HTMLProgressElement>(element))
             return true;
         if (equalIgnoringCase(element.fastGetAttribute(roleAttr), "img"))
             return true;
index ec94240..a8512a0 100644 (file)
@@ -118,9 +118,6 @@ private:
     String m_customValidationMessage;
 };
 
-#define FORM_ASSOCIATED_ELEMENT_TYPE_CASTS(ToClassName, predicate) \
-    TYPE_CASTS_BASE(ToClassName, FormAssociatedElement, element, element->predicate, element.predicate)
-
 } // namespace
 
 #endif // FormAssociatedElement_h
index 6734be1..6f823a0 100644 (file)
@@ -150,7 +150,7 @@ void isHTMLElement(const HTMLElement&); // Catch unnecessary runtime check of ty
 inline bool isHTMLElement(const Node& node) { return node.isHTMLElement(); }
 
 template <typename ArgType>
-struct ElementTypeCastTraits<const HTMLElement, ArgType> {
+struct NodeTypeCastTraits<const HTMLElement, ArgType> {
     static bool is(ArgType& node) { return isHTMLElement(node); }
 };
 
index 04619b5..5fd2d4c 100644 (file)
@@ -58,8 +58,8 @@ PassRefPtr<HTMLFieldSetElement> HTMLFieldSetElement::create(const QualifiedName&
 static void updateFromControlElementsAncestorDisabledStateUnder(HTMLElement& startNode, bool isDisabled)
 {
     HTMLFormControlElement* control;
-    if (isHTMLFormControlElement(startNode))
-        control = &toHTMLFormControlElement(startNode);
+    if (is<HTMLFormControlElement>(startNode))
+        control = &downcast<HTMLFormControlElement>(startNode);
     else
         control = Traversal<HTMLFormControlElement>::firstWithin(&startNode);
     while (control) {
@@ -167,8 +167,8 @@ void HTMLFieldSetElement::refreshElementsIfNeeded() const
     for (auto& element : descendantsOfType<Element>(const_cast<HTMLFieldSetElement&>(*this))) {
         if (element.hasTagName(objectTag))
             m_associatedElements.append(&downcast<HTMLObjectElement>(element));
-        else if (element.isFormControlElement())
-            m_associatedElements.append(&toHTMLFormControlElement(element));
+        else if (is<HTMLFormControlElement>(element))
+            m_associatedElements.append(&downcast<HTMLFormControlElement>(element));
     }
 }
 
index bcad276..8c7af16 100644 (file)
@@ -508,10 +508,10 @@ void HTMLFormControlElement::setAutocapitalize(const AtomicString& value)
 HTMLFormControlElement* HTMLFormControlElement::enclosingFormControlElement(Node* node)
 {
     for (; node; node = node->parentNode()) {
-        if (node->isElementNode() && toElement(node)->isFormControlElement())
-            return toHTMLFormControlElement(node);
+        if (is<HTMLFormControlElement>(node))
+            return downcast<HTMLFormControlElement>(node);
     }
-    return 0;
+    return nullptr;
 }
 
 } // namespace Webcore
index d56cfaa..d92083a 100644 (file)
@@ -190,18 +190,11 @@ private:
     bool m_hasAutofocused : 1;
 };
 
-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 <typename ArgType>
-struct ElementTypeCastTraits<const HTMLFormControlElement, ArgType> {
-    static bool is(ArgType& node) { return isHTMLFormControlElement(node); }
-};
-
-NODE_TYPE_CASTS(HTMLFormControlElement)
-
-FORM_ASSOCIATED_ELEMENT_TYPE_CASTS(HTMLFormControlElement, isFormControlElement())
+SPECIALIZE_TYPE_TRAITS_BEGIN(HTMLFormControlElement)
+    static bool isHTMLFormControlElement(const Element& element) { return element.isFormControlElement(); }
+    static bool isHTMLFormControlElement(const Node& node) { return node.isElementNode() && toElement(node).isFormControlElement(); }
+    static bool isHTMLFormControlElement(const FormAssociatedElement& element) { return element.isFormControlElement(); }
+SPECIALIZE_TYPE_TRAITS_END()
 
 } // namespace
 
index e39c84f..dcd2a88 100644 (file)
@@ -182,15 +182,15 @@ void HTMLFormElement::submitImplicitly(Event* event, bool fromImplicitSubmission
     unsigned submissionTriggerCount = 0;
     for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
         FormAssociatedElement* formAssociatedElement = m_associatedElements[i];
-        if (!formAssociatedElement->isFormControlElement())
+        if (!is<HTMLFormControlElement>(formAssociatedElement))
             continue;
-        HTMLFormControlElement* formElement = toHTMLFormControlElement(formAssociatedElement);
-        if (formElement->isSuccessfulSubmitButton()) {
-            if (formElement->renderer()) {
-                formElement->dispatchSimulatedClick(event);
+        HTMLFormControlElement& formElement = downcast<HTMLFormControlElement>(*formAssociatedElement);
+        if (formElement.isSuccessfulSubmitButton()) {
+            if (formElement.renderer()) {
+                formElement.dispatchSimulatedClick(event);
                 return;
             }
-        } else if (formElement->canTriggerImplicitSubmission())
+        } else if (formElement.canTriggerImplicitSubmission())
             ++submissionTriggerCount;
     }
 
@@ -206,10 +206,10 @@ void HTMLFormElement::submitImplicitly(Event* event, bool fromImplicitSubmission
 static inline HTMLFormControlElement* submitElementFromEvent(const Event* event)
 {
     for (Node* node = event->target()->toNode(); node; node = node->parentNode()) {
-        if (node->isElementNode() && toElement(node)->isFormControlElement())
-            return toHTMLFormControlElement(node);
+        if (is<HTMLFormControlElement>(node))
+            return downcast<HTMLFormControlElement>(node);
     }
-    return 0;
+    return nullptr;
 }
 
 bool HTMLFormElement::validateInteractively(Event* event)
@@ -223,8 +223,8 @@ bool HTMLFormElement::validateInteractively(Event* event)
         return true;
 
     for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
-        if (m_associatedElements[i]->isFormControlElement())
-            toHTMLFormControlElement(m_associatedElements[i])->hideVisibleValidationMessage();
+        if (is<HTMLFormControlElement>(m_associatedElements[i]))
+            downcast<HTMLFormControlElement>(*m_associatedElements[i]).hideVisibleValidationMessage();
     }
 
     Vector<RefPtr<FormAssociatedElement>> unhandledInvalidControls;
@@ -245,8 +245,8 @@ bool HTMLFormElement::validateInteractively(Event* event)
         if (element.inDocument() && element.isFocusable()) {
             element.scrollIntoViewIfNeeded(false);
             element.focus();
-            if (element.isFormControlElement())
-                toHTMLFormControlElement(element).updateVisibleValidationMessage();
+            if (is<HTMLFormControlElement>(element))
+                downcast<HTMLFormControlElement>(element).updateVisibleValidationMessage();
             break;
         }
     }
@@ -345,14 +345,14 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool proce
 
     for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
         FormAssociatedElement* associatedElement = m_associatedElements[i];
-        if (!associatedElement->isFormControlElement())
+        if (!is<HTMLFormControlElement>(associatedElement))
             continue;
         if (needButtonActivation) {
-            HTMLFormControlElement* control = toHTMLFormControlElement(associatedElement);
-            if (control->isActivatedSubmit())
+            HTMLFormControlElement& control = downcast<HTMLFormControlElement>(*associatedElement);
+            if (control.isActivatedSubmit())
                 needButtonActivation = false;
-            else if (firstSuccessfulSubmitButton == 0 && control->isSuccessfulSubmitButton())
-                firstSuccessfulSubmitButton = control;
+            else if (!firstSuccessfulSubmitButton && control.isSuccessfulSubmitButton())
+                firstSuccessfulSubmitButton = &control;
         }
     }
 
@@ -384,8 +384,8 @@ void HTMLFormElement::reset()
     }
 
     for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
-        if (m_associatedElements[i]->isFormControlElement())
-            toHTMLFormControlElement(m_associatedElements[i])->reset();
+        if (is<HTMLFormControlElement>(m_associatedElements[i]))
+            downcast<HTMLFormControlElement>(*m_associatedElements[i]).reset();
     }
 
     m_isInResetFunction = false;
@@ -592,7 +592,7 @@ unsigned HTMLFormElement::formElementIndex(FormAssociatedElement* associatedElem
     for (auto& element : descendants) {
         if (&element == &associatedHTMLElement)
             return i;
-        if (!isHTMLFormControlElement(element) && !is<HTMLObjectElement>(element))
+        if (!is<HTMLFormControlElement>(element) && !is<HTMLObjectElement>(element))
             continue;
         if (element.form() != this)
             continue;
@@ -696,14 +696,14 @@ bool HTMLFormElement::wasUserSubmitted() const
 HTMLFormControlElement* HTMLFormElement::defaultButton() const
 {
     for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
-        if (!m_associatedElements[i]->isFormControlElement())
+        if (!is<HTMLFormControlElement>(m_associatedElements[i]))
             continue;
-        HTMLFormControlElement* control = toHTMLFormControlElement(m_associatedElements[i]);
-        if (control->isSuccessfulSubmitButton())
-            return control;
+        HTMLFormControlElement& control = downcast<HTMLFormControlElement>(*m_associatedElements[i]);
+        if (control.isSuccessfulSubmitButton())
+            return &control;
     }
 
-    return 0;
+    return nullptr;
 }
 
 bool HTMLFormElement::checkValidity()
@@ -723,9 +723,9 @@ bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<Form
         elements.append(m_associatedElements[i]);
     bool hasInvalidControls = false;
     for (unsigned i = 0; i < elements.size(); ++i) {
-        if (elements[i]->form() == this && elements[i]->isFormControlElement()) {
-            HTMLFormControlElement* control = toHTMLFormControlElement(elements[i].get());
-            if (!control->checkValidity(&unhandledInvalidControls) && control->form() == this)
+        if (elements[i]->form() == this && is<HTMLFormControlElement>(*elements[i])) {
+            HTMLFormControlElement& control = downcast<HTMLFormControlElement>(*elements[i]);
+            if (!control.checkValidity(&unhandledInvalidControls) && control.form() == this)
                 hasInvalidControls = true;
         }
     }
@@ -810,8 +810,8 @@ void HTMLFormElement::documentDidResumeFromPageCache()
     ASSERT(!shouldAutocomplete());
 
     for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
-        if (m_associatedElements[i]->isFormControlElement())
-            toHTMLFormControlElement(m_associatedElements[i])->reset();
+        if (is<HTMLFormControlElement>(m_associatedElements[i]))
+            downcast<HTMLFormControlElement>(*m_associatedElements[i]).reset();
     }
 }
 
index d867f75..29b7003 100644 (file)
@@ -915,7 +915,7 @@ inline bool isHTMLMediaElement(const Element& element) { return element.isMediaE
 inline bool isHTMLMediaElement(const Node& node) { return node.isElementNode() && toElement(node).isMediaElement(); }
 
 template <typename ArgType>
-struct ElementTypeCastTraits<const HTMLMediaElement, ArgType> {
+struct NodeTypeCastTraits<const HTMLMediaElement, ArgType> {
     static bool is(ArgType& node) { return isHTMLMediaElement(node); }
 };
 
index 73361a0..d3004fe 100644 (file)
@@ -162,7 +162,7 @@ inline bool isHTMLPlugInImageElement(const HTMLPlugInElement& element) { return
 inline bool isHTMLPlugInImageElement(const Node& node) { return node.isPluginElement() && toHTMLPlugInElement(node).isPlugInImageElement(); }
 
 template <typename ArgType>
-struct ElementTypeCastTraits<const HTMLPlugInImageElement, ArgType> {
+struct NodeTypeCastTraits<const HTMLPlugInImageElement, ArgType> {
     static bool is(ArgType& node) { return isHTMLPlugInImageElement(node); }
 };
 
index b1e4eee..44b4dfd 100644 (file)
@@ -24,6 +24,7 @@
 #if ENABLE(DETAILS_ELEMENT)
 #include "DetailsMarkerControl.h"
 #include "HTMLDetailsElement.h"
+#include "HTMLFormControlElement.h"
 #include "InsertionPoint.h"
 #include "KeyboardEvent.h"
 #include "MouseEvent.h"
@@ -104,10 +105,10 @@ static bool isClickableControl(Node* node)
     if (!node->isElementNode())
         return false;
     Element* element = toElement(node);
-    if (element->isFormControlElement())
+    if (is<HTMLFormControlElement>(element))
         return true;
     Element* host = element->shadowHost();
-    return host && host->isFormControlElement();
+    return host && is<HTMLFormControlElement>(host);
 }
 
 bool HTMLSummaryElement::supportsFocus() const
index bbad69d..4895672 100644 (file)
@@ -55,7 +55,7 @@ inline bool isLabelableElement(const HTMLElement& element) { return element.isLa
 inline bool isLabelableElement(const Node& node) { return node.isHTMLElement() && toHTMLElement(node).isLabelable(); }
 
 template <typename ArgType>
-struct ElementTypeCastTraits<const LabelableElement, ArgType> {
+struct NodeTypeCastTraits<const LabelableElement, ArgType> {
     static bool is(ArgType& node) { return isLabelableElement(node); }
 };
 
index 702f21b..8d46921 100644 (file)
@@ -85,13 +85,13 @@ void RadioNodeList::setValue(const String& value)
 
 bool RadioNodeList::checkElementMatchesRadioNodeListFilter(const Element& testElement) const
 {
-    ASSERT(testElement.hasTagName(objectTag) || testElement.isFormControlElement());
+    ASSERT(is<HTMLObjectElement>(testElement) || is<HTMLFormControlElement>(testElement));
     if (isHTMLFormElement(ownerNode())) {
         HTMLFormElement* formElement = nullptr;
         if (testElement.hasTagName(objectTag))
             formElement = downcast<HTMLObjectElement>(testElement).form();
         else
-            formElement = toHTMLFormControlElement(testElement).form();
+            formElement = downcast<HTMLFormControlElement>(testElement).form();
         if (!formElement || formElement != &ownerNode())
             return false;
     }
@@ -101,7 +101,7 @@ bool RadioNodeList::checkElementMatchesRadioNodeListFilter(const Element& testEl
 
 bool RadioNodeList::elementMatches(Element& testElement) const
 {
-    if (!testElement.hasTagName(objectTag) && !testElement.isFormControlElement())
+    if (!is<HTMLObjectElement>(testElement) && !is<HTMLFormControlElement>(testElement))
         return false;
 
     if (HTMLInputElement* inputElement = testElement.toInputElement()) {
index a7be21f..b78de60 100644 (file)
@@ -727,7 +727,7 @@ void HTMLConstructionSite::findFosterSite(HTMLConstructionSiteTask& task)
         // and instead use the DocumentFragment as a root node. So we must treat the root node (DocumentFragment) as if it is a html element here.
         bool parentCanBeFosterParent = parent && (parent->isElementNode() || (m_isParsingFragment && parent == m_openElements.rootNode()));
 #if ENABLE(TEMPLATE_ELEMENT)
-        parentCanBeFosterParent = parentCanBeFosterParent || (parent && parent->isDocumentFragment() && toDocumentFragment(parent)->isTemplateContent());
+        parentCanBeFosterParent = parentCanBeFosterParent || (parent && is<DocumentFragment>(parent) && downcast<DocumentFragment>(parent)->isTemplateContent());
 #endif
         if (parentCanBeFosterParent) {
             task.parent = parent;
index 5805cf0..5694efd 100644 (file)
@@ -2381,7 +2381,7 @@ static inline bool disallowTelephoneNumberParsing(const Node& node)
     return node.isLink()
         || node.nodeType() == Node::COMMENT_NODE
         || node.hasTagName(scriptTag)
-        || (node.isHTMLElement() && toHTMLElement(node).isFormControlElement())
+        || is<HTMLFormControlElement>(node)
         || node.hasTagName(styleTag)
         || node.hasTagName(ttTag)
         || node.hasTagName(preTag)
index 50ab814..a97fd84 100644 (file)
@@ -144,8 +144,8 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
     HTMLFormControlElement* submitButton = 0;
     if (event && event->target()) {
         for (Node* node = event->target()->toNode(); node; node = node->parentNode()) {
-            if (node->isElementNode() && toElement(node)->isFormControlElement()) {
-                submitButton = toHTMLFormControlElement(node);
+            if (is<HTMLFormControlElement>(node)) {
+                submitButton = downcast<HTMLFormControlElement>(node);
                 break;
             }
         }
index e3c1484..6d05dbf 100644 (file)
@@ -77,7 +77,7 @@ void isMathMLElement(const MathMLElement&); // Catch unnecessary runtime check o
 inline bool isMathMLElement(const Node& node) { return node.isMathMLElement(); }
 
 template <typename ArgType>
-struct ElementTypeCastTraits<const MathMLElement, ArgType> {
+struct NodeTypeCastTraits<const MathMLElement, ArgType> {
     static bool is(ArgType& node) { return isMathMLElement(node); }
 };
 
index e9bc1b6..b519fd2 100644 (file)
@@ -836,7 +836,7 @@ void ContextMenuController::populate()
     if (!node)
         return;
 #if PLATFORM(GTK)
-    if (!m_context.hitTestResult().isContentEditable() && (node->isElementNode() && toElement(node)->isFormControlElement()))
+    if (!m_context.hitTestResult().isContentEditable() && is<HTMLFormControlElement>(node))
         return;
 #endif
     Frame* frame = node->document().frame();
index e6a3d25..892e4f5 100644 (file)
@@ -389,7 +389,7 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
     Node* n;
     for (n = NodeTraversal::previous(element); n && lengthSearched < charsSearchedThreshold; n = NodeTraversal::previous(n)) {
         // We hit another form element or the start of the form - bail out
-        if (isHTMLFormElement(n) || (n->isHTMLElement() && toElement(n)->isFormControlElement()))
+        if (is<HTMLFormElement>(n) || is<HTMLFormControlElement>(n))
             break;
 
         if (n->hasTagName(tdTag) && !startingTableCell) {
index c0c2580..53e0c75 100644 (file)
@@ -51,7 +51,7 @@ RenderButton::~RenderButton()
 
 HTMLFormControlElement& RenderButton::formControlElement() const
 {
-    return toHTMLFormControlElement(nodeForNonAnonymous());
+    return downcast<HTMLFormControlElement>(nodeForNonAnonymous());
 }
 
 bool RenderButton::canBeSelectionLeaf() const
index b373b99..5f3a497 100644 (file)
@@ -69,6 +69,7 @@
 #include "FrameView.h"
 #include "Gradient.h"
 #include "GraphicsContext.h"
+#include "HTMLFormControlElement.h"
 #include "HTMLFrameElement.h"
 #include "HTMLFrameOwnerElement.h"
 #include "HTMLNames.h"
@@ -2573,7 +2574,7 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const LayoutSize& oldOff
 
     EResize resize = renderer->style().resize();
     if (resize != RESIZE_VERTICAL && difference.width()) {
-        if (element->isFormControlElement()) {
+        if (is<HTMLFormControlElement>(element)) {
             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
             styledElement->setInlineStyleProperty(CSSPropertyMarginLeft, renderer->marginLeft() / zoomFactor, CSSPrimitiveValue::CSS_PX);
             styledElement->setInlineStyleProperty(CSSPropertyMarginRight, renderer->marginRight() / zoomFactor, CSSPrimitiveValue::CSS_PX);
@@ -2584,7 +2585,7 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const LayoutSize& oldOff
     }
 
     if (resize != RESIZE_HORIZONTAL && difference.height()) {
-        if (element->isFormControlElement()) {
+        if (is<HTMLFormControlElement>(element)) {
             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
             styledElement->setInlineStyleProperty(CSSPropertyMarginTop, renderer->marginTop() / zoomFactor, CSSPrimitiveValue::CSS_PX);
             styledElement->setInlineStyleProperty(CSSPropertyMarginBottom, renderer->marginBottom() / zoomFactor, CSSPrimitiveValue::CSS_PX);
index 9604536..ba675f0 100644 (file)
@@ -843,9 +843,9 @@ bool RenderTheme::isSpinUpButtonPartPressed(const RenderObject& o) const
 bool RenderTheme::isReadOnlyControl(const RenderObject& o) const
 {
     Node* node = o.node();
-    if (!node || !node->isElementNode() || !toElement(node)->isFormControlElement())
+    if (!node || !is<HTMLFormControlElement>(node))
         return false;
-    return !toElement(node)->matchesReadWritePseudoClass();
+    return !toElement(*node).matchesReadWritePseudoClass();
 }
 
 bool RenderTheme::isHovered(const RenderObject& o) const
index 6bde7bc..cdda998 100644 (file)
@@ -225,7 +225,7 @@ void isSVGElement(const SVGElement&); // Catch unnecessary runtime check of type
 inline bool isSVGElement(const Node& node) { return node.isSVGElement(); }
 
 template <typename ArgType>
-struct ElementTypeCastTraits<const SVGElement, ArgType> {
+struct NodeTypeCastTraits<const SVGElement, ArgType> {
     static bool is(ArgType& node) { return isSVGElement(node); }
 };
 
index 74fb56e..4f77895 100644 (file)
@@ -87,7 +87,7 @@ inline bool isSVGFilterPrimitiveStandardAttributes(const SVGElement& element) {
 inline bool isSVGFilterPrimitiveStandardAttributes(const Node& node) { return node.isSVGElement() && downcast<SVGElement>(node).isFilterEffect(); }
 
 template <typename ArgType>
-struct ElementTypeCastTraits<const SVGFilterPrimitiveStandardAttributes, ArgType> {
+struct NodeTypeCastTraits<const SVGFilterPrimitiveStandardAttributes, ArgType> {
     static bool is(ArgType& node) { return isSVGFilterPrimitiveStandardAttributes(node); }
 };
 
index f9840b6..637a056 100644 (file)
@@ -242,7 +242,7 @@ inline bool isSVGSMILElement(const SVGElement& element) { return element.isSMILE
 inline bool isSVGSMILElement(const Node& node) { return node.isSVGElement() && downcast<SVGElement>(node).isSMILElement(); }
 
 template <typename ArgType>
-struct ElementTypeCastTraits<const SVGSMILElement, ArgType> {
+struct NodeTypeCastTraits<const SVGSMILElement, ArgType> {
     static bool is(ArgType& node) { return isSVGSMILElement(node); }
 };
 
index 62ebe80..3c09b72 100644 (file)
@@ -1,5 +1,18 @@
 2014-09-24  Christophe Dumez  <cdumez@apple.com>
 
+        Add initial is<>() / downcast<>() support for any type of Nodes
+        https://bugs.webkit.org/show_bug.cgi?id=137056
+
+        Reviewed by Benjamin Poulain.
+
+        Use is<HTMLFormControlElement>() / downcast<HTMLFormControlElement>()
+        instead of isFormControlElement() / toHTMLFormControlElement().
+
+        * WebView/WebHTMLRepresentation.mm:
+        (searchForLabelsBeforeElement):
+
+2014-09-24  Christophe Dumez  <cdumez@apple.com>
+
         Use is<HTML*Element>() instead of isHTML*Element() - Part 1
         https://bugs.webkit.org/show_bug.cgi?id=137068
 
index 9b9de7a..84d3531 100644 (file)
@@ -445,15 +445,13 @@ static NSString* searchForLabelsBeforeElement(Frame* frame, NSArray* labels, Ele
     unsigned lengthSearched = 0;
     Node* n;
     for (n = NodeTraversal::previous(element);
-         n && lengthSearched < charsSearchedThreshold;
-         n = NodeTraversal::previous(n))
-    {
-        if (n->hasTagName(formTag)
-            || (n->isHTMLElement() && toElement(n)->isFormControlElement()))
-        {
+        n && lengthSearched < charsSearchedThreshold;
+        n = NodeTraversal::previous(n)) {
+        if (is<HTMLFormElement>(n) || is<HTMLFormControlElement>(n)) {
             // We hit another form element or the start of the form - bail out
             break;
-        } else if (n->hasTagName(tdTag) && !startingTableCell) {
+        }
+        if (n->hasTagName(tdTag) && !startingTableCell) {
             startingTableCell = static_cast<HTMLTableCellElement*>(n);
         } else if (n->hasTagName(trTag) && startingTableCell) {
             NSString* result = frame->searchForLabelsAboveCell(*regExp, startingTableCell, resultDistance);
index 3e8509c..40460df 100644 (file)
@@ -1,5 +1,18 @@
 2014-09-24  Christophe Dumez  <cdumez@apple.com>
 
+        Add initial is<>() / downcast<>() support for any type of Nodes
+        https://bugs.webkit.org/show_bug.cgi?id=137056
+
+        Reviewed by Benjamin Poulain.
+
+        Use is<HTMLFormControlElement>() / downcast<HTMLFormControlElement>()
+        instead of isFormControlElement() / toHTMLFormControlElement().
+
+        * WebFrame.cpp:
+        (WebFrame::elementWithName):
+
+2014-09-24  Christophe Dumez  <cdumez@apple.com>
+
         Unreviewed build fix after r173932.
 
         Unreviewed build fix after r173932 for Windows. Use WebCore:: namespace
index d50bafd..e33048a 100644 (file)
@@ -1101,12 +1101,12 @@ HRESULT WebFrame::elementWithName(BSTR name, IDOMElement* form, IDOMElement** el
         const Vector<FormAssociatedElement*>& elements = formElement->associatedElements();
         AtomicString targetName((UChar*)name, SysStringLen(name));
         for (unsigned int i = 0; i < elements.size(); i++) {
-            if (!elements[i]->isFormControlElement())
+            if (!is<HTMLFormControlElement>(elements[i]))
                 continue;
-            HTMLFormControlElement* elt = toHTMLFormControlElement(elements[i]);
+            HTMLFormControlElement& elt = downcast<HTMLFormControlElement>(*elements[i]);
             // Skip option elements, other duds
-            if (elt->name() == targetName) {
-                *element = DOMElement::createInstance(elt);
+            if (elt.name() == targetName) {
+                *element = DOMElement::createInstance(&elt);
                 return S_OK;
             }
         }