2010-07-16 Kent Tamura <tkent@chromium.org>
authortkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Jul 2010 21:18:43 +0000 (21:18 +0000)
committertkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Jul 2010 21:18:43 +0000 (21:18 +0000)
        Reviewed by Darin Fisher.

        Improve hover state handling for spin buttons
        https://bugs.webkit.org/show_bug.cgi?id=42260

        Background:
        When we move the mouse cursor to a node from the outside of the node,
        the following steps are executed.
         1. setHovered(true) is called.
         2. The node is repainted for the hover state.
         3. 'mousemove' event is dispatched for the node.
        For a spin-button, RenderTheme::paint{Inner,Outer}SpinButton() is
        called before the event handler of the spin-button. So we can't
        detect which of the up part or the down part is hovered correctly.

        Solution:
        The hover state of a spin-button is one of three states;
        Indeterminate, Up, and Down. The state is Indeterminate since
        setHovered(true) is called and until 'mousemove' event is
        dispatched.

        No new tests because there are no implementation of spin-buttons
        with hovered state yet.

        * rendering/RenderTheme.cpp:
        (WebCore::RenderTheme::isSpinUpButtonPartPressed):
        (WebCore::RenderTheme::isHovered):
         Return false if the node is a spin-button and the state is Indeterminate.
        (WebCore::RenderTheme::isSpinUpButtonPartHovered):
        * rendering/TextControlInnerElements.cpp:
        (WebCore::SpinButtonElement::SpinButtonElement):
         Initialize m_upDownState.
        (WebCore::SpinButtonElement::defaultEventHandler):
        (WebCore::SpinButtonElement::setHovered):
         Set the state to Indeterminate.
        * rendering/TextControlInnerElements.h:
        (WebCore::SpinButtonElement::upDownState):

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

WebCore/ChangeLog
WebCore/rendering/RenderTheme.cpp
WebCore/rendering/TextControlInnerElements.cpp
WebCore/rendering/TextControlInnerElements.h

index e48e83d..7d4bee2 100644 (file)
@@ -1,3 +1,43 @@
+2010-07-16  Kent Tamura  <tkent@chromium.org>
+
+        Reviewed by Darin Fisher.
+
+        Improve hover state handling for spin buttons
+        https://bugs.webkit.org/show_bug.cgi?id=42260
+
+        Background:
+        When we move the mouse cursor to a node from the outside of the node,
+        the following steps are executed.
+         1. setHovered(true) is called.
+         2. The node is repainted for the hover state.
+         3. 'mousemove' event is dispatched for the node.
+        For a spin-button, RenderTheme::paint{Inner,Outer}SpinButton() is
+        called before the event handler of the spin-button. So we can't
+        detect which of the up part or the down part is hovered correctly.
+
+        Solution:
+        The hover state of a spin-button is one of three states;
+        Indeterminate, Up, and Down. The state is Indeterminate since
+        setHovered(true) is called and until 'mousemove' event is
+        dispatched.
+
+        No new tests because there are no implementation of spin-buttons
+        with hovered state yet.
+
+        * rendering/RenderTheme.cpp:
+        (WebCore::RenderTheme::isSpinUpButtonPartPressed):
+        (WebCore::RenderTheme::isHovered):
+         Return false if the node is a spin-button and the state is Indeterminate.
+        (WebCore::RenderTheme::isSpinUpButtonPartHovered):
+        * rendering/TextControlInnerElements.cpp:
+        (WebCore::SpinButtonElement::SpinButtonElement):
+         Initialize m_upDownState.
+        (WebCore::SpinButtonElement::defaultEventHandler):
+        (WebCore::SpinButtonElement::setHovered):
+         Set the state to Indeterminate.
+        * rendering/TextControlInnerElements.h:
+        (WebCore::SpinButtonElement::upDownState):
+
 2010-07-16  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Simon Fraser.
index 6d18e4f..bd96d11 100644 (file)
@@ -828,7 +828,7 @@ bool RenderTheme::isSpinUpButtonPartPressed(const RenderObject* o) const
         || !static_cast<Element*>(node)->isSpinButtonElement())
         return false;
     SpinButtonElement* element = static_cast<SpinButtonElement*>(node);
