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 3100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3111 // mousemove events before the first layout should not lead to a premature l ayout() | 3111 // mousemove events before the first layout should not lead to a premature l ayout() |
3112 // happening, which could show a flash of white. | 3112 // happening, which could show a flash of white. |
3113 // See also the similar code in EventHandler::hitTestResultAtPoint. | 3113 // See also the similar code in EventHandler::hitTestResultAtPoint. |
3114 if (!layoutView() || !view() || !view()->didFirstLayout()) | 3114 if (!layoutView() || !view() || !view()->didFirstLayout()) |
3115 return MouseEventWithHitTestResults(event, HitTestResult(LayoutPoint())) ; | 3115 return MouseEventWithHitTestResults(event, HitTestResult(LayoutPoint())) ; |
3116 | 3116 |
3117 HitTestResult result(documentPoint); | 3117 HitTestResult result(documentPoint); |
3118 layoutView()->hitTest(request, result); | 3118 layoutView()->hitTest(request, result); |
3119 | 3119 |
3120 if (!request.readOnly()) | 3120 if (!request.readOnly()) |
3121 updateHoverActiveState(request, result.innerElement(), &event); | 3121 updateHoverActiveState(request, result.innerElement()); |
3122 | 3122 |
3123 return MouseEventWithHitTestResults(event, result); | 3123 return MouseEventWithHitTestResults(event, result); |
3124 } | 3124 } |
3125 | 3125 |
3126 // DOM Section 1.1.1 | 3126 // DOM Section 1.1.1 |
3127 bool Document::childTypeAllowed(NodeType type) const | 3127 bool Document::childTypeAllowed(NodeType type) const |
3128 { | 3128 { |
3129 switch (type) { | 3129 switch (type) { |
3130 case ATTRIBUTE_NODE: | 3130 case ATTRIBUTE_NODE: |
3131 case CDATA_SECTION_NODE: | 3131 case CDATA_SECTION_NODE: |
(...skipping 2100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5232 for (LayoutObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAnce stor()) { | 5232 for (LayoutObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAnce stor()) { |
5233 for (LayoutObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hover Ancestor()) { | 5233 for (LayoutObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hover Ancestor()) { |
5234 if (currObj1 == currObj2) | 5234 if (currObj1 == currObj2) |
5235 return currObj1; | 5235 return currObj1; |
5236 } | 5236 } |
5237 } | 5237 } |
5238 | 5238 |
5239 return 0; | 5239 return 0; |
5240 } | 5240 } |
5241 | 5241 |
5242 void Document::updateHoverActiveState(const HitTestRequest& request, Element* in nerElement, const PlatformMouseEvent* event) | 5242 void Document::updateHoverActiveState(const HitTestRequest& request, Element* in nerElement) |
5243 { | 5243 { |
5244 ASSERT(!request.readOnly()); | 5244 ASSERT(!request.readOnly()); |
5245 | 5245 |
5246 if (request.active() && m_frame) | 5246 if (request.active() && m_frame) |
5247 m_frame->eventHandler().notifyElementActivated(); | 5247 m_frame->eventHandler().notifyElementActivated(); |
5248 | 5248 |
5249 Element* innerElementInDocument = innerElement; | 5249 Element* innerElementInDocument = innerElement; |
5250 while (innerElementInDocument && innerElementInDocument->document() != this) { | 5250 while (innerElementInDocument && innerElementInDocument->document() != this) { |
5251 innerElementInDocument->document().updateHoverActiveState(request, inner ElementInDocument, event); | 5251 innerElementInDocument->document().updateHoverActiveState(request, inner ElementInDocument); |
5252 innerElementInDocument = innerElementInDocument->document().ownerElement (); | 5252 innerElementInDocument = innerElementInDocument->document().ownerElement (); |
5253 } | 5253 } |
5254 | 5254 |
5255 Element* oldActiveElement = activeHoverElement(); | 5255 Element* oldActiveElement = activeHoverElement(); |
5256 if (oldActiveElement && !request.active()) { | 5256 if (oldActiveElement && !request.active()) { |
5257 // The oldActiveElement renderer is null, dropped on :active by setting display: none, | 5257 // The oldActiveElement renderer is null, dropped on :active by setting display: none, |
5258 // for instance. We still need to clear the ActiveChain as the mouse is released. | 5258 // for instance. We still need to clear the ActiveChain as the mouse is released. |
5259 for (Node* node = oldActiveElement; node; node = NodeRenderingTraversal: :parent(*node)) { | 5259 for (Node* node = oldActiveElement; node; node = NodeRenderingTraversal: :parent(*node)) { |
5260 ASSERT(!node->isTextNode()); | 5260 ASSERT(!node->isTextNode()); |
5261 node->setActive(false); | 5261 node->setActive(false); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5315 nodesToRemoveFromChain.append(node); | 5315 nodesToRemoveFromChain.append(node); |
5316 } | 5316 } |
5317 | 5317 |
5318 } | 5318 } |
5319 | 5319 |
5320 // The old hover path only needs to be cleared up to (and not including) the common ancestor; | 5320 // The old hover path only needs to be cleared up to (and not including) the common ancestor; |
5321 for (LayoutObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) { | 5321 for (LayoutObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) { |
5322 if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr ->node()->inActiveChain())) | 5322 if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr ->node()->inActiveChain())) |
5323 nodesToRemoveFromChain.append(curr->node()); | 5323 nodesToRemoveFromChain.append(curr->node()); |
5324 } | 5324 } |
5325 | |
5326 // FIXME: It seems the two loops above can push a single node twice into nodesToRemoveFromChain. There must be a better way. | |
Mike West
2015/03/31 11:45:33
Nit: Blink is now writing these as "// TODO(mustaq
mustaq
2015/03/31 14:08:31
Done.
| |
5325 } | 5327 } |
5326 | 5328 |
5327 // Now set the hover state for our new object up to the root. | 5329 // Now set the hover state for our new object up to the root. |
5328 for (LayoutObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) { | 5330 for (LayoutObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) { |
5329 if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->no de()->inActiveChain())) | 5331 if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->no de()->inActiveChain())) |
5330 nodesToAddToChain.append(curr->node()); | 5332 nodesToAddToChain.append(curr->node()); |
5331 } | 5333 } |
5332 | 5334 |
5333 // mouseenter and mouseleave events do not bubble, so they are dispatched if f there is a capturing | |
5334 // event handler on an ancestor or a normal event handler on the element its elf. This special | |
5335 // handling is necessary to avoid O(n^2) capturing event handler checks. We' ll check the previously | |
5336 // hovered node's ancestor tree for 'mouseleave' handlers here, then check t he newly hovered node's | |
5337 // ancestor tree for 'mouseenter' handlers after dispatching the 'mouseleave ' events (as the handler | |
5338 // for 'mouseleave' might set a capturing 'mouseenter' handler, odd as that might be). | |
5339 bool ancestorHasCapturingMouseleaveListener = false; | |
5340 if (event && newHoverNode != oldHoverNode.get()) { | |
5341 for (Node* node = oldHoverNode.get(); node; node = node->parentOrShadowH ostNode()) { | |
5342 if (node->hasCapturingEventListeners(EventTypeNames::mouseleave)) { | |
5343 ancestorHasCapturingMouseleaveListener = true; | |
5344 break; | |
5345 } | |
5346 } | |
5347 } | |
5348 | |
5349 size_t removeCount = nodesToRemoveFromChain.size(); | 5335 size_t removeCount = nodesToRemoveFromChain.size(); |
5350 for (size_t i = 0; i < removeCount; ++i) { | 5336 for (size_t i = 0; i < removeCount; ++i) { |
5351 nodesToRemoveFromChain[i]->setHovered(false); | 5337 nodesToRemoveFromChain[i]->setHovered(false); |
5352 if (event && (ancestorHasCapturingMouseleaveListener || nodesToRemoveFro mChain[i]->hasEventListeners(EventTypeNames::mouseleave))) | |
5353 nodesToRemoveFromChain[i]->dispatchMouseEvent(*event, EventTypeNames ::mouseleave, 0, newHoverNode); | |
5354 } | |
5355 | |
5356 bool ancestorHasCapturingMouseenterListener = false; | |
5357 if (event && newHoverNode != oldHoverNode.get()) { | |
5358 for (Node* node = newHoverNode; node; node = node->parentOrShadowHostNod e()) { | |
5359 if (node->hasCapturingEventListeners(EventTypeNames::mouseenter)) { | |
5360 ancestorHasCapturingMouseenterListener = true; | |
5361 break; | |
5362 } | |
5363 } | |
5364 } | 5338 } |
5365 | 5339 |
5366 bool sawCommonAncestor = false; | 5340 bool sawCommonAncestor = false; |
5367 size_t addCount = nodesToAddToChain.size(); | 5341 size_t addCount = nodesToAddToChain.size(); |
5368 for (size_t i = 0; i < addCount; ++i) { | 5342 for (size_t i = 0; i < addCount; ++i) { |
5369 // Elements past the common ancestor do not change hover state, but migh t change active state. | 5343 // Elements past the common ancestor do not change hover state, but migh t change active state. |
5370 if (ancestorNode && nodesToAddToChain[i] == ancestorNode) | 5344 if (ancestorNode && nodesToAddToChain[i] == ancestorNode) |
5371 sawCommonAncestor = true; | 5345 sawCommonAncestor = true; |
5372 if (allowActiveChanges) | 5346 if (allowActiveChanges) |
5373 nodesToAddToChain[i]->setActive(true); | 5347 nodesToAddToChain[i]->setActive(true); |
5374 if (!sawCommonAncestor) { | 5348 if (!sawCommonAncestor) { |
5375 nodesToAddToChain[i]->setHovered(true); | 5349 nodesToAddToChain[i]->setHovered(true); |
5376 if (event && (ancestorHasCapturingMouseenterListener || nodesToAddTo Chain[i]->hasEventListeners(EventTypeNames::mouseenter))) | |
5377 nodesToAddToChain[i]->dispatchMouseEvent(*event, EventTypeNames: :mouseenter, 0, oldHoverNode.get()); | |
5378 } | 5350 } |
5379 } | 5351 } |
5380 } | 5352 } |
5381 | 5353 |
5382 bool Document::haveStylesheetsLoaded() const | 5354 bool Document::haveStylesheetsLoaded() const |
5383 { | 5355 { |
5384 return m_styleEngine->haveStylesheetsLoaded(); | 5356 return m_styleEngine->haveStylesheetsLoaded(); |
5385 } | 5357 } |
5386 | 5358 |
5387 Locale& Document::getCachedLocale(const AtomicString& locale) | 5359 Locale& Document::getCachedLocale(const AtomicString& locale) |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5756 #ifndef NDEBUG | 5728 #ifndef NDEBUG |
5757 using namespace blink; | 5729 using namespace blink; |
5758 void showLiveDocumentInstances() | 5730 void showLiveDocumentInstances() |
5759 { | 5731 { |
5760 WeakDocumentSet& set = liveDocumentSet(); | 5732 WeakDocumentSet& set = liveDocumentSet(); |
5761 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); | 5733 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); |
5762 for (Document* document : set) | 5734 for (Document* document : set) |
5763 fprintf(stderr, "- Document %p URL: %s\n", document, document->url().str ing().utf8().data()); | 5735 fprintf(stderr, "- Document %p URL: %s\n", document, document->url().str ing().utf8().data()); |
5764 } | 5736 } |
5765 #endif | 5737 #endif |
OLD | NEW |