Drop unnecessary Node::toInputElement() virtual function
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Oct 2015 03:29:34 +0000 (03:29 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Oct 2015 03:29:34 +0000 (03:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150341

Reviewed by Darin Adler.

Drop unnecessary Node::toInputElement() virtual function and use the
usual is<HTMLInputElement>() / downcast< HTMLInputElement >() instead.

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

18 files changed:
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AXObjectCache.cpp
Source/WebCore/accessibility/AccessibilityNodeObject.cpp
Source/WebCore/css/SelectorChecker.cpp
Source/WebCore/css/SelectorCheckerTestFunctions.h
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleResolver.h
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/editing/TextIterator.cpp
Source/WebCore/html/HTMLInputElement.h
Source/WebCore/html/RadioNodeList.cpp
Source/WebCore/html/shadow/SliderThumbElement.cpp
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/page/DragController.cpp
Source/WebCore/rendering/RenderButton.cpp
Source/WebCore/rendering/RenderTheme.cpp
Source/WebCore/testing/Internals.cpp

index 215f044..fadc3df 100644 (file)
@@ -1,3 +1,13 @@
+2015-10-19  Chris Dumez  <cdumez@apple.com>
+
+        Drop unnecessary Node::toInputElement() virtual function
+        https://bugs.webkit.org/show_bug.cgi?id=150341
+
+        Reviewed by Darin Adler.
+
+        Drop unnecessary Node::toInputElement() virtual function and use the
+        usual is<HTMLInputElement>() / downcast< HTMLInputElement >() instead.
+
 2015-10-19  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r191324.
index 914ab6d..2072090 100644 (file)
@@ -1316,11 +1316,8 @@ void AXObjectCache::textMarkerDataForVisiblePosition(TextMarkerData& textMarkerD
     if (!domNode)
         return;
     
-    if (domNode->isHTMLElement()) {
-        HTMLInputElement* inputElement = domNode->toInputElement();
-        if (inputElement && inputElement->isPasswordField())
-            return;
-    }
+    if (is<HTMLInputElement>(*domNode) && downcast<HTMLInputElement>(*domNode).isPasswordField())
+        return;
     
     // find or create an accessibility object for this node
     AXObjectCache* cache = domNode->document().axObjectCache();
index 8953eba..0719c1d 100644 (file)
@@ -494,10 +494,11 @@ bool AccessibilityNodeObject::isSearchField() const
     if (roleValue() == SearchFieldRole)
         return true;
 
-    HTMLInputElement* inputElement = node->toInputElement();
-    if (!inputElement)
+    if (!is<HTMLInputElement>(*node))
         return false;
 
+    auto& inputElement = downcast<HTMLInputElement>(*node);
+
     // Some websites don't label their search fields as such. However, they will
     // use the word "search" in either the form or input type. This won't catch every case,
     // but it will catch google.com for example.
@@ -508,7 +509,7 @@ bool AccessibilityNodeObject::isSearchField() const
         return true;
 
     // Check the form action and the name, which will sometimes be "search".
-    HTMLFormElement* form = inputElement->form();
+    auto* form = inputElement.form();
     if (form && (form->name().contains("search", false) || form->action().contains("search", false)))
         return true;
 
@@ -542,18 +543,14 @@ bool AccessibilityNodeObject::isImage() const
 
 bool AccessibilityNodeObject::isPasswordField() const
 {
-    Node* node = this->node();
-    if (!node || !node->isHTMLElement())
+    auto* node = this->node();
+    if (!is<HTMLInputElement>(node))
         return false;
 
     if (ariaRoleAttribute() != UnknownRole)
         return false;
 
-    HTMLInputElement* inputElement = node->toInputElement();
-    if (!inputElement)
-        return false;
-
-    return inputElement->isPasswordField();
+    return downcast<HTMLInputElement>(*node).isPasswordField();
 }
 
 AccessibilityObject* AccessibilityNodeObject::passwordFieldOrContainingPasswordField()
@@ -562,16 +559,14 @@ AccessibilityObject* AccessibilityNodeObject::passwordFieldOrContainingPasswordF
     if (!node)
         return nullptr;
 
-    if (HTMLInputElement* inputElement = node->toInputElement()) {
-        if (inputElement->isPasswordField())
-            return this;
-    }
+    if (is<HTMLInputElement>(*node) && downcast<HTMLInputElement>(*node).isPasswordField())
+        return this;
 
-    Element* element = node->shadowHost();
-    if (!element || !is<HTMLInputElement>(element))
+    auto* element = node->shadowHost();
+    if (!is<HTMLInputElement>(element))
         return nullptr;
 
-    if (AXObjectCache* cache = axObjectCache())
+    if (auto* cache = axObjectCache())
         return cache->getOrCreate(element);
 
     return nullptr;
@@ -643,14 +638,11 @@ bool AccessibilityNodeObject::isMenuItem() const
 bool AccessibilityNodeObject::isNativeCheckboxOrRadio() const
 {
     Node* node = this->node();
-    if (!node)
+    if (!is<HTMLInputElement>(node))
         return false;
 
-    HTMLInputElement* input = node->toInputElement();
-    if (input)
-        return input->isCheckbox() || input->isRadioButton();
-
-    return false;
+    auto& input = downcast<HTMLInputElement>(*node);
+    return input.isCheckbox() || input.isRadioButton();
 }
 
 bool AccessibilityNodeObject::isEnabled() const
@@ -676,15 +668,8 @@ bool AccessibilityNodeObject::isEnabled() const
 
 bool AccessibilityNodeObject::isIndeterminate() const
 {
-    Node* node = this->node();
-    if (!node)
-        return false;
-
-    HTMLInputElement* inputElement = node->toInputElement();
-    if (!inputElement)
-        return false;
-
-    return inputElement->shouldAppearIndeterminate();
+    auto* node = this->node();
+    return is<HTMLInputElement>(node) && downcast<HTMLInputElement>(*node).shouldAppearIndeterminate();
 }
 
 bool AccessibilityNodeObject::isPressed() const
@@ -716,9 +701,8 @@ bool AccessibilityNodeObject::isChecked() const
         return false;
 
     // First test for native checkedness semantics
-    HTMLInputElement* inputElement = node->toInputElement();
-    if (inputElement)
-        return inputElement->shouldAppearChecked();
+    if (is<HTMLInputElement>(*node))
+        return downcast<HTMLInputElement>(*node).shouldAppearChecked();
 
     // Else, if this is an ARIA checkbox or radio, respect the aria-checked attribute
     bool validRole = false;
index fbb3485..e773537 100644 (file)
@@ -903,7 +903,7 @@ bool SelectorChecker::checkOne(const CheckingContextWithStatus& context, PseudoI
             }
             break;
         case CSSSelector::PseudoClassAutofill:
-            return isAutofilled(element);
+            return isAutofilled(*element);
         case CSSSelector::PseudoClassAnyLink:
         case CSSSelector::PseudoClassAnyLinkDeprecated:
         case CSSSelector::PseudoClassLink:
@@ -972,7 +972,7 @@ bool SelectorChecker::checkOne(const CheckingContextWithStatus& context, PseudoI
         case CSSSelector::PseudoClassInvalid:
             return isInvalid(element);
         case CSSSelector::PseudoClassChecked:
-            return isChecked(element);
+            return isChecked(*element);
         case CSSSelector::PseudoClassIndeterminate:
             return shouldAppearIndeterminate(element);
         case CSSSelector::PseudoClassRoot:
index 86db58c..d251d62 100644 (file)
 
 namespace WebCore {
 
-ALWAYS_INLINE bool isAutofilled(const Element* element)
+ALWAYS_INLINE bool isAutofilled(const Element& element)
 {
-    if (is<HTMLFormControlElement>(*element)) {
-        if (const HTMLInputElement* inputElement = element->toInputElement())
-            return inputElement->isAutoFilled();
-    }
-    return false;
+    return is<HTMLInputElement>(element) && downcast<HTMLInputElement>(element).isAutoFilled();
 }
 
 ALWAYS_INLINE bool isDefaultButtonForForm(const Element* element)
@@ -72,16 +68,18 @@ ALWAYS_INLINE bool isMediaDocument(Element* element)
     return element->document().isMediaDocument();
 }
 
-ALWAYS_INLINE bool isChecked(Element* element)
+ALWAYS_INLINE bool isChecked(Element& element)
 {
     // Even though WinIE allows checked and indeterminate to co-exist, the CSS selector spec says that
     // you can't be both checked and indeterminate. We will behave like WinIE behind the scenes and just
     // obey the CSS spec here in the test for matching the pseudo.
-    const HTMLInputElement* inputElement = element->toInputElement();
-    if (inputElement && inputElement->shouldAppearChecked() && !inputElement->shouldAppearIndeterminate())
-        return true;
-    if (is<HTMLOptionElement>(*element) && downcast<HTMLOptionElement>(*element).selected())
-        return true;
+    if (is<HTMLInputElement>(element)) {
+        auto& inputElement = downcast<HTMLInputElement>(element);
+        return inputElement.shouldAppearChecked() && !inputElement.shouldAppearIndeterminate();
+    }
+    if (is<HTMLOptionElement>(element))
+        return downcast<HTMLOptionElement>(element).selected();
+
     return false;
 }
 
index 0a424ad..159d2c2 100644 (file)
@@ -479,84 +479,84 @@ bool StyleResolver::styleSharingCandidateMatchesRuleSet(RuleSet* ruleSet)
     return collector.hasAnyMatchingRules(ruleSet);
 }
 
-bool StyleResolver::canShareStyleWithControl(StyledElement* element) const
+bool StyleResolver::canShareStyleWithControl(StyledElement& element) const
 {
     const State& state = m_state;
-    HTMLInputElement* thisInputElement = element->toInputElement();
-    HTMLInputElement* otherInputElement = state.element()->toInputElement();
-
-    if (!thisInputElement || !otherInputElement)
+    if (!is<HTMLInputElement>(element) || !is<HTMLInputElement>(*state.element()))
         return false;
 
-    if (thisInputElement->isAutoFilled() != otherInputElement->isAutoFilled())
+    auto& thisInputElement = downcast<HTMLInputElement>(element);
+    auto& otherInputElement = downcast<HTMLInputElement>(*state.element());
+
+    if (thisInputElement.isAutoFilled() != otherInputElement.isAutoFilled())
         return false;
-    if (thisInputElement->shouldAppearChecked() != otherInputElement->shouldAppearChecked())
+    if (thisInputElement.shouldAppearChecked() != otherInputElement.shouldAppearChecked())
         return false;
-    if (thisInputElement->shouldAppearIndeterminate() != otherInputElement->shouldAppearIndeterminate())
+    if (thisInputElement.shouldAppearIndeterminate() != otherInputElement.shouldAppearIndeterminate())
         return false;
-    if (thisInputElement->isRequired() != otherInputElement->isRequired())
+    if (thisInputElement.isRequired() != otherInputElement.isRequired())
         return false;
 
-    if (element->isDisabledFormControl() != state.element()->isDisabledFormControl())
+    if (element.isDisabledFormControl() != state.element()->isDisabledFormControl())
         return false;
 
-    if (element->isDefaultButtonForForm() != state.element()->isDefaultButtonForForm())
+    if (element.isDefaultButtonForForm() != state.element()->isDefaultButtonForForm())
         return false;
 
-    if (element->isInRange() != state.element()->isInRange())
+    if (element.isInRange() != state.element()->isInRange())
         return false;
 
-    if (element->isOutOfRange() != state.element()->isOutOfRange())
+    if (element.isOutOfRange() != state.element()->isOutOfRange())
         return false;
 
     return true;
 }
 
-static inline bool elementHasDirectionAuto(Element* element)
+static inline bool elementHasDirectionAuto(Element& element)
 {
     // FIXME: This line is surprisingly hot, we may wish to inline hasDirectionAuto into StyleResolver.
-    return is<HTMLElement>(*element) && downcast<HTMLElement>(*element).hasDirectionAuto();
+    return is<HTMLElement>(element) && downcast<HTMLElement>(element).hasDirectionAuto();
 }
 
-bool StyleResolver::sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement* sharingCandidate) const
+bool StyleResolver::sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement& sharingCandidate) const
 {
     const State& state = m_state;
-    if (state.element()->elementData() == sharingCandidate->elementData())
+    if (state.element()->elementData() == sharingCandidate.elementData())
         return true;
-    if (state.element()->fastGetAttribute(XMLNames::langAttr) != sharingCandidate->fastGetAttribute(XMLNames::langAttr))
+    if (state.element()->fastGetAttribute(XMLNames::langAttr) != sharingCandidate.fastGetAttribute(XMLNames::langAttr))
         return false;
-    if (state.element()->fastGetAttribute(langAttr) != sharingCandidate->fastGetAttribute(langAttr))
+    if (state.element()->fastGetAttribute(langAttr) != sharingCandidate.fastGetAttribute(langAttr))
         return false;
 
     if (!state.elementAffectedByClassRules()) {
-        if (sharingCandidate->hasClass() && classNamesAffectedByRules(sharingCandidate->classNames()))
+        if (sharingCandidate.hasClass() && classNamesAffectedByRules(sharingCandidate.classNames()))
             return false;
-    } else if (sharingCandidate->hasClass()) {
+    } else if (sharingCandidate.hasClass()) {
         // SVG elements require a (slow!) getAttribute comparision because "class" is an animatable attribute for SVG.
         if (state.element()->isSVGElement()) {
-            if (state.element()->getAttribute(classAttr) != sharingCandidate->getAttribute(classAttr))
+            if (state.element()->getAttribute(classAttr) != sharingCandidate.getAttribute(classAttr))
                 return false;
         } else {
-            if (state.element()->classNames() != sharingCandidate->classNames())
+            if (state.element()->classNames() != sharingCandidate.classNames())
                 return false;
         }
     } else
         return false;
 
-    if (state.styledElement()->presentationAttributeStyle() != sharingCandidate->presentationAttributeStyle())
+    if (state.styledElement()->presentationAttributeStyle() != sharingCandidate.presentationAttributeStyle())
         return false;
 
     if (state.element()->hasTagName(progressTag)) {
-        if (state.element()->shouldAppearIndeterminate() != sharingCandidate->shouldAppearIndeterminate())
+        if (state.element()->shouldAppearIndeterminate() != sharingCandidate.shouldAppearIndeterminate())
             return false;
     }
 
     return true;
 }
 
-bool StyleResolver::canShareStyleWithElement(StyledElement* element) const
+bool StyleResolver::canShareStyleWithElement(StyledElement& element) const
 {
-    RenderStyle* style = element->renderStyle();
+    auto* style = element.renderStyle();
     const State& state = m_state;
 
     if (!style)
@@ -565,37 +565,37 @@ bool StyleResolver::canShareStyleWithElement(StyledElement* element) const
         return false;
     if (style->hasUniquePseudoStyle())
         return false;
-    if (element->tagQName() != state.element()->tagQName())
+    if (element.tagQName() != state.element()->tagQName())
         return false;
-    if (element->inlineStyle())
+    if (element.inlineStyle())
         return false;
-    if (element->needsStyleRecalc())
+    if (element.needsStyleRecalc())
         return false;
-    if (element->isSVGElement() && downcast<SVGElement>(*element).animatedSMILStyleProperties())
+    if (element.isSVGElement() && downcast<SVGElement>(element).animatedSMILStyleProperties())
         return false;
-    if (element->isLink() != state.element()->isLink())
+    if (element.isLink() != state.element()->isLink())
         return false;
-    if (element->hovered() != state.element()->hovered())
+    if (element.hovered() != state.element()->hovered())
         return false;
-    if (element->active() != state.element()->active())
+    if (element.active() != state.element()->active())
         return false;
-    if (element->focused() != state.element()->focused())
+    if (element.focused() != state.element()->focused())
         return false;
-    if (element->shadowPseudoId() != state.element()->shadowPseudoId())
+    if (element.shadowPseudoId() != state.element()->shadowPseudoId())
         return false;
-    if (element == element->document().cssTarget())
+    if (&element == element.document().cssTarget())
         return false;
     if (!sharingCandidateHasIdenticalStyleAffectingAttributes(element))
         return false;
-    if (element->additionalPresentationAttributeStyle() != state.styledElement()->additionalPresentationAttributeStyle())
+    if (element.additionalPresentationAttributeStyle() != state.styledElement()->additionalPresentationAttributeStyle())
         return false;
-    if (element->affectsNextSiblingElementStyle() || element->styleIsAffectedByPreviousSibling())
+    if (element.affectsNextSiblingElementStyle() || element.styleIsAffectedByPreviousSibling())
         return false;
 
-    if (element->hasID() && m_ruleSets.features().idsInRules.contains(element->idForStyleResolution().impl()))
+    if (element.hasID() && m_ruleSets.features().idsInRules.contains(element.idForStyleResolution().impl()))
         return false;
 
-    bool isControl = is<HTMLFormControlElement>(*element);
+    bool isControl = is<HTMLFormControlElement>(element);
 
     if (isControl != is<HTMLFormControlElement>(*state.element()))
         return false;
@@ -608,31 +608,31 @@ bool StyleResolver::canShareStyleWithElement(StyledElement* element) const
 
     // Turn off style sharing for elements that can gain layers for reasons outside of the style system.
     // See comments in RenderObject::setStyle().
-    if (element->hasTagName(iframeTag) || element->hasTagName(frameTag) || element->hasTagName(embedTag) || element->hasTagName(objectTag) || element->hasTagName(appletTag) || element->hasTagName(canvasTag))
+    if (element.hasTagName(iframeTag) || element.hasTagName(frameTag) || element.hasTagName(embedTag) || element.hasTagName(objectTag) || element.hasTagName(appletTag) || element.hasTagName(canvasTag))
         return false;
 
     if (elementHasDirectionAuto(element))
         return false;
 
-    if (element->isLink() && state.elementLinkState() != style->insideLink())
+    if (element.isLink() && state.elementLinkState() != style->insideLink())
         return false;
 
-    if (element->elementData() != state.element()->elementData()) {
-        if (element->fastGetAttribute(readonlyAttr) != state.element()->fastGetAttribute(readonlyAttr))
+    if (element.elementData() != state.element()->elementData()) {
+        if (element.fastGetAttribute(readonlyAttr) != state.element()->fastGetAttribute(readonlyAttr))
             return false;
-        if (element->isSVGElement()) {
-            if (element->getAttribute(typeAttr) != state.element()->getAttribute(typeAttr))
+        if (element.isSVGElement()) {
+            if (element.getAttribute(typeAttr) != state.element()->getAttribute(typeAttr))
                 return false;
         } else {
-            if (element->fastGetAttribute(typeAttr) != state.element()->fastGetAttribute(typeAttr))
+            if (element.fastGetAttribute(typeAttr) != state.element()->fastGetAttribute(typeAttr))
                 return false;
         }
     }
 
-    if (element->matchesValidPseudoClass() != state.element()->matchesValidPseudoClass())
+    if (element.matchesValidPseudoClass() != state.element()->matchesValidPseudoClass())
         return false;
 
-    if (element->matchesInvalidPseudoClass() != state.element()->matchesValidPseudoClass())
+    if (element.matchesInvalidPseudoClass() != state.element()->matchesValidPseudoClass())
         return false;
 
 #if ENABLE(VIDEO_TRACK)
@@ -642,7 +642,7 @@ bool StyleResolver::canShareStyleWithElement(StyledElement* element) const
 #endif
 
 #if ENABLE(FULLSCREEN_API)
-    if (element == element->document().webkitCurrentFullScreenElement() || state.element() == state.document().webkitCurrentFullScreenElement())
+    if (&element == element.document().webkitCurrentFullScreenElement() || state.element() == state.document().webkitCurrentFullScreenElement())
         return false;
 #endif
     return true;
@@ -653,7 +653,7 @@ inline StyledElement* StyleResolver::findSiblingForStyleSharing(Node* node, unsi
     for (; node; node = node->previousSibling()) {
         if (!is<StyledElement>(*node))
             continue;
-        if (canShareStyleWithElement(downcast<StyledElement>(node)))
+        if (canShareStyleWithElement(downcast<StyledElement>(*node)))
             break;
         if (count++ == cStyleSearchThreshold)
             return nullptr;
@@ -679,7 +679,7 @@ RenderStyle* StyleResolver::locateSharedStyle()
         return nullptr;
     if (state.element() == state.document().cssTarget())
         return nullptr;
-    if (elementHasDirectionAuto(state.element()))
+    if (elementHasDirectionAuto(*state.element()))
         return nullptr;
 
     // Cache whether state.element is affected by any known class selectors.
index ae71a67..cec823a 100644 (file)
@@ -183,7 +183,7 @@ private:
     bool styleSharingCandidateMatchesRuleSet(RuleSet*);
     Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const;
     StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const;
-    bool canShareStyleWithElement(StyledElement*) const;
+    bool canShareStyleWithElement(StyledElement&) const;
 
     Ref<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleKeyframe*, KeyframeValue&);
 
@@ -530,7 +530,7 @@ private:
 
     void cacheBorderAndBackground();
 
-    bool canShareStyleWithControl(StyledElement*) const;
+    bool canShareStyleWithControl(StyledElement&) const;
 
     void applyProperty(CSSPropertyID, CSSValue*, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault, const MatchResult* = nullptr);
     RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSVariableDependentValue&);
@@ -559,7 +559,7 @@ private:
     void sweepMatchedPropertiesCache();
 
     bool classNamesAffectedByRules(const SpaceSplitString&) const;
-    bool sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement*) const;
+    bool sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement&) const;
 
     unsigned m_matchedPropertiesCacheAdditionsSinceLastSweep;
 
index 5404517..6a5c2c0 100644 (file)
@@ -357,15 +357,6 @@ Node* Node::toNode()
     return this;
 }
 
-HTMLInputElement* Node::toInputElement()
-{
-    // If one of the below ASSERTs trigger, you are calling this function
-    // directly or indirectly from a constructor or destructor of this object.
-    // Don't do this!
-    ASSERT(!(isHTMLElement() && hasTagName(inputTag)));
-    return 0;
-}
-
 String Node::nodeValue() const
 {
     return String();
index 6a193aa..9e15467 100644 (file)
@@ -512,8 +512,6 @@ public:
     WEBCORE_EXPORT unsigned short compareDocumentPosition(Node*);
 
     virtual Node* toNode() override;
-    virtual HTMLInputElement* toInputElement();
-    const HTMLInputElement* toInputElement() const { return const_cast<Node*>(this)->toInputElement(); }
 
     virtual EventTargetInterface eventTargetInterface() const override;
     virtual ScriptExecutionContext* scriptExecutionContext() const override final; // Implemented in Document.h
index b870a3a..642ad0e 100644 (file)
@@ -858,7 +858,7 @@ static bool shouldEmitNewlineForNode(Node* node, bool emitsOriginalText)
     auto* renderer = node->renderer();
     if (!(renderer ? renderer->isBR() : node->hasTagName(brTag)))
         return false;
-    return emitsOriginalText || !(node->isInShadowTree() && node->shadowHost()->toInputElement());
+    return emitsOriginalText || !(node->isInShadowTree() && is<HTMLInputElement>(*node->shadowHost()));
 }
 
 static bool hasHeaderTag(HTMLElement& element)
index bbbd336..50549f4 100644 (file)
@@ -66,8 +66,6 @@ public:
     static Ref<HTMLInputElement> create(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser);
     virtual ~HTMLInputElement();
 
-    virtual HTMLInputElement* toInputElement() override final { return this; }
-
     WEBCORE_EXPORT virtual bool shouldAutocomplete() const override final;
 
     // For ValidityState
index 5e4025e..2825ff2 100644 (file)
@@ -50,20 +50,22 @@ RadioNodeList::~RadioNodeList()
     ownerNode().nodeLists()->removeCacheWithAtomicName(this, m_name);
 }
 
