Modified: trunk/LayoutTests/ChangeLog (155350 => 155351)
--- trunk/LayoutTests/ChangeLog 2013-09-09 14:30:45 UTC (rev 155350)
+++ trunk/LayoutTests/ChangeLog 2013-09-09 14:39:41 UTC (rev 155351)
@@ -1,3 +1,15 @@
+2013-09-09 Allan Sandfeld Jensen <[email protected]>
+
+ MouseEnter and MouseLeave may be emitted on Document nodes
+ https://bugs.webkit.org/show_bug.cgi?id=120862
+
+ Reviewed by Antonio Gomes.
+
+ Update expectations now we correctly do not get mouseenter/mouseleave events
+ targeted for Document nodes.
+
+ * fast/events/mouseenterleave-on-subframe-expected.txt:
+
2013-09-09 Mihai Maerean <[email protected]>
[Qt] fast/regions/overflow* converted reftests failing after r155114
Modified: trunk/LayoutTests/fast/events/mouseenterleave-on-subframe-expected.txt (155350 => 155351)
--- trunk/LayoutTests/fast/events/mouseenterleave-on-subframe-expected.txt 2013-09-09 14:30:45 UTC (rev 155350)
+++ trunk/LayoutTests/fast/events/mouseenterleave-on-subframe-expected.txt 2013-09-09 14:39:41 UTC (rev 155351)
@@ -1,12 +1,10 @@
-This is a test of a mouseleave events in an inner-document. The test is success if we get matching mouseleave events for every mouseenter event.
+This is a test of a mouseleave events in an inner-document. The test is success if we get matching mouseleave events for every mouseenter event, and if the logged nodeNames of event targets does not include '#document'.
mouseenter on DIV
mouseenter on BODY
mouseenter on HTML
-mouseenter on #document
mouseleave on DIV
mouseleave on BODY
mouseleave on HTML
-mouseleave on #document
Modified: trunk/Source/WebCore/ChangeLog (155350 => 155351)
--- trunk/Source/WebCore/ChangeLog 2013-09-09 14:30:45 UTC (rev 155350)
+++ trunk/Source/WebCore/ChangeLog 2013-09-09 14:39:41 UTC (rev 155351)
@@ -1,5 +1,21 @@
2013-09-09 Allan Sandfeld Jensen <[email protected]>
+ MouseEnter and MouseLeave may be emitted on Document nodes
+ https://bugs.webkit.org/show_bug.cgi?id=120862
+
+ Reviewed by Antonio Gomes.
+
+ Replace the overgeneric use of Nodes with Elements in updateHoverActiveState.
+ This also fixes the bug of emitting mouseenter/mouseleave events on Document,
+ since Document is not an Element.
+
+ This is tested by fast/events/mouseenterleave-on-subframe.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::updateHoverActiveState):
+
+2013-09-09 Allan Sandfeld Jensen <[email protected]>
+
MouseLeave not always emitted when cursor leaves subframe
https://bugs.webkit.org/show_bug.cgi?id=121026
Modified: trunk/Source/WebCore/dom/Document.cpp (155350 => 155351)
--- trunk/Source/WebCore/dom/Document.cpp 2013-09-09 14:30:45 UTC (rev 155350)
+++ trunk/Source/WebCore/dom/Document.cpp 2013-09-09 14:39:41 UTC (rev 155351)
@@ -5819,8 +5819,8 @@
// Locate the common ancestor render object for the two renderers.
RenderObject* ancestor = nearestCommonHoverAncestor(oldHoverObj, newHoverObj);
- Vector<RefPtr<Node>, 32> nodesToRemoveFromChain;
- Vector<RefPtr<Node>, 32> nodesToAddToChain;
+ Vector<RefPtr<Element>, 32> elementsToRemoveFromChain;
+ Vector<RefPtr<Element>, 32> elementsToAddToChain;
// mouseenter and mouseleave events are only dispatched if there is a capturing eventhandler on an ancestor
// or a normal eventhandler on the element itself (they don't bubble).
@@ -5847,18 +5847,19 @@
// (for instance by setting display:none in the :hover pseudo-class). In this case, the old hovered element (and its ancestors)
// must be updated, to ensure it's normal style is re-applied.
if (oldHoveredElement && !oldHoverObj) {
- for (Node* node = oldHoveredElement.get(); node; node = node->parentNode()) {
- if (!mustBeInActiveChain || (node->isElementNode() && toElement(node)->inActiveChain()))
- nodesToRemoveFromChain.append(node);
+ for (Element* element= oldHoveredElement.get(); element; element = element->parentElement()) {
+ if (!mustBeInActiveChain || element->inActiveChain())
+ elementsToRemoveFromChain.append(element);
}
}
// The old hover path only needs to be cleared up to (and not including) the common ancestor;
for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) {
- if (!curr->node() || curr->isText())
+ if (!curr->node() || !curr->node()->isElementNode())
continue;
- if (!mustBeInActiveChain || (curr->node()->isElementNode() && toElement(curr->node())->inActiveChain()))
- nodesToRemoveFromChain.append(curr->node());
+ Element* element = toElement(curr->node());
+ if (!mustBeInActiveChain || element->inActiveChain())
+ elementsToRemoveFromChain.append(element);
}
// Unset hovered nodes in sub frame documents if the old hovered node was a frame owner.
if (oldHoveredElement && oldHoveredElement->isFrameOwnerElement()) {
@@ -5869,33 +5870,31 @@
// Now set the hover state for our new object up to the root.
for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) {
- if (!curr->node() || curr->isText())
+ if (!curr->node() || !curr->node()->isElementNode())
continue;
- if (!mustBeInActiveChain || (curr->node()->isElementNode() && toElement(curr->node())->inActiveChain()))
- nodesToAddToChain.append(curr->node());
+ Element* element = toElement(curr->node());
+ if (!mustBeInActiveChain || element->inActiveChain())
+ elementsToAddToChain.append(element);
}
- size_t removeCount = nodesToRemoveFromChain.size();
+ size_t removeCount = elementsToRemoveFromChain.size();
for (size_t i = 0; i < removeCount; ++i) {
- 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, newHoveredElement);
+ elementsToRemoveFromChain[i]->setHovered(false);
+ if (event && (hasCapturingMouseLeaveListener || elementsToRemoveFromChain[i]->hasEventListeners(eventNames().mouseleaveEvent)))
+ elementsToRemoveFromChain[i]->dispatchMouseEvent(*event, eventNames().mouseleaveEvent, 0, newHoveredElement);
}
bool sawCommonAncestor = false;
- size_t addCount = nodesToAddToChain.size();
- for (size_t i = 0; i < addCount; ++i) {
- if (allowActiveChanges && nodesToAddToChain[i]->isElementNode())
- toElement(nodesToAddToChain[i].get())->setActive(true);
- if (ancestor && nodesToAddToChain[i] == ancestor->node())
+ for (size_t i = 0, size = elementsToAddToChain.size(); i < size; ++i) {
+ if (allowActiveChanges)
+ elementsToAddToChain[i]->setActive(true);
+ if (ancestor && elementsToAddToChain[i] == ancestor->node())
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.
- 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, oldHoveredElement.get());
+ elementsToAddToChain[i]->setHovered(true);
+ if (event && (hasCapturingMouseEnterListener || elementsToAddToChain[i]->hasEventListeners(eventNames().mouseenterEvent)))
+ elementsToAddToChain[i]->dispatchMouseEvent(*event, eventNames().mouseenterEvent, 0, oldHoveredElement.get());
}
}