Move Node::isMouseFocusable() to Element.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 25 May 2013 23:09:29 +0000 (23:09 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 25 May 2013 23:09:29 +0000 (23:09 +0000)
<http://webkit.org/b/116762>

Reviewed by Anders Carlsson.

Source/WebCore:

Node::isMouseFocusable() would just return isFocusable(), which is never true for a non-Element
since Node::supportsFocus() always returns false. So move it to Element!

* dom/Node.h:
* dom/Node.cpp:
* dom/Element.h:
* dom/Element.cpp:
(WebCore::Element::isMouseFocusable):

    Moved here from Node.

* editing/FrameSelection.cpp:
(WebCore::FrameSelection::setFocusedNodeIfNeeded):
* page/EventHandler.cpp:
(WebCore::EventHandler::dispatchMouseEvent):

    Walk up the parent chain with parentOrShadowHostElement() instead of parentOrShadowHostNode().
    Removed a misleading no-op hunk about mouse-focusable ShadowRoots, since ShadowRoots are not
    Elements and thus cannot be mouse-focusable.

* page/TouchAdjustment.cpp:
(WebCore::TouchAdjustment::nodeRespondsToTapGesture):

    Check that the Node is an Element before asking if it's mouse-focusable.

* html/HTMLAnchorElement.h:
* html/HTMLAreaElement.h:
* html/HTMLFormControlElement.h:
* html/HTMLInputElement.h:
* html/HTMLMediaElement.h:
* html/HTMLSelectElement.h:
* html/HTMLTextAreaElement.h:
* html/shadow/ClearButtonElement.h:
* html/shadow/TextControlInnerElements.h:
* svg/SVGAElement.h:
* svg/SVGStyledElement.h:

    Sprinkle OVERRIDE.

Source/WebKit2:

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::highlightPotentialActivation):

    Check that the potentially activated Node is an Element before asking if it's mouse-focusable.

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

21 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/editing/FrameSelection.cpp
Source/WebCore/html/HTMLAnchorElement.h
Source/WebCore/html/HTMLAreaElement.h
Source/WebCore/html/HTMLFormControlElement.h
Source/WebCore/html/HTMLInputElement.h
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLSelectElement.h
Source/WebCore/html/HTMLTextAreaElement.h
Source/WebCore/html/shadow/ClearButtonElement.h
Source/WebCore/html/shadow/TextControlInnerElements.h
Source/WebCore/page/EventHandler.cpp
Source/WebCore/page/TouchAdjustment.cpp
Source/WebCore/svg/SVGAElement.h
Source/WebCore/svg/SVGStyledElement.h
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebPage/WebPage.cpp

index e5ff2fe..e87f469 100644 (file)
@@ -1,5 +1,51 @@
 2013-05-25  Andreas Kling  <akling@apple.com>
 
+        Move Node::isMouseFocusable() to Element.
+        <http://webkit.org/b/116762>
+
+        Reviewed by Anders Carlsson.
+
+        Node::isMouseFocusable() would just return isFocusable(), which is never true for a non-Element
+        since Node::supportsFocus() always returns false. So move it to Element!
+
+        * dom/Node.h:
+        * dom/Node.cpp:
+        * dom/Element.h:
+        * dom/Element.cpp:
+        (WebCore::Element::isMouseFocusable):
+
+            Moved here from Node.
+
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::setFocusedNodeIfNeeded):
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::dispatchMouseEvent):
+
+            Walk up the parent chain with parentOrShadowHostElement() instead of parentOrShadowHostNode().
+            Removed a misleading no-op hunk about mouse-focusable ShadowRoots, since ShadowRoots are not
+            Elements and thus cannot be mouse-focusable.
+
+        * page/TouchAdjustment.cpp:
+        (WebCore::TouchAdjustment::nodeRespondsToTapGesture):
+
+            Check that the Node is an Element before asking if it's mouse-focusable.
+
+        * html/HTMLAnchorElement.h:
+        * html/HTMLAreaElement.h:
+        * html/HTMLFormControlElement.h:
+        * html/HTMLInputElement.h:
+        * html/HTMLMediaElement.h:
+        * html/HTMLSelectElement.h:
+        * html/HTMLTextAreaElement.h:
+        * html/shadow/ClearButtonElement.h:
+        * html/shadow/TextControlInnerElements.h:
+        * svg/SVGAElement.h:
+        * svg/SVGStyledElement.h:
+
+            Sprinkle OVERRIDE.
+
+2013-05-25  Andreas Kling  <akling@apple.com>
+
         Move Node::isKeyboardFocusable() to Element.
         <http://webkit.org/b/116761>
 
