Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: third_party/WebKit/Source/core/dom/Document.cpp

Issue 2797173002: Document::hoverNode() is always an Element. (Closed)
Patch Set: Documentation hovered node -> hovered element. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All
7 * rights reserved. 7 * rights reserved.
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
9 * (http://www.torchmobile.com/) 9 * (http://www.torchmobile.com/)
10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. 10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
(...skipping 2009 matching lines...) Expand 10 before | Expand all | Expand 10 after
2020 // SecurityOrigin. 2020 // SecurityOrigin.
2021 2021
2022 updateStyle(); 2022 updateStyle();
2023 2023
2024 notifyLayoutTreeOfSubtreeChanges(); 2024 notifyLayoutTreeOfSubtreeChanges();
2025 2025
2026 // As a result of the style recalculation, the currently hovered element might 2026 // As a result of the style recalculation, the currently hovered element might
2027 // have been detached (for example, by setting display:none in the :hover 2027 // have been detached (for example, by setting display:none in the :hover
2028 // style), schedule another mouseMove event to check if any other elements 2028 // style), schedule another mouseMove event to check if any other elements
2029 // ended up under the mouse pointer due to re-layout. 2029 // ended up under the mouse pointer due to re-layout.
2030 if (hoverNode() && !hoverNode()->layoutObject() && frame()) 2030 if (hoverElement() && !hoverElement()->layoutObject() && frame())
2031 frame()->eventHandler().dispatchFakeMouseMoveEventSoon(); 2031 frame()->eventHandler().dispatchFakeMouseMoveEventSoon();
2032 2032
2033 if (m_focusedElement && !m_focusedElement->isFocusable()) 2033 if (m_focusedElement && !m_focusedElement->isFocusable())
2034 clearFocusedElementSoon(); 2034 clearFocusedElementSoon();
2035 layoutViewItem().clearHitTestCache(); 2035 layoutViewItem().clearHitTestCache();
2036 2036
2037 DCHECK(!DocumentAnimations::needsAnimationTimingUpdate(*this)); 2037 DCHECK(!DocumentAnimations::needsAnimationTimingUpdate(*this));
2038 2038
2039 unsigned elementCount = 2039 unsigned elementCount =
2040 styleEngine().styleForElementCount() - startElementCount; 2040 styleEngine().styleForElementCount() - startElementCount;
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
2510 m_domWindow->clearEventQueue(); 2510 m_domWindow->clearEventQueue();
2511 2511
2512 if (m_layoutView) 2512 if (m_layoutView)
2513 m_layoutView->setIsInWindow(false); 2513 m_layoutView->setIsInWindow(false);
2514 2514
2515 if (registrationContext()) 2515 if (registrationContext())
2516 registrationContext()->documentWasDetached(); 2516 registrationContext()->documentWasDetached();
2517 2517
2518 MutationObserver::cleanSlotChangeList(*this); 2518 MutationObserver::cleanSlotChangeList(*this);
2519 2519
2520 m_hoverNode = nullptr; 2520 m_hoverElement = nullptr;
2521 m_activeHoverElement = nullptr; 2521 m_activeHoverElement = nullptr;
2522 m_autofocusElement = nullptr; 2522 m_autofocusElement = nullptr;
2523 2523
2524 if (m_focusedElement.get()) { 2524 if (m_focusedElement.get()) {
2525 Element* oldFocusedElement = m_focusedElement; 2525 Element* oldFocusedElement = m_focusedElement;
2526 m_focusedElement = nullptr; 2526 m_focusedElement = nullptr;
2527 if (page()) 2527 if (page())
2528 page()->chromeClient().focusedNodeChanged(oldFocusedElement, nullptr); 2528 page()->chromeClient().focusedNodeChanged(oldFocusedElement, nullptr);
2529 } 2529 }
2530 m_sequentialFocusNavigationStartingPoint = nullptr; 2530 m_sequentialFocusNavigationStartingPoint = nullptr;
(...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after
3913 // We need to manually repaint because we avoid doing all repaints in layout 3913 // We need to manually repaint because we avoid doing all repaints in layout
3914 // or style recalc while sheets are still loading to avoid FOUC. 3914 // or style recalc while sheets are still loading to avoid FOUC.
3915 m_pendingSheetLayout = IgnoreLayoutWithPendingSheets; 3915 m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
3916 3916
3917 DCHECK(!layoutViewItem().isNull() || importsController()); 3917 DCHECK(!layoutViewItem().isNull() || importsController());
3918 if (!layoutViewItem().isNull()) 3918 if (!layoutViewItem().isNull())
3919 layoutViewItem().invalidatePaintForViewAndCompositedLayers(); 3919 layoutViewItem().invalidatePaintForViewAndCompositedLayers();
3920 } 3920 }
3921 } 3921 }
3922 3922
3923 void Document::setHoverNode(Node* newHoverNode) { 3923 void Document::setHoverElement(Element* newHoverElement) {
3924 m_hoverNode = newHoverNode; 3924 m_hoverElement = newHoverElement;
3925 } 3925 }
3926 3926
3927 void Document::setActiveHoverElement(Element* newActiveElement) { 3927 void Document::setActiveHoverElement(Element* newActiveElement) {
3928 if (!newActiveElement) { 3928 if (!newActiveElement) {
3929 m_activeHoverElement.clear(); 3929 m_activeHoverElement.clear();
3930 return; 3930 return;
3931 } 3931 }
3932 3932
3933 m_activeHoverElement = newActiveElement; 3933 m_activeHoverElement = newActiveElement;
3934 } 3934 }
3935 3935
3936 void Document::removeFocusedElementOfSubtree(Node* node, 3936 void Document::removeFocusedElementOfSubtree(Node* node,
3937 bool amongChildrenOnly) { 3937 bool amongChildrenOnly) {
3938 if (!m_focusedElement) 3938 if (!m_focusedElement)
3939 return; 3939 return;
3940 3940
3941 // We can't be focused if we're not in the document. 3941 // We can't be focused if we're not in the document.
3942 if (!node->isConnected()) 3942 if (!node->isConnected())
3943 return; 3943 return;
3944 bool contains = 3944 bool contains =
3945 node->isShadowIncludingInclusiveAncestorOf(m_focusedElement.get()); 3945 node->isShadowIncludingInclusiveAncestorOf(m_focusedElement.get());
3946 if (contains && (m_focusedElement != node || !amongChildrenOnly)) 3946 if (contains && (m_focusedElement != node || !amongChildrenOnly))
3947 clearFocusedElement(); 3947 clearFocusedElement();
3948 } 3948 }
3949 3949
3950 static Node* skipDisplayNoneAncestors(Node* node) { 3950 static Element* skipDisplayNoneAncestors(Element* element) {
3951 while (node) { 3951 for (; element; element = FlatTreeTraversal::parentElement(*element)) {
3952 if (node->layoutObject()) 3952 if (element->layoutObject() || element->hasDisplayContentsStyle())
3953 return node; 3953 return element;
3954 if (node->isElementNode() && toElement(node)->hasDisplayContentsStyle())
3955 return node;
3956 node = FlatTreeTraversal::parent(*node);
3957 } 3954 }
3958 return nullptr; 3955 return nullptr;
3959 } 3956 }
3960 3957
3961 void Document::hoveredNodeDetached(Element& element) { 3958 void Document::hoveredElementDetached(Element& element) {
3962 if (!m_hoverNode) 3959 if (!m_hoverElement)
3960 return;
3961 if (element != m_hoverElement)
3963 return; 3962 return;
3964 3963
3965 m_hoverNode->updateDistribution(); 3964 m_hoverElement->updateDistribution();
3966 if (element != m_hoverNode && 3965 m_hoverElement = skipDisplayNoneAncestors(&element);
3967 (!m_hoverNode->isTextNode() ||
3968 element != FlatTreeTraversal::parent(*m_hoverNode)))
3969 return;
3970
3971 m_hoverNode = skipDisplayNoneAncestors(&element);
3972 3966
3973 // If the mouse cursor is not visible, do not clear existing 3967 // If the mouse cursor is not visible, do not clear existing
3974 // hover effects on the ancestors of |element| and do not invoke 3968 // hover effects on the ancestors of |element| and do not invoke
3975 // new hover effects on any other element. 3969 // new hover effects on any other element.
3976 if (!page()->isCursorVisible()) 3970 if (!page()->isCursorVisible())
3977 return; 3971 return;
3978 3972
3979 if (frame()) 3973 if (frame())
3980 frame()->eventHandler().scheduleHoverStateUpdate(); 3974 frame()->eventHandler().scheduleHoverStateUpdate();
3981 } 3975 }
3982 3976
3983 void Document::activeChainNodeDetached(Element& element) { 3977 void Document::activeChainNodeDetached(Element& element) {
3984 if (!m_activeHoverElement) 3978 if (element == m_activeHoverElement)
3985 return; 3979 m_activeHoverElement = skipDisplayNoneAncestors(&element);
3986
3987 if (element != m_activeHoverElement)
3988 return;
3989
3990 Node* activeNode = skipDisplayNoneAncestors(&element);
3991 m_activeHoverElement = activeNode && activeNode->isElementNode()
3992 ? toElement(activeNode)
3993 : nullptr;
3994 } 3980 }
3995 3981
3996 const Vector<AnnotatedRegionValue>& Document::annotatedRegions() const { 3982 const Vector<AnnotatedRegionValue>& Document::annotatedRegions() const {
3997 return m_annotatedRegions; 3983 return m_annotatedRegions;
3998 } 3984 }
3999 3985
4000 void Document::setAnnotatedRegions( 3986 void Document::setAnnotatedRegions(
4001 const Vector<AnnotatedRegionValue>& regions) { 3987 const Vector<AnnotatedRegionValue>& regions) {
4002 m_annotatedRegions = regions; 3988 m_annotatedRegions = regions;
4003 setAnnotatedRegionsDirty(false); 3989 setAnnotatedRegionsDirty(false);
(...skipping 2171 matching lines...) Expand 10 before | Expand all | Expand 10 after
6175 request, innerElementInDocument); 6161 request, innerElementInDocument);
6176 innerElementInDocument = innerElementInDocument->document().localOwner(); 6162 innerElementInDocument = innerElementInDocument->document().localOwner();
6177 } 6163 }
6178 6164
6179 updateDistribution(); 6165 updateDistribution();
6180 Element* oldActiveElement = activeHoverElement(); 6166 Element* oldActiveElement = activeHoverElement();
6181 if (oldActiveElement && !request.active()) { 6167 if (oldActiveElement && !request.active()) {
6182 // The oldActiveElement layoutObject is null, dropped on :active by setting 6168 // The oldActiveElement layoutObject is null, dropped on :active by setting
6183 // display: none, for instance. We still need to clear the ActiveChain as 6169 // display: none, for instance. We still need to clear the ActiveChain as
6184 // the mouse is released. 6170 // the mouse is released.
6185 for (Node* node = oldActiveElement; node; 6171 for (Element* element = oldActiveElement; element;
6186 node = FlatTreeTraversal::parent(*node)) { 6172 element = FlatTreeTraversal::parentElement(*element)) {
6187 DCHECK(!node->isTextNode()); 6173 element->setActive(false);
6188 node->setActive(false); 6174 m_userActionElements.setInActiveChain(element, false);
6189 m_userActionElements.setInActiveChain(node, false);
6190 } 6175 }
6191 setActiveHoverElement(nullptr); 6176 setActiveHoverElement(nullptr);
6192 } else { 6177 } else {
6193 Element* newActiveElement = innerElementInDocument; 6178 Element* newActiveElement = innerElementInDocument;
6194 if (!oldActiveElement && newActiveElement && 6179 if (!oldActiveElement && newActiveElement &&
6195 !newActiveElement->isDisabledFormControl() && request.active() && 6180 !newActiveElement->isDisabledFormControl() && request.active() &&
6196 !request.touchMove()) { 6181 !request.touchMove()) {
6197 // We are setting the :active chain and freezing it. If future moves 6182 // We are setting the :active chain and freezing it. If future moves
6198 // happen, they will need to reference this chain. 6183 // happen, they will need to reference this chain.
6199 for (Node* node = newActiveElement; node; 6184 for (Element* element = newActiveElement; element;
6200 node = FlatTreeTraversal::parent(*node)) { 6185 element = FlatTreeTraversal::parentElement(*element)) {
6201 DCHECK(!node->isTextNode()); 6186 m_userActionElements.setInActiveChain(element, true);
6202 m_userActionElements.setInActiveChain(node, true);
6203 } 6187 }
6204 setActiveHoverElement(newActiveElement); 6188 setActiveHoverElement(newActiveElement);
6205 } 6189 }
6206 } 6190 }
6207 // If the mouse has just been pressed, set :active on the chain. Those (and 6191 // If the mouse has just been pressed, set :active on the chain. Those (and
6208 // only those) nodes should remain :active until the mouse is released. 6192 // only those) nodes should remain :active until the mouse is released.
6209 bool allowActiveChanges = !oldActiveElement && activeHoverElement(); 6193 bool allowActiveChanges = !oldActiveElement && activeHoverElement();
6210 6194
6211 // If the mouse is down and if this is a mouse move event, we want to restrict 6195 // If the mouse is down and if this is a mouse move event, we want to restrict
6212 // changes in :hover/:active to only apply to elements that are in the :active 6196 // changes in :hover/:active to only apply to elements that are in the :active
6213 // chain that we froze at the time the mouse went down. 6197 // chain that we froze at the time the mouse went down.
6214 bool mustBeInActiveChain = request.active() && request.move(); 6198 bool mustBeInActiveChain = request.active() && request.move();
6215 6199
6216 Node* oldHoverNode = hoverNode(); 6200 Element* oldHoverElement = hoverElement();
6217 6201
6218 // The passed in innerElement may not be a result of a hit test for the 6202 // The passed in innerElement may not be a result of a hit test for the
6219 // current up-to-date flat/layout tree. That means the element may be 6203 // current up-to-date flat/layout tree. That means the element may be
6220 // display:none at this point. Skip up the ancestor chain until we reach an 6204 // display:none at this point. Skip up the ancestor chain until we reach an
6221 // element with a layoutObject or a display:contents element. 6205 // element with a layoutObject or a display:contents element.
6222 Node* newHoverNode = skipDisplayNoneAncestors(innerElementInDocument); 6206 Element* newHoverElement = skipDisplayNoneAncestors(innerElementInDocument);
6223 6207
6224 // Update our current hover node. 6208 // Update our current hover element.
6225 setHoverNode(newHoverNode); 6209 setHoverElement(newHoverElement);
6226 6210
6227 Node* ancestor = 6211 Node* ancestorElement = nullptr;
6228 (oldHoverNode && oldHoverNode->isConnected() && newHoverNode) 6212 if (oldHoverElement && oldHoverElement->isConnected() && newHoverElement) {
6229 ? FlatTreeTraversal::commonAncestor(*oldHoverNode, *newHoverNode) 6213 Node* ancestor =
6230 : nullptr; 6214 FlatTreeTraversal::commonAncestor(*oldHoverElement, *newHoverElement);
6215 if (ancestor && ancestor->isElementNode())
6216 ancestorElement = toElement(ancestor);
6217 }
6231 6218
6232 HeapVector<Member<Node>, 32> nodesToRemoveFromChain; 6219 HeapVector<Member<Element>, 32> elementsToRemoveFromChain;
6233 HeapVector<Member<Node>, 32> nodesToAddToChain; 6220 HeapVector<Member<Element>, 32> elementsToAddToChain;
6234 6221
6235 if (oldHoverNode != newHoverNode) { 6222 if (oldHoverElement != newHoverElement) {
6236 // The old hover path only needs to be cleared up to (and not including) the 6223 // The old hover path only needs to be cleared up to (and not including) the
6237 // common ancestor; 6224 // common ancestor;
6238 // 6225 //
6239 // FIXME(ecobos@igalia.com): oldHoverNode may be disconnected from the tree 6226 // FIXME(ecobos@igalia.com): oldHoverElement may be disconnected from the
6240 // already. This is due to our handling of m_hoverNode in 6227 // tree already. This is due to our handling of m_hoverElement in
6241 // hoveredNodeDetached (which assumes all the parents are hovered) and 6228 // hoveredElementDetached (which assumes all the parents are hovered) and
6242 // mustBeInActiveChain (which makes this not hold). 6229 // mustBeInActiveChain (which makes this not hold).
6243 // 6230 //
6244 // In that case, none of the nodes in the chain have the flags, so there's 6231 // In that case, none of the nodes in the chain have the flags, so there's
6245 // no problem in skipping this step. 6232 // no problem in skipping this step.
6246 if (oldHoverNode && oldHoverNode->isConnected()) { 6233 if (oldHoverElement && oldHoverElement->isConnected()) {
6247 for (Node* curr = oldHoverNode; curr && curr != ancestor; 6234 for (Element* curr = oldHoverElement; curr && curr != ancestorElement;
6248 curr = FlatTreeTraversal::parent(*curr)) { 6235 curr = FlatTreeTraversal::parentElement(*curr)) {
6249 if (!curr->isTextNode() && 6236 if (!mustBeInActiveChain || curr->inActiveChain())
6250 (!mustBeInActiveChain || curr->inActiveChain())) 6237 elementsToRemoveFromChain.push_back(curr);
6251 nodesToRemoveFromChain.push_back(curr);
6252 } 6238 }
6253 } 6239 }
6254 } 6240 }
6255 6241
6256 // Now set the hover state for our new object up to the root. 6242 // Now set the hover state for our new object up to the root.
6257 for (Node* curr = newHoverNode; curr; 6243 for (Element* curr = newHoverElement; curr;
6258 curr = FlatTreeTraversal::parent(*curr)) { 6244 curr = FlatTreeTraversal::parentElement(*curr)) {
6259 if (!curr->isTextNode() && (!mustBeInActiveChain || curr->inActiveChain())) 6245 if (!mustBeInActiveChain || curr->inActiveChain())
6260 nodesToAddToChain.push_back(curr); 6246 elementsToAddToChain.push_back(curr);
6261 } 6247 }
6262 6248
6263 for (Node* node : nodesToRemoveFromChain) 6249 for (Element* element : elementsToRemoveFromChain)
6264 node->setHovered(false); 6250 element->setHovered(false);
6265 6251
6266 bool sawCommonAncestor = false; 6252 bool sawCommonAncestor = false;
6267 for (Node* node : nodesToAddToChain) { 6253 for (Element* element : elementsToAddToChain) {
6268 // Elements past the common ancestor do not change hover state, but might 6254 // Elements past the common ancestor do not change hover state, but might
6269 // change active state. 6255 // change active state.
6270 if (node == ancestor) 6256 if (element == ancestorElement)
6271 sawCommonAncestor = true; 6257 sawCommonAncestor = true;
6272 if (allowActiveChanges) 6258 if (allowActiveChanges)
6273 node->setActive(true); 6259 element->setActive(true);
6274 if (!sawCommonAncestor || node == m_hoverNode) 6260 if (!sawCommonAncestor || element == m_hoverElement)
6275 node->setHovered(true); 6261 element->setHovered(true);
6276 } 6262 }
6277 } 6263 }
6278 6264
6279 bool Document::haveScriptBlockingStylesheetsLoaded() const { 6265 bool Document::haveScriptBlockingStylesheetsLoaded() const {
6280 return m_styleEngine->haveScriptBlockingStylesheetsLoaded(); 6266 return m_styleEngine->haveScriptBlockingStylesheetsLoaded();
6281 } 6267 }
6282 6268
6283 bool Document::haveRenderBlockingStylesheetsLoaded() const { 6269 bool Document::haveRenderBlockingStylesheetsLoaded() const {
6284 if (RuntimeEnabledFeatures::cssInBodyDoesNotBlockPaintEnabled()) 6270 if (RuntimeEnabledFeatures::cssInBodyDoesNotBlockPaintEnabled())
6285 return m_styleEngine->haveRenderBlockingStylesheetsLoaded(); 6271 return m_styleEngine->haveRenderBlockingStylesheetsLoaded();
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
6520 sendSensitiveInputVisibility(); 6506 sendSensitiveInputVisibility();
6521 } 6507 }
6522 6508
6523 DEFINE_TRACE(Document) { 6509 DEFINE_TRACE(Document) {
6524 visitor->trace(m_importsController); 6510 visitor->trace(m_importsController);
6525 visitor->trace(m_docType); 6511 visitor->trace(m_docType);
6526 visitor->trace(m_implementation); 6512 visitor->trace(m_implementation);
6527 visitor->trace(m_autofocusElement); 6513 visitor->trace(m_autofocusElement);
6528 visitor->trace(m_focusedElement); 6514 visitor->trace(m_focusedElement);
6529 visitor->trace(m_sequentialFocusNavigationStartingPoint); 6515 visitor->trace(m_sequentialFocusNavigationStartingPoint);
6530 visitor->trace(m_hoverNode); 6516 visitor->trace(m_hoverElement);
6531 visitor->trace(m_activeHoverElement); 6517 visitor->trace(m_activeHoverElement);
6532 visitor->trace(m_documentElement); 6518 visitor->trace(m_documentElement);
6533 visitor->trace(m_rootScrollerController); 6519 visitor->trace(m_rootScrollerController);
6534 visitor->trace(m_titleElement); 6520 visitor->trace(m_titleElement);
6535 visitor->trace(m_axObjectCache); 6521 visitor->trace(m_axObjectCache);
6536 visitor->trace(m_markers); 6522 visitor->trace(m_markers);
6537 visitor->trace(m_cssTarget); 6523 visitor->trace(m_cssTarget);
6538 visitor->trace(m_currentScriptStack); 6524 visitor->trace(m_currentScriptStack);
6539 visitor->trace(m_scriptRunner); 6525 visitor->trace(m_scriptRunner);
6540 visitor->trace(m_listsInvalidatedAtDocument); 6526 visitor->trace(m_listsInvalidatedAtDocument);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
6633 } 6619 }
6634 6620
6635 void showLiveDocumentInstances() { 6621 void showLiveDocumentInstances() {
6636 WeakDocumentSet& set = liveDocumentSet(); 6622 WeakDocumentSet& set = liveDocumentSet();
6637 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); 6623 fprintf(stderr, "There are %u documents currently alive:\n", set.size());
6638 for (blink::Document* document : set) 6624 for (blink::Document* document : set)
6639 fprintf(stderr, "- Document %p URL: %s\n", document, 6625 fprintf(stderr, "- Document %p URL: %s\n", document,
6640 document->url().getString().utf8().data()); 6626 document->url().getString().utf8().data());
6641 } 6627 }
6642 #endif 6628 #endif
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/Document.h ('k') | third_party/WebKit/Source/core/dom/Element.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698