Chromium Code Reviews| 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 |