index fdc69fc..d91b99e 100644 (file)
@@ -254,6 +254,11 @@ bool Element::isKeyboardFocusable(KeyboardEvent*) const
     return isFocusable() && tabIndex() >= 0;
 }
 
+bool Element::isMouseFocusable() const
+{
+    return isFocusable();
+}
+
 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, blur);
 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
index e460c03..6bb4ae4 100644 (file)
@@ -433,6 +433,7 @@ public:
     virtual void setFocus(bool flag);
 
     virtual bool isKeyboardFocusable(KeyboardEvent*) const;
+    virtual bool isMouseFocusable() const;
 
     RenderStyle* computedStyle(PseudoId = NOPSEUDO);
 
index 62144df..7cdaf27 100644 (file)
@@ -885,11 +885,6 @@ bool Node::isFocusable() const
     return true;
 }
 
-bool Node::isMouseFocusable() const
-{
-    return isFocusable();
-}
-
 Node* Node::focusDelegate()
 {
     return this;
index a0444c6..2bbf76b 100644 (file)
@@ -406,7 +406,6 @@ public:
     virtual bool supportsFocus() const;
     // Whether the node can actually be focused.
     virtual bool isFocusable() const;
-    virtual bool isMouseFocusable() const;
     virtual Node* focusDelegate();
 
     enum UserSelectAllTreatment {
index 1e84652..41c5f67 100644 (file)
@@ -1889,8 +1889,8 @@ void FrameSelection::setFocusedNodeIfNeeded()
         }
     }
 
-    if (Node* target = rootEditableElement()) {
-        // Walk up the DOM tree to search for a node to focus. 
+    if (Element* target = rootEditableElement()) {
+        // Walk up the DOM tree to search for an element to focus.
         while (target) {
             // We don't want to set focus on a subframe when selecting in a parent frame,
             // so add the !isFrameElement check here. There's probably a better way to make this
@@ -1899,7 +1899,7 @@ void FrameSelection::setFocusedNodeIfNeeded()
                 m_frame->page()->focusController()->setFocusedNode(target, m_frame);
                 return;
             }
-            target = target->parentOrShadowHostNode();
+            target = target->parentOrShadowHostElement();
         }
         m_frame->document()->setFocusedNode(0);
     }
index 040b6e1..a82ab75 100644 (file)
@@ -109,7 +109,7 @@ protected:
 
 private:
     virtual bool supportsFocus() const;
-    virtual bool isMouseFocusable() const;
+    virtual bool isMouseFocusable() const OVERRIDE;
     virtual bool isKeyboardFocusable(KeyboardEvent*) const OVERRIDE;
     virtual void defaultEventHandler(Event*);
     virtual void setActive(bool active = true, bool pause = false);
index 3202274..7af0dfb 100644 (file)
@@ -54,7 +54,7 @@ private:
     virtual bool supportsFocus() const;
     virtual String target() const;
     virtual bool isKeyboardFocusable(KeyboardEvent*) const OVERRIDE;
-    virtual bool isMouseFocusable() const;
+    virtual bool isMouseFocusable() const OVERRIDE;
     virtual bool isFocusable() const;
     virtual void updateFocusAppearance(bool /*restorePreviousSelection*/);
     virtual void setFocus(bool) OVERRIDE;
index db6430f..0f87566 100644 (file)
@@ -117,7 +117,7 @@ protected:
 
     virtual bool supportsFocus() const;
     virtual bool isKeyboardFocusable(KeyboardEvent*) const OVERRIDE;
-    virtual bool isMouseFocusable() const;
+    virtual bool isMouseFocusable() const OVERRIDE;
 
     virtual void didRecalcStyle(StyleChange) OVERRIDE;
 
index b031cce..e462286 100644 (file)
@@ -324,7 +324,7 @@ private:
 
     virtual bool hasCustomFocusLogic() const OVERRIDE;
     virtual bool isKeyboardFocusable(KeyboardEvent*) const OVERRIDE;
-    virtual bool isMouseFocusable() const;
+    virtual bool isMouseFocusable() const OVERRIDE;
     virtual bool isEnumeratable() const;
     virtual bool supportLabels() const OVERRIDE;
     virtual void updateFocusAppearance(bool restorePreviousSelection);
index c5721f1..2b15ed1 100644 (file)
@@ -431,7 +431,7 @@ private:
 
     virtual bool hasCustomFocusLogic() const OVERRIDE;
     virtual bool supportsFocus() const;
-    virtual bool isMouseFocusable() const;
+    virtual bool isMouseFocusable() const OVERRIDE;
     virtual bool rendererIsNeeded(const NodeRenderingContext&);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
     virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