-    return element->onUpButton();
+    return element->upDownState() == SpinButtonElement::Up;
 }
 
 bool RenderTheme::isReadOnlyControl(const RenderObject* o) const
@@ -841,19 +841,22 @@ bool RenderTheme::isReadOnlyControl(const RenderObject* o) const
 
 bool RenderTheme::isHovered(const RenderObject* o) const
 {
-    if (!o->node())
+    Node* node = o->node();
+    if (!node)
         return false;
-    return o->node()->hovered();
+    if (!node->isElementNode() || !static_cast<Element*>(node)->isSpinButtonElement())
+        return node->hovered();
+    SpinButtonElement* element = static_cast<SpinButtonElement*>(node);
+    return element->hovered() && element->upDownState() != SpinButtonElement::Indeterminate;
 }
 
 bool RenderTheme::isSpinUpButtonPartHovered(const RenderObject* o) const
 {
     Node* node = o->node();
-    if (!node || !node->active() || !node->isElementNode()
-        || !static_cast<Element*>(node)->isSpinButtonElement())
+    if (!node || !node->isElementNode() || !static_cast<Element*>(node)->isSpinButtonElement())
         return false;
     SpinButtonElement* element = static_cast<SpinButtonElement*>(node);
-    return element->onUpButton();
+    return element->upDownState() == SpinButtonElement::Up;
 }
 
 bool RenderTheme::isDefault(const RenderObject* o) const
index 9bbf491..24e1d74 100644 (file)
@@ -248,7 +248,7 @@ void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
 inline SpinButtonElement::SpinButtonElement(Node* shadowParent)
     : TextControlInnerElement(shadowParent->document(), shadowParent)
     , m_capturing(false)
-    , m_onUpButton(false)
+    , m_upDownState(Indeterminate)
 {
 }
 
@@ -306,9 +306,9 @@ void SpinButtonElement::defaultEventHandler(Event* event)
                     m_capturing = true;
                 }
             }
-            bool oldOnUpButton = m_onUpButton;
-            m_onUpButton = local.y() < box->height() / 2;
-            if (m_onUpButton != oldOnUpButton)
+            UpDownState oldUpDownState = m_upDownState;
+            m_upDownState = local.y() < box->height() / 2 ? Up : Down;
+            if (m_upDownState != oldUpDownState)
                 renderer()->repaint();
         } else {
             if (m_capturing) {
@@ -324,6 +324,14 @@ void SpinButtonElement::defaultEventHandler(Event* event)
         HTMLDivElement::defaultEventHandler(event);
 }
 
+void SpinButtonElement::setHovered(bool flag)
+{
+    if (!hovered() && flag)
+        m_upDownState = Indeterminate;
+    TextControlInnerElement::setHovered(flag);
+}
+
+
 // ----------------------------
 
 #if ENABLE(INPUT_SPEECH)
index b8380bd..68d6ff4 100644 (file)
@@ -90,11 +90,14 @@ private:
 
 class SpinButtonElement : public TextControlInnerElement {
 public:
-    static PassRefPtr<SpinButtonElement> create(Node*);
+    enum UpDownState {
+        Indeterminate, // Hovered, but the event is not handled.
+        Down,
+        Up,
+    };
 
-    // FIXME: "Spin button on up button" is not a phrase with a single clear meaning.
-    // Need a name for this that makes it clearer.
-    bool onUpButton() const { return m_onUpButton; }
+    static PassRefPtr<SpinButtonElement> create(Node*);
+    UpDownState upDownState() const { return m_upDownState; }
 
 private:
     SpinButtonElement(Node*);
@@ -104,9 +107,10 @@ private:
     virtual bool isEnabledFormControl() const { return static_cast<Element*>(const_cast<SpinButtonElement*>(this)->shadowAncestorNode())->isEnabledFormControl(); }
     virtual bool isReadOnlyFormControl() const { return static_cast<Element*>(const_cast<SpinButtonElement*>(this)->shadowAncestorNode())->isReadOnlyFormControl(); }
     virtual void defaultEventHandler(Event*);
+    virtual void setHovered(bool = true);
 
     bool m_capturing;
-    bool m_onUpButton;
+    UpDownState m_upDownState;
 };
 
 #if ENABLE(INPUT_SPEECH)