-static inline HTMLInputElement* toRadioButtonInputElement(Node* node)
+static inline HTMLInputElement* toRadioButtonInputElement(Node& node)
 {
-    ASSERT(node->isElementNode());
-    HTMLInputElement* inputElement = node->toInputElement();
-    if (!inputElement || !inputElement->isRadioButton() || inputElement->value().isEmpty())
-        return 0;
-    return inputElement;
+    if (!is<HTMLInputElement>(node))
+        return nullptr;
+
+    auto& inputElement = downcast<HTMLInputElement>(node);
+    if (!inputElement.isRadioButton() || inputElement.value().isEmpty())
+        return nullptr;
+    return &inputElement;
 }
 
 String RadioNodeList::value() const
 {
-    for (unsigned i = 0; i < length(); ++i) {
-        Node* node = item(i);
-        const HTMLInputElement* inputElement = toRadioButtonInputElement(node);
+    auto length = this->length();
+    for (unsigned i = 0; i < length; ++i) {
+        auto* inputElement = toRadioButtonInputElement(*item(i));
         if (!inputElement || !inputElement->checked())
             continue;
         return inputElement->value();
@@ -73,9 +75,9 @@ String RadioNodeList::value() const
 
 void RadioNodeList::setValue(const String& value)
 {
-    for (unsigned i = 0; i < length(); ++i) {
-        Node* node = item(i);
-        HTMLInputElement* inputElement = toRadioButtonInputElement(node);
+    auto length = this->length();
+    for (unsigned i = 0; i < length; ++i) {
+        auto* inputElement = toRadioButtonInputElement(*item(i));
         if (!inputElement || inputElement->value() != value)
             continue;
         inputElement->setChecked(true);
@@ -104,10 +106,8 @@ bool RadioNodeList::elementMatches(Element& testElement) const
     if (!is<HTMLObjectElement>(testElement) && !is<HTMLFormControlElement>(testElement))
         return false;
 
-    if (HTMLInputElement* inputElement = testElement.toInputElement()) {
-        if (inputElement->isImageButton())
-            return false;
-    }
+    if (is<HTMLInputElement>(testElement) && downcast<HTMLInputElement>(testElement).isImageButton())
+        return false;
 
     return checkElementMatchesRadioNodeListFilter(testElement);
 }
index 2cac6f4..76ccf8b 100644 (file)
@@ -55,20 +55,20 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
-inline static Decimal sliderPosition(HTMLInputElement* element)
+inline static Decimal sliderPosition(HTMLInputElement& element)
 {
-    const StepRange stepRange(element->createStepRange(RejectAny));
-    const Decimal oldValue = parseToDecimalForNumberType(element->value(), stepRange.defaultValue());
+    const StepRange stepRange(element.createStepRange(RejectAny));
+    const Decimal oldValue = parseToDecimalForNumberType(element.value(), stepRange.defaultValue());
     return stepRange.proportionFromValue(stepRange.clampValue(oldValue));
 }
 
-inline static bool hasVerticalAppearance(HTMLInputElement* input)
+inline static bool hasVerticalAppearance(HTMLInputElement& input)
 {
-    ASSERT(input->renderer());
-    const RenderStyle& sliderStyle = input->renderer()->style();
+    ASSERT(input.renderer());
+    const RenderStyle& sliderStyle = input.renderer()->style();
 
 #if ENABLE(VIDEO)
-    if (sliderStyle.appearance() == MediaVolumeSliderPart && input->renderer()->theme().usesVerticalVolumeSlider())
+    if (sliderStyle.appearance() == MediaVolumeSliderPart && input.renderer()->theme().usesVerticalVolumeSlider())
         return true;
 #endif
 
@@ -126,11 +126,12 @@ private:
 
 void RenderSliderContainer::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
 {
-    HTMLInputElement* input = element()->shadowHost()->toInputElement();
+    ASSERT(element()->shadowHost());
+    auto& input = downcast<HTMLInputElement>(*element()->shadowHost());
     bool isVertical = hasVerticalAppearance(input);
 
 #if ENABLE(DATALIST_ELEMENT)
-    if (input->renderer()->isSlider() && !isVertical && input->list()) {
+    if (input.renderer()->isSlider() && !isVertical && input.list()) {
         int offsetFromCenter = theme().sliderTickOffsetFromTrackCenter();
         LayoutUnit trackHeight = 0;
         if (offsetFromCenter < 0)
@@ -154,7 +155,8 @@ void RenderSliderContainer::computeLogicalHeight(LayoutUnit logicalHeight, Layou
 
 void RenderSliderContainer::layout()
 {
-    HTMLInputElement* input = element()->shadowHost()->toInputElement();
+    ASSERT(element()->shadowHost());
+    auto& input = downcast<HTMLInputElement>(*element()->shadowHost());
     bool isVertical = hasVerticalAppearance(input);
     style().setFlexDirection(isVertical ? FlowColumn : FlowRow);
     TextDirection oldTextDirection = style().direction();
@@ -165,8 +167,8 @@ void RenderSliderContainer::layout()
         style().setDirection(LTR);
     }
 
-    RenderBox* thumb = input->sliderThumbElement() ? input->sliderThumbElement()->renderBox() : 0;
-    RenderBox* track = input->sliderTrackElement() ? input->sliderTrackElement()->renderBox() : 0;
+    RenderBox* thumb = input.sliderThumbElement() ? input.sliderThumbElement()->renderBox() : nullptr;
+    RenderBox* track = input.sliderTrackElement() ? input.sliderTrackElement()->renderBox() : nullptr;
     // Force a layout to reset the position of the thumb so the code below doesn't move the thumb to the wrong place.
     // FIXME: Make a custom Render class for the track and move the thumb positioning code there.
     if (track)
@@ -261,7 +263,7 @@ void SliderThumbElement::setPositionFromPoint(const LayoutPoint& absolutePoint)
     RenderBox& inputRenderer = downcast<RenderBox>(*input->renderer());
     RenderBox& trackRenderer = *trackElement->renderBox();
 
-    bool isVertical = hasVerticalAppearance(input.get());
+    bool isVertical = hasVerticalAppearance(*input);
     bool isLeftToRightDirection = renderBox()->style().isLeftToRightDirection();
     
     LayoutPoint offset(inputRenderer.absoluteToLocal(absolutePoint, UseTransforms));
@@ -569,8 +571,7 @@ HTMLInputElement* SliderThumbElement::hostInput() const
 {
     // Only HTMLInputElement creates SliderThumbElement instances as its shadow nodes.
     // So, shadowHost() must be an HTMLInputElement.
-    Element* host = shadowHost();
-    return host ? host->toInputElement() : 0;
+    return downcast<HTMLInputElement>(shadowHost());
 }
 
 static const AtomicString& sliderThumbShadowPseudoId()
@@ -644,13 +645,14 @@ const AtomicString& SliderContainerElement::shadowPseudoId() const
     DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-media-slider-container", AtomicString::ConstructFromLiteral));
     DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, sliderContainer, ("-webkit-slider-container", AtomicString::ConstructFromLiteral));
 
-    HTMLInputElement* input = shadowHost()->toInputElement();
-    if (!input)
+    if (!is<HTMLInputElement>(*shadowHost()))
         return sliderContainer;
-    if (!input->renderer())
+
+    auto& input = downcast<HTMLInputElement>(*shadowHost());
+    if (!input.renderer())
         return emptyAtom;
 
-    const RenderStyle& sliderStyle = input->renderer()->style();
+    const RenderStyle& sliderStyle = input.renderer()->style();
     switch (sliderStyle.appearance()) {
     case MediaSliderPart:
     case MediaSliderThumbPart:
index 3fef111..707957b 100644 (file)
@@ -421,9 +421,9 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy)
     if (unloadEventPolicy != UnloadEventPolicyNone) {
         if (m_frame.document()) {
             if (m_didCallImplicitClose && !m_wasUnloadEventEmitted) {
-                Element* currentFocusedElement = m_frame.document()->focusedElement();
-                if (currentFocusedElement && currentFocusedElement->toInputElement())
-                    currentFocusedElement->toInputElement()->endEditing();
+                auto* currentFocusedElement = m_frame.document()->focusedElement();
+                if (is<HTMLInputElement>(currentFocusedElement))
+                    downcast<HTMLInputElement>(*currentFocusedElement).endEditing();
                 if (m_pageDismissalEventBeingDispatched == PageDismissalType::None) {
                     if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) {
                         m_pageDismissalEventBeingDispatched = PageDismissalType::PageHide;
index 2c76f63..050b628 100644 (file)
@@ -281,17 +281,20 @@ DragOperation DragController::dragEnteredOrUpdated(DragData& dragData)
     return dragOperation;
 }
 
-static HTMLInputElement* asFileInput(Node* node)
+static HTMLInputElement* asFileInput(Node& node)
 {
-    ASSERT(node);
+    if (!is<HTMLInputElement>(node))
+        return nullptr;
 
-    HTMLInputElement* inputElement = node->toInputElement();
+    auto* inputElement = &downcast<HTMLInputElement>(node);
 
     // If this is a button inside of the a file input, move up to the file input.
-    if (inputElement && inputElement->isTextButton() && is<ShadowRoot>(inputElement->treeScope().rootNode()))
-        inputElement = downcast<ShadowRoot>(inputElement->treeScope().rootNode()).host()->toInputElement();
+    if (inputElement->isTextButton() && is<ShadowRoot>(inputElement->treeScope().rootNode())) {
+        auto& host = *downcast<ShadowRoot>(inputElement->treeScope().rootNode()).host();
+        inputElement = is<HTMLInputElement>(host) ? &downcast<HTMLInputElement>(host) : nullptr;
+    }
 
-    return inputElement && inputElement->isFileUpload() ? inputElement : 0;
+    return inputElement && inputElement->isFileUpload() ? inputElement : nullptr;
 }
 
 // This can return null if an empty document is loaded.
@@ -355,7 +358,7 @@ bool DragController::tryDocumentDrag(DragData& dragData, DragDestinationAction a
         if (!element)
             return false;
         
-        HTMLInputElement* elementAsFileInput = asFileInput(element);
+        HTMLInputElement* elementAsFileInput = asFileInput(*element);
         if (m_fileInputElementUnderMouse != elementAsFileInput) {
             if (m_fileInputElementUnderMouse)
                 m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
@@ -565,7 +568,7 @@ bool DragController::canProcessDrag(DragData& dragData)
     if (!result.innerNonSharedNode())
         return false;
 
-    if (dragData.containsFiles() && asFileInput(result.innerNonSharedNode()))
+    if (dragData.containsFiles() && asFileInput(*result.innerNonSharedNode()))
         return true;
 
     if (is<HTMLPlugInElement>(*result.innerNonSharedNode())) {
index 7a3eaa9..d1d0d91 100644 (file)
@@ -61,7 +61,7 @@ bool RenderButton::canBeSelectionLeaf() const
 
 bool RenderButton::hasLineIfEmpty() const
 {
-    return formControlElement().toInputElement();
+    return is<HTMLInputElement>(formControlElement());
 }
 
 void RenderButton::addChild(RenderObject* newChild, RenderObject* beforeChild)
index 5961746..1aaf369 100644 (file)
@@ -785,26 +785,12 @@ bool RenderTheme::isActive(const RenderObject& o) const
 
 bool RenderTheme::isChecked(const RenderObject& o) const
 {
-    if (!o.node())
-        return false;
-
-    HTMLInputElement* inputElement = o.node()->toInputElement();
-    if (!inputElement)
-        return false;
-
-    return inputElement->shouldAppearChecked();
+    return is<HTMLInputElement>(o.node()) && downcast<HTMLInputElement>(*o.node()).shouldAppearChecked();
 }
 
 bool RenderTheme::isIndeterminate(const RenderObject& o) const
 {
-    if (!o.node())
-        return false;
-
-    HTMLInputElement* inputElement = o.node()->toInputElement();
-    if (!inputElement)
-        return false;
-
-    return inputElement->shouldAppearIndeterminate();
+    return is<HTMLInputElement>(o.node()) && downcast<HTMLInputElement>(*o.node()).shouldAppearIndeterminate();
 }
 
 bool RenderTheme::isEnabled(const RenderObject& renderer) const
@@ -993,20 +979,16 @@ LayoutUnit RenderTheme::sliderTickSnappingThreshold() const
 
 void RenderTheme::paintSliderTicks(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& rect)
 {
-    Node* node = o.node();
-    if (!node)
-        return;
-
-    HTMLInputElement* input = node->toInputElement();
-    if (!input)
+    if (!is<HTMLInputElement>(o.node()))
         return;
 
-    HTMLDataListElement* dataList = downcast<HTMLDataListElement>(input->list());
+    auto& input = downcast<HTMLInputElement>(*o.node());
+    auto* dataList = downcast<HTMLDataListElement>(input.list());
     if (!dataList)
         return;
 
-    double min = input->minimum();
-    double max = input->maximum();
+    double min = input.minimum();
+    double max = input.maximum();
     ControlPart part = o.style().appearance();
     // We don't support ticks on alternate sliders like MediaVolumeSliders.
     if (part !=  SliderHorizontalPart && part != SliderVerticalPart)
@@ -1014,7 +996,7 @@ void RenderTheme::paintSliderTicks(const RenderObject& o, const PaintInfo& paint
     bool isHorizontal = part ==  SliderHorizontalPart;
 
     IntSize thumbSize;
-    const RenderObject* thumbRenderer = input->sliderThumbElement()->renderer();
+    const RenderObject* thumbRenderer = input.sliderThumbElement()->renderer();
     if (thumbRenderer) {
         const RenderStyle& thumbStyle = thumbRenderer->style();
         int thumbWidth = thumbStyle.width().intValue();
@@ -1029,7 +1011,7 @@ void RenderTheme::paintSliderTicks(const RenderObject& o, const PaintInfo& paint
     int tickRegionSideMargin = 0;
     int tickRegionWidth = 0;
     IntRect trackBounds;
-    RenderObject* trackRenderer = input->sliderTrackElement()->renderer();
+    RenderObject* trackRenderer = input.sliderTrackElement()->renderer();
     // We can ignoring transforms because transform is handled by the graphics context.
     if (trackRenderer)
         trackBounds = trackRenderer->absoluteBoundingBoxRectIgnoringTransforms();
@@ -1059,9 +1041,9 @@ void RenderTheme::paintSliderTicks(const RenderObject& o, const PaintInfo& paint
         ASSERT(is<HTMLOptionElement>(*node));
         HTMLOptionElement& optionElement = downcast<HTMLOptionElement>(*node);
         String value = optionElement.value();
-        if (!input->isValidValue(value))
+        if (!input.isValidValue(value))
             continue;
-        double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value));
+        double parsedValue = parseToDoubleForNumberType(input.sanitizeValue(value));
         double tickFraction = (parsedValue - min) / (max - min);
         double tickRatio = isHorizontal && o.style().isLeftToRightDirection() ? tickFraction : 1.0 - tickFraction;
         double tickPosition = round(tickRegionSideMargin + tickRegionWidth * tickRatio);
index 8c6f122..43db808 100644 (file)
@@ -1188,8 +1188,8 @@ bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec)
         return false;
     }
 
-    if (HTMLInputElement* inputElement = textField->toInputElement())
-        return inputElement->lastChangeWasUserEdit();
+    if (is<HTMLInputElement>(*textField))
+        return downcast<HTMLInputElement>(*textField).lastChangeWasUserEdit();
 
     if (is<HTMLTextAreaElement>(*textField))
         return downcast<HTMLTextAreaElement>(*textField).lastChangeWasUserEdit();
@@ -1205,11 +1205,12 @@ bool Internals::elementShouldAutoComplete(Element* element, ExceptionCode& ec)
         return false;
     }
 
-    if (HTMLInputElement* inputElement = element->toInputElement())
-        return inputElement->shouldAutocomplete();
+    if (!is<HTMLInputElement>(*element)) {
+        ec = INVALID_NODE_TYPE_ERR;
+        return false;
+    }
 
-    ec = INVALID_NODE_TYPE_ERR;
-    return false;
+    return downcast<HTMLInputElement>(*element).shouldAutocomplete();
 }
 
 void Internals::setEditingValue(Element* element, const String& value, ExceptionCode& ec)
@@ -1219,33 +1220,42 @@ void Internals::setEditingValue(Element* element, const String& value, Exception
         return;
     }
 
-    HTMLInputElement* inputElement = element->toInputElement();
-    if (!inputElement) {
+    if (!is<HTMLInputElement>(*element)) {
         ec = INVALID_NODE_TYPE_ERR;
         return;
     }
 
-    inputElement->setEditingValue(value);
+    downcast<HTMLInputElement>(*element).setEditingValue(value);
 }
 
 void Internals::setAutofilled(Element* element, bool enabled, ExceptionCode& ec)
 {
-    HTMLInputElement* inputElement = element->toInputElement();
-    if (!inputElement) {
+    if (!element) {
         ec = INVALID_ACCESS_ERR;
         return;
     }
-    inputElement->setAutoFilled(enabled);
+
+    if (!is<HTMLInputElement>(*element)) {
+        ec = INVALID_NODE_TYPE_ERR;
+        return;
+    }
+
+    downcast<HTMLInputElement>(*element).setAutoFilled(enabled);
 }
 
 void Internals::setShowAutoFillButton(Element* element, bool show, ExceptionCode& ec)
 {
-    HTMLInputElement* inputElement = element->toInputElement();
-    if (!inputElement) {
+    if (!element) {
         ec = INVALID_ACCESS_ERR;
         return;
     }
-    inputElement->setShowAutoFillButton(show);
+
+    if (!is<HTMLInputElement>(*element)) {
+        ec = INVALID_NODE_TYPE_ERR;
+        return;
+    }
+
+    downcast<HTMLInputElement>(*element).setShowAutoFillButton(show);
 }