index 40ae3e2..45a0174 100644 (file)
@@ -112,7 +112,7 @@ private:
     virtual const AtomicString& formControlType() const;
     
     virtual bool isKeyboardFocusable(KeyboardEvent*) const OVERRIDE;
-    virtual bool isMouseFocusable() const;
+    virtual bool isMouseFocusable() const OVERRIDE;
 
     virtual void dispatchFocusEvent(PassRefPtr<Node> oldFocusedNode, FocusDirection) OVERRIDE;
     virtual void dispatchBlurEvent(PassRefPtr<Node> newFocusedNode);
index 76da41c..d86c3c2 100644 (file)
@@ -104,7 +104,7 @@ private:
     virtual bool appendFormData(FormDataList&, bool);
     virtual void reset();
     virtual bool hasCustomFocusLogic() const OVERRIDE;
-    virtual bool isMouseFocusable() const;
+    virtual bool isMouseFocusable() const OVERRIDE;
     virtual bool isKeyboardFocusable(KeyboardEvent*) const OVERRIDE;
     virtual void updateFocusAppearance(bool restorePreviousSelection);
 
index 35462b1..0f940a5 100644 (file)
@@ -48,7 +48,7 @@ public:
 private:
     ClearButtonElement(Document*, ClearButtonOwner&);
     virtual void detach();
-    virtual bool isMouseFocusable() const { return false; }
+    virtual bool isMouseFocusable() const OVERRIDE { return false; }
     virtual void defaultEventHandler(Event*);
 
     ClearButtonOwner* m_clearButtonOwner;
index 7f36582..62e2968 100644 (file)
@@ -52,7 +52,7 @@ protected:
     virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
 
 private:
-    virtual bool isMouseFocusable() const { return false; }
+    virtual bool isMouseFocusable() const OVERRIDE { return false; }
 };
 
 class TextControlInnerTextElement FINAL : public HTMLDivElement {
@@ -65,7 +65,7 @@ private:
     TextControlInnerTextElement(Document*);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
     virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
-    virtual bool isMouseFocusable() const { return false; }
+    virtual bool isMouseFocusable() const OVERRIDE { return false; }
 };
 
 class SearchFieldResultsButtonElement FINAL : public HTMLDivElement {
@@ -78,7 +78,7 @@ public:
 private:
     SearchFieldResultsButtonElement(Document*);
     virtual const AtomicString& shadowPseudoId() const;
-    virtual bool isMouseFocusable() const { return false; }
+    virtual bool isMouseFocusable() const OVERRIDE { return false; }
 };
 
 class SearchFieldCancelButtonElement FINAL : public HTMLDivElement {
@@ -92,7 +92,7 @@ private:
     SearchFieldCancelButtonElement(Document*);
     virtual const AtomicString& shadowPseudoId() const;
     virtual void detach();
-    virtual bool isMouseFocusable() const { return false; }
+    virtual bool isMouseFocusable() const OVERRIDE { return false; }
 
     bool m_capturing;
 };
@@ -130,7 +130,7 @@ private:
     SpeechInput* speechInput();
     void setState(SpeechInputState state);
     virtual const AtomicString& shadowPseudoId() const;
-    virtual bool isMouseFocusable() const { return false; }
+    virtual bool isMouseFocusable() const OVERRIDE { return false; }
     virtual void attach();
 
     bool m_capturing;
index 6de6733..0f7045e 100644 (file)
@@ -2330,37 +2330,41 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
         // Blur current focus node when a link/button is clicked; this
         // is expected by some sites that rely on onChange handlers running
         // from form fields before the button click is processed.
-        Node* node = m_nodeUnderMouse.get();
 
