Diff
Modified: trunk/Source/WebCore/ChangeLog (150683 => 150684)
--- trunk/Source/WebCore/ChangeLog 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/ChangeLog 2013-05-25 09:16:30 UTC (rev 150684)
@@ -1,3 +1,48 @@
+2013-05-24 Andreas Kling <[email protected]>
+
+ Move "hover" state logic from Node to Element.
+ <http://webkit.org/b/116757>
+
+ Reviewed by Antti Koivisto.
+
+ Resolve a 7 year old FIXME by merging the "hover" state logic from Node and ContainerNode
+ and moving it all to Element instead.
+
+ * dom/Node.cpp:
+ (WebCore::Node::detach):
+ * dom/Element.cpp:
+ (WebCore::Element::detach):
+
+ Move Document::hoveredNodeDetached() call from Node::detach() to Element::detach().
+
+ (WebCore::Element::isUserActionElementHovered):
+ (WebCore::Element::setHovered):
+ * dom/Element.h:
+ (WebCore::Element::hovered):
+
+ Moved here from Node/ContainerNode.
+
+ * dom/UserActionElementSet.h:
+ (WebCore::UserActionElementSet::setHovered):
+ (WebCore::UserActionElementSet::setFlags):
+
+ Make setHovered() take an Element* instead of a Node*. I'd like to do this will all
+ of these methods eventually, so added a setFlags() helper with the tighter type.
+
+ * html/HTMLLabelElement.h:
+ * html/shadow/SpinButtonElement.h:
+
+ Sprinkle OVERRIDE on setHovered() overrides.
+
+ * dom/Document.cpp:
+ (WebCore::Document::updateHoverActiveState):
+ * accessibility/AccessibilityNodeObject.cpp:
+ (WebCore::AccessibilityNodeObject::isHovered):
+ * rendering/RenderTheme.cpp:
+ (WebCore::RenderTheme::isHovered):
+
+ Check if the inspected Node is an element before asking if it's hovered.
+
2013-05-25 Andreas Kling <[email protected]>
Document::formController() should return a reference.
Modified: trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp (150683 => 150684)
--- trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp 2013-05-25 09:16:30 UTC (rev 150684)
@@ -672,7 +672,7 @@
if (!node)
return false;
- return node->hovered();
+ return node->isElementNode() && toElement(node)->hovered();
}
bool AccessibilityNodeObject::isMultiSelectable() const
Modified: trunk/Source/WebCore/dom/ContainerNode.cpp (150683 => 150684)
--- trunk/Source/WebCore/dom/ContainerNode.cpp 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/dom/ContainerNode.cpp 2013-05-25 09:16:30 UTC (rev 150684)
@@ -1029,22 +1029,6 @@
}
}
-void ContainerNode::setHovered(bool over)
-{
- if (over == hovered()) return;
-
- Node::setHovered(over);
-
- // note that we need to recalc the style
- // FIXME: Move to Element
- if (renderer()) {
- if (renderStyle()->affectedByHover() || (isElementNode() && toElement(this)->childrenAffectedByHover()))
- setNeedsStyleRecalc();
- if (renderer() && renderer()->style()->hasAppearance())
- renderer()->theme()->stateChanged(renderer(), HoverState);
- }
-}
-
unsigned ContainerNode::childNodeCount() const
{
unsigned count = 0;
Modified: trunk/Source/WebCore/dom/ContainerNode.h (150683 => 150684)
--- trunk/Source/WebCore/dom/ContainerNode.h 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/dom/ContainerNode.h 2013-05-25 09:16:30 UTC (rev 150684)
@@ -111,7 +111,6 @@
virtual LayoutRect boundingBox() const OVERRIDE;
virtual void setFocus(bool) OVERRIDE;
virtual void setActive(bool active = true, bool pause = false) OVERRIDE;
- virtual void setHovered(bool = true) OVERRIDE;
virtual void scheduleSetNeedsStyleRecalc(StyleChangeType = FullStyleChange) OVERRIDE FINAL;
// -----------------------------------------------------------------------------
Modified: trunk/Source/WebCore/dom/Document.cpp (150683 => 150684)
--- trunk/Source/WebCore/dom/Document.cpp 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/dom/Document.cpp 2013-05-25 09:16:30 UTC (rev 150684)
@@ -5969,7 +5969,8 @@
size_t removeCount = nodesToRemoveFromChain.size();
for (size_t i = 0; i < removeCount; ++i) {
- nodesToRemoveFromChain[i]->setHovered(false);
+ if (nodesToRemoveFromChain[i]->isElementNode())
+ toElement(nodesToRemoveFromChain[i].get())->setHovered(false);
if (event && (hasCapturingMouseLeaveListener || nodesToRemoveFromChain[i]->hasEventListeners(eventNames().mouseleaveEvent)))
nodesToRemoveFromChain[i]->dispatchMouseEvent(*event, eventNames().mouseleaveEvent, 0, newHoverNode);
}
@@ -5983,7 +5984,8 @@
sawCommonAncestor = true;
if (!sawCommonAncestor) {
// Elements after the common hover ancestor does not change hover state, but are iterated over because they may change active state.
- nodesToAddToChain[i]->setHovered(true);
+ if (nodesToAddToChain[i]->isElementNode())
+ toElement(nodesToAddToChain[i].get())->setHovered(true);
if (event && (hasCapturingMouseEnterListener || nodesToAddToChain[i]->hasEventListeners(eventNames().mouseenterEvent)))
nodesToAddToChain[i]->dispatchMouseEvent(*event, eventNames().mouseenterEvent, 0, oldHoverNode.get());
}
Modified: trunk/Source/WebCore/dom/Element.cpp (150683 => 150684)
--- trunk/Source/WebCore/dom/Element.cpp 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/dom/Element.cpp 2013-05-25 09:16:30 UTC (rev 150684)
@@ -70,6 +70,7 @@
#include "PointerLockController.h"
#include "PseudoElement.h"
#include "RenderRegion.h"
+#include "RenderTheme.h"
#include "RenderView.h"
#include "RenderWidget.h"
#include "SelectorQuery.h"
@@ -401,6 +402,30 @@
return nullAtom;
}
+bool Element::isUserActionElementHovered() const
+{
+ ASSERT(isUserActionElement());
+ return document()->userActionElements().isHovered(this);
+}
+
+void Element::setHovered(bool flag)
+{
+ if (flag == hovered())
+ return;
+
+ if (Document* document = this->document())
+ document->userActionElements().setHovered(this, flag);
+
+ if (!renderer())
+ return;
+
+ if (renderer()->style()->affectedByHover() || childrenAffectedByHover())
+ setNeedsStyleRecalc();
+
+ if (renderer()->style()->hasAppearance())
+ renderer()->theme()->stateChanged(renderer(), HoverState);
+}
+
void Element::scrollIntoView(bool alignToTop)
{
document()->updateLayoutIgnorePendingStylesheets();
@@ -1326,6 +1351,10 @@
detachChildrenIfNeeded();
shadow->detach();
}
+
+ if (hovered())
+ document()->hoveredNodeDetached(this);
+
ContainerNode::detach();
}
Modified: trunk/Source/WebCore/dom/Element.h (150683 => 150684)
--- trunk/Source/WebCore/dom/Element.h 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/dom/Element.h 2013-05-25 09:16:30 UTC (rev 150684)
@@ -426,6 +426,9 @@
virtual const AtomicString& shadowPseudoId() const;
+ bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); }
+ virtual void setHovered(bool flag = true);
+
RenderStyle* computedStyle(PseudoId = NOPSEUDO);
// Methods for indicating the style is affected by dynamic updates (e.g., children changing, our position changing in our sibling list, etc.)
@@ -654,6 +657,8 @@
void classAttributeChanged(const AtomicString& newClassString);
private:
+ bool isUserActionElementHovered() const;
+
void updatePseudoElement(PseudoId, StyleChange = NoChange);
PassRefPtr<PseudoElement> createPseudoElementIfNeeded(PseudoId);
void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>);
Modified: trunk/Source/WebCore/dom/Node.cpp (150683 => 150684)
--- trunk/Source/WebCore/dom/Node.cpp 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/dom/Node.cpp 2013-05-25 09:16:30 UTC (rev 150684)
@@ -1107,8 +1107,6 @@
Document* doc = document();
if (isUserActionElement()) {
- if (hovered())
- doc->hoveredNodeDetached(this);
if (inActiveChain())
doc->activeChainNodeDetached(this);
doc->userActionElements().didDetach(this);
@@ -2751,12 +2749,6 @@
document->userActionElements().setActive(this, flag);
}
-void Node::setHovered(bool flag)
-{
- if (Document* document = this->document())
- document->userActionElements().setHovered(this, flag);
-}
-
bool Node::isUserActionElementActive() const
{
ASSERT(isUserActionElement());
@@ -2769,12 +2761,6 @@
return document()->userActionElements().isInActiveChain(this);
}
-bool Node::isUserActionElementHovered() const
-{
- ASSERT(isUserActionElement());
- return document()->userActionElements().isHovered(this);
-}
-
bool Node::isUserActionElementFocused() const
{
ASSERT(isUserActionElement());
Modified: trunk/Source/WebCore/dom/Node.h (150683 => 150684)
--- trunk/Source/WebCore/dom/Node.h 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/dom/Node.h 2013-05-25 09:16:30 UTC (rev 150684)
@@ -360,7 +360,6 @@
bool active() const { return isUserActionElement() && isUserActionElementActive(); }
bool inActiveChain() const { return isUserActionElement() && isUserActionElementInActiveChain(); }
- bool hovered() const { return isUserActionElement() && isUserActionElementHovered(); }
bool focused() const { return isUserActionElement() && isUserActionElementFocused(); }
bool attached() const { return getFlag(IsAttachedFlag); }
@@ -401,7 +400,6 @@
virtual void setFocus(bool flag);
virtual void setActive(bool flag = true, bool pause = false);
- virtual void setHovered(bool flag = true);
virtual short tabIndex() const;
@@ -791,7 +789,6 @@
bool isUserActionElementActive() const;
bool isUserActionElementInActiveChain() const;
- bool isUserActionElementHovered() const;
bool isUserActionElementFocused() const;
void setStyleChange(StyleChangeType);
Modified: trunk/Source/WebCore/dom/UserActionElementSet.cpp (150683 => 150684)
--- trunk/Source/WebCore/dom/UserActionElementSet.cpp 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/dom/UserActionElementSet.cpp 2013-05-25 09:16:30 UTC (rev 150684)
@@ -72,7 +72,7 @@
return clearFlags(toElement(node), flags);
}
-inline bool UserActionElementSet::hasFlags(const Element* element, unsigned flags) const
+bool UserActionElementSet::hasFlags(const Element* element, unsigned flags) const
{
ASSERT(element->isUserActionElement());
ElementFlagMap::const_iterator found = m_elements.find(const_cast<Element*>(element));
@@ -81,7 +81,7 @@
return found->value & flags;
}
-inline void UserActionElementSet::clearFlags(Element* element, unsigned flags)
+void UserActionElementSet::clearFlags(Element* element, unsigned flags)
{
if (!element->isUserActionElement()) {
ASSERT(m_elements.end() == m_elements.find(element));
@@ -104,7 +104,7 @@
found->value = updated;
}
-inline void UserActionElementSet::setFlags(Element* element, unsigned flags)
+void UserActionElementSet::setFlags(Element* element, unsigned flags)
{
ElementFlagMap::iterator result = m_elements.find(element);
if (result != m_elements.end()) {
Modified: trunk/Source/WebCore/dom/UserActionElementSet.h (150683 => 150684)
--- trunk/Source/WebCore/dom/UserActionElementSet.h 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/dom/UserActionElementSet.h 2013-05-25 09:16:30 UTC (rev 150684)
@@ -49,7 +49,7 @@
void setFocused(Node* node, bool enable) { setFlags(node, enable, IsFocusedFlag); }
void setActive(Node* node, bool enable) { setFlags(node, enable, IsActiveFlag); }
void setInActiveChain(Node* node, bool enable) { setFlags(node, enable, InActiveChainFlag); }
- void setHovered(Node* node, bool enable) { setFlags(node, enable, IsHoveredFlag); }
+ void setHovered(Element* element, bool enable) { setFlags(element, enable, IsHoveredFlag); }
UserActionElementSet();
~UserActionElementSet();
@@ -70,6 +70,7 @@
void clearFlags(Node*, unsigned);
bool hasFlags(const Node*, unsigned flags) const;
+ void setFlags(Element* element, bool enable, unsigned flags) { enable ? setFlags(element, flags) : clearFlags(element, flags); }
void setFlags(Element*, unsigned);
void clearFlags(Element*, unsigned);
bool hasFlags(const Element*, unsigned flags) const;
Modified: trunk/Source/WebCore/html/HTMLLabelElement.h (150683 => 150684)
--- trunk/Source/WebCore/html/HTMLLabelElement.h 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/html/HTMLLabelElement.h 2013-05-25 09:16:30 UTC (rev 150684)
@@ -47,7 +47,7 @@
// Overridden to update the hover/active state of the corresponding control.
virtual void setActive(bool = true, bool pause = false);
- virtual void setHovered(bool = true);
+ virtual void setHovered(bool = true) OVERRIDE;
// Overridden to either click() or focus() the corresponding control.
virtual void defaultEventHandler(Event*);
Modified: trunk/Source/WebCore/html/shadow/SpinButtonElement.h (150683 => 150684)
--- trunk/Source/WebCore/html/shadow/SpinButtonElement.h 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/html/shadow/SpinButtonElement.h 2013-05-25 09:16:30 UTC (rev 150684)
@@ -81,7 +81,7 @@
void startRepeatingTimer();
void stopRepeatingTimer();
void repeatingTimerFired(Timer<SpinButtonElement>*);
- virtual void setHovered(bool = true);
+ virtual void setHovered(bool = true) OVERRIDE;
bool shouldRespondToMouseEvents();
virtual bool isMouseFocusable() const { return false; }
Modified: trunk/Source/WebCore/rendering/RenderTheme.cpp (150683 => 150684)
--- trunk/Source/WebCore/rendering/RenderTheme.cpp 2013-05-25 09:08:38 UTC (rev 150683)
+++ trunk/Source/WebCore/rendering/RenderTheme.cpp 2013-05-25 09:16:30 UTC (rev 150684)
@@ -831,10 +831,10 @@
bool RenderTheme::isHovered(const RenderObject* o) const
{
Node* node = o->node();
- if (!node)
+ if (!node || !node->isElementNode())
return false;
- if (!node->isElementNode() || !toElement(node)->isSpinButtonElement())
- return node->hovered();
+ if (!toElement(node)->isSpinButtonElement())
+ return toElement(node)->hovered();
SpinButtonElement* element = static_cast<SpinButtonElement*>(node);
return element->hovered() && element->upDownState() != SpinButtonElement::Indeterminate;
}