OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r
ights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r
ights reserved. |
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) |
8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. |
9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. |
(...skipping 2811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2822 // mousemove events before the first layout should not lead to a premature l
ayout() | 2822 // mousemove events before the first layout should not lead to a premature l
ayout() |
2823 // happening, which could show a flash of white. | 2823 // happening, which could show a flash of white. |
2824 // See also the similar code in EventHandler::hitTestResultAtPoint. | 2824 // See also the similar code in EventHandler::hitTestResultAtPoint. |
2825 if (!renderer() || !view() || !view()->didFirstLayout()) | 2825 if (!renderer() || !view() || !view()->didFirstLayout()) |
2826 return MouseEventWithHitTestResults(event, HitTestResult(LayoutPoint()))
; | 2826 return MouseEventWithHitTestResults(event, HitTestResult(LayoutPoint()))
; |
2827 | 2827 |
2828 HitTestResult result(documentPoint); | 2828 HitTestResult result(documentPoint); |
2829 renderView()->hitTest(request, result); | 2829 renderView()->hitTest(request, result); |
2830 | 2830 |
2831 if (!request.readOnly()) | 2831 if (!request.readOnly()) |
2832 updateHoverActiveState(request, result.innerElement()); | 2832 updateHoverActiveState(request, result.innerElement(), &event); |
2833 | 2833 |
2834 return MouseEventWithHitTestResults(event, result); | 2834 return MouseEventWithHitTestResults(event, result); |
2835 } | 2835 } |
2836 | 2836 |
2837 // DOM Section 1.1.1 | 2837 // DOM Section 1.1.1 |
2838 bool Document::childTypeAllowed(NodeType type) const | 2838 bool Document::childTypeAllowed(NodeType type) const |
2839 { | 2839 { |
2840 switch (type) { | 2840 switch (type) { |
2841 case ATTRIBUTE_NODE: | 2841 case ATTRIBUTE_NODE: |
2842 case CDATA_SECTION_NODE: | 2842 case CDATA_SECTION_NODE: |
(...skipping 2064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4907 for (RenderObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAnce
stor()) { | 4907 for (RenderObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAnce
stor()) { |
4908 for (RenderObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hover
Ancestor()) { | 4908 for (RenderObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hover
Ancestor()) { |
4909 if (currObj1 == currObj2) | 4909 if (currObj1 == currObj2) |
4910 return currObj1; | 4910 return currObj1; |
4911 } | 4911 } |
4912 } | 4912 } |
4913 | 4913 |
4914 return 0; | 4914 return 0; |
4915 } | 4915 } |
4916 | 4916 |
4917 void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
nerElement) | 4917 void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
nerElement, const PlatformMouseEvent* event) |
4918 { | 4918 { |
4919 ASSERT(!request.readOnly()); | 4919 ASSERT(!request.readOnly()); |
4920 | 4920 |
4921 Element* innerElementInDocument = innerElement; | 4921 Element* innerElementInDocument = innerElement; |
4922 while (innerElementInDocument && innerElementInDocument->document() != this)
{ | 4922 while (innerElementInDocument && innerElementInDocument->document() != this)
{ |
4923 innerElementInDocument->document()->updateHoverActiveState(request, inne
rElementInDocument); | 4923 innerElementInDocument->document()->updateHoverActiveState(request, inne
rElementInDocument, event); |
4924 innerElementInDocument = innerElementInDocument->document()->ownerElemen
t(); | 4924 innerElementInDocument = innerElementInDocument->document()->ownerElemen
t(); |
4925 } | 4925 } |
4926 | 4926 |
4927 Element* oldActiveElement = activeElement(); | 4927 Element* oldActiveElement = activeElement(); |
4928 if (oldActiveElement && !request.active()) { | 4928 if (oldActiveElement && !request.active()) { |
4929 // We are clearing the :active chain because the mouse has been released
. | 4929 // We are clearing the :active chain because the mouse has been released
. |
4930 for (RenderObject* curr = oldActiveElement->renderer(); curr; curr = cur
r->parent()) { | 4930 for (RenderObject* curr = oldActiveElement->renderer(); curr; curr = cur
r->parent()) { |
4931 if (curr->node()) { | 4931 if (curr->node()) { |
4932 ASSERT(!curr->node()->isTextNode()); | 4932 ASSERT(!curr->node()->isTextNode()); |
4933 curr->node()->setActive(false); | 4933 curr->node()->setActive(false); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5001 nodesToRemoveFromChain.append(curr->node()); | 5001 nodesToRemoveFromChain.append(curr->node()); |
5002 } | 5002 } |
5003 } | 5003 } |
5004 | 5004 |
5005 // Now set the hover state for our new object up to the root. | 5005 // Now set the hover state for our new object up to the root. |
5006 for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) { | 5006 for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) { |
5007 if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->no
de()->inActiveChain())) | 5007 if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->no
de()->inActiveChain())) |
5008 nodesToAddToChain.append(curr->node()); | 5008 nodesToAddToChain.append(curr->node()); |
5009 } | 5009 } |
5010 | 5010 |
| 5011 // mouseenter and mouseleave events do not bubble, so they are dispatched if
f there is a capturing |
| 5012 // event handler on an ancestor or a normal event handler on the element its
elf. This special |
| 5013 // handling is necessary to avoid O(n^2) capturing event handler checks. We'
ll check the previously |
| 5014 // hovered node's ancestor tree for 'mouseleave' handlers here, then check t
he newly hovered node's |
| 5015 // ancestor tree for 'mouseenter' handlers after dispatching the 'mouseleave
' events (as the handler |
| 5016 // for 'mouseleave' might set a capturing 'mouseenter' handler, odd as that
might be). |
| 5017 bool ancestorHasCapturingMouseleaveListener = false; |
| 5018 if (event && newHoverNode != oldHoverNode.get()) { |
| 5019 for (Node* node = oldHoverNode.get(); node; node = node->parentOrShadowH
ostNode()) { |
| 5020 if (node->hasCapturingEventListeners(eventNames().mouseleaveEvent))
{ |
| 5021 ancestorHasCapturingMouseleaveListener = true; |
| 5022 break; |
| 5023 } |
| 5024 } |
| 5025 } |
| 5026 |
5011 size_t removeCount = nodesToRemoveFromChain.size(); | 5027 size_t removeCount = nodesToRemoveFromChain.size(); |
5012 for (size_t i = 0; i < removeCount; ++i) | 5028 for (size_t i = 0; i < removeCount; ++i) { |
5013 nodesToRemoveFromChain[i]->setHovered(false); | 5029 nodesToRemoveFromChain[i]->setHovered(false); |
| 5030 if (event && (ancestorHasCapturingMouseleaveListener || nodesToRemoveFro
mChain[i]->hasEventListeners(eventNames().mouseleaveEvent))) |
| 5031 nodesToRemoveFromChain[i]->dispatchMouseEvent(*event, eventNames().m
ouseleaveEvent, 0, newHoverNode); |
| 5032 } |
| 5033 |
| 5034 bool ancestorHasCapturingMouseenterListener = false; |
| 5035 if (event && newHoverNode != oldHoverNode.get()) { |
| 5036 for (Node* node = newHoverNode; node; node = node->parentOrShadowHostNod
e()) { |
| 5037 if (node->hasCapturingEventListeners(eventNames().mouseenterEvent))
{ |
| 5038 ancestorHasCapturingMouseenterListener = true; |
| 5039 break; |
| 5040 } |
| 5041 } |
| 5042 } |
5014 | 5043 |
5015 bool sawCommonAncestor = false; | 5044 bool sawCommonAncestor = false; |
5016 size_t addCount = nodesToAddToChain.size(); | 5045 size_t addCount = nodesToAddToChain.size(); |
5017 for (size_t i = 0; i < addCount; ++i) { | 5046 for (size_t i = 0; i < addCount; ++i) { |
5018 // Elements past the common ancestor do not change hover state, but migh
t change active state. | 5047 // Elements past the common ancestor do not change hover state, but migh
t change active state. |
5019 if (ancestor && nodesToAddToChain[i] == ancestor->node()) | 5048 if (ancestor && nodesToAddToChain[i] == ancestor->node()) |
5020 sawCommonAncestor = true; | 5049 sawCommonAncestor = true; |
5021 if (allowActiveChanges) | 5050 if (allowActiveChanges) |
5022 nodesToAddToChain[i]->setActive(true); | 5051 nodesToAddToChain[i]->setActive(true); |
5023 if (!sawCommonAncestor) | 5052 if (!sawCommonAncestor) { |
5024 nodesToAddToChain[i]->setHovered(true); | 5053 nodesToAddToChain[i]->setHovered(true); |
| 5054 if (event && (ancestorHasCapturingMouseenterListener || nodesToAddTo
Chain[i]->hasEventListeners(eventNames().mouseenterEvent))) |
| 5055 nodesToAddToChain[i]->dispatchMouseEvent(*event, eventNames().mo
useenterEvent, 0, oldHoverNode.get()); |
| 5056 } |
5025 } | 5057 } |
5026 | 5058 |
5027 updateStyleIfNeeded(); | 5059 updateStyleIfNeeded(); |
5028 } | 5060 } |
5029 | 5061 |
5030 void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const | 5062 void Document::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const |
5031 { | 5063 { |
5032 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM); | 5064 MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM); |
5033 ContainerNode::reportMemoryUsage(memoryObjectInfo); | 5065 ContainerNode::reportMemoryUsage(memoryObjectInfo); |
5034 TreeScope::reportMemoryUsage(memoryObjectInfo); | 5066 TreeScope::reportMemoryUsage(memoryObjectInfo); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5173 { | 5205 { |
5174 return DocumentLifecycleNotifier::create(this); | 5206 return DocumentLifecycleNotifier::create(this); |
5175 } | 5207 } |
5176 | 5208 |
5177 DocumentLifecycleNotifier* Document::lifecycleNotifier() | 5209 DocumentLifecycleNotifier* Document::lifecycleNotifier() |
5178 { | 5210 { |
5179 return static_cast<DocumentLifecycleNotifier*>(ScriptExecutionContext::lifec
ycleNotifier()); | 5211 return static_cast<DocumentLifecycleNotifier*>(ScriptExecutionContext::lifec
ycleNotifier()); |
5180 } | 5212 } |
5181 | 5213 |
5182 } // namespace WebCore | 5214 } // namespace WebCore |
OLD | NEW |