-        // Walk up the DOM tree to search for a node to focus.
-        while (node) {
-            if (node->isMouseFocusable()) {
+        Element* element;
+        if (m_nodeUnderMouse)
+            element = m_nodeUnderMouse->isElementNode() ? toElement(m_nodeUnderMouse.get()) : m_nodeUnderMouse->parentOrShadowHostElement();
+        else
+            element = 0;
+
+        // Walk up the DOM tree to search for an element to focus.
+        while (element) {
+            if (element->isMouseFocusable()) {
                 // To fix <rdar://problem/4895428> Can't drag selected ToDo, we don't focus a
                 // node on mouse down if it's selected and inside a focused node. It will be
                 // focused if the user does a mouseup over it, however, because the mouseup
                 // will set a selection inside it, which will call setFocuseNodeIfNeeded.
-                Node* n = node->isShadowRoot() ? toShadowRoot(node)->host() : node;
                 if (m_frame->selection()->isRange()
-                    && m_frame->selection()->toNormalizedRange()->compareNode(n, IGNORE_EXCEPTION) == Range::NODE_INSIDE
-                    && n->isDescendantOf(m_frame->document()->focusedNode()))
+                    && m_frame->selection()->toNormalizedRange()->compareNode(element, IGNORE_EXCEPTION) == Range::NODE_INSIDE
+                    && element->isDescendantOf(m_frame->document()->focusedNode()))
                     return true;
                     
                 break;
             }
-            node = node->parentOrShadowHostNode();
+            element = element->parentOrShadowHostElement();
         }
 
         // Only change the focus when clicking scrollbars if it can transfered to a mouse focusable node.
-        if ((!node || !node->isMouseFocusable()) && isInsideScrollbar(mouseEvent.position()))
+        if ((!element || !element->isMouseFocusable()) && isInsideScrollbar(mouseEvent.position()))
             return false;
 
         // If focus shift is blocked, we eat the event.  Note we should never clear swallowEvent
         // if the page already set it (e.g., by canceling default behavior).
         if (Page* page = m_frame->page()) {
-            if (node && node->isMouseFocusable()) {
-                if (!page->focusController()->setFocusedNode(node, m_frame))
+            if (element && element->isMouseFocusable()) {
+                if (!page->focusController()->setFocusedNode(element, m_frame))
                     swallowEvent = true;
-            } else if (!node || !node->isElementNode() || !toElement(node)->focused()) {
+            } else if (!element || !element->focused()) {
                 if (!page->focusController()->setFocusedNode(0, m_frame))
                     swallowEvent = true;
             }
index 7b59df0..8b01c45 100644 (file)
@@ -73,13 +73,13 @@ typedef float (*DistanceFunction)(const IntPoint&, const IntRect&, const Subtarg
 // Takes non-const Node* because isContentEditable is a non-const function.
 bool nodeRespondsToTapGesture(Node* node)
 {
-    if (node->isMouseFocusable())
-        return true;
     if (node->willRespondToMouseClickEvents() || node->willRespondToMouseMoveEvents())
         return true;
     // Accept nodes that has a CSS effect when touched.
     if (node->isElementNode()) {
         Element* element = toElement(node);
+        if (element->isMouseFocusable())
+            return true;
         if (element->childrenAffectedByActive() || element->childrenAffectedByHover())
             return true;
     }
index e367123..4ccb10c 100644 (file)
@@ -57,7 +57,7 @@ private:
     virtual void defaultEventHandler(Event*);
     
     virtual bool supportsFocus() const;
-    virtual bool isMouseFocusable() const;
+    virtual bool isMouseFocusable() const OVERRIDE;
     virtual bool isKeyboardFocusable(KeyboardEvent*) const OVERRIDE;
     virtual bool isFocusable() const;
     virtual bool isURLAttribute(const Attribute&) const;
index 87f5c13..1283603 100644 (file)
@@ -81,7 +81,7 @@ private:
     virtual bool isSVGStyledElement() const OVERRIDE FINAL { return true; }
 
     virtual bool isKeyboardFocusable(KeyboardEvent*) const OVERRIDE;
-    virtual bool isMouseFocusable() const;
+    virtual bool isMouseFocusable() const OVERRIDE;
 
     void buildPendingResourcesIfNeeded();
 
index 91d0b9b..47575a5 100644 (file)
@@ -1,5 +1,17 @@
 2013-05-25  Andreas Kling  <akling@apple.com>
 
+        Move Node::isMouseFocusable() to Element.
+        <http://webkit.org/b/116762>
+
+        Reviewed by Anders Carlsson.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::highlightPotentialActivation):
+
+            Check that the potentially activated Node is an Element before asking if it's mouse-focusable.
+
+2013-05-25  Andreas Kling  <akling@apple.com>
+
         REGRESSION: WebProcess is terminated when all Safari windows are closed.
         <rdar://problem/13990901>
         <http://webkit.org/b/116766>
index bbe7089..5b8a6dc 100644 (file)
@@ -1883,7 +1883,7 @@ void WebPage::highlightPotentialActivation(const IntPoint& point, const IntSize&
                 break;
 
             // We always highlight focusable (form-elements), image links or content-editable elements.
-            if (node->isMouseFocusable() || node->isLink() || node->isContentEditable())
+            if ((node->isElementNode() && toElement(node)->isMouseFocusable()) || node->isLink() || node->isContentEditable())
                 activationNode = node;
             else if (node->willRespondToMouseClickEvents()) {
                 // Highlight elements with default mouse-click handlers, but highlight only inline elements with